drew 5 jaren geleden
bovenliggende
commit
8908cf1f54
48 gewijzigde bestanden met toevoegingen van 3468 en 3314 verwijderingen
  1. 22 0
      src/main/vue/.eslintrc.js
  2. 19 0
      src/main/vue/.prettierrc.js
  3. 2 4
      src/main/vue/babel.config.js
  4. 23 13
      src/main/vue/package.json
  5. 4 4
      src/main/vue/postcss.config.js
  6. 24 19
      src/main/vue/src/components/Bar.vue
  7. 23 18
      src/main/vue/src/components/Bubble.vue
  8. 204 216
      src/main/vue/src/components/CoordPick.vue
  9. 199 204
      src/main/vue/src/components/CoordinateSelect.vue
  10. 27 22
      src/main/vue/src/components/CropUpload.vue
  11. 77 47
      src/main/vue/src/components/DynamicForm.vue
  12. 69 77
      src/main/vue/src/components/FileUpload.vue
  13. 29 30
      src/main/vue/src/components/GenOptionsDialog.vue
  14. 95 86
      src/main/vue/src/components/JsonView.vue
  15. 24 19
      src/main/vue/src/components/Line.vue
  16. 24 19
      src/main/vue/src/components/LineBarChart.vue
  17. 45 33
      src/main/vue/src/components/MultiUpload.vue
  18. 23 18
      src/main/vue/src/components/Pie.vue
  19. 23 19
      src/main/vue/src/components/PolarArea.vue
  20. 23 18
      src/main/vue/src/components/Radar.vue
  21. 48 57
      src/main/vue/src/components/RichText.vue
  22. 22 17
      src/main/vue/src/components/SingleUpload.vue
  23. 19 13
      src/main/vue/src/components/SortableHeader.vue
  24. 23 23
      src/main/vue/src/components/SysMenu.vue
  25. 428 419
      src/main/vue/src/components/zh_CN.js
  26. 1 1
      src/main/vue/src/main.js
  27. 1 1
      src/main/vue/src/mixins/formatters.js
  28. 24 42
      src/main/vue/src/mixins/pageableTable.js
  29. 6 6
      src/main/vue/src/plugins/dataExport.js
  30. 56 65
      src/main/vue/src/router.js
  31. 186 186
      src/main/vue/src/views/404.vue
  32. 43 66
      src/main/vue/src/views/Admin.vue
  33. 76 75
      src/main/vue/src/views/Api.vue
  34. 37 21
      src/main/vue/src/views/Dashboard.vue
  35. 181 237
      src/main/vue/src/views/GenCodeEdit.vue
  36. 13 26
      src/main/vue/src/views/GenCodeList.vue
  37. 91 103
      src/main/vue/src/views/Login.vue
  38. 107 104
      src/main/vue/src/views/Menus.vue
  39. 3 3
      src/main/vue/src/views/RoleMenus.vue
  40. 185 185
      src/main/vue/src/views/SysConfigList.vue
  41. 33 41
      src/main/vue/src/views/UserEdit.vue
  42. 73 73
      src/main/vue/src/views/UserList.vue
  43. 45 42
      src/main/vue/src/widgets/BarChartWidget.vue
  44. 40 41
      src/main/vue/src/widgets/LineChartWidget.vue
  45. 34 40
      src/main/vue/src/widgets/PieChartWidget.vue
  46. 26 26
      src/main/vue/src/widgets/UserWidget.vue
  47. 15 15
      src/main/vue/src/widgets/WidgetCard.vue
  48. 673 520
      src/main/vue/yarn.lock

+ 22 - 0
src/main/vue/.eslintrc.js

@@ -0,0 +1,22 @@
+module.exports = {
+    root: true,
+    env: {
+        node: true,
+    },
+    extends: ['plugin:vue/essential', '@vue/prettier'],
+    rules: {
+        'no-console': 'off',
+        'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
+        'no-unused-vars': 'off',
+        'no-empty': ['error', { allowEmptyCatch: true }],
+        'prettier/prettier': ['error'],
+    },
+    parserOptions: {
+        parser: 'babel-eslint',
+    },
+    globals: {
+        Chart: true,
+        AMap: true,
+        FontAwesome: true,
+    },
+};

+ 19 - 0
src/main/vue/.prettierrc.js

@@ -0,0 +1,19 @@
+module.exports = {
+    printWidth: 120,
+    singleQuote: true,
+    tabWidth: 4,
+    overrides: [
+        {
+            files: '*.html',
+            options: {
+                parser: 'html',
+            },
+        },
+        {
+            files: '*.vue',
+            options: {
+                parser: 'vue',
+            },
+        },
+    ],
+};

+ 2 - 4
src/main/vue/babel.config.js

@@ -1,5 +1,3 @@
 module.exports = {
-  presets: [
-    '@vue/app'
-  ]
-}
+    presets: ['@vue/app'],
+};

+ 23 - 13
src/main/vue/package.json

@@ -4,38 +4,48 @@
   "private": true,
   "scripts": {
     "serve": "vue-cli-service serve",
-    "build": "vue-cli-service build"
+    "build": "vue-cli-service build",
+    "lint": "vue-cli-service lint"
   },
   "dependencies": {
     "@fortawesome/fontawesome": "^1.1.8",
     "@fortawesome/fontawesome-free-solid": "^5.0.13",
     "@fortawesome/vue-fontawesome": "^0.1.7",
     "@tinymce/tinymce-vue": "^3.2.1",
-    "axios": "^0.19.0",
+    "axios": "^0.19.2",
     "babel-polyfill": "^6.26.0",
     "chart.js": "^2.8.0",
     "clipboard": "^2.0.6",
     "core-js": "^2.6.5",
-    "date-fns": "^2.3.0",
-    "element-ui": "^2.12.0",
+    "date-fns": "^2.14.0",
+    "element-ui": "^2.13.2",
     "normalize.css": "^8.0.1",
     "qs": "^6.9.0",
     "resolve-url": "^0.2.1",
     "tinymce": "^5.2.2",
-    "vue": "^2.6.10",
+    "vue": "^2.6.11",
     "vue-avatar-cropper": "^1.0.5",
-    "vue-axios": "^2.1.4",
-    "vue-chartjs": "^3.4.2",
-    "vue-grid-layout": "^2.3.6",
-    "vue-i18n": "^8.14.1",
-    "vue-router": "^3.0.3",
-    "vuex": "^3.0.1"
+    "vue-axios": "^2.1.5",
+    "vue-chartjs": "^3.5.0",
+    "vue-grid-layout": "^2.3.7",
+    "vue-i18n": "^8.18.2",
+    "vue-router": "^3.3.4",
+    "vuex": "^3.4.0"
   },
   "devDependencies": {
-    "@vue/cli-plugin-babel": "^3.11.0",
-    "@vue/cli-service": "^3.11.0",
+    "@vue/cli-plugin-babel": "^4.4.4",
+    "@vue/cli-plugin-eslint": "^4.4.4",
+    "@vue/cli-plugin-router": "^4.4.4",
+    "@vue/cli-plugin-vuex": "^4.4.4",
+    "@vue/cli-service": "^4.4.4",
+    "@vue/eslint-config-prettier": "^6.0.0",
+    "babel-eslint": "^10.1.0",
+    "eslint": "^7.2.0",
+    "eslint-plugin-prettier": "^3.1.4",
+    "eslint-plugin-vue": "^6.2.2",
     "less": "^3.0.4",
     "less-loader": "^5.0.0",
+    "prettier": "^2.0.5",
     "style-resources-loader": "^1.3.3",
     "vue-cli-plugin-style-resources-loader": "^0.1.4",
     "vue-template-compiler": "^2.6.10"

+ 4 - 4
src/main/vue/postcss.config.js

@@ -1,5 +1,5 @@
 module.exports = {
-  plugins: {
-    autoprefixer: {}
-  }
-}
+    plugins: {
+        autoprefixer: {},
+    },
+};

+ 24 - 19
src/main/vue/src/components/Bar.vue

@@ -1,42 +1,47 @@
 <template>
     <div>
-        <canvas ref="chart" :height="height" style="margin: auto"></canvas>
+        <canvas ref="chart" :height="height" style="margin: auto;"></canvas>
     </div>
 </template>
 <script>
-import VueCharts from 'vue-chartjs'
-import { Bar } from 'vue-chartjs'
+import VueCharts from 'vue-chartjs';
+import { Bar } from 'vue-chartjs';
 export default {
     name: 'bar',
     props: ['chartData', 'options', 'width', 'height'],
     watch: {
         chartData() {
             if (this.myChart) {
-                this.myChart.update()
+                this.myChart.update();
+            } else {
+                this.myChart = new Chart(this.$refs.chart.getContext('2d'), {
+                    type: 'bar',
+                    data: this.chartData,
+                    options: this.options,
+                });
             }
-            else {
-                this.myChart = new Chart(this.$refs.chart.getContext('2d'), { type:'bar', data: this.chartData, options: this.options })
-            }
-        }
+        },
     },
     data() {
         return {
-            myChart: null
-        }
+            myChart: null,
+        };
     },
     mounted() {
-        console.log(this.type)
+        console.log(this.type);
         if (this.chartData) {
-            this.myChart = new Chart(this.$refs.chart.getContext('2d'), { type: 'bar', data: this.chartData, options: this.options })
+            this.myChart = new Chart(this.$refs.chart.getContext('2d'), {
+                type: 'bar',
+                data: this.chartData,
+                options: this.options,
+            });
         }
-
     },
     methods: {
         updateChart() {
-            this.myChart.update()
-        }
-    }
-}
+            this.myChart.update();
+        },
+    },
+};
 </script>
-<style lang="less" scoped>
-</style>
+<style lang="less" scoped></style>

+ 23 - 18
src/main/vue/src/components/Bubble.vue

@@ -1,41 +1,46 @@
 <template>
     <div>
-        <canvas ref="chart" style="margin: auto" ></canvas>
+        <canvas ref="chart" style="margin: auto;"></canvas>
     </div>
 </template>
 <script>
-import VueCharts from 'vue-chartjs'
-import { bubble} from 'vue-chartjs'
+import VueCharts from 'vue-chartjs';
+import { bubble } from 'vue-chartjs';
 export default {
     name: 'bubble',
     props: ['chartData', 'options', 'width', 'height'],
     watch: {
         chartData() {
             if (this.myChart) {
-                this.myChart.update()
+                this.myChart.update();
+            } else {
+                this.myChart = new Chart(this.$refs.chart.getContext('2d'), {
+                    type: 'bubble',
+                    data: this.chartData,
+                    options: this.options,
+                });
             }
-            else {
-                this.myChart = new Chart(this.$refs.chart.getContext('2d'), { type: 'bubble', data: this.chartData, options: this.options })
-            }
-        }
+        },
     },
     data() {
         return {
-            myChart: null
-        }
+            myChart: null,
+        };
     },
     mounted() {
         if (this.chartData) {
-            this.myChart = new Chart(this.$refs.chart.getContext('2d'), { type: 'bubble', data: this.chartData, options: this.options })
+            this.myChart = new Chart(this.$refs.chart.getContext('2d'), {
+                type: 'bubble',
+                data: this.chartData,
+                options: this.options,
+            });
         }
-
     },
     methods: {
         updateChart() {
-            this.myChart.update()
-        }
-    }
-}
+            this.myChart.update();
+        },
+    },
+};
 </script>
-<style lang="less" scoped>
-</style>
+<style lang="less" scoped></style>

+ 204 - 216
src/main/vue/src/components/CoordPick.vue

@@ -1,40 +1,30 @@
 <template>
     <div class="map-wrapper">
         <el-amap
-                ref="map"
-                :center="mapCenter"
-                :zoom="zoom"
-                class="map-view"
-                :events="mapEvents"
-                :expandZoomRange="true"
+            ref="map"
+            :center="mapCenter"
+            :zoom="zoom"
+            class="map-view"
+            :events="mapEvents"
+            :expandZoomRange="true"
         >
             <el-amap-marker
-                    v-if="myPosition"
-                    :position="myPosition"
-                    content="<div class='my-position'><div>"
-                    cursor="default"
+                v-if="myPosition"
+                :position="myPosition"
+                content="<div class='my-position'><div>"
+                cursor="default"
             >
             </el-amap-marker>
-            <el-amap-marker
-                    v-if="marker"
-                    :position="marker"
-                    :draggable="true"
-                    :events="markerEvents"
-                    cursor="default"
-            >
+            <el-amap-marker v-if="marker" :position="marker" :draggable="true" :events="markerEvents" cursor="default">
             </el-amap-marker>
         </el-amap>
-        <el-amap-search-box
-                class="search-box"
-                :search-option="searchOption"
-                :on-search-result="onSearchResult"
-        >
+        <el-amap-search-box class="search-box" :search-option="searchOption" :on-search-result="onSearchResult">
         </el-amap-search-box>
         <div class="btn-locate" @click="locate">
             <i
-                    :class="{
+                :class="{
                     'el-icon-loading': locating,
-                    'el-icon-location-outline': !locating
+                    'el-icon-location-outline': !locating,
                 }"
             ></i>
         </div>
@@ -47,213 +37,211 @@
     </div>
 </template>
 <script>
-    export default {
-        props: {
-            searchOption: {
-                type: Object,
-                default() {
-                    return {
-                        city: "全国",
-                        citylimit: false
-                    };
-                }
+export default {
+    props: {
+        searchOption: {
+            type: Object,
+            default() {
+                return {
+                    city: '全国',
+                    citylimit: false,
+                };
             },
-            center: {
-                type: Array
-            },
-            zoom: {
-                type: Number,
-                default: 15
-            },
-            value: {
-                type: Array
-            }
         },
-        data() {
-            let self = this;
-            return {
-                locating: false,
-                myPosition: null,
-                marker: null,
-                mapEvents: {
-                    complete() {
-                        self.$refs.map.$$getInstance().setDefaultCursor("default");
-                    },
-                    click(e) {
-                        self.marker = [e.lnglat.O, e.lnglat.P];
-                        self.mapCenter = [e.lnglat.O, e.lnglat.P];
-                        self.getGeolocation();
-                    }
-                },
-                markerEvents: {
-                    dragend(e) {
-                        self.marker = [e.lnglat.O, e.lnglat.P];
-                        self.mapCenter = [e.lnglat.O, e.lnglat.P];
-                        self.getGeolocation();
-                    }
-                },
-                mapCenter: [121.480342, 31.236339]
-            };
+        center: {
+            type: Array,
         },
-        created() {
-            if (this.center) {
-                this.mapCenter = this.center;
-            }
-            if (this.value) {
-                this.mapCenter = this.value;
-                this.marker = this.value;
-            }
+        zoom: {
+            type: Number,
+            default: 15,
         },
-        methods: {
-            locate() {
-                this.locating = true;
-                let geolocation = new AMap.Geolocation({
-                    enableHighAccuracy: true,
-                    timeout: 10000
-                });
-                geolocation.getCurrentPosition();
-                AMap.event.addListener(geolocation, "complete", data => {
-                    this.locating = false;
-                    this.mapCenter = [data.position.O, data.position.P];
-                    this.myPosition = [data.position.O, data.position.P];
-                });
-                AMap.event.addListener(geolocation, "error", err => {
-                    this.locating = false;
-                    console.log(err);
-                });
-            },
-            onSearchResult(pois) {
-                let latSum = 0;
-                let lngSum = 0;
-                if (pois.length > 0) {
-                    pois.forEach(poi => {
-                        let { lng, lat } = poi;
-                        lngSum += lng;
-                        latSum += lat;
-                    });
-                    let center = {
-                        lng: lngSum / pois.length,
-                        lat: latSum / pois.length
-                    };
-                    this.mapCenter = [center.lng, center.lat];
-                }
+        value: {
+            type: Array,
+        },
+    },
+    data() {
+        let self = this;
+        return {
+            locating: false,
+            myPosition: null,
+            marker: null,
+            mapEvents: {
+                complete() {
+                    self.$refs.map.$$getInstance().setDefaultCursor('default');
+                },
+                click(e) {
+                    self.marker = [e.lnglat.O, e.lnglat.P];
+                    self.mapCenter = [e.lnglat.O, e.lnglat.P];
+                    self.getGeolocation();
+                },
             },
-            setZoom(d) {
-                this.$refs.map
-                    .$$getInstance()
-                    .setZoom(this.$refs.map.$$getInstance().getZoom() + d);
+            markerEvents: {
+                dragend(e) {
+                    self.marker = [e.lnglat.O, e.lnglat.P];
+                    self.mapCenter = [e.lnglat.O, e.lnglat.P];
+                    self.getGeolocation();
+                },
             },
-            getGeolocation() {
-                let lnglat = this.marker;
-                AMap.plugin("AMap.Geocoder", () => {
-                    let geocoder = new AMap.Geocoder();
-                    geocoder.getAddress(lnglat, (status, result) => {
-                        if (status === "complete" && result.info === "OK") {
-                            this.$emit("selected", {
-                                lnglat: {
-                                    lng: lnglat[0],
-                                    lat: lnglat[1]
-                                },
-                                ...result.regeocode
-                            });
-                        }
-                    });
+            mapCenter: [121.480342, 31.236339],
+        };
+    },
+    created() {
+        if (this.center) {
+            this.mapCenter = this.center;
+        }
+        if (this.value) {
+            this.mapCenter = this.value;
+            this.marker = this.value;
+        }
+    },
+    methods: {
+        locate() {
+            this.locating = true;
+            let geolocation = new AMap.Geolocation({
+                enableHighAccuracy: true,
+                timeout: 10000,
+            });
+            geolocation.getCurrentPosition();
+            AMap.event.addListener(geolocation, 'complete', (data) => {
+                this.locating = false;
+                this.mapCenter = [data.position.O, data.position.P];
+                this.myPosition = [data.position.O, data.position.P];
+            });
+            AMap.event.addListener(geolocation, 'error', (err) => {
+                this.locating = false;
+                console.log(err);
+            });
+        },
+        onSearchResult(pois) {
+            let latSum = 0;
+            let lngSum = 0;
+            if (pois.length > 0) {
+                pois.forEach((poi) => {
+                    let { lng, lat } = poi;
+                    lngSum += lng;
+                    latSum += lat;
                 });
+                let center = {
+                    lng: lngSum / pois.length,
+                    lat: latSum / pois.length,
+                };
+                this.mapCenter = [center.lng, center.lat];
             }
         },
-        watch: {
-            value(val) {
-                this.mapCenter = val;
-                this.marker = val;
-            }
-        }
-    };
+        setZoom(d) {
+            this.$refs.map.$$getInstance().setZoom(this.$refs.map.$$getInstance().getZoom() + d);
+        },
+        getGeolocation() {
+            let lnglat = this.marker;
+            AMap.plugin('AMap.Geocoder', () => {
+                let geocoder = new AMap.Geocoder();
+                geocoder.getAddress(lnglat, (status, result) => {
+                    if (status === 'complete' && result.info === 'OK') {
+                        this.$emit('selected', {
+                            lnglat: {
+                                lng: lnglat[0],
+                                lat: lnglat[1],
+                            },
+                            ...result.regeocode,
+                        });
+                    }
+                });
+            });
+        },
+    },
+    watch: {
+        value(val) {
+            this.mapCenter = val;
+            this.marker = val;
+        },
+    },
+};
 </script>
 <style lang="less" scoped>
-    .map-wrapper {
-        position: relative;
-        border-radius: 4px;
-        border: 1px solid #E4E7ED;
-        overflow: hidden;
-        .map-view {
-            width: 100%;
-            height: 400px;
-        }
-        .btn-locate {
-            width: 30px;
-            height: 30px;
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            font-size: 16px;
-            color: #666;
-            position: absolute;
-            left: 10px;
-            bottom: 10px;
-            background: #fff;
-            border-radius: 2px;
-            box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.3);
-            &:active {
-                background: #f2f3f4;
-            }
-        }
-        .btn-minus {
-            width: 30px;
-            height: 30px;
-            font-size: 16px;
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            color: #666;
-            position: absolute;
-            left: 10px;
-            bottom: 50px;
-            background: #fff;
-            border-radius: 2px;
-            box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.3);
-            &:active {
-                background: #f2f3f4;
-            }
+.map-wrapper {
+    position: relative;
+    border-radius: 4px;
+    border: 1px solid #e4e7ed;
+    overflow: hidden;
+    .map-view {
+        width: 100%;
+        height: 400px;
+    }
+    .btn-locate {
+        width: 30px;
+        height: 30px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        font-size: 16px;
+        color: #666;
+        position: absolute;
+        left: 10px;
+        bottom: 10px;
+        background: #fff;
+        border-radius: 2px;
+        box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.3);
+        &:active {
+            background: #f2f3f4;
         }
-        .btn-plus {
-            width: 30px;
-            height: 30px;
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            font-size: 16px;
-            color: #666;
-            position: absolute;
-            left: 10px;
-            bottom: 90px;
-            background: #fff;
-            border-radius: 2px;
-            box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.3);
-            &:active {
-                background: #f2f3f4;
-            }
+    }
+    .btn-minus {
+        width: 30px;
+        height: 30px;
+        font-size: 16px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        color: #666;
+        position: absolute;
+        left: 10px;
+        bottom: 50px;
+        background: #fff;
+        border-radius: 2px;
+        box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.3);
+        &:active {
+            background: #f2f3f4;
         }
-        .search-box {
-            position: absolute;
-            top: 10px;
-            left: 10px;
+    }
+    .btn-plus {
+        width: 30px;
+        height: 30px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        font-size: 16px;
+        color: #666;
+        position: absolute;
+        left: 10px;
+        bottom: 90px;
+        background: #fff;
+        border-radius: 2px;
+        box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.3);
+        &:active {
+            background: #f2f3f4;
         }
     }
+    .search-box {
+        position: absolute;
+        top: 10px;
+        left: 10px;
+    }
+}
 </style>
 <style lang="less">
-    .anchorBL,
-    .amap-logo,
-    .amap-copyright {
-        display: none !important;
-    }
+.anchorBL,
+.amap-logo,
+.amap-copyright {
+    display: none !important;
+}
 
-    .my-position {
-        width: 14px;
-        height: 14px;
-        border-radius: 50%;
-        border: 3px solid #fff;
-        background: #20a0ff;
-        box-shadow: 0 2px 2px rgba(0, 0, 0, 0.15);
-        position: relative;
-    }
-</style>
+.my-position {
+    width: 14px;
+    height: 14px;
+    border-radius: 50%;
+    border: 3px solid #fff;
+    background: #20a0ff;
+    box-shadow: 0 2px 2px rgba(0, 0, 0, 0.15);
+    position: relative;
+}
+</style>

+ 199 - 204
src/main/vue/src/components/CoordinateSelect.vue

@@ -1,32 +1,27 @@
 <template>
     <div class="map-wrapper">
-        <el-amap ref="map"
-                 :center="mapCenter"
-                 :zoom="zoom"
-                 class="map-view"
-                 :events="mapEvents"
-                 :expandZoomRange="true">
+        <el-amap
+            ref="map"
+            :center="mapCenter"
+            :zoom="zoom"
+            class="map-view"
+            :events="mapEvents"
+            :expandZoomRange="true"
+        >
             <el-amap-marker
                 v-if="myPosition"
                 :position="myPosition"
                 content="<div class='my-position'><div>"
-                cursor="default">
+                cursor="default"
+            >
             </el-amap-marker>
-            <el-amap-marker
-                v-if="marker"
-                :position="marker"
-                :draggable="true"
-                :events="markerEvents"
-                cursor="default">
+            <el-amap-marker v-if="marker" :position="marker" :draggable="true" :events="markerEvents" cursor="default">
             </el-amap-marker>
         </el-amap>
-        <el-amap-search-box
-            class="search-box"
-            :search-option="searchOption"
-            :on-search-result="onSearchResult">
+        <el-amap-search-box class="search-box" :search-option="searchOption" :on-search-result="onSearchResult">
         </el-amap-search-box>
         <div class="btn-locate" @click="locate">
-            <i :class="{'el-icon-loading':locating,'el-icon-location-outline':!locating}"></i>
+            <i :class="{ 'el-icon-loading': locating, 'el-icon-location-outline': !locating }"></i>
         </div>
         <div class="btn-minus" @click="setZoom(-1)">
             <i class="el-icon-minus"></i>
@@ -37,208 +32,208 @@
     </div>
 </template>
 <script>
-    export default {
-        props: {
-            searchOption: {
-                type: Object,
-                default() {
-                    return {
-                        city: '全国',
-                        citylimit: false
-                    }
-                }
-            },
-            center: {
-                type: Array
+export default {
+    props: {
+        searchOption: {
+            type: Object,
+            default() {
+                return {
+                    city: '全国',
+                    citylimit: false,
+                };
             },
-            zoom: {
-                type: Number,
-                default: 15
-            },
-            value: {
-                type: Array
-            }
         },
-        data() {
-            let self = this;
-            return {
-                locating: false,
-                myPosition: null,
-                marker: null,
-                mapEvents: {
-                    complete() {
-                        self.$refs.map.$$getInstance().setDefaultCursor('default')
-                    },
-                    click(e) {
-                        self.marker = [e.lnglat.O, e.lnglat.P];
-                        self.mapCenter = [e.lnglat.O, e.lnglat.P];
-                        self.getGeolocation();
-                    }
+        center: {
+            type: Array,
+        },
+        zoom: {
+            type: Number,
+            default: 15,
+        },
+        value: {
+            type: Array,
+        },
+    },
+    data() {
+        let self = this;
+        return {
+            locating: false,
+            myPosition: null,
+            marker: null,
+            mapEvents: {
+                complete() {
+                    self.$refs.map.$$getInstance().setDefaultCursor('default');
                 },
-                markerEvents: {
-                    dragend(e) {
-                        self.marker = [e.lnglat.O, e.lnglat.P];
-                        self.mapCenter = [e.lnglat.O, e.lnglat.P];
-                        self.getGeolocation();
-                    }
+                click(e) {
+                    self.marker = [e.lnglat.O, e.lnglat.P];
+                    self.mapCenter = [e.lnglat.O, e.lnglat.P];
+                    self.getGeolocation();
                 },
-                mapCenter: [121.480342, 31.236339]
-            }
+            },
+            markerEvents: {
+                dragend(e) {
+                    self.marker = [e.lnglat.O, e.lnglat.P];
+                    self.mapCenter = [e.lnglat.O, e.lnglat.P];
+                    self.getGeolocation();
+                },
+            },
+            mapCenter: [121.480342, 31.236339],
+        };
+    },
+    created() {
+        if (this.center) {
+            this.mapCenter = this.center;
+        }
+        if (this.value) {
+            this.mapCenter = this.value;
+            this.marker = this.value;
+        }
+    },
+    methods: {
+        locate() {
+            this.locating = true;
+            let geolocation = new AMap.Geolocation({
+                enableHighAccuracy: true,
+                timeout: 10000,
+            });
+            geolocation.getCurrentPosition();
+            AMap.event.addListener(geolocation, 'complete', (data) => {
+                this.locating = false;
+                this.mapCenter = [data.position.O, data.position.P];
+                this.myPosition = [data.position.O, data.position.P];
+            });
+            AMap.event.addListener(geolocation, 'error', (err) => {
+                this.locating = false;
+                console.log(err);
+            });
         },
-        created() {
-            if (this.center) {
-                this.mapCenter = this.center;
-            }
-            if (this.value) {
-                this.mapCenter = this.value;
-                this.marker = this.value;
+        onSearchResult(pois) {
+            let latSum = 0;
+            let lngSum = 0;
+            if (pois.length > 0) {
+                pois.forEach((poi) => {
+                    let { lng, lat } = poi;
+                    lngSum += lng;
+                    latSum += lat;
+                });
+                let center = {
+                    lng: lngSum / pois.length,
+                    lat: latSum / pois.length,
+                };
+                this.mapCenter = [center.lng, center.lat];
             }
         },
-        methods: {
-            locate() {
-                this.locating = true;
-                let geolocation = new AMap.Geolocation({
-                    enableHighAccuracy: true,
-                    timeout: 10000,
-                });
-                geolocation.getCurrentPosition();
-                AMap.event.addListener(geolocation, 'complete', data => {
-                    this.locating = false;
-                    this.mapCenter = [data.position.O, data.position.P];
-                    this.myPosition = [data.position.O, data.position.P];
-                });
-                AMap.event.addListener(geolocation, 'error', err => {
-                    this.locating = false;
-                    console.log(err)
+        setZoom(d) {
+            this.$refs.map.$$getInstance().setZoom(this.$refs.map.$$getInstance().getZoom() + d);
+        },
+        getGeolocation() {
+            let lnglat = this.marker;
+            AMap.plugin('AMap.Geocoder', () => {
+                let geocoder = new AMap.Geocoder();
+                geocoder.getAddress(lnglat, (status, result) => {
+                    if (status === 'complete' && result.info === 'OK') {
+                        this.$emit('selected', {
+                            lnglat: {
+                                lng: lnglat[0],
+                                lat: lnglat[1],
+                            },
+                            ...result.regeocode,
+                        });
+                    }
                 });
-            },
-            onSearchResult(pois) {
-                let latSum = 0;
-                let lngSum = 0;
-                if (pois.length > 0) {
-                    pois.forEach(poi => {
-                        let {lng, lat} = poi;
-                        lngSum += lng;
-                        latSum += lat;
-                    });
-                    let center = {
-                        lng: lngSum / pois.length,
-                        lat: latSum / pois.length
-                    };
-                    this.mapCenter = [center.lng, center.lat];
-                }
-            },
-            setZoom(d) {
-                this.$refs.map.$$getInstance().setZoom(this.$refs.map.$$getInstance().getZoom() + d)
-            },
-            getGeolocation() {
-                let lnglat = this.marker;
-                AMap.plugin('AMap.Geocoder', () => {
-                    let geocoder = new AMap.Geocoder();
-                    geocoder.getAddress(lnglat, (status, result) => {
-                        if (status === 'complete' && result.info === 'OK') {
-                            this.$emit('selected', {
-                                lnglat: {
-                                    lng: lnglat[0],
-                                    lat: lnglat[1]
-                                },
-                                ...result.regeocode
-                            })
-                        }
-                    })
-                })
-            }
+            });
         },
-        watch: {
-            value(val) {
-                this.mapCenter = val;
-                this.marker = val;
-            }
-        }
-    }
+    },
+    watch: {
+        value(val) {
+            this.mapCenter = val;
+            this.marker = val;
+        },
+    },
+};
 </script>
 <style lang="less" scoped>
-    .map-wrapper {
-        position: relative;
-        .map-view {
-            width: 100%;
-            height: 400px;
-        }
-        .btn-locate {
-            width: 30px;
-            height: 30px;
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            font-size: 16px;
-            color: #666;
-            position: absolute;
-            left: 10px;
-            bottom: 10px;
-            background: #fff;
-            border-radius: 2px;
-            box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.3);
-            &:active {
-                background: #f2f3f4;
-            }
-        }
-        .btn-minus {
-            width: 30px;
-            height: 30px;
-            font-size: 16px;
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            color: #666;
-            position: absolute;
-            left: 10px;
-            bottom: 50px;
-            background: #fff;
-            border-radius: 2px;
-            box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.3);
-            &:active {
-                background: #f2f3f4;
-            }
+.map-wrapper {
+    position: relative;
+    .map-view {
+        width: 100%;
+        height: 400px;
+    }
+    .btn-locate {
+        width: 30px;
+        height: 30px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        font-size: 16px;
+        color: #666;
+        position: absolute;
+        left: 10px;
+        bottom: 10px;
+        background: #fff;
+        border-radius: 2px;
+        box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.3);
+        &:active {
+            background: #f2f3f4;
         }
-        .btn-plus {
-            width: 30px;
-            height: 30px;
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            font-size: 16px;
-            color: #666;
-            position: absolute;
-            left: 10px;
-            bottom: 90px;
-            background: #fff;
-            border-radius: 2px;
-            box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.3);
-            &:active {
-                background: #f2f3f4;
-            }
+    }
+    .btn-minus {
+        width: 30px;
+        height: 30px;
+        font-size: 16px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        color: #666;
+        position: absolute;
+        left: 10px;
+        bottom: 50px;
+        background: #fff;
+        border-radius: 2px;
+        box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.3);
+        &:active {
+            background: #f2f3f4;
         }
-        .search-box {
-            position: absolute;
-            top: 10px;
-            left: 10px;
+    }
+    .btn-plus {
+        width: 30px;
+        height: 30px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        font-size: 16px;
+        color: #666;
+        position: absolute;
+        left: 10px;
+        bottom: 90px;
+        background: #fff;
+        border-radius: 2px;
+        box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.3);
+        &:active {
+            background: #f2f3f4;
         }
     }
+    .search-box {
+        position: absolute;
+        top: 10px;
+        left: 10px;
+    }
+}
 </style>
 <style lang="less">
-    .anchorBL,
-    .amap-logo,
-    .amap-copyright {
-        display: none !important;
-    }
+.anchorBL,
+.amap-logo,
+.amap-copyright {
+    display: none !important;
+}
 
-    .my-position {
-        width: 14px;
-        height: 14px;
-        border-radius: 50%;
-        border: 3px solid #fff;
-        background: #20A0FF;
-        box-shadow: 0 2px 2px rgba(0, 0, 0, .15);
-        position: relative;
-    }
+.my-position {
+    width: 14px;
+    height: 14px;
+    border-radius: 50%;
+    border: 3px solid #fff;
+    background: #20a0ff;
+    box-shadow: 0 2px 2px rgba(0, 0, 0, 0.15);
+    position: relative;
+}
 </style>

+ 27 - 22
src/main/vue/src/components/CropUpload.vue

@@ -1,32 +1,37 @@
 <template>
     <div>
         <div id="upload-wrapper" class="upload-wrapper">
-            <img v-if="src" :src="src">
+            <img v-if="src" :src="src" />
             <i v-else class="el-icon-plus avatar-uploader-icon"></i>
-            <div v-if="loading" class="loading"><i class="el-icon-loading"></i>
-            </div>
+            <div v-if="loading" class="loading"><i class="el-icon-loading"></i></div>
         </div>
-        <avatar-cropper ref="cropper" @submit="loading=true"
-            @uploaded="handleUploaded" trigger="#upload-wrapper"
-            :cropper-options="cropperOptions" :output-options="outputOptions"
-            :upload-url="$baseUrl+'/upload/file'"
-            :labels="{submit: '确定',cancel: '取消'}" :upload-headers="headers" />
+        <avatar-cropper
+            ref="cropper"
+            @submit="loading = true"
+            @uploaded="handleUploaded"
+            trigger="#upload-wrapper"
+            :cropper-options="cropperOptions"
+            :output-options="outputOptions"
+            :upload-url="$baseUrl + '/upload/file'"
+            :labels="{ submit: '确定', cancel: '取消' }"
+            :upload-headers="headers"
+        />
     </div>
 </template>
 <script>
-import AvatarCropper from "vue-avatar-cropper";
+import AvatarCropper from 'vue-avatar-cropper';
 
 export default {
     props: {
         value: {},
         width: {
             type: Number,
-            default: 350
+            default: 350,
         },
         height: {
             type: Number,
-            default: 350
-        }
+            default: 350,
+        },
     },
     created() {
         if (this.value) {
@@ -41,38 +46,38 @@ export default {
     },
     data() {
         return {
-            src: "",
+            src: '',
             cropperOptions: {
-                aspectRatio: 1
+                aspectRatio: 1,
             },
             loading: false,
             headers: {
-                Authorization: "Bearer " + localStorage.getItem("token")
-            }
+                Authorization: 'Bearer ' + localStorage.getItem('token'),
+            },
         };
     },
     computed: {
         outputOptions() {
             return { width: this.width, height: this.height };
-        }
+        },
     },
     watch: {
         value() {
             if (this.value) {
                 this.src = this.value;
             }
-        }
+        },
     },
     methods: {
         handleUploaded(res) {
             this.loading = false;
             this.src = res;
-            this.$emit("input", res);
-        }
+            this.$emit('input', res);
+        },
     },
     components: {
-        AvatarCropper
-    }
+        AvatarCropper,
+    },
 };
 </script>
 <style lang="less" scoped>

+ 77 - 47
src/main/vue/src/components/DynamicForm.vue

@@ -1,16 +1,50 @@
 <template>
     <el-form :model="formData" ref="form" label-position="right" label-width="100px" :size="size" :rules="rules">
-        <el-form-item v-for="item in formDef" :prop="item.id" :label="item.name" :key="item.id" v-if="item.readable">
-            <el-input v-if="item.type === 'string'" v-model="formData[item.id]" :disabled="!item.writable" class="form-item"></el-input>
-            <el-select ref="select" v-else-if="item.type === 'enum'" :value="formData[item.id]" @input="valueChange($event, item.id)" :disabled="!item.writable" class="form-item">
-                <el-option v-for="(option,index) in item.enumValues" :label="option.name" :value="option.id" :key="index">
-                </el-option>
-            </el-select>
-            <el-date-picker v-else-if="item.type === 'date'" type="datetime" :value="formData[item.id]" @input="valueChange($event, item.id)" :format="item.datePattern" :value-format="item.datePattern" :disabled="!item.writable" class="form-item">
-            </el-date-picker>
-            <el-switch v-else-if="item.type === 'boolean'" :value="formData[item.id]" @input="valueChange($event, item.id)" :disabled="!item.writable" class="form-item">
-            </el-switch>
-        </el-form-item>
+        <template v-if="item.readable">
+            <el-form-item v-for="item in formDef" :prop="item.id" :label="item.name" :key="item.id">
+                <el-input
+                    v-if="item.type === 'string'"
+                    v-model="formData[item.id]"
+                    :disabled="!item.writable"
+                    class="form-item"
+                ></el-input>
+                <el-select
+                    ref="select"
+                    v-else-if="item.type === 'enum'"
+                    :value="formData[item.id]"
+                    @input="valueChange($event, item.id)"
+                    :disabled="!item.writable"
+                    class="form-item"
+                >
+                    <el-option
+                        v-for="(option, index) in item.enumValues"
+                        :label="option.name"
+                        :value="option.id"
+                        :key="index"
+                    >
+                    </el-option>
+                </el-select>
+                <el-date-picker
+                    v-else-if="item.type === 'date'"
+                    type="datetime"
+                    :value="formData[item.id]"
+                    @input="valueChange($event, item.id)"
+                    :format="item.datePattern"
+                    :value-format="item.datePattern"
+                    :disabled="!item.writable"
+                    class="form-item"
+                >
+                </el-date-picker>
+                <el-switch
+                    v-else-if="item.type === 'boolean'"
+                    :value="formData[item.id]"
+                    @input="valueChange($event, item.id)"
+                    :disabled="!item.writable"
+                    class="form-item"
+                >
+                </el-switch>
+            </el-form-item>
+        </template>
         <slot></slot>
     </el-form>
 </template>
@@ -19,78 +53,76 @@ export default {
     props: {
         formProps: {
             type: Array,
-            required: true
+            required: true,
         },
         value: {
-            type: Object
+            type: Object,
         },
         size: {
             type: String,
-            default: 'small'
-        }
+            default: 'small',
+        },
     },
     created() {
-        console.log('created', this.formProps)
-        this.updateForm(this.formProps)
+        console.log('created', this.formProps);
+        this.updateForm(this.formProps);
     },
     data() {
         return {
             formData: {},
-            formDef: []
-        }
+            formDef: [],
+        };
     },
     computed: {
         rules() {
             let rules = {};
-            this.formDef.forEach(item => {
-                rules[item.id] = [{ required: true, message: `请填写${item.name}`, trigger: 'blur' }]
+            this.formDef.forEach((item) => {
+                rules[item.id] = [{ required: true, message: `请填写${item.name}`, trigger: 'blur' }];
             });
             return rules;
-        }
+        },
     },
     methods: {
         validate(fn) {
-            this.$refs.form.validate(valid => {
+            this.$refs.form.validate((valid) => {
                 if (fn instanceof Function) {
-                    fn(valid)
+                    fn(valid);
                 }
-            })
+            });
         },
         clearValidate() {
-            this.$refs.form.clearValidate()
+            this.$refs.form.clearValidate();
         },
         getData(all) {
             let data = [];
-            this.formDef.forEach(i => {
+            this.formDef.forEach((i) => {
                 if (i.writable || all) {
                     if (this.formData[i.id]) {
                         data.push({
                             id: i.id,
-                            value: this.formData[i.id]
-                        })
+                            value: this.formData[i.id],
+                        });
                     }
                 }
-            })
+            });
             return data;
         },
         updateForm(props) {
             try {
                 this.$refs.form.clearValidate();
-            } catch (error) {
-
-            }
-            props.forEach(i => {
-                this.formData[i.id] = i.value || null
+            } catch (error) {}
+            props.forEach((i) => {
+                this.formData[i.id] = i.value || null;
             });
             this.formDef = this.formProps;
         },
         valueChange(val, id) {
             let formData = {
-                ...this.formData
-            }
-            formData[id] = val
-            this.formData = formData
-        }
+                ...this.formData,
+            };
+            formData[id] = val;
+            this.formData = formData;
+        },
     },
     watch: {
         formProps(val) {
@@ -100,20 +132,18 @@ export default {
             if (val instanceof Object) {
                 //this.formData = val
                 for (let key in val) {
-                    this.formData[key] = val[key]
+                    this.formData[key] = val[key];
                 }
             }
         },
         formData(val) {
-            this.$emit('input', val)
-        }
-    }
-}
+            this.$emit('input', val);
+        },
+    },
+};
 </script>
 <style lang="less" scoped>
 .form-item {
     width: 100%;
 }
 </style>
-
-

+ 69 - 77
src/main/vue/src/components/FileUpload.vue

@@ -1,98 +1,90 @@
 <template>
     <el-upload
-            class="upload-demo"
-            :action="$baseUrl + '/upload/file'"
-            :on-success="onSuccess"
-            :on-remove="onRemove"
-            :headers="headers"
-            :file-list="fileList"
+        class="upload-demo"
+        :action="$baseUrl + '/upload/file'"
+        :on-success="onSuccess"
+        :on-remove="onRemove"
+        :headers="headers"
+        :file-list="fileList"
     >
-        <el-button
-                type="primary"
-                :disabled="!(!single || fileList.length === 0)"
-                size="mini"
-        >点击上传
-        </el-button>
+        <el-button type="primary" :disabled="!(!single || fileList.length === 0)" size="mini">点击上传 </el-button>
     </el-upload>
 </template>
 
 <script>
-    import resolveUrl from "resolve-url";
-    export default {
-        name: "FileUpload",
-        props: {
-            single: {
-                type: Boolean,
-                default() {
-                    return false;
-                }
+import resolveUrl from 'resolve-url';
+export default {
+    name: 'FileUpload',
+    props: {
+        single: {
+            type: Boolean,
+            default() {
+                return false;
             },
-            value: {}
         },
-        data() {
+        value: {},
+    },
+    data() {
+        return {
+            fileList: [],
+            watchValue: true,
+        };
+    },
+    computed: {
+        headers() {
             return {
-                fileList: [],
-                watchValue: true
+                Authorization: 'Bearer ' + localStorage.getItem('token'),
             };
         },
-        computed: {
-            headers() {
-                return {
-                    Authorization: "Bearer " + localStorage.getItem("token")
-                };
-            }
+    },
+    created() {
+        this.uploadUrl = resolveUrl(this.$baseUrl, 'upload/file');
+        this.update(this.value);
+    },
+    methods: {
+        onSuccess(res, file, fileList) {
+            file.url = res;
+            this.fileList = fileList;
         },
-        created() {
-            this.uploadUrl = resolveUrl(this.$baseUrl, "upload/file");
-            this.update(this.value);
+        onRemove(file, fileList) {
+            this.fileList = fileList;
         },
-        methods: {
-            onSuccess(res, file, fileList) {
-                file.url = res;
-                this.fileList = fileList;
-            },
-            onRemove(file, fileList) {
-                this.fileList = fileList;
-            },
-            update(value) {
-                if (this.single) {
-                    this.fileList = value
-                        ? [{ name: value.split("/").pop(), url: value }]
-                        : [];
+        update(value) {
+            if (this.single) {
+                this.fileList = value ? [{ name: value.split('/').pop(), url: value }] : [];
+            } else {
+                if (!value) {
+                    this.fileList = [];
                 } else {
-                    if (!value) {
-                        this.fileList = [];
-                    } else {
-                        this.fileList = value.map(i => {
-                            return { name: i.split("/").pop(), url: i };
-                        });
-                    }
+                    this.fileList = value.map((i) => {
+                        return { name: i.split('/').pop(), url: i };
+                    });
                 }
             }
         },
-        watch: {
-            value(oldValue, value) {
-                if (!this.watchValue) return;
-                console.log("watch::");
-                this.update(value);
-            },
-            fileList(fileList) {
-                this.watchValue = false;
-                if (this.single) {
-                    this.$emit("input", fileList[0] ? fileList[0].url : null);
-                } else {
-                    this.$emit(
-                        "input",
-                        fileList.map(i => i.url)
-                    );
-                }
-                this.$nextTick(() => {
-                    this.watchValue = true;
-                });
+    },
+    watch: {
+        value(oldValue, value) {
+            if (!this.watchValue) return;
+            console.log('watch::');
+            this.update(value);
+        },
+        fileList(fileList) {
+            this.watchValue = false;
+            if (this.single) {
+                this.$emit('input', fileList[0] ? fileList[0].url : null);
+            } else {
+                this.$emit(
+                    'input',
+                    fileList.map((i) => i.url)
+                );
             }
-        }
-    };
+            this.$nextTick(() => {
+                this.watchValue = true;
+            });
+        },
+    },
+};
 </script>
 
-<style scoped>
-</style>
+<style scoped></style>

+ 29 - 30
src/main/vue/src/components/GenOptionsDialog.vue

@@ -2,17 +2,17 @@
     <el-dialog title="编辑选项" :visible.sync="show" width="500px">
         <el-table :data="options">
             <el-table-column label="名称" prop="label">
-                <template slot-scope="{row}">
+                <template slot-scope="{ row }">
                     <el-input v-model="row.label"></el-input>
                 </template>
             </el-table-column>
             <el-table-column label="值" prop="value">
-                <template slot-scope="{row}">
+                <template slot-scope="{ row }">
                     <el-input v-model="row.value"></el-input>
                 </template>
             </el-table-column>
             <el-table-column label="类型">
-                <template slot-scope="{row}">
+                <template slot-scope="{ row }">
                     <el-select v-model="row.type">
                         <el-option label="字符串" value="string"></el-option>
                         <el-option label="数字" value="number"></el-option>
@@ -21,7 +21,7 @@
                 </template>
             </el-table-column>
             <el-table-column>
-                <template slot-scope="{$index}">
+                <template slot-scope="{ $index }">
                     <el-button @click="del($index)" type="text">删除</el-button>
                 </template>
             </el-table-column>
@@ -36,13 +36,13 @@
 
 <script>
 export default {
-    name: "GenOptionsDialog",
+    name: 'GenOptionsDialog',
     props: {
         visible: {
             required: true,
-            type: Boolean
+            type: Boolean,
         },
-        value: {}
+        value: {},
     },
     created() {
         this.show = this.visible;
@@ -53,25 +53,25 @@ export default {
             show: false,
             options: [
                 {
-                    label: "",
-                    value: "",
-                    type: "string"
-                }
-            ]
+                    label: '',
+                    value: '',
+                    type: 'string',
+                },
+            ],
         };
     },
     methods: {
         update() {
             if (this.value) {
                 let arr = [];
-                JSON.parse(this.value).forEach(item => {
+                JSON.parse(this.value).forEach((item) => {
                     let value = item.value.toString(),
                         type = typeof item.value,
                         label = item.label;
                     arr.push({
                         label,
                         value,
-                        type
+                        type,
                     });
                 });
                 this.options = arr;
@@ -86,48 +86,47 @@ export default {
                 let label = this.options[i].label;
                 let value;
                 switch (this.options[i].type) {
-                    case "string":
+                    case 'string':
                         value = this.options[i].value.toString();
                         break;
-                    case "number":
+                    case 'number':
                         value = Number(this.options[i].value);
                         break;
-                    case "boolean":
-                        value = "false" !== this.options[i].value;
+                    case 'boolean':
+                        value = 'false' !== this.options[i].value;
                         break;
                 }
                 arr.push({
                     label: label,
-                    value: value
+                    value: value,
                 });
             }
-            this.$emit("input", JSON.stringify(arr));
-            this.$emit("update:visible", false);
+            this.$emit('input', JSON.stringify(arr));
+            this.$emit('update:visible', false);
         },
         add() {
             this.options.push({
-                label: "",
-                value: "",
-                type: "string"
+                label: '',
+                value: '',
+                type: 'string',
             });
         },
         del(index) {
             this.options.splice(index, 1);
-        }
+        },
     },
     watch: {
         visible(val) {
             this.show = val;
         },
         show(val) {
-            this.$emit("update:visible", val);
+            this.$emit('update:visible', val);
         },
         value() {
             this.update();
-        }
-    }
+        },
+    },
 };
 </script>
 
-<style scoped>
-</style>
+<style scoped></style>

+ 95 - 86
src/main/vue/src/components/JsonView.vue

@@ -2,99 +2,108 @@
     <el-tree :data="treeData" :render-content="renderContent" :expand-on-click-node="false" class="json-view"></el-tree>
 </template>
 <script>
-    export default {
-        name: 'jsonView',
-        created() {
-            this.parseTreeData();
-        },
-        props: {
-            json: {
-                type: [Object, Array],
-                required: true
-            },
-            rootKey: {
-                type: String,
-                default: "root"
-            },
+export default {
+    name: 'jsonView',
+    created() {
+        this.parseTreeData();
+    },
+    props: {
+        json: {
+            type: [Object, Array],
+            required: true,
         },
-        data() {
-            return {
-                treeData: []
-            }
+        rootKey: {
+            type: String,
+            default: 'root',
         },
-        methods: {
-            parseTreeData() {
-                let id = 0;
-                const parse = obj => {
-                    let root = [];
-                    if (obj instanceof Object) {
-                        for (let key in obj) {
-                            if (obj[key] instanceof Array) {
-                                root.push({
-                                    id: ++id,
-                                    label: key + ': Array[' + obj[key].length + ']',
-                                    children: parse(obj[key])
-                                })
-                            } else if (obj[key] instanceof Object) {
-                                root.push({
-                                    id: ++id,
-                                    label: key + ': Object',
-                                    children: parse(obj[key])
-                                })
-                            } else {
-                                root.push({
-                                    id: ++id,
-                                    label: key + ': ' + obj[key]
-                                })
-                            }
+    },
+    data() {
+        return {
+            treeData: [],
+        };
+    },
+    methods: {
+        parseTreeData() {
+            let id = 0;
+            const parse = (obj) => {
+                let root = [];
+                if (obj instanceof Object) {
+                    for (let key in obj) {
+                        if (obj[key] instanceof Array) {
+                            root.push({
+                                id: ++id,
+                                label: key + ': Array[' + obj[key].length + ']',
+                                children: parse(obj[key]),
+                            });
+                        } else if (obj[key] instanceof Object) {
+                            root.push({
+                                id: ++id,
+                                label: key + ': Object',
+                                children: parse(obj[key]),
+                            });
+                        } else {
+                            root.push({
+                                id: ++id,
+                                label: key + ': ' + obj[key],
+                            });
                         }
-                    } else if (obj instanceof Array) {
-                        for (let i = 0; i < obj.length; i++) {
-                            if (obj[i] instanceof Array) {
-                                root.push({
-                                    id: ++id,
-                                    label: i + ': Array[' + obj[i].length + ']',
-                                    children: parse(obj[i])
-                                })
-                            } else if (obj[i] instanceof Object) {
-                                root.push({
-                                    id: ++id,
-                                    label: i + ': Object',
-                                    children: parse(obj[i])
-                                })
-                            } else {
-                                root.push({
-                                    id: ++id,
-                                    label: i + ': ' + obj[i]
-                                })
-                            }
+                    }
+                } else if (obj instanceof Array) {
+                    for (let i = 0; i < obj.length; i++) {
+                        if (obj[i] instanceof Array) {
+                            root.push({
+                                id: ++id,
+                                label: i + ': Array[' + obj[i].length + ']',
+                                children: parse(obj[i]),
+                            });
+                        } else if (obj[i] instanceof Object) {
+                            root.push({
+                                id: ++id,
+                                label: i + ': Object',
+                                children: parse(obj[i]),
+                            });
+                        } else {
+                            root.push({
+                                id: ++id,
+                                label: i + ': ' + obj[i],
+                            });
                         }
                     }
-                    return root;
-                };
-                this.treeData = parse(this.json);
-            },
-            renderContent(h, {node, data, store}) {
-                return h('span', {
-                    class: 'json-view-content'
-                }, [h('span', {class: 'json-view-content-key'}, [data.label.split(':')[0]]), ":", data.label.split(':')[1]]);
-            }
+                }
+                return root;
+            };
+            this.treeData = parse(this.json);
+        },
+        renderContent(h, { node, data, store }) {
+            return h(
+                'span',
+                {
+                    class: 'json-view-content',
+                },
+                [
+                    h('span', { class: 'json-view-content-key' }, [data.label.split(':')[0]]),
+                    ':',
+                    data.label.split(':')[1],
+                ]
+            );
+        },
+    },
+    watch: {
+        json() {
+            this.parseTreeData();
         },
-        watch: {
-            json() {
-                this.parseTreeData();
-            }
-        }
-    }
+    },
+};
 </script>
 <style>
-    .json-view .json-view-content {
-        cursor: text !important;
-        font-family: "dejavu sans mono", "droid sans mono", consolas, monaco, "lucida console", "courier new", courier, monospace, sans-serif;
-        font-size: 13px !important;
-    }
+.json-view .json-view-content {
+    cursor: text !important;
+    font-family: 'dejavu sans mono', 'droid sans mono', consolas, monaco, 'lucida console', 'courier new', courier,
+        monospace, sans-serif;
+    font-size: 13px !important;
+}
 
-    .json-view .json-view-content .json-view-content-key {
-        color: #409EFF;
-    }
+.json-view .json-view-content .json-view-content-key {
+    color: #409eff;
+}
 </style>

+ 24 - 19
src/main/vue/src/components/Line.vue

@@ -1,42 +1,47 @@
 <template>
     <div>
-        <canvas ref="chart" :height="height" style="margin: auto;" ></canvas>
+        <canvas ref="chart" :height="height" style="margin: auto;"></canvas>
     </div>
 </template>
 <script>
-import VueCharts from 'vue-chartjs'
-import { Line, Bar } from 'vue-chartjs'
+import VueCharts from 'vue-chartjs';
+import { Line, Bar } from 'vue-chartjs';
 export default {
     name: 'line',
     props: ['chartData', 'options', 'width', 'height'],
     watch: {
         chartData() {
             if (this.myChart) {
-                this.myChart.update()
+                this.myChart.update();
+            } else {
+                this.myChart = new Chart(this.$refs.chart.getContext('2d'), {
+                    type: 'line',
+                    data: this.chartData,
+                    options: this.options,
+                });
             }
-            else {
-                this.myChart = new Chart(this.$refs.chart.getContext('2d'), { type: 'line', data: this.chartData, options: this.options })
-            }
-        }
+        },
     },
     data() {
         return {
-            myChart: null
-        }
+            myChart: null,
+        };
     },
     mounted() {
-        console.log(this.type)
+        console.log(this.type);
         if (this.chartData) {
-            this.myChart = new Chart(this.$refs.chart.getContext('2d'), { type: 'line', data: this.chartData, options: this.options })
+            this.myChart = new Chart(this.$refs.chart.getContext('2d'), {
+                type: 'line',
+                data: this.chartData,
+                options: this.options,
+            });
         }
-
     },
     methods: {
         updateChart() {
-            this.myChart.update()
-        }
-    }
-}
+            this.myChart.update();
+        },
+    },
+};
 </script>
-<style lang="less" scoped>
-</style>
+<style lang="less" scoped></style>

+ 24 - 19
src/main/vue/src/components/LineBarChart.vue

@@ -1,42 +1,47 @@
 <template>
     <div>
-        <canvas ref="chart" style="margin: auto"></canvas>
+        <canvas ref="chart" style="margin: auto;"></canvas>
     </div>
 </template>
 <script>
-import VueCharts from 'vue-chartjs'
-import { Line, Bar } from 'vue-chartjs'
+import VueCharts from 'vue-chartjs';
+import { Line, Bar } from 'vue-chartjs';
 export default {
     name: 'lineBarChart',
     props: ['chartData', 'options', 'width', 'height', 'type'],
     watch: {
         chartData() {
             if (this.myChart) {
-                this.myChart.update()
+                this.myChart.update();
+            } else {
+                this.myChart = new Chart(this.$refs.chart.getContext('2d'), {
+                    type: this.type,
+                    data: this.chartData,
+                    options: this.options,
+                });
             }
-            else {
-                this.myChart = new Chart(this.$refs.chart.getContext('2d'), { type: this.type, data: this.chartData, options: this.options })
-            }
-        }
+        },
     },
     data() {
         return {
-            myChart: null
-        }
+            myChart: null,
+        };
     },
     mounted() {
-        console.log(this.type)
+        console.log(this.type);
         if (this.chartData) {
-            this.myChart = new Chart(this.$refs.chart.getContext('2d'), { type: this.type, data: this.chartData, options: this.options })
+            this.myChart = new Chart(this.$refs.chart.getContext('2d'), {
+                type: this.type,
+                data: this.chartData,
+                options: this.options,
+            });
         }
-
     },
     methods: {
         updateChart() {
-            this.myChart.update()
-        }
-    }
-}
+            this.myChart.update();
+        },
+    },
+};
 </script>
-<style lang="less" scoped>
-</style>
+<style lang="less" scoped></style>

+ 45 - 33
src/main/vue/src/components/MultiUpload.vue

@@ -1,9 +1,15 @@
 <template>
     <section>
-        <el-upload list-type="picture-card" :action="uploadUrl"
-            :headers="headers" :on-preview="handlePictureCardPreview"
-            :on-remove="handleRemove" :on-success="handleSuccess"
-            :file-list="fileList" multiple>
+        <el-upload
+            list-type="picture-card"
+            :action="uploadUrl"
+            :headers="headers"
+            :on-preview="handlePictureCardPreview"
+            :on-remove="handleRemove"
+            :on-success="handleSuccess"
+            :file-list="fileList"
+            multiple
+        >
             <i class="el-icon-plus"></i>
             <div slot="tip" class="el-upload__tip">
                 <slot></slot>
@@ -12,54 +18,61 @@
         <el-dialog :visible.sync="dialogVisible">
             <img width="100%" :src="dialogImageUrl" alt />
         </el-dialog>
-        <el-image style="width: 0; height: 0; position: absolute;" ref="preview"
-            :src="previewUrl" :preview-src-list="previewList">
+        <el-image
+            style="width: 0; height: 0; position: absolute;"
+            ref="preview"
+            :src="previewUrl"
+            :preview-src-list="previewList"
+        >
         </el-image>
     </section>
 </template>
 <script>
-import resolveUrl from "resolve-url";
+import resolveUrl from 'resolve-url';
 export default {
     created() {
-        this.uploadUrl = resolveUrl(this.$baseUrl, "upload/file");
+        this.uploadUrl = resolveUrl(this.$baseUrl, 'upload/file');
         this.updateFileList(this.value);
     },
     props: {
         value: Array,
         usePrefix: {
             type: Boolean,
-            default: true
+            default: true,
         },
         url: {
-            type: String
-        }
+            type: String,
+        },
     },
     data() {
         return {
-            dialogImageUrl: "",
+            dialogImageUrl: '',
             dialogVisible: false,
             fileList: [],
-            uploadUrl: "",
+            uploadUrl: '',
             realFileList: [],
-            previewUrl: "",
-            previewList: []
+            previewUrl: '',
+            previewList: [],
         };
     },
     computed: {
         headers() {
             return {
-                Authorization: "Bearer " + localStorage.getItem("token")
+                Authorization: 'Bearer ' + localStorage.getItem('token'),
             };
-        }
+        },
     },
     methods: {
         handleRemove(file, fileList) {
             this.realFileList = fileList;
-            this.$emit("input", fileList.map(i => i.value));
+            this.$emit(
+                'input',
+                fileList.map((i) => i.value)
+            );
         },
         handlePictureCardPreview(file) {
             this.previewUrl = file.value;
-            this.previewList = this.fileList.map(i => i.value);
+            this.previewList = this.fileList.map((i) => i.value);
             console.log(this.$refs.preview.$el);
             this.$refs.preview.showViewer = true;
         },
@@ -70,24 +83,27 @@ export default {
                 file.value = res;
             }
             this.realFileList = fileList;
-            this.$emit("input", fileList.map(i => i.value));
+            this.$emit(
+                'input',
+                fileList.map((i) => i.value)
+            );
         },
         updateFileList(list) {
             if (!list) {
                 list = [];
-            } else if (typeof list == "string") {
-                list = list.split(",");
+            } else if (typeof list == 'string') {
+                list = list.split(',');
             }
             for (let i = 0; i < list.length; i++) {
                 if (!this.fileList[i]) {
                     this.fileList[i] = {
                         value: list[i],
-                        url: list[i]
+                        url: list[i],
                     };
                 } else if (this.fileList[i].value !== list[i]) {
                     this.fileList[i] = {
                         value: list[i],
-                        url: list[i]
+                        url: list[i],
                     };
                 }
             }
@@ -98,20 +114,16 @@ export default {
             //         url: i,
             //     };
             // });
-        }
+        },
     },
     watch: {
         value(val, oldVal) {
-            if (
-                JSON.stringify(val) ==
-                JSON.stringify(this.realFileList.map(i => i.value))
-            ) {
+            if (JSON.stringify(val) == JSON.stringify(this.realFileList.map((i) => i.value))) {
                 return;
             }
             this.updateFileList(val);
-        }
-    }
+        },
+    },
 };
 </script>
-<style lang="less" scoped>
-</style>
+<style lang="less" scoped></style>

+ 23 - 18
src/main/vue/src/components/Pie.vue

@@ -1,41 +1,46 @@
 <template>
     <div>
-        <canvas ref="chart" :height="height" style="margin: auto" ></canvas>
+        <canvas ref="chart" :height="height" style="margin: auto;"></canvas>
     </div>
 </template>
 <script>
-import VueCharts from 'vue-chartjs'
-import { pie} from 'vue-chartjs'
+import VueCharts from 'vue-chartjs';
+import { pie } from 'vue-chartjs';
 export default {
     name: 'pie',
     props: ['chartData', 'options', 'width', 'height'],
     watch: {
         chartData() {
             if (this.myChart) {
-                this.myChart.update()
+                this.myChart.update();
+            } else {
+                this.myChart = new Chart(this.$refs.chart.getContext('2d'), {
+                    type: 'pie',
+                    data: this.chartData,
+                    options: this.options,
+                });
             }
-            else {
-                this.myChart = new Chart(this.$refs.chart.getContext('2d'), { type: 'pie', data: this.chartData, options: this.options })
-            }
-        }
+        },
     },
     data() {
         return {
-            myChart: null
-        }
+            myChart: null,
+        };
     },
     mounted() {
         if (this.chartData) {
-            this.myChart = new Chart(this.$refs.chart.getContext('2d'), { type: 'pie', data: this.chartData, options: this.options })
+            this.myChart = new Chart(this.$refs.chart.getContext('2d'), {
+                type: 'pie',
+                data: this.chartData,
+                options: this.options,
+            });
         }
-
     },
     methods: {
         updateChart() {
-            this.myChart.update()
-        }
-    }
-}
+            this.myChart.update();
+        },
+    },
+};
 </script>
-<style lang="less" scoped>
-</style>
+<style lang="less" scoped></style>

+ 23 - 19
src/main/vue/src/components/PolarArea.vue

@@ -1,42 +1,46 @@
 <template>
     <div>
-        <canvas ref="chart" :height="height" style="margin: auto"></canvas>
+        <canvas ref="chart" :height="height" style="margin: auto;"></canvas>
     </div>
 </template>
 <script>
-import VueCharts from 'vue-chartjs'
-import { PolarArea } from 'vue-chartjs'
+import VueCharts from 'vue-chartjs';
+import { PolarArea } from 'vue-chartjs';
 export default {
     name: 'polarArea',
     props: ['chartData', 'options', 'width', 'height'],
     watch: {
         chartData() {
             if (this.myChart) {
-                this.myChart.update()
+                this.myChart.update();
+            } else {
+                this.myChart = new Chart(this.$refs.chart.getContext('2d'), {
+                    type: 'polarArea',
+                    data: this.chartData,
+                    options: this.options,
+                });
             }
-            else {
-                this.myChart = new Chart(this.$refs.chart.getContext('2d'), { type: 'polarArea', data: this.chartData, options: this.options })
-            }
-        }
+        },
     },
     data() {
         return {
-            myChart: null
-        }
+            myChart: null,
+        };
     },
     mounted() {
-
         if (this.chartData) {
-            this.myChart = new Chart(this.$refs.chart.getContext('2d'), { type: 'polarArea', data: this.chartData, options: this.options })
+            this.myChart = new Chart(this.$refs.chart.getContext('2d'), {
+                type: 'polarArea',
+                data: this.chartData,
+                options: this.options,
+            });
         }
-
     },
     methods: {
         updateChart() {
-            this.myChart.update()
-        }
-    }
-}
+            this.myChart.update();
+        },
+    },
+};
 </script>
-<style lang="less" scoped>
-</style>
+<style lang="less" scoped></style>

+ 23 - 18
src/main/vue/src/components/Radar.vue

@@ -1,41 +1,46 @@
 <template>
     <div>
-        <canvas ref="chart" :height="height" style="margin: auto" ></canvas>
+        <canvas ref="chart" :height="height" style="margin: auto;"></canvas>
     </div>
 </template>
 <script>
-import VueCharts from 'vue-chartjs'
-import { radar} from 'vue-chartjs'
+import VueCharts from 'vue-chartjs';
+import { radar } from 'vue-chartjs';
 export default {
     name: 'radar',
     props: ['chartData', 'options', 'width', 'height'],
     watch: {
         chartData() {
             if (this.myChart) {
-                this.myChart.update()
+                this.myChart.update();
+            } else {
+                this.myChart = new Chart(this.$refs.chart.getContext('2d'), {
+                    type: 'radar',
+                    data: this.chartData,
+                    options: this.options,
+                });
             }
-            else {
-                this.myChart = new Chart(this.$refs.chart.getContext('2d'), { type: 'radar', data: this.chartData, options: this.options })
-            }
-        }
+        },
     },
     data() {
         return {
-            myChart: null
-        }
+            myChart: null,
+        };
     },
     mounted() {
         if (this.chartData) {
-            this.myChart = new Chart(this.$refs.chart.getContext('2d'), { type: 'radar', data: this.chartData, options: this.options })
+            this.myChart = new Chart(this.$refs.chart.getContext('2d'), {
+                type: 'radar',
+                data: this.chartData,
+                options: this.options,
+            });
         }
-
     },
     methods: {
         updateChart() {
-            this.myChart.update()
-        }
-    }
-}
+            this.myChart.update();
+        },
+    },
+};
 </script>
-<style lang="less" scoped>
-</style>
+<style lang="less" scoped></style>

+ 48 - 57
src/main/vue/src/components/RichText.vue

@@ -1,93 +1,84 @@
 <template>
-    <tinymce-editor
-        :init="init"
-        :value="value"
-        @input="onInput"
-    >
-    </tinymce-editor>
+    <tinymce-editor :init="init" :value="value" @input="onInput"> </tinymce-editor>
 </template>
 <script>
-import Editor from "@tinymce/tinymce-vue";
-import tinymce from "tinymce/tinymce";
-import "./zh_CN";
-import "tinymce/themes/silver";
-import "tinymce/plugins/advlist";
-import "tinymce/plugins/autolink";
-import "tinymce/plugins/lists";
-import "tinymce/plugins/link";
-import "tinymce/plugins/image";
-import "tinymce/plugins/charmap";
-import "tinymce/plugins/print";
-import "tinymce/plugins/preview";
-import "tinymce/plugins/anchor";
-import "tinymce/plugins/textcolor";
-import "tinymce/plugins/searchreplace";
-import "tinymce/plugins/visualblocks";
-import "tinymce/plugins/code";
-import "tinymce/plugins/fullscreen";
-import "tinymce/plugins/insertdatetime";
-import "tinymce/plugins/media";
-import "tinymce/plugins/table";
-import "tinymce/plugins/contextmenu";
-import "tinymce/plugins/paste";
-import "tinymce/plugins/code";
-import "tinymce/plugins/help";
-import "tinymce/plugins/imagetools";
-import "tinymce/skins/ui/oxide/skin.css";
+import Editor from '@tinymce/tinymce-vue';
+import tinymce from 'tinymce/tinymce';
+import './zh_CN';
+import 'tinymce/themes/silver';
+import 'tinymce/plugins/advlist';
+import 'tinymce/plugins/autolink';
+import 'tinymce/plugins/lists';
+import 'tinymce/plugins/link';
+import 'tinymce/plugins/image';
+import 'tinymce/plugins/charmap';
+import 'tinymce/plugins/print';
+import 'tinymce/plugins/preview';
+import 'tinymce/plugins/anchor';
+import 'tinymce/plugins/textcolor';
+import 'tinymce/plugins/searchreplace';
+import 'tinymce/plugins/visualblocks';
+import 'tinymce/plugins/code';
+import 'tinymce/plugins/fullscreen';
+import 'tinymce/plugins/insertdatetime';
+import 'tinymce/plugins/media';
+import 'tinymce/plugins/table';
+import 'tinymce/plugins/contextmenu';
+import 'tinymce/plugins/paste';
+import 'tinymce/plugins/code';
+import 'tinymce/plugins/help';
+import 'tinymce/plugins/imagetools';
+import 'tinymce/skins/ui/oxide/skin.css';
 
 export default {
-    props: ["value", "disabled"],
+    props: ['value', 'disabled'],
     created() {},
     data() {
         return {
             init: {
-                language: "zh_CN",
-                skin: "oxide-dark",
+                language: 'zh_CN',
+                skin: 'oxide-dark',
                 menubar: false,
                 branding: false,
                 statusbar: false,
                 height: 400,
                 toolbar:
-                    "undo redo | styleselect bold italic strikethrough forecolor backcolor  | image media link blockquote visualblocks insert | formatselect | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | removeformat | preview fullscreen code help",
+                    'undo redo | styleselect bold italic strikethrough forecolor backcolor  | image media link blockquote visualblocks insert | formatselect | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | removeformat | preview fullscreen code help',
                 plugins: [
-                    "advlist autolink lists link image charmap print preview anchor textcolor",
-                    "searchreplace visualblocks code fullscreen",
-                    "insertdatetime media table contextmenu paste code help imagetools"
+                    'advlist autolink lists link image charmap print preview anchor textcolor',
+                    'searchreplace visualblocks code fullscreen',
+                    'insertdatetime media table contextmenu paste code help imagetools',
                 ],
-                images_upload_url: this.$baseUrl + "/upload/file",
+                images_upload_url: this.$baseUrl + '/upload/file',
                 images_upload_handler: (blobInfo, success, failure) => {
                     let formData = new FormData();
-                    formData.append(
-                        "file",
-                        blobInfo.blob(),
-                        blobInfo.filename()
-                    );
+                    formData.append('file', blobInfo.blob(), blobInfo.filename());
                     this.$axios
-                        .post("/upload/file", formData)
-                        .then(res => {
+                        .post('/upload/file', formData)
+                        .then((res) => {
                             success(res.data);
                         })
-                        .catch(e => {
+                        .catch((e) => {
                             failure(e);
                         });
                 },
-                init_instance_callback: editor => {
+                init_instance_callback: (editor) => {
                     this.editor = editor;
-                }
+                },
             },
             editor: null,
-            content: ""
+            content: '',
         };
     },
     methods: {
         onInput(val) {
-            this.$emit("input", val);
-        }
+            this.$emit('input', val);
+        },
     },
     watch: {},
     components: {
-        "tinymce-editor": Editor // <- Important part
-    }
+        'tinymce-editor': Editor, // <- Important part
+    },
 };
 </script>
 <style lang="less" scoped>
@@ -97,4 +88,4 @@ export default {
     background-color: #fbfdff;
     border-radius: 4px;
 }
-</style>
+</style>

+ 22 - 17
src/main/vue/src/components/SingleUpload.vue

@@ -1,7 +1,12 @@
 <template>
-    <el-upload class="single-upload" :action="uploadUrl" :headers="headers"
-        :show-file-list="false" :on-success="onSuccess"
-        :before-upload="beforeUpload">
+    <el-upload
+        class="single-upload"
+        :action="uploadUrl"
+        :headers="headers"
+        :show-file-list="false"
+        :on-success="onSuccess"
+        :before-upload="beforeUpload"
+    >
         <div></div>
         <div class="wrapper">
             <img v-if="imageUrl" :src="imageUrl" class="upload-image" />
@@ -16,47 +21,47 @@
     </el-upload>
 </template>
 <script>
-import resolveUrl from "resolve-url";
+import resolveUrl from 'resolve-url';
 export default {
     created() {
-        this.uploadUrl = resolveUrl(this.$baseUrl, "upload/file");
+        this.uploadUrl = resolveUrl(this.$baseUrl, 'upload/file');
         this.updateImageUrl(this.value);
     },
     props: {
         value: String,
         usePrefix: {
             type: Boolean,
-            default: true
+            default: true,
         },
         url: {
-            type: String
-        }
+            type: String,
+        },
     },
     data() {
         return {
-            imageUrl: "",
+            imageUrl: '',
             loading: false,
-            uploadUrl: ""
+            uploadUrl: '',
         };
     },
     computed: {
         headers() {
             return {
-                Authorization: "Bearer " + localStorage.getItem("token")
+                Authorization: 'Bearer ' + localStorage.getItem('token'),
             };
-        }
+        },
     },
     methods: {
         onSuccess(res, file) {
             this.loading = false;
             this.imageUrl = URL.createObjectURL(file.raw);
-            var newVal = "";
+            var newVal = '';
             if (res instanceof Array) {
                 newVal = res[0];
             } else {
                 newVal = res;
             }
-            this.$emit("input", newVal);
+            this.$emit('input', newVal);
         },
         onError(err, file, fileList) {
             this.loading = false;
@@ -67,13 +72,13 @@ export default {
         },
         updateImageUrl(url) {
             this.imageUrl = url;
-        }
+        },
     },
     watch: {
         value(val) {
             this.updateImageUrl(val);
-        }
-    }
+        },
+    },
 };
 </script>
 <style lang="less" scoped>

+ 19 - 13
src/main/vue/src/components/SortableHeader.vue

@@ -1,31 +1,37 @@
 <template>
     <span>
-        <span class="sortable-header" @click="changeSort('')">{{column.label}}</span>
+        <span class="sortable-header" @click="changeSort('')">{{ column.label }}</span>
         <span class="sort-caret-wrapper">
-            <i class="sort-caret asc" @click="changeSort('asc')"
-                :class="{active:currentSort[column.property] === 'asc'}"></i>
-            <i class="sort-caret desc" @click="changeSort('desc')"
-                :class="{active:currentSort[column.property] === 'desc'}"></i>
+            <i
+                class="sort-caret asc"
+                @click="changeSort('asc')"
+                :class="{ active: currentSort[column.property] === 'asc' }"
+            ></i>
+            <i
+                class="sort-caret desc"
+                @click="changeSort('desc')"
+                :class="{ active: currentSort[column.property] === 'desc' }"
+            ></i>
         </span>
     </span>
 </template>
 <script>
 export default {
-    name: "sortbaleHeader",
+    name: 'sortbaleHeader',
     props: {
         column: {
             type: Object,
-            required: true
+            required: true,
         },
         currentSort: {
             type: Object,
-            required: true
-        }
+            required: true,
+        },
     },
     methods: {
         changeSort(order) {
-            this.$emit("changeSort", this.column.property, order);
-        }
-    }
+            this.$emit('changeSort', this.column.property, order);
+        },
+    },
 };
-</script>
+</script>

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

@@ -1,36 +1,36 @@
 <template>
-    <el-menu-item v-if="isLeaf" :index="''+menu.id" :route="{path:menu.path}">
-        <i class="fa-fw" :class="menu.icon" v-if="menu.icon"></i><span slot="title">{{menu.name}}</span>
+    <el-menu-item v-if="isLeaf" :index="'' + menu.id" :route="{ path: menu.path }">
+        <i class="fa-fw" :class="menu.icon" v-if="menu.icon"></i><span slot="title">{{ menu.name }}</span>
     </el-menu-item>
-    <el-submenu v-else :index="''+menu.id">
+    <el-submenu v-else :index="'' + menu.id">
         <template slot="title">
             <i class="fa-fw" :class="menu.icon" v-if="menu.icon"></i>
-            <span slot="title">{{menu.name}}</span>
+            <span slot="title">{{ menu.name }}</span>
         </template>
         <sys-menu v-for="item in menu.children" :menu="item" :key="item.id"></sys-menu>
     </el-submenu>
 </template>
 <script>
