Просмотр исходного кода

Merge remote-tracking branch 'origin/master'

梁展鹏 3 лет назад
Родитель
Сommit
310a1d1b3b
82 измененных файлов с 4065 добавлено и 717 удалено
  1. 281 274
      .eslintrc.js
  2. 9 0
      .prettierrc
  3. 1 1
      package.json
  4. 161 0
      src/components/BaseTable.vue
  5. 0 0
      src/components/Breadcrumb.vue
  6. 0 0
      src/components/Hamburger.vue
  7. 0 0
      src/components/SvgIcon.vue
  8. 10 0
      src/components/index.js
  9. 35 0
      src/components/inject.js
  10. 201 0
      src/containers/ToolbarContainer.vue
  11. 4 0
      src/containers/index.js
  12. 35 0
      src/containers/inject.js
  13. 4 3
      src/layout/components/AppMain.vue
  14. 0 6
      src/layout/components/Navbar.vue
  15. 20 20
      src/layout/components/Sidebar/index.vue
  16. 20 17
      src/main.js
  17. 73 0
      src/mixins/filterList.js
  18. 40 29
      src/permission.js
  19. 403 88
      src/router/index.js
  20. 5 3
      src/store/getters.js
  21. 20 14
      src/store/index.js
  22. 75 0
      src/store/modules/permission.js
  23. 19 6
      src/store/modules/user.js
  24. 8 0
      src/styles/common.scss
  25. 20 0
      src/utils/params.js
  26. 9 4
      src/utils/request.js
  27. 84 0
      src/views/baseManagement/bannerManagement/index.vue
  28. 22 0
      src/views/baseManagement/bannerManagement/toolbar.vue
  29. 83 0
      src/views/baseManagement/infoManagement/index.vue
  30. 34 0
      src/views/baseManagement/infoManagement/toolbar.vue
  31. 59 0
      src/views/baseManagement/problemFeedbackManagement/index.vue
  32. 35 0
      src/views/baseManagement/problemFeedbackManagement/toolbar.vue
  33. 94 6
      src/views/dashboard/index.vue
  34. 59 0
      src/views/financialManagement/fundDetail/index.vue
  35. 35 0
      src/views/financialManagement/fundDetail/toolbar.vue
  36. 59 0
      src/views/financialManagement/orderManagement/index.vue
  37. 35 0
      src/views/financialManagement/orderManagement/toolbar.vue
  38. 78 0
      src/views/helpInfo/information/index.vue
  39. 29 0
      src/views/helpInfo/information/toolbar.vue
  40. 78 0
      src/views/helpInfo/issueType/index.vue
  41. 29 0
      src/views/helpInfo/issueType/toolbar.vue
  42. 78 0
      src/views/memberManagement/memberLever/index.vue
  43. 22 0
      src/views/memberManagement/memberLever/toolbar.vue
  44. 99 0
      src/views/memberManagement/memberList/index.vue
  45. 55 0
      src/views/memberManagement/memberList/toolbar.vue
  46. 0 7
      src/views/nested/menu1/index.vue
  47. 0 7
      src/views/nested/menu1/menu1-1/index.vue
  48. 0 7
      src/views/nested/menu1/menu1-2/index.vue
  49. 0 5
      src/views/nested/menu1/menu1-2/menu1-2-1/index.vue
  50. 0 5
      src/views/nested/menu1/menu1-2/menu1-2-2/index.vue
  51. 0 5
      src/views/nested/menu1/menu1-3/index.vue
  52. 0 5
      src/views/nested/menu2/index.vue
  53. 59 0
      src/views/photoManagement/eventsList/index.vue
  54. 35 0
      src/views/photoManagement/eventsList/toolbar.vue
  55. 59 0
      src/views/photoManagement/imageGoodsManagement/index.vue
  56. 35 0
      src/views/photoManagement/imageGoodsManagement/toolbar.vue
  57. 59 0
      src/views/photoManagement/uploadManagement/index.vue
  58. 35 0
      src/views/photoManagement/uploadManagement/toolbar.vue
  59. 74 0
      src/views/photographerManagement/photoVerify/index.vue
  60. 34 0
      src/views/photographerManagement/photoVerify/toolbar.vue
  61. 89 0
      src/views/photographerManagement/photographerVerify/index.vue
  62. 34 0
      src/views/photographerManagement/photographerVerify/toolbar.vue
  63. 89 0
      src/views/pointsManagement/pointsDetail/index.vue
  64. 34 0
      src/views/pointsManagement/pointsDetail/toolbar.vue
  65. 88 0
      src/views/pointsManagement/pointsSetting/index.vue
  66. 88 0
      src/views/sceneManagement/sceneList/index.vue
  67. 44 0
      src/views/sceneManagement/sceneList/toolbar.vue
  68. 79 0
      src/views/sceneManagement/sceneVerify/index.vue
  69. 43 0
      src/views/sceneManagement/sceneVerify/toolbar.vue
  70. 59 0
      src/views/statistics/downloadImage/index.vue
  71. 35 0
      src/views/statistics/downloadImage/toolbar.vue
  72. 59 0
      src/views/statistics/uploadImage/index.vue
  73. 35 0
      src/views/statistics/uploadImage/toolbar.vue
  74. 59 0
      src/views/statistics/withdrawalRecord/index.vue
  75. 35 0
      src/views/statistics/withdrawalRecord/toolbar.vue
  76. 83 0
      src/views/systemManagement/accountManagement/index.vue
  77. 34 0
      src/views/systemManagement/accountManagement/toolbar.vue
  78. 84 0
      src/views/systemManagement/roleManagement/index.vue
  79. 22 0
      src/views/systemManagement/roleManagement/toolbar.vue
  80. 0 79
      src/views/table/index.vue
  81. 0 78
      src/views/tree/index.vue
  82. 62 48
      vue.config.js

+ 281 - 274
.eslintrc.js

@@ -9,279 +9,286 @@ module.exports = {
     node: true,
     es6: true
   },
-  extends: ['plugin:vue/recommended', 'eslint:recommended'],
+  parser: 'vue-eslint-parser'
+  // extends: ["plugin:vue/essential"]
 
-  // add your custom rules here
-  //it is base on https://github.com/vuejs/eslint-config-vue
-  rules: {
-    'vue/html-self-closing': [
-      0,
-      {
-        html: {
-          void: 'always',
-          normal: 'never',
-          component: 'always'
-        },
-        svg: 'always',
-        math: 'always'
-      }
-    ],
-    'vue/max-attributes-per-line': [
-      2,
-      {
-        singleline: 10,
-        multiline: {
-          max: 1,
-          allowFirstLine: false
-        }
-      }
-    ],
-    'vue/singleline-html-element-content-newline': 'off',
-    'vue/multiline-html-element-content-newline': 'off',
-    'vue/name-property-casing': ['error', 'PascalCase'],
-    'vue/no-v-html': 'off',
-    'accessor-pairs': 2,
-    'arrow-spacing': [
-      2,
-      {
-        before: true,
-        after: true
-      }
-    ],
-    'block-spacing': [2, 'always'],
-    'brace-style': [
-      2,
-      '1tbs',
-      {
-        allowSingleLine: true
-      }
-    ],
-    camelcase: [
-      0,
-      {
-        properties: 'always'
-      }
-    ],
-    'comma-dangle': [2, 'never'],
-    'comma-spacing': [
-      2,
-      {
-        before: false,
-        after: true
-      }
-    ],
-    'comma-style': [2, 'last'],
-    'constructor-super': 2,
-    curly: [2, 'multi-line'],
-    'dot-location': [2, 'property'],
-    'eol-last': 2,
-    eqeqeq: ['error', 'always', { null: 'ignore' }],
-    'generator-star-spacing': [
-      2,
-      {
-        before: true,
-        after: true
-      }
-    ],
-    'handle-callback-err': [2, '^(err|error)$'],
-    indent: [
-      2,
-      2,
-      {
-        SwitchCase: 1
-      }
-    ],
-    'jsx-quotes': [2, 'prefer-single'],
-    'key-spacing': [
-      2,
-      {
-        beforeColon: false,
-        afterColon: true
-      }
-    ],
-    'keyword-spacing': [
-      2,
-      {
-        before: true,
-        after: true
-      }
-    ],
-    'new-cap': [
-      2,
-      {
-        newIsCap: true,
-        capIsNew: false
-      }
-    ],
-    'new-parens': 2,
-    'no-array-constructor': 2,
-    'no-caller': 2,
-    'no-console': 'off',
-    'no-class-assign': 2,
-    'no-cond-assign': 2,
-    'no-const-assign': 2,
-    'no-control-regex': 0,
-    'no-delete-var': 2,
-    'no-dupe-args': 2,
-    'no-dupe-class-members': 2,
-    'no-dupe-keys': 2,
-    'no-duplicate-case': 2,
-    'no-empty-character-class': 2,
-    'no-empty-pattern': 2,
-    'no-eval': 2,
-    'no-ex-assign': 2,
-    'no-extend-native': 2,
-    'no-extra-bind': 2,
-    'no-extra-boolean-cast': 2,
-    'no-extra-parens': [2, 'functions'],
-    'no-fallthrough': 2,
-    'no-floating-decimal': 2,
-    'no-func-assign': 2,
-    'no-implied-eval': 2,
-    'no-inner-declarations': [2, 'functions'],
-    'no-invalid-regexp': 2,
-    'no-irregular-whitespace': 2,
-    'no-iterator': 2,
-    'no-label-var': 2,
-    'no-labels': [
-      2,
-      {
-        allowLoop: false,
-        allowSwitch: false
-      }
-    ],
-    'no-lone-blocks': 2,
-    'no-mixed-spaces-and-tabs': 2,
-    'no-multi-spaces': 2,
-    'no-multi-str': 2,
-    'no-multiple-empty-lines': [
-      2,
-      {
-        max: 1
-      }
-    ],
-    'no-native-reassign': 2,
-    'no-negated-in-lhs': 2,
-    'no-new-object': 2,
-    'no-new-require': 2,
-    'no-new-symbol': 2,
-    'no-new-wrappers': 2,
-    'no-obj-calls': 2,
-    'no-octal': 2,
-    'no-octal-escape': 2,
-    'no-path-concat': 2,
-    'no-proto': 2,
-    'no-redeclare': 2,
-    'no-regex-spaces': 2,
-    'no-return-assign': [2, 'except-parens'],
-    'no-self-assign': 2,
-    'no-self-compare': 2,
-    'no-sequences': 2,
-    'no-shadow-restricted-names': 2,
-    'no-spaced-func': 2,
-    'no-sparse-arrays': 2,
-    'no-this-before-super': 2,
-    'no-throw-literal': 2,
-    'no-trailing-spaces': 2,
-    'no-undef': 2,
-    'no-undef-init': 2,
-    'no-unexpected-multiline': 2,
-    'no-unmodified-loop-condition': 2,
-    'no-unneeded-ternary': [
-      2,
-      {
-        defaultAssignment: false
-      }
-    ],
-    'no-unreachable': 2,
-    'no-unsafe-finally': 2,
-    'no-unused-vars': [
-      2,
-      {
-        vars: 'all',
-        args: 'none'
-      }
-    ],
-    'no-useless-call': 2,
-    'no-useless-computed-key': 2,
-    'no-useless-constructor': 2,
-    'no-useless-escape': 0,
-    'no-whitespace-before-property': 2,
-    'no-with': 2,
-    'one-var': [
-      2,
-      {
-        initialized: 'never'
-      }
-    ],
-    'operator-linebreak': [
-      2,
-      'after',
-      {
-        overrides: {
-          '?': 'before',
-          ':': 'before'
-        }
-      }
-    ],
-    'padded-blocks': [2, 'never'],
-    quotes: [
-      2,
-      'single',
-      {
-        avoidEscape: true,
-        allowTemplateLiterals: true
-      }
-    ],
-    semi: [0, 'never'],
-    'semi-spacing': [
-      0,
-      {
-        before: false,
-        after: true
-      }
-    ],
-    'space-before-blocks': [2, 'always'],
-    'space-before-function-paren': [2, 'never'],
-    'space-in-parens': [2, 'never'],
-    'space-infix-ops': 2,
-    'space-unary-ops': [
-      2,
-      {
-        words: true,
-        nonwords: false
-      }
-    ],
-    'spaced-comment': [
-      2,
-      'always',
-      {
-        markers: [
-          'global',
-          'globals',
-          'eslint',
-          'eslint-disable',
-          '*package',
-          '!',
-          ','
-        ]
-      }
-    ],
-    'template-curly-spacing': [2, 'never'],
-    'use-isnan': 2,
-    'valid-typeof': 2,
-    'wrap-iife': [2, 'any'],
-    'yield-star-spacing': [2, 'both'],
-    yoda: [2, 'never'],
-    'prefer-const': 2,
-    'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
-    'object-curly-spacing': [
-      2,
-      'always',
-      {
-        objectsInObjects: false
-      }
-    ],
-    'array-bracket-spacing': [2, 'never']
-  }
+  //   // add your custom rules here
+  //   //it is base on https://github.com/vuejs/eslint-config-vue
+  //   // rules: {
+  //   //   'vue/html-self-closing': [
+  //   //     0,
+  //   //     {
+  //   //       html: {
+  //   //         void: 'always',
+  //   //         normal: 'never',
+  //   //         component: 'always'
+  //   //       },
+  //   //       svg: 'always',
+  //   //       math: 'always'
+  //   //     }
+  //   //   ],
+  //   //   'vue/max-attributes-per-line': [
+  //   //     2,
+  //   //     {
+  //   //       singleline: 10,
+  //   //       multiline: {
+  //   //         max: 1,
+  //   //         allowFirstLine: false
+  //   //       }
+  //   //     }
+  //   //   ],
+  //   //   'vue/singleline-html-element-content-newline': 'off',
+  //   //   'vue/multiline-html-element-content-newline': 'off',
+  //   //   'vue/name-property-casing': ['error', 'PascalCase'],
+  //   //   'vue/no-v-html': 'off',
+  //   //   'accessor-pairs': 2,
+  //   //   'arrow-spacing': [
+  //   //     2,
+  //   //     {
+  //   //       before: true,
+  //   //       after: true
+  //   //     }
+  //   //   ],
+  //   //   'block-spacing': [2, 'always'],
+  //   //   'brace-style': [
+  //   //     2,
+  //   //     '1tbs',
+  //   //     {
+  //   //       allowSingleLine: true
+  //   //     }
+  //   //   ],
+  //   //   camelcase: [
+  //   //     0,
+  //   //     {
+  //   //       properties: 'always'
+  //   //     }
+  //   //   ],
+  //   //   'comma-dangle': [2, 'never'],
+  //   //   'comma-spacing': [
+  //   //     2,
+  //   //     {
+  //   //       before: false,
+  //   //       after: true
+  //   //     }
+  //   //   ],
+  //   //   'comma-style': [2, 'last'],
+  //   //   'constructor-super': 2,
+  //   //   curly: [2, 'multi-line'],
+  //   //   'dot-location': [2, 'property'],
+  //   //   'eol-last': 2,
+  //   //   eqeqeq: [
+  //   //     'error',
+  //   //     'always',
+  //   //     {
+  //   //       null: 'ignore'
+  //   //     }
+  //   //   ],
+  //   //   'generator-star-spacing': [
+  //   //     2,
+  //   //     {
+  //   //       before: true,
+  //   //       after: true
+  //   //     }
+  //   //   ],
+  //   //   'handle-callback-err': [2, '^(err|error)$'],
+  //   //   indent: [
+  //   //     2,
+  //   //     2,
+  //   //     {
+  //   //       SwitchCase: 1
+  //   //     }
+  //   //   ],
+  //   //   'jsx-quotes': [2, 'prefer-single'],
+  //   //   'key-spacing': [
+  //   //     2,
+  //   //     {
+  //   //       beforeColon: false,
+  //   //       afterColon: true
+  //   //     }
+  //   //   ],
+  //   //   'keyword-spacing': [
+  //   //     2,
+  //   //     {
+  //   //       before: true,
+  //   //       after: true
+  //   //     }
+  //   //   ],
+  //   //   'new-cap': [
+  //   //     2,
+  //   //     {
+  //   //       newIsCap: true,
+  //   //       capIsNew: false
+  //   //     }
+  //   //   ],
+  //   //   'new-parens': 2,
+  //   //   'no-array-constructor': 2,
+  //   //   'no-caller': 2,
+  //   //   'no-console': 'off',
+  //   //   'no-class-assign': 2,
+  //   //   'no-cond-assign': 2,
+  //   //   'no-const-assign': 2,
+  //   //   'no-control-regex': 0,
+  //   //   'no-delete-var': 2,
+  //   //   'no-dupe-args': 2,
+  //   //   'no-dupe-class-members': 2,
+  //   //   'no-dupe-keys': 2,
+  //   //   'no-duplicate-case': 2,
+  //   //   'no-empty-character-class': 2,
+  //   //   'no-empty-pattern': 2,
+  //   //   'no-eval': 2,
+  //   //   'no-ex-assign': 2,
+  //   //   'no-extend-native': 2,
+  //   //   'no-extra-bind': 2,
+  //   //   'no-extra-boolean-cast': 2,
+  //   //   'no-extra-parens': [2, 'functions'],
+  //   //   'no-fallthrough': 2,
+  //   //   'no-floating-decimal': 2,
+  //   //   'no-func-assign': 2,
+  //   //   'no-implied-eval': 2,
+  //   //   'no-inner-declarations': [2, 'functions'],
+  //   //   'no-invalid-regexp': 2,
+  //   //   'no-irregular-whitespace': 2,
+  //   //   'no-iterator': 2,
+  //   //   'no-label-var': 2,
+  //   //   'no-labels': [
+  //   //     0,
+  //   //     {
+  //   //       allowLoop: true,
+  //   //       allowSwitch: true
+  //   //     }
+  //   //   ],
+  //   //   'no-lone-blocks': 2,
+  //   //   'no-mixed-spaces-and-tabs': 2,
+  //   //   'no-multi-spaces': 2,
+  //   //   'no-multi-str': 2,
+  //   //   'no-multiple-empty-lines': [
+  //   //     2,
+  //   //     {
+  //   //       max: 1
+  //   //     }
+  //   //   ],
+  //   //   'no-native-reassign': 2,
+  //   //   'no-negated-in-lhs': 2,
+  //   //   'no-new-object': 2,
+  //   //   'no-new-require': 2,
+  //   //   'no-new-symbol': 2,
+  //   //   'no-new-wrappers': 2,
+  //   //   'no-obj-calls': 2,
+  //   //   'no-octal': 2,
+  //   //   'no-octal-escape': 2,
+  //   //   'no-path-concat': 2,
+  //   //   'no-proto': 2,
+  //   //   'no-redeclare': 2,
+  //   //   'no-regex-spaces': 2,
+  //   //   'no-return-assign': [2, 'except-parens'],
+  //   //   'no-self-assign': 2,
+  //   //   'no-self-compare': 2,
+  //   //   'no-sequences': 2,
+  //   //   'no-shadow-restricted-names': 2,
+  //   //   'no-spaced-func': 2,
+  //   //   'no-sparse-arrays': 2,
+  //   //   'no-this-before-super': 2,
+  //   //   'no-throw-literal': 2,
+  //   //   'no-trailing-spaces': 2,
+  //   //   'no-undef': 2,
+  //   //   'no-undef-init': 2,
+  //   //   'no-unexpected-multiline': 2,
+  //   //   'no-unmodified-loop-condition': 2,
+  //   //   'no-unneeded-ternary': [
+  //   //     2,
+  //   //     {
+  //   //       defaultAssignment: false
+  //   //     }
+  //   //   ],
+  //   //   'no-unreachable': 2,
+  //   //   'no-unsafe-finally': 2,
+  //   //   'no-unused-vars': [
+  //   //     2,
+  //   //     {
+  //   //       vars: 'all',
+  //   //       args: 'none'
+  //   //     }
+  //   //   ],
+  //   //   'no-useless-call': 2,
+  //   //   'no-useless-computed-key': 2,
+  //   //   'no-useless-constructor': 2,
+  //   //   'no-useless-escape': 0,
+  //   //   'no-whitespace-before-property': 2,
+  //   //   'no-with': 2,
+  //   //   'one-var': [
+  //   //     2,
+  //   //     {
+  //   //       initialized: 'never'
+  //   //     }
+  //   //   ],
+  //   //   'operator-linebreak': [
+  //   //     2,
+  //   //     'after',
+  //   //     {
+  //   //       overrides: {
+  //   //         '?': 'before',
+  //   //         ':': 'before'
+  //   //       }
+  //   //     }
+  //   //   ],
+  //   //   'padded-blocks': [2, 'never'],
+  //   //   quotes: [
+  //   //     2,
+  //   //     'single',
+  //   //     {
+  //   //       avoidEscape: true,
+  //   //       allowTemplateLiterals: true
+  //   //     }
+  //   //   ],
+  //   //   semi: [0, 'never'],
+  //   //   'semi-spacing': [
+  //   //     0,
+  //   //     {
+  //   //       before: false,
+  //   //       after: true
+  //   //     }
+  //   //   ],
+  //   //   'space-before-blocks': [2, 'always'],
+  //   //   'space-before-function-paren': [2, 'never'],
+  //   //   'space-in-parens': [2, 'never'],
+  //   //   'space-infix-ops': 2,
+  //   //   'space-unary-ops': [
+  //   //     2,
+  //   //     {
+  //   //       words: true,
+  //   //       nonwords: false
+  //   //     }
+  //   //   ],
+  //   //   'spaced-comment': [
+  //   //     2,
+  //   //     'always',
+  //   //     {
+  //   //       markers: [
+  //   //         'global',
+  //   //         'globals',
+  //   //         'eslint',
+  //   //         'eslint-disable',
+  //   //         '*package',
+  //   //         '!',
+  //   //         ','
+  //   //       ]
+  //   //     }
+  //   //   ],
+  //   //   'template-curly-spacing': [2, 'never'],
+  //   //   'use-isnan': 2,
+  //   //   'valid-typeof': 2,
+  //   //   'wrap-iife': [2, 'any'],
+  //   //   'yield-star-spacing': [2, 'both'],
+  //   //   yoda: [2, 'never'],
+  //   //   'prefer-const': 2,
+  //   //   'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
+  //   //   'object-curly-spacing': [
+  //   //     2,
+  //   //     'always',
+  //   //     {
+  //   //       objectsInObjects: false
+  //   //     }
+  //   //   ],
+  //   //   'array-bracket-spacing': [2, 'never']
+  //   // }
 };

