wj hai 1 ano
achega
27b89c3d93
Modificáronse 100 ficheiros con 6250 adicións e 0 borrados
  1. 14 0
      .editorconfig
  2. 5 0
      .env.development
  3. 6 0
      .env.production
  4. 8 0
      .env.staging
  5. 4 0
      .env.test
  6. 4 0
      .eslintignore
  7. 198 0
      .eslintrc.js
  8. 16 0
      .gitignore
  9. 5 0
      .travis.yml
  10. 21 0
      LICENSE
  11. 14 0
      babel.config.js
  12. 35 0
      build/index.js
  13. 24 0
      jest.config.js
  14. 9 0
      jsconfig.json
  15. 65 0
      package.json
  16. 8 0
      postcss.config.js
  17. BIN=BIN
      public/favicon.ico
  18. 17 0
      public/index.html
  19. 39 0
      src/App.vue
  20. 40 0
      src/api/auth.js
  21. 38 0
      src/api/home.js
  22. 41 0
      src/api/menu.js
  23. 22 0
      src/api/order.js
  24. 156 0
      src/api/user.js
  25. BIN=BIN
      src/assets/404_images/404.png
  26. BIN=BIN
      src/assets/404_images/404_cloud.png
  27. BIN=BIN
      src/assets/bg.png
  28. 71 0
      src/assets/font/iconfont.css
  29. BIN=BIN
      src/assets/font/iconfont.ttf
  30. BIN=BIN
      src/assets/font/iconfont.woff
  31. BIN=BIN
      src/assets/font/iconfont.woff2
  32. BIN=BIN
      src/assets/home.png
  33. 18 0
      src/assets/icon1.svg
  34. 18 0
      src/assets/icon2.svg
  35. 78 0
      src/components/Breadcrumb/index.vue
  36. 44 0
      src/components/Hamburger/index.vue
  37. 62 0
      src/components/SvgIcon/index.vue
  38. 10 0
      src/components/TabCard/index.js
  39. 47 0
      src/components/TabCard/index.vue
  40. 107 0
      src/components/Table/index.vue
  41. 20 0
      src/components/Title/index.js
  42. 58 0
      src/components/Title/index.vue
  43. 10 0
      src/components/TopBar/index.js
  44. 76 0
      src/components/TopBar/index.vue
  45. 99 0
      src/components/Upload/index.vue
  46. 9 0
      src/icons/index.js
  47. 0 0
      src/icons/svg/dashboard.svg
  48. 1 0
      src/icons/svg/example.svg
  49. 1 0
      src/icons/svg/eye-open.svg
  50. 1 0
      src/icons/svg/eye.svg
  51. 0 0
      src/icons/svg/form.svg
  52. 1 0
      src/icons/svg/link.svg
  53. 1 0
      src/icons/svg/nested.svg
  54. 1 0
      src/icons/svg/password.svg
  55. 1 0
      src/icons/svg/table.svg
  56. 1 0
      src/icons/svg/tree.svg
  57. 1 0
      src/icons/svg/user.svg
  58. 22 0
      src/icons/svgo.yml
  59. 52 0
      src/layout/components/AppMain.vue
  60. 282 0
      src/layout/components/Navbar.vue
  61. 26 0
      src/layout/components/Sidebar/FixiOSBug.js
  62. 42 0
      src/layout/components/Sidebar/Item.vue
  63. 43 0
      src/layout/components/Sidebar/Link.vue
  64. 82 0
      src/layout/components/Sidebar/Logo.vue
  65. 95 0
      src/layout/components/Sidebar/SidebarItem.vue
  66. 58 0
      src/layout/components/Sidebar/index.vue
  67. 3 0
      src/layout/components/index.js
  68. 93 0
      src/layout/index.vue
  69. 45 0
      src/layout/mixin/ResizeHandler.js
  70. 64 0
      src/main.js
  71. 85 0
      src/permission.js
  72. 497 0
      src/router/index.js
  73. 26 0
      src/settings.js
  74. 10 0
      src/store/getters.js
  75. 19 0
      src/store/index.js
  76. 48 0
      src/store/modules/app.js
  77. 32 0
      src/store/modules/settings.js
  78. 122 0
      src/store/modules/user.js
  79. 49 0
      src/styles/element-ui.scss
  80. 7 0
      src/styles/element-variables.scss
  81. 153 0
      src/styles/index.scss
  82. 28 0
      src/styles/mixin.scss
  83. 226 0
      src/styles/sidebar.scss
  84. 48 0
      src/styles/transition.scss
  85. 25 0
      src/styles/variables.scss
  86. 29 0
      src/utils/auth.js
  87. 20 0
      src/utils/get-page-title.js
  88. 143 0
      src/utils/index.js
  89. 0 0
      src/utils/map.json
  90. 93 0
      src/utils/request.js
  91. 20 0
      src/utils/validate.js
  92. 228 0
      src/views/404.vue
  93. 147 0
      src/views/adminManage/adminAdd.vue
  94. 171 0
      src/views/adminManage/adminDetail.vue
  95. 319 0
      src/views/adminManage/adminList.vue
  96. 271 0
      src/views/adminManage/menu.js
  97. 246 0
      src/views/afterSales/afterSalesList.vue
  98. 187 0
      src/views/afterSales/detail.vue
  99. 471 0
      src/views/goodsManage/index.vue
  100. 98 0
      src/views/home/index.vue

+ 14 - 0
.editorconfig

@@ -0,0 +1,14 @@
+# http://editorconfig.org
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 2
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.md]
+insert_final_newline = false
+trim_trailing_whitespace = false

+ 5 - 0
.env.development

@@ -0,0 +1,5 @@
+# just a flag
+ENV = 'development'
+
+# base api
+VUE_APP_BASE_API = '/dev-api'

+ 6 - 0
.env.production

@@ -0,0 +1,6 @@
+# just a flag
+ENV = 'production'
+
+# base api
+VUE_APP_BASE_API = '/prod-api'
+

+ 8 - 0
.env.staging

@@ -0,0 +1,8 @@
+NODE_ENV = production
+
+# just a flag
+ENV = 'staging'
+
+# base api
+VUE_APP_BASE_API = '/stage-api'
+

+ 4 - 0
.env.test

@@ -0,0 +1,4 @@
+ENV = 'test'
+
+# base api
+VUE_APP_BASE_API = '/dev-api'

+ 4 - 0
.eslintignore

@@ -0,0 +1,4 @@
+build/*.js
+src/assets
+public
+dist

+ 198 - 0
.eslintrc.js

@@ -0,0 +1,198 @@
+module.exports = {
+  root: true,
+  parserOptions: {
+    parser: 'babel-eslint',
+    sourceType: 'module'
+  },
+  env: {
+    browser: true,
+    node: true,
+    es6: true,
+  },
+  extends: ['plugin:vue/recommended', 'eslint:recommended'],
+
+  // add your custom rules here
+  //it is base on https://github.com/vuejs/eslint-config-vue
+  rules: {
+    "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': [2, 'never'],
+    'semi-spacing': [2, {
+      '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']
+  }
+}

+ 16 - 0
.gitignore

@@ -0,0 +1,16 @@
+.DS_Store
+node_modules/
+dist/
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+package-lock.json
+tests/**/coverage/
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln

+ 5 - 0
.travis.yml

@@ -0,0 +1,5 @@
+language: node_js
+node_js: 10
+script: npm run test
+notifications:
+  email: false

+ 21 - 0
LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017-present PanJiaChen
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 14 - 0
babel.config.js

@@ -0,0 +1,14 @@
+module.exports = {
+  presets: [
+    // https://github.com/vuejs/vue-cli/tree/master/packages/@vue/babel-preset-app
+    '@vue/cli-plugin-babel/preset'
+  ],
+  'env': {
+    'development': {
+      // babel-plugin-dynamic-import-node plugin only does one thing by converting all import() to require().
+      // This plugin can significantly increase the speed of hot updates, when you have a large number of pages.
+      // https://panjiachen.github.io/vue-element-admin-site/guide/advanced/lazy-loading.html
+      'plugins': ['dynamic-import-node']
+    }
+  }
+}

+ 35 - 0
build/index.js

@@ -0,0 +1,35 @@
+const { run } = require('runjs')
+const chalk = require('chalk')
+const config = require('../vue.config.js')
+const rawArgv = process.argv.slice(2)
+const args = rawArgv.join(' ')
+
+if (process.env.npm_config_preview || rawArgv.includes('--preview')) {
+  const report = rawArgv.includes('--report')
+
+  run(`vue-cli-service build ${args}`)
+
+  const port = 9526
+  const publicPath = config.publicPath
+
+  var connect = require('connect')
+  var serveStatic = require('serve-static')
+  const app = connect()
+
+  app.use(
+    publicPath,
+    serveStatic('./dist', {
+      index: ['index.html', '/']
+    })
+  )
+
+  app.listen(port, function () {
+    console.log(chalk.green(`> Preview at  http://localhost:${port}${publicPath}`))
+    if (report) {
+      console.log(chalk.green(`> Report at  http://localhost:${port}${publicPath}report.html`))
+    }
+
+  })
+} else {
+  run(`vue-cli-service build ${args}`)
+}

+ 24 - 0
jest.config.js

@@ -0,0 +1,24 @@
+module.exports = {
+  moduleFileExtensions: ['js', 'jsx', 'json', 'vue'],
+  transform: {
+    '^.+\\.vue$': 'vue-jest',
+    '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$':
+      'jest-transform-stub',
+    '^.+\\.jsx?$': 'babel-jest'
+  },
+  moduleNameMapper: {
+    '^@/(.*)$': '<rootDir>/src/$1'
+  },
+  snapshotSerializers: ['jest-serializer-vue'],
+  testMatch: [
+    '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
+  ],
+  collectCoverageFrom: ['src/utils/**/*.{js,vue}', '!src/utils/auth.js', '!src/utils/request.js', 'src/components/**/*.{js,vue}'],
+  coverageDirectory: '<rootDir>/tests/unit/coverage',
+  // 'collectCoverage': true,
+  'coverageReporters': [
+    'lcov',
+    'text-summary'
+  ],
+  testURL: 'http://localhost/'
+}

+ 9 - 0
jsconfig.json

@@ -0,0 +1,9 @@
+{
+  "compilerOptions": {
+    "baseUrl": "./",
+    "paths": {
+        "@/*": ["src/*"]
+    }
+  },
+  "exclude": ["node_modules", "dist"]
+}

+ 65 - 0
package.json

@@ -0,0 +1,65 @@
+{
+  "name": "vue-admin-template",
+  "version": "4.4.0",
+  "description": "A vue admin template with Element UI & axios & iconfont & permission control & lint",
+  "author": "Pan <panfree23@gmail.com>",
+  "scripts": {
+    "dev": "vue-cli-service serve",
+    "build:prod": "vue-cli-service build",
+    "build:stage": "vue-cli-service build --mode staging",
+    "build:test": "vue-cli-service build --mode test",
+    "preview": "node build/index.js --preview",
+    "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml",
+    "lint": "eslint --ext .js,.vue src",
+    "test:unit": "jest --clearCache && vue-cli-service test:unit",
+    "test:ci": "npm run lint && npm run test:unit"
+  },
+  "dependencies": {
+    "axios": "0.18.1",
+    "blueimp-md5": "^2.19.0",
+    "core-js": "^3.6.5",
+    "echarts": "^5.4.2",
+    "element-ui": "2.15.13",
+    "js-cookie": "2.2.0",
+    "normalize.css": "7.0.0",
+    "nprogress": "0.2.0",
+    "path-to-regexp": "2.4.0",
+    "vue": "2.6.14",
+    "vue-router": "3.0.6",
+    "vuex": "3.1.0"
+  },
+  "devDependencies": {
+    "@vue/cli-plugin-babel": "4.4.4",
+    "@vue/cli-plugin-eslint": "4.4.4",
+    "@vue/cli-plugin-unit-jest": "4.4.4",
+    "@vue/cli-service": "4.4.4",
+    "@vue/test-utils": "1.0.0-beta.29",
+    "autoprefixer": "9.5.1",
+    "babel-eslint": "10.1.0",
+    "babel-jest": "23.6.0",
+    "babel-plugin-dynamic-import-node": "2.3.3",
+    "chalk": "2.4.2",
+    "compression-webpack-plugin": "^5.0.1",
+    "connect": "3.6.6",
+    "eslint": "6.7.2",
+    "eslint-plugin-vue": "6.2.2",
+    "html-webpack-plugin": "3.2.0",
+    "runjs": "4.3.2",
+    "sass": "1.26.8",
+    "sass-loader": "8.0.2",
+    "script-ext-html-webpack-plugin": "2.1.3",
+    "serve-static": "1.13.2",
+    "svg-sprite-loader": "4.1.3",
+    "svgo": "1.2.2",
+    "vue-template-compiler": "^2.6.14"
+  },
+  "browserslist": [
+    "> 1%",
+    "last 2 versions"
+  ],
+  "engines": {
+    "node": ">=8.9",
+    "npm": ">= 3.0.0"
+  },
+  "license": "MIT"
+}

+ 8 - 0
postcss.config.js

@@ -0,0 +1,8 @@
+// https://github.com/michael-ciniawsky/postcss-load-config
+
+module.exports = {
+  'plugins': {
+    // to edit target browsers: use "browserslist" field in package.json
+    'autoprefixer': {}
+  }
+}

BIN=BIN
public/favicon.ico


+ 17 - 0
public/index.html

@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
+    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
+    <title><%= webpackConfig.name %></title>
+  </head>
+  <body>
+    <noscript>
+      <strong>We're sorry but <%= webpackConfig.name %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
+    </noscript>
+    <div id="app"></div>
+    <!-- built files will be auto injected -->
+  </body>
+</html>

+ 39 - 0
src/App.vue

@@ -0,0 +1,39 @@
+<!--
+ * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @Date: 2021-09-03 17:23:10
+ * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @LastEditTime: 2023-06-13 11:25:28
+ * @FilePath: \agentManage\src\App.vue
+ * @Description: 
+ * 
+ * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. 
+-->
+<template>
+  <div id="app">
+    <router-view v-if="flag" />
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'App',
+  provide(){
+    return {
+      reload:this.reload
+    }
+  },
+  data() {
+    return {
+      flag: true
+    }
+  },
+  methods: {
+    reload() {
+      this.flag = false
+      this.$nextTick(()=>{
+        this.flag = true
+      })
+    }
+  },
+}
+</script>

+ 40 - 0
src/api/auth.js

@@ -0,0 +1,40 @@
+/*
+ * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @Date: 2021-07-15 12:26:02
+ * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @LastEditTime: 2023-08-30 13:49:34
+ * @FilePath: \agentManage\src\api\auth.js
+ * @Description: 
+ * 
+ * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. 
+ */
+import request from '@/utils/request'
+
+export function refreshToken(data) {
+  return request({
+    url: '/token',
+    method: 'post',
+    data
+  })
+}
+
+// 登录
+export function login(data) {
+    return request({
+        url: '/analystserver/index/login',
+        method: 'post',
+        data
+    })
+}
+
+// 获取企业列表
+export function adminenterprise(params) {
+  return request({
+      url: '/analystserver/index/adminenterprise',
+      method: 'get',
+      params
+  })
+}
+
+
+

+ 38 - 0
src/api/home.js

@@ -0,0 +1,38 @@
+/*
+ * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @Date: 2023-08-15 15:52:35
+ * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @LastEditTime: 2023-08-17 15:49:36
+ * @FilePath: \agentManage\src\api\home.js
+ * @Description: 
+ * 
+ * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. 
+ */
+import request from '@/utils/request'
+
+// 上传
+export function upload(data) {
+  return request({
+    url: '/home/upload',
+    method: 'post',
+    params: data
+  })
+}
+
+// 用户统计
+export function getUser(params) {
+  return request({
+    url: '/analystserver/user/count',
+    method: 'get',
+    params
+  })
+}
+
+// 用户统计图表
+export function getUserStatistics(data) {
+  return request({
+    url: '/analystserver/user/countDetails',
+    method: 'post',
+    data
+  })
+}

+ 41 - 0
src/api/menu.js

@@ -0,0 +1,41 @@
+import request from '@/utils/request'
+
+export function getMenu(params) {
+  return request({
+    url: '/menu/getMenu',
+    method: 'get',
+    params
+  })
+}
+
+export function roleList(params) {
+  return request({
+    url: '/menu/roleList',
+    method: 'get',
+    params
+  })
+}
+
+export function editRole(data) {
+    return request({
+      url: '/menu/editRole',
+      method: 'post',
+      data
+    })
+}
+
+export function addRole(data) {
+  return request({
+    url: '/menu/addRole',
+    method: 'post',
+    data
+  })
+}
+
+export function delRole(data) {
+  return request({
+    url: '/menu/delRole',
+    method: 'delete',
+    data
+  })
+}

+ 22 - 0
src/api/order.js

@@ -0,0 +1,22 @@
+/*
+ * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @Date: 2023-08-15 17:33:37
+ * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @LastEditTime: 2023-08-15 17:34:05
+ * @FilePath: \agentManage\src\api\order.js
+ * @Description: 
+ * 
+ * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. 
+ */
+
+import request from '@/utils/request'
+
+export function findOrder(data) {
+  return request({
+    url: '/orderserver/order/findOrder',
+    method: 'post',
+    data
+  })
+}
+
+

+ 156 - 0
src/api/user.js

@@ -0,0 +1,156 @@
+import request from '@/utils/request'
+// 员工列表
+export function userList(params) {
+  return request({
+    url: '/user/userList',
+    method: 'get',
+    params
+  })
+}
+
+// 员工添加
+export function add(data) {
+  return request({
+    url: '/user/add',
+    method: 'post',
+    data
+  })
+}
+
+// 编辑用户
+export function edit(data) {
+  return request({
+    url: '/user/edit',
+    method: 'post',
+    data
+  })
+}
+
+// 删除用户
+export function del(data) {
+  return request({
+    url: '/user/del',
+    method: 'delete',
+    data
+  })
+}
+
+// 编辑用户
+export function setting(data) {
+  return request({
+    url: '/user/setting',
+    method: 'post',
+    data
+  })
+}
+
+// 黑钻收支明细
+export function diamondList(params) {
+  return request({
+    url: '/user/diamondList',
+    method: 'get',
+    params
+  })
+}
+// 返佣查询
+export function rebateList(params) {
+  return request({
+    url: '/user/rebateList',
+    method: 'get',
+    params
+  })
+}
+// 返佣查询
+export function getRebate(params) {
+  return request({
+    url: '/user/getRebate',
+    method: 'get',
+    params
+  })
+}
+// 返佣设置
+export function editRebate(data) {
+  return request({
+    url: '/user/editRebate',
+    method: 'post',
+    data
+  })
+}
+// 修改上级员工
+export function editLeader(data) {
+  return request({
+    url: '/user/editLeader',
+    method: 'post',
+    data
+  })
+}
+// 修改会员账号启用状态
+export function changeStatus(data) {
+  return request({
+    url: '/user/changeStatus',
+    method: 'post',
+    data
+  })
+}
+// 修改测试账号状态
+export function changeTestStatus(data) {
+  return request({
+    url: '/user/changeTestStatus',
+    method: 'post',
+    data
+  })
+}
+// 用户操作日志
+export function logs(params) {
+  return request({
+    url: '/user/logs',
+    method: 'get',
+    params
+  })
+}
+
+// 登录日志
+export function loginLogs(params) {
+  return request({
+    url: '/user/loginLogs',
+    method: 'get',
+    params
+  })
+}
+
+
+// 查看用户的返佣明细列表
+export function rebateDetail(params) {
+  return request({
+    url: '/user/rebateDetail',
+    method: 'get',
+    params
+  })
+}
+
+// 好友列表
+export function friendList(params) {
+  return request({
+    url: '/user/friendList',
+    method: 'get',
+    params
+  })
+}
+
+// 获取产生利益明细
+export function getEarnings(params) {
+  return request({
+    url: '/user/getEarnings',
+    method: 'get',
+    params
+  })
+}
+
+// 礼包领取记录
+export function sendLog(params) {
+  return request({
+    url: '/game/sendLog',
+    method: 'get',
+    params
+  })
+}

BIN=BIN
src/assets/404_images/404.png


BIN=BIN
src/assets/404_images/404_cloud.png


BIN=BIN
src/assets/bg.png


+ 71 - 0
src/assets/font/iconfont.css