-    export default {
-        name: 'SysMenu',
-        props: {
-            menu: {
-                type: Object,
-                required: true
-            }
+export default {
+    name: 'SysMenu',
+    props: {
+        menu: {
+            type: Object,
+            required: true,
         },
-        data() {
-            return {}
+    },
+    data() {
+        return {};
+    },
+    methods: {
+        click(e) {
+            console.log(e);
         },
-        methods: {
-            click(e) {
-                console.log(e);
-            }
+    },
+    computed: {
+        isLeaf() {
+            return !(this.menu.children instanceof Array && this.menu.children.length);
         },
-        computed: {
-            isLeaf() {
-                return !(this.menu.children instanceof Array && this.menu.children.length)
-            }
-        }
-    }
+    },
+};
 </script>

+ 428 - 419
src/main/vue/src/components/zh_CN.js

@@ -1,419 +1,428 @@
-tinymce.addI18n('zh_CN',{
-    "Redo": "\u91cd\u505a",
-    "Undo": "\u64a4\u9500",
-    "Cut": "\u526a\u5207",
-    "Copy": "\u590d\u5236",
-    "Paste": "\u7c98\u8d34",
-    "Select all": "\u5168\u9009",
-    "New document": "\u65b0\u6587\u4ef6",
-    "Ok": "\u786e\u5b9a",
-    "Cancel": "\u53d6\u6d88",
-    "Visual aids": "\u7f51\u683c\u7ebf",
-    "Bold": "\u7c97\u4f53",
-    "Italic": "\u659c\u4f53",
-    "Underline": "\u4e0b\u5212\u7ebf",
-    "Strikethrough": "\u5220\u9664\u7ebf",
-    "Superscript": "\u4e0a\u6807",
-    "Subscript": "\u4e0b\u6807",
-    "Clear formatting": "\u6e05\u9664\u683c\u5f0f",
-    "Align left": "\u5de6\u8fb9\u5bf9\u9f50",
-    "Align center": "\u4e2d\u95f4\u5bf9\u9f50",
-    "Align right": "\u53f3\u8fb9\u5bf9\u9f50",
-    "Justify": "\u4e24\u7aef\u5bf9\u9f50",
-    "Bullet list": "\u9879\u76ee\u7b26\u53f7",
-    "Numbered list": "\u7f16\u53f7\u5217\u8868",
-    "Decrease indent": "\u51cf\u5c11\u7f29\u8fdb",
-    "Increase indent": "\u589e\u52a0\u7f29\u8fdb",
-    "Close": "\u5173\u95ed",
-    "Formats": "\u683c\u5f0f",
-    "Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X\/C\/V keyboard shortcuts instead.": "\u4f60\u7684\u6d4f\u89c8\u5668\u4e0d\u652f\u6301\u6253\u5f00\u526a\u8d34\u677f\uff0c\u8bf7\u4f7f\u7528Ctrl+X\/C\/V\u7b49\u5feb\u6377\u952e\u3002",
-    "Headers": "\u6807\u9898",
-    "Header 1": "\u6807\u98981",
-    "Header 2": "\u6807\u98982",
-    "Header 3": "\u6807\u98983",
-    "Header 4": "\u6807\u98984",
-    "Header 5": "\u6807\u98985",
-    "Header 6": "\u6807\u98986",
-    "Headings": "\u6807\u9898",
-    "Heading 1": "\u6807\u98981",
-    "Heading 2": "\u6807\u98982",
-    "Heading 3": "\u6807\u98983",
-    "Heading 4": "\u6807\u98984",
-    "Heading 5": "\u6807\u98985",
-    "Heading 6": "\u6807\u98986",
-    "Preformatted": "\u9884\u5148\u683c\u5f0f\u5316\u7684",
-    "Div": "Div",
-    "Pre": "Pre",
-    "Code": "\u4ee3\u7801",
-    "Paragraph": "\u6bb5\u843d",
-    "Blockquote": "\u5f15\u6587\u533a\u5757",
-    "Inline": "\u6587\u672c",
-    "Blocks": "\u57fa\u5757",
-    "Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.": "\u5f53\u524d\u4e3a\u7eaf\u6587\u672c\u7c98\u8d34\u6a21\u5f0f\uff0c\u518d\u6b21\u70b9\u51fb\u53ef\u4ee5\u56de\u5230\u666e\u901a\u7c98\u8d34\u6a21\u5f0f\u3002",
-    "Fonts": "\u5b57\u4f53",
-    "Font Sizes": "\u5b57\u53f7",
-    "Class": "\u7c7b\u578b",
-    "Browse for an image": "\u6d4f\u89c8\u56fe\u50cf",
-    "OR": "\u6216",
-    "Drop an image here": "\u62d6\u653e\u4e00\u5f20\u56fe\u50cf\u81f3\u6b64",
-    "Upload": "\u4e0a\u4f20",
-    "Block": "\u5757",
-    "Align": "\u5bf9\u9f50",
-    "Default": "\u9ed8\u8ba4",
-    "Circle": "\u7a7a\u5fc3\u5706",
-    "Disc": "\u5b9e\u5fc3\u5706",
-    "Square": "\u65b9\u5757",
-    "Lower Alpha": "\u5c0f\u5199\u82f1\u6587\u5b57\u6bcd",
-    "Lower Greek": "\u5c0f\u5199\u5e0c\u814a\u5b57\u6bcd",
-    "Lower Roman": "\u5c0f\u5199\u7f57\u9a6c\u5b57\u6bcd",
-    "Upper Alpha": "\u5927\u5199\u82f1\u6587\u5b57\u6bcd",
-    "Upper Roman": "\u5927\u5199\u7f57\u9a6c\u5b57\u6bcd",
-    "Anchor...": "\u951a\u70b9...",
-    "Name": "\u540d\u79f0",
-    "Id": "\u6807\u8bc6\u7b26",
-    "Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.": "\u6807\u8bc6\u7b26\u5e94\u8be5\u4ee5\u5b57\u6bcd\u5f00\u5934\uff0c\u540e\u8ddf\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u7834\u6298\u53f7\u3001\u70b9\u3001\u5192\u53f7\u6216\u4e0b\u5212\u7ebf\u3002",
-    "You have unsaved changes are you sure you want to navigate away?": "\u4f60\u8fd8\u6709\u6587\u6863\u5c1a\u672a\u4fdd\u5b58\uff0c\u786e\u5b9a\u8981\u79bb\u5f00\uff1f",
-    "Restore last draft": "\u6062\u590d\u4e0a\u6b21\u7684\u8349\u7a3f",
-    "Special character...": "\u7279\u6b8a\u5b57\u7b26...",
-    "Source code": "\u6e90\u4ee3\u7801",
-    "Insert\/Edit code sample": "\u63d2\u5165\/\u7f16\u8f91\u4ee3\u7801\u793a\u4f8b",
-    "Language": "\u8bed\u8a00",
-    "Code sample...": "\u793a\u4f8b\u4ee3\u7801...",
-    "Color Picker": "\u9009\u8272\u5668",
-    "R": "R",
-    "G": "G",
-    "B": "B",
-    "Left to right": "\u4ece\u5de6\u5230\u53f3",
-    "Right to left": "\u4ece\u53f3\u5230\u5de6",
-    "Emoticons...": "\u8868\u60c5\u7b26\u53f7...",
-    "Metadata and Document Properties": "\u5143\u6570\u636e\u548c\u6587\u6863\u5c5e\u6027",
-    "Title": "\u6807\u9898",
-    "Keywords": "\u5173\u952e\u8bcd",
-    "Description": "\u63cf\u8ff0",
-    "Robots": "\u673a\u5668\u4eba",
-    "Author": "\u4f5c\u8005",
-    "Encoding": "\u7f16\u7801",
-    "Fullscreen": "\u5168\u5c4f",
-    "Action": "\u64cd\u4f5c",
-    "Shortcut": "\u5feb\u6377\u952e",
-    "Help": "\u5e2e\u52a9",
-    "Address": "\u5730\u5740",
-    "Focus to menubar": "\u79fb\u52a8\u7126\u70b9\u5230\u83dc\u5355\u680f",
-    "Focus to toolbar": "\u79fb\u52a8\u7126\u70b9\u5230\u5de5\u5177\u680f",
-    "Focus to element path": "\u79fb\u52a8\u7126\u70b9\u5230\u5143\u7d20\u8def\u5f84",
-    "Focus to contextual toolbar": "\u79fb\u52a8\u7126\u70b9\u5230\u4e0a\u4e0b\u6587\u83dc\u5355",
-    "Insert link (if link plugin activated)": "\u63d2\u5165\u94fe\u63a5 (\u5982\u679c\u94fe\u63a5\u63d2\u4ef6\u5df2\u6fc0\u6d3b)",
-    "Save (if save plugin activated)": "\u4fdd\u5b58(\u5982\u679c\u4fdd\u5b58\u63d2\u4ef6\u5df2\u6fc0\u6d3b)",
-    "Find (if searchreplace plugin activated)": "\u67e5\u627e(\u5982\u679c\u67e5\u627e\u66ff\u6362\u63d2\u4ef6\u5df2\u6fc0\u6d3b)",
-    "Plugins installed ({0}):": "\u5df2\u5b89\u88c5\u63d2\u4ef6 ({0}):",
-    "Premium plugins:": "\u4f18\u79c0\u63d2\u4ef6\uff1a",
-    "Learn more...": "\u4e86\u89e3\u66f4\u591a...",
-    "You are using {0}": "\u4f60\u6b63\u5728\u4f7f\u7528 {0}",
-    "Plugins": "\u63d2\u4ef6",
-    "Handy Shortcuts": "\u5feb\u6377\u952e",
-    "Horizontal line": "\u6c34\u5e73\u5206\u5272\u7ebf",
-    "Insert\/edit image": "\u63d2\u5165\/\u7f16\u8f91\u56fe\u7247",
-    "Image description": "\u56fe\u7247\u63cf\u8ff0",
-    "Source": "\u5730\u5740",
-    "Dimensions": "\u5927\u5c0f",
-    "Constrain proportions": "\u4fdd\u6301\u7eb5\u6a2a\u6bd4",
-    "General": "\u666e\u901a",
-    "Advanced": "\u9ad8\u7ea7",
-    "Style": "\u6837\u5f0f",
-    "Vertical space": "\u5782\u76f4\u8fb9\u8ddd",
-    "Horizontal space": "\u6c34\u5e73\u8fb9\u8ddd",
-    "Border": "\u8fb9\u6846",
-    "Insert image": "\u63d2\u5165\u56fe\u7247",
-    "Image...": "\u56fe\u7247...",
-    "Image list": "\u56fe\u7247\u5217\u8868",
-    "Rotate counterclockwise": "\u9006\u65f6\u9488\u65cb\u8f6c",
-    "Rotate clockwise": "\u987a\u65f6\u9488\u65cb\u8f6c",
-    "Flip vertically": "\u5782\u76f4\u7ffb\u8f6c",
-    "Flip horizontally": "\u6c34\u5e73\u7ffb\u8f6c",
-    "Edit image": "\u7f16\u8f91\u56fe\u7247",
-    "Image options": "\u56fe\u7247\u9009\u9879",
-    "Zoom in": "\u653e\u5927",
-    "Zoom out": "\u7f29\u5c0f",
-    "Crop": "\u88c1\u526a",
-    "Resize": "\u8c03\u6574\u5927\u5c0f",
-    "Orientation": "\u65b9\u5411",
-    "Brightness": "\u4eae\u5ea6",
-    "Sharpen": "\u9510\u5316",
-    "Contrast": "\u5bf9\u6bd4\u5ea6",
-    "Color levels": "\u989c\u8272\u5c42\u6b21",
-    "Gamma": "\u4f3d\u9a6c\u503c",
-    "Invert": "\u53cd\u8f6c",
-    "Apply": "\u5e94\u7528",
-    "Back": "\u540e\u9000",
-    "Insert date\/time": "\u63d2\u5165\u65e5\u671f\/\u65f6\u95f4",
-    "Date\/time": "\u65e5\u671f\/\u65f6\u95f4",
-    "Insert\/Edit Link": "\u63d2\u5165\/\u7f16\u8f91\u94fe\u63a5",
-    "Insert\/edit link": "\u63d2\u5165\/\u7f16\u8f91\u94fe\u63a5",
-    "Text to display": "\u663e\u793a\u6587\u5b57",
-    "Url": "\u5730\u5740",
-    "Open link in...": "\u94fe\u63a5\u6253\u5f00\u4f4d\u7f6e...",
-    "Current window": "\u5f53\u524d\u7a97\u53e3",
-    "None": "\u65e0",
-    "New window": "\u5728\u65b0\u7a97\u53e3\u6253\u5f00",
-    "Remove link": "\u5220\u9664\u94fe\u63a5",
-    "Anchors": "\u951a\u70b9",
-    "Link...": "\u94fe\u63a5...",
-    "Paste or type a link": "\u7c98\u8d34\u6216\u8f93\u5165\u94fe\u63a5",
-    "The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?": "\u4f60\u6240\u586b\u5199\u7684URL\u5730\u5740\u4e3a\u90ae\u4ef6\u5730\u5740\uff0c\u9700\u8981\u52a0\u4e0amailto:\u524d\u7f00\u5417\uff1f",
-    "The URL you entered seems to be an external link. Do you want to add the required http:\/\/ prefix?": "\u4f60\u6240\u586b\u5199\u7684URL\u5730\u5740\u5c5e\u4e8e\u5916\u90e8\u94fe\u63a5\uff0c\u9700\u8981\u52a0\u4e0ahttp:\/\/:\u524d\u7f00\u5417\uff1f",
-    "Link list": "\u94fe\u63a5\u5217\u8868",
-    "Insert video": "\u63d2\u5165\u89c6\u9891",
-    "Insert\/edit video": "\u63d2\u5165\/\u7f16\u8f91\u89c6\u9891",
-    "Insert\/edit media": "\u63d2\u5165\/\u7f16\u8f91\u5a92\u4f53",
-    "Alternative source": "\u955c\u50cf",
-    "Alternative source URL": "\u66ff\u4ee3\u6765\u6e90\u7f51\u5740",
-    "Media poster (Image URL)": "\u5c01\u9762(\u56fe\u7247\u5730\u5740)",
-    "Paste your embed code below:": "\u5c06\u5185\u5d4c\u4ee3\u7801\u7c98\u8d34\u5728\u4e0b\u9762:",
-    "Embed": "\u5185\u5d4c",
-    "Media...": "\u591a\u5a92\u4f53...",
-    "Nonbreaking space": "\u4e0d\u95f4\u65ad\u7a7a\u683c",
-    "Page break": "\u5206\u9875\u7b26",
-    "Paste as text": "\u7c98\u8d34\u4e3a\u6587\u672c",
-    "Preview": "\u9884\u89c8",
-    "Print...": "\u6253\u5370...",
-    "Save": "\u4fdd\u5b58",
-    "Find": "\u67e5\u627e",
-    "Replace with": "\u66ff\u6362\u4e3a",
-    "Replace": "\u66ff\u6362",
-    "Replace all": "\u5168\u90e8\u66ff\u6362",
-    "Previous": "\u4e0a\u4e00\u4e2a",
-    "Next": "\u4e0b\u4e00\u4e2a",
-    "Find and replace...": "\u67e5\u627e\u5e76\u66ff\u6362...",
-    "Could not find the specified string.": "\u672a\u627e\u5230\u641c\u7d22\u5185\u5bb9.",
-    "Match case": "\u533a\u5206\u5927\u5c0f\u5199",
-    "Find whole words only": "\u5168\u5b57\u5339\u914d",
-    "Spell check": "\u62fc\u5199\u68c0\u67e5",
-    "Ignore": "\u5ffd\u7565",
-    "Ignore all": "\u5168\u90e8\u5ffd\u7565",
-    "Finish": "\u5b8c\u6210",
-    "Add to Dictionary": "\u6dfb\u52a0\u5230\u5b57\u5178",
-    "Insert table": "\u63d2\u5165\u8868\u683c",
-    "Table properties": "\u8868\u683c\u5c5e\u6027",
-    "Delete table": "\u5220\u9664\u8868\u683c",
-    "Cell": "\u5355\u5143\u683c",
-    "Row": "\u884c",
-    "Column": "\u5217",
-    "Cell properties": "\u5355\u5143\u683c\u5c5e\u6027",
-    "Merge cells": "\u5408\u5e76\u5355\u5143\u683c",
-    "Split cell": "\u62c6\u5206\u5355\u5143\u683c",
-    "Insert row before": "\u5728\u4e0a\u65b9\u63d2\u5165",
-    "Insert row after": "\u5728\u4e0b\u65b9\u63d2\u5165",
-    "Delete row": "\u5220\u9664\u884c",
-    "Row properties": "\u884c\u5c5e\u6027",
-    "Cut row": "\u526a\u5207\u884c",
-    "Copy row": "\u590d\u5236\u884c",
-    "Paste row before": "\u7c98\u8d34\u5230\u4e0a\u65b9",
-    "Paste row after": "\u7c98\u8d34\u5230\u4e0b\u65b9",
-    "Insert column before": "\u5728\u5de6\u4fa7\u63d2\u5165",
-    "Insert column after": "\u5728\u53f3\u4fa7\u63d2\u5165",
-    "Delete column": "\u5220\u9664\u5217",
-    "Cols": "\u5217",
-    "Rows": "\u884c",
-    "Width": "\u5bbd",
-    "Height": "\u9ad8",
-    "Cell spacing": "\u5355\u5143\u683c\u5916\u95f4\u8ddd",
-    "Cell padding": "\u5355\u5143\u683c\u5185\u8fb9\u8ddd",
-    "Show caption": "\u663e\u793a\u6807\u9898",
-    "Left": "\u5de6\u5bf9\u9f50",
-    "Center": "\u5c45\u4e2d",
-    "Right": "\u53f3\u5bf9\u9f50",
-    "Cell type": "\u5355\u5143\u683c\u7c7b\u578b",
-    "Scope": "\u8303\u56f4",
-    "Alignment": "\u5bf9\u9f50\u65b9\u5f0f",
-    "H Align": "\u6c34\u5e73\u5bf9\u9f50",
-    "V Align": "\u5782\u76f4\u5bf9\u9f50",
-    "Top": "\u9876\u90e8\u5bf9\u9f50",
-    "Middle": "\u5782\u76f4\u5c45\u4e2d",
-    "Bottom": "\u5e95\u90e8\u5bf9\u9f50",
-    "Header cell": "\u8868\u5934\u5355\u5143\u683c",
-    "Row group": "\u884c\u7ec4",
-    "Column group": "\u5217\u7ec4",
-    "Row type": "\u884c\u7c7b\u578b",
-    "Header": "\u8868\u5934",
-    "Body": "\u8868\u4f53",
-    "Footer": "\u8868\u5c3e",
-    "Border color": "\u8fb9\u6846\u989c\u8272",
-    "Insert template...": "\u63d2\u5165\u6a21\u677f...",
-    "Templates": "\u6a21\u677f",
-    "Template": "\u6a21\u677f",
-    "Text color": "\u6587\u5b57\u989c\u8272",
-    "Background color": "\u80cc\u666f\u8272",
-    "Custom...": "\u81ea\u5b9a\u4e49...",
-    "Custom color": "\u81ea\u5b9a\u4e49\u989c\u8272",
-    "No color": "\u65e0",
-    "Remove color": "\u79fb\u9664\u989c\u8272",
-    "Table of Contents": "\u5185\u5bb9\u5217\u8868",
-    "Show blocks": "\u663e\u793a\u533a\u5757\u8fb9\u6846",
-    "Show invisible characters": "\u663e\u793a\u4e0d\u53ef\u89c1\u5b57\u7b26",
-    "Word count": "\u5b57\u6570",
-    "Count": "\u8ba1\u6570",
-    "Document": "\u6587\u6863",
-    "Selection": "\u9009\u62e9",
-    "Words": "\u5355\u8bcd",
-    "Words: {0}": "\u5b57\u6570\uff1a{0}",
-    "{0} words": "{0} \u5b57",
-    "File": "\u6587\u4ef6",
-    "Edit": "\u7f16\u8f91",
-    "Insert": "\u63d2\u5165",
-    "View": "\u89c6\u56fe",
-    "Format": "\u683c\u5f0f",
-    "Table": "\u8868\u683c",
-    "Tools": "\u5de5\u5177",
-    "Powered by {0}": "\u7531{0}\u9a71\u52a8",
-    "Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help": "\u5728\u7f16\u8f91\u533a\u6309ALT-F9\u6253\u5f00\u83dc\u5355\uff0c\u6309ALT-F10\u6253\u5f00\u5de5\u5177\u680f\uff0c\u6309ALT-0\u67e5\u770b\u5e2e\u52a9",
-    "Image title": "\u56fe\u7247\u6807\u9898",
-    "Border width": "\u8fb9\u6846\u5bbd\u5ea6",
-    "Border style": "\u8fb9\u6846\u6837\u5f0f",
-    "Error": "\u9519\u8bef",
-    "Warn": "\u8b66\u544a",
-    "Valid": "\u6709\u6548",
-    "To open the popup, press Shift+Enter": "\u6309Shitf+Enter\u952e\u6253\u5f00\u5bf9\u8bdd\u6846",
-    "Rich Text Area. Press ALT-0 for help.": "\u7f16\u8f91\u533a\u3002\u6309Alt+0\u952e\u6253\u5f00\u5e2e\u52a9\u3002",
-    "System Font": "\u7cfb\u7edf\u5b57\u4f53",
-    "Failed to upload image: {0}": "\u56fe\u7247\u4e0a\u4f20\u5931\u8d25: {0}",
-    "Failed to load plugin: {0} from url {1}": "\u63d2\u4ef6\u52a0\u8f7d\u5931\u8d25: {0} \u6765\u81ea\u94fe\u63a5 {1}",
-    "Failed to load plugin url: {0}": "\u63d2\u4ef6\u52a0\u8f7d\u5931\u8d25 \u94fe\u63a5: {0}",
-    "Failed to initialize plugin: {0}": "\u63d2\u4ef6\u521d\u59cb\u5316\u5931\u8d25: {0}",
-    "example": "\u793a\u4f8b",
-    "Search": "\u641c\u7d22",
-    "All": "\u5168\u90e8",
-    "Currency": "\u8d27\u5e01",
-    "Text": "\u6587\u5b57",
-    "Quotations": "\u5f15\u7528",
-    "Mathematical": "\u6570\u5b66",
-    "Extended Latin": "\u62c9\u4e01\u8bed\u6269\u5145",
-    "Symbols": "\u7b26\u53f7",
-    "Arrows": "\u7bad\u5934",
-    "User Defined": "\u81ea\u5b9a\u4e49",
-    "dollar sign": "\u7f8e\u5143\u7b26\u53f7",
-    "currency sign": "\u8d27\u5e01\u7b26\u53f7",
-    "euro-currency sign": "\u6b27\u5143\u7b26\u53f7",
-    "colon sign": "\u5192\u53f7",
-    "cruzeiro sign": "\u514b\u9c81\u8d5b\u7f57\u5e01\u7b26\u53f7",
-    "french franc sign": "\u6cd5\u90ce\u7b26\u53f7",
-    "lira sign": "\u91cc\u62c9\u7b26\u53f7",
-    "mill sign": "\u5bc6\u5c14\u7b26\u53f7",
-    "naira sign": "\u5948\u62c9\u7b26\u53f7",
-    "peseta sign": "\u6bd4\u585e\u5854\u7b26\u53f7",
-    "rupee sign": "\u5362\u6bd4\u7b26\u53f7",
-    "won sign": "\u97e9\u5143\u7b26\u53f7",
-    "new sheqel sign": "\u65b0\u8c22\u514b\u5c14\u7b26\u53f7",
-    "dong sign": "\u8d8a\u5357\u76fe\u7b26\u53f7",
-    "kip sign": "\u8001\u631d\u57fa\u666e\u7b26\u53f7",
-    "tugrik sign": "\u56fe\u683c\u91cc\u514b\u7b26\u53f7",
-    "drachma sign": "\u5fb7\u62c9\u514b\u9a6c\u7b26\u53f7",
-    "german penny symbol": "\u5fb7\u56fd\u4fbf\u58eb\u7b26\u53f7",
-    "peso sign": "\u6bd4\u7d22\u7b26\u53f7",
-    "guarani sign": "\u74dc\u62c9\u5c3c\u7b26\u53f7",
-    "austral sign": "\u6fb3\u5143\u7b26\u53f7",
-    "hryvnia sign": "\u683c\u91cc\u592b\u5c3c\u4e9a\u7b26\u53f7",
-    "cedi sign": "\u585e\u5730\u7b26\u53f7",
-    "livre tournois sign": "\u91cc\u5f17\u5f17\u5c14\u7b26\u53f7",
-    "spesmilo sign": "spesmilo\u7b26\u53f7",
-    "tenge sign": "\u575a\u6208\u7b26\u53f7",
-    "indian rupee sign": "\u5370\u5ea6\u5362\u6bd4",
-    "turkish lira sign": "\u571f\u8033\u5176\u91cc\u62c9",
-    "nordic mark sign": "\u5317\u6b27\u9a6c\u514b",
-    "manat sign": "\u9a6c\u7eb3\u7279\u7b26\u53f7",
-    "ruble sign": "\u5362\u5e03\u7b26\u53f7",
-    "yen character": "\u65e5\u5143\u5b57\u6837",
-    "yuan character": "\u4eba\u6c11\u5e01\u5143\u5b57\u6837",
-    "yuan character, in hong kong and taiwan": "\u5143\u5b57\u6837\uff08\u6e2f\u53f0\u5730\u533a\uff09",
-    "yen\/yuan character variant one": "\u5143\u5b57\u6837\uff08\u5927\u5199\uff09",
-    "Loading emoticons...": "\u52a0\u8f7d\u8868\u60c5\u7b26\u53f7...",
-    "Could not load emoticons": "\u4e0d\u80fd\u52a0\u8f7d\u8868\u60c5\u7b26\u53f7",
-    "People": "\u4eba\u7c7b",
-    "Animals and Nature": "\u52a8\u7269\u548c\u81ea\u7136",
-    "Food and Drink": "\u98df\u7269\u548c\u996e\u54c1",
-    "Activity": "\u6d3b\u52a8",
-    "Travel and Places": "\u65c5\u6e38\u548c\u5730\u70b9",
-    "Objects": "\u7269\u4ef6",
-    "Flags": "\u65d7\u5e1c",
-    "Characters": "\u5b57\u7b26",
-    "Characters (no spaces)": "\u5b57\u7b26(\u65e0\u7a7a\u683c)",
-    "{0} characters": "{0} \u4e2a\u5b57\u7b26",
-    "Error: Form submit field collision.": "\u9519\u8bef: \u8868\u5355\u63d0\u4ea4\u5b57\u6bb5\u51b2\u7a81\u3002",
-    "Error: No form element found.": "\u9519\u8bef: \u6ca1\u6709\u8868\u5355\u63a7\u4ef6\u3002",
-    "Update": "\u66f4\u65b0",
-    "Color swatch": "\u989c\u8272\u6837\u672c",
-    "Turquoise": "\u9752\u7eff\u8272",
-    "Green": "\u7eff\u8272",
-    "Blue": "\u84dd\u8272",
-    "Purple": "\u7d2b\u8272",
-    "Navy Blue": "\u6d77\u519b\u84dd",
-    "Dark Turquoise": "\u6df1\u84dd\u7eff\u8272",
-    "Dark Green": "\u6df1\u7eff\u8272",
-    "Medium Blue": "\u4e2d\u84dd\u8272",
-    "Medium Purple": "\u4e2d\u7d2b\u8272",
-    "Midnight Blue": "\u6df1\u84dd\u8272",
-    "Yellow": "\u9ec4\u8272",
-    "Orange": "\u6a59\u8272",
-    "Red": "\u7ea2\u8272",
-    "Light Gray": "\u6d45\u7070\u8272",
-    "Gray": "\u7070\u8272",
-    "Dark Yellow": "\u6697\u9ec4\u8272",
-    "Dark Orange": "\u6df1\u6a59\u8272",
-    "Dark Red": "\u6df1\u7ea2\u8272",
-    "Medium Gray": "\u4e2d\u7070\u8272",
-    "Dark Gray": "\u6df1\u7070\u8272",
-    "Light Green": "\u6d45\u7eff\u8272",
-    "Light Yellow": "\u6d45\u9ec4\u8272",
-    "Light Red": "\u6d45\u7ea2\u8272",
-    "Light Purple": "\u6d45\u7d2b\u8272",
-    "Light Blue": "\u6d45\u84dd\u8272",
-    "Dark Purple": "\u6df1\u7d2b\u8272",
-    "Dark Blue": "\u6df1\u84dd\u8272",
-    "Black": "\u9ed1\u8272",
-    "White": "\u767d\u8272",
-    "Switch to or from fullscreen mode": "\u5207\u6362\u5168\u5c4f\u6a21\u5f0f",
-    "Open help dialog": "\u6253\u5f00\u5e2e\u52a9\u5bf9\u8bdd\u6846",
-    "history": "\u5386\u53f2",
-    "styles": "\u6837\u5f0f",
-    "formatting": "\u683c\u5f0f\u5316",
-    "alignment": "\u5bf9\u9f50",
-    "indentation": "\u7f29\u8fdb",
-    "permanent pen": "\u8bb0\u53f7\u7b14",
-    "comments": "\u5907\u6ce8",
-    "Format Painter": "\u683c\u5f0f\u5237",
-    "Insert\/edit iframe": "\u63d2\u5165\/\u7f16\u8f91\u6846\u67b6",
-    "Capitalization": "\u5927\u5199",
-    "lowercase": "\u5c0f\u5199",
-    "UPPERCASE": "\u5927\u5199",
-    "Title Case": "\u9996\u5b57\u6bcd\u5927\u5199",
-    "Permanent Pen Properties": "\u6c38\u4e45\u7b14\u5c5e\u6027",
-    "Permanent pen properties...": "\u6c38\u4e45\u7b14\u5c5e\u6027...",
-    "Font": "\u5b57\u4f53",
-    "Size": "\u5b57\u53f7",
-    "More...": "\u66f4\u591a...",
-    "Spellcheck Language": "\u62fc\u5199\u68c0\u67e5\u8bed\u8a00",
-    "Select...": "\u9009\u62e9...",
-    "Preferences": "\u9996\u9009\u9879",
-    "Yes": "\u662f",
-    "No": "\u5426",
-    "Keyboard Navigation": "\u952e\u76d8\u6307\u5f15",
-    "Version": "\u7248\u672c",
-    "Anchor": "\u951a\u70b9",
-    "Special character": "\u7279\u6b8a\u7b26\u53f7",
-    "Code sample": "\u4ee3\u7801\u793a\u4f8b",
-    "Color": "\u989c\u8272",
-    "Emoticons": "\u8868\u60c5",
-    "Document properties": "\u6587\u6863\u5c5e\u6027",
-    "Image": "\u56fe\u7247",
-    "Insert link": "\u63d2\u5165\u94fe\u63a5",
-    "Target": "\u6253\u5f00\u65b9\u5f0f",
-    "Link": "\u94fe\u63a5",
-    "Poster": "\u5c01\u9762",
-    "Media": "\u5a92\u4f53",
-    "Print": "\u6253\u5370",
-    "Prev": "\u4e0a\u4e00\u4e2a",
-    "Find and replace": "\u67e5\u627e\u548c\u66ff\u6362",
-    "Whole words": "\u5168\u5b57\u5339\u914d",
-    "Spellcheck": "\u62fc\u5199\u68c0\u67e5",
-    "Caption": "\u6807\u9898",
-    "Insert template": "\u63d2\u5165\u6a21\u677f"
-    });
+tinymce.addI18n('zh_CN', {
+    Redo: '\u91cd\u505a',
+    Undo: '\u64a4\u9500',
+    Cut: '\u526a\u5207',
+    Copy: '\u590d\u5236',
+    Paste: '\u7c98\u8d34',
+    'Select all': '\u5168\u9009',
+    'New document': '\u65b0\u6587\u4ef6',
+    Ok: '\u786e\u5b9a',
+    Cancel: '\u53d6\u6d88',
+    'Visual aids': '\u7f51\u683c\u7ebf',
+    Bold: '\u7c97\u4f53',
+    Italic: '\u659c\u4f53',
+    Underline: '\u4e0b\u5212\u7ebf',
+    Strikethrough: '\u5220\u9664\u7ebf',
+    Superscript: '\u4e0a\u6807',
+    Subscript: '\u4e0b\u6807',
+    'Clear formatting': '\u6e05\u9664\u683c\u5f0f',
+    'Align left': '\u5de6\u8fb9\u5bf9\u9f50',
+    'Align center': '\u4e2d\u95f4\u5bf9\u9f50',
+    'Align right': '\u53f3\u8fb9\u5bf9\u9f50',
+    Justify: '\u4e24\u7aef\u5bf9\u9f50',
+    'Bullet list': '\u9879\u76ee\u7b26\u53f7',
+    'Numbered list': '\u7f16\u53f7\u5217\u8868',
+    'Decrease indent': '\u51cf\u5c11\u7f29\u8fdb',
+    'Increase indent': '\u589e\u52a0\u7f29\u8fdb',
+    Close: '\u5173\u95ed',
+    Formats: '\u683c\u5f0f',
+    "Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X/C/V keyboard shortcuts instead.":
+        '\u4f60\u7684\u6d4f\u89c8\u5668\u4e0d\u652f\u6301\u6253\u5f00\u526a\u8d34\u677f\uff0c\u8bf7\u4f7f\u7528Ctrl+X/C/V\u7b49\u5feb\u6377\u952e\u3002',
+    Headers: '\u6807\u9898',
+    'Header 1': '\u6807\u98981',
+    'Header 2': '\u6807\u98982',
+    'Header 3': '\u6807\u98983',
+    'Header 4': '\u6807\u98984',
+    'Header 5': '\u6807\u98985',
+    'Header 6': '\u6807\u98986',
+    Headings: '\u6807\u9898',
+    'Heading 1': '\u6807\u98981',
+    'Heading 2': '\u6807\u98982',
+    'Heading 3': '\u6807\u98983',
+    'Heading 4': '\u6807\u98984',
+    'Heading 5': '\u6807\u98985',
+    'Heading 6': '\u6807\u98986',
+    Preformatted: '\u9884\u5148\u683c\u5f0f\u5316\u7684',
+    Div: 'Div',
+    Pre: 'Pre',
+    Code: '\u4ee3\u7801',
+    Paragraph: '\u6bb5\u843d',
+    Blockquote: '\u5f15\u6587\u533a\u5757',
+    Inline: '\u6587\u672c',
+    Blocks: '\u57fa\u5757',
+    'Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.':
+        '\u5f53\u524d\u4e3a\u7eaf\u6587\u672c\u7c98\u8d34\u6a21\u5f0f\uff0c\u518d\u6b21\u70b9\u51fb\u53ef\u4ee5\u56de\u5230\u666e\u901a\u7c98\u8d34\u6a21\u5f0f\u3002',
+    Fonts: '\u5b57\u4f53',
+    'Font Sizes': '\u5b57\u53f7',
+    Class: '\u7c7b\u578b',
+    'Browse for an image': '\u6d4f\u89c8\u56fe\u50cf',
+    OR: '\u6216',
+    'Drop an image here': '\u62d6\u653e\u4e00\u5f20\u56fe\u50cf\u81f3\u6b64',
+    Upload: '\u4e0a\u4f20',
+    Block: '\u5757',
+    Align: '\u5bf9\u9f50',
+    Default: '\u9ed8\u8ba4',
+    Circle: '\u7a7a\u5fc3\u5706',
+    Disc: '\u5b9e\u5fc3\u5706',
+    Square: '\u65b9\u5757',
+    'Lower Alpha': '\u5c0f\u5199\u82f1\u6587\u5b57\u6bcd',
+    'Lower Greek': '\u5c0f\u5199\u5e0c\u814a\u5b57\u6bcd',
+    'Lower Roman': '\u5c0f\u5199\u7f57\u9a6c\u5b57\u6bcd',
+    'Upper Alpha': '\u5927\u5199\u82f1\u6587\u5b57\u6bcd',
+    'Upper Roman': '\u5927\u5199\u7f57\u9a6c\u5b57\u6bcd',
+    'Anchor...': '\u951a\u70b9...',
+    Name: '\u540d\u79f0',
+    Id: '\u6807\u8bc6\u7b26',
+    'Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.':
+        '\u6807\u8bc6\u7b26\u5e94\u8be5\u4ee5\u5b57\u6bcd\u5f00\u5934\uff0c\u540e\u8ddf\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u7834\u6298\u53f7\u3001\u70b9\u3001\u5192\u53f7\u6216\u4e0b\u5212\u7ebf\u3002',
+    'You have unsaved changes are you sure you want to navigate away?':
+        '\u4f60\u8fd8\u6709\u6587\u6863\u5c1a\u672a\u4fdd\u5b58\uff0c\u786e\u5b9a\u8981\u79bb\u5f00\uff1f',
+    'Restore last draft': '\u6062\u590d\u4e0a\u6b21\u7684\u8349\u7a3f',
+    'Special character...': '\u7279\u6b8a\u5b57\u7b26...',
+    'Source code': '\u6e90\u4ee3\u7801',
+    'Insert/Edit code sample': '\u63d2\u5165/\u7f16\u8f91\u4ee3\u7801\u793a\u4f8b',
+    Language: '\u8bed\u8a00',
+    'Code sample...': '\u793a\u4f8b\u4ee3\u7801...',
+    'Color Picker': '\u9009\u8272\u5668',
+    R: 'R',
+    G: 'G',
+    B: 'B',
+    'Left to right': '\u4ece\u5de6\u5230\u53f3',
+    'Right to left': '\u4ece\u53f3\u5230\u5de6',
+    'Emoticons...': '\u8868\u60c5\u7b26\u53f7...',
+    'Metadata and Document Properties': '\u5143\u6570\u636e\u548c\u6587\u6863\u5c5e\u6027',
+    Title: '\u6807\u9898',
+    Keywords: '\u5173\u952e\u8bcd',
+    Description: '\u63cf\u8ff0',
+    Robots: '\u673a\u5668\u4eba',
+    Author: '\u4f5c\u8005',
+    Encoding: '\u7f16\u7801',
+    Fullscreen: '\u5168\u5c4f',
+    Action: '\u64cd\u4f5c',
+    Shortcut: '\u5feb\u6377\u952e',
+    Help: '\u5e2e\u52a9',
+    Address: '\u5730\u5740',
+    'Focus to menubar': '\u79fb\u52a8\u7126\u70b9\u5230\u83dc\u5355\u680f',
+    'Focus to toolbar': '\u79fb\u52a8\u7126\u70b9\u5230\u5de5\u5177\u680f',
+    'Focus to element path': '\u79fb\u52a8\u7126\u70b9\u5230\u5143\u7d20\u8def\u5f84',
+    'Focus to contextual toolbar': '\u79fb\u52a8\u7126\u70b9\u5230\u4e0a\u4e0b\u6587\u83dc\u5355',
+    'Insert link (if link plugin activated)':
+        '\u63d2\u5165\u94fe\u63a5 (\u5982\u679c\u94fe\u63a5\u63d2\u4ef6\u5df2\u6fc0\u6d3b)',
+    'Save (if save plugin activated)': '\u4fdd\u5b58(\u5982\u679c\u4fdd\u5b58\u63d2\u4ef6\u5df2\u6fc0\u6d3b)',
+    'Find (if searchreplace plugin activated)':
+        '\u67e5\u627e(\u5982\u679c\u67e5\u627e\u66ff\u6362\u63d2\u4ef6\u5df2\u6fc0\u6d3b)',
+    'Plugins installed ({0}):': '\u5df2\u5b89\u88c5\u63d2\u4ef6 ({0}):',
+    'Premium plugins:': '\u4f18\u79c0\u63d2\u4ef6\uff1a',
+    'Learn more...': '\u4e86\u89e3\u66f4\u591a...',
+    'You are using {0}': '\u4f60\u6b63\u5728\u4f7f\u7528 {0}',
+    Plugins: '\u63d2\u4ef6',
+    'Handy Shortcuts': '\u5feb\u6377\u952e',
+    'Horizontal line': '\u6c34\u5e73\u5206\u5272\u7ebf',
+    'Insert/edit image': '\u63d2\u5165/\u7f16\u8f91\u56fe\u7247',
+    'Image description': '\u56fe\u7247\u63cf\u8ff0',
+    Source: '\u5730\u5740',
+    Dimensions: '\u5927\u5c0f',
+    'Constrain proportions': '\u4fdd\u6301\u7eb5\u6a2a\u6bd4',
+    General: '\u666e\u901a',
+    Advanced: '\u9ad8\u7ea7',
+    Style: '\u6837\u5f0f',
+    'Vertical space': '\u5782\u76f4\u8fb9\u8ddd',
+    'Horizontal space': '\u6c34\u5e73\u8fb9\u8ddd',
+    Border: '\u8fb9\u6846',
+    'Insert image': '\u63d2\u5165\u56fe\u7247',
+    'Image...': '\u56fe\u7247...',
+    'Image list': '\u56fe\u7247\u5217\u8868',
+    'Rotate counterclockwise': '\u9006\u65f6\u9488\u65cb\u8f6c',
+    'Rotate clockwise': '\u987a\u65f6\u9488\u65cb\u8f6c',
+    'Flip vertically': '\u5782\u76f4\u7ffb\u8f6c',
+    'Flip horizontally': '\u6c34\u5e73\u7ffb\u8f6c',
+    'Edit image': '\u7f16\u8f91\u56fe\u7247',
+    'Image options': '\u56fe\u7247\u9009\u9879',
+    'Zoom in': '\u653e\u5927',
+    'Zoom out': '\u7f29\u5c0f',
+    Crop: '\u88c1\u526a',
+    Resize: '\u8c03\u6574\u5927\u5c0f',
+    Orientation: '\u65b9\u5411',
+    Brightness: '\u4eae\u5ea6',
+    Sharpen: '\u9510\u5316',
+    Contrast: '\u5bf9\u6bd4\u5ea6',
+    'Color levels': '\u989c\u8272\u5c42\u6b21',
+    Gamma: '\u4f3d\u9a6c\u503c',
+    Invert: '\u53cd\u8f6c',
+    Apply: '\u5e94\u7528',
+    Back: '\u540e\u9000',
+    'Insert date/time': '\u63d2\u5165\u65e5\u671f/\u65f6\u95f4',
+    'Date/time': '\u65e5\u671f/\u65f6\u95f4',
+    'Insert/Edit Link': '\u63d2\u5165/\u7f16\u8f91\u94fe\u63a5',
+    'Insert/edit link': '\u63d2\u5165/\u7f16\u8f91\u94fe\u63a5',
+    'Text to display': '\u663e\u793a\u6587\u5b57',
+    Url: '\u5730\u5740',
+    'Open link in...': '\u94fe\u63a5\u6253\u5f00\u4f4d\u7f6e...',
+    'Current window': '\u5f53\u524d\u7a97\u53e3',
+    None: '\u65e0',
+    'New window': '\u5728\u65b0\u7a97\u53e3\u6253\u5f00',
+    'Remove link': '\u5220\u9664\u94fe\u63a5',
+    Anchors: '\u951a\u70b9',
+    'Link...': '\u94fe\u63a5...',
+    'Paste or type a link': '\u7c98\u8d34\u6216\u8f93\u5165\u94fe\u63a5',
+    'The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?':
+        '\u4f60\u6240\u586b\u5199\u7684URL\u5730\u5740\u4e3a\u90ae\u4ef6\u5730\u5740\uff0c\u9700\u8981\u52a0\u4e0amailto:\u524d\u7f00\u5417\uff1f',
+    'The URL you entered seems to be an external link. Do you want to add the required http:// prefix?':
+        '\u4f60\u6240\u586b\u5199\u7684URL\u5730\u5740\u5c5e\u4e8e\u5916\u90e8\u94fe\u63a5\uff0c\u9700\u8981\u52a0\u4e0ahttp://:\u524d\u7f00\u5417\uff1f',
+    'Link list': '\u94fe\u63a5\u5217\u8868',
+    'Insert video': '\u63d2\u5165\u89c6\u9891',
+    'Insert/edit video': '\u63d2\u5165/\u7f16\u8f91\u89c6\u9891',
+    'Insert/edit media': '\u63d2\u5165/\u7f16\u8f91\u5a92\u4f53',
+    'Alternative source': '\u955c\u50cf',
+    'Alternative source URL': '\u66ff\u4ee3\u6765\u6e90\u7f51\u5740',
+    'Media poster (Image URL)': '\u5c01\u9762(\u56fe\u7247\u5730\u5740)',
+    'Paste your embed code below:': '\u5c06\u5185\u5d4c\u4ee3\u7801\u7c98\u8d34\u5728\u4e0b\u9762:',
+    Embed: '\u5185\u5d4c',
+    'Media...': '\u591a\u5a92\u4f53...',
+    'Nonbreaking space': '\u4e0d\u95f4\u65ad\u7a7a\u683c',
+    'Page break': '\u5206\u9875\u7b26',
+    'Paste as text': '\u7c98\u8d34\u4e3a\u6587\u672c',
+    Preview: '\u9884\u89c8',
+    'Print...': '\u6253\u5370...',
+    Save: '\u4fdd\u5b58',
+    Find: '\u67e5\u627e',
+    'Replace with': '\u66ff\u6362\u4e3a',
+    Replace: '\u66ff\u6362',
+    'Replace all': '\u5168\u90e8\u66ff\u6362',
+    Previous: '\u4e0a\u4e00\u4e2a',
+    Next: '\u4e0b\u4e00\u4e2a',
+    'Find and replace...': '\u67e5\u627e\u5e76\u66ff\u6362...',
+    'Could not find the specified string.': '\u672a\u627e\u5230\u641c\u7d22\u5185\u5bb9.',
+    'Match case': '\u533a\u5206\u5927\u5c0f\u5199',
+    'Find whole words only': '\u5168\u5b57\u5339\u914d',
+    'Spell check': '\u62fc\u5199\u68c0\u67e5',
+    Ignore: '\u5ffd\u7565',
+    'Ignore all': '\u5168\u90e8\u5ffd\u7565',
+    Finish: '\u5b8c\u6210',
+    'Add to Dictionary': '\u6dfb\u52a0\u5230\u5b57\u5178',
+    'Insert table': '\u63d2\u5165\u8868\u683c',
+    'Table properties': '\u8868\u683c\u5c5e\u6027',
+    'Delete table': '\u5220\u9664\u8868\u683c',
+    Cell: '\u5355\u5143\u683c',
+    Row: '\u884c',
+    Column: '\u5217',
+    'Cell properties': '\u5355\u5143\u683c\u5c5e\u6027',
+    'Merge cells': '\u5408\u5e76\u5355\u5143\u683c',
+    'Split cell': '\u62c6\u5206\u5355\u5143\u683c',
+    'Insert row before': '\u5728\u4e0a\u65b9\u63d2\u5165',
+    'Insert row after': '\u5728\u4e0b\u65b9\u63d2\u5165',
+    'Delete row': '\u5220\u9664\u884c',
+    'Row properties': '\u884c\u5c5e\u6027',
+    'Cut row': '\u526a\u5207\u884c',
+    'Copy row': '\u590d\u5236\u884c',
+    'Paste row before': '\u7c98\u8d34\u5230\u4e0a\u65b9',
+    'Paste row after': '\u7c98\u8d34\u5230\u4e0b\u65b9',
+    'Insert column before': '\u5728\u5de6\u4fa7\u63d2\u5165',
+    'Insert column after': '\u5728\u53f3\u4fa7\u63d2\u5165',
+    'Delete column': '\u5220\u9664\u5217',
+    Cols: '\u5217',
+    Rows: '\u884c',
+    Width: '\u5bbd',
+    Height: '\u9ad8',
+    'Cell spacing': '\u5355\u5143\u683c\u5916\u95f4\u8ddd',
+    'Cell padding': '\u5355\u5143\u683c\u5185\u8fb9\u8ddd',
+    'Show caption': '\u663e\u793a\u6807\u9898',
+    Left: '\u5de6\u5bf9\u9f50',
+    Center: '\u5c45\u4e2d',
+    Right: '\u53f3\u5bf9\u9f50',
+    'Cell type': '\u5355\u5143\u683c\u7c7b\u578b',
+    Scope: '\u8303\u56f4',
+    Alignment: '\u5bf9\u9f50\u65b9\u5f0f',
+    'H Align': '\u6c34\u5e73\u5bf9\u9f50',
+    'V Align': '\u5782\u76f4\u5bf9\u9f50',
+    Top: '\u9876\u90e8\u5bf9\u9f50',
+    Middle: '\u5782\u76f4\u5c45\u4e2d',
+    Bottom: '\u5e95\u90e8\u5bf9\u9f50',
+    'Header cell': '\u8868\u5934\u5355\u5143\u683c',
+    'Row group': '\u884c\u7ec4',
+    'Column group': '\u5217\u7ec4',
+    'Row type': '\u884c\u7c7b\u578b',
+    Header: '\u8868\u5934',
+    Body: '\u8868\u4f53',
+    Footer: '\u8868\u5c3e',
+    'Border color': '\u8fb9\u6846\u989c\u8272',
+    'Insert template...': '\u63d2\u5165\u6a21\u677f...',
+    Templates: '\u6a21\u677f',
+    Template: '\u6a21\u677f',
+    'Text color': '\u6587\u5b57\u989c\u8272',
+    'Background color': '\u80cc\u666f\u8272',
+    'Custom...': '\u81ea\u5b9a\u4e49...',
+    'Custom color': '\u81ea\u5b9a\u4e49\u989c\u8272',
+    'No color': '\u65e0',
+    'Remove color': '\u79fb\u9664\u989c\u8272',
+    'Table of Contents': '\u5185\u5bb9\u5217\u8868',
+    'Show blocks': '\u663e\u793a\u533a\u5757\u8fb9\u6846',
+    'Show invisible characters': '\u663e\u793a\u4e0d\u53ef\u89c1\u5b57\u7b26',
+    'Word count': '\u5b57\u6570',
+    Count: '\u8ba1\u6570',
+    Document: '\u6587\u6863',
+    Selection: '\u9009\u62e9',
+    Words: '\u5355\u8bcd',
+    'Words: {0}': '\u5b57\u6570\uff1a{0}',
+    '{0} words': '{0} \u5b57',
+    File: '\u6587\u4ef6',
+    Edit: '\u7f16\u8f91',
+    Insert: '\u63d2\u5165',
+    View: '\u89c6\u56fe',
+    Format: '\u683c\u5f0f',
+    Table: '\u8868\u683c',
+    Tools: '\u5de5\u5177',
+    'Powered by {0}': '\u7531{0}\u9a71\u52a8',
+    'Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help':
+        '\u5728\u7f16\u8f91\u533a\u6309ALT-F9\u6253\u5f00\u83dc\u5355\uff0c\u6309ALT-F10\u6253\u5f00\u5de5\u5177\u680f\uff0c\u6309ALT-0\u67e5\u770b\u5e2e\u52a9',
+    'Image title': '\u56fe\u7247\u6807\u9898',
+    'Border width': '\u8fb9\u6846\u5bbd\u5ea6',
+    'Border style': '\u8fb9\u6846\u6837\u5f0f',
+    Error: '\u9519\u8bef',
+    Warn: '\u8b66\u544a',
+    Valid: '\u6709\u6548',
+    'To open the popup, press Shift+Enter': '\u6309Shitf+Enter\u952e\u6253\u5f00\u5bf9\u8bdd\u6846',
+    'Rich Text Area. Press ALT-0 for help.': '\u7f16\u8f91\u533a\u3002\u6309Alt+0\u952e\u6253\u5f00\u5e2e\u52a9\u3002',
+    'System Font': '\u7cfb\u7edf\u5b57\u4f53',
+    'Failed to upload image: {0}': '\u56fe\u7247\u4e0a\u4f20\u5931\u8d25: {0}',
+    'Failed to load plugin: {0} from url {1}': '\u63d2\u4ef6\u52a0\u8f7d\u5931\u8d25: {0} \u6765\u81ea\u94fe\u63a5 {1}',
+    'Failed to load plugin url: {0}': '\u63d2\u4ef6\u52a0\u8f7d\u5931\u8d25 \u94fe\u63a5: {0}',
+    'Failed to initialize plugin: {0}': '\u63d2\u4ef6\u521d\u59cb\u5316\u5931\u8d25: {0}',
+    example: '\u793a\u4f8b',
+    Search: '\u641c\u7d22',
+    All: '\u5168\u90e8',
+    Currency: '\u8d27\u5e01',
+    Text: '\u6587\u5b57',
+    Quotations: '\u5f15\u7528',
+    Mathematical: '\u6570\u5b66',
+    'Extended Latin': '\u62c9\u4e01\u8bed\u6269\u5145',
+    Symbols: '\u7b26\u53f7',
+    Arrows: '\u7bad\u5934',
+    'User Defined': '\u81ea\u5b9a\u4e49',
+    'dollar sign': '\u7f8e\u5143\u7b26\u53f7',
+    'currency sign': '\u8d27\u5e01\u7b26\u53f7',
+    'euro-currency sign': '\u6b27\u5143\u7b26\u53f7',
+    'colon sign': '\u5192\u53f7',
+    'cruzeiro sign': '\u514b\u9c81\u8d5b\u7f57\u5e01\u7b26\u53f7',
+    'french franc sign': '\u6cd5\u90ce\u7b26\u53f7',
+    'lira sign': '\u91cc\u62c9\u7b26\u53f7',
+    'mill sign': '\u5bc6\u5c14\u7b26\u53f7',
+    'naira sign': '\u5948\u62c9\u7b26\u53f7',
+    'peseta sign': '\u6bd4\u585e\u5854\u7b26\u53f7',
+    'rupee sign': '\u5362\u6bd4\u7b26\u53f7',
+    'won sign': '\u97e9\u5143\u7b26\u53f7',
+    'new sheqel sign': '\u65b0\u8c22\u514b\u5c14\u7b26\u53f7',
+    'dong sign': '\u8d8a\u5357\u76fe\u7b26\u53f7',
+    'kip sign': '\u8001\u631d\u57fa\u666e\u7b26\u53f7',
+    'tugrik sign': '\u56fe\u683c\u91cc\u514b\u7b26\u53f7',
+    'drachma sign': '\u5fb7\u62c9\u514b\u9a6c\u7b26\u53f7',
+    'german penny symbol': '\u5fb7\u56fd\u4fbf\u58eb\u7b26\u53f7',
+    'peso sign': '\u6bd4\u7d22\u7b26\u53f7',
+    'guarani sign': '\u74dc\u62c9\u5c3c\u7b26\u53f7',
+    'austral sign': '\u6fb3\u5143\u7b26\u53f7',
+    'hryvnia sign': '\u683c\u91cc\u592b\u5c3c\u4e9a\u7b26\u53f7',
+    'cedi sign': '\u585e\u5730\u7b26\u53f7',
+    'livre tournois sign': '\u91cc\u5f17\u5f17\u5c14\u7b26\u53f7',
+    'spesmilo sign': 'spesmilo\u7b26\u53f7',
+    'tenge sign': '\u575a\u6208\u7b26\u53f7',
+    'indian rupee sign': '\u5370\u5ea6\u5362\u6bd4',
+    'turkish lira sign': '\u571f\u8033\u5176\u91cc\u62c9',
+    'nordic mark sign': '\u5317\u6b27\u9a6c\u514b',
+    'manat sign': '\u9a6c\u7eb3\u7279\u7b26\u53f7',
+    'ruble sign': '\u5362\u5e03\u7b26\u53f7',
+    'yen character': '\u65e5\u5143\u5b57\u6837',
+    'yuan character': '\u4eba\u6c11\u5e01\u5143\u5b57\u6837',
+    'yuan character, in hong kong and taiwan': '\u5143\u5b57\u6837\uff08\u6e2f\u53f0\u5730\u533a\uff09',
+    'yen/yuan character variant one': '\u5143\u5b57\u6837\uff08\u5927\u5199\uff09',
+    'Loading emoticons...': '\u52a0\u8f7d\u8868\u60c5\u7b26\u53f7...',
+    'Could not load emoticons': '\u4e0d\u80fd\u52a0\u8f7d\u8868\u60c5\u7b26\u53f7',
+    People: '\u4eba\u7c7b',
+    'Animals and Nature': '\u52a8\u7269\u548c\u81ea\u7136',
+    'Food and Drink': '\u98df\u7269\u548c\u996e\u54c1',
+    Activity: '\u6d3b\u52a8',
+    'Travel and Places': '\u65c5\u6e38\u548c\u5730\u70b9',
+    Objects: '\u7269\u4ef6',
+    Flags: '\u65d7\u5e1c',
+    Characters: '\u5b57\u7b26',
+    'Characters (no spaces)': '\u5b57\u7b26(\u65e0\u7a7a\u683c)',
+    '{0} characters': '{0} \u4e2a\u5b57\u7b26',
+    'Error: Form submit field collision.': '\u9519\u8bef: \u8868\u5355\u63d0\u4ea4\u5b57\u6bb5\u51b2\u7a81\u3002',
+    'Error: No form element found.': '\u9519\u8bef: \u6ca1\u6709\u8868\u5355\u63a7\u4ef6\u3002',
+    Update: '\u66f4\u65b0',
+    'Color swatch': '\u989c\u8272\u6837\u672c',
+    Turquoise: '\u9752\u7eff\u8272',
+    Green: '\u7eff\u8272',
+    Blue: '\u84dd\u8272',
+    Purple: '\u7d2b\u8272',
+    'Navy Blue': '\u6d77\u519b\u84dd',
+    'Dark Turquoise': '\u6df1\u84dd\u7eff\u8272',
+    'Dark Green': '\u6df1\u7eff\u8272',
+    'Medium Blue': '\u4e2d\u84dd\u8272',
+    'Medium Purple': '\u4e2d\u7d2b\u8272',
+    'Midnight Blue': '\u6df1\u84dd\u8272',
+    Yellow: '\u9ec4\u8272',
+    Orange: '\u6a59\u8272',
+    Red: '\u7ea2\u8272',
+    'Light Gray': '\u6d45\u7070\u8272',
+    Gray: '\u7070\u8272',
+    'Dark Yellow': '\u6697\u9ec4\u8272',
+    'Dark Orange': '\u6df1\u6a59\u8272',
+    'Dark Red': '\u6df1\u7ea2\u8272',
+    'Medium Gray': '\u4e2d\u7070\u8272',
+    'Dark Gray': '\u6df1\u7070\u8272',
+    'Light Green': '\u6d45\u7eff\u8272',
+    'Light Yellow': '\u6d45\u9ec4\u8272',
+    'Light Red': '\u6d45\u7ea2\u8272',
+    'Light Purple': '\u6d45\u7d2b\u8272',
+    'Light Blue': '\u6d45\u84dd\u8272',
+    'Dark Purple': '\u6df1\u7d2b\u8272',
+    'Dark Blue': '\u6df1\u84dd\u8272',
+    Black: '\u9ed1\u8272',
+    White: '\u767d\u8272',
+    'Switch to or from fullscreen mode': '\u5207\u6362\u5168\u5c4f\u6a21\u5f0f',
+    'Open help dialog': '\u6253\u5f00\u5e2e\u52a9\u5bf9\u8bdd\u6846',
+    history: '\u5386\u53f2',
+    styles: '\u6837\u5f0f',
+    formatting: '\u683c\u5f0f\u5316',
+    alignment: '\u5bf9\u9f50',
+    indentation: '\u7f29\u8fdb',
+    'permanent pen': '\u8bb0\u53f7\u7b14',
+    comments: '\u5907\u6ce8',
+    'Format Painter': '\u683c\u5f0f\u5237',
+    'Insert/edit iframe': '\u63d2\u5165/\u7f16\u8f91\u6846\u67b6',
+    Capitalization: '\u5927\u5199',
+    lowercase: '\u5c0f\u5199',
+    UPPERCASE: '\u5927\u5199',
+    'Title Case': '\u9996\u5b57\u6bcd\u5927\u5199',
+    'Permanent Pen Properties': '\u6c38\u4e45\u7b14\u5c5e\u6027',
+    'Permanent pen properties...': '\u6c38\u4e45\u7b14\u5c5e\u6027...',
+    Font: '\u5b57\u4f53',
+    Size: '\u5b57\u53f7',
+    'More...': '\u66f4\u591a...',
+    'Spellcheck Language': '\u62fc\u5199\u68c0\u67e5\u8bed\u8a00',
+    'Select...': '\u9009\u62e9...',
+    Preferences: '\u9996\u9009\u9879',
+    Yes: '\u662f',
+    No: '\u5426',
+    'Keyboard Navigation': '\u952e\u76d8\u6307\u5f15',
+    Version: '\u7248\u672c',
+    Anchor: '\u951a\u70b9',
+    'Special character': '\u7279\u6b8a\u7b26\u53f7',
+    'Code sample': '\u4ee3\u7801\u793a\u4f8b',
+    Color: '\u989c\u8272',
+    Emoticons: '\u8868\u60c5',
+    'Document properties': '\u6587\u6863\u5c5e\u6027',
+    Image: '\u56fe\u7247',
+    'Insert link': '\u63d2\u5165\u94fe\u63a5',
+    Target: '\u6253\u5f00\u65b9\u5f0f',
+    Link: '\u94fe\u63a5',
+    Poster: '\u5c01\u9762',
+    Media: '\u5a92\u4f53',
+    Print: '\u6253\u5370',
+    Prev: '\u4e0a\u4e00\u4e2a',
+    'Find and replace': '\u67e5\u627e\u548c\u66ff\u6362',
+    'Whole words': '\u5168\u5b57\u5339\u914d',
+    Spellcheck: '\u62fc\u5199\u68c0\u67e5',
+    Caption: '\u6807\u9898',
+    'Insert template': '\u63d2\u5165\u6a21\u677f',
+});

+ 1 - 1
src/main/vue/src/main.js

@@ -49,5 +49,5 @@ Vue.mixin(Formatters);
 new Vue({
     router,
     store,
-    render: h => h(App),
+    render: (h) => h(App),
 }).$mount('#app');

+ 1 - 1
src/main/vue/src/mixins/formatters.js

@@ -11,7 +11,7 @@ export default {
         },
         dateFormatter(row, column, cellValue, index) {
             if (cellValue) {
-                return format(new Date(cellValue), 'yyyy/MM/dd', {locale: zhCN})
+                return format(new Date(cellValue), 'yyyy/MM/dd', { locale: zhCN });
             }
         },
     },

+ 24 - 42
src/main/vue/src/mixins/pageableTable.js

@@ -26,9 +26,7 @@ export default {
         this.getData();
     },
     mounted() {
-        this.tableHeight = document
-            .querySelector('.el-table')
-            .getBoundingClientRect().height;
+        this.tableHeight = document.querySelector('.el-table').getBoundingClientRect().height;
     },
     methods: {
         getData() {
@@ -50,7 +48,7 @@ export default {
             }
             this.$http
                 .get(this.url, data)
-                .then(res => {
+                .then((res) => {
                     this.tableData = res.content;
                     this.totalPages = res.totalPages;
                     this.totalElements = res.totalElements;
@@ -58,7 +56,7 @@ export default {
                         this.afterGetData(res);
                     }
                 })
-                .catch(e => {
+                .catch((e) => {
                     console.log(e);
                     this.$message.error(e.error);
                 });
@@ -100,53 +98,37 @@ export default {
                         page: e,
                     },
                 })
-                .catch(_ => {});
+                .catch((_) => {});
             this.page = e;
             this.getData();
         },
         adjustColumnWidth() {
             let canvas = document.createElement('canvas');
             let ctx = canvas.getContext('2d');
-            let measureTxt = text => {
+            let measureTxt = (text) => {
                 return parseInt(ctx.measureText(text).width);
             };
             let rowWidth = [];
             let headWidth = [];
-            document
-                .querySelectorAll('.el-table__body-wrapper .table-row')
-                .forEach(row => {
-                    row.querySelectorAll('.table-cell').forEach(
-                        (cell, index) => {
-                            let children = cell.querySelector('.cell').children;
-                            if (children && children.length) {
-                                let width = 0;
-                                console.log(children);
-                                for (let child of children) {
-                                    width +=
-                                        child.clientWidth +
-                                        parseInt(
-                                            window
-                                                .getComputedStyle(child)
-                                                .marginLeft.replace('px', ''),
-                                        ) +
-                                        parseInt(
-                                            window
-                                                .getComputedStyle(child)
-                                                .marginRight.replace('px', ''),
-                                        );
-                                }
-                                rowWidth[index] = width;
-                            } else {
-                                console.log(
-                                    cell.querySelector('.cell').innerHTML,
-                                );
-                                rowWidth[index] = measureTxt(
-                                    cell.querySelector('.cell').innerHTML,
-                                );
-                            }
-                        },
-                    );
+            document.querySelectorAll('.el-table__body-wrapper .table-row').forEach((row) => {
+                row.querySelectorAll('.table-cell').forEach((cell, index) => {
+                    let children = cell.querySelector('.cell').children;
+                    if (children && children.length) {
+                        let width = 0;
+                        console.log(children);
+                        for (let child of children) {
+                            width +=
+                                child.clientWidth +
+                                parseInt(window.getComputedStyle(child).marginLeft.replace('px', '')) +
+                                parseInt(window.getComputedStyle(child).marginRight.replace('px', ''));
+                        }
+                        rowWidth[index] = width;
+                    } else {
+                        console.log(cell.querySelector('.cell').innerHTML);
+                        rowWidth[index] = measureTxt(cell.querySelector('.cell').innerHTML);
+                    }
                 });
+            });
             this.$refs.table.columns.forEach(({ label }, index) => {
                 headWidth[index] = measureTxt(label) + 50;
             });
@@ -170,7 +152,7 @@ export default {
                         sort: sortStr,
                     },
                 })
-                .catch(_ => {});
+                .catch((_) => {});
             this.sortStr = sortStr;
             this.getData();
         },

+ 6 - 6
src/main/vue/src/plugins/dataExport.js

@@ -21,7 +21,7 @@ function getPropByPath(obj, path, strict) {
     return {
         o: tempObj,
         k: keyArr[i],
-        v: tempObj ? tempObj[keyArr[i]] : null
+        v: tempObj ? tempObj[keyArr[i]] : null,
     };
 }
 export default {
@@ -34,11 +34,11 @@ export default {
                 throw new Error('filename cannot be empty');
             }
             filename = filename.replace(/.xlsx$/i, '');
-            const columns = ref.columns.filter(column => !!column.property);
+            const columns = ref.columns.filter((column) => !!column.property);
             let workbook = XLSX.utils.book_new();
             let sheet = XLSX.utils.aoa_to_sheet([
-                columns.map(column => column.label),
-                ...ref.tableData.map(row => {
+                columns.map((column) => column.label),
+                ...ref.tableData.map((row) => {
                     return columns.map((column, index) => {
                         const value = getPropByPath(row, column.property).v;
                         if (column.formatter) {
@@ -46,10 +46,10 @@ export default {
                         }
                         return value;
                     });
-                })
+                }),
             ]);
             XLSX.utils.book_append_sheet(workbook, sheet, filename);
             XLSX.writeFile(workbook, filename + '.xlsx');
         };
-    }
+    },
 };

+ 56 - 65
src/main/vue/src/router.js

@@ -1,110 +1,101 @@
-import Vue from "vue";
-import Router from "vue-router";
-import Admin from "@/views/Admin";
-import store from "./store";
-import http from "./plugins/http";
+import Vue from 'vue';
+import Router from 'vue-router';
+import Admin from '@/views/Admin';
+import store from './store';
+import http from './plugins/http';
 
 Vue.use(Router);
 
 const router = new Router({
-    mode: "history",
+    mode: 'history',
     base: process.env.BASE_URL,
     routes: [
         {
-            path: "/",
+            path: '/',
             component: Admin,
             children: [
                 {
-                    path: "/",
-                    redirect: "dashboard",
+                    path: '/',
+                    redirect: 'dashboard',
                 },
                 {
-                    path: "/404",
-                    name: "404",
-                    component: () =>
-                        import(/* webpackChunkName: "404" */ "@/views/404.vue"),
+                    path: '/404',
+                    name: '404',
+                    component: () => import(/* webpackChunkName: "404" */ '@/views/404.vue'),
                 },
                 {
-                    path: "/dashboard",
-                    name: "dashboard",
-                    component: () =>
-                        import(/* webpackChunkName: "404" */ "@/views/Dashboard.vue"),
+                    path: '/dashboard',
+                    name: 'dashboard',
+                    component: () => import(/* webpackChunkName: "404" */ '@/views/Dashboard.vue'),
                     meta: {
-                        title: "首页",
+                        title: '首页',
                     },
                 },
                 {
-                    path: "/api",
-                    name: "api",
-                    component: () =>
-                        import(/* webpackChunkName: "api" */ "@/views/Api.vue"),
+                    path: '/api',
+                    name: 'api',
+                    component: () => import(/* webpackChunkName: "api" */ '@/views/Api.vue'),
                     meta: {
-                        title: "接口调试",
+                        title: '接口调试',
                     },
                 },
                 {
-                    path: "/genCodeEdit",
-                    name: "genCodeEdit",
-                    component: () =>
-                        import(/* webpackChunkName: "genCodeEdit" */ "@/views/GenCodeEdit.vue"),
+                    path: '/genCodeEdit',
+                    name: 'genCodeEdit',
+                    component: () => import(/* webpackChunkName: "genCodeEdit" */ '@/views/GenCodeEdit.vue'),
                     meta: {
-                        title: "代码生成编辑",
+                        title: '代码生成编辑',
                     },
                 },
                 {
-                    path: "/genCodeList",
-                    name: "genCodeList",
-                    component: () =>
-                        import(/* webpackChunkName: "genCodeList" */ "@/views/GenCodeList.vue"),
+                    path: '/genCodeList',
+                    name: 'genCodeList',
+                    component: () => import(/* webpackChunkName: "genCodeList" */ '@/views/GenCodeList.vue'),
                     meta: {
-                        title: "代码生成",
+                        title: '代码生成',
                     },
                 },
                 {
-                    path: "/menus",
-                    name: "menus",
-                    component: () =>
-                        import(/* webpackChunkName: "menus" */ "@/views/Menus.vue"),
+                    path: '/menus',
+                    name: 'menus',
+                    component: () => import(/* webpackChunkName: "menus" */ '@/views/Menus.vue'),
                     meta: {
-                        title: "菜单配置",
+                        title: '菜单配置',
                     },
                 },
                 {
-                    path: "/userEdit",
-                    name: "userEdit",
-                    component: () =>
-                        import(/* webpackChunkName: "userEdit" */ "@/views/UserEdit.vue"),
+                    path: '/userEdit',
+                    name: 'userEdit',
+                    component: () => import(/* webpackChunkName: "userEdit" */ '@/views/UserEdit.vue'),
                     meta: {
-                        title: "用户编辑",
+                        title: '用户编辑',
                     },
                 },
                 {
-                    path: "/userList",
-                    name: "userList",
-                    component: () =>
-                        import(/* webpackChunkName: "userList" */ "@/views/UserList.vue"),
+                    path: '/userList',
+                    name: 'userList',
+                    component: () => import(/* webpackChunkName: "userList" */ '@/views/UserList.vue'),
                     meta: {
-                        title: "用户管理",
+                        title: '用户管理',
                     },
                 },
                 {
-                    path: "/sysConfigList",
-                    name: "sysConfigList",
-                    component: () =>
-                        import(/* webpackChunkName: "sysConfigList" */ "@/views/SysConfigList.vue"),
+                    path: '/sysConfigList',
+                    name: 'sysConfigList',
+                    component: () => import(/* webpackChunkName: "sysConfigList" */ '@/views/SysConfigList.vue'),
                     meta: {
-                        title: "参数配置",
+                        title: '参数配置',
                     },
                 },
                 /**INSERT_LOCATION**/
             ],
         },
         {
-            path: "/login",
-            name: "login",
-            component: () => import("@/views/Login"),
+            path: '/login',
+            name: 'login',
+            component: () => import('@/views/Login'),
             meta: {
-                title: "登录",
+                title: '登录',
             },
         },
     ],
@@ -113,7 +104,7 @@ router.beforeEach((to, from, next) => {
     //console.log(to);
     if (/^\/http/.test(to.path)) {
         console.log(Vue.$baseUrl);
-        let url = to.path.replace("/", "");
+        let url = to.path.replace('/', '');
         let params = [];
         if (to.query) {
             for (let key in to.query) {
@@ -123,25 +114,25 @@ router.beforeEach((to, from, next) => {
             }
         }
         if (params.length > 0) {
-            url += `?${params.join("&")}`;
+            url += `?${params.join('&')}`;
         }
         window.open(url);
         return;
     }
-    if (!store.state.userInfo && to.path !== "/login") {
+    if (!store.state.userInfo && to.path !== '/login') {
         http.axios
-            .get("/user/my")
+            .get('/user/my')
             .then((res) => {
-                store.commit("updateUserInfo", res.data);
+                store.commit('updateUserInfo', res.data);
                 next();
                 return;
             })
             .catch(() => {
-                localStorage.removeItem("token");
-                next("/login");
+                localStorage.removeItem('token');
+                next('/login');
             });
     } else if (!to.matched.length) {
-        next("/404");
+        next('/404');
     } else {
         next();
     }

+ 186 - 186
src/main/vue/src/views/404.vue

@@ -1,10 +1,10 @@
 <template>
     <div class="wscn-http404">
         <div class="pic-404">
-            <img class="pic-404__parent" :src="img_404" alt="404">
-            <img class="pic-404__child left" :src="img_404_cloud" alt="404">
-            <img class="pic-404__child mid" :src="img_404_cloud" alt="404">
-            <img class="pic-404__child right" :src="img_404_cloud" alt="404">
+            <img class="pic-404__parent" :src="img_404" alt="404" />
+            <img class="pic-404__child left" :src="img_404_cloud" alt="404" />
+            <img class="pic-404__child mid" :src="img_404_cloud" alt="404" />
+            <img class="pic-404__child right" :src="img_404_cloud" alt="404" />
         </div>
         <div class="bullshit">
             <div class="bullshit__oops">OOPS!</div>
@@ -16,218 +16,218 @@
 </template>
 
 <script>
-    import img_404 from '../assets/404_images/404.png'
-    import img_404_cloud from '../assets/404_images/404_cloud.png'
+import img_404 from '../assets/404_images/404.png';
+import img_404_cloud from '../assets/404_images/404_cloud.png';
 
-    export default {
-        name: 'page404',
-        data() {
-            return {
-                img_404,
-                img_404_cloud
-            }
+export default {
+    name: 'page404',
+    data() {
+        return {
+            img_404,
+            img_404_cloud,
+        };
+    },
+    computed: {
+        message() {
+            return '未找到该页面';
         },
-        computed: {
-            message() {
-                return '未找到该页面'
-            }
+    },
+    methods: {
+        goBack() {
+            this.$router.go(-1);
         },
-        methods: {
-            goBack() {
-                this.$router.go(-1);
-            }
-        }
-    }
+    },
+};
 </script>
 
 <style lang="less" scoped>
-    .wscn-http404 {
-        background: #f0f2f5;
-        margin: -20px;
-        min-height: 100%;
+.wscn-http404 {
+    background: #f0f2f5;
+    margin: -20px;
+    min-height: 100%;
+    position: relative;
+    padding: 20px 100px;
+    overflow: hidden;
+    height: 100%;
+    .pic-404 {
         position: relative;
-        padding: 20px 100px;
+        float: left;
+        width: 600px;
+        padding: 150px 0;
         overflow: hidden;
-        height: 100%;
-        .pic-404 {
-            position: relative;
-            float: left;
-            width: 600px;
-            padding: 150px 0;
-            overflow: hidden;
-            &__parent {
-                width: 100%;
+        &__parent {
+            width: 100%;
+        }
+        &__child {
+            position: absolute;
+            &.left {
+                width: 80px;
+                top: 17px;
+                left: 220px;
+                opacity: 0;
+                animation-name: cloudLeft;
+                animation-duration: 2s;
+                animation-timing-function: linear;
+                animation-fill-mode: forwards;
+                animation-delay: 1s;
+            }
+            &.mid {
+                width: 46px;
+                top: 10px;
+                left: 420px;
+                opacity: 0;
+                animation-name: cloudMid;
+                animation-duration: 2s;
+                animation-timing-function: linear;
+                animation-fill-mode: forwards;
+                animation-delay: 1.2s;
             }
-            &__child {
-                position: absolute;
-                &.left {
-                    width: 80px;
+            &.right {
+                width: 62px;
+                top: 100px;
+                left: 500px;
+                opacity: 0;
+                animation-name: cloudRight;
+                animation-duration: 2s;
+                animation-timing-function: linear;
+                animation-fill-mode: forwards;
+                animation-delay: 1s;
+            }
+            @keyframes cloudLeft {
+                0% {
                     top: 17px;
                     left: 220px;
                     opacity: 0;
-                    animation-name: cloudLeft;
-                    animation-duration: 2s;
-                    animation-timing-function: linear;
-                    animation-fill-mode: forwards;
-                    animation-delay: 1s;
                 }
-                &.mid {
-                    width: 46px;
+                20% {
+                    top: 33px;
+                    left: 188px;
+                    opacity: 1;
+                }
+                80% {
+                    top: 81px;
+                    left: 92px;
+                    opacity: 1;
+                }
+                100% {
+                    top: 97px;
+                    left: 60px;
+                    opacity: 0;
+                }
+            }
+            @keyframes cloudMid {
+                0% {
                     top: 10px;
                     left: 420px;
                     opacity: 0;
-                    animation-name: cloudMid;
-                    animation-duration: 2s;
-                    animation-timing-function: linear;
-                    animation-fill-mode: forwards;
-                    animation-delay: 1.2s;
                 }
-                &.right {
-                    width: 62px;
+                20% {
+                    top: 40px;
+                    left: 360px;
+                    opacity: 1;
+                }
+                70% {
+                    top: 130px;
+                    left: 180px;
+                    opacity: 1;
+                }
+                100% {
+                    top: 160px;
+                    left: 120px;
+                    opacity: 0;
+                }
+            }
+            @keyframes cloudRight {
+                0% {
                     top: 100px;
                     left: 500px;
                     opacity: 0;
-                    animation-name: cloudRight;
-                    animation-duration: 2s;
-                    animation-timing-function: linear;
-                    animation-fill-mode: forwards;
-                    animation-delay: 1s;
                 }
-                @keyframes cloudLeft {
-                    0% {
-                        top: 17px;
-                        left: 220px;
-                        opacity: 0;
-                    }
-                    20% {
-                        top: 33px;
-                        left: 188px;
-                        opacity: 1;
-                    }
-                    80% {
-                        top: 81px;
-                        left: 92px;
-                        opacity: 1;
-                    }
-                    100% {
-                        top: 97px;
-                        left: 60px;
-                        opacity: 0;
-                    }
+                20% {
+                    top: 120px;
+                    left: 460px;
+                    opacity: 1;
                 }
-                @keyframes cloudMid {
-                    0% {
-                        top: 10px;
-                        left: 420px;
-                        opacity: 0;
-                    }
-                    20% {
-                        top: 40px;
-                        left: 360px;
-                        opacity: 1;
-                    }
-                    70% {
-                        top: 130px;
-                        left: 180px;
-                        opacity: 1;
-                    }
-                    100% {
-                        top: 160px;
-                        left: 120px;
-                        opacity: 0;
-                    }
+                80% {
+                    top: 180px;
+                    left: 340px;
+                    opacity: 1;
                 }
-                @keyframes cloudRight {
-                    0% {
-                        top: 100px;
-                        left: 500px;
-                        opacity: 0;
-                    }
-                    20% {
-                        top: 120px;
-                        left: 460px;
-                        opacity: 1;
-                    }
-                    80% {
-                        top: 180px;
-                        left: 340px;
-                        opacity: 1;
-                    }
-                    100% {
-                        top: 200px;
-                        left: 300px;
-                        opacity: 0;
-                    }
+                100% {
+                    top: 200px;
+                    left: 300px;
+                    opacity: 0;
                 }
             }
         }
-        .bullshit {
-            position: relative;
+    }
+    .bullshit {
+        position: relative;
+        float: left;
+        width: 330px;
+        padding: 150px 0;
+        overflow: hidden;
+        &__oops {
+            font-size: 32px;
+            font-weight: bold;
+            line-height: 40px;
+            color: #1482f0;
+            opacity: 0;
+            margin-bottom: 20px;
+            animation-name: slideUp;
+            animation-duration: 0.5s;
+            animation-fill-mode: forwards;
+        }
+        &__headline {
+            font-size: 20px;
+            line-height: 24px;
+            color: #1482f0;
+            opacity: 0;
+            margin-bottom: 10px;
+            animation-name: slideUp;
+            animation-duration: 0.5s;
+            animation-delay: 0.1s;
+            animation-fill-mode: forwards;
+        }
+        &__info {
+            font-size: 13px;
+            line-height: 21px;
+            color: grey;
+            opacity: 0;
+            margin-bottom: 30px;
+            animation-name: slideUp;
+            animation-duration: 0.5s;
+            animation-delay: 0.2s;
+            animation-fill-mode: forwards;
+        }
+        &__return-home {
+            display: block;
             float: left;
-            width: 330px;
-            padding: 150px 0;
-            overflow: hidden;
-            &__oops {
-                font-size: 32px;
-                font-weight: bold;
-                line-height: 40px;
-                color: #1482f0;
-                opacity: 0;
-                margin-bottom: 20px;
-                animation-name: slideUp;
-                animation-duration: 0.5s;
-                animation-fill-mode: forwards;
-            }
-            &__headline {
-                font-size: 20px;
-                line-height: 24px;
-                color: #1482f0;
-                opacity: 0;
-                margin-bottom: 10px;
-                animation-name: slideUp;
-                animation-duration: 0.5s;
-                animation-delay: 0.1s;
-                animation-fill-mode: forwards;
-            }
-            &__info {
-                font-size: 13px;
-                line-height: 21px;
-                color: grey;
+            width: 110px;
+            height: 36px;
+            background: #1482f0;
+            border-radius: 100px;
+            text-align: center;
+            color: #ffffff;
+            opacity: 0;
+            font-size: 14px;
+            line-height: 36px;
+            cursor: pointer;
+            animation-name: slideUp;
+            animation-duration: 0.5s;
+            animation-delay: 0.3s;
+            animation-fill-mode: forwards;
+        }
+        @keyframes slideUp {
+            0% {
+                transform: translateY(60px);
                 opacity: 0;
-                margin-bottom: 30px;
-                animation-name: slideUp;
-                animation-duration: 0.5s;
-                animation-delay: 0.2s;
-                animation-fill-mode: forwards;
             }
-            &__return-home {
-                display: block;
-                float: left;
-                width: 110px;
-                height: 36px;
-                background: #1482f0;
-                border-radius: 100px;
-                text-align: center;
-                color: #ffffff;
-                opacity: 0;
-                font-size: 14px;
-                line-height: 36px;
-                cursor: pointer;
-                animation-name: slideUp;
-                animation-duration: 0.5s;
-                animation-delay: 0.3s;
-                animation-fill-mode: forwards;
-            }
-            @keyframes slideUp {
-                0% {
-                    transform: translateY(60px);
-                    opacity: 0;
-                }
-                100% {
-                    transform: translateY(0);
-                    opacity: 1;
-                }
+            100% {
+                transform: translateY(0);
+                opacity: 1;
             }
         }
     }
+}
 </style>

+ 43 - 66
src/main/vue/src/views/Admin.vue

@@ -10,19 +10,16 @@
                 :unique-opened="true"
                 :router="true"
                 :default-active="activeMenu"
-                style="border-right: 1px solid #545c64"
+                style="border-right: 1px solid #545c64;"
                 class="el-menu-vertical-demo"
             >
-                <sys-menu v-for="item in menus" :menu="item" :key="item.id">
-                </sys-menu>
+                <sys-menu v-for="item in menus" :menu="item" :key="item.id"> </sys-menu>
             </el-menu>
         </el-aside>
         <el-container>
             <el-header class="header">
                 <div class="header-btn" @click="collapse = !collapse">
-                    <div
-                        :style="{ transform: collapse ? 'rotate(90deg)' : '' }"
-                    >
+                    <div :style="{ transform: collapse ? 'rotate(90deg)' : '' }">
                         <i class="fas fa-bars" style="font-size: 20px;"></i>
                     </div>
                 </div>
@@ -31,12 +28,9 @@
                         <el-breadcrumb-item :to="{ path: '/dashboard' }">
                             首页
                         </el-breadcrumb-item>
-                        <el-breadcrumb-item
-                            v-if="$route.name !== 'dashboard'"
-                            >{{
-                                $route.meta.title || $route.name
-                            }}</el-breadcrumb-item
-                        >
+                        <el-breadcrumb-item v-if="$route.name !== 'dashboard'">{{
+                            $route.meta.title || $route.name
+                        }}</el-breadcrumb-item>
                     </el-breadcrumb>
                 </div>
 
@@ -46,28 +40,19 @@
                     placement="bottom"
                     :open-delay="1000"
                 >
-                    <div
-                        class="header-btn"
-                        @click="toggleFullScreen"
-                        ref="fullscreen"
-                    >
+                    <div class="header-btn" @click="toggleFullScreen" ref="fullscreen">
                         <i class="fas fa-expand" style="font-size: 20px;"></i>
                     </div>
                 </el-tooltip>
 
                 <el-dropdown @command="onCommand" style="margin-left: 20px;">
-                    <img
-                        :src="userInfo ? userInfo.avatar || '' : ''"
-                        class="avatar"
-                    />
+                    <img :src="userInfo ? userInfo.avatar || '' : ''" class="avatar" />
                     <el-dropdown-menu slot="dropdown">
-                        <el-dropdown-item command="logout"
-                            >退出登录
-                        </el-dropdown-item>
+                        <el-dropdown-item command="logout">退出登录 </el-dropdown-item>
                     </el-dropdown-menu>
                 </el-dropdown>
             </el-header>
-            <el-main style="background: #f2f4f5;height:100%">
+            <el-main style="background: #f2f4f5; height: 100%;">
                 <router-view></router-view>
             </el-main>
         </el-container>
@@ -75,49 +60,46 @@
 </template>
 
 <script>
-import SysMenu from "../components/SysMenu";
-import { mapState } from "vuex";
+import SysMenu from '../components/SysMenu';
+import { mapState } from 'vuex';
 
 export default {
-    name: "admin",
+    name: 'admin',
     created() {
         this.getMenus();
         let fn = () => {
-            this.isFullscreen =
-                document.fullScreen ||
-                document.mozFullScreen ||
-                document.webkitIsFullScreen;
+            this.isFullscreen = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen;
         };
-        document.addEventListener("fullscreenchange", fn);
-        document.addEventListener("webkitfullscreenchange", fn);
-        document.addEventListener("mozfullscreenchange", fn);
-        document.addEventListener("MSFullscreenChange", fn);
+        document.addEventListener('fullscreenchange', fn);
+        document.addEventListener('webkitfullscreenchange', fn);
+        document.addEventListener('mozfullscreenchange', fn);
+        document.addEventListener('MSFullscreenChange', fn);
     },
     data() {
         return {
             rawMenus: [],
             menus: [],
-            activeMenu: "",
+            activeMenu: '',
             menuPath: [],
-            collapse: localStorage.getItem("menu-collapse") == "true",
-            isFullscreen: false
+            collapse: localStorage.getItem('menu-collapse') == 'true',
+            isFullscreen: false,
         };
     },
     computed: {
-        ...mapState(["userInfo"])
+        ...mapState(['userInfo']),
     },
     methods: {
         findActiveMenu() {
-            this.activeMenu = "";
+            this.activeMenu = '';
             this.menuPath = [];
             let path = this.$route.path;
             const findActiveMenu = (parents, childMenus) => {
-                childMenus.forEach(i => {
+                childMenus.forEach((i) => {
                     let parents_copy = [...parents];
                     if (i.path === path) {
                         parents_copy.push(i);
-                        this.menuPath = parents_copy.map(i => i.name);
-                        this.activeMenu = "" + i.id;
+                        this.menuPath = parents_copy.map((i) => i.name);
+                        this.activeMenu = '' + i.id;
                     } else {
                         if (i.children) {
                             parents_copy.push(i);
@@ -130,8 +112,8 @@ export default {
         },
         getMenus() {
             this.$http
-                .get("/menu/userMenu", {
-                    name: "系统菜单"
+                .get('/menu/userMenu', {
+                    name: '系统菜单',
                 })
                 .then(([{ children: menus }]) => {
                     this.rawMenus = menus;
@@ -140,17 +122,12 @@ export default {
                 });
         },
         toggleFullScreen() {
-            this.isFullscreen =
-                document.fullScreen ||
-                document.mozFullScreen ||
-                document.webkitIsFullScreen;
+            this.isFullscreen = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen;
             let element = document.body;
             let requestMethod;
             if (this.isFullscreen) {
                 requestMethod =
-                    document.exitFullscreen ||
-                    document.mozCancelFullScreen ||
-                    document.webkitExitFullscreen;
+                    document.exitFullscreen || document.mozCancelFullScreen || document.webkitExitFullscreen;
             } else {
                 requestMethod =
                     element.requestFullScreen ||
@@ -163,32 +140,32 @@ export default {
             }
         },
         onCommand(command) {
-            if (command === "logout") {
-                localStorage.removeItem("token");
-                this.$store.commit("updateUserInfo", null);
-                this.$router.replace("/login");
+            if (command === 'logout') {
+                localStorage.removeItem('token');
+                this.$store.commit('updateUserInfo', null);
+                this.$router.replace('/login');
             }
-        }
+        },
     },
     watch: {
         $route(val) {
             this.findActiveMenu(this.rawMenus);
         },
         isFullscreen(val) {
-            this.$refs.fullscreen.innerHTML = "";
-            let i = document.createElement("i");
-            i.style.fontSize = "20px";
-            i.className = val ? "fas fa-compress" : "fas fa-expand";
+            this.$refs.fullscreen.innerHTML = '';
+            let i = document.createElement('i');
+            i.style.fontSize = '20px';
+            i.className = val ? 'fas fa-compress' : 'fas fa-expand';
             this.$refs.fullscreen.append(i);
             FontAwesome.dom.i2svg();
         },
         collapse(val) {
-            localStorage.setItem("menu-collapse", val);
-        }
+            localStorage.setItem('menu-collapse', val);
+        },
     },
     components: {
-        SysMenu
-    }
+        SysMenu,
+    },
 };
 </script>
 <style lang="less">

+ 76 - 75
src/main/vue/src/views/Api.vue

@@ -1,11 +1,22 @@
 <template>
     <div>
-        <el-form :model="formData" :rules="rules" ref="form" label-width="80px"
-            label-position="right" style="max-width: 800px;">
+        <el-form
+            :model="formData"
+            :rules="rules"
+            ref="form"
+            label-width="80px"
+            label-position="right"
+            style="max-width: 800px;"
+        >
             <el-form-item prop="url" label="URL">
-                <el-autocomplete style="width: 100%;" v-model="formData.url"
-                    :fetch-suggestions="querySearch" @select="handleSelect"
-                    placeholder="输入或选择" :clearable="true">
+                <el-autocomplete
+                    style="width: 100%;"
+                    v-model="formData.url"
+                    :fetch-suggestions="querySearch"
+                    @select="handleSelect"
+                    placeholder="输入或选择"
+                    :clearable="true"
+                >
                 </el-autocomplete>
             </el-form-item>
             <el-form-item prop="type" label="方法">
@@ -43,35 +54,34 @@
                 <el-table :data="params" :show-header="false" border>
                     <el-table-column label="key" prop="key">
                         <template slot-scope="{ row, column, $index }">
-                            <el-input v-model="row.key"
+                            <el-input
+                                v-model="row.key"
                                 @change="paramChange($event, $index)"
-                                placeholder="key" clearable></el-input>
+                                placeholder="key"
+                                clearable
+                            ></el-input>
                         </template>
                     </el-table-column>
                     <el-table-column label="value" prop="value">
                         <template slot-scope="{ row }">
-                            <el-input v-model="row.value" placeholder="value"
-                                clearable></el-input>
+                            <el-input v-model="row.value" placeholder="value" clearable></el-input>
                         </template>
                     </el-table-column>
                     <el-table-column width="60" align="center">
                         <template slot-scope="{ row, column, $index }">
-                            <el-button @click="removeParam($index)" type="text">
-                                删除</el-button>
+                            <el-button @click="removeParam($index)" type="text"> 删除</el-button>
                         </template>
                     </el-table-column>
                 </el-table>
             </el-form-item>
             <el-form-item>
-                <el-button @click="sendRequest" :loading="loading"
-                    type="primary">发送</el-button>
+                <el-button @click="sendRequest" :loading="loading" type="primary">发送</el-button>
             </el-form-item>
             <el-form-item v-if="showResult" label="Status">
-                <el-tag :type="statusType">{{statusCode}}</el-tag>
+                <el-tag :type="statusType">{{ statusCode }}</el-tag>
             </el-form-item>
             <el-form-item v-if="showResult" label="Response">
-                <el-tabs v-model="activeName" type="border-card"
-                    style="min-height: 150px;">
+                <el-tabs v-model="activeName" type="border-card" style="min-height: 150px;">
                     <el-tab-pane label="JSON" name="json">
                         <json-view :json="jsonResult"></json-view>
                     </el-tab-pane>
@@ -85,15 +95,15 @@
 </template>
 
 <script>
-import axios from "axios";
-import JsonView from "../components/JsonView";
+import axios from 'axios';
+import JsonView from '../components/JsonView';
 
 export default {
     created() {
         this.axios = axios.create({
-            baseURL: this.$baseUrl
+            baseURL: this.$baseUrl,
         });
-        this.$http.get("/dev/mappings").then(res => {
+        this.$http.get('/dev/mappings').then((res) => {
             this.urls = res.sort((a, b) => {
                 return a.className.localeCompare(b.className);
             });
@@ -103,41 +113,41 @@ export default {
         return {
             urls: [],
             formData: {
-                url: "",
-                method: "get"
+                url: '',
+                method: 'get',
             },
             params: [
                 {
-                    key: "",
-                    value: ""
-                }
+                    key: '',
+                    value: '',
+                },
             ],
             rules: {
-                url: [{ required: true, message: "请填写URL" }]
+                url: [{ required: true, message: '请填写URL' }],
             },
             jsonResult: {},
-            htmlResult: "",
-            statusCode: "",
-            statusType: "",
+            htmlResult: '',
+            statusCode: '',
+            statusType: '',
             showResult: false,
-            activeName: "json",
+            activeName: 'json',
             loading: false,
-            axios: {}
+            axios: {},
         };
     },
     methods: {
         querySearch(k, cb) {
             var arr = [];
-            this.urls.forEach(i => {
+            this.urls.forEach((i) => {
                 if (i.url.toLowerCase().indexOf(k.toLowerCase()) > -1) {
                     arr.push(i);
                 }
             });
             cb(
-                arr.map(i => {
+                arr.map((i) => {
                     return {
                         value: i.url,
-                        method: i.type
+                        method: i.type,
                     };
                 })
             );
@@ -148,46 +158,45 @@ export default {
         paramChange(e, i) {
             if (e && this.params.length - 1 === i) {
                 this.params.push({
-                    key: "",
-                    value: ""
+                    key: '',
+                    value: '',
                 });
             }
         },
         removeParam(i) {
             if (i === 0) {
                 this.$set(this.params, 0, {
-                    key: "",
-                    value: ""
+                    key: '',
+                    value: '',
                 });
             } else {
                 this.params.splice(i, 1);
             }
         },
         sendRequest() {
-            this.$refs.form.validate(valid => {
+            this.$refs.form.validate((valid) => {
                 if (valid) {
                     this.loading = true;
                     this.showResult = false;
                     this.jsonResult = {};
-                    this.htmlResult = "";
+                    this.htmlResult = '';
                     let req = {
                         method: this.formData.method,
                         url: this.formData.url,
                         headers: {
-                            Authorization:
-                                "Bearer " + localStorage.getItem("token")
-                        }
+                            Authorization: 'Bearer ' + localStorage.getItem('token'),
+                        },
                     };
-                    if (this.formData.method === "get") {
+                    if (this.formData.method === 'get') {
                         req.params = {};
-                        this.params.forEach(i => {
+                        this.params.forEach((i) => {
                             if (i.key) {
                                 req.params[i.key] = i.value;
                             }
                         });
                     } else {
                         let data = new FormData();
-                        this.params.forEach(i => {
+                        this.params.forEach((i) => {
                             if (i.key) {
                                 data.append(i.key, i.value);
                             }
@@ -195,65 +204,57 @@ export default {
                         req.data = data;
                     }
                     this.axios(req)
-                        .then(res => {
+                        .then((res) => {
                             this.loading = false;
                             this.showResult = true;
-                            this.statusCode = res.status + " " + res.statusText;
+                            this.statusCode = res.status + ' ' + res.statusText;
                             if (res.status === 200) {
-                                this.statusType = "success";
+                                this.statusType = 'success';
                                 if (
-                                    res.headers["content-type"] &&
-                                    res.headers["content-type"]
-                                        .toLowerCase()
-                                        .indexOf("json") !== -1
+                                    res.headers['content-type'] &&
+                                    res.headers['content-type'].toLowerCase().indexOf('json') !== -1
                                 ) {
-                                    this.activeName = "json";
+                                    this.activeName = 'json';
                                     this.jsonResult = res.data;
                                     this.htmlResult = res.data;
                                 } else {
-                                    this.activeName = "html";
+                                    this.activeName = 'html';
                                     this.htmlResult = res.data;
                                 }
                             } else {
-                                this.statusType = "danger";
-                                this.activeName = "html";
+                                this.statusType = 'danger';
+                                this.activeName = 'html';
                             }
                         })
-                        .catch(error => {
+                        .catch((error) => {
                             console.log(error.response);
                             this.loading = false;
                             this.showResult = true;
-                            this.statusType = "danger";
-                            this.activeName = "html";
+                            this.statusType = 'danger';
+                            this.activeName = 'html';
                             if (error.response) {
                                 this.htmlResult = error.response.data;
-                                this.statusCode =
-                                    error.response.status +
-                                    " " +
-                                    error.response.statusText;
+                                this.statusCode = error.response.status + ' ' + error.response.statusText;
                                 if (
-                                    error.response.headers["content-type"] &&
-                                    error.response.headers["content-type"]
-                                        .toLowerCase()
-                                        .indexOf("json") !== -1
+                                    error.response.headers['content-type'] &&
+                                    error.response.headers['content-type'].toLowerCase().indexOf('json') !== -1
                                 ) {
-                                    this.activeName = "json";
+                                    this.activeName = 'json';
                                     this.jsonResult = error.response.data;
                                 }
                             } else {
                                 this.htmlResult = error;
-                                this.statusCode = "ERROR";
+                                this.statusCode = 'ERROR';
                             }
                         });
                 }
             });
-        }
+        },
     },
     components: {
-        JsonView
-    }
+        JsonView,
+    },
 };
 </script>
 
-<style scoped>
-</style>
+<style scoped></style>

+ 37 - 21
src/main/vue/src/views/Dashboard.vue

@@ -1,45 +1,61 @@
 <template>
     <div>
-        <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">
+        <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>
         <el-button v-if="editable" @click="save">保存</el-button>
-        <el-button v-else @click="editable=true">编辑</el-button>
+        <el-button v-else @click="editable = true">编辑</el-button>
     </div>
 </template>
 
 <script>
-import { GridLayout, GridItem } from "vue-grid-layout";
-import UserWidget from "../widgets/UserWidget";
-import LineChartWidget from "../widgets/LineChartWidget";
-import BarChartWidget from "../widgets/BarChartWidget";
-import PieChartWidget from "../widgets/PieChartWidget";
+import { GridLayout, GridItem } from 'vue-grid-layout';
+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: "UserWidget" },
-                { 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" }
+                { x: 0, y: 0, w: 6, h: 4, i: '0', name: 'UserWidget' },
+                { 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
+            editable: false,
         };
     },
     methods: {
         save() {
             console.log(JSON.stringify(this.layout));
             this.editable = false;
-        }
+        },
     },
     components: {
         GridLayout,
@@ -47,8 +63,8 @@ export default {
         UserWidget,
         LineChartWidget,
         BarChartWidget,
-        PieChartWidget
-    }
+        PieChartWidget,
+    },
 };
 </script>
 

+ 181 - 237
src/main/vue/src/views/GenCodeEdit.vue

@@ -1,96 +1,87 @@
 <template>
     <div v-loading="loading" element-loading-text="拼命加载中">
-        <el-form :model="formData" :rules="rules" ref="form" label-width="80px"
-                 label-position="right" size="mini">
-
+        <el-form :model="formData" :rules="rules" ref="form" label-width="80px" label-position="right" size="mini">
             <el-form-item prop="tableName" label="表名">
-                <el-select placeholder="表名" clearable filterable
-                           v-model="formData.tableName" @change="changeTableName"
-                           class="filter-item">
-                    <el-option v-for="item in tableList" :label="item.name"
-                               :value="item.name" :key="item.name"></el-option>
+                <el-select
+                    placeholder="表名"
+                    clearable
+                    filterable
+                    v-model="formData.tableName"
+                    @change="changeTableName"
+                    class="filter-item"
+                >
+                    <el-option
+                        v-for="item in tableList"
+                        :label="item.name"
+                        :value="item.name"
+                        :key="item.name"
+                    ></el-option>
                 </el-select>
-
             </el-form-item>
 
             <el-form-item prop="className" label="类名">
-                <el-input v-model="formData.className" style="width: 400px;">
-                </el-input>
+                <el-input v-model="formData.className" style="width: 400px;"> </el-input>
             </el-form-item>
 
             <el-form-item prop="tablePackage" label="包名">
-                <el-input v-model="formData.tablePackage" style="width: 400px;">
-                </el-input>
+                <el-input v-model="formData.tablePackage" style="width: 400px;"> </el-input>
             </el-form-item>
 
             <el-form-item prop="remark" label="描述">
-                <el-input v-model="formData.remark" style="width: 400px;">
-                </el-input>
+                <el-input v-model="formData.remark" style="width: 400px;"> </el-input>
             </el-form-item>
 
             <el-form-item label="目录">
-                {{formData.javaPath}}<br>
-                {{formData.viewPath}}<br>
-                {{formData.routerPath}}<br>
-                {{formData.resourcesPath}}
+                {{ formData.javaPath }}<br />
+                {{ formData.viewPath }}<br />
+                {{ formData.routerPath }}<br />
+                {{ formData.resourcesPath }}
             </el-form-item>
 
             <el-form-item prop="genCode" label="生成">
-                <el-checkbox v-model="formData.genClass" label="类">
-                </el-checkbox>
-                <el-checkbox v-model="formData.genList" label="列表">
-                </el-checkbox>
-                <el-checkbox v-model="formData.genForm" label="表单">
-                </el-checkbox>
-                <el-checkbox v-model="formData.genRouter" label="路由">
-                </el-checkbox>
+                <el-checkbox v-model="formData.genClass" label="类"> </el-checkbox>
+                <el-checkbox v-model="formData.genList" label="列表"> </el-checkbox>
+                <el-checkbox v-model="formData.genForm" label="表单"> </el-checkbox>
+                <el-checkbox v-model="formData.genRouter" label="路由"> </el-checkbox>
             </el-form-item>
             <el-form-item prop="fields" label="数据">
                 <el-tabs value="1" type="border-card">
                     <el-tab-pane label="字段" name="1">
                         <el-table :data="fields">
-                            <el-table-column prop="name" label="字段名" width="200"
-                                             align="center">
-                                <template slot-scope="{row}">
+                            <el-table-column prop="name" label="字段名" width="200" align="center">
+                                <template slot-scope="{ row }">
                                     <el-input v-model="row.name"></el-input>
                                 </template>
                             </el-table-column>
-                            <el-table-column prop="remark" label="描述"
-                                             align="center" width="200">
-                                <template slot-scope="{row}">
+                            <el-table-column prop="remark" label="描述" align="center" width="200">
+                                <template slot-scope="{ row }">
                                     <el-input v-model="row.remark"></el-input>
                                 </template>
                             </el-table-column>
                             <el-table-column width="130" align="center">
                                 <template slot-scope="{ row, column, $index }">
-                                    <el-button @click="moveUp($index)"
-                                               type="text">上移</el-button>
-                                    <el-button @click="moveDown($index)"
-                                               type="text">下移</el-button>
-                                    <el-button @click="removeField($index)"
-                                               type="text">删除</el-button>
+                                    <el-button @click="moveUp($index)" type="text">上移</el-button>
+                                    <el-button @click="moveDown($index)" type="text">下移</el-button>
+                                    <el-button @click="removeField($index)" type="text">删除</el-button>
                                 </template>
                             </el-table-column>
                         </el-table>
-                        <el-button @click="addField" type="text"
-                                   icon="el-icon-plus">添加</el-button>
+                        <el-button @click="addField" type="text" icon="el-icon-plus">添加</el-button>
                     </el-tab-pane>
                     <el-tab-pane label="页面属性" name="2">
                         <el-table :data="editableFields">
-                            <el-table-column prop="name" label="字段" width="200">
-                            </el-table-column>
-                            <el-table-column prop="showInList" label="列表"
-                                             width="50" align="center">
-                                <template slot-scope="{row}">
-                                    <el-checkbox v-model="row.showInList">
-                                    </el-checkbox>
+                            <el-table-column prop="name" label="字段" width="200"> </el-table-column>
+                            <el-table-column prop="showInList" label="列表" width="50" align="center">
+                                <template slot-scope="{ row }">
+                                    <el-checkbox v-model="row.showInList"> </el-checkbox>
                                 </template>
                             </el-table-column>
-                            <el-table-column prop="showInForm" label="表单"
-                                             width="50" align="center">
-                                <template slot-scope="{row}">
-                                    <el-checkbox v-model="row.showInForm"
-                                                 :disabled="row.primaryKey&&!formData.readTable">
+                            <el-table-column prop="showInForm" label="表单" width="50" align="center">
+                                <template slot-scope="{ row }">
+                                    <el-checkbox
+                                        v-model="row.showInForm"
+                                        :disabled="row.primaryKey && !formData.readTable"
+                                    >
                                     </el-checkbox>
                                 </template>
                             </el-table-column>
@@ -99,45 +90,60 @@
                                     <el-checkbox v-model="row.sortable"></el-checkbox>
                                 </template>
                             </el-table-column> -->
-                            <el-table-column prop="formType" label="表单类型"
-                                             width="150" align="center">
-                                <template slot-scope="{row}">
+                            <el-table-column prop="formType" label="表单类型" width="150" align="center">
+                                <template slot-scope="{ row }">
                                     <el-select v-model="row.formType">
-                                        <el-option v-for="item in formTypes"
-                                                   :label="item.label"
-                                                   :value="item.value"
-                                                   :key="item.value"></el-option>
+                                        <el-option
+                                            v-for="item in formTypes"
+                                            :label="item.label"
+                                            :value="item.value"
+                                            :key="item.value"
+                                        ></el-option>
                                     </el-select>
                                 </template>
                             </el-table-column>
-                            <el-table-column prop="apiFlag" label="接口"
-                                             width="300" align="center">
-                                <template slot-scope="{row}">
-                                    <el-radio v-model="row.apiFlag" label="1"
-                                              :disabled="row.formType!=='select'&&row.formType!=='multiSelect'">
+                            <el-table-column prop="apiFlag" label="接口" width="300" align="center">
+                                <template slot-scope="{ row }">
+                                    <el-radio
+                                        v-model="row.apiFlag"
+                                        label="1"
+                                        :disabled="row.formType !== 'select' && row.formType !== 'multiSelect'"
+                                    >
                                         枚举
                                     </el-radio>
-                                    <el-radio v-model="row.apiFlag" label="2"
-                                              :disabled="row.formType!=='select'&&row.formType!=='multiSelect'">
+                                    <el-radio
+                                        v-model="row.apiFlag"
+                                        label="2"
+                                        :disabled="row.formType !== 'select' && row.formType !== 'multiSelect'"
+                                    >
                                         接口
                                     </el-radio>
                                 </template>
                             </el-table-column>
-                            <el-table-column prop="optionsValue" label="选项"
-                                             min-width="150" align="center">
-                                <template slot-scope="{row}">
-                                    <el-input class="code"
-                                              v-model="row.optionsValue" autosize
-                                              v-if="row.apiFlag==='1'&&(row.formType==='select'||row.formType==='multiSelect')">
-                                        <el-button slot="append" type="text"
-                                                   @click="editOptions(row)">编辑
-                                        </el-button>
+                            <el-table-column prop="optionsValue" label="选项" min-width="150" align="center">
+                                <template slot-scope="{ row }">
+                                    <el-input
+                                        class="code"
+                                        v-model="row.optionsValue"
+                                        autosize
+                                        v-if="
+                                            row.apiFlag === '1' &&
+                                            (row.formType === 'select' || row.formType === 'multiSelect')
+                                        "
+                                    >
+                                        <el-button slot="append" type="text" @click="editOptions(row)">编辑 </el-button>
                                     </el-input>
-                                    <el-input class="code"
-                                              :value="optionsInfo(row)" disabled
-                                              v-if="(row.apiFlag==='2'||row.apiFlag==='3')&&(row.formType==='select'||row.formType==='multiSelect')">
-                                        <el-button slot="append" type="text"
-                                                   @click="editSelectField(row)">编辑
+                                    <el-input
+                                        class="code"
+                                        :value="optionsInfo(row)"
+                                        disabled
+                                        v-if="
+                                            (row.apiFlag === '2' || row.apiFlag === '3') &&
+                                            (row.formType === 'select' || row.formType === 'multiSelect')
+                                        "
+                                    >
+                                        <el-button slot="append" type="text" @click="editSelectField(row)"
+                                            >编辑
                                         </el-button>
                                     </el-input>
                                 </template>
@@ -153,8 +159,7 @@
                     </el-tab-pane>
                     <el-tab-pane label="表单校验" name="3">
                         <el-table :data="fields">
-                            <el-table-column prop="name" label="字段" width="200">
-                            </el-table-column>
+                            <el-table-column prop="name" label="字段" width="200"> </el-table-column>
                             <!-- <el-table-column prop="logicalKey" label="逻辑关键字"
                                              width="100" align="center">
                                 <template slot-scope="{row}">
@@ -162,56 +167,45 @@
                                     </el-checkbox>
                                 </template>
                             </el-table-column> -->
-                            <el-table-column prop="required" label="必填"
-                                             width="50" align="center">
-                                <template slot-scope="{row}">
-                                    <el-checkbox v-model="row.required">
-                                    </el-checkbox>
+                            <el-table-column prop="required" label="必填" width="50" align="center">
+                                <template slot-scope="{ row }">
+                                    <el-checkbox v-model="row.required"> </el-checkbox>
                                 </template>
                             </el-table-column>
-                            <el-table-column prop="validate" label="校验"
-                                             width="50" align="center">
-                                <template slot-scope="{row}">
-                                    <el-checkbox v-model="row.validate">
-                                    </el-checkbox>
+                            <el-table-column prop="validate" label="校验" width="50" align="center">
+                                <template slot-scope="{ row }">
+                                    <el-checkbox v-model="row.validate"> </el-checkbox>
                                 </template>
                             </el-table-column>
-                            <el-table-column prop="minLength" label="最短"
-                                             min-width="80" align="center">
-                                <template slot-scope="{row}">
-                                    <el-input v-model.number="row.minLength">
-                                    </el-input>
+                            <el-table-column prop="minLength" label="最短" min-width="80" align="center">
+                                <template slot-scope="{ row }">
+                                    <el-input v-model.number="row.minLength"> </el-input>
                                 </template>
                             </el-table-column>
-                            <el-table-column prop="maxLength" label="最长"
-                                             min-width="80" align="center">
-                                <template slot-scope="{row}">
-                                    <el-input v-model.number="row.maxLength">
-                                    </el-input>
+                            <el-table-column prop="maxLength" label="最长" min-width="80" align="center">
+                                <template slot-scope="{ row }">
+                                    <el-input v-model.number="row.maxLength"> </el-input>
                                 </template>
                             </el-table-column>
-                            <el-table-column prop="min" label="最小值"
-                                             min-width="80" align="center">
-                                <template slot-scope="{row}">
+                            <el-table-column prop="min" label="最小值" min-width="80" align="center">
+                                <template slot-scope="{ row }">
                                     <el-input v-model="row.min"></el-input>
                                 </template>
                             </el-table-column>
-                            <el-table-column prop="max" label="最大值"
-                                             min-width="80" align="center">
-                                <template slot-scope="{row}">
+                            <el-table-column prop="max" label="最大值" min-width="80" align="center">
+                                <template slot-scope="{ row }">
                                     <el-input v-model="row.max"></el-input>
                                 </template>
                             </el-table-column>
-                            <el-table-column prop="validatorType" label="校验类型"
-                                             min-width="150" align="center">
-                                <template slot-scope="{row}">
-                                    <el-select v-model="row.validatorType"
-                                               clearable>
+                            <el-table-column prop="validatorType" label="校验类型" min-width="150" align="center">
+                                <template slot-scope="{ row }">
+                                    <el-select v-model="row.validatorType" clearable>
                                         <el-option
-                                                   v-for="item in validatorTypes"
-                                                   :label="item.label"
-                                                   :value="item.value"
-                                                   :key="item.value"></el-option>
+                                            v-for="item in validatorTypes"
+                                            :label="item.label"
+                                            :value="item.value"
+                                            :key="item.value"
+                                        ></el-option>
                                     </el-select>
                                 </template>
                             </el-table-column>
@@ -219,89 +213,78 @@
                     </el-tab-pane>
                     <el-tab-pane label="子表" name="4">
                         <el-table :data="subtables">
-
-                            <el-table-column prop="name" label="控件名" width="150"
-                                             align="center">
-                                <template slot-scope="{row}">
+                            <el-table-column prop="name" label="控件名" width="150" align="center">
+                                <template slot-scope="{ row }">
                                     <el-input v-model="row.name"></el-input>
                                 </template>
                             </el-table-column>
 
-                            <el-table-column prop="column" label="主表字段"
-                                             width="150" align="center">
-                                <template slot-scope="{row}">
+                            <el-table-column prop="column" label="主表字段" width="150" align="center">
+                                <template slot-scope="{ row }">
                                     <el-input v-model="row.column"></el-input>
                                 </template>
                             </el-table-column>
 
-                            <el-table-column prop="subColumn" label="子表字段"
-                                             width="150" align="center">
-                                <template slot-scope="{row}">
-                                    <el-input v-model="row.subColumn">
-                                    </el-input>
+                            <el-table-column prop="subColumn" label="子表字段" width="150" align="center">
+                                <template slot-scope="{ row }">
+                                    <el-input v-model="row.subColumn"> </el-input>
                                 </template>
                             </el-table-column>
-                            <el-table-column prop="subCode" label="子表类"
-                                             width="150" align="center">
-                                <template slot-scope="{row}">
+                            <el-table-column prop="subCode" label="子表类" width="150" align="center">
+                                <template slot-scope="{ row }">
                                     <el-select v-model="row.subCode" clearable>
-                                        <el-option v-for="item in subCodes"
-                                                   :label="item.className"
-                                                   :value="item.className"
-                                                   :key="item.className"></el-option>
+                                        <el-option
+                                            v-for="item in subCodes"
+                                            :label="item.className"
+                                            :value="item.className"
+                                            :key="item.className"
+                                        ></el-option>
                                     </el-select>
                                 </template>
                             </el-table-column>
                             <el-table-column width="60" align="center">
                                 <template slot-scope="{ row, column, $index }">
-                                    <el-button @click="removeSubtable($index)"
-                                               type="text">删除</el-button>
+                                    <el-button @click="removeSubtable($index)" type="text">删除</el-button>
                                 </template>
                             </el-table-column>
                         </el-table>
-                        <el-button @click="addSubtable" type="text"
-                                   icon="el-icon-plus">添加</el-button>
+                        <el-button @click="addSubtable" type="text" icon="el-icon-plus">添加</el-button>
                     </el-tab-pane>
                 </el-tabs>
-
             </el-form-item>
             <el-form-item>
-                <el-button @click="onSave" :loading="$store.state.fetchingData"
-                           type="primary">保存</el-button>
+                <el-button @click="onSave" :loading="$store.state.fetchingData" type="primary">保存</el-button>
                 <el-button @click="$router.go(-1)">取消</el-button>
             </el-form-item>
         </el-form>
 
         <el-dialog title="接口选项" :visible.sync="showApiSelectDialog">
-            <el-form :model="selectField" label-position="right"
-                     label-width="80px">
+            <el-form :model="selectField" label-position="right" label-width="80px">
                 <el-form-item label="接口">
-                    <el-select placeholder="接口" filterable clearable
-                               v-model="selectField.optionsMethod" class="filter-item">
-                        <el-option v-for="item in selectMappings"
-                                   :label="item.url" :value="item.url" :key="item.url">
+                    <el-select
+                        placeholder="接口"
+                        filterable
+                        clearable
+                        v-model="selectField.optionsMethod"
+                        class="filter-item"
+                    >
+                        <el-option v-for="item in selectMappings" :label="item.url" :value="item.url" :key="item.url">
                         </el-option>
                     </el-select>
                 </el-form-item>
                 <el-form-item label="显示">
-                    <el-input
-                              v-model="selectField.optionsLabel">
-                    </el-input>
+                    <el-input v-model="selectField.optionsLabel"> </el-input>
                 </el-form-item>
                 <el-form-item label="选项">
-                    <el-input
-                              v-model="selectField.optionsValue">
-                    </el-input>
+                    <el-input v-model="selectField.optionsValue"> </el-input>
                 </el-form-item>
             </el-form>
             <span slot="footer" class="dialog-footer">
-                <el-button type="primary" @click="selectMappingSubmit">确定
-                </el-button>
+                <el-button type="primary" @click="selectMappingSubmit">确定 </el-button>
             </span>
         </el-dialog>
 
-        <gen-option-dialog :visible.sync="showGenOptionsDialog"
-                           v-model="tempRow.optionsValue"></gen-option-dialog>
+        <gen-option-dialog :visible.sync="showGenOptionsDialog" v-model="tempRow.optionsValue"></gen-option-dialog>
     </div>
 </template>
 
@@ -316,7 +299,7 @@ export default {
                 .get('/genCode/getOne', {
                     className: this.$route.query.className,
                 })
-                .then(res => {
+                .then((res) => {
                     console.log(res);
                     this.loading = false;
 
@@ -324,7 +307,7 @@ export default {
                         .get('/genCode/tableFields', {
                             className: res.tablePackage,
                         })
-                        .then(fields => {
+                        .then((fields) => {
                             this.formData = {
                                 ...this.formData,
                                 ...res,
@@ -334,8 +317,8 @@ export default {
                             };
                             let finalFields = [];
 
-                            fields.forEach(field => {
-                                let f = this.formData.fields.find(i => {
+                            fields.forEach((field) => {
+                                let f = this.formData.fields.find((i) => {
                                     return (i.modelName = field.modalName);
                                 });
                                 if (f) {
@@ -347,11 +330,11 @@ export default {
                             this.fields = finalFields;
                             this.subtables = this.formData.subtables;
                         })
-                        .catch(e => {
+                        .catch((e) => {
                             console.log(e);
                         });
                 })
-                .catch(e => {
+                .catch((e) => {
                     console.log(e);
                     this.loading = false;
                 });
@@ -367,14 +350,14 @@ export default {
                     return Promise.resolve();
                 }
             })
-            .then(res => {
+            .then((res) => {
                 this.loading = false;
                 if (res) {
                     this.$http
                         .get('/genCode/tableFields', {
                             className: res.tablePackage,
                         })
-                        .then(fields => {
+                        .then((fields) => {
                             this.formData = {
                                 ...this.formData,
                                 ...res,
@@ -384,8 +367,8 @@ export default {
                             };
                             let finalFields = [];
 
-                            fields.forEach(field => {
-                                let f = res.fields.find(item => {
+                            fields.forEach((field) => {
+                                let f = res.fields.find((item) => {
                                     return item.modelName === field.modelName;
                                 });
                                 if (f) {
@@ -397,19 +380,19 @@ export default {
                             this.fields = finalFields;
                             this.subtables = this.formData.subtables;
                         })
-                        .catch(e => {
+                        .catch((e) => {
                             console.log(e);
                         });
                 }
                 return this.$http.get('/genCode/getSrcPath');
             })
-            .then(res => {
+            .then((res) => {
                 this.formData.javaPath = res.javaPath;
                 this.formData.viewPath = res.viewPath;
                 this.formData.routerPath = res.routerPath;
                 this.formData.resourcesPath = res.resourcesPath;
             })
-            .catch(e => {
+            .catch((e) => {
                 console.log(e);
                 this.$message.error(e.error);
                 this.loading = false;
@@ -417,26 +400,26 @@ export default {
 
         this.$http
             .get('/genCode/all')
-            .then(res => {
+            .then((res) => {
                 this.subCodes = res;
             })
-            .catch(e => {
+            .catch((e) => {
                 console.log(e);
             });
 
         this.$http
             .get('/dev/selectMappings')
-            .then(res => {
+            .then((res) => {
                 let temp = {};
                 if (res.length > 0) {
-                    res.forEach(item => {
+                    res.forEach((item) => {
                         temp[item.url] = item;
                     });
                 }
                 this.selectMappingsJson = temp;
                 this.selectMappings = res;
             })
-            .catch(e => {
+            .catch((e) => {
                 console.log(e);
             });
 
@@ -445,30 +428,8 @@ export default {
     data() {
         return {
             loading: false,
-            fieldTypes: [
-                'char',
-                'varchar',
-                'int',
-                'bit',
-                'text',
-                'timestamp',
-                'datetime',
-                'decimal',
-                'float',
-                'vue',
-            ],
-            searchMethods: [
-                '=',
-                '!=',
-                '>',
-                '>=',
-                '<',
-                '<=',
-                'between',
-                'like',
-                'left like',
-                'right like',
-            ],
+            fieldTypes: ['char', 'varchar', 'int', 'bit', 'text', 'timestamp', 'datetime', 'decimal', 'float', 'vue'],
+            searchMethods: ['=', '!=', '>', '>=', '<', '<=', 'between', 'like', 'left like', 'right like'],
             formTypes: [
                 { label: '单行文本', value: 'singleLineText' },
                 { label: '数字', value: 'number' },
@@ -501,9 +462,7 @@ export default {
                     {
                         validator: (rule, value, callback) => {
                             if (value) {
-                                if (
-                                    /^[\u4e00-\u9fa5a-zA-Z0-9_]*$/.test(value)
-                                ) {
+                                if (/^[\u4e00-\u9fa5a-zA-Z0-9_]*$/.test(value)) {
                                     callback();
                                 } else {
                                     callback(new Error('类名不正确'));
@@ -518,9 +477,7 @@ export default {
                     {
                         validator: (rule, value, callback) => {
                             if (value) {
-                                if (
-                                    /^[\u4e00-\u9fa5a-zA-Z0-9_]*$/.test(value)
-                                ) {
+                                if (/^[\u4e00-\u9fa5a-zA-Z0-9_]*$/.test(value)) {
                                     callback();
                                 } else {
                                     callback(new Error('表名不正确'));
@@ -530,9 +487,7 @@ export default {
                         trigger: 'blur',
                     },
                 ],
-                remark: [
-                    { required: true, message: '请填写描述', trigger: 'blur' },
-                ],
+                remark: [{ required: true, message: '请填写描述', trigger: 'blur' }],
                 dataBaseType: [
                     {
                         required: true,
@@ -589,14 +544,14 @@ export default {
     },
     computed: {
         editableFields() {
-            return this.fields.filter(i => {
+            return this.fields.filter((i) => {
                 return i.name;
             });
         },
     },
     methods: {
         onSave() {
-            this.$refs.form.validate(valid => {
+            this.$refs.form.validate((valid) => {
                 if (valid) {
                     this.submit();
                 } else {
@@ -609,11 +564,7 @@ export default {
             this.formData.subtables = this.subtables;
             this.formData.genJson = '';
 
-            this.$alert(
-                '生成代码可能会删除已有同名表、数据或文件,确认要生成么?',
-                '警告',
-                { type: 'error' },
-            )
+            this.$alert('生成代码可能会删除已有同名表、数据或文件,确认要生成么?', '警告', { type: 'error' })
                 .then(() => {
                     this.loading = true;
                     return this.$http.post('/genCode/save', this.formData, {
@@ -625,7 +576,7 @@ export default {
                     this.$message.success('代码生成成功');
                     this.$router.go(-1);
                 })
-                .catch(e => {
+                .catch((e) => {
                     this.loading = false;
                     if ('cancel' === e) {
                         this.$message.info('生成取消');
@@ -657,16 +608,16 @@ export default {
             this.tableList = [];
             this.$http
                 .get('/dev/entities')
-                .then(res => {
+                .then((res) => {
                     this.tableList = res;
                 })
-                .catch(e => {
+                .catch((e) => {
                     console.log(e);
                 });
         },
         getPackageByTableName(tableName) {
             var packageName = '';
-            this.tableList.forEach(item => {
+            this.tableList.forEach((item) => {
                 if (item.name == tableName) {
                     packageName = item.package;
                 }
@@ -676,9 +627,7 @@ export default {
         changeTableName() {
             this.fields = [];
             this.formData.className = this.formData.tableName;
-            this.formData.tablePackage = this.getPackageByTableName(
-                this.formData.tableName,
-            );
+            this.formData.tablePackage = this.getPackageByTableName(this.formData.tableName);
             this.getTableFields(this.formData.tableName);
         },
         changeOptionsTableName() {
@@ -692,10 +641,10 @@ export default {
             };
             this.$http
                 .get('/genCode/tableFields', data)
-                .then(res => {
+                .then((res) => {
                     this.fields = res;
                 })
-                .catch(e => {
+                .catch((e) => {
                     console.log(e);
                 });
         },
@@ -705,10 +654,10 @@ export default {
             };
             this.$http
                 .get('/genCode/tableFields', data)
-                .then(res => {
+                .then((res) => {
                     this.optionsFields = res;
                 })
-                .catch(e => {
+                .catch((e) => {
                     console.log(e);
                 });
         },
@@ -760,12 +709,7 @@ export default {
             if (row.apiFlag === '1') {
                 value = row.optionsValue;
             } else if (row.apiFlag === '2') {
-                value =
-                    row.optionsMethod +
-                    ',' +
-                    row.optionsLabel +
-                    ',' +
-                    row.optionsValue;
+                value = row.optionsMethod + ',' + row.optionsLabel + ',' + row.optionsValue;
             }
             return value;
         },
@@ -787,7 +731,7 @@ export default {
 
 <style lang="less" scoped>
 .code {
-    font-family: 'dejavu sans mono', 'droid sans mono', consolas, monaco,
-        'lucida console', 'courier new', courier, monospace, sans-serif;
+    font-family: 'dejavu sans mono', 'droid sans mono', consolas, monaco, 'lucida console', 'courier new', courier,
+        monospace, sans-serif;
 }
 </style>

+ 13 - 26
src/main/vue/src/views/GenCodeList.vue

@@ -1,14 +1,9 @@
 <template>
     <div class="edit-view">
         <div class="filters-container">
-            <el-input placeholder="输入关键字" v-model="search" clearable
-                      class="filter-item"></el-input>
-            <el-button @click="getData" type="primary" icon="el-icon-search"
-                       class="filter-item">搜索
-            </el-button>
-            <el-button @click="addRow" type="primary" icon="el-icon-plus"
-                       class="filter-item">添加
-            </el-button>
+            <el-input placeholder="输入关键字" v-model="search" clearable class="filter-item"></el-input>
+            <el-button @click="getData" type="primary" icon="el-icon-search" class="filter-item">搜索 </el-button>
+            <el-button @click="addRow" type="primary" icon="el-icon-plus" class="filter-item">添加 </el-button>
             <!-- <el-dropdown trigger="click" size="medium"
                          class="table-column-filter">
                 <span>
@@ -24,29 +19,22 @@
             </el-dropdown> -->
         </div>
         <el-table :data="tableData" row-key="id" ref="table">
-            <el-table-column type="index" min-width="50" align="center">
+            <el-table-column type="index" min-width="50" align="center"> </el-table-column>
+            <el-table-column v-if="isColumnShow('tableName')" prop="tableName" label="表名" min-width="100">
             </el-table-column>
-            <el-table-column v-if="isColumnShow('tableName')" prop="tableName"
-                             label="表名" min-width="100">
-            </el-table-column>
-            <el-table-column v-if="isColumnShow('className')" prop="className"
-                             label="类名" min-width="100">
+            <el-table-column v-if="isColumnShow('className')" prop="className" label="类名" min-width="100">
             </el-table-column>
             <!-- <el-table-column v-if="isColumnShow('typeFlag')" prop="typeFlag"
                              label="分类" min-width="100">
             </el-table-column> -->
-            <el-table-column v-if="isColumnShow('remark')" prop="remark"
-                             label="备注" min-width="100">
+            <el-table-column v-if="isColumnShow('remark')" prop="remark" label="备注" min-width="100">
             </el-table-column>
-            <el-table-column label="操作" align="center" fixed="right"
-                             min-width="150">
+            <el-table-column label="操作" align="center" fixed="right" min-width="150">
                 <template slot-scope="scope">
-                    <el-button @click="editRow(scope.row)" type="primary"
-                               size="mini" plain>编辑</el-button>
+                    <el-button @click="editRow(scope.row)" type="primary" size="mini" plain>编辑</el-button>
                 </template>
             </el-table-column>
         </el-table>
-
     </div>
 </template>
 <script>
@@ -93,10 +81,10 @@ export default {
 
             this.$http
                 .get(this.url, data)
-                .then(res => {
+                .then((res) => {
                     this.tableData = res;
                 })
-                .catch(e => {
+                .catch((e) => {
                     console.log(e);
                     this.$message.error(e.error);
                 });
@@ -120,7 +108,7 @@ export default {
         },
 
         isColumnShow(column) {
-            var row = this.tableColumns.find(i => i.value === column);
+            var row = this.tableColumns.find((i) => i.value === column);
             return row ? row.show : false;
         },
         operation1() {
@@ -135,5 +123,4 @@ export default {
     },
 };
 </script>
-<style lang="less" scoped>
-</style>
+<style lang="less" scoped></style>

+ 91 - 103
src/main/vue/src/views/Login.vue

@@ -1,31 +1,22 @@
 <template>
-    <div class="container"
-        :style="{backgroundImage :'url(' + require('../assets/bg_login.jpg') + ')'}">
-        <transition :name="`slide-${register?'in':'out'}`">
-            <div class="login-wrapper" @keyup.enter="doRegister" v-if="register"
-                key="register">
-
-                <el-page-header @back="register=false" title="登录"
-                    style="width: 350px;line-height: 60px;">
+    <div class="container" :style="{ backgroundImage: 'url(' + require('../assets/bg_login.jpg') + ')' }">
+        <transition :name="`slide-${register ? 'in' : 'out'}`">
+            <div class="login-wrapper" @keyup.enter="doRegister" v-if="register" key="register">
+                <el-page-header @back="register = false" title="登录" style="width: 350px; line-height: 60px;">
                     <div class="register-title" slot="content">注册账号</div>
                 </el-page-header>
 
-                <el-form :model="registerInfo" style="width: 350px"
-                    ref="registerForm">
-                    <el-form-item prop="username"
-                        :rules="{required: true, message: '请输入用户名', trigger: 'blur'}">
-                        <el-input v-model="registerInfo.username"
-                            placeholder="用户名">
-                        </el-input>
+                <el-form :model="registerInfo" style="width: 350px;" ref="registerForm">
+                    <el-form-item prop="username" :rules="{ required: true, message: '请输入用户名', trigger: 'blur' }">
+                        <el-input v-model="registerInfo.username" placeholder="用户名"> </el-input>
                     </el-form-item>
-                    <el-form-item prop="password"
-                        :rules="{required: true, message: '请输入密码', trigger: 'blur'}">
-                        <el-input v-model="registerInfo.password"
-                            placeholder="密码" type="password"></el-input>
+                    <el-form-item prop="password" :rules="{ required: true, message: '请输入密码', trigger: 'blur' }">
+                        <el-input v-model="registerInfo.password" placeholder="密码" type="password"></el-input>
                     </el-form-item>
                     <el-form-item>
-                        <el-button :loading="loading" @click="doRegister"
-                            type="primary" style="width: 100%;">注册</el-button>
+                        <el-button :loading="loading" @click="doRegister" type="primary" style="width: 100%;"
+                            >注册</el-button
+                        >
                     </el-form-item>
                 </el-form>
             </div>
@@ -33,22 +24,22 @@
                 <div class="title">欢迎登录</div>
                 <el-tabs v-model="activeName" stretch class="tab-list">
                     <el-tab-pane label="用户名登陆" name="first">
-                        <el-form :model="userInfo" style="width: 350px"
-                            ref="form">
-                            <el-form-item prop="username"
-                                :rules="{required: true, message: '请输入用户名', trigger: 'blur'}">
-                                <el-input v-model="userInfo.username"
-                                    placeholder="用户名">
-                                </el-input>
+                        <el-form :model="userInfo" style="width: 350px;" ref="form">
+                            <el-form-item
+                                prop="username"
+                                :rules="{ required: true, message: '请输入用户名', trigger: 'blur' }"
+                            >
+                                <el-input v-model="userInfo.username" placeholder="用户名"> </el-input>
                             </el-form-item>
-                            <el-form-item prop="password"
-                                :rules="{required: true, message: '请输入密码', trigger: 'blur'}">
-                                <el-input v-model="userInfo.password"
-                                    placeholder="密码" type="password"></el-input>
+                            <el-form-item
+                                prop="password"
+                                :rules="{ required: true, message: '请输入密码', trigger: 'blur' }"
+                            >
+                                <el-input v-model="userInfo.password" placeholder="密码" type="password"></el-input>
                             </el-form-item>
                             <el-form-item>
-                                <el-button :loading="loading" @click="login"
-                                    type="primary" style="width: 100%;">登录
+                                <el-button :loading="loading" @click="login" type="primary" style="width: 100%;"
+                                    >登录
                                 </el-button>
                             </el-form-item>
                             <!-- <el-form-item>
@@ -57,33 +48,32 @@
                                     style="width: 100%;">手机登录</el-button>
                             </el-form-item> -->
                             <el-form-item label="">
-                                <el-checkbox v-model="rememberMe">7天内免登录
-                                </el-checkbox>
-                                <el-button type="text" style="float: right;"
-                                    @click="register=true">注册账号
+                                <el-checkbox v-model="rememberMe">7天内免登录 </el-checkbox>
+                                <el-button type="text" style="float: right;" @click="register = true"
+                                    >注册账号
                                 </el-button>
                             </el-form-item>
                         </el-form>
                     </el-tab-pane>
                     <el-tab-pane label="验证码登陆" name="second">
-                        <el-form :model="userInfo" style="width: 350px"
-                            ref="form2">
-                            <el-form-item prop="phone"
-                                :rules="{required: true, message: '请输入手机号', trigger: 'blur'}">
-                                <el-input v-model="userInfo.phone" name="phone"
-                                    placeholder="手机号">
-                                </el-input>
+                        <el-form :model="userInfo" style="width: 350px;" ref="form2">
+                            <el-form-item
+                                prop="phone"
+                                :rules="{ required: true, message: '请输入手机号', trigger: 'blur' }"
+                            >
+                                <el-input v-model="userInfo.phone" name="phone" placeholder="手机号"> </el-input>
                             </el-form-item>
-                            <el-form-item prop="code"
-                                :rules="{required: true, message: '验证码', trigger: 'blur'}">
+                            <el-form-item prop="code" :rules="{ required: true, message: '验证码', trigger: 'blur' }">
                                 <div class="code">
-                                    <el-input v-model="userInfo.code"
-                                        placeholder="请输入验证码"></el-input>
+                                    <el-input v-model="userInfo.code" placeholder="请输入验证码"></el-input>
 
-                                    <el-button :loading="sending"
-                                        @click="sendMsg" type="primary"
-                                        :disabled="time!==0">
-                                        {{time ===0 ? '发送验证码' : `重新发送(${time}s)`}}
+                                    <el-button
+                                        :loading="sending"
+                                        @click="sendMsg"
+                                        type="primary"
+                                        :disabled="time !== 0"
+                                    >
+                                        {{ time === 0 ? '发送验证码' : `重新发送(${time}s)` }}
                                     </el-button>
                                 </div>
                             </el-form-item>
@@ -93,21 +83,19 @@
                                 </el-button>
                             </el-form-item> -->
                             <el-form-item>
-                                <el-button :loading="loading"
-                                    @click="phonelogin" type="primary"
-                                    style="width: 100%;">手机登录</el-button>
+                                <el-button :loading="loading" @click="phonelogin" type="primary" style="width: 100%;"
+                                    >手机登录</el-button
+                                >
                             </el-form-item>
                             <el-form-item label="">
-                                <el-checkbox v-model="rememberMe">7天内免登录
-                                </el-checkbox>
-                                <el-button type="text" style="float: right;"
-                                    @click="register=true">注册账号
+                                <el-checkbox v-model="rememberMe">7天内免登录 </el-checkbox>
+                                <el-button type="text" style="float: right;" @click="register = true"
+                                    >注册账号
                                 </el-button>
                             </el-form-item>
                         </el-form>
                     </el-tab-pane>
                 </el-tabs>
-
             </div>
         </transition>
     </div>
@@ -119,44 +107,44 @@ export default {
             rememberMe: false,
             loading: false,
             userInfo: {
-                username: "",
-                password: "",
-                phone: "",
-                code: ""
+                username: '',
+                password: '',
+                phone: '',
+                code: '',
             },
             register: false,
             registerInfo: {
-                username: "",
-                password: ""
+                username: '',
+                password: '',
             },
-            activeName: "first",
+            activeName: 'first',
             time: 0,
-            sending: false
+            sending: false,
         };
     },
     methods: {
         login() {
-            this.$refs.form.validate(valid => {
+            this.$refs.form.validate((valid) => {
                 if (valid) {
                     this.loading = true;
                     this.$http
-                        .post("/auth/login", {
+                        .post('/auth/login', {
                             username: this.userInfo.username,
                             password: this.userInfo.password,
-                            remember: this.rememberMe
+                            remember: this.rememberMe,
                         })
-                        .then(res => {
-                            localStorage.setItem("token", res);
-                            return this.$http.get("/user/my");
+                        .then((res) => {
+                            localStorage.setItem('token', res);
+                            return this.$http.get('/user/my');
                         })
-                        .then(res => {
+                        .then((res) => {
                             this.loading = false;
-                            this.$store.commit("updateUserInfo", res);
+                            this.$store.commit('updateUserInfo', res);
                             this.$router.replace({
-                                name: this.$route.params.name || "dashboard"
+                                name: this.$route.params.name || 'dashboard',
                             });
                         })
-                        .catch(e => {
+                        .catch((e) => {
                             console.log(e);
                             this.loading = false;
                             this.$message.error(e.error);
@@ -165,25 +153,25 @@ export default {
             });
         },
         phonelogin() {
-            this.$refs.form2.validate(valid => {
+            this.$refs.form2.validate((valid) => {
                 if (valid) {
                     this.loading = true;
                     this.$http
-                        .post("/auth/phoneLogin", {
-                            phone: this.userInfo.phone
+                        .post('/auth/phoneLogin', {
+                            phone: this.userInfo.phone,
                         })
-                        .then(res => {
-                            localStorage.setItem("token", res);
-                            return this.$http.get("/user/my");
+                        .then((res) => {
+                            localStorage.setItem('token', res);
+                            return this.$http.get('/user/my');
                         })
-                        .then(res => {
+                        .then((res) => {
                             this.loading = false;
-                            this.$store.commit("updateUserInfo", res);
+                            this.$store.commit('updateUserInfo', res);
                             this.$router.replace({
-                                name: this.$route.params.name || "dashboard"
+                                name: this.$route.params.name || 'dashboard',
                             });
                         })
-                        .catch(e => {
+                        .catch((e) => {
                             console.log(e);
                             this.loading = false;
                             this.$message.error(e.error);
@@ -192,20 +180,20 @@ export default {
             });
         },
         doRegister() {
-            this.$refs.registerForm.validate(valid => {
+            this.$refs.registerForm.validate((valid) => {
                 if (valid) {
                     this.loading = true;
                     this.$http
-                        .post("/user/register", {
+                        .post('/user/register', {
                             username: this.registerInfo.username,
-                            password: this.registerInfo.password
+                            password: this.registerInfo.password,
                         })
-                        .then(res => {
+                        .then((res) => {
                             this.loading = false;
-                            this.$message.success("注册成功");
+                            this.$message.success('注册成功');
                             this.register = false;
                         })
-                        .catch(e => {
+                        .catch((e) => {
                             console.log(e);
                             this.loading = false;
                             this.$message.error(e.error);
@@ -215,19 +203,19 @@ export default {
         },
         sendMsg() {
             if (!/^1[3-9]\d{9}$/.test(this.userInfo.phone)) {
-                this.$message.warning("手机号格式错误");
+                this.$message.warning('手机号格式错误');
                 return;
             }
             this.sending = true;
             this.$http
-                .get("/sms/sendVerify", {
-                    phone: this.userInfo.phone
+                .get('/sms/sendVerify', {
+                    phone: this.userInfo.phone,
                 })
-                .then(res => {
+                .then((res) => {
                     this.sending = false;
                     this.checkTime();
                 })
-                .catch(e => {
+                .catch((e) => {
                     this.sending = false;
                     console.log(e);
                     this.$message.error(e.error);
@@ -241,8 +229,8 @@ export default {
                     clearInterval(i);
                 }
             }, 1000);
-        }
-    }
+        },
+    },
 };
 </script>
 <style lang="less" scoped>
@@ -253,7 +241,7 @@ export default {
     align-items: center;
     justify-content: center;
     background-color: #ebebeb;
-    background-image: url("https://microball.oss-cn-hangzhou.aliyuncs.com/izouma/application/rawpixel-com-565462-unsplash%20%281%29.jpg");
+    background-image: url('https://microball.oss-cn-hangzhou.aliyuncs.com/izouma/application/rawpixel-com-565462-unsplash%20%281%29.jpg');
     background-size: cover;
     background-position: center;
     background-repeat: no-repeat;

+ 107 - 104
src/main/vue/src/views/Menus.vue

@@ -1,37 +1,48 @@
 <template>
     <div class="edit-view">
-        <el-tree :data="menus" :render-content="renderContent"
-            :highlight-current="true" :expand-on-click-node="true" node-key="id"
-            default-expand-all v-loading="loading">
+        <el-tree
+            :data="menus"
+            :render-content="renderContent"
+            :highlight-current="true"
+            :expand-on-click-node="true"
+            node-key="id"
+            default-expand-all
+            v-loading="loading"
+        >
         </el-tree>
-        <el-button type="text" @click="addRootMenu" style="margin-left: 24px">添加
-        </el-button>
+        <el-button type="text" @click="addRootMenu" style="margin-left: 24px;">添加 </el-button>
         <el-dialog :visible.sync="dialogVisible" title="添加菜单">
             <el-form :model="menu" ref="form" label-position="top">
-                <el-form-item label="菜单名" prop="name"
-                    :rules="[{required: true, message: '请填写菜单名', trigger: 'blur'}]">
+                <el-form-item
+                    label="菜单名"
+                    prop="name"
+                    :rules="[{ required: true, message: '请填写菜单名', trigger: 'blur' }]"
+                >
                     <el-input v-model="menu.name"></el-input>
                 </el-form-item>
                 <el-form-item label="菜单地址" prop="path">
                     <el-input v-model="menu.path"></el-input>
                 </el-form-item>
                 <el-form-item prop="icon">
-                    <template slot="label">图标
-                        <a href="https://fontawesome.com/icons?d=gallery&s=brands,solid&m=free"
+                    <template slot="label"
+                        >图标
+                        <a
+                            href="https://fontawesome.com/icons?d=gallery&s=brands,solid&m=free"
                             target="_blank"
-                            class="available-icons">查看所有可用图标</a></template>
+                            class="available-icons"
+                            >查看所有可用图标</a
+                        ></template
+                    >
                     <el-input v-model="icon">
-                        <template slot="append"><span ref="iconContainer"
-                                style="font-size: 18px"><i
-                                    class="fas fa-"></i></span></template>
+                        <template slot="append"
+                            ><span ref="iconContainer" style="font-size: 18px;"><i class="fas fa-"></i></span
+                        ></template>
                     </el-input>
                 </el-form-item>
             </el-form>
             <div slot="footer">
-                <el-button @click="dialogVisible = false">取消
-                </el-button>
-                <el-button type="primary" @click="addMenu" :loading="loading">保存
-                </el-button>
+                <el-button @click="dialogVisible = false">取消 </el-button>
+                <el-button type="primary" @click="addMenu" :loading="loading">保存 </el-button>
             </div>
         </el-dialog>
     </div>
@@ -48,32 +59,32 @@ export default {
             loading: false,
             menus: [],
             menu: {
-                name: "",
-                path: "",
-                icon: "",
+                name: '',
+                path: '',
+                icon: '',
                 root: false,
-                active: true
+                active: true,
             },
             parent: null,
             currentRef: null,
             edit: false,
-            icon: ""
+            icon: '',
         };
     },
     methods: {
         addRootMenu() {
             this.menu = {
-                name: "",
-                path: "",
+                name: '',
+                path: '',
                 active: true,
                 root: true,
-                icon: "bars"
+                icon: 'bars',
             };
             this.parent = null;
-            this.icon = "bars";
+            this.icon = 'bars';
             this.dialogVisible = true;
             setTimeout(() => {
-                this.showIcon("bars");
+                this.showIcon('bars');
             }, 100);
         },
         showAddDialog(node, data) {
@@ -81,34 +92,31 @@ export default {
             this.parent = node.data;
             this.menu = {
                 parent: node.data.id,
-                name: "",
-                path: "",
+                name: '',
+                path: '',
                 active: true,
                 root: false,
-                icon: null
+                icon: null,
             };
-            this.icon = "";
+            this.icon = '';
             this.dialogVisible = true;
             setTimeout(() => {
-                this.showIcon("");
+                this.showIcon('');
             }, 100);
         },
         showEditDialog(node, data) {
             this.edit = true;
             this.currentRef = node.data;
-            const getIconName = icon => {
-                let iconName = "";
+            const getIconName = (icon) => {
+                let iconName = '';
                 if (icon) {
-                    iconName = icon
-                        .replace("fas ", "")
-                        .replace("fab ", "")
-                        .replace("fa-", "");
+                    iconName = icon.replace('fas ', '').replace('fab ', '').replace('fa-', '');
                 }
                 return iconName || null;
             };
             let iconName = getIconName(data.icon);
             this.menu = {
-                ...data
+                ...data,
             };
             this.icon = iconName;
             this.dialogVisible = true;
@@ -117,16 +125,16 @@ export default {
             }, 100);
         },
         addMenu() {
-            this.$refs.form.validate(valid => {
+            this.$refs.form.validate((valid) => {
                 if (valid) {
                     this.loading = true;
                     let menu = { ...this.menu };
                     delete menu.children;
                     this.$http
-                        .post("/menu/save", menu)
-                        .then(res => {
+                        .post('/menu/save', menu)
+                        .then((res) => {
                             this.loading = false;
-                            this.$message.success("添加成功");
+                            this.$message.success('添加成功');
                             this.dialogVisible = false;
                             if (this.edit) {
                                 for (let [key, value] of Object.entries(res)) {
@@ -134,14 +142,13 @@ export default {
                                     this.$set(this.currentRef, key, value);
                                 }
                             } else if (this.parent) {
-                                this.parent.children =
-                                    this.parent.children || [];
+                                this.parent.children = this.parent.children || [];
                                 this.parent.children.push(res);
                             } else {
                                 this.menus.push(res);
                             }
                         })
-                        .catch(e => {
+                        .catch((e) => {
                             console.log(e);
                             this.loading = false;
                             this.$message.error(e.error);
@@ -151,30 +158,28 @@ export default {
         },
         remove(node, data) {
             console.log(node);
-            this.$confirm("确定删除菜单?", "提示", {
-                confirmButtonText: "确定",
-                cancelButtonText: "取消",
-                type: "error"
+            this.$confirm('确定删除菜单?', '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'error',
             })
                 .then(() => {
                     this.$http
-                        .post("/menu/save", {
+                        .post('/menu/save', {
                             ...data,
                             active: false,
-                            children: null
+                            children: null,
                         })
-                        .then(res => {
-                            this.$message.success("删除成功");
-                            let index = node.parent.data.children.findIndex(
-                                i => {
-                                    return i.id === data.id;
-                                }
-                            );
+                        .then((res) => {
+                            this.$message.success('删除成功');
+                            let index = node.parent.data.children.findIndex((i) => {
+                                return i.id === data.id;
+                            });
                             if (index > -1) {
                                 node.parent.data.children.splice(index, 1);
                             }
                         })
-                        .catch(e => {
+                        .catch((e) => {
                             console.log(e);
                             this.loading = false;
                             this.$message.error(e.error);
@@ -188,27 +193,27 @@ export default {
                 let sort0 = node.previousSibling.data.sort,
                     sort1 = node.data.sort;
                 Promise.all([
-                    this.$http.post("/menu/save", {
+                    this.$http.post('/menu/save', {
                         ...node.data,
                         children: null,
-                        sort: sort0
+                        sort: sort0,
                     }),
-                    this.$http.post("/menu/save", {
+                    this.$http.post('/menu/save', {
                         ...node.previousSibling.data,
                         children: null,
-                        sort: sort1
-                    })
+                        sort: sort1,
+                    }),
                 ])
-                    .then(_ => {
+                    .then((_) => {
                         this.loading = false;
                         let tmp = { ...node.previousSibling.data, sort: sort1 };
                         node.previousSibling.data = {
                             ...node.data,
-                            sort: sort0
+                            sort: sort0,
                         };
                         node.data = tmp;
                     })
-                    .catch(e => {
+                    .catch((e) => {
                         console.log(e);
                         this.loading = false;
                         this.$message.error(e.error);
@@ -221,24 +226,24 @@ export default {
                 let sort0 = node.data.sort,
                     sort1 = node.nextSibling.data.sort;
                 Promise.all([
-                    this.$http.post("/menu/save", {
+                    this.$http.post('/menu/save', {
                         ...node.data,
                         children: null,
-                        sort: sort1
+                        sort: sort1,
                     }),
-                    this.$http.post("/menu/save", {
+                    this.$http.post('/menu/save', {
                         ...node.nextSibling.data,
                         children: null,
-                        sort: sort0
-                    })
+                        sort: sort0,
+                    }),
                 ])
-                    .then(_ => {
+                    .then((_) => {
                         this.loading = false;
                         let tmp = { ...node.nextSibling.data, sort: sort0 };
                         node.nextSibling.data = { ...node.data, sort: sort1 };
                         node.data = tmp;
                     })
-                    .catch(e => {
+                    .catch((e) => {
                         console.log(e);
                         this.loading = false;
                         this.$message.error(e.error);
@@ -247,11 +252,11 @@ export default {
         },
         getData() {
             this.$http
-                .get("/menu/all")
-                .then(res => {
+                .get('/menu/all')
+                .then((res) => {
                     this.menus = res;
                 })
-                .catch(e => {
+                .catch((e) => {
                     console.log(e);
                     this.$message.error(e.error);
                 });
@@ -264,7 +269,7 @@ export default {
                     <span class="opt">
                         <el-button
                             type="text"
-                            on-click={e => {
+                            on-click={(e) => {
                                 this.moveUp(node, data), e.stopPropagation();
                             }}
                             class="up"
@@ -274,7 +279,7 @@ export default {
                         </el-button>
                         <el-button
                             type="text"
-                            on-click={e => {
+                            on-click={(e) => {
                                 this.moveDown(node, data), e.stopPropagation();
                             }}
                             icon="el-icon-bottom"
@@ -283,9 +288,8 @@ export default {
                         </el-button>
                         <el-button
                             type="text"
-                            on-click={e => {
-                                this.showEditDialog(node, data),
-                                    e.stopPropagation();
+                            on-click={(e) => {
+                                this.showEditDialog(node, data), e.stopPropagation();
                             }}
                             icon="el-icon-edit"
                         >
@@ -293,9 +297,8 @@ export default {
                         </el-button>
                         <el-button
                             type="text"
-                            on-click={e => {
-                                this.showAddDialog(node, data),
-                                    e.stopPropagation();
+                            on-click={(e) => {
+                                this.showAddDialog(node, data), e.stopPropagation();
                             }}
                             icon="el-icon-plus"
                         >
@@ -303,7 +306,7 @@ export default {
                         </el-button>
                         <el-button
                             type="text"
-                            on-click={e => {
+                            on-click={(e) => {
                                 this.remove(node, data), e.stopPropagation();
                             }}
                             icon="el-icon-delete"
@@ -316,35 +319,35 @@ export default {
         },
         showIcon(val) {
             if (!this.$refs.iconContainer) return;
-            if (FontAwesome.icon({ prefix: "fas", iconName: val })) {
-                this.$refs.iconContainer.innerHTML = "";
-                let i = document.createElement("i");
-                i.className = "fas fa-" + val;
+            if (FontAwesome.icon({ prefix: 'fas', iconName: val })) {
+                this.$refs.iconContainer.innerHTML = '';
+                let i = document.createElement('i');
+                i.className = 'fas fa-' + val;
                 this.$refs.iconContainer.append(i);
                 FontAwesome.dom.i2svg();
-                this.menu.icon = "fas fa-" + val;
-            } else if (FontAwesome.icon({ prefix: "fab", iconName: val })) {
-                this.$refs.iconContainer.innerHTML = "";
-                let i = document.createElement("i");
-                i.className = "fab fa-" + val;
+                this.menu.icon = 'fas fa-' + val;
+            } else if (FontAwesome.icon({ prefix: 'fab', iconName: val })) {
+                this.$refs.iconContainer.innerHTML = '';
+                let i = document.createElement('i');
+                i.className = 'fab fa-' + val;
                 this.$refs.iconContainer.append(i);
                 FontAwesome.dom.i2svg();
-                this.menu.icon = "fab fa-" + val;
+                this.menu.icon = 'fab fa-' + val;
             } else {
-                this.$refs.iconContainer.innerHTML = "";
-                let i = document.createElement("i");
-                i.className = "fab fa-" + val;
+                this.$refs.iconContainer.innerHTML = '';
+                let i = document.createElement('i');
+                i.className = 'fab fa-' + val;
                 this.$refs.iconContainer.append(i);
                 FontAwesome.dom.i2svg();
-                this.menu.icon = "";
+                this.menu.icon = '';
             }
-        }
+        },
     },
     watch: {
         icon(val) {
             this.showIcon(val);
-        }
-    }
+        },
+    },
 };
 </script>
 <style lang="less">

+ 3 - 3
src/main/vue/src/views/RoleMenus.vue

@@ -5,14 +5,14 @@
 export default {
     data() {
         return {
-            menus: []
+            menus: [],
         };
     },
     created() {
-        this.$http.get("/menu/groupByCategory").then(res => {
+        this.$http.get('/menu/groupByCategory').then((res) => {
             this.menus = res;
         });
-    }
+    },
 };
 </script>
 <style lang="less" scoped></style>

+ 185 - 185
src/main/vue/src/views/SysConfigList.vue

@@ -5,23 +5,23 @@
             <el-button @click="getData" type="primary" icon="el-icon-search" class="filter-item">搜索 </el-button>
             <el-button @click="editRow()" type="primary" icon="el-icon-plus" class="filter-item">添加 </el-button>
             <el-button
-                    @click="download"
-                    type="primary"
-                    icon="el-icon-download"
-                    :loading="downloading"
-                    class="filter-item"
-            >导出EXCEL
+                @click="download"
+                type="primary"
+                icon="el-icon-download"
+                :loading="downloading"
+                class="filter-item"
+                >导出EXCEL
             </el-button>
         </div>
         <el-table
-                :data="tableData"
-                row-key="id"
-                ref="table"
-                header-row-class-name="table-header-row"
-                header-cell-class-name="table-header-cell"
-                row-class-name="table-row"
-                cell-class-name="table-cell"
-                :height="tableHeight"
+            :data="tableData"
+            row-key="id"
+            ref="table"
+            header-row-class-name="table-header-row"
+            header-cell-class-name="table-header-cell"
+            row-class-name="table-row"
+            cell-class-name="table-cell"
+            :height="tableHeight"
         >
             <el-table-column prop="name" label="名称"> </el-table-column>
             <el-table-column prop="desc" label="描述"> </el-table-column>
@@ -35,14 +35,14 @@
         </el-table>
         <div class="pagination-wrapper">
             <el-pagination
-                    background
-                    @size-change="onSizeChange"
-                    @current-change="onCurrentChange"
-                    :current-page="page"
-                    :page-sizes="[10, 20, 30, 40, 50]"
-                    :page-size="pageSize"
-                    layout="total, sizes, prev, pager, next, jumper"
-                    :total="totalElements"
+                background
+                @size-change="onSizeChange"
+                @current-change="onCurrentChange"
+                :current-page="page"
+                :page-sizes="[10, 20, 30, 40, 50]"
+                :page-size="pageSize"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="totalElements"
             >
             </el-pagination>
         </div>
@@ -58,43 +58,43 @@
                 <el-form-item prop="type" label="类型">
                     <el-select v-model="formData.type" placeholder="请选择" :disabled="edit === true">
                         <el-option
-                                v-for="item in valueTypes"
-                                :label="item.label"
-                                :value="item.value"
-                                :key="item.value"
+                            v-for="item in valueTypes"
+                            :label="item.label"
+                            :value="item.value"
+                            :key="item.value"
                         ></el-option>
                     </el-select>
                 </el-form-item>
                 <el-form-item prop="value" label="值">
                     <el-input v-model="formData.value" v-if="formData.type === 'STRING'"></el-input>
                     <el-date-picker
-                            v-model="formData.value"
-                            v-if="formData.type === 'DATETIME'"
-                            type="datetime"
-                            value-format="yyyy-MM-dd HH:mm:ss"
-                            placeholder="请选择日期时间"
+                        v-model="formData.value"
+                        v-if="formData.type === 'DATETIME'"
+                        type="datetime"
+                        value-format="yyyy-MM-dd HH:mm:ss"
+                        placeholder="请选择日期时间"
                     ></el-date-picker>
                     <el-date-picker
-                            v-model="formData.value"
-                            v-if="formData.type === 'DATE'"
-                            type="date"
-                            value-format="yyyy-MM-dd"
-                            placeholder="请选择日期"
+                        v-model="formData.value"
+                        v-if="formData.type === 'DATE'"
+                        type="date"
+                        value-format="yyyy-MM-dd"
+                        placeholder="请选择日期"
                     ></el-date-picker>
                     <el-time-picker
-                            v-model="formData.value"
-                            v-if="formData.type === 'TIME'"
-                            value-format="HH:mm"
-                            placeholder="请选择时间"
-                            arrow-control
+                        v-model="formData.value"
+                        v-if="formData.type === 'TIME'"
+                        value-format="HH:mm"
+                        placeholder="请选择时间"
+                        arrow-control
                     ></el-time-picker>
                     <el-switch
-                            v-model="formData.value"
-                            v-if="formData.type === 'BOOLEAN'"
-                            active-text="是"
-                            inactive-text="否"
-                            active-value="1"
-                            inactive-value="0"
+                        v-model="formData.value"
+                        v-if="formData.type === 'BOOLEAN'"
+                        active-text="是"
+                        inactive-text="否"
+                        active-value="1"
+                        inactive-value="0"
                     ></el-switch>
                     <el-input-number v-model="formData.value" v-if="formData.type === 'NUMBER'"></el-input-number>
                 </el-form-item>
@@ -106,151 +106,151 @@
     </div>
 </template>
 <script>
-    import { mapState } from 'vuex';
-    import pageableTable from '@/mixins/pageableTable';
+import { mapState } from 'vuex';
+import pageableTable from '@/mixins/pageableTable';
 
-    export default {
-        name: 'SysConfigList',
-        mixins: [pageableTable],
-        data() {
-            return {
-                multipleMode: false,
-                search: '',
-                url: '/sysConfig/all',
-                downloading: false,
-                formData: {
-                    name: '',
-                    desc: '',
-                    value: '',
-                    type: 'STRING'
+export default {
+    name: 'SysConfigList',
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/sysConfig/all',
+            downloading: false,
+            formData: {
+                name: '',
+                desc: '',
+                value: '',
+                type: 'STRING',
+            },
+            rules: {
+                name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
+                desc: [{ required: true, message: '请输入描述', trigger: 'blur' }],
+                type: [{ required: true, message: '请选择类型', trigger: 'blur' }],
+                value: [{ required: true, message: '请输入值', trigger: 'blur' }],
+            },
+            showDialog: false,
+            saving: false,
+            edit: false,
+            sortStr: 'createdAt,desc',
+            valueTypes: [
+                {
+                    label: '字符串',
+                    value: 'STRING',
+                },
+                {
+                    label: '日期时间',
+                    value: 'DATETIME',
+                },
+                {
+                    label: '日期',
+                    value: 'DATE',
+                },
+                {
+                    label: '时间',
+                    value: 'TIME',
                 },
-                rules: {
-                    name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
-                    desc: [{ required: true, message: '请输入描述', trigger: 'blur' }],
-                    type: [{ required: true, message: '请选择类型', trigger: 'blur' }],
-                    value: [{ required: true, message: '请输入值', trigger: 'blur' }]
+                {
+                    label: '开关',
+                    value: 'BOOLEAN',
                 },
-                showDialog: false,
-                saving: false,
-                edit: false,
-                sortStr: 'createdAt,desc',
-                valueTypes: [
-                    {
-                        label: '字符串',
-                        value: 'STRING'
-                    },
-                    {
-                        label: '日期时间',
-                        value: 'DATETIME'
-                    },
-                    {
-                        label: '日期',
-                        value: 'DATE'
-                    },
-                    {
-                        label: '时间',
-                        value: 'TIME'
-                    },
-                    {
-                        label: '开关',
-                        value: 'BOOLEAN'
-                    },
-                    {
-                        label: '数字',
-                        value: 'NUMBER'
-                    }
-                ]
-            };
+                {
+                    label: '数字',
+                    value: 'NUMBER',
+                },
+            ],
+        };
+    },
+    computed: {
+        selection() {
+            return this.$refs.table.selection.map((i) => i.id);
+        },
+    },
+    methods: {
+        beforeGetData() {
+            return { search: this.search, sort: 'createdAt,desc' };
         },
-        computed: {
-            selection() {
-                return this.$refs.table.selection.map(i => i.id);
+        toggleMultipleMode(multipleMode) {
+            this.multipleMode = multipleMode;
+            if (!multipleMode) {
+                this.$refs.table.clearSelection();
             }
         },
-        methods: {
-            beforeGetData() {
-                return { search: this.search, sort: 'createdAt,desc' };
-            },
-            toggleMultipleMode(multipleMode) {
-                this.multipleMode = multipleMode;
-                if (!multipleMode) {
-                    this.$refs.table.clearSelection();
-                }
-            },
-            addRow() {
-                this.$router.push({
-                    path: '/sysConfigEdit',
-                    query: {
-                        ...this.$route.query
-                    }
+        addRow() {
+            this.$router.push({
+                path: '/sysConfigEdit',
+                query: {
+                    ...this.$route.query,
+                },
+            });
+        },
+        editRow(row, edit) {
+            this.edit = edit;
+            if (!row) {
+                row = {
+                    name: '',
+                    desc: '',
+                    value: '',
+                    type: null,
+                };
+            }
+            this.formData = { ...row };
+            this.showDialog = true;
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/sysConfig/excel', {
+                    responseType: 'blob',
+                    params: { size: 10000 },
+                })
+                .then((res) => {
+                    console.log(res);
+                    this.downloading = false;
+                    const downloadUrl = window.URL.createObjectURL(new Blob([res.data]));
+                    const link = document.createElement('a');
+                    link.href = downloadUrl;
+                    link.setAttribute('download', res.headers['content-disposition'].split('filename=')[1]);
+                    document.body.appendChild(link);
+                    link.click();
+                    link.remove();
+                })
+                .catch((e) => {
+                    console.log(e);
+                    this.downloading = false;
+                    this.$message.error(e.error);
                 });
-            },
-            editRow(row, edit) {
-                this.edit = edit;
-                if (!row) {
-                    row = {
-                        name: '',
-                        desc: '',
-                        value: '',
-                        type: null
-                    };
+        },
+        save() {
+            this.$refs.form.validate((valid) => {
+                if (valid) {
+                    let data = { ...this.formData };
+                    this.saving = true;
+                    this.$http
+                        .post('/sysConfig/save', data, { body: 'json' })
+                        .then((res) => {
+                            this.saving = false;
+                            this.$message.success('成功');
+                            this.showDialog = false;
+                            this.getData();
+                        })
+                        .catch((e) => {
+                            console.log(e);
+                            this.saving = false;
+                            this.showDialog = false;
+                            this.$message.error(e.error);
+                        });
+                } else {
+                    return false;
                 }
-                this.formData = { ...row };
-                this.showDialog = true;
-            },
-            download() {
-                this.downloading = true;
-                this.$axios
-                    .get('/sysConfig/excel', {
-                        responseType: 'blob',
-                        params: { size: 10000 }
-                    })
-                    .then(res => {
-                        console.log(res);
-                        this.downloading = false;
-                        const downloadUrl = window.URL.createObjectURL(new Blob([res.data]));
-                        const link = document.createElement('a');
-                        link.href = downloadUrl;
-                        link.setAttribute('download', res.headers['content-disposition'].split('filename=')[1]);
-                        document.body.appendChild(link);
-                        link.click();
-                        link.remove();
-                    })
-                    .catch(e => {
-                        console.log(e);
-                        this.downloading = false;
-                        this.$message.error(e.error);
-                    });
-            },
-            save() {
-                this.$refs.form.validate(valid => {
-                    if (valid) {
-                        let data = { ...this.formData };
-                        this.saving = true;
-                        this.$http
-                            .post('/sysConfig/save', data, { body: 'json' })
-                            .then(res => {
-                                this.saving = false;
-                                this.$message.success('成功');
-                                this.showDialog = false;
-                                this.getData();
-                            })
-                            .catch(e => {
-                                console.log(e);
-                                this.saving = false;
-                                this.showDialog = false;
-                                this.$message.error(e.error);
-                            });
-                    } else {
-                        return false;
-                    }
-                });
-            },
-            typeFormatter(row, cell, cellValue) {
-                let item = this.valueTypes.find(i => i.value === cellValue);
-                return item ? item.label : '';
-            }
-        }
-    };
+            });
+        },
+        typeFormatter(row, cell, cellValue) {
+            let item = this.valueTypes.find((i) => i.value === cellValue);
+            return item ? item.label : '';
+        },
+    },
+};
 </script>
 <style lang="less" scoped></style>

+ 33 - 41
src/main/vue/src/views/UserEdit.vue

@@ -1,7 +1,13 @@
 <template>
     <div class="edit-view">
-        <el-form :model="formData" :rules="rules" ref="form" label-width="80px"
-                 label-position="right" style="max-width: 500px;">
+        <el-form
+            :model="formData"
+            :rules="rules"
+            ref="form"
+            label-width="80px"
+            label-position="right"
+            style="max-width: 500px;"
+        >
             <el-form-item prop="avatar" label="头像">
                 <crop-upload v-model="formData.avatar"></crop-upload>
             </el-form-item>
@@ -12,8 +18,7 @@
                 <el-input v-model="formData.nickname"></el-input>
             </el-form-item>
             <el-form-item v-if="formData.id" label="密码">
-                <el-button type="primary" plain @click="resetPassword">重置
-                </el-button>
+                <el-button type="primary" plain @click="resetPassword">重置 </el-button>
             </el-form-item>
             <el-form-item v-else prop="password" label="密码">
                 <el-input v-model="formData.password"></el-input>
@@ -22,18 +27,15 @@
                 <el-input v-model="formData.phone"></el-input>
             </el-form-item>
             <el-form-item prop="authorities" label="角色">
-                <el-select v-model="formData.authorities" multiple
-                           placeholder="请选择" value-key="name">
-                    <el-option v-for="item in authorities" :key="item.name"
-                               :label="item.name" :value="item">
+                <el-select v-model="formData.authorities" multiple placeholder="请选择" value-key="name">
+                    <el-option v-for="item in authorities" :key="item.name" :label="item.name" :value="item">
                     </el-option>
                 </el-select>
             </el-form-item>
             <el-form-item>
-                <el-button @click="onSave" :loading="$store.state.fetchingData"
-                           type="primary">保存</el-button>
-                <el-button @click="del" :loading="$store.state.fetchingData"
-                           type="danger" v-if="formData.id">删除
+                <el-button @click="onSave" :loading="$store.state.fetchingData" type="primary">保存</el-button>
+                <el-button @click="del" :loading="$store.state.fetchingData" type="danger" v-if="formData.id"
+                    >删除
                 </el-button>
                 <el-button @click="$router.go(-1)">取消</el-button>
             </el-form-item>
@@ -46,20 +48,20 @@ export default {
         if (this.$route.query.id) {
             this.$http
                 .get(`/user/get/${this.$route.query.id}`)
-                .then(res => {
+                .then((res) => {
                     this.formData = res;
                 })
-                .catch(e => {
+                .catch((e) => {
                     console.log(e);
                     this.$message.error(e.error);
                 });
         }
         this.$http
             .get('/authority/all')
-            .then(res => {
+            .then((res) => {
                 this.authorities = res;
             })
-            .catch(e => {
+            .catch((e) => {
                 console.log(e);
             });
     },
@@ -67,8 +69,7 @@ export default {
         return {
             saving: false,
             formData: {
-                avatar:
-                    'https://zhumj.oss-cn-hangzhou.aliyuncs.com/image/user.jpg',
+                avatar: 'https://zhumj.oss-cn-hangzhou.aliyuncs.com/image/user.jpg',
             },
             rules: {
                 avatar: [
@@ -79,15 +80,9 @@ export default {
                         trigger: 'blur',
                     },
                 ],
-                username: [
-                    { required: true, message: '请输入昵称', trigger: 'blur' },
-                ],
-                nickname: [
-                    { required: true, message: '请输入昵称', trigger: 'blur' },
-                ],
-                password: [
-                    { required: true, message: '请输入密码', trigger: 'blur' },
-                ],
+                username: [{ required: true, message: '请输入昵称', trigger: 'blur' }],
+                nickname: [{ required: true, message: '请输入昵称', trigger: 'blur' }],
+                password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
                 phone: [
                     {
                         regexp: /^1[3-9]\d{9}$/,
@@ -95,16 +90,14 @@ export default {
                         trigger: 'blur',
                     },
                 ],
-                authorities: [
-                    { required: true, message: '请选择角色', trigger: 'blur' },
-                ],
+                authorities: [{ required: true, message: '请选择角色', trigger: 'blur' }],
             },
             authorities: [],
         };
     },
     methods: {
         onSave() {
-            this.$refs.form.validate(valid => {
+            this.$refs.form.validate((valid) => {
                 if (valid) {
                     this.submit();
                 } else {
@@ -115,7 +108,7 @@ export default {
         submit() {
             this.$http
                 .post('/user/save', this.formData, { body: 'json' })
-                .then(res => {
+                .then((res) => {
                     this.$message.success('成功');
                     this.formData = res;
                     this.$router.replace({
@@ -124,7 +117,7 @@ export default {
                         },
                     });
                 })
-                .catch(e => {
+                .catch((e) => {
                     console.log(e);
                     this.$message.error(e.error);
                 });
@@ -139,7 +132,7 @@ export default {
                                 id: this.formData.id,
                             },
                         })
-                        .then(res => {
+                        .then((res) => {
                             if (res.success) {
                                 this.$message.success('成功');
                                 this.$router.go(-1);
@@ -152,19 +145,19 @@ export default {
         },
         resetPassword() {
             this.$prompt('请输入新密码', '重置密码', { inputType: 'password' })
-                .then(res => {
+                .then((res) => {
                     console.log(res);
                     if (res.value) {
                         this.$alert('确定重置密码?', '提示', {
-                            showCancelButton: true
+                            showCancelButton: true,
                         })
                             .then(() => {
                                 return this.$http.post('/user/setPasswordAdmin', {
                                     userId: this.formData.id,
-                                    password: res.value
+                                    password: res.value,
                                 });
                             })
-                            .then(res => {
+                            .then((res) => {
                                 this.$message.success('密码重置成功');
                             })
                             .catch(() => {
@@ -173,9 +166,8 @@ export default {
                     }
                 })
                 .catch(() => {});
-        }
+        },
     },
 };
 </script>
-<style lang="less" scoped>
-</style>
+<style lang="less" scoped></style>

+ 73 - 73
src/main/vue/src/views/UserList.vue

@@ -1,68 +1,74 @@
 <template>
     <div class="list-view">
         <div class="filters-container">
-            <el-input placeholder="输入关键字" v-model="search" clearable
-                class="filter-item"></el-input>
-            <el-button @click="getData" type="primary" icon="el-icon-search"
-                class="filter-item">搜索
-            </el-button>
-            <el-button @click="addRow" type="primary" icon="el-icon-plus"
-                class="filter-item">添加
-            </el-button>
-            <el-button @click="download" type="primary" icon="el-icon-download"
-                :loading="downloading" class="filter-item">导出EXCEL
+            <el-input placeholder="输入关键字" v-model="search" clearable class="filter-item"></el-input>
+            <el-button @click="getData" type="primary" icon="el-icon-search" class="filter-item">搜索 </el-button>
+            <el-button @click="addRow" type="primary" icon="el-icon-plus" class="filter-item">添加 </el-button>
+            <el-button
+                @click="download"
+                type="primary"
+                icon="el-icon-download"
+                :loading="downloading"
+                class="filter-item"
+                >导出EXCEL
             </el-button>
         </div>
-        <el-table :data="tableData" row-key="id" ref="table"
-            height="tableHeight" header-row-class-name="table-header-row"
+        <el-table
+            :data="tableData"
+            row-key="id"
+            ref="table"
+            height="tableHeight"
+            header-row-class-name="table-header-row"
             header-cell-class-name="table-header-cell"
-            row-class-name="table-row" cell-class-name="table-cell">
-            <el-table-column v-if="multipleMode" align="center" type="selection"
-                width="50">
-            </el-table-column>
+            row-class-name="table-row"
+            cell-class-name="table-cell"
+        >
+            <el-table-column v-if="multipleMode" align="center" type="selection" width="50"> </el-table-column>
             <el-table-column prop="id" label="ID" width="100">
-                <template slot="header" slot-scope="{column}">
-                    <sortable-header :column="column" :current-sort="sort"
-                        @changeSort="changeSort">
-                    </sortable-header>
+                <template slot="header" slot-scope="{ column }">
+                    <sortable-header :column="column" :current-sort="sort" @changeSort="changeSort"> </sortable-header>
                 </template>
             </el-table-column>
             <el-table-column prop="username" label="用户名" min-width="300">
-                <template slot="header" slot-scope="{column}">
-                    <sortable-header :column="column" :current-sort="sort"
-                        @changeSort="changeSort">
-                    </sortable-header>
+                <template slot="header" slot-scope="{ column }">
+                    <sortable-header :column="column" :current-sort="sort" @changeSort="changeSort"> </sortable-header>
                 </template>
             </el-table-column>
-            <el-table-column prop="nickname" label="昵称" min-width="300">
-            </el-table-column>
+            <el-table-column prop="nickname" label="昵称" min-width="300"> </el-table-column>
             <el-table-column label="头像" min-width="300">
-                <template slot-scope="{row}">
-                    <el-image style="width: 30px; height: 30px"
-                        :src="row.avatar" fit="cover"
-                        :preview-src-list="[row.avatar]"></el-image>
+                <template slot-scope="{ row }">
+                    <el-image
+                        style="width: 30px; height: 30px;"
+                        :src="row.avatar"
+                        fit="cover"
+                        :preview-src-list="[row.avatar]"
+                    ></el-image>
                 </template>
             </el-table-column>
             <el-table-column label="操作" align="center" fixed="right">
-                <template slot-scope="{row}">
-                    <el-button @click="editRow(row)" type="primary" size="mini"
-                        plain>编辑</el-button>
+                <template slot-scope="{ row }">
+                    <el-button @click="editRow(row)" type="primary" size="mini" plain>编辑</el-button>
                 </template>
             </el-table-column>
         </el-table>
         <div class="pagination-wrapper">
-            <el-pagination background @size-change="onSizeChange"
-                @current-change="onCurrentChange" :current-page="page"
-                :page-sizes="[10, 20, 30, 40, 50]" :page-size="pageSize"
+            <el-pagination
+                background
+                @size-change="onSizeChange"
+                @current-change="onCurrentChange"
+                :current-page="page"
+                :page-sizes="[10, 20, 30, 40, 50]"
+                :page-size="pageSize"
                 layout="total, sizes, prev, pager, next, jumper"
-                :total="totalElements">
+                :total="totalElements"
+            >
             </el-pagination>
         </div>
     </div>
 </template>
 <script>
-import { mapState } from "vuex";
-import pageableTable from "@/mixins/pageableTable";
+import { mapState } from 'vuex';
+import pageableTable from '@/mixins/pageableTable';
 import ClipboardJS from 'clipboard';
 const clickData = {};
 export default {
@@ -70,16 +76,16 @@ export default {
     data() {
         return {
             multipleMode: false,
-            search: "",
-            url: "/user/all",
-            downloading: false
+            search: '',
+            url: '/user/all',
+            downloading: false,
         };
     },
     computed: {
         ...mapState([]),
         selection() {
-            return this.$refs.table.selection.map(i => i.id);
-        }
+            return this.$refs.table.selection.map((i) => i.id);
+        },
     },
     methods: {
         beforeGetData() {
@@ -95,41 +101,36 @@ export default {
         },
         addRow() {
             this.$router.push({
-                path: "/userEdit",
+                path: '/userEdit',
                 query: {
-                    ...this.$route.query
-                }
+                    ...this.$route.query,
+                },
             });
         },
         editRow(row) {
             this.$router.push({
-                path: "/userEdit",
+                path: '/userEdit',
                 query: {
-                    id: row.id
-                }
+                    id: row.id,
+                },
             });
         },
         download() {
             this.downloading = true;
             this.$axios
-                .get("/user/excel", { responseType: "blob" })
-                .then(res => {
+                .get('/user/excel', { responseType: 'blob' })
+                .then((res) => {
                     console.log(res);
                     this.downloading = false;
-                    const downloadUrl = window.URL.createObjectURL(
-                        new Blob([res.data])
-                    );
-                    const link = document.createElement("a");
+                    const downloadUrl = window.URL.createObjectURL(new Blob([res.data]));
+                    const link = document.createElement('a');
                     link.href = downloadUrl;
-                    link.setAttribute(
-                        "download",
-                        res.headers["content-disposition"].split("filename=")[1]
-                    );
+                    link.setAttribute('download', res.headers['content-disposition'].split('filename=')[1]);
                     document.body.appendChild(link);
                     link.click();
                     link.remove();
                 })
-                .catch(e => {
+                .catch((e) => {
                     console.log(e);
                     this.downloading = false;
                     this.$message.error(e.error);
@@ -137,12 +138,12 @@ export default {
         },
         operation1() {
             this.$notify({
-                title: "提示",
-                message: this.selection
+                title: '提示',
+                message: this.selection,
             });
         },
         operation2() {
-            this.$message("操作2");
+            this.$message('操作2');
         },
         clickId(row) {
             if (row.id !== clickData.id) {
@@ -153,30 +154,29 @@ export default {
             if (clickData.i) {
                 clearInterval(clickData.i);
             }
-            clickData.i = setTimeout(_ => {
+            clickData.i = setTimeout((_) => {
                 clickData.c = 0;
             }, 200);
             if (clickData.c === 5) {
                 this.$http
                     .get(`/user/getToken/${row.id}`)
-                    .then(res => {
+                    .then((res) => {
                         let el = document.createElement('div');
                         new ClipboardJS(el, {
-                            text: function(trigger) {
+                            text: function (trigger) {
                                 return res;
-                            }
+                            },
                         });
                         el.click();
                         this.$message.success('已复制Token');
                         clickData.c = 0;
                     })
-                    .catch(e => {
+                    .catch((e) => {
                         this.$message.error(e.error);
                     });
             }
-        }
-    }
+        },
+    },
 };
 </script>
-<style lang="less" scoped>
-</style>
+<style lang="less" scoped></style>

+ 45 - 42
src/main/vue/src/widgets/BarChartWidget.vue

@@ -4,27 +4,28 @@
     </widget-card>
 </template>
 <script>
-    import WidgetCard from './WidgetCard'
-    import VueCharts from 'vue-chartjs'
+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: [{
+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: [
@@ -33,7 +34,7 @@
                             'rgba(255, 206, 86, 0.2)',
                             'rgba(75, 192, 192, 0.2)',
                             'rgba(153, 102, 255, 0.2)',
-                            'rgba(255, 159, 64, 0.2)'
+                            'rgba(255, 159, 64, 0.2)',
                         ],
                         borderColor: [
                             'rgba(255,99,132,1)',
@@ -41,27 +42,29 @@
                             'rgba(255, 206, 86, 1)',
                             'rgba(75, 192, 192, 1)',
                             'rgba(153, 102, 255, 1)',
-                            'rgba(255, 159, 64, 1)'
+                            'rgba(255, 159, 64, 1)',
                         ],
-                        borderWidth: 1
-                    }]
-                },
-                options: {
-                    maintainAspectRatio: false,
-                    scales: {
-                        yAxes: [{
+                        borderWidth: 1,
+                    },
+                ],
+            },
+            options: {
+                maintainAspectRatio: false,
+                scales: {
+                    yAxes: [
+                        {
                             ticks: {
-                                beginAtZero: false
-                            }
-                        }]
-                    }
-                }
-            });
-        },
-        components: {
-            WidgetCard
-        }
-    }
+                                beginAtZero: false,
+                            },
+                        },
+                    ],
+                },
+            },
+        });
+    },
+    components: {
+        WidgetCard,
+    },
+};
 </script>
-<style lang="less" scoped>
-</style>
+<style lang="less" scoped></style>

+ 40 - 41
src/main/vue/src/widgets/LineChartWidget.vue

@@ -4,47 +4,46 @@
     </widget-card>
 </template>
 <script>
-    import WidgetCard from './WidgetCard'
-    import VueCharts from 'vue-chartjs'
+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);
+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
-        }
-    }
+        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>
+<style lang="less" scoped></style>

+ 34 - 40
src/main/vue/src/widgets/PieChartWidget.vue

@@ -4,45 +4,39 @@
     </widget-card>
 </template>
 <script>
-    import WidgetCard from './WidgetCard'
-    import VueCharts from 'vue-chartjs'
+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
-        }
-    }
+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>
+<style lang="less" scoped></style>

+ 26 - 26
src/main/vue/src/widgets/UserWidget.vue

@@ -8,34 +8,34 @@
     </widget-card>
 </template>
 <script>
-    import WidgetCard from './WidgetCard'
+import WidgetCard from './WidgetCard';
 
-    export default {
-        data() {
-            return {
-                bodyStyle: {
-                    display: 'flex',
-                    alignItems: 'center'
-                }
-            }
-        },
-        components: {
-            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;
-        }
+.info {
+    flex-grow: 1;
+    text-align: right;
+    .text {
+        color: #999;
+        font-size: 16px;
+        margin-bottom: 12px;
+    }
+    .num {
+        font-size: 20px;
+        color: #333;
     }
+}
 </style>

+ 15 - 15
src/main/vue/src/widgets/WidgetCard.vue

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

File diff suppressed because it is too large
+ 673 - 520
src/main/vue/yarn.lock


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