+ 9 - 0
.prettierrc

@@ -0,0 +1,9 @@
+{
+    "printWidth": 80,
+    "tabWidth": 2,
+    "singleQuote": true,
+    "trailingComma": "none",
+    "bracketSpacing": true,
+    "arrowParens": "avoid",
+    "htmlWhitespaceSensitivity": "css"
+}

+ 1 - 1
package.json

@@ -39,7 +39,7 @@
     "chalk": "2.4.2",
     "connect": "3.6.6",
     "eslint": "6.7.2",
-    "eslint-plugin-vue": "6.2.2",
+    "eslint-plugin-vue": "^6.2.2",
     "html-webpack-plugin": "3.2.0",
     "mockjs": "1.0.1-beta3",
     "runjs": "4.3.2",

+ 161 - 0
src/components/BaseTable.vue

@@ -0,0 +1,161 @@
+<template>
+  <div class="mt-20">
+    <el-table
+      :data="items"
+      :style="`width: 100%; min-height:${minHeight};`"
+      v-bind="$attrs"
+      @selection-change="handleSelectionChange"
+    >
+      <slot name="table">
+        <template v-for="column in columns">
+          <el-table-column
+            v-if="column.key === 'selection'"
+            :key="column.key"
+            :type="column.key"
+            :min-width="column.minWidth"
+            :width="column.width || 50"
+            :align="column.align || 'center'"
+          />
+          <el-table-column
+            v-else
+            :key="column.key"
+            :prop="column.key"
+            :label="column.name"
+            :min-width="column.minWidth"
+            :width="column.width"
+            :align="column.align"
+            :fixed="column.fixed"
+            :show-overflow-tooltip="column['show-overflow-tooltip']"
+          >
+            <template slot-scope="scope">
+              <ex-slot
+                v-if="column.render"
+                :render="column.render"
+                :row="scope.row"
+                :index="scope.$index"
+                :column="column"
+              />
+              <span v-else-if="column.type === 'tag'">
+                <el-tag
+                  size="medium"
+                  :type="column.fetchTagType(scope.row[column.key]) || ''"
+                  >{{ scope.row[column.key] }}</el-tag
+                >
+              </span>
+              <span v-else>{{ scope.row[column.key] || '-' }}</span>
+            </template>
+          </el-table-column>
+        </template>
+      </slot>
+    </el-table>
+    <div class="page-select">
+      <div class="btn-box">
+        <slot :selected="multipleSelection" name="btn-box" />
+      </div>
+      <el-pagination
+        v-if="showPage"
+        background
+        layout="prev, pager, next"
+        :current-page="pagination.page"
+        :page-size="pagination.pageSize"
+        :total="pagination.total"
+        @current-change="num => pageChange(num)"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+// 自定义内容的组件
+var exSlot = {
+  functional: true,
+  props: {
+    row: Object,
+    render: Function,
+    index: Number,
+    column: {
+      type: Object,
+      default: null
+    }
+  },
+
+  render: (h, data) => {
+    const params = {
+      row: data.props.row,
+      index: data.props.index
+    };
+
+    if (data.props.column) params.column = data.props.column;
+    return data.props.render(h, params);
+  }
+};
+
+export default {
+  name: 'TableWithPage',
+
+  components: {
+    'ex-slot': exSlot
+  },
+
+  props: {
+    columns: {
+      type: Array,
+      default: () => []
+    },
+    items: {
+      type: Array,
+      default: () => []
+    },
+    pagination: {
+      type: Object,
+      default: () => ({})
+    },
+    pageChange: {
+      type: Function,
+      default: () => {}
+    },
+    minHeight: {
+      type: String,
+      default: '600px'
+    },
+    showPage: {
+      type: Boolean,
+      default: true
+    }
+  },
+
+  data() {
+    return {
+      multipleSelection: []
+    };
+  },
+
+  watch: {
+    items: {
+      handler(val) {
+        this.multipleSelection = [];
+      },
+      immedaite: true
+    }
+  },
+
+  methods: {
+    handleSelectionChange(params) {
+      this.multipleSelection = params;
+    }
+  }
+};
+</script>
+
+<style scoped>
+.page-select {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 6px 20px 0 20px;
+}
+
+.btn-box .el-button {
+  margin: 2px 10px;
+}
+</style>

+ 0 - 0
src/components/Breadcrumb/index.vue → src/components/Breadcrumb.vue


+ 0 - 0
src/components/Hamburger/index.vue → src/components/Hamburger.vue


+ 0 - 0
src/components/SvgIcon/index.vue → src/components/SvgIcon.vue


+ 10 - 0
src/components/index.js

@@ -0,0 +1,10 @@
+import Vue from 'vue';
+import BaseTable from './BaseTable.vue';
+import Breadcrumb from './Breadcrumb.vue';
+import Hamburger from './Hamburger.vue';
+import SvgIcon from './SvgIcon.vue';
+
+Vue.component('BaseTable', BaseTable);
+Vue.component('Breadcrumb', Breadcrumb);
+Vue.component('Hamburger', Hamburger);
+Vue.component('SvgIcon', SvgIcon);

+ 35 - 0
src/components/inject.js

@@ -0,0 +1,35 @@
+const glob = require('glob');
+const fs = require('fs');
+const filenames = [];
+var entryFiles = glob.sync('./**/*.vue');
+entryFiles.forEach(filePath => {
+  filenames.push(filePath);
+});
+const getImportItemStr = path => {
+  const filename = path.substring(
+    path.lastIndexOf('/') + 1,
+    path.lastIndexOf('.')
+  );
+  return `import ${filename} from '${path}';`;
+};
+const getRegistItemStr = path => {
+  const filename = path.substring(
+    path.lastIndexOf('/') + 1,
+    path.lastIndexOf('.')
+  );
+  return `Vue.component('${filename}', ${filename});`;
+};
+
+const content = [
+  `import Vue from 'vue';`,
+  '\r\n',
+  filenames.map(x => getImportItemStr(x)).join('\r\n'),
+  '\r\n\r\n',
+  filenames.map(x => getRegistItemStr(x)).join('\r\n'),
+  '\r\n'
+];
+
+fs.writeFile('./index.js', content.join(''), function(err) {
+  if (err) console.log(err);
+  else console.log('写文件操作成功');
+});

+ 201 - 0
src/containers/ToolbarContainer.vue

@@ -0,0 +1,201 @@
+<template>
+  <el-form
+    :class="fields.length > 0 ? 'm-10 p-20 br-10 bg-w' : ''"
+    label-position="right"
+    label-width="0"
+    :model="form"
+  >
+    <div class="f-sb-fs">
+      <el-row class="f-1" :gutter="20">
+        <el-col
+          v-for="field in fields"
+          :key="field.name"
+          :span="field.col || 8"
+          class="h-50"
+        >
+          <el-form-item
+            :label="field.label"
+            :label-width="
+              field.labelWidth ? field.labelWidth : field.label && '80px'
+            "
+          >
+            <!-- 输入文本 -->
+            <el-input
+              v-if="field.type === 'text'"
+              v-model="form[field.name]"
+              :clearable="true"
+              :placeholder="'请输入' + field.label"
+            />
+
+            <!-- 单选 -->
+            <el-select
+              v-if="field.type === 'select'"
+              v-model="form[field.name]"
+              :clearable="true"
+              :placeholder="'请选择' + field.label"
+            >
+              <el-option
+                v-for="item in field.options"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
+              >
+              </el-option>
+            </el-select>
+
+            <!-- 多选 -->
+            <el-select
+              v-if="field.type === 'multipleSelect'"
+              v-model="form[field.name]"
+              multiple
+              collapse-tags
+              :clearable="true"
+              :placeholder="'请选择' + field.label"
+            >
+              <el-option
+                v-for="item in field.options"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
+              >
+              </el-option>
+            </el-select>
+
+            <!-- 时间选择器 -->
+            <el-date-picker
+              v-if="field.type === 'dateArray'"
+              v-model="form[field.name]"
+              type="datetimerange"
+              start-placeholder="开始日期"
+              end-placeholder="结束日期"
+            >
+            </el-date-picker>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <div class="f-fe-c pl-40">
+        <el-button v-if="showSearch" type="primary" @click="handleSubmit"
+          >查询</el-button
+        >
+        <el-button v-if="showReset" @click="handleReset">重置</el-button>
+      </div>
+    </div>
+  </el-form>
+</template>
+
+<script>
+function isPromise(obj) {
+  return (
+    !!obj &&
+    (typeof obj === 'object' || typeof obj === 'function') &&
+    typeof obj.then === 'function'
+  );
+}
+export default {
+  name: 'Toolbar',
+
+  props: {
+    fields: {
+      type: Array,
+      default: () => []
+    },
+    showSearch: {
+      type: Boolean,
+      default: true
+    },
+    showReset: {
+      type: Boolean,
+      default: true
+    },
+    firstLoad: {
+      type: Boolean,
+      default: true
+    }
+  },
+
+  data() {
+    return {
+      form: {}
+    };
+  },
+
+  mounted() {
+    if (this.firstLoad) {
+      this.handleReset();
+    } else {
+      this.initForm();
+    }
+  },
+
+  methods: {
+    handleSubmit() {
+      const filter = this.getFormData();
+      this.$emit('on-filter', filter);
+    },
+
+    async handleReset() {
+      await this.initForm();
+      const filter = this.getFormData();
+      this.$emit('on-reset', filter);
+    },
+
+    async initForm() {
+      const form = this.fields.reduce(async (init, current) => {
+        init = await init;
+        init[current.name] = current.defaultValue || null;
+
+        if (current.options && isPromise(current.options)) {
+          current.options = await current.options;
+        }
+
+        return init;
+      }, Promise.resolve({}));
+      this.form = await form;
+    },
+
+    getFormData() {
+      const filter =
+        this.fields.length > 0
+          ? this.fields.reduce((init, { name, apiName, type, format }) => {
+              const values = this.form[name];
+              const key = apiName || name;
+              let temp = null;
+
+              if (type === 'dateArray') {
+                temp = [];
+                apiName.forEach((x, i) => {
+                  temp.push(values && values[i]);
+                });
+              } else {
+                temp = values || values === 0 ? values : null;
+              }
+              const val = format ? format(values, temp) : temp;
+              if (typeof key === 'string') {
+                init[key] = val;
+              } else {
+                key.forEach((x, i) => {
+                  init[x] = val[i];
+                });
+              }
+              return init;
+            })
+          : [];
+    }
+  }
+};
+</script>
+
+<style scoped lang="scss">
+.f-1 {
+  flex: 1;
+}
+.h-50 {
+  height: 50px;
+}
+.el-select {
+  width: 100%;
+}
+.el-range-editor.el-input__inner {
+  width: 100%;
+}
+</style>

+ 4 - 0
src/containers/index.js

@@ -0,0 +1,4 @@
+import Vue from 'vue';
+import ToolbarContainer from './ToolbarContainer.vue';
+
+Vue.component('ToolbarContainer', ToolbarContainer);

+ 35 - 0
src/containers/inject.js

@@ -0,0 +1,35 @@
+const glob = require('glob');
+const fs = require('fs');
+const filenames = [];
+var entryFiles = glob.sync('./**/*.vue');
+entryFiles.forEach(filePath => {
+  filenames.push(filePath);
+});
+const getImportItemStr = path => {
+  const filename = path.substring(
+    path.lastIndexOf('/') + 1,
+    path.lastIndexOf('.')
+  );
+  return `import ${filename} from '${path}';`;
+};
+const getRegistItemStr = path => {
+  const filename = path.substring(
+    path.lastIndexOf('/') + 1,
+    path.lastIndexOf('.')
+  );
+  return `Vue.component('${filename}', ${filename});`;
+};
+
+const content = [
+  `import Vue from 'vue';`,
+  '\r\n',
+  filenames.map(x => getImportItemStr(x)).join('\r\n'),
+  '\r\n\r\n',
+  filenames.map(x => getRegistItemStr(x)).join('\r\n'),
+  '\r\n'
+];
+
+fs.writeFile('./index.js', content.join(''), function(err) {
+  if (err) console.log(err);
+  else console.log('写文件操作成功');
+});

+ 4 - 3
src/layout/components/AppMain.vue

@@ -11,10 +11,10 @@ export default {
   name: 'AppMain',
   computed: {
     key() {
-      return this.$route.path
+      return this.$route.path;
     }
   }
-}
+};
 </script>
 
 <style scoped>
@@ -24,8 +24,9 @@ export default {
   width: 100%;
   position: relative;
   overflow: hidden;
+  background-color: #eceeef;
 }
-.fixed-header+.app-main {
+.fixed-header + .app-main {
   padding-top: 50px;
 }
 </style>

+ 0 - 6
src/layout/components/Navbar.vue

@@ -38,14 +38,8 @@
 
 <script>
 import { mapGetters } from 'vuex';
-import Breadcrumb from '@/components/Breadcrumb';
-import Hamburger from '@/components/Hamburger';
 
 export default {
-  components: {
-    Breadcrumb,
-    Hamburger
-  },
   computed: {
     ...mapGetters(['sidebar', 'avatar', 'name'])
   },

+ 20 - 20
src/layout/components/Sidebar/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <div :class="{'has-logo':showLogo}">
+  <div :class="{ 'has-logo': showLogo }">
     <logo v-if="showLogo" :collapse="isCollapse" />
     <el-scrollbar wrap-class="scrollbar-wrapper">
       <el-menu
@@ -12,45 +12,45 @@
         :collapse-transition="false"
         mode="vertical"
       >
-        <sidebar-item v-for="route in routes" :key="route.path" :item="route" :base-path="route.path" />
+        <sidebar-item
+          v-for="route in permission_routes"
+          :key="route.path"
+          :item="route"
+          :base-path="route.path"
+        />
       </el-menu>
     </el-scrollbar>
   </div>
 </template>
 
 <script>
-import { mapGetters } from 'vuex'
-import Logo from './Logo'
-import SidebarItem from './SidebarItem'
-import variables from '@/styles/variables.scss'
+import { mapGetters } from 'vuex';
+import Logo from './Logo';
+import SidebarItem from './SidebarItem';
+import variables from '@/styles/variables.scss';
 
 export default {
   components: { SidebarItem, Logo },
   computed: {
-    ...mapGetters([
-      'sidebar'
-    ]),
-    routes() {
-      return this.$router.options.routes
-    },
+    ...mapGetters(['permission_routes', 'sidebar']),
     activeMenu() {
-      const route = this.$route
-      const { meta, path } = route
+      const route = this.$route;
+      const { meta, path } = route;
       // if set path, the sidebar will highlight the path you set
       if (meta.activeMenu) {
-        return meta.activeMenu
+        return meta.activeMenu;
       }
-      return path
+      return path;
     },
     showLogo() {
-      return this.$store.state.settings.sidebarLogo
+      return this.$store.state.settings.sidebarLogo;
     },
     variables() {
-      return variables
+      return variables;
     },
     isCollapse() {
-      return !this.sidebar.opened
+      return !this.sidebar.opened;
     }
   }
-}
+};
 </script>

+ 20 - 17
src/main.js

@@ -1,19 +1,22 @@
-import Vue from 'vue'
+import Vue from 'vue';
 
-import 'normalize.css/normalize.css' // A modern alternative to CSS resets
+import 'normalize.css/normalize.css'; // A modern alternative to CSS resets
 
-import ElementUI from 'element-ui'
-import 'element-ui/lib/theme-chalk/index.css'
-import locale from 'element-ui/lib/locale/lang/en' // lang i18n
+import ElementUI from 'element-ui';
+import 'element-ui/lib/theme-chalk/index.css';
+import locale from 'element-ui/lib/locale/lang/en'; // lang i18n
 
-import '@/styles/index.scss' // global css
+import '@/styles/index.scss'; // global css
 
-import App from './App'
-import store from './store'
-import router from './router'
+import App from './App';
+import store from './store';
+import router from './router';
 
-import '@/icons' // icon
-import '@/permission' // permission control
+import '@/icons'; // icon
+import '@/permission'; // permission control
+
+import './components';
+import './containers';
 
 /**
  * If you don't want to use mock-server
@@ -24,20 +27,20 @@ import '@/permission' // permission control
  * please remove it before going online ! ! !
  */
 if (process.env.NODE_ENV === 'production') {
-  const { mockXHR } = require('../mock')
-  mockXHR()
+  const { mockXHR } = require('../mock');
+  mockXHR();
 }
 
 // set ElementUI lang to EN
-Vue.use(ElementUI, { locale })
+// Vue.use(ElementUI, { locale })
 // 如果想要中文版 element-ui,按如下方式声明
-// Vue.use(ElementUI)
+Vue.use(ElementUI, { size: 'small', zIndex: 3000 });
 
-Vue.config.productionTip = false
+Vue.config.productionTip = false;
 
 new Vue({
   el: '#app',
   router,
   store,
   render: h => h(App)
-})
+});

+ 73 - 0
src/mixins/filterList.js

@@ -0,0 +1,73 @@
+import { Message } from 'element-ui';
+// import tips from 'utils/tips'
+const filterList = (params = {}) => ({
+  data() {
+    return {
+      isLoading: false,
+      items: [],
+      pagination: {
+        page: 1,
+        total: 0,
+        pageSize: 50
+      },
+      filter: {}, // 每次填写的过滤条件
+      internalFilterObj: {}, // 必定的内置过滤条件
+      fetchList: () => {}
+    };
+  },
+
+  created() {
+    Object.assign(this, params);
+  },
+
+  methods: {
+    loadCallBack() {},
+
+    apiList(data) {
+      return this.fetchList(data);
+    },
+
+    reload() {
+      this.pageChange(this.pagination.page);
+    },
+
+    async pageChange(page) {
+      this.pagination.page = page;
+      const inParams = {
+        ...this.filter,
+        ...this.internalFilterObj,
+        page: this.pagination.page,
+        size: this.pagination.pageSize
+      };
+
+      const { data, message } = await this.apiList(inParams);
+      if (data) {
+        const items = data.data;
+        const total = {
+          page: data.page,
+          pageSize: data.size,
+          total: data.total
+        };
+        if (items.length === 0 && this.pagination.page > 1) {
+          this.pageChange(1);
+        } else {
+          this.items = items;
+          this.pagination = total;
+        }
+        this.loadCallBack(data);
+      } else {
+        Message({
+          message: message,
+          type: 'error',
+          duration: 5 * 1000
+        });
+      }
+    },
+
+    filterData(filter) {
+      this.filter = filter;
+      this.pageChange(1);
+    }
+  }
+});
+export default filterList;

+ 40 - 29
src/permission.js

@@ -1,46 +1,57 @@
-import router from './router'
-import store from './store'
-import { Message } from 'element-ui'
-import NProgress from 'nprogress' // progress bar
-import 'nprogress/nprogress.css' // progress bar style
-import { getToken } from '@/utils/auth' // get token from cookie
-import getPageTitle from '@/utils/get-page-title'
+import router from './router';
+import store from './store';
+import { Message } from 'element-ui';
+import NProgress from 'nprogress'; // progress bar
+import 'nprogress/nprogress.css'; // progress bar style
+import { getToken } from '@/utils/auth'; // get token from cookie
+import getPageTitle from '@/utils/get-page-title';
 
-NProgress.configure({ showSpinner: false }) // NProgress Configuration
+NProgress.configure({ showSpinner: false }); // NProgress Configuration
 
-const whiteList = ['/login'] // no redirect whitelist
+const whiteList = ['/login']; // no redirect whitelist
 
-router.beforeEach(async(to, from, next) => {
+router.beforeEach(async (to, from, next) => {
   // start progress bar
-  NProgress.start()
+  NProgress.start();
 
   // set page title
-  document.title = getPageTitle(to.meta.title)
+  document.title = getPageTitle(to.meta.title);
 
   // determine whether the user has logged in
-  const hasToken = getToken()
+  const hasToken = getToken();
 
   if (hasToken) {
     if (to.path === '/login') {
       // if is logged in, redirect to the home page
-      next({ path: '/' })
-      NProgress.done()
+      next({ path: '/' });
+      NProgress.done();
     } else {
-      const hasGetUserInfo = store.getters.name
+      const hasGetUserInfo = store.getters.name;
       if (hasGetUserInfo) {
-        next()
+        next();
       } else {
         try {
           // get user info
-          await store.dispatch('user/getInfo')
+          const { roles } = await store.dispatch('user/getInfo');
+          // await store.dispatch('user/getInfo');
 
-          next()
+          // generate accessible routes map based on roles
+          const accessRoutes = await store.dispatch(
+            'permission/generateRoutes',
+            roles
+          );
+
+          // dynamically add accessible routes
+          router.addRoutes(accessRoutes);
+
+          next({ ...to, replace: true });
+          // next()
         } catch (error) {
           // remove token and go to login page to re-login
-          await store.dispatch('user/resetToken')
-          Message.error(error || 'Has Error')
-          next(`/login?redirect=${to.path}`)
-          NProgress.done()
+          await store.dispatch('user/resetToken');
+          Message.error(error || 'Has Error');
+          next(`/login?redirect=${to.path}`);
+          NProgress.done();
         }
       }
     }
@@ -49,16 +60,16 @@ router.beforeEach(async(to, from, next) => {
 
     if (whiteList.indexOf(to.path) !== -1) {
       // in the free login whitelist, go directly
-      next()
+      next();
     } else {
       // other pages that do not have permission to access are redirected to the login page.
-      next(`/login?redirect=${to.path}`)
-      NProgress.done()
+      next(`/login?redirect=${to.path}`);
+      NProgress.done();
     }
   }
-})
+});
 
 router.afterEach(() => {
   // finish progress bar
-  NProgress.done()
-})
+  NProgress.done();
+});

+ 403 - 88
src/router/index.js

@@ -1,10 +1,10 @@
-import Vue from 'vue'
-import Router from 'vue-router'
+import Vue from 'vue';
+import Router from 'vue-router';
 
-Vue.use(Router)
+Vue.use(Router);
 
 /* Layout */
-import Layout from '@/layout'
+import Layout from '@/layout';
 
 /**
  * Note: sub-menu only appear when route children.length >= 1
@@ -47,135 +47,450 @@ export const constantRoutes = [
     path: '/',
     component: Layout,
     redirect: '/dashboard',
-    children: [{
-      path: 'dashboard',
-      name: 'Dashboard',
-      component: () => import('@/views/dashboard/index'),
-      meta: { title: 'Dashboard', icon: 'dashboard' }
-    }]
+    children: [
+      {
+        path: 'dashboard',
+        name: 'Dashboard',
+        component: () => import('@/views/dashboard/index'),
+        meta: {
+          title: 'Dashboard',
+          icon: 'dashboard'
+        }
+      }
+    ]
+  },
+
+  {
+    path: '/form',
+    component: Layout,
+    children: [
+      {
+        path: 'index',
+        name: 'Form',
+        component: () => import('@/views/form/index'),
+        meta: {
+          title: 'Form',
+          icon: 'form'
+        }
+      }
+    ]
+  },
+  {
+    path: '/baseManagement',
+    component: Layout,
+    redirect: '/baseManagement/BannerManagement',
+    name: '基础管理',
+    meta: {
+      title: '基础管理',
+      icon: 'el-icon-s-help'
+    },
+    children: [
+      {
+        path: 'BannerManagement',
+        name: 'Banner管理',
+        component: () =>
+          import('@/views/baseManagement/bannerManagement/index'),
+        meta: {
+          title: 'Banner管理'
+          // icon: 'table'
+        }
+      },
+      {
+        path: 'InfoManagement',
+        name: '资讯管理',
+        component: () => import('@/views/baseManagement/infoManagement/index'),
+        meta: {
+          title: '资讯管理'
+          // icon: 'tree'
+        }
+      },
+      {
+        path: 'ProblemFeedbackManagement',
+        name: '问题反馈管理',
+        component: () =>
+          import('@/views/baseManagement/problemFeedbackManagement/index'),
+        meta: {
+          title: '问题反馈管理'
+          // icon: 'tree'
+        }
+      }
+    ]
+  },
+  {
+    path: '/photographerManagement',
+    component: Layout,
+    redirect: '/photographerManagement/PhotographerVerify',
+    name: '摄影师管理',
+    meta: {
+      title: '摄影师管理',
+      icon: 'el-icon-s-help'
+    },
+    children: [
+      {
+        path: 'PhotographerVerify',
+        name: '摄影师审核',
+        component: () =>
+          import('@/views/photographerManagement/photographerVerify/index'),
+        meta: {
+          title: '摄影师审核'
+          // icon: 'table'
+        }
+      },
+      {
+        path: 'PhotoVerify',
+        name: '照片管理',
+        component: () =>
+          import('@/views/photographerManagement/photoVerify/index'),
+        meta: {
+          title: '照片管理'
+          // icon: 'tree'
+        }
+      }
+    ]
   },
 
   {
-    path: '/example',
+    path: '/pointsManagement',
     component: Layout,
-    redirect: '/example/table',
-    name: 'Example',
-    meta: { title: 'Example', icon: 'el-icon-s-help' },
+    redirect: '/pointsManagement/PointsDetail',
+    name: '积分管理',
+    meta: {
+      title: '积分管理',
+      icon: 'el-icon-s-help'
+    },
     children: [
       {
-        path: 'table',
-        name: 'Table',
-        component: () => import('@/views/table/index'),
-        meta: { title: 'Table', icon: 'table' }
+        path: 'PointsDetail',
+        name: '积分明细',
+        component: () => import('@/views/pointsManagement/pointsDetail/index'),
+        meta: {
+          title: '积分明细'
+          // icon: 'table'
+        }
       },
       {
-        path: 'tree',
-        name: 'Tree',
-        component: () => import('@/views/tree/index'),
-        meta: { title: 'Tree', icon: 'tree' }
+        path: 'PointsSetting',
+        name: '积分设置',
+        component: () => import('@/views/pointsManagement/pointsSetting/index'),
+        meta: {
+          title: '积分设置'
+          // icon: 'tree'
+        }
       }
     ]
   },
 
   {
-    path: '/form',
+    path: '/sceneManagement',
     component: Layout,
+    redirect: '/sceneManagement/SceneList',
+    name: '场景管理',
+    meta: {
+      title: '场景管理',
+      icon: 'el-icon-s-help'
+    },
     children: [
       {
-        path: 'index',
-        name: 'Form',
-        component: () => import('@/views/form/index'),
-        meta: { title: 'Form', icon: 'form' }
+        path: 'SceneList',
+        name: '场景列表',
+        component: () => import('@/views/sceneManagement/sceneList/index'),
+        meta: {
+          title: '场景列表'
+          // icon: 'table'
+        }
+      },
+      {
+        path: 'SceneVerify',
+        name: '场景审核',
+        component: () => import('@/views/sceneManagement/sceneVerify/index'),
+        meta: {
+          title: '场景审核'
+          // icon: 'tree'
+        }
+      }
+    ]
+  },
+
+  {
+    path: '/memberManagement',
+    component: Layout,
+    redirect: '/memberManagement/MemberLever',
+    name: '会员管理',
+    meta: {
+      title: '会员管理',
+      icon: 'el-icon-s-help'
+    },
+    children: [
+      {
+        path: 'MemberLever',
+        name: '会员等级',
+        component: () => import('@/views/memberManagement/memberLever/index'),
+        meta: {
+          title: '会员等级'
+          // icon: 'table'
+        }
+      },
+      {
+        path: 'MemberList',
+        name: '会员列表',
+        component: () => import('@/views/memberManagement/memberList/index'),
+        meta: {
+          title: '会员列表'
+          // icon: 'tree'
+        }
+      }
+    ]
+  },
+
+  {
+    path: '/helpInfo',
+    component: Layout,
+    redirect: '/helpInfo/IssueType',
+    name: '帮助信息',
+    meta: {
+      title: '帮助信息',
+      icon: 'el-icon-s-help'
+    },
+    children: [
+      {
+        path: 'IssueType',
+        name: '问题分类',
+        component: () => import('@/views/helpInfo/issueType/index'),
+        meta: {
+          title: '问题分类'
+          // icon: 'table'
+        }
+      },
+      {
+        path: 'Information',
+        name: '信息内容',
+        component: () => import('@/views/helpInfo/information/index'),
+        meta: {
+          title: '信息内容'
+          // icon: 'tree'
+        }
+      }
+    ]
+  },
+
+  {
+    path: '/systemManagement',
+    component: Layout,
+    redirect: '/systemManagement/AccountManagement',
+    name: '系统管理',
+    meta: {
+      title: '系统管理',
+      icon: 'el-icon-s-help'
+    },
+    children: [
+      {
+        path: 'AccountManagement',
+        name: '账号列表',
+        component: () =>
+          import('@/views/systemManagement/accountManagement/index'),
+        meta: {
+          title: '账号列表'
+          // icon: 'table'
+        }
+      },
+      {
+        path: 'RoleManagement',
+        name: '角色列表',
+        component: () =>
+          import('@/views/systemManagement/roleManagement/index'),
+        meta: {
+          title: '角色列表'
+          // icon: 'tree'
+        }
+      }
+    ]
+  },
+
+  {
+    path: '/photoManagement',
+    component: Layout,
+    redirect: '/photoManagement/ImageGoodsManagement',
+    name: '图片库管理',
+    meta: {
+      title: '图片库管理',
+      icon: 'el-icon-s-help'
+    },
+    children: [
+      {
+        path: 'ImageGoodsManagement',
+        name: '照片商品管理',
+        component: () =>
+          import('@/views/photoManagement/imageGoodsManagement/index'),
+        meta: {
+          title: '照片商品管理'
+          // icon: 'table'
+        }
+      },
+      {
+        path: 'EventsList',
+        name: '活动列表',
+        component: () => import('@/views/photoManagement/eventsList/index'),
+        meta: {
+          title: '活动列表'
+          // icon: 'tree'
+        }
+      },
+      {
+        path: 'UploadManagement',
+        name: '上传照片管理',
+        component: () =>
+          import('@/views/photoManagement/uploadManagement/index'),
+        meta: {
+          title: '上传照片管理'
+          // icon: 'tree'
+        }
       }
     ]
   },
 
   {
-    path: '/nested',
+    path: 'financialManagement',
     component: Layout,
-    redirect: '/nested/menu1',
-    name: 'Nested',
+    redirect: '/financialManagement/OrderManagement',
+    name: '财务管理',
     meta: {
-      title: 'Nested',
-      icon: 'nested'
+      title: '财务管理',
+      icon: 'el-icon-s-help'
     },
     children: [
       {
-        path: 'menu1',
-        component: () => import('@/views/nested/menu1/index'), // Parent router-view
-        name: 'Menu1',
-        meta: { title: 'Menu1' },
-        children: [
-          {
-            path: 'menu1-1',
-            component: () => import('@/views/nested/menu1/menu1-1'),
-            name: 'Menu1-1',
-            meta: { title: 'Menu1-1' }
-          },
-          {
-            path: 'menu1-2',
-            component: () => import('@/views/nested/menu1/menu1-2'),
-            name: 'Menu1-2',
-            meta: { title: 'Menu1-2' },
-            children: [
-              {
-                path: 'menu1-2-1',
-                component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'),
-                name: 'Menu1-2-1',
-                meta: { title: 'Menu1-2-1' }
-              },
-              {
-                path: 'menu1-2-2',
-                component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'),
-                name: 'Menu1-2-2',
-                meta: { title: 'Menu1-2-2' }
-              }
-            ]
-          },
-          {
-            path: 'menu1-3',
-            component: () => import('@/views/nested/menu1/menu1-3'),
-            name: 'Menu1-3',
-            meta: { title: 'Menu1-3' }
-          }
-        ]
+        path: 'OrderManagement',
+        name: '订单列表',
+        component: () =>
+          import('@/views/financialManagement/orderManagement/index'),
+        meta: {
+          title: '订单列表'
+          // icon: 'table'
+        }
       },
       {
-        path: 'menu2',
-        component: () => import('@/views/nested/menu2/index'),
-        name: 'Menu2',
-        meta: { title: 'menu2' }
+        path: 'FundDetail',
+        name: '资金明细',
+        component: () => import('@/views/financialManagement/fundDetail/index'),
+        meta: {
+          title: '资金明细'
+          // icon: 'tree'
+        }
       }
     ]
   },
 
   {
-    path: 'external-link',
+    path: 'statistics',
     component: Layout,
+    redirect: '/statistics/DownloadImage',
+    name: '数据统计',
+    meta: {
+      title: '数据统计',
+      icon: 'el-icon-s-help'
+    },
     children: [
       {
-        path: 'https://panjiachen.github.io/vue-element-admin-site/#/',
-        meta: { title: 'External Link', icon: 'link' }
+        path: 'DownloadImage',
+        name: '下载照片',
+        component: () => import('@/views/statistics/downloadImage/index'),
+        meta: {
+          title: '下载照片'
+          // icon: 'table'
+        }
+      },
+      {
+        path: 'UploadImage',
+        name: '上传照片',
+        component: () => import('@/views/statistics/uploadImage/index'),
+        meta: {
+          title: '上传照片'
+          // icon: 'tree'
+        }
+      },
+      {
+        path: 'WithdrawalRecord',
+        name: '提现记录',
+        component: () => import('@/views/statistics/withdrawalRecord/index'),
+        meta: {
+          title: '提现记录'
+          // icon: 'tree'
+        }
       }
     ]
   },
 
   // 404 page must be placed at the end !!!
-  { path: '*', redirect: '/404', hidden: true }
-]
+  {
+    path: '*',
+    redirect: '/404',
+    hidden: true
+  }
+];
+
+/**
+ * asyncRoutes
+ * the routes that need to be dynamically loaded based on user roles
+ */
+export const asyncRoutes = [
+  // {
+  //   path: '/example',
+  //   component: Layout,
+  //   redirect: '/example/table',
+  //   name: '基础管理',
+  //   meta: {
+  //     title: '基础管理',
+  //     icon: 'el-icon-s-help'
+  //   },
+  //   children: [
+  //     {
+  //       path: 'BannerManagement',
+  //       name: 'Banner管理',
+  //       component: () =>
+  //         import('@/views/baseManagement/bannerManagement/index'),
+  //       meta: {
+  //         title: 'Banner管理'
+  //         // icon: 'table'
+  //       }
+  //     },
+  //     {
+  //       path: 'InfoManagement',
+  //       name: '资讯管理',
+  //       component: () => import('@/views/baseManagement/infoManagement/index'),
+  //       meta: {
+  //         title: '资讯管理'
+  //         // icon: 'tree'
+  //       }
+  //     },
+  //     {
+  //       path: 'ProblemFeedbackManagement',
+  //       name: '问题反馈管理',
+  //       component: () =>
+  //         import('@/views/baseManagement/problemFeedbackManagement/index'),
+  //       meta: {
+  //         title: '问题反馈管理'
+  //         // icon: 'tree'
+  //       }
+  //     }
+  //   ]
+  // }
+];
 
-const createRouter = () => new Router({
-  // mode: 'history', // require service support
-  scrollBehavior: () => ({ y: 0 }),
-  routes: constantRoutes
-})
+const createRouter = () =>
+  new Router({
+    // mode: 'history', // require service support
+    scrollBehavior: () => ({
+      y: 0
+    }),
+    routes: constantRoutes
+  });
 
-const router = createRouter()
+const router = createRouter();
 
 // Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
 export function resetRouter() {
-  const newRouter = createRouter()
-  router.matcher = newRouter.matcher // reset router
+  const newRouter = createRouter();
+  router.matcher = newRouter.matcher; // reset router
 }
 
-export default router
+export default router;

+ 5 - 3
src/store/getters.js

@@ -3,6 +3,8 @@ const getters = {
   device: state => state.app.device,
   token: state => state.user.token,
   avatar: state => state.user.avatar,
-  name: state => state.user.name
-}
-export default getters
+  name: state => state.user.name,
+  roles: state => state.user.roles,
+  permission_routes: state => state.permission.routes
+};
+export default getters;

+ 20 - 14
src/store/index.js

@@ -1,19 +1,25 @@
-import Vue from 'vue'
-import Vuex from 'vuex'
-import getters from './getters'
-import app from './modules/app'
-import settings from './modules/settings'
-import user from './modules/user'
+import Vue from 'vue';
+import Vuex from 'vuex';
+import getters from './getters';
 
-Vue.use(Vuex)
+Vue.use(Vuex);
+
+// https://webpack.js.org/guides/dependency-management/#requirecontext
+const modulesFiles = require.context('./modules', true, /\.js$/);
+
+// you do not need `import app from './modules/app'`
+// it will auto require all vuex module from modules file
+const modules = modulesFiles.keys().reduce((modules, modulePath) => {
+  // set './app.js' => 'app'
+  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1');
+  const value = modulesFiles(modulePath);
+  modules[moduleName] = value.default;
+  return modules;
+}, {});
 
 const store = new Vuex.Store({
-  modules: {
-    app,
-    settings,
-    user
-  },
+  modules,
   getters
-})
+});
 
-export default store
+export default store;

+ 75 - 0
src/store/modules/permission.js

@@ -0,0 +1,75 @@
+import { asyncRoutes, constantRoutes } from '@/router';
+
+/**
+ * Use meta.role to determine if the current user has permission
+ * @param roles
+ * @param route
+ */
+function hasPermission(roles, route) {
+  if (route.meta && route.meta.roles) {
+    return roles.some(role => route.meta.roles.includes(role));
+  } else {
+    return true;
+  }
+}
+
+/**
+ * Filter asynchronous routing tables by recursion
+ * @param routes asyncRoutes
+ * @param roles
+ */
+export function filterAsyncRoutes(routes, roles) {
+  const res = [];
+
+  routes.forEach(route => {
+    const tmp = { ...route };
+    if (hasPermission(roles, tmp)) {
+      if (tmp.children) {
+        tmp.children = filterAsyncRoutes(tmp.children, roles);
+      }
+      res.push(tmp);
+    }
+  });
+
+  return res;
+}
+
+const state = {
+  routes: [],
+  addRoutes: []
+};
+
+const mutations = {
+  SET_ROUTES: (state, routes) => {
+    state.addRoutes = routes;
+    state.routes = constantRoutes.concat(routes);
+  }
+};
+
+const actions = {
+  generateRoutes({ commit }, roles) {
+    return new Promise(resolve => {
+      let accessedRoutes = asyncRoutes;
+      // commit('SET_ROUTES', []);
+      commit('SET_ROUTES', accessedRoutes);
+      resolve(accessedRoutes);
+    });
+    // return new Promise(resolve => {
+    //   let accessedRoutes = asyncRoutes;
+    //   if (roles.includes('admin')) {
+    //     accessedRoutes = asyncRoutes || [];
+    //   } else {
+    //     accessedRoutes = filterAsyncRoutes(asyncRoutes, roles);
+    //   }
+    //   commit('SET_ROUTES', accessedRoutes);
+    //   resolve(accessedRoutes);
+    // });
+  }
+};
+
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions
+};

+ 19 - 6
src/store/modules/user.js

@@ -1,12 +1,13 @@
 import { login, logout, getInfo } from '@/api/user';
 import { getToken, setToken, removeToken } from '@/utils/auth';
-import { resetRouter } from '@/router';
+import router, { resetRouter } from '@/router';
 
 const getDefaultState = () => {
   return {
     token: getToken(),
     name: '',
-    avatar: ''
+    avatar: '',
+    roles: []
   };
 };
 
@@ -22,6 +23,9 @@ const mutations = {
   SET_NAME: (state, name) => {
     state.name = name;
   },
+  SET_ROLES: (state, roles) => {
+    state.roles = roles;
+  },
   SET_AVATAR: (state, avatar) => {
     state.avatar = avatar;
   }
@@ -32,9 +36,11 @@ const actions = {
   login({ commit }, userInfo) {
     const { username, password } = userInfo;
     return new Promise((resolve, reject) => {
-      login({ username: username.trim(), password: password })
+      login({
+        username: username.trim(),
+        password: password
+      })
         .then(response => {
-          console.warn(response);
           const { data } = response;
           if (data.token) {
             commit('SET_TOKEN', data.token);
@@ -54,17 +60,22 @@ const actions = {
   getInfo({ commit, state }) {
     return new Promise((resolve, reject) => {
       getInfo(state.token)
-        .then(response => {
+        .then(async response => {
           const { data } = response;
 
           if (!data) {
             return reject('Verification failed, please Login again.');
           }
 
-          const { name, avatar } = data;
+          const { name, avatar, roles } = data;
 
+          // const roles = [];
+
+          commit('SET_ROLES', roles);
           commit('SET_NAME', name);
           commit('SET_AVATAR', avatar);
+
+          // dispatch('permission/generateRoutes');
           resolve(data);
         })
         .catch(error => {
@@ -81,6 +92,7 @@ const actions = {
           removeToken(); // must remove  token  first
           resetRouter();
           commit('RESET_STATE');
+          commit('SET_ROLES', []);
           resolve();
         })
         .catch(error => {
@@ -94,6 +106,7 @@ const actions = {
     return new Promise(resolve => {
       removeToken(); // must remove  token  first
       commit('RESET_STATE');
+      commit('SET_ROLES', []);
       resolve();
     });
   }

+ 8 - 0
src/styles/common.scss

@@ -87,3 +87,11 @@ $ais: (
     min-width: 0;
   }
 }
+
+.bg-w {
+  background-color: #fff;
+}
+
+.br-10 {
+  border-radius: 10px;
+}

+ 20 - 0
src/utils/params.js

@@ -0,0 +1,20 @@
+const format = (params) => {
+  const keys = Object.keys(params);
+  if (!keys.length) {
+    return {};
+  }
+  return keys.reduce((initObj, key) => {
+    let val = params[key];
+    if (typeof (val) === 'string') {
+      val = val.trim();
+    }
+    if (val !== null && val !== undefined && val !== '') {
+      initObj[key] = val;
+    }
+    return initObj;
+  }, {});
+};
+
+export {
+  format
+};

+ 9 - 4
src/utils/request.js

@@ -110,7 +110,6 @@ const formatResponse = fetchResult =>
  * 格式化status
  */
 const formatStatus = response => {
-  console.error(response);
   // 如果http状态码正常,则直接返回数据
   if (response && (response.code === 200 || response.code === 20000)) {
     response.success = true;
@@ -261,7 +260,9 @@ const get = (url, data = {}, config) => {
       ...config,
       params: data,
       paramsSerializer(params) {
-        return qs.stringify(params, { arrayFormat: 'brackets' });
+        return qs.stringify(params, {
+          arrayFormat: 'brackets'
+        });
       }
     })
   );
@@ -274,7 +275,9 @@ const del = (url, data = {}, config, type) => {
       ...config,
       params: data,
       paramsSerializer(params) {
-        return qs.stringify(params, { arrayFormat: 'brackets' });
+        return qs.stringify(params, {
+          arrayFormat: 'brackets'
+        });
       }
     })
   );
@@ -288,7 +291,9 @@ const delData = (url, data = {}, params, config) => {
       data: data,
       params: params,
       paramsSerializer(params) {
-        return qs.stringify(params, { arrayFormat: 'brackets' });
+        return qs.stringify(params, {
+          arrayFormat: 'brackets'
+        });
       }
     })
   );

+ 84 - 0
src/views/baseManagement/bannerManagement/index.vue

@@ -0,0 +1,84 @@
+<template>
+  <div class="">
+    <toolbar @onSearch="filterData" />
+
+    <div class="m-10 bg-w p-20 br-10">
+      <el-button type="primary" icon="el-icon-plus" @click="handleSubmit"
+        >新增</el-button
+      >
+      <base-table
+        :columns="columns"
+        :items="items"
+        :pagination="pagination"
+        :page-change="pageChange"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+import toolbar from './toolbar';
+import mxFilterList from '@/mixins/filterList';
+
+export default {
+  name: 'BannerManagement',
+
+  components: { toolbar },
+
+  mixins: [
+    mxFilterList({
+      // fetchList: iGetList // 在下方data再声明一个 fetchList: iGetList 同等效果
+    })
+  ],
+
+  data() {
+    return {
+      columns: [
+        {
+          key: 'id',
+          name: 'ID',
+          width: '60'
+        },
+        {
+          key: 'photo',
+          name: '图片',
+          width: '240'
+        },
+        {
+          key: 'region',
+          name: '位置',
+          minWidth: '120'
+        },
+        {
+          key: 'region',
+          name: '标题',
+          minWidth: '180'
+        },
+        {
+          key: 'region',
+          name: '链接',
+          minWidth: '240',
+          showOverflowTooltip: true
+        },
+        {
+          key: 'region',
+          name: '排序',
+          width: '60'
+        },
+        {
+          key: 'region',
+          name: '状态',
+          width: '80'
+        },
+        {
+          key: 'action',
+          name: '操作',
+          width: '120'
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 22 - 0
src/views/baseManagement/bannerManagement/toolbar.vue

@@ -0,0 +1,22 @@
+<template>
+  <toolbar-container
+    :fields="fields"
+    :showSearch="false"
+    :showReset="false"
+    v-on="$listeners"
+  />
+</template>
+
+<script>
+export default {
+  name: 'BannerManagementToolbar',
+
+  data() {
+    return {
+      fields: []
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 83 - 0
src/views/baseManagement/infoManagement/index.vue

@@ -0,0 +1,83 @@
+<template>
+  <div class="">
+    <toolbar @onSearch="filterData" />
+
+    <div class="m-10 bg-w p-20 br-10">
+      <el-button type="primary" icon="el-icon-plus" @click="handleSubmit"
+        >新增</el-button
+      >
+      <base-table
+        :columns="columns"
+        :items="items"
+        :pagination="pagination"
+        :page-change="pageChange"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+import toolbar from './toolbar';
+import mxFilterList from '@/mixins/filterList';
+
+export default {
+  name: 'InfoManagement',
+
+  components: { toolbar },
+
+  mixins: [
+    mxFilterList({
+      // fetchList: iGetList // 在下方data再声明一个 fetchList: iGetList 同等效果
+    })
+  ],
+
+  data() {
+    return {
+      columns: [
+        {
+          key: 'id',
+          name: '标题',
+          minWidth: '240'
+        },
+        {
+          key: 'photo',
+          name: '作者',
+          width: '160'
+        },
+        {
+          key: 'region',
+          name: '发布时间',
+          minWidth: '180'
+        },
+        {
+          key: 'region',
+          name: '阅读',
+          width: '120'
+        },
+        {
+          key: 'region',
+          name: '点赞',
+          width: '120'
+        },
+        {
+          key: 'region',
+          name: '收藏',
+          width: '120'
+        },
+        {
+          key: 'region',
+          name: '状态',
+          width: '80'
+        },
+        {
+          key: 'action',
+          name: '操作',
+          width: '120'
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 34 - 0
src/views/baseManagement/infoManagement/toolbar.vue

@@ -0,0 +1,34 @@
+<template>
+  <toolbar-container :fields="fields" v-on="$listeners" />
+</template>
+
+<script>
+export default {
+  name: 'InfoManagementToolbar',
+
+  data() {
+    return {
+      fields: [
+        {
+          type: 'text',
+          name: 'title',
+          label: '标题'
+        },
+        {
+          type: 'select',
+          name: 'status',
+          label: '状态'
+        },
+        {
+          type: 'dateArray',
+          name: 'date',
+          label: '发布日期',
+          apiName: ['start', 'end']
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 59 - 0
src/views/baseManagement/problemFeedbackManagement/index.vue

@@ -0,0 +1,59 @@
+<template>
+  <div class="">
+    <toolbar @onSearch="filterData" />
+
+    <base-table
+      class="m-10 bg-w p-20 br-10"
+      :columns="columns"
+      :items="items"
+      :pagination="pagination"
+      :page-change="pageChange"
+    />
+  </div>
+</template>
+
+<script>
+import toolbar from './toolbar';
+import mxFilterList from '@/mixins/filterList';
+
+export default {
+  name: 'ProblemFeedbackManagement',
+
+  components: { toolbar },
+
+  mixins: [
+    mxFilterList({
+      // fetchList: iGetList // 在下方data再声明一个 fetchList: iGetList 同等效果
+    })
+  ],
+
+  data() {
+    return {
+      columns: [
+        {
+          key: 'photo',
+          name: '用户名称',
+          width: '160'
+        },
+        {
+          key: 'region',
+          name: '手机号',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '反馈内容',
+          minWidth: '120'
+        },
+        {
+          key: 'region',
+          name: '反馈时间',
+          width: '180'
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 35 - 0
src/views/baseManagement/problemFeedbackManagement/toolbar.vue

@@ -0,0 +1,35 @@
+<template>
+  <toolbar-container :fields="fields" v-on="$listeners" />
+</template>
+
+<script>
+export default {
+  name: 'ProblemFeedbackManagementToolbar',
+
+  data() {
+    return {
+      fields: [
+        {
+          type: 'text',
+          name: 'title',
+          label: '用户名称'
+        },
+        {
+          type: 'text',
+          name: 'status',
+          label: '用户手机号',
+          labelWidth: '100px'
+        },
+        {
+          type: 'dateArray',
+          name: 'date',
+          label: '反馈日期',
+          apiName: ['start', 'end']
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 94 - 6
src/views/dashboard/index.vue

@@ -1,20 +1,108 @@
 <template>
   <div class="dashboard-container">
-    <div class="dashboard-text">name: {{ name }}</div>
+    <!-- <div class="dashboard-text">name: {{ name }}</div> -->
+    <div class="bg-w p-20 br-10">
+      <toolbar-container :fields="fields" @on-filter="eee" />
+      <base-table
+        :columns="columns"
+        :items="items"
+        :pagination="pagination"
+        :page-change="pageChange"
+      />
+    </div>
   </div>
 </template>
 
 <script>
-import { mapGetters } from 'vuex'
+import { mapGetters } from 'vuex';
+import mxFilterList from '@/mixins/filterList';
 
 export default {
   name: 'Dashboard',
+
+  mixins: [
+    mxFilterList({
+      fetchList: () => {}
+    })
+  ],
+
   computed: {
-    ...mapGetters([
-      'name'
-    ])
+    ...mapGetters(['name'])
+  },
+  data() {
+    return {
+      fields: [
+        {
+          type: 'dateArray',
+          name: 'paidTime',
+          label: '收款时间',
+          apiName: ['start', 'end'],
+          defaultValue: [,]
+        },
+
+        {
+          type: 'text',
+          name: 'paidTime2',
+          label: '收款时间',
+          defaultValue: 'fick'
+        },
+        {
+          type: 'text',
+          name: 'paidTime3',
+          label: '收款时间',
+          defaultValue: 'fick'
+        }
+      ],
+      columns: [
+        {
+          key: 'region',
+          name: '大区',
+          width: '120'
+        },
+        {
+          key: 'province',
+          name: '省',
+          width: '120'
+        },
+        {
+          key: 'city',
+          name: '市',
+          width: '150'
+        },
+        {
+          key: 'area',
+          name: '区',
+          minWidth: '100'
+        },
+        {
+          key: 'storeChain',
+          name: '连锁',
+          minWidth: '100'
+        },
+        {
+          key: 'storeName',
+          name: '门店',
+          minWidth: '100'
+        },
+        {
+          key: 'coupons',
+          name: '发行码数',
+          width: '100'
+        },
+        {
+          key: 'writeoff',
+          name: '核销数',
+          width: '100'
+        }
+      ]
+    };
+  },
+  methods: {
+    eee() {
+      console.warn('-------');
+    }
   }
-}
+};
 </script>
 
 <style lang="scss" scoped>

+ 59 - 0
src/views/financialManagement/fundDetail/index.vue

@@ -0,0 +1,59 @@
+<template>
+  <div class="">
+    <toolbar @onSearch="filterData" />
+
+    <base-table
+      class="m-10 bg-w p-20 br-10"
+      :columns="columns"
+      :items="items"
+      :pagination="pagination"
+      :page-change="pageChange"
+    />
+  </div>
+</template>
+
+<script>
+import toolbar from './toolbar';
+import mxFilterList from '@/mixins/filterList';
+
+export default {
+  name: 'FundDetail',
+
+  components: { toolbar },
+
+  mixins: [
+    mxFilterList({
+      // fetchList: iGetList // 在下方data再声明一个 fetchList: iGetList 同等效果
+    })
+  ],
+
+  data() {
+    return {
+      columns: [
+        {
+          key: 'photo',
+          name: '用户名称',
+          width: '160'
+        },
+        {
+          key: 'region',
+          name: '手机号',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '反馈内容',
+          minWidth: '120'
+        },
+        {
+          key: 'region',
+          name: '反馈时间',
+          width: '180'
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 35 - 0
src/views/financialManagement/fundDetail/toolbar.vue

@@ -0,0 +1,35 @@
+<template>
+  <toolbar-container :fields="fields" v-on="$listeners" />
+</template>
+
+<script>
+export default {
+  name: 'FundDetailToolbar',
+
+  data() {
+    return {
+      fields: [
+        {
+          type: 'text',
+          name: 'title',
+          label: '用户名称'
+        },
+        {
+          type: 'text',
+          name: 'status',
+          label: '用户手机号',
+          labelWidth: '100px'
+        },
+        {
+          type: 'dateArray',
+          name: 'date',
+          label: '反馈日期',
+          apiName: ['start', 'end']
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 59 - 0
src/views/financialManagement/orderManagement/index.vue

@@ -0,0 +1,59 @@
+<template>
+  <div class="">
+    <toolbar @onSearch="filterData" />
+
+    <base-table
+      class="m-10 bg-w p-20 br-10"
+      :columns="columns"
+      :items="items"
+      :pagination="pagination"
+      :page-change="pageChange"
+    />
+  </div>
+</template>
+
+<script>
+import toolbar from './toolbar';
+import mxFilterList from '@/mixins/filterList';
+
+export default {
+  name: 'OrderManagement',
+
+  components: { toolbar },
+
+  mixins: [
+    mxFilterList({
+      // fetchList: iGetList // 在下方data再声明一个 fetchList: iGetList 同等效果
+    })
+  ],
+
+  data() {
+    return {
+      columns: [
+        {
+          key: 'photo',
+          name: '用户名称',
+          width: '160'
+        },
+        {
+          key: 'region',
+          name: '手机号',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '反馈内容',
+          minWidth: '120'
+        },
+        {
+          key: 'region',
+          name: '反馈时间',
+          width: '180'
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 35 - 0
src/views/financialManagement/orderManagement/toolbar.vue

@@ -0,0 +1,35 @@
+<template>
+  <toolbar-container :fields="fields" v-on="$listeners" />
+</template>
+
+<script>
+export default {
+  name: 'OrderManagementToolbar',
+
+  data() {
+    return {
+      fields: [
+        {
+          type: 'text',
+          name: 'title',
+          label: '用户名称'
+        },
+        {
+          type: 'text',
+          name: 'status',
+          label: '用户手机号',
+          labelWidth: '100px'
+        },
+        {
+          type: 'dateArray',
+          name: 'date',
+          label: '反馈日期',
+          apiName: ['start', 'end']
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 78 - 0
src/views/helpInfo/information/index.vue

@@ -0,0 +1,78 @@
+<template>
+  <div class="">
+    <toolbar @onSearch="filterData" />
+
+    <div class="m-10 bg-w p-20 br-10">
+      <el-button type="primary" icon="el-icon-plus" @click="handleSubmit"
+        >新增</el-button
+      >
+      <base-table
+        :columns="columns"
+        :items="items"
+        :pagination="pagination"
+        :page-change="pageChange"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+import toolbar from './toolbar';
+import mxFilterList from '@/mixins/filterList';
+
+export default {
+  name: 'Information',
+
+  components: { toolbar },
+
+  mixins: [
+    mxFilterList({
+      // fetchList: iGetList // 在下方data再声明一个 fetchList: iGetList 同等效果
+    })
+  ],
+
+  data() {
+    return {
+      columns: [
+        {
+          key: 'photo',
+          name: 'ID',
+          width: '160'
+        },
+        {
+          key: 'region',
+          name: '分类名称',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '排序',
+          minWidth: '120'
+        },
+        {
+          key: 'region',
+          name: '创建时间',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '备注',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '状态',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '操作',
+          width: '180'
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 29 - 0
src/views/helpInfo/information/toolbar.vue

@@ -0,0 +1,29 @@
+<template>
+  <toolbar-container :fields="fields" v-on="$listeners" />
+</template>
+
+<script>
+export default {
+  name: 'InformationToolbar',
+
+  data() {
+    return {
+      fields: [
+        {
+          type: 'text',
+          name: 'title',
+          label: '分类名称'
+        },
+        {
+          type: 'select',
+          name: 'status',
+          label: '状态',
+          labelWidth: '100px'
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 78 - 0
src/views/helpInfo/issueType/index.vue

@@ -0,0 +1,78 @@
+<template>
+  <div class="">
+    <toolbar @onSearch="filterData" />
+
+    <div class="m-10 bg-w p-20 br-10">
+      <el-button type="primary" icon="el-icon-plus" @click="handleSubmit"
+        >新增</el-button
+      >
+      <base-table
+        :columns="columns"
+        :items="items"
+        :pagination="pagination"
+        :page-change="pageChange"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+import toolbar from './toolbar';
+import mxFilterList from '@/mixins/filterList';
+
+export default {
+  name: 'IssueType',
+
+  components: { toolbar },
+
+  mixins: [
+    mxFilterList({
+      // fetchList: iGetList // 在下方data再声明一个 fetchList: iGetList 同等效果
+    })
+  ],
+
+  data() {
+    return {
+      columns: [
+        {
+          key: 'photo',
+          name: 'ID',
+          width: '160'
+        },
+        {
+          key: 'region',
+          name: '分类名称',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '排序',
+          minWidth: '120'
+        },
+        {
+          key: 'region',
+          name: '创建时间',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '备注',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '状态',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '操作',
+          width: '180'
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 29 - 0
src/views/helpInfo/issueType/toolbar.vue

@@ -0,0 +1,29 @@
+<template>
+  <toolbar-container :fields="fields" v-on="$listeners" />
+</template>
+
+<script>
+export default {
+  name: 'IssueTypeToolbar',
+
+  data() {
+    return {
+      fields: [
+        {
+          type: 'text',
+          name: 'title',
+          label: '分类名称'
+        },
+        {
+          type: 'select',
+          name: 'status',
+          label: '状态',
+          labelWidth: '100px'
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 78 - 0
src/views/memberManagement/memberLever/index.vue

@@ -0,0 +1,78 @@
+<template>
+  <div class="">
+    <toolbar @onSearch="filterData" />
+
+    <div class="m-10 bg-w p-20 br-10">
+      <el-button type="primary" icon="el-icon-plus" @click="handleSubmit"
+        >新增</el-button
+      >
+      <base-table
+        :columns="columns"
+        :items="items"
+        :pagination="pagination"
+        :page-change="pageChange"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+import toolbar from './toolbar';
+import mxFilterList from '@/mixins/filterList';
+
+export default {
+  name: 'MemberLever',
+
+  components: { toolbar },
+
+  mixins: [
+    mxFilterList({
+      // fetchList: iGetList // 在下方data再声明一个 fetchList: iGetList 同等效果
+    })
+  ],
+
+  data() {
+    return {
+      columns: [
+        {
+          key: 'id',
+          name: 'ID',
+          width: '60'
+        },
+        {
+          key: 'photo',
+          name: '等级名称',
+          width: '240'
+        },
+        {
+          key: 'region',
+          name: '会员年费',
+          minWidth: '120'
+        },
+        {
+          key: 'region',
+          name: '会员月费',
+          minWidth: '180'
+        },
+        {
+          key: 'region',
+          name: '商品优惠折扣',
+          minWidth: '240'
+        },
+        {
+          key: 'region',
+          name: '状态',
+          width: '80'
+        },
+        {
+          key: 'action',
+          name: '操作',
+          width: '120'
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 22 - 0
src/views/memberManagement/memberLever/toolbar.vue

@@ -0,0 +1,22 @@
+<template>
+  <toolbar-container
+    :fields="fields"
+    :showSearch="false"
+    :showReset="false"
+    v-on="$listeners"
+  />
+</template>
+
+<script>
+export default {
+  name: 'MemberLeverToolbar',
+
+  data() {
+    return {
+      fields: []
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 99 - 0
src/views/memberManagement/memberList/index.vue

@@ -0,0 +1,99 @@
+<template>
+  <div class="">
+    <toolbar @onSearch="filterData" />
+
+    <base-table
+      class="m-10 bg-w p-20 br-10"
+      :columns="columns"
+      :items="items"
+      :pagination="pagination"
+      :page-change="pageChange"
+    />
+  </div>
+</template>
+
+<script>
+import toolbar from './toolbar';
+import mxFilterList from '@/mixins/filterList';
+
+export default {
+  name: 'MemberList',
+
+  components: { toolbar },
+
+  mixins: [
+    mxFilterList({
+      // fetchList: iGetList // 在下方data再声明一个 fetchList: iGetList 同等效果
+    })
+  ],
+
+  data() {
+    return {
+      columns: [
+        {
+          key: 'photo',
+          name: '会员ID',
+          width: '160'
+        },
+        {
+          key: 'region',
+          name: '头像',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '昵称',
+          minWidth: '120'
+        },
+        {
+          key: 'region',
+          name: '手机号码',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '性别',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '微信',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '邮箱',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '会员等级',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '角色',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '注册时间',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '状态',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '操作',
+          width: '180'
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 55 - 0
src/views/memberManagement/memberList/toolbar.vue

@@ -0,0 +1,55 @@
+<template>
+  <toolbar-container :fields="fields" v-on="$listeners" />
+</template>
+
+<script>
+export default {
+  name: 'MemberListToolbar',
+
+  data() {
+    return {
+      fields: [
+        {
+          type: 'text',
+          name: 'title',
+          label: '会员ID'
+        },
+        {
+          type: 'text',
+          name: 'status',
+          label: '手机号',
+          labelWidth: '100px'
+        },
+        {
+          type: 'select',
+          name: 'date',
+          label: '性别'
+        },
+        {
+          type: 'select',
+          name: 'date',
+          label: '状态'
+        },
+        {
+          type: 'select',
+          name: 'date',
+          label: '角色'
+        },
+        {
+          type: 'select',
+          name: 'date',
+          label: '会员等级'
+        },
+        {
+          type: 'dateArray',
+          name: 'date',
+          label: '反馈日期',
+          apiName: ['start', 'end']
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 0 - 7
src/views/nested/menu1/index.vue

@@ -1,7 +0,0 @@
-<template>
-  <div style="padding:30px;">
-    <el-alert :closable="false" title="menu 1">
-      <router-view />
-    </el-alert>
-  </div>
-</template>

+ 0 - 7
src/views/nested/menu1/menu1-1/index.vue

@@ -1,7 +0,0 @@
-<template>
-  <div style="padding:30px;">
-    <el-alert :closable="false" title="menu 1-1" type="success">
-      <router-view />
-    </el-alert>
-  </div>
-</template>

+ 0 - 7
src/views/nested/menu1/menu1-2/index.vue

@@ -1,7 +0,0 @@
-<template>
-  <div style="padding:30px;">
-    <el-alert :closable="false" title="menu 1-2" type="success">
-      <router-view />
-    </el-alert>
-  </div>
-</template>

+ 0 - 5
src/views/nested/menu1/menu1-2/menu1-2-1/index.vue

@@ -1,5 +0,0 @@
-<template functional>
-  <div style="padding:30px;">
-    <el-alert :closable="false" title="menu 1-2-1" type="warning" />
-  </div>
-</template>

+ 0 - 5
src/views/nested/menu1/menu1-2/menu1-2-2/index.vue

@@ -1,5 +0,0 @@
-<template functional>
-  <div style="padding:30px;">
-    <el-alert :closable="false" title="menu 1-2-2" type="warning" />
-  </div>
-</template>

+ 0 - 5
src/views/nested/menu1/menu1-3/index.vue

@@ -1,5 +0,0 @@
-<template functional>
-  <div style="padding:30px;">
-    <el-alert :closable="false" title="menu 1-3" type="success" />
-  </div>
-</template>

+ 0 - 5
src/views/nested/menu2/index.vue

@@ -1,5 +0,0 @@
-<template>
-  <div style="padding:30px;">
-    <el-alert :closable="false" title="menu 2" />
-  </div>
-</template>

+ 59 - 0
src/views/photoManagement/eventsList/index.vue

@@ -0,0 +1,59 @@
+<template>
+  <div class="">
+    <toolbar @onSearch="filterData" />
+
+    <base-table
+      class="m-10 bg-w p-20 br-10"
+      :columns="columns"
+      :items="items"
+      :pagination="pagination"
+      :page-change="pageChange"
+    />
+  </div>
+</template>
+
+<script>
+import toolbar from './toolbar';
+import mxFilterList from '@/mixins/filterList';
+
+export default {
+  name: 'EventsList',
+
+  components: { toolbar },
+
+  mixins: [
+    mxFilterList({
+      // fetchList: iGetList // 在下方data再声明一个 fetchList: iGetList 同等效果
+    })
+  ],
+
+  data() {
+    return {
+      columns: [
+        {
+          key: 'photo',
+          name: '用户名称',
+          width: '160'
+        },
+        {
+          key: 'region',
+          name: '手机号',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '反馈内容',
+          minWidth: '120'
+        },
+        {
+          key: 'region',
+          name: '反馈时间',
+          width: '180'
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 35 - 0
src/views/photoManagement/eventsList/toolbar.vue

@@ -0,0 +1,35 @@
+<template>
+  <toolbar-container :fields="fields" v-on="$listeners" />
+</template>
+
+<script>
+export default {
+  name: 'EventsListToolbar',
+
+  data() {
+    return {
+      fields: [
+        {
+          type: 'text',
+          name: 'title',
+          label: '用户名称'
+        },
+        {
+          type: 'text',
+          name: 'status',
+          label: '用户手机号',
+          labelWidth: '100px'
+        },
+        {
+          type: 'dateArray',
+          name: 'date',
+          label: '反馈日期',
+          apiName: ['start', 'end']
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 59 - 0
src/views/photoManagement/imageGoodsManagement/index.vue

@@ -0,0 +1,59 @@
+<template>
+  <div class="">
+    <toolbar @onSearch="filterData" />
+
+    <base-table
+      class="m-10 bg-w p-20 br-10"
+      :columns="columns"
+      :items="items"
+      :pagination="pagination"
+      :page-change="pageChange"
+    />
+  </div>
+</template>
+
+<script>
+import toolbar from './toolbar';
+import mxFilterList from '@/mixins/filterList';
+
+export default {
+  name: 'ImageGoodsManagement',
+
+  components: { toolbar },
+
+  mixins: [
+    mxFilterList({
+      // fetchList: iGetList // 在下方data再声明一个 fetchList: iGetList 同等效果
+    })
+  ],
+
+  data() {
+    return {
+      columns: [
+        {
+          key: 'photo',
+          name: '用户名称',
+          width: '160'
+        },
+        {
+          key: 'region',
+          name: '手机号',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '反馈内容',
+          minWidth: '120'
+        },
+        {
+          key: 'region',
+          name: '反馈时间',
+          width: '180'
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 35 - 0
src/views/photoManagement/imageGoodsManagement/toolbar.vue

@@ -0,0 +1,35 @@
+<template>
+  <toolbar-container :fields="fields" v-on="$listeners" />
+</template>
+
+<script>
+export default {
+  name: 'ImageGoodsManagementToolbar',
+
+  data() {
+    return {
+      fields: [
+        {
+          type: 'text',
+          name: 'title',
+          label: '用户名称'
+        },
+        {
+          type: 'text',
+          name: 'status',
+          label: '用户手机号',
+          labelWidth: '100px'
+        },
+        {
+          type: 'dateArray',
+          name: 'date',
+          label: '反馈日期',
+          apiName: ['start', 'end']
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 59 - 0
src/views/photoManagement/uploadManagement/index.vue

@@ -0,0 +1,59 @@
+<template>
+  <div class="">
+    <toolbar @onSearch="filterData" />
+
+    <base-table
+      class="m-10 bg-w p-20 br-10"
+      :columns="columns"
+      :items="items"
+      :pagination="pagination"
+      :page-change="pageChange"
+    />
+  </div>
+</template>
+
+<script>
+import toolbar from './toolbar';
+import mxFilterList from '@/mixins/filterList';
+
+export default {
+  name: 'UploadManagement',
+
+  components: { toolbar },
+
+  mixins: [
+    mxFilterList({
+      // fetchList: iGetList // 在下方data再声明一个 fetchList: iGetList 同等效果
+    })
+  ],
+
+  data() {
+    return {
+      columns: [
+        {
+          key: 'photo',
+          name: '用户名称',
+          width: '160'
+        },
+        {
+          key: 'region',
+          name: '手机号',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '反馈内容',
+          minWidth: '120'
+        },
+        {
+          key: 'region',
+          name: '反馈时间',
+          width: '180'
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 35 - 0
src/views/photoManagement/uploadManagement/toolbar.vue

@@ -0,0 +1,35 @@
+<template>
+  <toolbar-container :fields="fields" v-on="$listeners" />
+</template>
+
+<script>
+export default {
+  name: 'UploadManagementToolbar',
+
+  data() {
+    return {
+      fields: [
+        {
+          type: 'text',
+          name: 'title',
+          label: '用户名称'
+        },
+        {
+          type: 'text',
+          name: 'status',
+          label: '用户手机号',
+          labelWidth: '100px'
+        },
+        {
+          type: 'dateArray',
+          name: 'date',
+          label: '反馈日期',
+          apiName: ['start', 'end']
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 74 - 0
src/views/photographerManagement/photoVerify/index.vue

@@ -0,0 +1,74 @@
+<template>
+  <div class="">
+    <toolbar @onSearch="filterData" />
+
+    <base-table
+      class="m-10 bg-w p-20 br-10"
+      :columns="columns"
+      :items="items"
+      :pagination="pagination"
+      :page-change="pageChange"
+    />
+  </div>
+</template>
+
+<script>
+import toolbar from './toolbar';
+import mxFilterList from '@/mixins/filterList';
+
+export default {
+  name: 'PhotoVerify',
+
+  components: { toolbar },
+
+  mixins: [
+    mxFilterList({
+      // fetchList: iGetList // 在下方data再声明一个 fetchList: iGetList 同等效果
+    })
+  ],
+
+  data() {
+    return {
+      columns: [
+        {
+          key: 'photo',
+          name: '照片ID',
+          width: '160'
+        },
+        {
+          key: 'region',
+          name: '图片',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '上传者',
+          width: '120'
+        },
+        {
+          key: 'region',
+          name: '上传位置',
+          minWidth: '180'
+        },
+        {
+          key: 'region',
+          name: '上传时间',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '状态',
+          width: '180'
+        },
+        {
+          key: 'action',
+          name: '操作',
+          minWidth: '180'
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 34 - 0
src/views/photographerManagement/photoVerify/toolbar.vue

@@ -0,0 +1,34 @@
+<template>
+  <toolbar-container :fields="fields" v-on="$listeners" />
+</template>
+
+<script>
+export default {
+  name: 'PhotoVerifyToolbar',
+
+  data() {
+    return {
+      fields: [
+        {
+          type: 'select',
+          name: 'title',
+          label: '上传位置'
+        },
+        {
+          type: 'select',
+          name: 'date',
+          label: '状态'
+        },
+        {
+          type: 'dateArray',
+          name: 'date',
+          label: '上传日期',
+          apiName: ['start', 'end']
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 89 - 0
src/views/photographerManagement/photographerVerify/index.vue

@@ -0,0 +1,89 @@
+<template>
+  <div class="">
+    <toolbar @onSearch="filterData" />
+
+    <base-table
+      class="m-10 bg-w p-20 br-10"
+      :columns="columns"
+      :items="items"
+      :pagination="pagination"
+      :page-change="pageChange"
+    />
+  </div>
+</template>
+
+<script>
+import toolbar from './toolbar';
+import mxFilterList from '@/mixins/filterList';
+
+export default {
+  name: 'PhotographerVerify',
+
+  components: { toolbar },
+
+  mixins: [
+    mxFilterList({
+      // fetchList: iGetList // 在下方data再声明一个 fetchList: iGetList 同等效果
+    })
+  ],
+
+  data() {
+    return {
+      columns: [
+        {
+          key: 'photo',
+          name: '会员ID',
+          width: '160'
+        },
+        {
+          key: 'region',
+          name: '申请者',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '姓名',
+          width: '120'
+        },
+        {
+          key: 'region',
+          name: '身份证号码',
+          minWidth: '180'
+        },
+        {
+          key: 'region',
+          name: '手机号',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '微信号',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '电子邮箱',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '常合作场景',
+          minWidth: '180'
+        },
+        {
+          key: 'region',
+          name: '状态',
+          minWidth: '180'
+        },
+        {
+          key: 'action',
+          name: '操作',
+          minWidth: '180'
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 34 - 0
src/views/photographerManagement/photographerVerify/toolbar.vue

@@ -0,0 +1,34 @@
+<template>
+  <toolbar-container :fields="fields" v-on="$listeners" />
+</template>
+
+<script>
+export default {
+  name: 'PhotographerVerifyToolbar',
+
+  data() {
+    return {
+      fields: [
+        {
+          type: 'text',
+          name: 'title',
+          label: '申请者'
+        },
+        {
+          type: 'text',
+          name: 'status',
+          label: '用户手机号',
+          labelWidth: '100px'
+        },
+        {
+          type: 'select',
+          name: 'date',
+          label: '状态'
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 89 - 0
src/views/pointsManagement/pointsDetail/index.vue

@@ -0,0 +1,89 @@
+<template>
+  <div class="">
+    <toolbar @onSearch="filterData" />
+
+    <base-table
+      class="m-10 bg-w p-20 br-10"
+      :columns="columns"
+      :items="items"
+      :pagination="pagination"
+      :page-change="pageChange"
+    />
+  </div>
+</template>
+
+<script>
+import toolbar from './toolbar';
+import mxFilterList from '@/mixins/filterList';
+
+export default {
+  name: 'PointsDetail',
+
+  components: { toolbar },
+
+  mixins: [
+    mxFilterList({
+      // fetchList: iGetList // 在下方data再声明一个 fetchList: iGetList 同等效果
+    })
+  ],
+
+  data() {
+    return {
+      columns: [
+        {
+          key: 'photo',
+          name: '会员ID',
+          width: '160'
+        },
+        {
+          key: 'region',
+          name: '申请者',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '姓名',
+          width: '120'
+        },
+        {
+          key: 'region',
+          name: '身份证号码',
+          minWidth: '180'
+        },
+        {
+          key: 'region',
+          name: '手机号',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '微信号',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '电子邮箱',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '常合作场景',
+          minWidth: '180'
+        },
+        {
+          key: 'region',
+          name: '状态',
+          minWidth: '180'
+        },
+        {
+          key: 'action',
+          name: '操作',
+          minWidth: '180'
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 34 - 0
src/views/pointsManagement/pointsDetail/toolbar.vue

@@ -0,0 +1,34 @@
+<template>
+  <toolbar-container :fields="fields" v-on="$listeners" />
+</template>
+
+<script>
+export default {
+  name: 'PointsDetailToolbar',
+
+  data() {
+    return {
+      fields: [
+        {
+          type: 'text',
+          name: 'title',
+          label: '申请者'
+        },
+        {
+          type: 'text',
+          name: 'status',
+          label: '用户手机号',
+          labelWidth: '100px'
+        },
+        {
+          type: 'select',
+          name: 'date',
+          label: '状态'
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 88 - 0
src/views/pointsManagement/pointsSetting/index.vue

@@ -0,0 +1,88 @@
+<template>
+  <div class="m-10 bg-w p-20 br-10">
+    <h1>积分设置</h1>
+    <el-form
+      ref="form"
+      :model="form"
+      label-width="280px"
+      label-position="top"
+      class="mrow-60"
+    >
+      <el-form-item label="积分抵现(设置多少积分抵一元人民币)">
+        <el-input v-model="form.name"></el-input>
+      </el-form-item>
+      <el-form-item label="活动区域">
+        <el-select v-model="form.region" placeholder="请选择活动区域">
+          <el-option label="区域一" value="shanghai"></el-option>
+          <el-option label="区域二" value="beijing"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="活动时间">
+        <el-col :span="11">
+          <el-date-picker
+            type="date"
+            placeholder="选择日期"
+            v-model="form.date1"
+            style="width: 100%;"
+          ></el-date-picker>
+        </el-col>
+        <el-col class="line" :span="2">-</el-col>
+        <el-col :span="11">
+          <el-time-picker
+            placeholder="选择时间"
+            v-model="form.date2"
+            style="width: 100%;"
+          ></el-time-picker>
+        </el-col>
+      </el-form-item>
+      <el-form-item label="即时配送">
+        <el-switch v-model="form.delivery"></el-switch>
+      </el-form-item>
+      <el-form-item label="活动性质">
+        <el-checkbox-group v-model="form.type">
+          <el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
+          <el-checkbox label="地推活动" name="type"></el-checkbox>
+          <el-checkbox label="线下主题活动" name="type"></el-checkbox>
+          <el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
+        </el-checkbox-group>
+      </el-form-item>
+      <el-form-item label="特殊资源">
+        <el-radio-group v-model="form.resource">
+          <el-radio label="线上品牌商赞助"></el-radio>
+          <el-radio label="线下场地免费"></el-radio>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="活动形式">
+        <el-input type="textarea" v-model="form.desc"></el-input>
+      </el-form-item>
+      <el-form-item class="f-fe-c">
+        <el-button type="primary" @click="onSubmit">立即创建</el-button>
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'PointsSetting',
+
+  components: { toolbar },
+
+  data() {
+    return {
+      form: {
+        name: '',
+        region: '',
+        date1: '',
+        date2: '',
+        delivery: false,
+        type: [],
+        resource: '',
+        desc: ''
+      }
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 88 - 0
src/views/sceneManagement/sceneList/index.vue

@@ -0,0 +1,88 @@
+<template>
+  <div class="">
+    <toolbar @onSearch="filterData" />
+
+    <div class="m-10 bg-w p-20 br-10">
+      <el-button type="primary" icon="el-icon-plus" @click="handleSubmit"
+        >新增</el-button
+      >
+      <base-table
+        :columns="columns"
+        :items="items"
+        :pagination="pagination"
+        :page-change="pageChange"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+import toolbar from './toolbar';
+import mxFilterList from '@/mixins/filterList';
+
+export default {
+  name: 'SceneList',
+
+  components: { toolbar },
+
+  mixins: [
+    mxFilterList({
+      // fetchList: iGetList // 在下方data再声明一个 fetchList: iGetList 同等效果
+    })
+  ],
+
+  data() {
+    return {
+      columns: [
+        {
+          key: 'photo',
+          name: 'ID',
+          width: '160'
+        },
+        {
+          key: 'region',
+          name: '机构名称',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: 'Logo',
+          width: '120'
+        },
+        {
+          key: 'region',
+          name: '所在地区',
+          minWidth: '180'
+        },
+        {
+          key: 'region',
+          name: '机构类型',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '申请人',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '手机号',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '状态',
+          minWidth: '180'
+        },
+        {
+          key: 'action',
+          name: '操作',
+          minWidth: '180'
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 44 - 0
src/views/sceneManagement/sceneList/toolbar.vue

@@ -0,0 +1,44 @@
+<template>
+  <toolbar-container :fields="fields" v-on="$listeners" />
+</template>
+
+<script>
+export default {
+  name: 'sceneListToolbar',
+
+  data() {
+    return {
+      fields: [
+        {
+          type: 'text',
+          name: 'title',
+          label: '机构名称'
+        },
+        {
+          type: 'text',
+          name: 'status',
+          label: '所在地区',
+          labelWidth: '100px'
+        },
+        {
+          type: 'select',
+          name: 'date',
+          label: '状态'
+        },
+        {
+          type: 'select',
+          name: 'date',
+          label: '机构类型'
+        },
+        {
+          type: 'text',
+          name: 'title',
+          label: '手机号'
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 79 - 0
src/views/sceneManagement/sceneVerify/index.vue

@@ -0,0 +1,79 @@
+<template>
+  <div class="">
+    <toolbar @onSearch="filterData" />
+
+    <base-table
+      class="m-10 bg-w p-20 br-10"
+      :columns="columns"
+      :items="items"
+      :pagination="pagination"
+      :page-change="pageChange"
+    />
+  </div>
+</template>
+
+<script>
+import toolbar from './toolbar';
+import mxFilterList from '@/mixins/filterList';
+
+export default {
+  name: 'SceneVerify',
+
+  components: { toolbar },
+
+  mixins: [
+    mxFilterList({
+      // fetchList: iGetList // 在下方data再声明一个 fetchList: iGetList 同等效果
+    })
+  ],
+
+  data() {
+    return {
+      columns: [
+        {
+          key: 'id',
+          name: '标题',
+          minWidth: '240'
+        },
+        {
+          key: 'photo',
+          name: '作者',
+          width: '160'
+        },
+        {
+          key: 'region',
+          name: '发布时间',
+          minWidth: '180'
+        },
+        {
+          key: 'region',
+          name: '阅读',
+          width: '120'
+        },
+        {
+          key: 'region',
+          name: '点赞',
+          width: '120'
+        },
+        {
+          key: 'region',
+          name: '收藏',
+          width: '120'
+        },
+        {
+          key: 'region',
+          name: '状态',
+          width: '80'
+        },
+        {
+          key: 'action',
+          name: '操作',
+          width: '120'
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 43 - 0
src/views/sceneManagement/sceneVerify/toolbar.vue

@@ -0,0 +1,43 @@
+<template>
+  <toolbar-container :fields="fields" v-on="$listeners" />
+</template>
+
+<script>
+export default {
+  name: 'SceneVerifyToolbar',
+
+  data() {
+    return {
+      fields: [
+        {
+          type: 'text',
+          name: 'title',
+          label: '机构名称'
+        },
+        {
+          type: 'select',
+          name: 'status',
+          label: '所在地区'
+        },
+        {
+          type: 'select',
+          name: 'status',
+          label: '状态'
+        },
+        {
+          type: 'select',
+          name: 'status',
+          label: '机构类型'
+        },
+        {
+          type: 'text',
+          name: 'status',
+          label: '手机号'
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 59 - 0
src/views/statistics/downloadImage/index.vue

@@ -0,0 +1,59 @@
+<template>
+  <div class="">
+    <toolbar @onSearch="filterData" />
+
+    <base-table
+      class="m-10 bg-w p-20 br-10"
+      :columns="columns"
+      :items="items"
+      :pagination="pagination"
+      :page-change="pageChange"
+    />
+  </div>
+</template>
+
+<script>
+import toolbar from './toolbar';
+import mxFilterList from '@/mixins/filterList';
+
+export default {
+  name: 'DownloadImage',
+
+  components: { toolbar },
+
+  mixins: [
+    mxFilterList({
+      // fetchList: iGetList // 在下方data再声明一个 fetchList: iGetList 同等效果
+    })
+  ],
+
+  data() {
+    return {
+      columns: [
+        {
+          key: 'photo',
+          name: '用户名称',
+          width: '160'
+        },
+        {
+          key: 'region',
+          name: '手机号',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '反馈内容',
+          minWidth: '120'
+        },
+        {
+          key: 'region',
+          name: '反馈时间',
+          width: '180'
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 35 - 0
src/views/statistics/downloadImage/toolbar.vue

@@ -0,0 +1,35 @@
+<template>
+  <toolbar-container :fields="fields" v-on="$listeners" />
+</template>
+
+<script>
+export default {
+  name: 'DownloadImageToolbar',
+
+  data() {
+    return {
+      fields: [
+        {
+          type: 'text',
+          name: 'title',
+          label: '用户名称'
+        },
+        {
+          type: 'text',
+          name: 'status',
+          label: '用户手机号',
+          labelWidth: '100px'
+        },
+        {
+          type: 'dateArray',
+          name: 'date',
+          label: '反馈日期',
+          apiName: ['start', 'end']
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 59 - 0
src/views/statistics/uploadImage/index.vue

@@ -0,0 +1,59 @@
+<template>
+  <div class="">
+    <toolbar @onSearch="filterData" />
+
+    <base-table
+      class="m-10 bg-w p-20 br-10"
+      :columns="columns"
+      :items="items"
+      :pagination="pagination"
+      :page-change="pageChange"
+    />
+  </div>
+</template>
+
+<script>
+import toolbar from './toolbar';
+import mxFilterList from '@/mixins/filterList';
+
+export default {
+  name: 'UploadImage',
+
+  components: { toolbar },
+
+  mixins: [
+    mxFilterList({
+      // fetchList: iGetList // 在下方data再声明一个 fetchList: iGetList 同等效果
+    })
+  ],
+
+  data() {
+    return {
+      columns: [
+        {
+          key: 'photo',
+          name: '用户名称',
+          width: '160'
+        },
+        {
+          key: 'region',
+          name: '手机号',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '反馈内容',
+          minWidth: '120'
+        },
+        {
+          key: 'region',
+          name: '反馈时间',
+          width: '180'
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 35 - 0
src/views/statistics/uploadImage/toolbar.vue

@@ -0,0 +1,35 @@
+<template>
+  <toolbar-container :fields="fields" v-on="$listeners" />
+</template>
+
+<script>
+export default {
+  name: 'UploadImageToolbar',
+
+  data() {
+    return {
+      fields: [
+        {
+          type: 'text',
+          name: 'title',
+          label: '用户名称'
+        },
+        {
+          type: 'text',
+          name: 'status',
+          label: '用户手机号',
+          labelWidth: '100px'
+        },
+        {
+          type: 'dateArray',
+          name: 'date',
+          label: '反馈日期',
+          apiName: ['start', 'end']
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 59 - 0
src/views/statistics/withdrawalRecord/index.vue

@@ -0,0 +1,59 @@
+<template>
+  <div class="">
+    <toolbar @onSearch="filterData" />
+
+    <base-table
+      class="m-10 bg-w p-20 br-10"
+      :columns="columns"
+      :items="items"
+      :pagination="pagination"
+      :page-change="pageChange"
+    />
+  </div>
+</template>
+
+<script>
+import toolbar from './toolbar';
+import mxFilterList from '@/mixins/filterList';
+
+export default {
+  name: 'WithdrawalRecord',
+
+  components: { toolbar },
+
+  mixins: [
+    mxFilterList({
+      // fetchList: iGetList // 在下方data再声明一个 fetchList: iGetList 同等效果
+    })
+  ],
+
+  data() {
+    return {
+      columns: [
+        {
+          key: 'photo',
+          name: '用户名称',
+          width: '160'
+        },
+        {
+          key: 'region',
+          name: '手机号',
+          width: '180'
+        },
+        {
+          key: 'region',
+          name: '反馈内容',
+          minWidth: '120'
+        },
+        {
+          key: 'region',
+          name: '反馈时间',
+          width: '180'
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 35 - 0
src/views/statistics/withdrawalRecord/toolbar.vue

@@ -0,0 +1,35 @@
+<template>
+  <toolbar-container :fields="fields" v-on="$listeners" />
+</template>
+
+<script>
+export default {
+  name: 'WithdrawalRecordToolbar',
+
+  data() {
+    return {
+      fields: [
+        {
+          type: 'text',
+          name: 'title',
+          label: '用户名称'
+        },
+        {
+          type: 'text',
+          name: 'status',
+          label: '用户手机号',
+          labelWidth: '100px'
+        },
+        {
+          type: 'dateArray',
+          name: 'date',
+          label: '反馈日期',
+          apiName: ['start', 'end']
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 83 - 0
src/views/systemManagement/accountManagement/index.vue

@@ -0,0 +1,83 @@
+<template>
+  <div class="">
+    <toolbar @onSearch="filterData" />
+
+    <div class="m-10 bg-w p-20 br-10">
+      <el-button type="primary" icon="el-icon-plus" @click="handleSubmit"
+        >新增</el-button
+      >
+      <base-table
+        :columns="columns"
+        :items="items"
+        :pagination="pagination"
+        :page-change="pageChange"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+import toolbar from './toolbar';
+import mxFilterList from '@/mixins/filterList';
+
+export default {
+  name: 'AccountManagement',
+
+  components: { toolbar },
+
+  mixins: [
+    mxFilterList({
+      // fetchList: iGetList // 在下方data再声明一个 fetchList: iGetList 同等效果
+    })
+  ],
+
+  data() {
+    return {
+      columns: [
+        {
+          key: 'id',
+          name: '标题',
+          minWidth: '240'
+        },
+        {
+          key: 'photo',
+          name: '作者',
+          width: '160'
+        },
+        {
+          key: 'region',
+          name: '发布时间',
+          minWidth: '180'
+        },
+        {
+          key: 'region',
+          name: '阅读',
+          width: '120'
+        },
+        {
+          key: 'region',
+          name: '点赞',
+          width: '120'
+        },
+        {
+          key: 'region',
+          name: '收藏',
+          width: '120'
+        },
+        {
+          key: 'region',
+          name: '状态',
+          width: '80'
+        },
+        {
+          key: 'action',
+          name: '操作',
+          width: '120'
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 34 - 0
src/views/systemManagement/accountManagement/toolbar.vue

@@ -0,0 +1,34 @@
+<template>
+  <toolbar-container :fields="fields" v-on="$listeners" />
+</template>
+
+<script>
+export default {
+  name: 'AccountManagementToolbar',
+
+  data() {
+    return {
+      fields: [
+        {
+          type: 'text',
+          name: 'title',
+          label: '标题'
+        },
+        {
+          type: 'select',
+          name: 'status',
+          label: '状态'
+        },
+        {
+          type: 'dateArray',
+          name: 'date',
+          label: '发布日期',
+          apiName: ['start', 'end']
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 84 - 0
src/views/systemManagement/roleManagement/index.vue

@@ -0,0 +1,84 @@
+<template>
+  <div class="">
+    <toolbar @onSearch="filterData" />
+
+    <div class="m-10 bg-w p-20 br-10">
+      <el-button type="primary" icon="el-icon-plus" @click="handleSubmit"
+        >新增</el-button
+      >
+      <base-table
+        :columns="columns"
+        :items="items"
+        :pagination="pagination"
+        :page-change="pageChange"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+import toolbar from './toolbar';
+import mxFilterList from '@/mixins/filterList';
+
+export default {
+  name: 'RoleManagement',
+
+  components: { toolbar },
+
+  mixins: [
+    mxFilterList({
+      // fetchList: iGetList // 在下方data再声明一个 fetchList: iGetList 同等效果
+    })
+  ],
+
+  data() {
+    return {
+      columns: [
+        {
+          key: 'id',
+          name: 'ID',
+          width: '60'
+        },
+        {
+          key: 'photo',
+          name: '图片',
+          width: '240'
+        },
+        {
+          key: 'region',
+          name: '位置',
+          minWidth: '120'
+        },
+        {
+          key: 'region',
+          name: '标题',
+          minWidth: '180'
+        },
+        {
+          key: 'region',
+          name: '链接',
+          minWidth: '240',
+          showOverflowTooltip: true
+        },
+        {
+          key: 'region',
+          name: '排序',
+          width: '60'
+        },
+        {
+          key: 'region',
+          name: '状态',
+          width: '80'
+        },
+        {
+          key: 'action',
+          name: '操作',
+          width: '120'
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 22 - 0
src/views/systemManagement/roleManagement/toolbar.vue

@@ -0,0 +1,22 @@
+<template>
+  <toolbar-container
+    :fields="fields"
+    :showSearch="false"
+    :showReset="false"
+    v-on="$listeners"
+  />
+</template>
+
+<script>
+export default {
+  name: 'RoleManagementToolbar',
+
+  data() {
+    return {
+      fields: []
+    };
+  }
+};
+</script>
+
+<style type="scss" scoped></style>

+ 0 - 79
src/views/table/index.vue

@@ -1,79 +0,0 @@
-<template>
-  <div class="app-container">
-    <el-table
-      v-loading="listLoading"
-      :data="list"
-      element-loading-text="Loading"
-      border
-      fit
-      highlight-current-row
-    >
-      <el-table-column align="center" label="ID" width="95">
-        <template slot-scope="scope">
-          {{ scope.$index }}
-        </template>
-      </el-table-column>
-      <el-table-column label="Title">
-        <template slot-scope="scope">
-          {{ scope.row.title }}
-        </template>
-      </el-table-column>
-      <el-table-column label="Author" width="110" align="center">
-        <template slot-scope="scope">
-          <span>{{ scope.row.author }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column label="Pageviews" width="110" align="center">
-        <template slot-scope="scope">
-          {{ scope.row.pageviews }}
-        </template>
-      </el-table-column>
-      <el-table-column class-name="status-col" label="Status" width="110" align="center">
-        <template slot-scope="scope">
-          <el-tag :type="scope.row.status | statusFilter">{{ scope.row.status }}</el-tag>
-        </template>
-      </el-table-column>
-      <el-table-column align="center" prop="created_at" label="Display_time" width="200">
-        <template slot-scope="scope">
-          <i class="el-icon-time" />
-          <span>{{ scope.row.display_time }}</span>
-        </template>
-      </el-table-column>
-    </el-table>
-  </div>
-</template>
-
-<script>
-import { getList } from '@/api/table'
-
-export default {
-  filters: {
-    statusFilter(status) {
-      const statusMap = {
-        published: 'success',
-        draft: 'gray',
-        deleted: 'danger'
-      }
-      return statusMap[status]
-    }
-  },
-  data() {
-    return {
-      list: null,
-      listLoading: true
-    }
-  },
-  created() {
-    this.fetchData()
-  },
-  methods: {
-    fetchData() {
-      this.listLoading = true
-      getList().then(response => {
-        this.list = response.data.items
-        this.listLoading = false
-      })
-    }
-  }
-}
-</script>

+ 0 - 78
src/views/tree/index.vue

@@ -1,78 +0,0 @@
-<template>
-  <div class="app-container">
-    <el-input v-model="filterText" placeholder="Filter keyword" style="margin-bottom:30px;" />
-
-    <el-tree
-      ref="tree2"
-      :data="data2"
-      :props="defaultProps"
-      :filter-node-method="filterNode"
-      class="filter-tree"
-      default-expand-all
-    />
-
-  </div>
-</template>
-
-<script>
-export default {
-
-  data() {
-    return {
-      filterText: '',
-      data2: [{
-        id: 1,
-        label: 'Level one 1',
-        children: [{
-          id: 4,
-          label: 'Level two 1-1',
-          children: [{
-            id: 9,
-            label: 'Level three 1-1-1'
-          }, {
-            id: 10,
-            label: 'Level three 1-1-2'
-          }]
-        }]
-      }, {
-        id: 2,
-        label: 'Level one 2',
-        children: [{
-          id: 5,
-          label: 'Level two 2-1'
-        }, {
-          id: 6,
-          label: 'Level two 2-2'
-        }]
-      }, {
-        id: 3,
-        label: 'Level one 3',
-        children: [{
-          id: 7,
-          label: 'Level two 3-1'
-        }, {
-          id: 8,
-          label: 'Level two 3-2'
-        }]
-      }],
-      defaultProps: {
-        children: 'children',
-        label: 'label'
-      }
-    }
-  },
-  watch: {
-    filterText(val) {
-      this.$refs.tree2.filter(val)
-    }
-  },
-
-  methods: {
-    filterNode(value, data) {
-      if (!value) return true
-      return data.label.indexOf(value) !== -1
-    }
-  }
-}
-</script>
-

+ 62 - 48
vue.config.js

@@ -1,19 +1,19 @@
-'use strict'
-const path = require('path')
-const defaultSettings = require('./src/settings.js')
+'use strict';
+const path = require('path');
+const defaultSettings = require('./src/settings.js');
 
 function resolve(dir) {
-  return path.join(__dirname, dir)
+  return path.join(__dirname, dir);
 }
 
-const name = defaultSettings.title || 'vue Admin Template' // page title
+const name = defaultSettings.title || 'vue Admin Template'; // page title
 
 // If your port is set to 80,
 // use administrator privileges to execute the command line.
 // For example, Mac: sudo npm run
 // You can change the port by the following methods:
 // port = 9528 npm run dev OR npm run dev --port = 9528
-const port = process.env.port || process.env.npm_config_port || 9528 // dev port
+const port = process.env.port || process.env.npm_config_port || 9528; // dev port
 
 // All configuration item explanations can be find in https://cli.vuejs.org/config/
 module.exports = {
@@ -58,16 +58,16 @@ module.exports = {
         fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/],
         include: 'initial'
       }
-    ])
+    ]);
 
     // when there are many pages, it will cause too many meaningless requests
-    config.plugins.delete('prefetch')
+    config.plugins.delete('prefetch');
 
     // set svg-sprite-loader
     config.module
       .rule('svg')
       .exclude.add(resolve('src/icons'))
-      .end()
+      .end();
     config.module
       .rule('icons')
       .test(/\.svg$/)
@@ -78,46 +78,60 @@ module.exports = {
       .options({
         symbolId: 'icon-[name]'
       })
-      .end()
+      .end();
 
-    config
-      .when(process.env.NODE_ENV !== 'development',
-        config => {
-          config
-            .plugin('ScriptExtHtmlWebpackPlugin')
-            .after('html')
-            .use('script-ext-html-webpack-plugin', [{
+    config.resolve.alias
+      .set('api', path.resolve('src/api'))
+      .set('assets', path.resolve('src/assets'))
+      .set('components', path.resolve('src/components'))
+      .set('config', path.resolve('src/config'))
+      .set('const', path.resolve('src/const'))
+      .set('containers', path.resolve('src/containers'))
+      .set('directives', path.resolve('src/directives'))
+      .set('mixins', path.resolve('src/mixins'))
+      .set('model', path.resolve('src/model'))
+      .set('plugins', path.resolve('src/plugins'))
+      .set('src', path.resolve('src'))
+      .set('store', path.resolve('src/store'))
+      .set('utils', path.resolve('src/utils'))
+      .set('views', path.resolve('src/views'));
+
+    config.when(process.env.NODE_ENV !== 'development', (config) => {
+      config
+        .plugin('ScriptExtHtmlWebpackPlugin')
+        .after('html')
+        .use('script-ext-html-webpack-plugin', [
+          {
             // `runtime` must same as runtimeChunk name. default is `runtime`
-              inline: /runtime\..*\.js$/
-            }])
-            .end()
-          config
-            .optimization.splitChunks({
-              chunks: 'all',
-              cacheGroups: {
-                libs: {
-                  name: 'chunk-libs',
-                  test: /[\\/]node_modules[\\/]/,
-                  priority: 10,
-                  chunks: 'initial' // only package third parties that are initially dependent
-                },
-                elementUI: {
-                  name: 'chunk-elementUI', // split elementUI into a single package
-                  priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
-                  test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
-                },
-                commons: {
-                  name: 'chunk-commons',
-                  test: resolve('src/components'), // can customize your rules
-                  minChunks: 3, //  minimum common number
-                  priority: 5,
-                  reuseExistingChunk: true
-                }
-              }
-            })
-          // https:// webpack.js.org/configuration/optimization/#optimizationruntimechunk
-          config.optimization.runtimeChunk('single')
+            inline: /runtime\..*\.js$/
+          }
+        ])
+        .end();
+      config.optimization.splitChunks({
+        chunks: 'all',
+        cacheGroups: {
+          libs: {
+            name: 'chunk-libs',
+            test: /[\\/]node_modules[\\/]/,
+            priority: 10,
+            chunks: 'initial' // only package third parties that are initially dependent
+          },
+          elementUI: {
+            name: 'chunk-elementUI', // split elementUI into a single package
+            priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
+            test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
+          },
+          commons: {
+            name: 'chunk-commons',
+            test: resolve('src/components'), // can customize your rules
+            minChunks: 3, //  minimum common number
+            priority: 5,
+            reuseExistingChunk: true
+          }
         }
-      )
+      });
+      // https:// webpack.js.org/configuration/optimization/#optimizationruntimechunk
+      config.optimization.runtimeChunk('single');
+    });
   }
-}
+};