@@ -0,0 +1,71 @@
+@font-face {
+  font-family: "iconfont"; /* Project id 3490344 */
+  src: url('iconfont.woff2?t=1656489699750') format('woff2'),
+       url('iconfont.woff?t=1656489699750') format('woff'),
+       url('iconfont.ttf?t=1656489699750') format('truetype');
+}
+
+.iconfont {
+  font-family: "iconfont" !important;
+  font-size: 16px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+.icon-shouyefill:before {
+  content: "\e750";
+}
+
+.icon-baobiao:before {
+  content: "\e654";
+}
+
+.icon-duanxinyingxiao:before {
+  content: "\e601";
+}
+
+.icon-caidancaiwu:before {
+  content: "\e615";
+}
+
+.icon-xinwen:before {
+  content: "\e650";
+}
+
+.icon-youxi:before {
+  content: "\e617";
+}
+
+.icon-bianjiwenzhang_huaban:before {
+  content: "\e62e";
+}
+
+.icon-shezhi:before {
+  content: "\e62a";
+}
+
+.icon-weibiaoti1:before {
+  content: "\e600";
+}
+
+.icon-dingdan:before {
+  content: "\e634";
+}
+
+.icon-tongzhi4:before {
+  content: "\e605";
+}
+
+.icon-guanliyuan_jiaoseguanli:before {
+  content: "\e612";
+}
+
+.icon-tianjia:before {
+  content: "\e609";
+}
+
+.icon-guanji:before {
+  content: "\e631";
+}
+

BIN=BIN
src/assets/font/iconfont.ttf


BIN=BIN
src/assets/font/iconfont.woff


BIN=BIN
src/assets/font/iconfont.woff2


BIN=BIN
src/assets/home.png


+ 18 - 0
src/assets/icon1.svg

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="135px" height="147px" xmlns="http://www.w3.org/2000/svg">
+  <defs>
+    <filter x="143px" y="-11px" width="135px" height="147px" filterUnits="userSpaceOnUse" id="filter1">
+      <feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetInner" />
+      <feGaussianBlur stdDeviation="5" in="shadowOffsetInner" result="shadowGaussian" />
+      <feComposite in2="shadowGaussian" operator="atop" in="SourceAlpha" result="shadowComposite" />
+      <feColorMatrix type="matrix" values="0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0.34901960784313724 0  " in="shadowComposite" />
+    </filter>
+    <g id="widget2">
+      <path d="M 115 17.688369914273153  C 115 7.967619080059655  107.98802978099712 0  99.17412937167865 0  L 16.054816768527758 0  C 7.240916487938705 0  0 7.967619080059655  0 17.688369914273153  L 0 89.98722653057015  C 0 99.70797736478369  7.241048049460061 107.50968303146789  16.054816768527758 107  L 38.3317526641336 107  L 54.80204470805489 125.68620438507574  C 55.58214776063241 126.54439204674401  56.60331618965694 127  57.624484618681606 127  C 58.648551005603736 127  59.67288090175714 126.58172972025716  60.453510972797254 125.71903835052808  C 62.01226809900351 123.99568953458291  62.00937014110602 121.21191893183737  60.446924529308376 119.49263796291814  L 42.80674109392862 100.00842304887345  C 42.05759451884319 99.18408645638829  41.04261733382515 98.64741048027071  39.98430118330194 98  L 16.054816768527758 98  C 11.647932408993853 98.6474103382964  8.035509844921137 94.84752925684634  8 89.98722653057015  L 8 17.688369914273153  C 8.035509716191712 12.828067046022703  11.647932408993853 8.716989562196389  16.054816639798247 9  L 99.17412924294916 9  C 103.58101360248293 8.716989562196389  106.96449002634935 12.827921806335866  107 17.688369914273153  L 107 89.98722653057015  C 106.96449002634935 94.84752939882067  103.58101347375353 98.6474103382964  99.17412924294916 98  L 66.40597931410053 98  C 64.1989804677226 98.6474103382964  62.40982809363186 100.64447264341788  62.40982809363186 103.07854668488216  C 62.40982809363186 105.51262072634651  64.1989804677226 107.50968303146789  66.40597931410053 107  L 99.17412937167865 107  C 107.98802965226764 107.50968303146789  114.99999987127046 99.70797736478369  115 89.98722653057015  L 115 17.688369914273153  Z " fill-rule="nonzero" fill="#ffffff" stroke="none" transform="matrix(1 0 0 1 153 -1 )" />
+    </g>
+  </defs>
+  <g transform="matrix(1 0 0 1 -143 11 )">
+    <use xlink:href="#widget2" filter="url(#filter1)" />
+    <use xlink:href="#widget2" />
+  </g>
+</svg>

+ 18 - 0
src/assets/icon2.svg

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="101px" height="74px" xmlns="http://www.w3.org/2000/svg">
+  <defs>
+    <filter x="162px" y="20px" width="101px" height="74px" filterUnits="userSpaceOnUse" id="filter3">
+      <feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetInner" />
+      <feGaussianBlur stdDeviation="5" in="shadowOffsetInner" result="shadowGaussian" />
+      <feComposite in2="shadowGaussian" operator="atop" in="SourceAlpha" result="shadowComposite" />
+      <feColorMatrix type="matrix" values="0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0.34901960784313724 0  " in="shadowComposite" />
+    </filter>
+    <g id="widget4">
+      <path d="M 2.291519135427734 13.492891184031862  C 1.320406235275527 20.617701855165407  1.2299992331205658 31.932237633818854  7.8685989300758195 40.94031364648305  C 14.254552521385392 49.60600422623679  25.161725093108714 54  40.28682534587955 54  C 55.32804882620155 54  66.25234515234376 49.601216505121286  72.7558423111214 40.92595076668533  C 79.49181445622827 31.940797120778516  79.65463413172739 20.629017861569793  78.82021984643956 13.375522547251435  C 80.1699392957232 11.95505786525625  81 10.035958054492752  81 7.921872523993983  C 81 3.54659182022111  77.45236085443781 0  73.07611215099894 0  C 68.69986344756023 0  65.15222430199807 3.5467368554210026  65.15222430199807 7.921872523993983  C 65.15222430199807 11.26622459609375  67.22621527319939 14.124418394526515  70.15769394180529 15.28664315362927  C 70.70797197512354 21.050471296531796  70.41730563525815 29.3962634209839  65.68610436681288 35.67990821168996  C 60.93052375375828 41.995615422235915  52.384960986394105 45.19779046610134  40.28697041797642 45.19779046610134  C 28.134996863126474 45.19779046610134  19.62077916998942 42.01969835414138  14.981000691998219 35.7518672205554  C 10.26924489876407 29.386978332701542  10.253282146551527 20.888853738758797  10.952593893661799 15.243264585610676  C 13.825735994824356 14.0539101629834  15.847775698001927 11.224441982371758  15.847775698001927 7.92201755919389  C 15.847775698001927 3.5467368554210315  12.300136552439739 0.00014503519991393432  7.923887849000948 0.00014503519991393432  C 3.5476391455621585 0.00014503519991393432  0 3.5468818906209094  0 7.92201755919389  C 0 10.094279643108834  0.8751917402111359 12.061690636432004  2.291519135427734 13.492891184031862  Z " fill-rule="nonzero" fill="#ffffff" stroke="none" transform="matrix(1 0 0 1 172 30 )" />
+    </g>
+  </defs>
+  <g transform="matrix(1 0 0 1 -162 -20 )">
+    <use xlink:href="#widget4" filter="url(#filter3)" />
+    <use xlink:href="#widget4" />
+  </g>
+</svg>

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

@@ -0,0 +1,78 @@
+<template>
+  <el-breadcrumb class="app-breadcrumb" separator="/">
+    <transition-group name="breadcrumb">
+      <el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
+        <span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect">{{ item.meta.title }}</span>
+        <a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
+      </el-breadcrumb-item>
+    </transition-group>
+  </el-breadcrumb>
+</template>
+
+<script>
+import pathToRegexp from 'path-to-regexp'
+
+export default {
+  data() {
+    return {
+      levelList: null
+    }
+  },
+  watch: {
+    $route() {
+      this.getBreadcrumb()
+    }
+  },
+  created() {
+    this.getBreadcrumb()
+  },
+  methods: {
+    getBreadcrumb() {
+      // only show routes with meta.title
+      let matched = this.$route.matched.filter(item => item.meta && item.meta.title)
+      const first = matched[0]
+
+      if (!this.isDashboard(first)) {
+        matched = [].concat(matched)
+      }
+
+      this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
+    },
+    isDashboard(route) {
+      const name = route && route.name
+      if (!name) {
+        return false
+      }
+      return name.trim().toLocaleLowerCase() === 'Dashboard'.toLocaleLowerCase()
+    },
+    pathCompile(path) {
+      // To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561
+      const { params } = this.$route
+      var toPath = pathToRegexp.compile(path)
+      return toPath(params)
+    },
+    handleLink(item) {
+      const { redirect, path } = item
+      if (redirect) {
+        this.$router.push(redirect)
+        return
+      }
+      this.$router.push(this.pathCompile(path))
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.app-breadcrumb.el-breadcrumb {
+  display: inline-block;
+  font-size: 14px;
+  line-height: 50px;
+  margin-left: 8px;
+
+  .no-redirect {
+    color: #97a8be;
+    cursor: text;
+  }
+}
+</style>

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

@@ -0,0 +1,44 @@
+<template>
+  <div style="padding: 0 15px;" @click="toggleClick">
+    <svg
+      :class="{'is-active':isActive}"
+      class="hamburger"
+      viewBox="0 0 1024 1024"
+      xmlns="http://www.w3.org/2000/svg"
+      width="64"
+      height="64"
+    >
+      <path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" />
+    </svg>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'Hamburger',
+  props: {
+    isActive: {
+      type: Boolean,
+      default: false
+    }
+  },
+  methods: {
+    toggleClick() {
+      this.$emit('toggleClick')
+    }
+  }
+}
+</script>
+
+<style scoped>
+.hamburger {
+  display: inline-block;
+  vertical-align: middle;
+  width: 20px;
+  height: 20px;
+}
+
+.hamburger.is-active {
+  transform: rotate(180deg);
+}
+</style>

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

@@ -0,0 +1,62 @@
+<template>
+  <div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" />
+  <svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
+    <use :xlink:href="iconName" />
+  </svg>
+</template>
+
+<script>
+// doc: https://panjiachen.github.io/vue-element-admin-site/feature/component/svg-icon.html#usage
+import { isExternal } from '@/utils/validate'
+
+export default {
+  name: 'SvgIcon',
+  props: {
+    iconClass: {
+      type: String,
+      required: true
+    },
+    className: {
+      type: String,
+      default: ''
+    }
+  },
+  computed: {
+    isExternal() {
+      return isExternal(this.iconClass)
+    },
+    iconName() {
+      return `#icon-${this.iconClass}`
+    },
+    svgClass() {
+      if (this.className) {
+        return 'svg-icon ' + this.className
+      } else {
+        return 'svg-icon'
+      }
+    },
+    styleExternalIcon() {
+      return {
+        mask: `url(${this.iconClass}) no-repeat 50% 50%`,
+        '-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+.svg-icon {
+  width: 1em;
+  height: 1em;
+  vertical-align: -0.15em;
+  fill: currentColor;
+  overflow: hidden;
+}
+
+.svg-external-icon {
+  background-color: currentColor;
+  mask-size: cover!important;
+  display: inline-block;
+}
+</style>

+ 10 - 0
src/components/TabCard/index.js

@@ -0,0 +1,10 @@
+import TabCard from './index.vue'
+// 这里是重点
+const myTabCard = {
+    install: function (Vue) {
+        Vue.component('TabCard', TabCard)
+    }
+}
+
+// 导出组件
+export default myTabCard

+ 47 - 0
src/components/TabCard/index.vue

@@ -0,0 +1,47 @@
+<template>
+    <div class="TabCard">
+        <div class="title">{{title}}</div>
+        <slot></slot>
+        <el-button v-if="isSearch" class="btn" size="small" :loading="loading" @click="search">查询结果</el-button>
+    </div>
+</template>
+
+<script>
+    export default {
+        name:"TabCard",
+        props: {
+            title: {
+                type: String,
+                default: '标题'
+            },
+            isSearch:{
+                type:Boolean,
+                default:false
+            },
+            loading:{
+                type:Boolean,
+                default:false
+            }
+        },
+        methods: {
+            search() {
+                this.$emit('search')
+            }
+        },
+    }
+</script>
+
+<style lang="scss" scoped>
+.TabCard{
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    height: 40px;
+    background: #f3f3f3;
+    padding: 0 10px;
+    font-size: 14px;
+    color: #666;
+    font-weight: 600;
+
+}
+</style>

+ 107 - 0
src/components/Table/index.vue

@@ -0,0 +1,107 @@
+<!--
+ * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @Date: 2023-06-13 14:35:07
+ * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @LastEditTime: 2023-06-25 09:57:57
+ * @FilePath: \agentManage\src\components\Table\index.vue
+ * @Description: 
+ * 
+ * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. 
+-->
+<template>
+    <div class="table-container">
+        <el-table :border="border" :data="tableData" style="width: 100%">
+            <el-table-column align="center" show-overflow-tooltip v-for="(item, index) in labelObj" :key="index" :prop="item.prop"
+                :label="item.label" :width="item.width || ''">
+            </el-table-column>
+            <el-table-column align="center" label="操作" v-if="btnObj.btnList" :width="btnObj.width || ''">
+                <template slot-scope="scope">
+                    <el-button v-for="(i, d) in btnObj.btnList" :key="d" type="text" size="small"
+                        @click="handleBtn(scope.row, i.text)">{{ i.text }}</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+
+        <div class="pagination">
+            <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="current"
+                :page-sizes="pageSizes" :page-size="size" layout="total, sizes, prev, pager, next, jumper" :total="total">
+            </el-pagination>
+        </div>
+    </div>
+</template>
+
+<script>
+export default {
+    props: {
+        tableData: {
+            type: Array,
+            default: () => []
+        },
+        // 行key和label
+        labelObj: {
+            type: Array,
+            default: () => []
+        },
+        /**
+         * @description: 操作按钮对象
+         * @width {参数类型} 参数名称
+         * @btnList {Array} [{text: '查看'}]
+         */
+        btnObj: {
+            type: Object,
+            default: () => { }
+        },
+        total: {
+            type: Number,
+            default: 0
+        },
+        page: {
+            type: Number,
+            default: 1
+        },
+        pageSize: {
+            type: Number,
+            default: 10
+        },
+        pageSizes: {
+            type: Array,
+            default: () => [10, 20, 50]
+        },
+        border: {
+            type: Boolean,
+            default: true
+        },
+    },
+    data() {
+        return {
+            size: this.pageSize,
+            current: this.page
+        }
+    },
+    methods: {
+        // 单页显示数据量变化
+        handleSizeChange() {
+            this.$emit('sizeChange', this.size)
+        },
+        // 页码变化
+        handleCurrentChange() {
+            this.$emit('pageChange', this.current)
+        },
+        handleBtn(row, text) {
+            this.$emit('handleBtn',{row,text})
+        }
+
+
+    },
+}
+</script>
+
+<style lang="scss" scoped>
+.table-container {
+    .pagination {
+        display: flex;
+        justify-content: center;
+        margin-top: 30px;
+    }
+}
+</style>

+ 20 - 0
src/components/Title/index.js

@@ -0,0 +1,20 @@
+/*
+ * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @Date: 2023-07-05 15:43:06
+ * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @LastEditTime: 2023-07-05 15:43:17
+ * @FilePath: \yidong\src\components\Title\index.js
+ * @Description: 
+ * 
+ * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. 
+ */
+import Title from './index.vue'
+// 这里是重点
+const myTopBar = {
+    install: function (Vue) {
+        Vue.component('Title', Title)
+    }
+}
+
+// 导出组件
+export default myTopBar

+ 58 - 0
src/components/Title/index.vue

@@ -0,0 +1,58 @@
+<!--
+ * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @Date: 2022-07-01 11:25:48
+ * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @LastEditTime: 2023-07-05 15:50:12
+ * @FilePath: \yidong\src\components\Title\index.vue
+ * @Description: 
+ * 
+ * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. 
+-->
+<template>
+    <div class="TopBar">
+        <div class="title-box">
+            <div class="line"></div>
+            <div class="title">{{title}}</div>
+        </div>
+        <div>
+        </div>
+    </div>
+</template>
+
+<script>
+    export default {
+        name:'TopBar',
+        props: {
+            title: {
+                type: String,
+                default: ''
+            },
+        },
+       
+    }
+</script>
+
+<style lang="scss" scoped>
+.TopBar{
+    line-height: 50px;
+    padding: 0 10px;
+    background: #F3F3F3;
+    margin-top: 30px;
+    .title-box{
+        display: flex;
+        align-items: center;
+        .line{
+            width: 5px;
+            height: 16px;
+            background: #1abc9c;
+        }
+        .title{
+            font-size: 14px;
+            color: #666;
+            font-weight: 600;
+            margin-left: 3px;
+        }
+    }
+
+}
+</style>

+ 10 - 0
src/components/TopBar/index.js

@@ -0,0 +1,10 @@
+import TopBar from './index.vue'
+// 这里是重点
+const myTopBar = {
+    install: function (Vue) {
+        Vue.component('TopBar', TopBar)
+    }
+}
+
+// 导出组件
+export default myTopBar

+ 76 - 0
src/components/TopBar/index.vue

@@ -0,0 +1,76 @@
+<!--
+ * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @Date: 2022-07-01 11:25:48
+ * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @LastEditTime: 2023-05-26 15:23:03
+ * @FilePath: \agentManage\src\components\TopBar\index.vue
+ * @Description: 
+ * 
+ * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. 
+-->
+<template>
+    <div class="TopBar">
+        <div class="title-box">
+            <div class="line"></div>
+            <div class="title">{{this.$route.meta.title}}</div>
+        </div>
+        <div>
+
+        <el-button size="small" icon="el-icon-refresh" @click="handleRefresh">刷新</el-button>
+        <el-button v-if="isBack" size="small" icon="el-icon-arrow-left" @click="handleBack">返回</el-button>
+        </div>
+    </div>
+</template>
+
+<script>
+    export default {
+        name:'TopBar',
+        props: {
+            title: {
+                type: String,
+                default: ''
+            },
+            isBack: {
+                type: Boolean,
+                default: false
+            },
+        },
+        methods: {
+            handleRefresh() {
+                this.$emit('refresh')
+                window.location.reload()
+            },
+            handleBack(){
+                this.$router.go(-1)
+            }
+        },
+    }
+</script>
+
+<style lang="scss" scoped>
+.TopBar{
+    line-height: 50px;
+    padding: 0 10px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    background: #F3F3F3;
+    margin-bottom: 20px;
+    .title-box{
+        display: flex;
+        align-items: center;
+        .line{
+            width: 5px;
+            height: 16px;
+            background: #1abc9c;
+        }
+        .title{
+            font-size: 14px;
+            color: #666;
+            font-weight: 600;
+            margin-left: 3px;
+        }
+    }
+
+}
+</style>

+ 99 - 0
src/components/Upload/index.vue

@@ -0,0 +1,99 @@
+<template>
+    <div class="upload">
+        <input type="file" :id="id" v-show="false" :ref="id" @change="upload">
+        <div class="upload-btn" :style="{'width':width,'height':height}" v-loading="imgLoading" v-if="!url" @click="handleUpload">
+            <i class="el-icon-plus"></i>
+        </div>
+        <img class="img" :style="{'width':width,'height':height}" @click="handleUpload" v-else :src="url" alt="">
+    </div>
+</template>
+
+<script>
+// import { getConfig} from '@/api/app'
+import { upload} from '@/api/home'
+    export default {
+        props: {
+            imgUrl: {
+                type: String,
+                default: ''
+            },
+            id:{//同一个页面使用多个上传组件时必填
+                 type: String,
+                default: 'file'
+            },
+            width:{
+                type: String,
+                default: '100px'
+            },
+            height:{
+                type: String,
+                default: '100px'
+            }
+        },
+        data() {
+            return {
+                imgLoading:false,
+                config:null
+            }
+        },
+       computed: {
+           url() {
+               return this.imgUrl 
+           }
+       },
+        methods: {
+            async upload(val) {
+            //oss上传
+            this.imgLoading = true
+            let flie = val.target.files[0]
+            let formdata = new FormData()
+            formdata.append('file',flie)
+                upload(formdata).then(res=>{
+                    if(res.code == 200){
+                        this.url = res.data.url
+                        this.$refs[this.id].value = ''
+                        this.$emit('uploadEnd',this.url)
+                    }
+                })
+
+            },
+            
+            handleUpload() {
+                 document.getElementById(this.id).click()
+            },
+            //获取oss配置
+            // getConfig() {
+            //     return getConfig().then((res) => {
+            //         return res.data;
+            //     });
+            // },
+
+        },
+        created () {
+        },
+    }
+</script>
+
+<style lang="scss" scoped>
+.upload{
+    .upload-btn{
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        background: rgba(176, 176, 177,.5);
+        border-radius: 4px;
+        cursor: pointer;
+    }
+    .el-icon-plus{
+            font-size: 20px;
+            font-weight: 600;
+            color: #666;
+        }
+    .img{
+        // width: 100px;
+        // height: 100px;
+        border-radius: 4px;
+        object-fit: contain;
+    }
+}
+</style>

+ 9 - 0
src/icons/index.js

@@ -0,0 +1,9 @@
+import Vue from 'vue'
+import SvgIcon from '@/components/SvgIcon'// svg component
+
+// register globally
+Vue.component('svg-icon', SvgIcon)
+
+const req = require.context('./svg', false, /\.svg$/)
+const requireAll = requireContext => requireContext.keys().map(requireContext)
+requireAll(req)

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
src/icons/svg/dashboard.svg


+ 1 - 0
src/icons/svg/example.svg

@@ -0,0 +1 @@
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M96.258 57.462h31.421C124.794 27.323 100.426 2.956 70.287.07v31.422a32.856 32.856 0 0 1 25.971 25.97zm-38.796-25.97V.07C27.323 2.956 2.956 27.323.07 57.462h31.422a32.856 32.856 0 0 1 25.97-25.97zm12.825 64.766v31.421c30.46-2.885 54.507-27.253 57.713-57.712H96.579c-2.886 13.466-13.146 23.726-26.292 26.291zM31.492 70.287H.07c2.886 30.46 27.253 54.507 57.713 57.713V96.579c-13.466-2.886-23.726-13.146-26.291-26.292z"/></svg>

+ 1 - 0
src/icons/svg/eye-open.svg

@@ -0,0 +1 @@
+<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="128" height="128"><defs><style/></defs><path d="M512 128q69.675 0 135.51 21.163t115.498 54.997 93.483 74.837 73.685 82.006 51.67 74.837 32.17 54.827L1024 512q-2.347 4.992-6.315 13.483T998.87 560.17t-31.658 51.669-44.331 59.99-56.832 64.34-69.504 60.16-82.347 51.5-94.848 34.687T512 896q-69.675 0-135.51-21.163t-115.498-54.826-93.483-74.326-73.685-81.493-51.67-74.496-32.17-54.997L0 513.707q2.347-4.992 6.315-13.483t18.816-34.816 31.658-51.84 44.331-60.33 56.832-64.683 69.504-60.331 82.347-51.84 94.848-34.816T512 128.085zm0 85.333q-46.677 0-91.648 12.331t-81.152 31.83-70.656 47.146-59.648 54.485-48.853 57.686-37.675 52.821-26.325 43.99q12.33 21.674 26.325 43.52t37.675 52.351 48.853 57.003 59.648 53.845T339.2 767.02t81.152 31.488T512 810.667t91.648-12.331 81.152-31.659 70.656-46.848 59.648-54.186 48.853-57.344 37.675-52.651T927.957 512q-12.33-21.675-26.325-43.648t-37.675-52.65-48.853-57.345-59.648-54.186-70.656-46.848-81.152-31.659T512 213.334zm0 128q70.656 0 120.661 50.006T682.667 512 632.66 632.661 512 682.667 391.339 632.66 341.333 512t50.006-120.661T512 341.333zm0 85.334q-35.328 0-60.33 25.002T426.666 512t25.002 60.33T512 597.334t60.33-25.002T597.334 512t-25.002-60.33T512 426.666z"/></svg>

+ 1 - 0
src/icons/svg/eye.svg

@@ -0,0 +1 @@
+<svg width="128" height="64" xmlns="http://www.w3.org/2000/svg"><path d="M127.072 7.994c1.37-2.208.914-5.152-.914-6.87-2.056-1.717-4.797-1.226-6.396.982-.229.245-25.586 32.382-55.74 32.382-29.24 0-55.74-32.382-55.968-32.627-1.6-1.963-4.57-2.208-6.397-.49C-.17 3.086-.399 6.275 1.2 8.238c.457.736 5.94 7.36 14.62 14.72L4.17 35.96c-1.828 1.963-1.6 5.152.228 6.87.457.98 1.6 1.471 2.742 1.471s2.284-.49 3.198-1.472l12.564-13.983c5.94 4.416 13.021 8.587 20.788 11.53l-4.797 17.418c-.685 2.699.686 5.397 3.198 6.133h1.37c2.057 0 3.884-1.472 4.341-3.68L52.6 42.83c3.655.736 7.538 1.227 11.422 1.227 3.883 0 7.767-.49 11.422-1.227l4.797 17.173c.457 2.208 2.513 3.68 4.34 3.68.457 0 .914 0 1.143-.246 2.513-.736 3.883-3.434 3.198-6.133l-4.797-17.172c7.767-2.944 14.848-7.114 20.788-11.53l12.336 13.738c.913.981 2.056 1.472 3.198 1.472s2.284-.49 3.198-1.472c1.828-1.963 1.828-4.906.228-6.87l-11.65-13.001c9.366-7.36 14.849-14.474 14.849-14.474z"/></svg>

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
src/icons/svg/form.svg


+ 1 - 0
src/icons/svg/link.svg

@@ -0,0 +1 @@
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M115.625 127.937H.063V12.375h57.781v12.374H12.438v90.813h90.813V70.156h12.374z"/><path d="M116.426 2.821l8.753 8.753-56.734 56.734-8.753-8.745z"/><path d="M127.893 37.982h-12.375V12.375H88.706V0h39.187z"/></svg>

+ 1 - 0
src/icons/svg/nested.svg

@@ -0,0 +1 @@
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.002 9.2c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-5.043-3.58-9.132-7.997-9.132S.002 4.157.002 9.2zM31.997.066h95.981V18.33H31.997V.066zm0 45.669c0 5.044 3.58 9.132 7.998 9.132 4.417 0 7.997-4.088 7.997-9.132 0-3.263-1.524-6.278-3.998-7.91-2.475-1.63-5.524-1.63-7.998 0-2.475 1.632-4 4.647-4 7.91zM63.992 36.6h63.986v18.265H63.992V36.6zm-31.995 82.2c0 5.043 3.58 9.132 7.998 9.132 4.417 0 7.997-4.089 7.997-9.132 0-5.044-3.58-9.133-7.997-9.133s-7.998 4.089-7.998 9.133zm31.995-9.131h63.986v18.265H63.992V109.67zm0-27.404c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-3.263-1.524-6.277-3.998-7.909-2.475-1.631-5.524-1.631-7.998 0-2.475 1.632-4 4.646-4 7.91zm31.995-9.13h31.991V91.4H95.987V73.135z"/></svg>

+ 1 - 0
src/icons/svg/password.svg

@@ -0,0 +1 @@
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M108.8 44.322H89.6v-5.36c0-9.04-3.308-24.163-25.6-24.163-23.145 0-25.6 16.881-25.6 24.162v5.361H19.2v-5.36C19.2 15.281 36.798 0 64 0c27.202 0 44.8 15.281 44.8 38.961v5.361zm-32 39.356c0-5.44-5.763-9.832-12.8-9.832-7.037 0-12.8 4.392-12.8 9.832 0 3.682 2.567 6.808 6.407 8.477v11.205c0 2.718 2.875 4.962 6.4 4.962 3.524 0 6.4-2.244 6.4-4.962V92.155c3.833-1.669 6.393-4.795 6.393-8.477zM128 64v49.201c0 8.158-8.645 14.799-19.2 14.799H19.2C8.651 128 0 121.359 0 113.201V64c0-8.153 8.645-14.799 19.2-14.799h89.6c10.555 0 19.2 6.646 19.2 14.799z"/></svg>

+ 1 - 0
src/icons/svg/table.svg

@@ -0,0 +1 @@
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/></svg>

+ 1 - 0
src/icons/svg/tree.svg

@@ -0,0 +1 @@
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M126.713 90.023c.858.985 1.287 2.134 1.287 3.447v29.553c0 1.423-.429 2.6-1.287 3.53-.858.93-1.907 1.395-3.146 1.395H97.824c-1.145 0-2.146-.465-3.004-1.395-.858-.93-1.287-2.107-1.287-3.53V93.47c0-.875.19-1.696.572-2.462.382-.766.906-1.368 1.573-1.806a3.84 3.84 0 0 1 2.146-.657h9.725V69.007a3.84 3.84 0 0 0-.43-1.806 3.569 3.569 0 0 0-1.143-1.313 2.714 2.714 0 0 0-1.573-.492h-36.47v23.149h9.725c1.144 0 2.145.492 3.004 1.478.858.985 1.287 2.134 1.287 3.447v29.553c0 .876-.191 1.696-.573 2.463-.38.766-.905 1.368-1.573 1.806a3.84 3.84 0 0 1-2.145.656H51.915a3.84 3.84 0 0 1-2.145-.656c-.668-.438-1.216-1.04-1.645-1.806a4.96 4.96 0 0 1-.644-2.463V93.47c0-1.313.43-2.462 1.288-3.447.858-.986 1.907-1.478 3.146-1.478h9.582v-23.15h-37.9c-.953 0-1.74.356-2.359 1.068-.62.711-.93 1.56-.93 2.544v19.538h9.726c1.239 0 2.264.492 3.074 1.478.81.985 1.216 2.134 1.216 3.447v29.553c0 1.423-.405 2.6-1.216 3.53-.81.93-1.835 1.395-3.074 1.395H4.29c-.476 0-.93-.082-1.358-.246a4.1 4.1 0 0 1-1.144-.657 4.658 4.658 0 0 1-.93-1.067 5.186 5.186 0 0 1-.643-1.395 5.566 5.566 0 0 1-.215-1.56V93.47c0-.437.048-.875.143-1.313a3.95 3.95 0 0 1 .429-1.15c.19-.328.429-.656.715-.984.286-.329.572-.602.858-.821.286-.22.62-.383 1.001-.493.382-.11.763-.164 1.144-.164h9.726V61.619c0-.985.31-1.833.93-2.544.619-.712 1.358-1.068 2.216-1.068h44.335V39.62h-9.582c-1.24 0-2.288-.492-3.146-1.477a5.09 5.09 0 0 1-1.287-3.448V5.14c0-1.423.429-2.627 1.287-3.612.858-.985 1.907-1.477 3.146-1.477h25.743c.763 0 1.478.246 2.145.739a5.17 5.17 0 0 1 1.573 1.888c.382.766.573 1.587.573 2.462v29.553c0 1.313-.43 2.463-1.287 3.448-.859.985-1.86 1.477-3.004 1.477h-9.725v18.389h42.762c.954 0 1.74.355 2.36 1.067.62.711.93 1.56.93 2.545v26.925h9.582c1.239 0 2.288.492 3.146 1.478z"/></svg>

+ 1 - 0
src/icons/svg/user.svg

@@ -0,0 +1 @@
+<svg width="130" height="130" xmlns="http://www.w3.org/2000/svg"><path d="M63.444 64.996c20.633 0 37.359-14.308 37.359-31.953 0-17.649-16.726-31.952-37.359-31.952-20.631 0-37.36 14.303-37.358 31.952 0 17.645 16.727 31.953 37.359 31.953zM80.57 75.65H49.434c-26.652 0-48.26 18.477-48.26 41.27v2.664c0 9.316 21.608 9.325 48.26 9.325H80.57c26.649 0 48.256-.344 48.256-9.325v-2.663c0-22.794-21.605-41.271-48.256-41.271z" stroke="#979797"/></svg>

+ 22 - 0
src/icons/svgo.yml

@@ -0,0 +1,22 @@
+# replace default config
+
+# multipass: true
+# full: true
+
+plugins:
+
+  # - name
+  #
+  # or:
+  # - name: false
+  # - name: true
+  #
+  # or:
+  # - name:
+  #     param1: 1
+  #     param2: 2
+
+- removeAttrs:
+    attrs:
+      - 'fill'
+      - 'fill-rule'

+ 52 - 0
src/layout/components/AppMain.vue

@@ -0,0 +1,52 @@
+<!--
+ * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @Date: 2022-07-01 17:39:58
+ * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @LastEditTime: 2023-06-13 10:29:28
+ * @FilePath: \agentManage\src\layout\components\AppMain.vue
+ * @Description: 
+ * 
+ * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. 
+-->
+<template>
+  <section class="app-main">
+    <transition name="fade-transform" mode="out-in">
+      <keep-alive>
+        <router-view :key="key" />
+      </keep-alive>
+    </transition>
+  </section>
+</template>
+
+<script>
+export default {
+  name: 'AppMain',
+  computed: {
+    key() {
+      return this.$route.path
+    }
+  }
+}
+</script>
+
+<style scoped>
+.app-main {
+  /*50 = navbar  */
+  height: calc(100vh - 50px);
+  width: 100%;
+  position: relative;
+  overflow: auto;
+}
+.fixed-header+.app-main {
+  padding-top: 50px;
+}
+</style>
+
+<style lang="scss">
+// fix css style bug in open el-dialog
+.el-popup-parent--hidden {
+  .fixed-header {
+    padding-right: 15px;
+  }
+}
+</style>

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

@@ -0,0 +1,282 @@
+<template>
+  <div class="navbar">
+    <div class="left-box">
+         <div class="logo-box">
+        <img src="../../assets/icon1.svg" alt="" class="outside">
+        <img src="../../assets/icon2.svg" alt="" class="inside">
+      </div>
+      <div class="title">中数移动</div>
+    </div>
+
+    <div class="right-menu">
+
+
+
+      <i class="iconfont icon-weibiaoti1"></i>
+      <!-- <div class="name">{{name}}</div>
+      <div class="msg-box">
+        <div class="num-icon"  v-if="num">{{num>99?'99+':num}}</div>
+        <i class="iconfont icon-tongzhi4"></i>
+        <div class="menu-box">
+          <div class="title">订单提示</div>
+          <div class="msg" @click="jump">
+            <div class="label">待处理提现申请</div>
+            <div class="value">(<span class="num">{{num}}</span>)</div>
+          </div>
+        </div>
+      </div> -->
+      <i class="iconfont icon-guanji" @click="logout"></i>
+
+      <!-- <el-dropdown class="avatar-container ml10" trigger="click">
+        <div class="avatar-wrapper">
+          <img src="https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif?imageView2/1/w/80/h/80" class="user-avatar">
+          <i class="el-icon-caret-bottom" />
+        </div>
+        <el-dropdown-menu slot="dropdown" class="user-dropdown">
+          <router-link to="/">
+            <el-dropdown-item>
+              首页
+            </el-dropdown-item>
+          </router-link>
+          <el-dropdown-item divided @click.native="logout">
+            <span style="display:block;">登出</span>
+          </el-dropdown-item>
+        </el-dropdown-menu>
+      </el-dropdown> -->
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+import Breadcrumb from '@/components/Breadcrumb'
+import Hamburger from '@/components/Hamburger'
+// import { withdrawApplyType} from '@/api/withdraw'
+export default {
+  components: {
+    Breadcrumb,
+    Hamburger
+  },
+  data() {
+    return {
+      num:0,
+      timer:null,
+    }
+  },
+  computed: {
+    ...mapGetters([
+      'sidebar',
+      'avatar'
+    ]),
+    name(){
+      return localStorage.getItem('name')
+    }
+  },
+  watch: {
+    $route(newValue, oldValue) {
+      // this.withdrawApplyType()
+    }
+  },
+  created () {
+    // this.withdrawApplyType()
+  },
+
+  methods: {
+    jump(){
+      this.$router.push({
+        path:'/financeManage/withdrawApply',
+        query:{
+          type:2
+        }
+      })
+    },
+    logout() {
+       this.$confirm('确定要退出登录吗?', '退出确认', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          this.$store.dispatch('user/logout')
+          this.$router.push(`/login?redirect=${this.$route.fullPath}`)
+        })
+    },
+    withdrawApplyType(){
+      withdrawApplyType().then(res=>{
+        if(res.code == 200){
+          this.num = res.data.pending
+        }
+      })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.navbar {
+  height: 50px;
+  // overflow: hidden;
+  position: relative;
+  background: #464c5be5;
+  box-shadow: 0 1px 4px rgba(0,21,41,.08);
+  padding: 0 10px;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  .left-box{
+    display: flex;
+    align-items: center;
+
+    .logo-box{
+      position: relative;
+      width: 50px;
+      height: 50px;
+      .outside{
+        position: absolute;
+        top: 0;
+        left: 0;
+        right: 0;
+        bottom: 0;
+        margin: auto;
+        width: 30px;
+      }
+      .inside {
+        position: absolute;
+        top: 0;
+        left: 0;
+        right: 0;
+        bottom: 0;
+        margin: auto;
+        width: 20px;
+      }
+    }
+    .title{
+      color: #fff;
+      font-size: 18px;
+      font-weight: 600;
+    }
+  }
+
+  .right-menu {
+    height: 100%;
+    line-height: 50px;
+    display: flex;
+    align-items: center;
+    margin-right: 40px;
+      color: #fff;
+      .name{
+        font-size: 12px;
+      }
+      .iconfont{
+        font-size: 20px;
+        padding: 0 10px;
+      }
+      .icon-guanji{
+        cursor: pointer;
+      }
+      .msg-box{
+        position: relative;
+        padding: 0 15px;
+        .num-icon{
+          position: absolute;
+          top: 0;
+          left: 50%;
+          transform: translate(2%,30%);
+          // width: 20px;
+          height: 18px;
+          padding: 0 5px;
+          border-radius: 9px;
+          background: #f04844;
+          line-height: 18px;
+          font-size: 12px;
+          text-align: center;
+        }
+        .menu-box{
+          display: none;
+          position: absolute;
+          top: 99%;
+          left: 50%;
+          transform: translate(-70%);
+          width: 300px;
+          padding: 15px;
+          border-radius: 4px;
+          box-shadow: 0 1px 4px rgba(0,21,41,.08);
+          background: #fff;
+          z-index: 9;
+          font-size: 12px;
+          .title{
+            color: #999;
+          }
+          .msg{
+            color: #666;
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+            cursor: pointer;
+            .label{
+            }
+            .num{
+              color: #f04844;
+            }
+            .value{
+            }
+          }
+          .msg:hover{
+            .label{
+              color: #1abc9c;
+            }
+          }
+        }
+      }
+      .msg-box:hover .menu-box{
+        display: block;
+      }
+
+
+    &:focus {
+      outline: none;
+    }
+
+    .right-menu-item {
+      display: inline-block;
+      padding: 0 8px;
+      height: 100%;
+      font-size: 18px;
+      color: #5a5e66;
+      vertical-align: text-bottom;
+
+      &.hover-effect {
+        cursor: pointer;
+        transition: background .3s;
+
+        &:hover {
+          background: rgba(0, 0, 0, .025)
+        }
+      }
+    }
+
+    .avatar-container {
+      margin-right: 30px;
+
+      .avatar-wrapper {
+        margin-top: 5px;
+        position: relative;
+
+        .user-avatar {
+          cursor: pointer;
+          width: 40px;
+          height: 40px;
+          border-radius: 10px;
+        }
+
+        .el-icon-caret-bottom {
+          cursor: pointer;
+          position: absolute;
+          right: -20px;
+          top: 25px;
+          font-size: 12px;
+        }
+      }
+    }
+  }
+}
+</style>

+ 26 - 0
src/layout/components/Sidebar/FixiOSBug.js

@@ -0,0 +1,26 @@
+export default {
+  computed: {
+    device() {
+      return this.$store.state.app.device
+    }
+  },
+  mounted() {
+    // In order to fix the click on menu on the ios device will trigger the mouseleave bug
+    // https://github.com/PanJiaChen/vue-element-admin/issues/1135
+    this.fixBugIniOS()
+  },
+  methods: {
+    fixBugIniOS() {
+      const $subMenu = this.$refs.subMenu
+      if ($subMenu) {
+        const handleMouseleave = $subMenu.handleMouseleave
+        $subMenu.handleMouseleave = (e) => {
+          if (this.device === 'mobile') {
+            return
+          }
+          handleMouseleave(e)
+        }
+      }
+    }
+  }
+}

+ 42 - 0
src/layout/components/Sidebar/Item.vue

@@ -0,0 +1,42 @@
+<script>
+export default {
+  name: 'MenuItem',
+  functional: true,
+  props: {
+    icon: {
+      type: String,
+      default: ''
+    },
+    title: {
+      type: String,
+      default: ''
+    }
+  },
+  render(h, context) {
+    const { icon, title } = context.props
+    const vnodes = []
+
+    if (icon) {
+      if (icon.includes('el-icon')) {
+        vnodes.push(<i class={[icon, 'sub-el-icon']} />)
+      }else {
+        vnodes.push(<i class={[icon, 'iconfont sub-el-icon']} />)
+      }
+      
+    }
+
+    if (title) {
+      vnodes.push(<span slot='title'>{(title)}</span>)
+    }
+    return vnodes
+  }
+}
+</script>
+
+<style scoped>
+.sub-el-icon {
+  color: currentColor;
+  width: 1em;
+  height: 1em;
+}
+</style>

+ 43 - 0
src/layout/components/Sidebar/Link.vue

@@ -0,0 +1,43 @@
+<template>
+  <component :is="type" v-bind="linkProps(to)">
+    <slot />
+  </component>
+</template>
+
+<script>
+import { isExternal } from '@/utils/validate'
+
+export default {
+  props: {
+    to: {
+      type: String,
+      required: true
+    }
+  },
+  computed: {
+    isExternal() {
+      return isExternal(this.to)
+    },
+    type() {
+      if (this.isExternal) {
+        return 'a'
+      }
+      return 'router-link'
+    }
+  },
+  methods: {
+    linkProps(to) {
+      if (this.isExternal) {
+        return {
+          href: to,
+          target: '_blank',
+          rel: 'noopener'
+        }
+      }
+      return {
+        to: to
+      }
+    }
+  }
+}
+</script>

+ 82 - 0
src/layout/components/Sidebar/Logo.vue

@@ -0,0 +1,82 @@
+<template>
+  <div class="sidebar-logo-container" :class="{'collapse':collapse}">
+    <transition name="sidebarLogoFade">
+      <router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
+        <img v-if="logo" :src="logo" class="sidebar-logo">
+        <h1 v-else class="sidebar-title">{{ title }} </h1>
+      </router-link>
+      <router-link v-else key="expand" class="sidebar-logo-link" to="/">
+        <img v-if="logo" :src="logo" class="sidebar-logo">
+        <h1 class="sidebar-title">{{ title }} </h1>
+      </router-link>
+    </transition>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'SidebarLogo',
+  props: {
+    collapse: {
+      type: Boolean,
+      required: true
+    }
+  },
+  data() {
+    return {
+      title: 'Vue Admin Template',
+      logo: 'https://wpimg.wallstcn.com/69a1c46c-eb1c-4b46-8bd4-e9e686ef5251.png'
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.sidebarLogoFade-enter-active {
+  transition: opacity 1.5s;
+}
+
+.sidebarLogoFade-enter,
+.sidebarLogoFade-leave-to {
+  opacity: 0;
+}
+
+.sidebar-logo-container {
+  position: relative;
+  width: 100%;
+  height: 50px;
+  line-height: 50px;
+  background: #2b2f3a;
+  text-align: center;
+  overflow: hidden;
+
+  & .sidebar-logo-link {
+    height: 100%;
+    width: 100%;
+
+    & .sidebar-logo {
+      width: 32px;
+      height: 32px;
+      vertical-align: middle;
+      margin-right: 12px;
+    }
+
+    & .sidebar-title {
+      display: inline-block;
+      margin: 0;
+      color: #fff;
+      font-weight: 600;
+      line-height: 50px;
+      font-size: 14px;
+      font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
+      vertical-align: middle;
+    }
+  }
+
+  &.collapse {
+    .sidebar-logo {
+      margin-right: 0px;
+    }
+  }
+}
+</style>

+ 95 - 0
src/layout/components/Sidebar/SidebarItem.vue

@@ -0,0 +1,95 @@
+<template>
+  <div v-if="!item.hidden">
+    <template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">
+      <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)">
+        <el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}">
+          <item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="onlyOneChild.meta.title" />
+        </el-menu-item>
+      </app-link>
+    </template>
+
+    <el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body>
+      <template slot="title">
+        <item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" />
+      </template>
+      <sidebar-item
+        v-for="child in item.children"
+        :key="child.path"
+        :is-nest="true"
+        :item="child"
+        :base-path="resolvePath(child.path)"
+        class="nest-menu"
+      />
+    </el-submenu>
+  </div>
+</template>
+
+<script>
+import path from 'path'
+import { isExternal } from '@/utils/validate'
+import Item from './Item'
+import AppLink from './Link'
+import FixiOSBug from './FixiOSBug'
+
+export default {
+  name: 'SidebarItem',
+  components: { Item, AppLink },
+  mixins: [FixiOSBug],
+  props: {
+    // route object
+    item: {
+      type: Object,
+      required: true
+    },
+    isNest: {
+      type: Boolean,
+      default: false
+    },
+    basePath: {
+      type: String,
+      default: ''
+    }
+  },
+  data() {
+    // To fix https://github.com/PanJiaChen/vue-admin-template/issues/237
+    // TODO: refactor with render function
+    this.onlyOneChild = null
+    return {}
+  },
+  methods: {
+    hasOneShowingChild(children = [], parent) {
+      const showingChildren = children.filter(item => {
+        if (item.hidden) {
+          return false
+        } else {
+          // Temp set(will be used if only has one showing child)
+          this.onlyOneChild = item
+          return true
+        }
+      })
+
+      // When there is only one child router, the child router is displayed by default
+      if (showingChildren.length === 1) {
+        return true
+      }
+
+      // Show parent if there are no child router to display
+      if (showingChildren.length === 0) {
+        this.onlyOneChild = { ... parent, path: '', noShowingChildren: true }
+        return true
+      }
+
+      return false
+    },
+    resolvePath(routePath) {
+      if (isExternal(routePath)) {
+        return routePath
+      }
+      if (isExternal(this.basePath)) {
+        return this.basePath
+      }
+      return path.resolve(this.basePath, routePath)
+    }
+  }
+}
+</script>

+ 58 - 0
src/layout/components/Sidebar/index.vue

@@ -0,0 +1,58 @@
+<template>
+  <div :class="{'has-logo':showLogo}">
+    <logo v-if="showLogo" :collapse="isCollapse" />
+    <el-scrollbar wrap-class="scrollbar-wrapper">
+      <el-menu
+        :default-active="activeMenu"
+        :collapse="false"
+        :background-color="variables.menuBg"
+        :text-color="variables.menuText"
+        :unique-opened="true"
+        :active-text-color="variables.menuActiveText"
+        :collapse-transition="false"
+        mode="vertical"
+      >
+        <sidebar-item v-for="route in 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'
+
+export default {
+  components: { SidebarItem, Logo },
+  computed: {
+    ...mapGetters([
+      'sidebar','menus'
+    ]),
+    routes() {
+      return this.$router.options.routes
+    },
+    activeMenu() {
+      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 path
+    },
+    showLogo() {
+      return this.$store.state.settings.sidebarLogo
+    },
+    variables() {
+      return variables
+    },
+    isCollapse() {
+      return !this.sidebar.opened
+    }
+  },
+  created () {
+  },
+}
+</script>

+ 3 - 0
src/layout/components/index.js

@@ -0,0 +1,3 @@
+export { default as Navbar } from './Navbar'
+export { default as Sidebar } from './Sidebar'
+export { default as AppMain } from './AppMain'

+ 93 - 0
src/layout/index.vue

@@ -0,0 +1,93 @@
+<template>
+  <div :class="classObj" class="app-wrapper">
+        <navbar />
+    <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
+    <sidebar class="sidebar-container" />
+    <div class="main-container">
+      <div :class="{'fixed-header':fixedHeader}">
+      </div>
+      <app-main />
+    </div>
+  </div>
+</template>
+
+<script>
+import { Navbar, Sidebar, AppMain } from './components'
+import ResizeMixin from './mixin/ResizeHandler'
+
+export default {
+  name: 'Layout',
+  components: {
+    Navbar,
+    Sidebar,
+    AppMain
+  },
+  mixins: [ResizeMixin],
+  computed: {
+    sidebar() {
+      return this.$store.state.app.sidebar
+    },
+    device() {
+      return this.$store.state.app.device
+    },
+    fixedHeader() {
+      return this.$store.state.settings.fixedHeader
+    },
+    classObj() {
+      return {
+        // hideSidebar: !this.sidebar.opened,
+        // openSidebar: this.sidebar.opened,
+        withoutAnimation: this.sidebar.withoutAnimation,
+        // mobile: this.device === 'mobile'
+      }
+    }
+  },
+  methods: {
+    handleClickOutside() {
+      this.$store.dispatch('closeSideBar', { withoutAnimation: false })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+  @import "~@/styles/mixin.scss";
+  @import "~@/styles/variables.scss";
+
+  .app-wrapper {
+    @include clearfix;
+    position: relative;
+    height: 100%;
+    width: 100%;
+    &.mobile.openSidebar{
+      position: fixed;
+      top: 0;
+    }
+  }
+  .drawer-bg {
+    background: #000;
+    opacity: 0.3;
+    width: 100%;
+    top: 0;
+    height: 100%;
+    position: absolute;
+    z-index: 999;
+  }
+
+  .fixed-header {
+    position: fixed;
+    top: 0;
+    right: 0;
+    z-index: 9;
+    width: calc(100% - #{$sideBarWidth});
+    transition: width 0.28s;
+  }
+
+  .hideSidebar .fixed-header {
+    width: calc(100% - 54px)
+  }
+
+  .mobile .fixed-header {
+    width: 100%;
+  }
+</style>

+ 45 - 0
src/layout/mixin/ResizeHandler.js

@@ -0,0 +1,45 @@
+import store from '@/store'
+
+const { body } = document
+const WIDTH = 992 // refer to Bootstrap's responsive design
+
+export default {
+  watch: {
+    $route(route) {
+      if (this.device === 'mobile' && this.sidebar.opened) {
+        store.dispatch('closeSideBar', { withoutAnimation: false })
+      }
+    }
+  },
+  beforeMount() {
+    window.addEventListener('resize', this.$_resizeHandler)
+  },
+  beforeDestroy() {
+    window.removeEventListener('resize', this.$_resizeHandler)
+  },
+  mounted() {
+    const isMobile = this.$_isMobile()
+    if (isMobile) {
+      store.dispatch('toggleDevice', 'mobile')
+      store.dispatch('closeSideBar', { withoutAnimation: true })
+    }
+  },
+  methods: {
+    // use $_ for mixins properties
+    // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
+    $_isMobile() {
+      const rect = body.getBoundingClientRect()
+      return rect.width - 1 < WIDTH
+    },
+    $_resizeHandler() {
+      if (!document.hidden) {
+        const isMobile = this.$_isMobile()
+        store.dispatch('toggleDevice', isMobile ? 'mobile' : 'desktop')
+
+        if (isMobile) {
+          store.dispatch('closeSideBar', { withoutAnimation: true })
+        }
+      }
+    }
+  }
+}

+ 64 - 0
src/main.js

@@ -0,0 +1,64 @@
+/*
+ * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @Date: 2022-06-29 15:28:34
+ * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @LastEditTime: 2023-06-16 15:56:24
+ * @FilePath: \agentManage\src\main.js
+ * @Description: 
+ * 
+ * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. 
+ */
+import Vue from 'vue'
+
+import 'normalize.css/normalize.css' // A modern alternative to CSS resets
+
+import ElementUI from 'element-ui'
+import './styles/element-variables.scss'
+// import locale from 'element-ui/lib/locale/lang/en' // lang i18n
+import './assets/font/iconfont.css'
+import '@/styles/index.scss' // global css
+import echarts from "echarts";
+Vue.prototype.$echarts = echarts;
+
+
+import App from './App'
+import store from './store'
+import router from './router'
+
+import '@/icons' // icon
+import '@/permission' // permission control
+
+import TabCard from '@/components/TabCard'
+Vue.use(TabCard)
+
+import TopBar from '@/components/TopBar'
+Vue.use(TopBar)
+
+import Title from '@/components/Title'
+Vue.use(Title)
+/**
+ * If you don't want to use mock-server
+ * you want to use MockJs for mock api
+ * you can execute: mockXHR()
+ *
+ * Currently MockJs will be used in the production environment,
+ * please remove it before going online ! ! !
+ */
+// if (process.env.NODE_ENV === 'production') {
+//   const { mockXHR } = require('../mock')
+//   mockXHR()
+// }
+
+// set ElementUI lang to EN
+// Vue.use(ElementUI, { locale })
+// 如果想要中文版 element-ui,按如下方式声明
+Vue.use(ElementUI)
+
+Vue.config.productionTip = false
+
+new Vue({
+  el: '#app',
+  router,
+  store,
+  render: h => h(App)
+})

+ 85 - 0
src/permission.js

@@ -0,0 +1,85 @@
+/*
+ * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @Date: 2022-08-02 18:10:30
+ * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @LastEditTime: 2023-08-16 09:37:27
+ * @FilePath: \agentManage\src\permission.js
+ * @Description: 
+ * 
+ * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. 
+ */
+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 Layout from '@/layout'
+import { getMenu } from '@/api/menu'
+NProgress.configure({ showSpinner: false }) // NProgress Configuration
+
+const whiteList = ['/login'] // no redirect whitelist
+
+router.beforeEach((to, from, next) => {
+  // start progress bar
+  NProgress.start()
+
+  // set page title
+  document.title = getPageTitle(to.meta.title)
+  // console.log(constantRoutes);
+  // determine whether the user has logged in
+  const hasToken = getToken()
+  if (hasToken ) {
+    if (to.path === '/login') {
+      // if is logged in, redirect to the home page
+      next({ path: '/' })
+      NProgress.done()
+    } else {
+      next()
+      NProgress.done()
+      // const hasGetUserInfo = store.getters.menu
+      // if (store.getters.menus) {
+      //   next()
+      // } else {
+      //   try {
+      //     // 获取用户信息
+      //     store.dispatch('user/getMenu').then(res=>{
+      //       // res.push({ path: '*', redirect: '/404', hidden: true })
+
+      //       router.addRoutes(res)
+            
+      //       next({ ...to, replace: true })
+      //     })
+      //     // let asyncRouterMap = asyncRouter
+
+
+      //   } 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()
+      //   }
+      // }
+
+    }
+  } else {
+    /* has no token*/
+    if (whiteList.indexOf(to.path) !== -1) {
+      // in the free login whitelist, go directly
+      next()
+
+    } else {
+      // other pages that do not have permission to access are redirected to the login page.
+      next(`/login?redirect=${to.path}`)
+      NProgress.done()
+    }
+  }
+})
+
+router.afterEach(() => {
+  // finish progress bar
+  NProgress.done()
+})
+ 

+ 497 - 0
src/router/index.js

@@ -0,0 +1,497 @@
+import Vue from 'vue'
+import Router from 'vue-router'
+
+Vue.use(Router)
+
+/* Layout */
+import Layout from '@/layout'
+
+/**
+ * Note: sub-menu only appear when route children.length >= 1
+ * Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html
+ *
+ * hidden: true                   if set true, item will not show in the sidebar(default is false)
+ * alwaysShow: true               if set true, will always show the root menu
+ *                                if not set alwaysShow, when item has more than one children route,
+ *                                it will becomes nested mode, otherwise not show the root menu
+ * redirect: noRedirect           if set noRedirect will no redirect in the breadcrumb
+ * name:'router-name'             the name is used by <keep-alive> (must set!!!)
+ * meta : {
+    roles: ['admin','editor']    control the page roles (you can set multiple roles)
+    title: 'title'               the name show in sidebar and breadcrumb (recommend set)
+    icon: 'svg-name'/'el-icon-x' the icon show in the sidebar
+    breadcrumb: false            if set false, the item will hidden in breadcrumb(default is true)
+    activeMenu: '/example/list'  if set path, the sidebar will highlight the path you set
+  }
+ */
+
+/**
+ * constantRoutes
+ * a base page that does not have permission requirements
+ * all roles can be accessed
+ */
+export let constantRoutes = [
+  {
+    path: '/login',
+    component: () => import('@/views/login/index'),
+    hidden: true
+  },
+  {
+    path: '/404',
+    component: () => import('@/views/404'),
+    hidden: true
+  },
+  {
+    id: 0,
+    path: '/statisticsManage',
+    component: Layout,
+    meta: { title: '中数❤移动', icon: 'icon-shouyefill' },
+    children: [
+      {
+        id: 1,
+        path: '/statisticsManage',
+        name: '/statisticsManage',
+        component: () => import('@/views/statisticsManage/index.vue'),
+        meta: { title: '中数❤移动', icon: '' },
+      },
+     
+    ]
+  },
+  {
+    id: 0,
+    path: '/',
+    component: Layout,
+    redirect: '/home',
+    meta: { title: '系统首页', icon: 'icon-shouyefill' },
+    alwaysShow: true,
+    children: [
+      {
+        id: 1,
+        path: '/home',
+        name: '/home',
+        component: () => import('@/views/home/index.vue'),
+        meta: { title: '系统首页', icon: '' },
+      },
+     
+    ]
+  },
+  {
+    id: 36,
+    path: '/adminManage',
+    component: Layout,
+    meta: { title: '账号管理', icon: 'el-icon-user-solid' },
+    alwaysShow: true,
+    children: [
+      {
+        id: 37,
+        path: '/adminManage/adminList',
+        name: '/adminManage/adminList',
+        component: () => import('@/views/adminManage/adminList.vue'),
+        meta: { title: '账号列表', icon: '' },
+      },
+      {
+        id: 37,
+        path: '/adminManage/adminDetail',
+        name: '/adminManage/adminDetail',
+        hidden: true , 
+        component: () => import('@/views/adminManage/adminDetail.vue'),
+        meta: { title: '账号详情', icon: '',activeMenu:'/adminManage/adminList' },
+      },
+      {
+        id: 37,
+        path: '/adminManage/adminAdd',
+        name: '/adminManage/adminAdd',
+        hidden: true , 
+        component: () => import('@/views/adminManage/adminAdd.vue'),
+        meta: { title: '人员添加', icon: '',activeMenu:'/adminManage/adminList' },
+      },
+    ]
+  },
+  {
+    id: 0,
+    path: '/shopManage/index',
+    component: Layout,
+    meta: { title: '商铺管理', icon: 'el-icon-s-shop' },
+    alwaysShow: true,
+    children: [
+      {
+        id: 1,
+        path: '/shopManage/index',
+        name: '/shopManage/index',
+        component: () => import('@/views/shopManage/index.vue'),
+        meta: { title: '商铺列表', icon: '' },
+      },
+      {
+        id: 1,
+        path: '/shopManage/shopDetail',
+        name: '/shopManage/shopDetail',
+        hidden: true , 
+        component: () => import('@/views/shopManage/shopDetail.vue'),
+        meta: { title: '商铺详情', icon: '',activeMenu:'/shopManage/index' },
+      },
+      {
+        id: 1,
+        path: '/shopManage/shopAdd',
+        name: '/shopManage/shopAdd',
+        component: () => import('@/views/shopManage/shopAdd.vue'),
+        meta: { title: '商铺添加'},
+      }
+    ]
+  },
+  {
+    id: 0,
+    path: '/goodsManage/index',
+    component: Layout,
+    meta: { title: '商品管理', icon: 'el-icon-s-goods' },
+    alwaysShow: true,
+    children: [
+      {
+        id: 1,
+        path: '/goodsManage/index',
+        name: '/goodsManage/index',
+        component: () => import('@/views/goodsManage/index.vue'),
+        meta: { title: '商品列表', icon: '' },
+      },
+      
+    ]
+  },
+  {
+    id: 0,
+    path: '/orderManage/orderList',
+    component: Layout,
+    meta: { title: '订单管理', icon: 'el-icon-s-goods' },
+    alwaysShow: true,
+    children: [
+      {
+        id: 1,
+        path: '/orderManage/orderList',
+        name: '/orderManage/orderList',
+        component: () => import('@/views/orderManage/orderList.vue'),
+        meta: { title: '订单列表', icon: '' },
+      },
+      {
+        id: 1,
+        path: '/orderManage/detail',
+        name: '/orderManage/detail',
+        component: () => import('@/views/orderManage/detail.vue'),
+        meta: { title: '订单详情', icon: '' },
+      },
+    ]
+  },
+  {
+    id: 0,
+    path: '/afterSales/afterSalesList',
+    component: Layout,
+    meta: { title: '售后管理', icon: 'el-icon-s-goods' },
+    alwaysShow: true,
+    children: [
+      {
+        id: 1,
+        path: '/afterSales/afterSalesList',
+        name: '/afterSales/afterSalesList',
+        component: () => import('@/views/afterSales/afterSalesList.vue'),
+        meta: { title: '售后列表', icon: '' },
+      },
+      {
+        id: 1,
+        path: '/afterSales/detail',
+        name: '/afterSales/detail',
+        component: () => import('@/views/afterSales/detail.vue'),
+        meta: { title: '售后详情', icon: '' },
+      },
+    ]
+  },
+  // {
+  //   id: 3,
+  //   path: '/announcementManage',
+  //   component: Layout,
+  //   meta: { title: '公告管理', icon: 'icon-xinwen' },
+  //   alwaysShow: true,
+  //   children: [
+  //     {
+  //       id: 4,
+  //       path: '/announcementManage',
+  //       name: '/announcementManage',
+  //       component: () => import('@/views/announcementManage/index.vue'),
+  //       meta: { title: '公告列表', icon: '' },
+  //     },
+  //     {
+  //       id: 5,
+  //       path: '/announcementManage/addAnnouncement',
+  //       name: '/announcementManage/addAnnouncement',
+  //       component: () => import('@/views/announcementManage/addAnnouncement.vue'),
+  //       meta: { title: '发布公告', icon: '', activeMenu: '/announcementManage' },
+  //       hidden: true
+  //     },
+  //   ]
+  // },
+  // {
+  //   id: 6,
+  //   path: '/emailManage',
+  //   component: Layout,
+  //   meta: { title: '邮件管理', icon: 'icon-duanxinyingxiao' },
+  //   alwaysShow: true,
+  //   children: [
+  //     {
+  //       id: 7,
+  //       path: '/emailManage',
+  //       name: '/emailManage',
+  //       component: () => import('@/views/emailManage/index.vue'),
+  //       meta: { title: '邮件列表', icon: '' },
+  //     },
+  //     {
+  //       id: 8,
+  //       path: '/emailManage/sendEmail',
+  //       name: '/emailManage/sendEmail',
+  //       component: () => import('@/views/emailManage/sendEmail.vue'),
+  //       meta: { title: '发送邮件', icon: '', activeMenu: '/emailManage' },
+  //       hidden: true
+  //     },
+  //   ]
+  // },
+  // {
+  //   id: 9,
+  //   path: '/articleManage',
+  //   component: Layout,
+  //   meta: { title: '文章管理', icon: 'icon-bianjiwenzhang_huaban' },
+  //   alwaysShow: true,
+  //   children: [
+  //     {
+  //       id: 10,
+  //       path: '/articleManage',
+  //       name: '/articleManage',
+  //       component: () => import('@/views/articleManage/index.vue'),
+  //       meta: { title: '游戏攻略', icon: '' },
+  //     },
+  //   ]
+  // },
+  // {
+  //   id: 11,
+  //   path: '/memberManage',
+  //   component: Layout,
+  //   meta: { title: '会员管理', icon: 'icon-guanliyuan_jiaoseguanli' },
+  //   alwaysShow: true,
+  //   children: [
+  //     {
+  //       id: 12,
+  //       path: '/memberManage/memberList',
+  //       name: '/memberManage/memberList',
+  //       component: () => import('@/views/memberManage/memberList.vue'),
+  //       meta: { title: '会员列表', icon: '' },
+  //     },
+  //     {
+  //       id: 13,
+  //       path: '/memberManage/memberDetail',
+  //       name: '/memberManage/memberDetail',
+  //       component: () => import('@/views/memberManage/memberDetail.vue'),
+  //       meta: { title: '会员详情', icon: '', activeMenu: '/memberManage/memberList' },
+  //       hidden: true
+  //     },
+  //     {
+  //       id: 14,
+  //       path: '/memberManage/diamondIncome',
+  //       name: '/memberManage/diamondIncome',
+  //       component: () => import('@/views/memberManage/diamondIncome.vue'),
+  //       meta: { title: '黑钻收支明细', icon: '' },
+  //     },
+  //     {
+  //       id: 15,
+  //       path: '/memberManage/rebateList',
+  //       name: '/memberManage/rebateList',
+  //       component: () => import('@/views/memberManage/rebateList.vue'),
+  //       meta: { title: '返佣查询', icon: '' },
+  //     },
+  //     {
+  //       id: 16,
+  //       path: '/memberManage/rebateDetail',
+  //       name: '/memberManage/rebateDetail',
+  //       component: () => import('@/views/memberManage/rebateDetail.vue'),
+  //       meta: { title: '返佣明细', icon: '', activeMenu: '/memberManage/rebateList' },
+  //       hidden: true
+  //     },
+  //     {
+  //       id: 17,
+  //       path: '/memberManage/earningsDetail',
+  //       name: '/memberManage/earningsDetail',
+  //       component: () => import('@/views/memberManage/earningsDetail.vue'),
+  //       meta: { title: '产生收益明细', icon: '', activeMenu: '/memberManage/rebateList' },
+  //       hidden: true
+  //     },
+  //     {
+  //       id: 41,
+  //       path: '/memberManage/history',
+  //       name: '/memberManage/history',
+  //       component: () => import('@/views/memberManage/history.vue'),
+  //       meta: { title: '礼包领取记录', icon: '', },
+  //     },
+  //   ]
+  // },
+  // {
+  //   id: 18,
+  //   path: '/gameManage',
+  //   component: Layout,
+  //   meta: { title: '游戏管理', icon: 'icon-youxi' },
+  //   alwaysShow: true,
+  //   children: [
+  //     {
+  //       id: 19,
+  //       path: '/gameManage/kittyLevel',
+  //       name: '/gameManage/kittyLevel',
+  //       component: () => import('@/views/gameManage/kittyLevel.vue'),
+  //       meta: { title: '猫咪品级管理', icon: '' },
+  //     },
+  //     {
+  //       id: 20,
+  //       path: '/gameManage/kittyMarket',
+  //       name: '/gameManage/kittyMarket',
+  //       component: () => import('@/views/gameManage/kittyMarket.vue'),
+  //       meta: { title: '猫市列表', icon: '' },
+  //     },
+  //     {
+  //       id: 21,
+  //       path: '/gameManage/cattery',
+  //       name: '/gameManage/cattery',
+  //       component: () => import('@/views/gameManage/cattery.vue'),
+  //       meta: { title: '猫窝管理', icon: '' },
+  //     },
+  //     {
+  //       id: 22,
+  //       path: '/gameManage/propManage',
+  //       name: '/gameManage/propManage',
+  //       component: () => import('@/views/gameManage/propManage.vue'),
+  //       meta: { title: '道具管理', icon: '' },
+  //     },
+  //     {
+  //       id: 23,
+  //       path: '/gameManage/goodsManage',
+  //       name: '/gameManage/goodsManage',
+  //       component: () => import('@/views/gameManage/goodsManage.vue'),
+  //       meta: { title: '物品管理', icon: '' },
+  //     },
+  //     {
+  //       id: 24,
+  //       path: '/gameManage/dailyGift',
+  //       name: '/gameManage/dailyGift',
+  //       component: () => import('@/views/gameManage/dailyGift.vue'),
+  //       meta: { title: '每日礼包', icon: '' },
+  //     },
+  //     {
+  //       id: 25,
+  //       path: '/gameManage/gameSetting',
+  //       name: '/gameManage/gameSetting',
+  //       component: () => import('@/views/gameManage/gameSetting.vue'),
+  //       meta: { title: '游戏设置', icon: '' },
+  //     },
+  //   ]
+  // },
+  // {
+  //   id: 26,
+  //   path: '/stateManage',
+  //   component: Layout,
+  //   meta: { title: '报表统计', icon: 'icon-baobiao' },
+  //   alwaysShow: true,
+  //   children: [
+  //     {
+  //       id: 27,
+  //       path: '/stateManage/businessReport',
+  //       name: '/stateManage/businessReport',
+  //       component: () => import('@/views/stateManage/businessReport.vue'),
+  //       meta: { title: '业务报表', icon: '' },
+  //     },
+  //     {
+  //       id: 28,
+  //       path: '/stateManage/agentList',
+  //       name: '/stateManage/agentList',
+  //       component: () => import('@/views/stateManage/agentList.vue'),
+  //       meta: { title: '业务报表(代理)', icon: '', activeMenu: '/stateManage/businessReport' },
+  //       hidden: true
+  //     },
+  //     {
+  //       id: 29,
+  //       path: '/stateManage/groupLeader',
+  //       name: '/stateManage/groupLeader',
+  //       component: () => import('@/views/stateManage/groupLeader.vue'),
+  //       meta: { title: '业务报表(组长)', icon: '', activeMenu: '/stateManage/businessReport' },
+  //       hidden: true
+  //     },
+  //     {
+  //       id: 30,
+  //       path: '/stateManage/groupMembers',
+  //       name: '/stateManage/groupMembers',
+  //       component: () => import('@/views/stateManage/groupMembers.vue'),
+  //       meta: { title: '业务报表(组员)', icon: '', activeMenu: '/stateManage/businessReport' },
+  //       hidden: true
+  //     },
+  //     {
+  //       id: 31,
+  //       path: '/stateManage/memberList',
+  //       name: '/stateManage/memberList',
+  //       component: () => import('@/views/stateManage/memberList.vue'),
+  //       meta: { title: '查看明细', icon: '', activeMenu: '/stateManage/businessReport' },
+  //       hidden: true
+  //     },
+  //     {
+  //       id: 32,
+  //       path: '/stateManage/memberStatistics',
+  //       name: '/stateManage/memberStatistics',
+  //       component: () => import('@/views/stateManage/memberStatistics.vue'),
+  //       meta: { title: '会员每日统计', icon: '', },
+  //     },
+  //   ]
+  // },
+  // {
+  //   id: 33,
+  //   path: '/financeManage',
+  //   component: Layout,
+  //   meta: { title: '财务管理', icon: 'icon-caidancaiwu' },
+  //   alwaysShow: true,
+  //   children: [
+  //     {
+  //       id: 34,
+  //       path: '/financeManage/withdrawApply',
+  //       name: '/financeManage/withdrawApply',
+  //       component: () => import('@/views/financeManage/withdrawApply.vue'),
+  //       meta: { title: '提现申请', icon: '' },
+  //     },
+  //     // {
+  //     //   id: 35,
+  //     //   path: '/financeManage/serviceCharge',
+  //     //   name: '/financeManage/serviceCharge',
+  //     //   component: () => import('@/views/financeManage/serviceCharge.vue'),
+  //     //   meta: { title: '提现手续费设置', icon: '' },
+  //     // },
+  //     {
+  //       id: 40,
+  //       path: '/financeManage/userRecharge',
+  //       name: '/financeManage/userRecharge',
+  //       component: () => import('@/views/financeManage/userRecharge.vue'),
+  //       meta: { title: '充值列表', icon: '' },
+  //     },
+  //   ]
+  // },
+  
+
+  // 404 page must be placed at the end !!!
+  // { path: '*', redirect: '/404', hidden: true }
+]
+
+export const asyncRouter = [
+ 
+
+]
+
+const createRouter = () => new Router({
+  // mode: 'history', // require service support
+  scrollBehavior: () => ({ y: 0 }),
+  routes: constantRoutes
+})
+
+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
+}
+
+export default router

+ 26 - 0
src/settings.js

@@ -0,0 +1,26 @@
+/*
+ * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @Date: 2022-08-04 17:24:52
+ * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @LastEditTime: 2023-06-01 16:43:17
+ * @FilePath: \agentManage\src\settings.js
+ * @Description: 
+ * 
+ * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. 
+ */
+module.exports = {
+
+  title: '中数生活宝',
+
+  /**
+   * @type {boolean} true | false
+   * @description Whether fix the header
+   */
+  fixedHeader: false,
+
+  /**
+   * @type {boolean} true | false
+   * @description Whether show the logo in sidebar
+   */
+  sidebarLogo: false
+}

+ 10 - 0
src/store/getters.js

@@ -0,0 +1,10 @@
+const getters = {
+  sidebar: state => state.app.sidebar,
+  device: state => state.app.device,
+  token: state => state.user.token,
+  refreshToken: state => state.user.refreshToken,
+  avatar: state => state.user.avatar,
+  menus: state => state.user.menus,
+  name: state => state.user.name
+}
+export default getters

+ 19 - 0
src/store/index.js

@@ -0,0 +1,19 @@
+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'
+
+Vue.use(Vuex)
+
+const store = new Vuex.Store({
+  modules: {
+    app,
+    settings,
+    user
+  },
+  getters
+})
+
+export default store

+ 48 - 0
src/store/modules/app.js

@@ -0,0 +1,48 @@
+import Cookies from 'js-cookie'
+
+const state = {
+  sidebar: {
+    opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
+    withoutAnimation: false
+  },
+  device: 'desktop'
+}
+
+const mutations = {
+  TOGGLE_SIDEBAR: state => {
+    state.sidebar.opened = !state.sidebar.opened
+    state.sidebar.withoutAnimation = false
+    if (state.sidebar.opened) {
+      Cookies.set('sidebarStatus', 1)
+    } else {
+      Cookies.set('sidebarStatus', 0)
+    }
+  },
+  CLOSE_SIDEBAR: (state, withoutAnimation) => {
+    Cookies.set('sidebarStatus', 0)
+    state.sidebar.opened = false
+    state.sidebar.withoutAnimation = withoutAnimation
+  },
+  TOGGLE_DEVICE: (state, device) => {
+    state.device = device
+  }
+}
+
+const actions = {
+  toggleSideBar({ commit }) {
+    commit('TOGGLE_SIDEBAR')
+  },
+  closeSideBar({ commit }, { withoutAnimation }) {
+    commit('CLOSE_SIDEBAR', withoutAnimation)
+  },
+  toggleDevice({ commit }, device) {
+    commit('TOGGLE_DEVICE', device)
+  }
+}
+
+export default {
+  namespaced: false,
+  state,
+  mutations,
+  actions
+}

+ 32 - 0
src/store/modules/settings.js

@@ -0,0 +1,32 @@
+import defaultSettings from '@/settings'
+
+const { showSettings, fixedHeader, sidebarLogo } = defaultSettings
+
+const state = {
+  showSettings: showSettings,
+  fixedHeader: fixedHeader,
+  sidebarLogo: sidebarLogo
+}
+
+const mutations = {
+  CHANGE_SETTING: (state, { key, value }) => {
+    // eslint-disable-next-line no-prototype-builtins
+    if (state.hasOwnProperty(key)) {
+      state[key] = value
+    }
+  }
+}
+
+const actions = {
+  changeSetting({ commit }, data) {
+    commit('CHANGE_SETTING', data)
+  }
+}
+
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions
+}
+

+ 122 - 0
src/store/modules/user.js

@@ -0,0 +1,122 @@
+import { login} from '@/api/auth'
+import { getToken, setToken, removeToken,setREToken } from '@/utils/auth'
+import { resetRouter, asyncRouter } from '@/router'
+import { getMenu } from '@/api/menu'
+// import {login} from '@/api/home'
+const getDefaultState = () => {
+  return {
+    token: getToken(),
+    refreshToken:'',
+    name: '',
+    avatar: '',
+    menus:null
+  }
+}
+
+const state = getDefaultState()
+
+const mutations = {
+  RESET_STATE: (state) => {
+    Object.assign(state, getDefaultState())
+  },
+  SET_TOKEN: (state, token) => {
+    state.token = token
+  },
+  REFRESH_TOKEN: (state, token) => {
+    state.refreshToken = token
+  },
+  SET_NAME: (state, name) => {
+    state.name = name
+  },
+  SET_AVATAR: (state, avatar) => {
+    state.avatar = avatar
+  },
+  SET_MENU: (state, menus) => {
+    state.menus = menus
+  }
+}
+
+const actions = {
+  // user login
+  login({ commit }, userInfo) {
+    const { account, password } = userInfo
+    return new Promise((resolve, reject) => {
+      login({ account: account.trim(), pwd: password.trim() }).then(response => {
+        if (response.state == 'Success') {
+          const { content } = response
+          commit('SET_TOKEN', content.access_token)
+          commit('REFRESH_TOKEN', content.refresh_token)
+          setToken(content.access_token)
+          setREToken(content.refresh_token)
+          window.localStorage.setItem('user_type', content.token_type)
+        }
+        resolve()
+      }).catch(error => {
+        reject(error)
+      })
+    })
+  },
+
+  // 获取菜单
+  getMenu({ commit, state }) {
+    return new Promise((resolve, reject) => {
+      getMenu().then(response => {
+        let menuList = response.data.menu
+        let list = asyncRouter
+        let menuIndex = []
+        list.map((menu,d)=>{
+            if(menu.children){
+              let ids = []
+              menu.children.map((item,index)=>{//删除不存在的页面
+                if(menuList.includes(item.id)){
+                  }else{
+                  ids.unshift(index)
+                }
+              })
+              ids.map(i=>{
+                menu.children.splice(i,1)
+              })
+            }
+          if (!menu.children||!menu.children.length){
+              menuIndex.unshift(d)
+            }
+        })
+        menuIndex.map(i=>{
+          list.splice(i,1)
+        })
+        list.push({ path: '*', redirect: '/404', hidden: true })
+        commit('SET_MENU', list)
+        resolve(list)
+      }).catch(error => {
+        reject(error)
+      })
+    })
+  },
+
+  // user logout
+  logout({ commit, state }) {
+    return new Promise((resolve, reject) => {
+        removeToken() // must remove  token  first
+        resetRouter()
+        commit('RESET_STATE')
+        resolve()
+    })
+  },
+
+  // remove token
+  resetToken({ commit }) {
+    return new Promise(resolve => {
+      removeToken() // must remove  token  first
+      commit('RESET_STATE')
+      resolve()
+    })
+  }
+}
+
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions
+}
+

+ 49 - 0
src/styles/element-ui.scss

@@ -0,0 +1,49 @@
+// cover some element-ui styles
+
+.el-breadcrumb__inner,
+.el-breadcrumb__inner a {
+  font-weight: 400 !important;
+}
+
+.el-upload {
+  input[type="file"] {
+    display: none !important;
+  }
+}
+
+.el-upload__input {
+  display: none;
+}
+
+
+// to fixed https://github.com/ElemeFE/element/issues/2461
+.el-dialog {
+  transform: none;
+  left: 0;
+  position: relative;
+  margin: 0 auto;
+}
+
+// refine element ui upload
+.upload-container {
+  .el-upload {
+    width: 100%;
+
+    .el-upload-dragger {
+      width: 100%;
+      height: 200px;
+    }
+  }
+}
+
+// dropdown
+.el-dropdown-menu {
+  a {
+    display: block
+  }
+}
+
+// to fix el-date-picker css style
+.el-range-separator {
+  box-sizing: content-box;
+}

+ 7 - 0
src/styles/element-variables.scss

@@ -0,0 +1,7 @@
+/* 改变主题色变量 */
+$--color-primary: #1abc9c;
+
+/* 改变 icon 字体路径变量,必需 */
+$--font-path: '~element-ui/lib/theme-chalk/fonts';
+
+@import "~element-ui/packages/theme-chalk/src/index";

+ 153 - 0
src/styles/index.scss

@@ -0,0 +1,153 @@
+@import './variables.scss';
+@import './mixin.scss';
+@import './transition.scss';
+@import './element-ui.scss';
+@import './sidebar.scss';
+
+body {
+  height: 100%;
+  -moz-osx-font-smoothing: grayscale;
+  -webkit-font-smoothing: antialiased;
+  text-rendering: optimizeLegibility;
+  font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
+}
+
+label {
+  font-weight: 700;
+}
+
+html {
+  height: 100%;
+  box-sizing: border-box;
+}
+
+#app {
+  height: 100%;
+}
+
+*,
+*:before,
+*:after {
+  box-sizing: inherit;
+}
+
+a:focus,
+a:active {
+  outline: none;
+}
+
+a,
+a:focus,
+a:hover {
+  cursor: pointer;
+  color: inherit;
+  text-decoration: none;
+}
+
+div:focus {
+  outline: none;
+}
+
+.clearfix {
+  &:after {
+    visibility: hidden;
+    display: block;
+    font-size: 0;
+    content: " ";
+    clear: both;
+    height: 0;
+  }
+}
+
+// main-container global css
+.app-container {
+  padding:0 40px ;
+}
+.item-width-100 {
+  width: 100px !important;
+}
+.item-width-150 {
+  width: 150px !important;
+}
+
+.item-width-200{
+  width: 200px !important;
+}
+
+.item-width-250{
+  width: 250px !important;
+}
+.item-width-300{
+  width: 300px!important;
+}
+.item-width-350{
+  width: 350px !important;
+}
+.item-width-400{
+  width: 400px !important;
+}
+.item-width-500{
+  width: 500px !important;
+}
+.ml10{
+  margin-left: 10px;
+}
+.mb10{
+  margin-bottom: 10px;
+}
+.mr10{
+  margin-right: 10px;
+}
+.mt10 {
+  margin-top: 10px;
+}
+.mt20{
+  margin-top: 20px;
+}
+
+.page-box{
+  display: flex;
+  justify-content: flex-end;
+  padding: 20px 0;
+}
+
+.logo{
+  position: fixed;
+  width: 150px;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%,-50%);
+  margin-top: -300px;
+  .outside{
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    margin: auto;
+    width: 150px;
+  }
+  .inside {
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    margin: auto;
+    width: 100px;
+  }
+}
+
+.handle-box{
+  margin-bottom: 20px;
+}
+
+
+  input::-webkit-outer-spin-button,
+  
+  input::-webkit-inner-spin-button {
+    -webkit-appearance: none !important;
+  
+    margin: 0;
+  
+  }

+ 28 - 0
src/styles/mixin.scss

@@ -0,0 +1,28 @@
+@mixin clearfix {
+  &:after {
+    content: "";
+    display: table;
+    clear: both;
+  }
+}
+
+@mixin scrollBar {
+  &::-webkit-scrollbar-track-piece {
+    background: #d3dce6;
+  }
+
+  &::-webkit-scrollbar {
+    width: 6px;
+  }
+
+  &::-webkit-scrollbar-thumb {
+    background: #99a9bf;
+    border-radius: 20px;
+  }
+}
+
+@mixin relative {
+  position: relative;
+  width: 100%;
+  height: 100%;
+}

+ 226 - 0
src/styles/sidebar.scss

@@ -0,0 +1,226 @@
+#app {
+
+  .main-container {
+    // min-height: 100%;
+    transition: margin-left .28s;
+    margin-left: $sideBarWidth;
+    position: relative;
+  }
+
+  .sidebar-container {
+    transition: width 0.28s;
+    width: $sideBarWidth !important;
+    background-color: $menuBg;
+    height: 100%;
+    position: fixed;
+    font-size: 0px;
+    top: 50px;
+    bottom: 0;
+    left: 0;
+    z-index: 1001;
+    overflow: hidden;
+
+    // reset element-ui css
+    .horizontal-collapse-transition {
+      transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out;
+    }
+
+    .scrollbar-wrapper {
+      overflow-x: hidden !important;
+    }
+
+    .el-scrollbar__bar.is-vertical {
+      right: 0px;
+    }
+
+    .el-scrollbar {
+      height: 100%;
+    }
+
+    &.has-logo {
+      .el-scrollbar {
+        height: calc(100% - 50px);
+      }
+    }
+
+    .is-horizontal {
+      display: none;
+    }
+
+    a {
+      display: inline-block;
+      width: 100%;
+      overflow: hidden;
+    }
+
+    .svg-icon {
+      margin-right: 16px;
+    }
+
+    .sub-el-icon {
+      margin-right: 12px;
+      margin-left: -2px;
+    }
+
+    .el-menu {
+      border: none;
+      height: 100%;
+      width: 100% !important;
+    }
+
+    // menu hover
+    .submenu-title-noDropdown,
+    .el-submenu__title {
+      &:hover {
+        background-color: $menuHover !important;
+      }
+    }
+
+    .is-active>.el-submenu__title {
+      color: $subMenuActiveText !important;
+    }
+
+    & .nest-menu .el-submenu>.el-submenu__title,
+    & .el-submenu .el-menu-item {
+      min-width: $sideBarWidth !important;
+      background-color: $subMenuBg !important;
+
+      &:hover {
+        background-color: $subMenuHover !important;
+      }
+    }
+  }
+
+  .hideSidebar {
+    .sidebar-container {
+      width: 54px !important;
+    }
+
+    .main-container {
+      margin-left: 54px;
+    }
+
+    .submenu-title-noDropdown {
+      padding: 0 !important;
+      position: relative;
+
+      .el-tooltip {
+        padding: 0 !important;
+
+        .svg-icon {
+          margin-left: 20px;
+        }
+
+        .sub-el-icon {
+          margin-left: 19px;
+        }
+      }
+    }
+
+    .el-submenu {
+      overflow: hidden;
+
+      &>.el-submenu__title {
+        padding: 0 !important;
+
+        .svg-icon {
+          margin-left: 20px;
+        }
+
+        .sub-el-icon {
+          margin-left: 19px;
+        }
+
+        .el-submenu__icon-arrow {
+          display: none;
+        }
+      }
+    }
+
+    .el-menu--collapse {
+      .el-submenu {
+        &>.el-submenu__title {
+          &>span {
+            height: 0;
+            width: 0;
+            overflow: hidden;
+            visibility: hidden;
+            display: inline-block;
+          }
+        }
+      }
+    }
+  }
+
+  .el-menu--collapse .el-menu .el-submenu {
+    min-width: $sideBarWidth !important;
+  }
+
+  // mobile responsive
+  .mobile {
+    .main-container {
+      margin-left: 0px;
+    }
+
+    .sidebar-container {
+      transition: transform .28s;
+      width: $sideBarWidth !important;
+    }
+
+    &.hideSidebar {
+      .sidebar-container {
+        pointer-events: none;
+        transition-duration: 0.3s;
+        transform: translate3d(-$sideBarWidth, 0, 0);
+      }
+    }
+  }
+
+  .withoutAnimation {
+
+    .main-container,
+    .sidebar-container {
+      transition: none;
+    }
+  }
+}
+
+// when menu collapsed
+.el-menu--vertical {
+  &>.el-menu {
+    .svg-icon {
+      margin-right: 16px;
+    }
+    .sub-el-icon {
+      margin-right: 12px;
+      margin-left: -2px;
+    }
+  }
+
+  .nest-menu .el-submenu>.el-submenu__title,
+  .el-menu-item {
+    &:hover {
+      // you can use $subMenuHover
+      background-color: $menuHover !important;
+    }
+  }
+
+  // the scroll bar appears when the subMenu is too long
+  >.el-menu--popup {
+    max-height: 100vh;
+    overflow-y: auto;
+
+    &::-webkit-scrollbar-track-piece {
+      background: #d3dce6;
+    }
+
+    &::-webkit-scrollbar {
+      width: 6px;
+    }
+
+    &::-webkit-scrollbar-thumb {
+      background: #99a9bf;
+      border-radius: 20px;
+    }
+  }
+}

+ 48 - 0
src/styles/transition.scss

@@ -0,0 +1,48 @@
+// global transition css
+
+/* fade */
+.fade-enter-active,
+.fade-leave-active {
+  transition: opacity 0.28s;
+}
+
+.fade-enter,
+.fade-leave-active {
+  opacity: 0;
+}
+
+/* fade-transform */
+.fade-transform-leave-active,
+.fade-transform-enter-active {
+  transition: all .5s;
+}
+
+.fade-transform-enter {
+  opacity: 0;
+  transform: translateX(-30px);
+}
+
+.fade-transform-leave-to {
+  opacity: 0;
+  transform: translateX(30px);
+}
+
+/* breadcrumb transition */
+.breadcrumb-enter-active,
+.breadcrumb-leave-active {
+  transition: all .5s;
+}
+
+.breadcrumb-enter,
+.breadcrumb-leave-active {
+  opacity: 0;
+  transform: translateX(20px);
+}
+
+.breadcrumb-move {
+  transition: all .5s;
+}
+
+.breadcrumb-leave-active {
+  position: absolute;
+}

+ 25 - 0
src/styles/variables.scss

@@ -0,0 +1,25 @@
+// sidebar
+$menuText:#999;
+$menuActiveText:#1abc9c;
+$subMenuActiveText:#1abc9c; //https://github.com/ElemeFE/element/issues/12951
+
+$menuBg:#F2F2F2;
+$menuHover:#F2F2F2;
+
+$subMenuBg:#EAEDF1;
+$subMenuHover:#fff;
+
+$sideBarWidth: 210px;
+
+// the :export directive is the magic sauce for webpack
+// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
+:export {
+  menuText: $menuText;
+  menuActiveText: $menuActiveText;
+  subMenuActiveText: $subMenuActiveText;
+  menuBg: $menuBg;
+  menuHover: $menuHover;
+  subMenuBg: $subMenuBg;
+  subMenuHover: $subMenuHover;
+  sideBarWidth: $sideBarWidth;
+}

+ 29 - 0
src/utils/auth.js

@@ -0,0 +1,29 @@
+import Cookies from 'js-cookie'
+
+const TokenKey = 'agent_token'
+const RETokenKey = 'agent_refreshtoken'
+
+export function getToken() {
+  return Cookies.get(TokenKey)
+}
+
+export function setToken(token) {
+  return Cookies.set(TokenKey, token)
+}
+
+export function removeToken() {
+  return Cookies.remove(TokenKey)
+}
+
+export function getREToken() {
+  return Cookies.get(RETokenKey)
+}
+
+export function setREToken(token) {
+  return Cookies.set(RETokenKey, token)
+}
+
+export function removeREToken() {
+  return Cookies.remove(RETokenKey)
+}
+

+ 20 - 0
src/utils/get-page-title.js

@@ -0,0 +1,20 @@
+/*
+ * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @Date: 2022-08-04 17:24:58
+ * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @LastEditTime: 2023-06-01 16:32:20
+ * @FilePath: \agentManage\src\utils\get-page-title.js
+ * @Description: 
+ * 
+ * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. 
+ */
+import defaultSettings from '@/settings'
+
+const title = defaultSettings.title || '中数生活宝'
+
+export default function getPageTitle(pageTitle) {
+  if (pageTitle) {
+    return `${pageTitle} - ${title}`
+  }
+  return `${title}`
+}

+ 143 - 0
src/utils/index.js

@@ -0,0 +1,143 @@
+/**
+ * Created by PanJiaChen on 16/11/18.
+ */
+
+/**
+ * Parse the time to string
+ * @param {(Object|string|number)} time
+ * @param {string} cFormat
+ * @returns {string | null}
+ */
+export function parseTime(time, cFormat) {
+  if (arguments.length === 0 || !time) {
+    return null
+  }
+  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
+  let date
+  if (typeof time === 'object') {
+    date = time
+  } else {
+    if ((typeof time === 'string')) {
+      if ((/^[0-9]+$/.test(time))) {
+        // support "1548221490638"
+        time = parseInt(time)
+      } else {
+        // support safari
+        // https://stackoverflow.com/questions/4310953/invalid-date-in-safari
+        time = time.replace(new RegExp(/-/gm), '/')
+      }
+    }
+
+    if ((typeof time === 'number') && (time.toString().length === 10)) {
+      time = time * 1000
+    }
+    date = new Date(time)
+  }
+  const formatObj = {
+    y: date.getFullYear(),
+    m: date.getMonth() + 1,
+    d: date.getDate(),
+    h: date.getHours(),
+    i: date.getMinutes(),
+    s: date.getSeconds(),
+    a: date.getDay()
+  }
+  const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
+    const value = formatObj[key]
+    // Note: getDay() returns 0 on Sunday
+    if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value ] }
+    return value.toString().padStart(2, '0')
+  })
+  return time_str
+}
+
+/**
+ * @param {number} time
+ * @param {string} option
+ * @returns {string}
+ */
+export function formatTime(time, option) {
+  if (('' + time).length === 10) {
+    time = parseInt(time) * 1000
+  } else {
+    time = +time
+  }
+  const d = new Date(time)
+  const now = Date.now()
+
+  const diff = (now - d) / 1000
+
+  if (diff < 30) {
+    return '刚刚'
+  } else if (diff < 3600) {
+    // less 1 hour
+    return Math.ceil(diff / 60) + '分钟前'
+  } else if (diff < 3600 * 24) {
+    return Math.ceil(diff / 3600) + '小时前'
+  } else if (diff < 3600 * 24 * 2) {
+    return '1天前'
+  }
+  if (option) {
+    return parseTime(time, option)
+  } else {
+    return (
+      d.getMonth() +
+      1 +
+      '月' +
+      d.getDate() +
+      '日' +
+      d.getHours() +
+      '时' +
+      d.getMinutes() +
+      '分'
+    )
+  }
+}
+
+/**
+ * @param {string} url
+ * @returns {Object}
+ */
+export function param2Obj(url) {
+  const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
+  if (!search) {
+    return {}
+  }
+  const obj = {}
+  const searchArr = search.split('&')
+  searchArr.forEach(v => {
+    const index = v.indexOf('=')
+    if (index !== -1) {
+      const name = v.substring(0, index)
+      const val = v.substring(index + 1, v.length)
+      obj[name] = val
+    }
+  })
+  return obj
+}
+
+
+//获取当前时间
+export function getTime(num) {
+  let s = new Date().getTime() + num * 1000 * 60 * 60 * 24
+  let date = new Date(s)
+  let year = date.getFullYear();
+  let month = date.getMonth() + 1 >= 10 ? date.getMonth() + 1 : '0' + (date.getMonth() + 1);
+  let day = date.getDate() >= 10 ? date.getDate() : '0' + date.getDate();
+  let hour = date.getHours() >= 10 ? date.getHours() : '0' + date.getHours();
+  let minute = date.getMinutes() >= 10 ? date.getMinutes() : '0' + date.getMinutes();
+  let second = date.getSeconds() >= 10 ? date.getSeconds() : '0' + date.getSeconds();
+  let time = `${year}-${month}-${day}`
+  // let time = `${year}-${month}-${day} ${hour}:${minute}:${second}`
+  return time;
+}
+
+//获取当前时间
+export function timeFormat(num) {
+  let date = new Date(num)
+  let year = date.getFullYear();
+  let month = date.getMonth() + 1 >= 10 ? date.getMonth() + 1 : '0' + (date.getMonth() + 1);
+  let day = date.getDate() >= 10 ? date.getDate() : '0' + date.getDate();
+  let time = `${year}-${month}-${day}`
+  return time;
+}

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
src/utils/map.json


+ 93 - 0
src/utils/request.js

@@ -0,0 +1,93 @@
+/*
+ * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @Date: 2022-08-02 14:50:38
+ * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @LastEditTime: 2023-08-17 16:17:24
+ * @FilePath: \agentManage\src\utils\request.js
+ * @Description: 
+ * 
+ * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. 
+ */
+import axios from 'axios'
+import { MessageBox, Message } from 'element-ui'
+import store from '@/store'
+import { getToken,setToken,getREToken,removeToken } from '@/utils/auth'
+import { refreshToken } from '@/api/auth'
+// create an axios instance
+const service = axios.create({
+  // baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
+  // baseURL: "http://nei.pgtgame.com/api/apimock-v2/9066e4ae45cff724b020fe29478b3506", // url = base url + request url
+  baseURL: "/admin", // url = base url + request url
+  
+  // withCredentials: true, // send cookies when cross-domain requests
+  timeout: 30000 // request timeout
+})
+
+// request interceptor
+service.interceptors.request.use(
+  config => {
+    // do something before request is sent
+
+    // if (store.getters.token) {
+      // let each request carry token
+      // ['X-Token'] is a custom headers key
+      // please modify it according to the actual situation
+      config.headers['Accesstoken'] = getToken()
+      config.headers['epid'] = localStorage.getItem('epid')
+      // config.headers['Content-Type'] = 'application/x-www-form-urlencoded'
+    // }
+    return config
+  },
+  error => {
+    // do something with request error
+    console.log(error) // for debug
+    return Promise.reject(error)
+  }
+)
+
+// response interceptor
+service.interceptors.response.use(
+  /**
+   * If you want to get http information such as headers or status
+   * Please return  response => response
+  */
+
+  /**
+   * Determine the request status by custom code
+   * Here is just an example
+   * You can also judge the status by HTTP Status Code
+   */
+  response => {
+    const res = response.data
+console.log('response',response);
+    // 如果code不是 0, 这被判定为一个错误。
+    if (res.state !== "Success") {
+      Message({
+        message: res.msg || 'Error',
+        type: 'error',
+        duration: 5 * 1000
+      })
+
+      // 10001:令牌过期
+      if (res.code === 10001) {
+        removeToken()
+        location.reload()
+      }
+      return res
+      // return Promise.reject(new Error(res.message || 'Error'))
+    } else {
+      return res
+    }
+  },
+  error => {
+    console.log('err' + error) // for debug
+    Message({
+      message: error.message,
+      type: 'error',
+      duration: 5 * 1000
+    })
+    return Promise.reject(error)
+  }
+)
+
+export default service

+ 20 - 0
src/utils/validate.js

@@ -0,0 +1,20 @@
+/**
+ * Created by PanJiaChen on 16/11/18.
+ */
+
+/**
+ * @param {string} path
+ * @returns {Boolean}
+ */
+export function isExternal(path) {
+  return /^(https?:|mailto:|tel:)/.test(path)
+}
+
+/**
+ * @param {string} str
+ * @returns {Boolean}
+ */
+export function validUsername(str) {
+  const valid_map = ['admin', 'editor']
+  return valid_map.indexOf(str.trim()) >= 0
+}

+ 228 - 0
src/views/404.vue

@@ -0,0 +1,228 @@
+<template>
+  <div class="wscn-http404-container">
+    <div class="wscn-http404">
+      <div class="pic-404">
+        <img class="pic-404__parent" src="@/assets/404_images/404.png" alt="404">
+        <img class="pic-404__child left" src="@/assets/404_images/404_cloud.png" alt="404">
+        <img class="pic-404__child mid" src="@/assets/404_images/404_cloud.png" alt="404">
+        <img class="pic-404__child right" src="@/assets/404_images/404_cloud.png" alt="404">
+      </div>
+      <div class="bullshit">
+        <div class="bullshit__oops">OOPS!</div>
+        <div class="bullshit__info">All rights reserved
+          <a style="color:#20a0ff" href="https://wallstreetcn.com" target="_blank">wallstreetcn</a>
+        </div>
+        <div class="bullshit__headline">{{ message }}</div>
+        <div class="bullshit__info">Please check that the URL you entered is correct, or click the button below to return to the homepage.</div>
+        <a href="" class="bullshit__return-home">Back to home</a>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+
+export default {
+  name: 'Page404',
+  computed: {
+    message() {
+      return 'The webmaster said that you can not enter this page...'
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.wscn-http404-container{
+  transform: translate(-50%,-50%);
+  position: absolute;
+  top: 40%;
+  left: 50%;
+}
+.wscn-http404 {
+  position: relative;
+  width: 1200px;
+  padding: 0 50px;
+  overflow: hidden;
+  .pic-404 {
+    position: relative;
+    float: left;
+    width: 600px;
+    overflow: hidden;
+    &__parent {
+      width: 100%;
+    }
+    &__child {
+      position: absolute;
+      &.left {
+        width: 80px;
+        top: 17px;
+        left: 220px;
+        opacity: 0;
+        animation-name: cloudLeft;
+        animation-duration: 2s;
+        animation-timing-function: linear;
+        animation-fill-mode: forwards;
+        animation-delay: 1s;
+      }
+      &.mid {
+        width: 46px;
+        top: 10px;
+        left: 420px;
+        opacity: 0;
+        animation-name: cloudMid;
+        animation-duration: 2s;
+        animation-timing-function: linear;
+        animation-fill-mode: forwards;
+        animation-delay: 1.2s;
+      }
+      &.right {
+        width: 62px;
+        top: 100px;
+        left: 500px;
+        opacity: 0;
+        animation-name: cloudRight;
+        animation-duration: 2s;
+        animation-timing-function: linear;
+        animation-fill-mode: forwards;
+        animation-delay: 1s;
+      }
+      @keyframes cloudLeft {
+        0% {
+          top: 17px;
+          left: 220px;
+          opacity: 0;
+        }
+        20% {
+          top: 33px;
+          left: 188px;
+          opacity: 1;
+        }
+        80% {
+          top: 81px;
+          left: 92px;
+          opacity: 1;
+        }
+        100% {
+          top: 97px;
+          left: 60px;
+          opacity: 0;
+        }
+      }
+      @keyframes cloudMid {
+        0% {
+          top: 10px;
+          left: 420px;
+          opacity: 0;
+        }
+        20% {
+          top: 40px;
+          left: 360px;
+          opacity: 1;
+        }
+        70% {
+          top: 130px;
+          left: 180px;
+          opacity: 1;
+        }
+        100% {
+          top: 160px;
+          left: 120px;
+          opacity: 0;
+        }
+      }
+      @keyframes cloudRight {
+        0% {
+          top: 100px;
+          left: 500px;
+          opacity: 0;
+        }
+        20% {
+          top: 120px;
+          left: 460px;
+          opacity: 1;
+        }
+        80% {
+          top: 180px;
+          left: 340px;
+          opacity: 1;
+        }
+        100% {
+          top: 200px;
+          left: 300px;
+          opacity: 0;
+        }
+      }
+    }
+  }
+  .bullshit {
+    position: relative;
+    float: left;
+    width: 300px;
+    padding: 30px 0;
+    overflow: hidden;
+    &__oops {
+      font-size: 32px;
+      font-weight: bold;
+      line-height: 40px;
+      color: #1482f0;
+      opacity: 0;
+      margin-bottom: 20px;
+      animation-name: slideUp;
+      animation-duration: 0.5s;
+      animation-fill-mode: forwards;
+    }
+    &__headline {
+      font-size: 20px;
+      line-height: 24px;
+      color: #222;
+      font-weight: bold;
+      opacity: 0;
+      margin-bottom: 10px;
+      animation-name: slideUp;
+      animation-duration: 0.5s;
+      animation-delay: 0.1s;
+      animation-fill-mode: forwards;
+    }
+    &__info {
+      font-size: 13px;
+      line-height: 21px;
+      color: grey;
+      opacity: 0;
+      margin-bottom: 30px;
+      animation-name: slideUp;
+      animation-duration: 0.5s;
+      animation-delay: 0.2s;
+      animation-fill-mode: forwards;
+    }
+    &__return-home {
+      display: block;
+      float: left;
+      width: 110px;
+      height: 36px;
+      background: #1482f0;
+      border-radius: 100px;
+      text-align: center;
+      color: #ffffff;
+      opacity: 0;
+      font-size: 14px;
+      line-height: 36px;
+      cursor: pointer;
+      animation-name: slideUp;
+      animation-duration: 0.5s;
+      animation-delay: 0.3s;
+      animation-fill-mode: forwards;
+    }
+    @keyframes slideUp {
+      0% {
+        transform: translateY(60px);
+        opacity: 0;
+      }
+      100% {
+        transform: translateY(0);
+        opacity: 1;
+      }
+    }
+  }
+}
+</style>

+ 147 - 0
src/views/adminManage/adminAdd.vue

@@ -0,0 +1,147 @@
+<!--
+ * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @Date: 2023-05-26 16:37:34
+ * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @LastEditTime: 2023-05-26 17:44:09
+ * @FilePath: \agentManage\src\views\adminManage\adminAdd.vue
+ * @Description: 
+ * 
+ * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. 
+-->
+<template>
+    <div class="adminAdd app-container">
+      <TopBar></TopBar>
+      <el-form
+        :model="setQuery"
+        ref="setQuery"
+        :rules="rules"
+        label-width="130px"
+      >
+        <el-form-item label="用户名:" prop="name">
+          <el-input
+            v-model="setQuery.name"
+            :maxlength="11"
+            class="item-width-300"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="手机号:" prop="phone">
+          <el-input
+            v-model.number="setQuery.phone"
+            :maxlength="11"
+            class="item-width-300"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="角色:" prop="role">
+            <el-select v-model="setQuery.role" class="item-width-300" placeholder="请选择">
+                  <el-option
+                    v-for="item in options"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value">
+                  </el-option>
+                </el-select>
+        </el-form-item>
+       
+        <el-form-item label="商铺手机号:" prop="shopPhone">
+          <el-input
+            v-model.number="setQuery.shopPhone"
+            :maxlength="11"
+            class="item-width-300"
+          ></el-input>
+        </el-form-item>
+        
+        <el-form-item label="状态:">
+          <el-switch
+            v-model="setQuery.status"
+            active-text="启用"
+            inactive-text="禁用"
+            active-color="#13ce66"
+            inactive-color="#ff4949"
+          >
+          </el-switch>
+        </el-form-item>
+      </el-form>
+  
+      <div class="btn" @click="save">保存</div>
+    </div>
+  </template>
+  
+  <script>
+  export default {
+    data() {
+      return {
+        setQuery: {
+            id:1,
+            name:'',
+            shopPhone:'',
+            status:1,
+            createTime:'2023-05-23 16:56',
+            phone:'',
+            role:1
+        },
+        options: [
+          {
+            value: 1,
+            label: '商家'
+          }, {
+            value: 2,
+            label: '用户'
+          },
+          {
+            value: 3,
+            label: '业务员'
+          }
+        ],
+        rules: {
+          name: [{ required: true, message: "请输入用户名", trigger: "blur" }],
+          phone: [
+            { required: true, message: "请输入手机号", trigger: "blur" },
+          ],
+          shopPhone: [
+            { required: true, message: "请输入商铺手机号", trigger: "blur" },
+          ],
+        },
+      };
+    },
+    methods: {
+      save() {
+        this.$refs.setQuery.validate((v) => {
+          if (v) {
+              this.$notify({
+                  title: '成功',
+                  message: '操作成功',
+                  type: 'success'
+                });
+                this.setQuery = {
+                    id:1,
+                    name:'',
+                    shopPhone:'',
+                    status:1,
+                    createTime:'2023-05-23 16:56',
+                    phone:'',
+                    role:1
+                  }
+                  this.$router.push('/adminManage/adminList')
+                
+          }
+        });
+      },
+    },
+  };
+  </script>
+  
+  <style lang="scss" scoped>
+  .adminAdd {
+    .btn {
+      width: 110px;
+      line-height: 42px;
+      background: #1abc9c;
+      color: #fff;
+      text-align: center;
+      border-radius: 4px;
+      margin-left: 120px;
+      margin-top: 30px;
+      cursor: pointer;
+    }
+  }
+  </style>

+ 171 - 0
src/views/adminManage/adminDetail.vue

@@ -0,0 +1,171 @@
+
+<template>
+    <div class="adminDetail app-container">
+      <TopBar ></TopBar>
+  
+      <div class="content">
+        <el-descriptions class="margin-top" :column="3" border>
+                <el-descriptions-item>
+                    <template slot="label">
+                        用户名
+                    </template>
+                    kooriookami
+                </el-descriptions-item>
+                <el-descriptions-item>
+                    <template slot="label">
+                        用户ID
+                    </template>
+                    12321515
+                </el-descriptions-item>
+                <el-descriptions-item>
+                    <template slot="label">
+                        用户状态
+                    </template>
+                    启用
+                </el-descriptions-item>
+                <el-descriptions-item>
+                    <template slot="label">
+                        手机号
+                    </template>
+                    13512546985
+                </el-descriptions-item>
+                <el-descriptions-item>
+                    <template slot="label">
+                        角色
+                    </template>
+                    商家
+                </el-descriptions-item>
+                <el-descriptions-item>
+                    <template slot="label">
+                        省份
+                    </template>
+                    四川
+                </el-descriptions-item>
+                <el-descriptions-item>
+                    <template slot="label">
+                        城市
+                    </template>
+                    成都
+                </el-descriptions-item>
+                <el-descriptions-item>
+                    <template slot="label">
+                        区县
+                    </template>
+                    高新区
+                </el-descriptions-item>
+                <el-descriptions-item>
+                        <template slot="label">
+                            详细地址
+                        </template>
+                        红星美凯龙2006
+                    </el-descriptions-item>
+                    <el-descriptions-item contentClassName="test">
+                        <template slot="label">
+                            申请审核时间
+                        </template>
+                        2023-05-26 16:55:30
+                    </el-descriptions-item>
+            </el-descriptions>
+        
+        <div class="img-box">
+            <div class="img-item">
+                <div class="img"></div>
+                <div class="img-title">头像</div>
+            </div>
+            <div class="img-item">
+                <div class="img"></div>
+                <div class="img-title">身份证正面照</div>
+            </div>
+            <div class="img-item">
+                <div class="img"></div>
+                <div class="img-title">身份证反面照</div>
+            </div>
+            <div class="img-item">
+                <div class="img"></div>
+                <div class="img-title">手持身份证照</div>
+            </div>
+            <div class="img-item">
+                <div class="img"></div>
+                <div class="img-title">其他资质</div>
+            </div>
+        </div>
+
+      </div>
+
+  
+    </div>
+  </template>
+  
+  <script>
+  export default {
+    name: 'adminDetail',
+    components: {
+    },
+    data() {
+      return {
+          
+      }
+    },
+
+    methods: {
+       
+      
+    },
+      created () {
+    },
+  }
+  </script>
+  
+  <style lang="scss" >
+  .adminDetail {
+      .content{
+        border: 1px solid #ccc;
+        padding: 40px 20px;
+        border-radius: 4px;
+        .table{
+    .item{
+        display: flex;
+        align-items: center;
+        font-size: 14px;
+        text-align: center;
+        .label{
+            flex: 0 0 100px;
+            line-height: 42px;
+            background: #f1f1f1;
+            border: 1px solid #ccc;
+            font-weight: bold;
+        }
+        .value{
+            flex: 1;
+            line-height: 42px;
+            border: 1px solid #ccc;
+        }
+    }
+}
+
+        .img-box{
+            display: flex;
+            align-items: center;
+            margin-top: 80px;
+            .img-item{
+                flex: 1;
+                display: flex;
+                flex-direction: column;
+                align-items: center;
+                .img{
+                    width: 90%;
+                    height: 150px;
+                    background: #f1f1f1;
+                }
+                .img-title{
+                    font-size: 14px;
+                    margin-top: 15px;
+                    font-weight: bold;
+                }
+            }
+        }
+ 
+      }
+  }
+  </style>
+  

+ 319 - 0
src/views/adminManage/adminList.vue

@@ -0,0 +1,319 @@
+
+<template>
+  <div class="shopManage app-container">
+    <TopBar title="商铺管理"></TopBar>
+
+    <TabCard title="筛选查询" :isSearch="true" :loading="loading" @search="search">
+    </TabCard>
+    <div class="search">
+        <el-form :model="query" inline ref="query" label-width="100px">
+            <el-form-item label="用户名:">
+                <el-input v-model="query.userName" size="small" class="item-width-200"></el-input>
+            </el-form-item>
+            <el-form-item label="手机号:" >
+                  <el-input v-model.number="query.phone" type="number" size="small" class="item-width-200"></el-input>
+              </el-form-item>
+              <el-form-item label="角色:" >
+                  <el-select v-model="query.role"  size="small" placeholder="请选择">
+                  <el-option
+                    v-for="item in options"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value">
+                  </el-option>
+                </el-select>
+              </el-form-item>
+        </el-form>
+    </div>
+
+    <TabCard title="数据列表">
+        <el-button size="small"   @click="handleAdd">添加</el-button>
+    </TabCard>
+    <el-table
+    :data="tableData"
+    tooltip-effect="dark"
+    border
+    v-loading="loading"
+    style="width: 100%"
+    >
+    <el-table-column
+      align="center"
+      label="用户名"
+      prop="name"
+      show-overflow-tooltip
+      >
+    </el-table-column>
+    <el-table-column
+      prop="phone"
+      align="center"
+      label="手机号"
+      show-overflow-tooltip>
+    </el-table-column>
+    <el-table-column
+      prop="role"
+      align="center"
+      label="角色"
+      show-overflow-tooltip>
+      <template slot-scope="scope">
+          {{scope.row.status | filterRole}}
+      </template>
+    </el-table-column>
+    <el-table-column
+      prop="createTime"
+      align="center"
+      label="添加时间"
+      show-overflow-tooltip>
+    </el-table-column>
+    <el-table-column
+      align="center"
+      prop="status"
+      label="状态"
+      show-overflow-tooltip>
+      <template slot-scope="scope">
+          {{scope.row.status==1?'启用':'禁用'}}
+      </template>
+    </el-table-column>
+    <el-table-column
+      align="center"
+      prop="shopPhone"
+      label="商户手机号"
+      show-overflow-tooltip>
+    </el-table-column>
+    <el-table-column
+      prop="address"
+      align="center"
+      label="操作">
+      <template slot-scope="scope">
+        <el-button type="text" size="small" @click="handle(scope.row,scope.$index)">{{scope.row.status==1?'禁用':'启用'}}</el-button>
+        <el-button type="text" size="small" @click="handleDetail(scope.row)">查看</el-button>
+      </template>
+    </el-table-column>
+  </el-table>
+  <div class="page-box">
+      <el-pagination
+      @size-change="handleSizeChange"
+      @current-change="handleCurrentChange"
+      background
+      :current-page="query.page"
+      :page-sizes="[10, 20, 30, 40]"
+      :page-size="query.pageSize"
+      layout="total, sizes, prev, pager, next, jumper"
+      :total="tableData.length">
+    </el-pagination>
+  </div>
+
+  </div>
+</template>
+
+<script>
+
+export default {
+  name: 'shopManage',
+  data() {
+    return {
+        tableData: [
+          {
+              id:1,
+              name:'张三',
+              shopPhone:13189854526,
+              status:1,
+              createTime:'2023-05-23 16:56',
+              phone:13945678945,
+              role:2
+          },
+          {
+              id:2,
+              name:'李四',
+              shopPhone:13189854526,
+              status:0,
+              createTime:'2023-05-23 16:56',
+              phone:13945678945,
+              role:1
+          },
+          {
+              id:3,
+              name:'王五',
+              shopPhone:13189854526,
+              status:1,
+              createTime:'2023-05-23 16:56',
+              phone:13945678945,
+              role:1
+          }
+          
+        ],
+        options: [
+          {
+            value: 1,
+            label: '商家'
+          }, {
+            value: 2,
+            label: '用户'
+          },
+          {
+            value: 3,
+            label: '业务员'
+          }
+        ],
+        loading:false,
+        btnLoading:false,
+        dialogFormVisible:false,
+        query:{
+            userName:'',
+            phone:'',
+            role:'',
+            page:1,
+            pageSize:10,
+        },
+        setQuery:{
+              id:4,
+              name:'商品1',
+              type:'类别1',
+              shopName:'中石油',
+              discounts:'95折',
+              status:'上架中',
+              createTime:'2023-05-23',
+              icon:`https://picsum.photos/750?r1`,
+              stock:231,
+              number:50,
+        },
+        title:'',
+        total:0,
+    }
+  },
+  filters: {
+    filterRole: function(value) {
+      if(value == 1){
+        return '商家';
+      }else if(value == 2){
+        return '用户';
+      }else{
+        return '业务员';
+      }
+    }
+  },
+  methods: {
+      handleAdd(){
+            this.$router.push('/adminManage/adminAdd')
+        },
+      handle(item,index){
+          this.$set(item,'status',this.tableData[index].status == 1?0:1)
+      },
+      handleDetail(row) {
+      this.$router.push('/adminManage/adminDetail')
+    },
+    save() {
+      this.$refs.setQuery.validate(v=>{
+        if(v){
+          // this.btnLoading = true
+          if(this.title == "添加员工"){
+           this.tableData.push(this.setQuery)
+           this.dialogFormVisible = false
+          }else{
+           this.dialogFormVisible = false
+            
+          }
+        }
+      })
+    },
+      handleSizeChange(val) {
+      this.query.page = 1;
+      this.query.pageSize = val;
+    },
+    handleCurrentChange(val) {
+      this.query.page = val;
+    },
+
+    search(){
+      this.query.page = 1
+    },
+    
+  },
+    created () {
+  },
+}
+</script>
+
+<style lang="scss" >
+.shopManage {
+    .search{
+        padding: 10px 0;
+      box-shadow: 0 1px 4px rgba(0,21,41,.08);
+      margin-bottom: 20px;
+      .el-form-item{
+          margin: 0;
+      }
+    }
+
+    .icon{
+      width: 100px;
+      height: 100px;
+    }
+    .choose-box{
+        width: 300px;
+        min-height: 40px;
+        max-height: 120px;
+        overflow: auto;
+        display: flex;
+        align-items: center;
+        flex-wrap: wrap;
+        border-radius: 4px;
+        border: 1px solid #DCDFE6;
+        padding: 10px 30px 10px 10px;
+        .open-btn{
+            position: absolute;
+            top: 10px;
+            right: 100px;
+            color: #1abc9c;
+            font-size: 28px;
+        }
+        .tab{
+            display: flex;
+            align-items: center;
+            height: 26px;
+            font-size: 12px;
+            color: #999;
+            padding: 4px;
+            border: 1px solid #1abc9c;
+            border-radius: 4px;
+            box-sizing: border-box;
+            margin-bottom: 10px;
+            margin-right: 10px;
+
+            .name{
+                font-size: 12px;
+                color: #666;
+                margin-right: 6px;
+            }
+            i{
+                font-size: 16px;
+                color: #1abc9c;
+                cursor: pointer;
+            }
+        }
+    }
+}
+
+.shopManage .setting-dialog{
+     .el-dialog__header{
+         background: #f2f2f2;
+         .el-dialog__title{
+             font-size: 16px;
+             color: #666;
+             font-weight: 600;
+         }
+     }
+    .top{
+        margin-bottom: 10px;
+        display: flex;
+        align-items: center;
+        .text{
+                margin-left: 15px;
+            .num{
+                color: #f04844;
+            }
+        }
+    }
+   
+}
+
+</style>

+ 271 - 0
src/views/adminManage/menu.js

@@ -0,0 +1,271 @@
+export const asyncRouter = [
+    {
+        id: 0,
+        path: '/',
+        redirect: '/home',
+        meta: { title: '系统首页', icon: 'icon-shouyefill' },
+        alwaysShow: true,
+        children: [
+            {
+                id: 1,
+                path: '/home',
+                name: '/home',
+                meta: { title: '系统首页', icon: '' },
+            },
+            {
+                id: 2,
+                path: '/home/accountSetting',
+                name: '/home/accountSetting',
+                meta: { title: '账户设置', icon: '' },
+            },
+        ]
+    },
+    {
+        id: 3,
+        path: '/announcementManage',
+        meta: { title: '公告管理', icon: 'icon-xinwen' },
+        alwaysShow: true,
+        children: [
+            {
+                id: 4,
+                path: '/announcementManage',
+                name: '/announcementManage',
+                meta: { title: '公告列表', icon: '' },
+            },
+            // {
+            //     id: 5,
+            //     path: '/announcementManage/addAnnouncement',
+            //     name: '/announcementManage/addAnnouncement',
+            //     meta: { title: '发布公告', icon: '', activeMenu: '/announcementManage' },
+            //     hidden: true
+            // },
+        ]
+    },
+    {
+        id: 6,
+        path: '/emailManage',
+        meta: { title: '邮件管理', icon: 'icon-duanxinyingxiao' },
+        alwaysShow: true,
+        children: [
+            {
+                id: 7,
+                path: '/emailManage',
+                name: '/emailManage',
+                meta: { title: '邮件列表', icon: '' },
+            },
+            // {
+            //     id: 8,
+            //     path: '/emailManage/sendEmail',
+            //     name: '/emailManage/sendEmail',
+            //     meta: { title: '发送邮件', icon: '', activeMenu: '/emailManage' },
+            //     hidden: true
+            // },
+        ]
+    },
+    // {
+    //     id: 9,
+    //     path: '/articleManage',
+    //     meta: { title: '文章管理', icon: 'icon-bianjiwenzhang_huaban' },
+    //     alwaysShow: true,
+    //     children: [
+    //         {
+    //             id: 10,
+    //             path: '/articleManage',
+    //             name: '/articleManage',
+    //             meta: { title: '游戏攻略', icon: '' },
+    //         },
+    //     ]
+    // },
+    {
+        id: 11,
+        path: '/memberManage',
+        meta: { title: '会员管理', icon: 'icon-guanliyuan_jiaoseguanli' },
+        alwaysShow: true,
+        children: [
+            {
+                id: 12,
+                path: '/memberManage/memberList',
+                name: '/memberManage/memberList',
+                meta: { title: '会员列表', icon: '' },
+            },
+            {
+                id: 13,
+                path: '/memberManage/memberDetail',
+                name: '/memberManage/memberDetail',
+                hidden: true
+            },
+            {
+                id: 14,
+                path: '/memberManage/diamondIncome',
+                name: '/memberManage/diamondIncome',
+                meta: { title: '黑钻收支明细', icon: '' },
+            },
+            {
+                id: 15,
+                path: '/memberManage/rebateList',
+                name: '/memberManage/rebateList',
+                meta: { title: '返佣查询', icon: '' },
+            },
+            {
+                id: 16,
+                path: '/memberManage/rebateDetail',
+                name: '/memberManage/rebateDetail',
+                meta: { title: '返佣明细', icon: '', activeMenu: '/memberManage/rebateList' },
+                hidden: true
+            },
+            {
+                id: 17,
+                path: '/memberManage/earningsDetail',
+                name: '/memberManage/earningsDetail',
+                meta: { title: '产生收益明细', icon: '', activeMenu: '/memberManage/rebateList' },
+                hidden: true
+            },
+        ]
+    },
+    // {
+    //     id: 18,
+    //     path: '/gameManage',
+    //     meta: { title: '游戏管理', icon: 'icon-youxi' },
+    //     alwaysShow: true,
+    //     children: [
+    //         {
+    //             id: 19,
+    //             path: '/gameManage/kittyLevel',
+    //             name: '/gameManage/kittyLevel',
+    //             meta: { title: '猫咪品级管理', icon: '' },
+    //         },
+    //         {
+    //             id: 20,
+    //             path: '/gameManage/kittyMarket',
+    //             name: '/gameManage/kittyMarket',
+    //             meta: { title: '猫市列表', icon: '' },
+    //         },
+    //         {
+    //             id: 21,
+    //             path: '/gameManage/cattery',
+    //             name: '/gameManage/cattery',
+    //             meta: { title: '猫窝管理', icon: '' },
+    //         },
+    //         {
+    //             id: 22,
+    //             path: '/gameManage/propManage',
+    //             name: '/gameManage/propManage',
+    //             meta: { title: '道具管理', icon: '' },
+    //         },
+    //         {
+    //             id: 23,
+    //             path: '/gameManage/goodsManage',
+    //             name: '/gameManage/goodsManage',
+    //             meta: { title: '物品管理', icon: '' },
+    //         },
+    //         {
+    //             id: 24,
+    //             path: '/gameManage/dailyGift',
+    //             name: '/gameManage/dailyGift',
+    //             meta: { title: '每日礼包', icon: '' },
+    //         },
+    //         {
+    //             id: 25,
+    //             path: '/gameManage/gameSetting',
+    //             name: '/gameManage/gameSetting',
+    //             meta: { title: '游戏设置', icon: '' },
+    //         },
+    //     ]
+    // },
+    {
+        id: 26,
+        path: '/stateManage',
+        meta: { title: '报表统计', icon: 'icon-baobiao' },
+        alwaysShow: true,
+        children: [
+            {
+                id: 27,
+                path: '/stateManage/businessReport',
+                name: '/stateManage/businessReport',
+                meta: { title: '业务报表', icon: '' },
+            },
+            {
+                id: 28,
+                path: '/stateManage/agentList',
+                name: '/stateManage/agentList',
+                meta: { title: '业务报表(代理)', icon: '', activeMenu: '/stateManage/businessReport' },
+                hidden: true
+            },
+            {
+                id: 29,
+                path: '/stateManage/groupLeader',
+                name: '/stateManage/groupLeader',
+                meta: { title: '业务报表(组长)', icon: '', activeMenu: '/stateManage/businessReport' },
+                hidden: true
+            },
+            {
+                id: 30,
+                path: '/stateManage/groupMembers',
+                name: '/stateManage/groupMembers',
+                meta: { title: '业务报表(组员)', icon: '', activeMenu: '/stateManage/businessReport' },
+                hidden: true
+            },
+            {
+                id: 31,
+                path: '/stateManage/memberList',
+                name: '/stateManage/memberList',
+                meta: { title: '查看明细', icon: '', activeMenu: '/stateManage/businessReport' },
+                hidden: true
+            },
+            {
+                id: 32,
+                path: '/stateManage/memberStatistics',
+                name: '/stateManage/memberStatistics',
+                meta: { title: '会员每日统计', icon: '', },
+            },
+        ]
+    },
+    {
+        id: 33,
+        path: '/financeManage',
+        meta: { title: '财务管理', icon: 'icon-caidancaiwu' },
+        alwaysShow: true,
+        children: [
+            {
+                id: 34,
+                path: '/financeManage/withdrawApply',
+                name: '/financeManage/withdrawApply',
+                meta: { title: '提现申请', icon: '' },
+            },
+            // {
+            //     id: 35,
+            //     path: '/financeManage/serviceCharge',
+            //     name: '/financeManage/serviceCharge',
+            //     meta: { title: '提现手续费设置', icon: '' },
+            // },
+            {
+                id: 40,
+                path: '/financeManage/userRecharge',
+                name: '/financeManage/userRecharge',
+                meta: { title: '充值列表', icon: '' },
+            },
+        ]
+    },
+    {
+        id: 36,
+        path: '/adminManage',
+        meta: { title: '权限管理', icon: 'icon-shezhi' },
+        alwaysShow: true,
+        children: [
+            {
+                id: 37,
+                path: '/adminManage/adminList',
+                name: '/adminManage/adminList',
+                meta: { title: '员工管理', icon: '' },
+            },
+            // {
+            //     id: 38,
+            //     path: '/adminManage/roleList',
+            //     name: '/adminManage/roleList',
+            //     meta: { title: '权限列表', icon: '' },
+            // },
+
+        ]
+    },
+
+]

+ 246 - 0
src/views/afterSales/afterSalesList.vue

@@ -0,0 +1,246 @@
+<!--
+ * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @Date: 2023-06-19 16:22:03
+ * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @LastEditTime: 2023-09-01 09:36:30
+ * @FilePath: \agentManage\src\views\afterSales\afterSalesList.vue
+ * @Description: 
+ * 
+ * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. 
+-->
+<template>
+  <div class="afterSalesList app-container">
+    <TopBar></TopBar>
+
+    <el-form :inline="true" :model="form" class="demo-form-inline"  label-width="100px">
+      <el-form-item label="售后服务单号">
+        <el-input
+          size="small"
+          class="item-width-150"
+          v-model="form.orderNum"
+          placeholder=""
+        ></el-input>
+      </el-form-item>
+      <el-form-item label="售后服务状态">
+        <el-input
+          size="small"
+          class="item-width-150"
+          v-model="form.orderNum"
+          placeholder=""
+        ></el-input>
+      </el-form-item>
+      <el-form-item label="订单号">
+        <el-input
+          size="small"
+          class="item-width-150"
+          v-model="form.orderNum"
+          placeholder=""
+        ></el-input>
+      </el-form-item>
+      <el-form-item label="商铺名">
+        <el-input
+          size="small"
+          class="item-width-150"
+          v-model="form.orderNum"
+          placeholder=""
+        ></el-input>
+      </el-form-item>
+      <el-form-item label="订单时间">
+        <el-date-picker
+          v-model="date"
+          size="small"
+          class="item-width-450"
+          type="datetimerange"
+          range-separator="至"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+        >
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item label="买家手机号"  label-width="110px">
+        <el-input
+          size="small"
+          class="item-width-150"
+          v-model="form.orderNum"
+          placeholder=""
+        ></el-input>
+      </el-form-item>
+     <el-form-item label="申请时间">
+        <el-date-picker
+          v-model="date"
+          size="small"
+          class="item-width-450"
+          type="datetimerange"
+          range-separator="至"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+        >
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item>
+        <el-button size="small" type="primary" @click="search">查询</el-button>
+      </el-form-item>
+    </el-form>
+<Title title="详细数据">
+        </Title>
+    <Table :labelObj="labelObj" :tableData="tableData" :btnObj="btnObj" :page="page" @pageChange="pageChange"
+            @sizeChange="sizeChange" @handleBtn="handleBtn"></Table>
+  
+  </div>
+</template>
+
+<script>
+import Table from "@/components/Table";
+export default {
+  components: {
+    Table,
+  },
+  data() {
+    return {
+      page: 1,
+      tableData: [
+        {
+          date: "2016-05-02",
+          name: "待审核",
+          name1: 1234124234,
+          name2: 1234124234,
+          name3: 1234124234,
+          name5: "中石油麓湖店",
+          name6: "2020-10-01 16:45:00",
+        },
+        {
+          date: "2016-05-02",
+          name: "待审核",
+          name1: 1234124234,
+          name2: 1234124234,
+          name3: 1234124234,
+          name5: "中石油麓湖店",
+          name6: "2020-10-01 16:45:00",
+        },
+        {
+          date: "2016-05-02",
+          name: "待审核",
+          name1: 1234124234,
+          name2: 1234124234,
+          name3: 1234124234,
+          name5: "中石油麓湖店",
+          name6: "2020-10-01 16:45:00",
+        },
+        {
+          date: "2016-05-02",
+          name: "待审核",
+          name1: 1234124234,
+          name2: 1234124234,
+          name3: 1234124234,
+          name5: "中石油麓湖店",
+          name6: "2020-10-01 16:45:00",
+        },
+        
+      ],
+      labelObj: [
+        {
+          label: "售后服务单号",
+          prop: "date",
+        },
+        {
+          label: "售后服务状态",
+          prop: "name",
+        },
+        {
+          label: "订单号",
+          prop: "name1",
+        },
+        {
+          label: "买家手机号",
+          prop: "name2",
+        },
+        {
+          label: "商家手机号",
+          prop: "name3",
+        },
+        {
+          label: "商品名称",
+          prop: "name5",
+        },
+        {
+          label: "申请时间",
+          prop: "name6",
+        },
+      ],
+      btnObj: {
+        width: 140,
+        label: "操作",
+        btnList: [
+          {
+            text: "查看",
+          },
+        ],
+      },
+      form: {
+        orderNum: "",
+      },
+      date: "",
+    };
+  },
+  methods: {
+    search() {},
+    pageChange(val) {
+      this.page = val;
+    },
+    sizeChange() {},
+    handleBtn(obj) {
+      console.log(obj);
+      if (obj.text == "查看") {
+      } else if (obj.text == "删除") {
+      }
+    },
+    jump(){
+      this.$router.push('/orderManage/detail')
+    }
+  },
+};
+</script>
+
+<style lang="scss">
+.el-form--inline .el-form-item{
+    margin-bottom: 0!important;
+}
+.afterSalesList{
+
+  .item {
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      .box{
+          display: flex;
+          align-items: center;
+          flex: 1;
+  
+          .icon {
+            width: 80px;
+            height: 80px;
+          }
+          .type{
+            margin-left: 60px;
+          }
+          .price{
+            margin-left: 160px;
+          }
+          .num{
+            margin-left: 160px;
+          }
+          .name{
+            margin-left: 160px;
+          }
+      }
+      .status{
+          width: 200px;
+          text-align: center;
+      }
+      .btn{
+        color: red;
+        margin: 0 60px;
+      }
+    }
+}
+</style>

+ 187 - 0
src/views/afterSales/detail.vue

@@ -0,0 +1,187 @@
+<!--
+ * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @Date: 2023-06-21 15:59:06
+ * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @LastEditTime: 2023-07-07 14:20:44
+ * @FilePath: \agentManage\src\views\afterSales\detail.vue
+ * @Description: 
+ * 
+ * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. 
+-->
+<template>
+    <div class="afterSales-detail app-container">
+        <topBar></topBar>
+
+        <el-descriptions :column="4" border>
+                <el-descriptions-item>
+                    <template slot="label">
+                        售后服务单号
+                    </template>
+                    235156485462
+                </el-descriptions-item>
+                <el-descriptions-item>
+                    <template slot="label">
+                        售后服务状态
+                    </template>
+                    不通过
+                </el-descriptions-item>
+                <el-descriptions-item>
+                    <template slot="label">
+                        订单号
+                    </template>
+                    135454641551
+                </el-descriptions-item>
+                <el-descriptions-item>
+                    <template slot="label">
+                        买家手机号
+                    </template>
+                   13154687458
+                </el-descriptions-item>
+                <el-descriptions-item>
+                    <template slot="label">
+                        商铺名称
+                    </template>
+                    中石油
+                </el-descriptions-item>
+                <el-descriptions-item>
+                    <template slot="label">
+                        商户手机号
+                    </template>
+                   13545647895
+                </el-descriptions-item>
+                <el-descriptions-item>
+                    <template slot="label">
+                        售后申请时间
+                    </template>
+                    2023-10-01 17:00:00
+                </el-descriptions-item>
+            </el-descriptions>
+
+            <el-descriptions class="mt20" :column="4" border>
+                <el-descriptions-item>
+                    <template slot="label">
+                        商品总额
+                    </template>
+                    ¥500
+                </el-descriptions-item>
+                <el-descriptions-item>
+                    <template slot="label">
+                        运费
+                    </template>
+                    ¥10
+                </el-descriptions-item>
+                <el-descriptions-item>
+                    <template slot="label">
+                        订单金额
+                    </template>
+                    ¥500
+                </el-descriptions-item>
+                <el-descriptions-item>
+                    <template slot="label">
+                        优惠券抵扣额
+                    </template>
+                    ¥50
+                </el-descriptions-item>
+                <el-descriptions-item>
+                    <template slot="label">
+                        实际金额
+                    </template>
+                    ¥80
+                </el-descriptions-item>
+                <el-descriptions-item>
+                    <template slot="label">
+                        退货运费承担
+                    </template>
+                    卖家承担
+                </el-descriptions-item>
+                <el-descriptions-item>
+                    <template slot="label">
+                        应退金额
+                    </template>
+                    ¥80
+                </el-descriptions-item>
+                
+            </el-descriptions>
+
+            <el-table
+            class="mt20"
+            :data="tableData"
+            border
+            style="width: 100%">
+            <el-table-column
+            align="center"
+                prop="date"
+                label="商品图片"
+             >
+            </el-table-column>
+            <el-table-column
+            align="center"
+                prop="name"
+                label="商品名称"
+             >
+            </el-table-column>
+            <el-table-column
+            align="center"
+                prop="address"
+                label="原价">
+            </el-table-column>
+            <el-table-column
+            align="center"
+                prop="address"
+                label="销售价">
+            </el-table-column>
+            <el-table-column
+                align="center"
+                prop="address"
+                label="数量">
+            </el-table-column>
+            <el-table-column
+            align="center"
+                prop="address"
+                label="运费">
+            </el-table-column>
+            <el-table-column
+            align="center"
+                prop="address"
+                width="140px"
+                label="操作">
+                <template slot-scope="scope">
+                    <el-button type="text" size="small">商品快照</el-button>
+                </template>
+            </el-table-column>
+            </el-table>
+
+    </div>
+</template>
+
+<script>
+    export default {
+        data() {
+            return {
+                tableData: [{
+                    date: '2016-05-02',
+                    name: '王小虎',
+                    address: '上海市普陀区金沙江路 1518 弄'
+                }, {
+                    date: '2016-05-04',
+                    name: '王小虎',
+                    address: '上海市普陀区金沙江路 1517 弄'
+                }, {
+                    date: '2016-05-01',
+                    name: '王小虎',
+                    address: '上海市普陀区金沙江路 1519 弄'
+                }, {
+                    date: '2016-05-03',
+                    name: '王小虎',
+                    address: '上海市普陀区金沙江路 1516 弄'
+                }]
+            }
+        },
+    }
+</script>
+
+<style lang="scss" scoped>
+.afterSales-detail{
+
+}
+</style>

+ 471 - 0
src/views/goodsManage/index.vue

@@ -0,0 +1,471 @@
+
+<template>
+    <div class="goodsManage app-container">
+      <TopBar title="商品管理"></TopBar>
+  
+      <TabCard title="筛选查询" :isSearch="true" :loading="loading" @search="search">
+      </TabCard>
+      <div class="search">
+          <el-form :model="query" inline ref="query" label-width="100px">
+              <el-form-item label="类目:">
+                  <el-input v-model="query.type" size="small" class="item-width-200" placeholder="成员账号/姓名"></el-input>
+              </el-form-item>
+              <el-form-item label="商品名称:">
+                  <el-input v-model="query.name" size="small" class="item-width-200" placeholder="成员账号/姓名"></el-input>
+              </el-form-item>
+              <el-form-item label="商铺名称:">
+                  <el-input v-model="query.shopName" size="small" class="item-width-200" placeholder="成员账号/姓名"></el-input>
+              </el-form-item>
+              <el-form-item label="申请时间:">
+                  <el-date-picker
+                    size="small"
+                    v-model="query.createTime"
+                    type="datetimerange"
+                    range-separator="至"
+                    start-placeholder="开始日期"
+                    end-placeholder="结束日期">
+                  </el-date-picker>
+              </el-form-item>
+
+             
+          </el-form>
+      </div>
+  
+      <TabCard title="数据列表">
+          <el-button size="small"   @click="handleAdd">添加</el-button>
+      </TabCard>
+      <el-table
+      :data="tableData"
+      tooltip-effect="dark"
+      border
+      v-loading="loading"
+      style="width: 100%"
+      >
+      <el-table-column
+        align="center"
+        prop="status"
+        label="商品图"
+        width="120"
+        >
+        <template slot-scope="scope">
+          <el-image class="icon" :src="scope.row.icon" lazy></el-image>
+        </template>
+      </el-table-column>
+      <el-table-column
+        align="center"
+        label="商品名称"
+        prop="name"
+        show-overflow-tooltip
+        >
+      </el-table-column>
+      <el-table-column
+        align="center"
+        prop="type"
+        label="商品类别"
+        show-overflow-tooltip>
+      </el-table-column>
+      <el-table-column
+        prop="shopName"
+        align="center"
+        label="商铺名称"
+        show-overflow-tooltip>
+      </el-table-column>
+      <el-table-column
+        align="center"
+        prop="discounts"
+        label="优惠政策"
+        show-overflow-tooltip>
+        <template slot-scope="scope">
+         {{ scope.row.discounts }}折
+        </template>
+      </el-table-column>
+      <el-table-column
+        prop="createTime"
+        align="center"
+        label="添加时间"
+        show-overflow-tooltip>
+      </el-table-column>
+      <el-table-column
+        align="center"
+        prop="status"
+        label="状态"
+        show-overflow-tooltip>
+      </el-table-column>
+      
+      <el-table-column
+        align="center"
+        prop="stock"
+        label="库存"
+        show-overflow-tooltip>
+      </el-table-column>
+      <el-table-column
+        align="center"
+        prop="number"
+        label="销量"
+        show-overflow-tooltip>
+      </el-table-column>
+      <el-table-column
+        prop="address"
+        align="center"
+        label="操作">
+        <template slot-scope="scope">
+          <el-button type="text" size="small" @click="handleEdit(scope.row)">编辑</el-button>
+          <el-button type="text" size="small" @click="handleDel(scope.$index)">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <div class="page-box">
+        <el-pagination
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+        background
+        :current-page="query.page"
+        :page-sizes="[10, 20, 30, 40]"
+        :page-size="query.pageSize"
+        layout="total, sizes, prev, pager, next, jumper"
+        :total="tableData.length">
+      </el-pagination>
+    </div>
+
+
+    <el-dialog :title="title" :visible.sync="dialogFormVisible" top="8vh" width="550px" custom-class="setting-dialog" :close-on-click-modal="false">
+             <el-form :model="setQuery"  ref="setQuery" :rules="rules" label-width="130px">
+             <el-form-item label="商品名称:" prop="name">
+                <el-input v-model="setQuery.name"  :maxlength="11" class="item-width-300"></el-input>
+            </el-form-item>
+            <el-form-item label="商品类别:" prop="type">
+                <el-input v-model="setQuery.type"  class="item-width-300"></el-input>
+            </el-form-item>
+            <el-form-item label="商铺名称:" prop="shopName">
+                <el-input v-model="setQuery.shopName"  class="item-width-300"></el-input>
+            </el-form-item>
+            <el-form-item label="优惠政策:" prop="discounts">
+                <el-input v-model.number="setQuery.discounts" :min="1" :max="100" type="number" class="item-width-300">
+                    <template slot="append">折</template>
+                </el-input>
+            </el-form-item>
+            <el-form-item label="状态:">
+                <el-switch
+                    v-model="setQuery.status"
+                    active-text="上架中"
+                    inactive-text="下架中"
+                    active-color="#13ce66"
+                    inactive-color="#ff4949">
+                </el-switch>
+            </el-form-item>
+            <el-form-item label="库存:" prop="stock">
+                <el-input v-model.number="setQuery.stock" type="number" class="item-width-300"></el-input>
+            </el-form-item>
+            <el-form-item label="销量:" prop="number">
+                <el-input v-model.number="setQuery.number" type="number" class="item-width-300"></el-input>
+            </el-form-item>
+            </el-form>
+
+             <div slot="footer" class="dialog-footer">
+                <el-button @click="dialogFormVisible = false">取 消</el-button>
+                <el-button type="primary" @click="save">确 定</el-button>
+            </div>
+        </el-dialog>
+  
+    </div>
+  </template>
+  
+  <script>
+
+  export default {
+    name: 'goodsManage',
+    components: {
+    },
+    data() {
+      return {
+          tableData: [
+            {
+                id:1,
+                name:'商品1',
+                type:'类别1',
+                shopName:'中石油',
+                discounts:95,
+                status:'上架中',
+                createTime:'2023-05-23',
+                icon:`https://picsum.photos/750?r111`,
+                stock:231,
+                number:50,
+            },
+            {
+                id:2,
+                name:'商品1',
+                type:'类别1',
+                shopName:'中石油',
+                discounts:95,
+                status:'上架中',
+                createTime:'2023-05-23',
+                icon:`https://picsum.photos/750?r1113`,
+                stock:231,
+                number:50,
+            },
+            {
+                id:3,
+                name:'商品1',
+                type:'类别1',
+                shopName:'中石油',
+                discounts:95,
+                status:'上架中',
+                createTime:'2023-05-23',
+                icon:`https://picsum.photos/750?r1112`,
+                stock:231,
+                number:50,
+            },
+            {
+                id:4,
+                name:'商品1',
+                type:'类别1',
+                shopName:'中石油',
+                discounts:98,
+                status:'上架中',
+                createTime:'2023-05-23',
+                icon:`https://picsum.photos/750?r1`,
+                stock:231,
+                number:50,
+            }
+          ],
+          rules:{
+            name: [
+                { required: true, message: '请输入商品名称', trigger: 'blur' },
+            ],
+            type: [
+                { required: true, message: '请输入商品类别', trigger: 'blur' },
+            ],
+            shopName: [
+                { required: true, message: '请输入商铺名称', trigger: 'blur' },
+            ],
+            discounts: [
+                { required: true, message: '请输入折扣', trigger: 'blur' },
+            ],
+            stock: [
+                { required: true, message: '请输入库存数量', trigger: 'change' },
+            ],
+            number: [
+                { required: true, message: '请输入销售量', trigger: 'change' },
+            ],
+          },
+          loading:false,
+          btnLoading:false,
+          dialogFormVisible:false,
+          query:{
+              name:'',
+              shopName:'',
+              type:'',
+              createTime:[],
+              page:1,
+              pageSize:10,
+          },
+          setQuery:{
+                id:4,
+                name:'商品1',
+                type:'类别1',
+                shopName:'中石油',
+                discounts:'95折',
+                status:'上架中',
+                createTime:'2023-05-23',
+                icon:`https://picsum.photos/750?r1`,
+                stock:231,
+                number:50,
+          },
+          title:'',
+          total:0,
+      }
+    },
+
+    methods: {
+   
+        handleAdd(){
+            this.dialogFormVisible = true
+            this.title = '添加商品'
+            this.setQuery = {
+                id:this.tableData.length+1,
+                name:'商品1',
+                type:'类别1',
+                shopName:'中石油',
+                discounts:'95折',
+                status:'上架中',
+                createTime:'2023-05-23',
+                icon:`https://picsum.photos/750?r1`,
+                stock:0,
+                number:50,
+            }
+        },
+        handleEdit(row){
+            this.dialogFormVisible = true
+            this.title = '编辑员工'
+            this.setQuery = {
+                id:row.id,
+                name:row.name,
+                type:row.type,
+                shopName:row.shopName,
+                discounts:row.discounts,
+                status:row.status,
+                createTime:row.createTime,
+                icon:row.icon,
+                stock:row.stock,
+                number:row.number,
+            }
+   
+        },
+        handleDel(id) {
+        this.$confirm("此操作将永久删除该条数据, 是否继续?", "提示", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning",
+        })
+          .then(() => {
+           this.tableData.splice(id,1)
+          });
+      },
+      save() {
+        this.$refs.setQuery.validate(v=>{
+          if(v){
+            // this.btnLoading = true
+            if(this.title == "添加员工"){
+             this.tableData.push(this.setQuery)
+             this.dialogFormVisible = false
+            }else{
+             this.dialogFormVisible = false
+              
+            }
+          }
+        })
+      },
+        handleSizeChange(val) {
+        this.query.page = 1;
+        this.query.pageSize = val;
+      },
+      handleCurrentChange(val) {
+        this.query.page = val;
+      },
+
+      search(){
+        this.query.page = 1
+      },
+      
+    },
+      created () {
+    },
+  }
+  </script>
+  
+  <style lang="scss" >
+  .goodsManage {
+      .search{
+          padding: 10px 0;
+        box-shadow: 0 1px 4px rgba(0,21,41,.08);
+        margin-bottom: 20px;
+        .el-form-item{
+            margin: 0;
+        }
+      }
+
+      .icon{
+        width: 100px;
+        height: 100px;
+      }
+      .choose-box{
+          width: 300px;
+          min-height: 40px;
+          max-height: 120px;
+          overflow: auto;
+          display: flex;
+          align-items: center;
+          flex-wrap: wrap;
+          border-radius: 4px;
+          border: 1px solid #DCDFE6;
+          padding: 10px 30px 10px 10px;
+          .open-btn{
+              position: absolute;
+              top: 10px;
+              right: 100px;
+              color: #1abc9c;
+              font-size: 28px;
+          }
+          .tab{
+              display: flex;
+              align-items: center;
+              height: 26px;
+              font-size: 12px;
+              color: #999;
+              padding: 4px;
+              border: 1px solid #1abc9c;
+              border-radius: 4px;
+              box-sizing: border-box;
+              margin-bottom: 10px;
+              margin-right: 10px;
+  
+              .name{
+                  font-size: 12px;
+                  color: #666;
+                  margin-right: 6px;
+              }
+              i{
+                  font-size: 16px;
+                  color: #1abc9c;
+                  cursor: pointer;
+              }
+          }
+      }
+  }
+  // 去除表头的全选框  添加文字
+   .user-dialog .el-table__header .el-table-column--selection {
+          .el-checkbox{
+              display: none;
+          }
+          .cell::before{
+              content: '操作';
+          }
+      }
+   
+  .user-dialog{
+       .el-dialog__header{
+           background: #f2f2f2;
+           .el-dialog__title{
+               font-size: 16px;
+               color: #666;
+               font-weight: 600;
+           }
+       }
+      .top{
+          margin-bottom: 10px;
+          display: flex;
+          align-items: center;
+          .text{
+                  margin-left: 15px;
+              .num{
+                  color: #f04844;
+              }
+          }
+      }
+     
+  }
+  .goodsManage .setting-dialog{
+       .el-dialog__header{
+           background: #f2f2f2;
+           .el-dialog__title{
+               font-size: 16px;
+               color: #666;
+               font-weight: 600;
+           }
+       }
+      .top{
+          margin-bottom: 10px;
+          display: flex;
+          align-items: center;
+          .text{
+                  margin-left: 15px;
+              .num{
+                  color: #f04844;
+              }
+          }
+      }
+     
+  }
+  
+  </style>
+  

+ 98 - 0
src/views/home/index.vue

@@ -0,0 +1,98 @@
+<!--
+ * @Author: your name
+ * @Date: 2021-07-08 12:10:55
+ * @LastEditTime: 2023-08-30 16:18:03
+ * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
+ * @Description: In User Settings Edit
+ * @FilePath: \agentManage\src\views\home\index.vue
+-->
+<template>
+  <div class="gameList app-container">
+
+    <div id="chart" style="width: 800px;height: 600px;"></div>
+
+  </div>
+</template>
+
+<script>
+import * as echarts from "echarts";
+import guiyang from "@/utils/map.json";  //地图包
+export default {
+  name: 'gameList',
+  components: {
+  },
+  data() {
+    return {
+      chart: null,
+      option: {
+        title: {
+          text: '贵阳办理套餐人数分布',
+          x: 'center'
+        },
+        dataRange: {
+          min: 0,
+          max: 800,
+          text: ['高', '低'],
+          realtime: true,
+          calculable: true,
+          color: ['orangered', 'yellow', 'green']
+        },
+        tooltip: {
+          trigger: 'item',
+          formatter: '{b}<br/>{c} 人'
+        },
+        series: [
+          {
+            name: '犯罪数量',
+            type: 'map',
+            map: '贵阳',
+            label: {
+              show: true
+            },
+            mapLocation: {
+              y: 60
+            },
+            itemSytle: {
+              emphasis: { label: { show: false } }
+            },
+            data: [
+              { name: '开阳县', value: 700 },
+              { name: '息烽县', value: 600 },
+              { name: '修文县', value: 500 },
+              { name: '清镇市', value: 400 },
+              { name: '云岩区', value: 300 },
+              { name: '南明区', value: 200 },
+              { name: '花溪区', value: 100 },
+              { name: '乌当区', value: 100 },
+              { name: '白云区', value: 100 },
+              { name: '观山湖区', value: 100 },
+            ],
+
+          }
+        ],
+
+      }
+    }
+  },
+  methods: {
+    
+  },
+  created() {
+  },
+  mounted() {
+    this.chart = echarts.init(document.getElementById('chart'))
+    echarts.registerMap("贵阳", guiyang)
+    this.chart.setOption(this.option);
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+.gameList {
+  width: 100%;
+  height: calc(100vh - 50px);
+  // background: url('../../assets/home.png') no-repeat;
+  background-size: 100% 100%;
+  cursor: pointer;
+}
+</style>

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio