haopeifu пре 4 година
родитељ
комит
8166ce2224
79 измењених фајлова са 27818 додато и 15 уклоњено
  1. 1 0
      .env.development
  2. 1 0
      .env.production
  3. 3 14
      .gitignore
  4. 4 0
      Dockerfile
  5. 2 1
      README.md
  6. 14 0
      babel.config.js
  7. 8 0
      build.sh
  8. 18334 0
      package-lock.json
  9. 136 0
      package.json
  10. 3 0
      public/html/style.css
  11. 668 0
      public/html/user_agreement.html
  12. 23 0
      public/index.html
  13. BIN
      public/logo.png
  14. 6 0
      scripts/zip_dist.sh
  15. 29 0
      src/App.vue
  16. 56 0
      src/api/appControlList.js
  17. 21 0
      src/api/common.js
  18. 40 0
      src/api/cp.js
  19. 40 0
      src/api/cpGame.js
  20. 80 0
      src/api/feedback.js
  21. 32 0
      src/api/gameData.js
  22. 79 0
      src/api/gift.js
  23. 103 0
      src/api/giftList.js
  24. 61 0
      src/api/logInfo.js
  25. 19 0
      src/api/login.js
  26. 53 0
      src/api/messageList.js
  27. 24 0
      src/api/miniTest.js
  28. 89 0
      src/api/mini_test.js
  29. 32 0
      src/api/mini_type.js
  30. 42 0
      src/api/order.js
  31. 47 0
      src/api/sysVip.js
  32. 108 0
      src/api/table.js
  33. 28 0
      src/api/verified.js
  34. 158 0
      src/assets/css/global.less
  35. 265 0
      src/components/CommonList.vue
  36. 110 0
      src/config/router.config.js
  37. 106 0
      src/core/lazy_lib/components_use.js
  38. 164 0
      src/core/lazy_lib/components_use_vue.js
  39. 11 0
      src/core/lazy_use.js
  40. 15 0
      src/logger.js
  41. 38 0
      src/main.js
  42. 17 0
      src/router/index.js
  43. 7 0
      src/store/getters.js
  44. 18 0
      src/store/index.js
  45. 1 0
      src/store/modules/app.js
  46. 125 0
      src/store/modules/common_list.js
  47. 0 0
      src/store/mutation-types.js
  48. 33 0
      src/utils/device.js
  49. 19 0
      src/utils/domUtil.js
  50. 38 0
      src/utils/filter.js
  51. 51 0
      src/utils/mixin.js
  52. 8 0
      src/utils/permissions.js
  53. 50 0
      src/utils/service.js
  54. 77 0
      src/utils/storage.js
  55. 195 0
      src/utils/util.js
  56. 180 0
      src/views/appControlList/appControlList.vue
  57. 299 0
      src/views/cp/cpList.vue
  58. 309 0
      src/views/cpGame/cpGameList.vue
  59. 111 0
      src/views/feedbackDetail/feedbackDetail.vue
  60. 279 0
      src/views/feedbackGame/feedbackGame.vue
  61. 221 0
      src/views/feedbackList/feedbackList.vue
  62. 161 0
      src/views/gameData/gameData.vue
  63. 217 0
      src/views/giftCodeList/giftCodeList.vue
  64. 296 0
      src/views/giftGameList/giftGameList.vue
  65. 486 0
      src/views/giftList/giftList.vue
  66. 136 0
      src/views/loginLogList/loginLogList.vue
  67. 177 0
      src/views/message/messageList.vue
  68. 134 0
      src/views/miniTestList/MiniTypeList.vue
  69. 64 0
      src/views/miniTestList/miniTestList.vue
  70. 412 0
      src/views/order/orderList.vue
  71. 235 0
      src/views/table/table.vue
  72. 553 0
      src/views/test/Test2.vue
  73. 141 0
      src/views/test/TestCommon.vue
  74. 111 0
      src/views/userWhiteList/userWhiteList.vue
  75. 299 0
      src/views/verified/verified.vue
  76. 555 0
      src/views/vip/Test2.vue
  77. 667 0
      src/views/vip/vipList.vue
  78. 1 0
      test.css
  79. 82 0
      vue.config.js

+ 1 - 0
.env.development

@@ -0,0 +1 @@
+VUE_APP_HOST=http://localhost:8082

+ 1 - 0
.env.production

@@ -0,0 +1 @@
+VUE_APP_HOST=http://manage.funcheergame.com

+ 3 - 14
.gitignore

@@ -1,14 +1,3 @@
-# ---> Java
-*.class
-
-# Mobile Tools for Java (J2ME)
-.mtj.tmp/
-
-# Package Files #
-*.jar
-*.war
-*.ear
-
-# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
-hs_err_pid*
-
+node_modules/
+dist/
+.idea

+ 4 - 0
Dockerfile

@@ -0,0 +1,4 @@
+FROM nginx
+RUN rm -rf /usr/share/nginx/html/index.html
+RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
+COPY dist/ /usr/share/nginx/html/

+ 2 - 1
README.md

@@ -1,2 +1,3 @@
-# FengqiGame
+# FengqiAdminVue
 
+凤起后台vue页面

+ 14 - 0
babel.config.js

@@ -0,0 +1,14 @@
+module.exports = {
+  presets: [
+    '@vue/app',
+    [
+      '@babel/preset-env',
+      {
+        'useBuiltIns': 'entry'
+      }
+    ]
+  ],
+  plugins: [
+    ["@babel/plugin-transform-modules-commonjs", { "strictMode": false }]
+  ]
+}

+ 8 - 0
build.sh

@@ -0,0 +1,8 @@
+#!/bin/bash
+sudo git pull http://linxiaozhe:792724060@47.96.66.225:10080/linxiaozhe/FengqiAdminVue.git
+sudo npm run build
+sudo docker build -t fengqi-admin .
+sudo docker rm -f fengqi-admin
+sudo docker run -d -p 8080:80 --name=fengqi-admin fengqi-admin
+
+#

Разлика између датотеке није приказан због своје велике величине
+ 18334 - 0
package-lock.json


+ 136 - 0
package.json

@@ -0,0 +1,136 @@
+{
+  "name": "halo-admin",
+  "version": "1.0.3",
+  "private": true,
+  "scripts": {
+    "serve": "vue-cli-service serve",
+    "build": "vue-cli-service build",
+    "lint": "vue-cli-service lint",
+    "test:unit": "vue-cli-service test:unit"
+  },
+  "dependencies": {
+    "animate.css": "^3.7.0",
+    "ant-design-vue": "~1.3.13",
+    "axios": "^0.18.0",
+    "element-ui": "^2.10.1",
+    "enquire.js": "^2.1.6",
+    "marked": "^0.6.2",
+    "mavon-editor": "^2.7.4",
+    "moment": "^2.24.0",
+    "nprogress": "^0.2.0",
+    "semver": "^7.3.2",
+    "v-viewer": "^1.4.2",
+    "viser-vue": "^2.4.6",
+    "vue": "^2.6.10",
+    "vue-awesome-swiper": "^3.1.3",
+    "vue-clipboard2": "^0.3.0",
+    "vue-codemirror-lite": "^1.0.4",
+    "vue-count-to": "^1.0.13",
+    "vue-cropper": "0.4.9",
+    "vue-ls": "^3.2.1",
+    "vue-material": "^1.0.0-beta-11",
+    "vue-router": "^3.0.6",
+    "vue-video-player": "^5.0.2",
+    "vuedraggable": "^2.23.2",
+    "vuejs-logger": "^1.5.3",
+    "vuex": "^3.1.1"
+  },
+  "devDependencies": {
+    "@babel/plugin-transform-modules-commonjs": "^7.5.0",
+    "@babel/plugin-transform-strict-mode": "^7.2.0",
+    "@babel/polyfill": "^7.4.4",
+    "@vue/cli-plugin-babel": "^3.8.0",
+    "@vue/cli-plugin-eslint": "^3.8.0",
+    "@vue/cli-plugin-unit-jest": "^3.8.0",
+    "@vue/cli-service": "^3.8.0",
+    "@vue/eslint-config-standard": "^4.0.0",
+    "@vue/test-utils": "^1.0.0-beta.20",
+    "babel-core": "7.0.0-bridge.0",
+    "babel-eslint": "^10.0.1",
+    "babel-jest": "^24.8.0",
+    "babel-plugin-import": "^1.11.2",
+    "eslint": "^5.16.0",
+    "eslint-plugin-html": "^5.0.5",
+    "eslint-plugin-vue": "^5.2.2",
+    "generate-asset-webpack-plugin": "^0.3.0",
+    "less": "^3.9.0",
+    "less-loader": "^5.0.0",
+    "vue-svg-icon-loader": "^2.1.1",
+    "vue-template-compiler": "^2.6.10"
+  },
+  "eslintConfig": {
+    "root": true,
+    "env": {
+      "node": true
+    },
+    "extends": [
+      "plugin:vue/strongly-recommended",
+      "@vue/standard"
+    ],
+    "parserOptions": {
+      "parser": "babel-eslint"
+    },
+    "rules": {
+      "space-before-function-paren": [
+        "error",
+        "never"
+      ],
+      "generator-star-spacing": "off",
+      "no-mixed-operators": 0,
+      "vue/max-attributes-per-line": [
+        2,
+        {
+          "singleline": 5,
+          "multiline": {
+            "max": 1,
+            "allowFirstLine": false
+          }
+        }
+      ],
+      "vue/attribute-hyphenation": 0,
+      "vue/html-self-closing": 0,
+      "vue/component-name-in-template-casing": 0,
+      "vue/html-closing-bracket-spacing": 0,
+      "vue/singleline-html-element-content-newline": 0,
+      "vue/no-unused-components": 0,
+      "vue/multiline-html-element-content-newline": 0,
+      "vue/no-use-v-if-with-v-for": 0,
+      "vue/html-closing-bracket-newline": 0,
+      "vue/no-parsing-error": 0,
+      "no-console": 0,
+      "no-tabs": 0,
+      "quotes": [
+        2,
+        "single",
+        {
+          "avoidEscape": true,
+          "allowTemplateLiterals": true
+        }
+      ],
+      "semi": [
+        2,
+        "never",
+        {
+          "beforeStatementContinuationChars": "never"
+        }
+      ],
+      "no-delete-var": 2,
+      "prefer-const": [
+        2,
+        {
+          "ignoreReadBeforeAssign": false
+        }
+      ]
+    }
+  },
+  "postcss": {
+    "plugins": {
+      "autoprefixer": {}
+    }
+  },
+  "browserslist": [
+    "> 1%",
+    "last 2 versions",
+    "not ie <= 10"
+  ]
+}

+ 3 - 0
public/html/style.css

@@ -0,0 +1,3 @@
+p {
+    text-indent: 2rem;
+}

Разлика између датотеке није приказан због своје велике величине
+ 668 - 0
public/html/user_agreement.html


+ 23 - 0
public/index.html

@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html lang="zh-cmn-Hans">
+  <head>
+    <meta charset="utf-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
+    <meta name="robots" content="noindex,nofllow" />
+    <meta name="generator" content="Halo" />
+    <link rel="icon" href="<%= BASE_URL %>logo.png" />
+    <title>Halo Dashboard</title>
+  </head>
+
+  <body>
+    <noscript>
+      <strong
+        >We're sorry but vue-antd-pro 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>


+ 6 - 0
scripts/zip_dist.sh

@@ -0,0 +1,6 @@
+#!/bin/bash
+PACKAGE_VERSION=$(sed -nE 's/^\s*"version": "(.*?)",$/\1/p' package.json)
+echo "Halo admin version $PACKAGE_VERSION"
+zip -r dist/halo-admin-$PACKAGE_VERSION.zip dist
+
+export PACKAGE_VERSION

+ 29 - 0
src/App.vue

@@ -0,0 +1,29 @@
+<template>
+
+    <div id="app">
+        <router-view/>
+    </div>
+</template>
+
+<script>
+
+    export default {
+        name: 'app',
+        methods: {},
+        watch: {
+
+            $route(to, from) {
+                console.log("路由变化");
+                this.$store.commit('REFRESH_STATE')
+            }
+        }
+    }
+</script>
+
+<style lang="less">
+    @import url('./assets/css/global.less');
+
+    #app {
+        height: 100%;
+    }
+</style>

+ 56 - 0
src/api/appControlList.js

@@ -0,0 +1,56 @@
+import service from '@/utils/service'
+
+const baseUrl = process.env.VUE_APP_HOST + '/manage/api';
+
+const appControlApi = {};
+
+appControlApi.baseUrl = baseUrl;
+
+
+appControlApi.getAppControlList = () => {
+  return service({
+    url: `${baseUrl}/appControl/list`,
+    method: 'get',
+  })
+};
+
+appControlApi.updateAppControlList = data => {
+  return service({
+    url: `${baseUrl}/appControl/v1`,
+    method: 'put',
+    data:data
+  })
+};
+
+appControlApi.addAppControlList = data =>{
+  return service({
+    url: `${baseUrl}/appControl/v1`,
+    method: 'post',
+    data:data
+  })
+}
+
+appControlApi.getGameList = () => {
+  return service({
+    url: process.env.VUE_APP_HOST  + `/manager/api/feedback/game/list`,
+    method: 'get'
+  })
+};
+
+appControlApi.getChannelList = () => {
+  return service({
+    url: `${baseUrl}/appControl/channel/list`,
+    method: 'get'
+  })
+};
+
+
+// miniTestApi.getMiniClassList = () => {
+//   return service({
+//     url: `${baseUrl}/miniTest/v1/list`,
+//     method: 'get',
+//   })
+// };
+
+
+export default appControlApi

+ 21 - 0
src/api/common.js

@@ -0,0 +1,21 @@
+import service from '@/utils/service'
+
+// const baseUrl = 'http://localhost:8082/manager/api/order'
+
+const baseUrl = process.env.VUE_APP_HOST;
+
+const commonApi = {};
+
+commonApi.baseUrl = baseUrl;
+
+commonApi.getPolicy = path => {
+    return service({
+        url: `${baseUrl}/upload/aliyun/getUploadOssPolicy`,
+        method: 'post',
+        data: {path:path}
+    })
+}
+
+
+export default commonApi
+

+ 40 - 0
src/api/cp.js

@@ -0,0 +1,40 @@
+import service from '@/utils/service'
+
+const baseUrl = process.env.VUE_APP_HOST + '/manager/api/cp'
+
+const cpApi = {}
+
+cpApi.baseUrl = baseUrl
+
+cpApi.getList = params => {
+  return service({
+    url: `${baseUrl}/v1/list`,
+    method: 'get',
+    params: params
+  })
+}
+
+cpApi.getById = id => {
+  return service({
+    url: `${baseUrl}/v1/${id}`,
+    method: 'get',
+  })
+}
+
+cpApi.add = data => {
+  return service({
+    url: `${baseUrl}/v1`,
+    method: 'post',
+    data: data
+  })
+}
+
+cpApi.update = data => {
+  return service({
+    url: `${baseUrl}/v1`,
+    method: 'put',
+    data: data
+  })
+}
+
+export default cpApi

+ 40 - 0
src/api/cpGame.js

@@ -0,0 +1,40 @@
+import service from '@/utils/service'
+
+const baseUrl = process.env.VUE_APP_HOST + '/manager/api/cp_game'
+
+const cpGame = {}
+
+cpGame.baseUrl = baseUrl
+
+cpGame.getList = params => {
+  return service({
+    url: `${baseUrl}/v1/list`,
+    method: 'get',
+    params: params
+  })
+}
+
+cpGame.getById = id => {
+  return service({
+    url: `${baseUrl}/v1/${id}`,
+    method: 'get',
+  })
+}
+
+cpGame.add = data => {
+  return service({
+    url: `${baseUrl}/v1`,
+    method: 'post',
+    data: data
+  })
+}
+
+cpGame.update = data => {
+  return service({
+    url: `${baseUrl}/v1`,
+    method: 'put',
+    data: data
+  })
+}
+
+export default cpGame

+ 80 - 0
src/api/feedback.js

@@ -0,0 +1,80 @@
+import service from '@/utils/service'
+
+const baseUrl = process.env.VUE_APP_HOST + '/manager/api';
+
+const feedbackApi = {};
+
+feedbackApi.baseUrl = baseUrl;
+
+feedbackApi.getGameList = () => {
+    return service({
+        url: `${baseUrl}/feedback/game/list`,
+        method: 'get'
+    })
+};
+
+
+feedbackApi.getFeedbackGameList = () => {
+    return service({
+        url: `${baseUrl}/feedback/v1/list`,
+        method: 'get',
+        params: {deleted: 0}
+    })
+};
+
+feedbackApi.getFeedbackGameById = id => {
+    return service({
+        url: `${baseUrl}/feedback/v1/${id}`,
+        method: 'get',
+    })
+};
+
+feedbackApi.addFeedbackGame = data => {
+    return service({
+        url: `${baseUrl}/feedback/v1`,
+        method: 'post',
+        data: data
+    })
+};
+
+feedbackApi.updateFeedbackGame = data => {
+    return service({
+        url: `${baseUrl}/feedback/v1`,
+        method: 'put',
+        data: data
+    })
+};
+
+feedbackApi.deleteFeedbackGame = id => {
+    return service({
+        url: `${baseUrl}/feedback/v1/${id}`,
+        method: 'delete',
+    })
+};
+
+feedbackApi.getFeedbackList = params => {
+    return service({
+        url: `${baseUrl}/feedbackServer/v1/page`,
+        method: 'get',
+        params: params
+    })
+};
+
+
+feedbackApi.getFeedbackById = id => {
+    return service({
+        url: `${baseUrl}/feedbackServer/v1/${id}`,
+        method: 'get',
+    })
+};
+
+feedbackApi.updateFeedback = data => {
+    return service({
+        url: `${baseUrl}/feedbackServer/v1`,
+        method: 'put',
+        data: data
+    })
+};
+
+
+export default feedbackApi

+ 32 - 0
src/api/gameData.js

@@ -0,0 +1,32 @@
+import service from '@/utils/service'
+
+const baseUrl = process.env.VUE_APP_HOST + '/manager/api';
+
+const gameDataApi = {};
+
+gameDataApi.baseUrl = baseUrl;
+
+gameDataApi.getGameData = params => {
+  return service({
+    url: `${baseUrl}/v1/getGameData`,
+    method: 'get',
+    params:params
+  })
+};
+
+gameDataApi.getAllGameData = params => {
+  return service({
+    url: `${baseUrl}/v1/getAllGameData`,
+    method: 'get',
+    params:params
+  })
+};
+
+gameDataApi.getCollections = () => {
+  return service({
+    url: `${baseUrl}/v1/getCollections`,
+    method: 'get',
+  })
+};
+
+export default gameDataApi

+ 79 - 0
src/api/gift.js

@@ -0,0 +1,79 @@
+import service from '@/utils/service'
+
+const baseUrl = process.env.VUE_APP_HOST + '/manager/api';
+
+const giftApi = {};
+
+giftApi.baseUrl = baseUrl;
+
+
+
+giftApi.getGiftGameList = () => {
+    return service({
+        url: `${baseUrl}/giftGame/v1/list`,
+        method: 'get',
+        params: {deleted: 0}
+    })
+};
+
+giftApi.getGiftGameById = id => {
+    return service({
+        url: `${baseUrl}/giftGame/v1/${id}`,
+        method: 'get',
+    })
+};
+
+giftApi.addGiftGame = data => {
+    return service({
+        url: `${baseUrl}/giftGame/v1`,
+        method: 'post',
+        data: data
+    })
+};
+
+giftApi.updateGiftGame = data => {
+    return service({
+        url: `${baseUrl}/giftGame/v1`,
+        method: 'put',
+        data: data
+    })
+};
+
+giftApi.deleteGiftGame = id => {
+    return service({
+        url: `${baseUrl}/giftGame/v1`,
+        method: 'put',
+        data: {
+            id,
+            deleted:1
+        }
+
+    })
+};
+
+// giftApi.getFeedbackList = params => {
+//     return service({
+//         url: `${baseUrl}/feedbackServer/v1/page`,
+//         method: 'get',
+//         params: params
+//     })
+// };
+//
+//
+// giftApi.getFeedbackById = id => {
+//     return service({
+//         url: `${baseUrl}/feedbackServer/v1/${id}`,
+//         method: 'get',
+//     })
+// };
+//
+// giftApi.updateFeedback = data => {
+//     return service({
+//         url: `${baseUrl}/feedbackServer/v1`,
+//         method: 'put',
+//         data: data
+//     })
+// };
+
+
+export default giftApi

+ 103 - 0
src/api/giftList.js

@@ -0,0 +1,103 @@
+import service from '@/utils/service'
+
+const baseUrl = process.env.VUE_APP_HOST + '/manager/api';
+
+const giftListApi = {};
+
+giftListApi.baseUrl = baseUrl;
+
+
+
+giftListApi.getGameList = () => {
+    return service({
+        url: `${baseUrl}/gift/v1/game`,
+        method: 'get',
+    })
+};
+giftListApi.getGiftList = params => {
+    return service({
+        url: `${baseUrl}/gift/v1/page`,
+        method: 'get',
+        params: params
+    })
+};
+giftListApi.addGift = data => {
+    return service({
+        url: `${baseUrl}/gift/v1/insert`,
+        method: 'post',
+        data: data
+    })
+};
+giftListApi.updateGift = data =>{
+    return service({
+        url: `${baseUrl}/gift/v1`,
+        method: 'put',
+        data: data
+    })
+}
+
+giftListApi.getGiftById = id => {
+    return service({
+        url: `${baseUrl}/gift/v1/${id}`,
+        method: 'get',
+    })
+};
+giftListApi.deleteGift = id =>{
+    return service({
+        url: `${baseUrl}/gift/v1`,
+        method: 'put',
+        data:{
+            id,
+            deleted : 1
+        }
+    })
+};
+
+
+giftListApi.getGiftGameList = () =>{
+    return service({
+        url: `${baseUrl}/giftCode/v1/game`,
+        method: 'get',
+    })
+};
+giftListApi.getGiftCodeList = params =>{
+    return service({
+        url: `${baseUrl}/giftCode/v1/page`,
+        method: 'get',
+        params:params
+    })
+};
+giftListApi.getGiftCodeById = id =>{
+    return service({
+        url: `${baseUrl}/giftCode/v1/${id}`,
+        method: 'get',
+    })
+};
+giftListApi.updateGiftCode = data =>{
+    return service({
+        url: `${baseUrl}/giftCode/v1`,
+        method: 'put',
+        data:data
+    })
+};
+giftListApi.deleteGiftCode = id =>{
+    return service({
+        url: `${baseUrl}/giftCode/v1`,
+        method: 'put',
+        data:{
+            id,
+            deleted:1
+        }
+    })
+};
+giftListApi.addGiftCode = data => {
+    return service({
+        url: `${baseUrl}/giftCode/v1/insert`,
+        method: 'post',
+        data: data
+    })
+};
+
+
+
+export default giftListApi

+ 61 - 0
src/api/logInfo.js

@@ -0,0 +1,61 @@
+import service from '@/utils/service'
+
+const baseUrl = process.env.VUE_APP_HOST + '/manager/api'
+
+const logInfoApi = {};
+
+logInfoApi.baseUrl = baseUrl;
+
+
+logInfoApi.getLoginLogList = params => {
+    return service({
+        url: `${baseUrl}/whiteList/loginList`,
+        method: 'get',
+        params: params
+    })
+};
+logInfoApi.getLoginLogByUid = params => {
+    return service({
+        url: `${baseUrl}/whiteList/getLoginLogByUid`,
+        method: 'get',
+        params: params
+    })
+};
+logInfoApi.banPerson = params =>{
+    return service({
+        url: `${baseUrl}/whiteList/ban`,
+        method: 'post',
+        params: params
+    })
+};
+
+
+// ↓ whiteListApi
+
+
+logInfoApi.getWhiteList = params =>{
+    return service({
+        url: `${baseUrl}/whiteList/list`,
+        method: 'get',
+        params: params
+    })
+};
+logInfoApi.addWhiteList = data =>{
+    return service({
+        url: `${baseUrl}/whiteList/v1`,
+        method: 'post',
+        data: data
+    })
+};
+logInfoApi.deleteWhiteList = id =>{
+    return service({
+        url: `${baseUrl}/whiteList/v1/${id}`,
+        method: 'delete',
+    })
+};
+
+
+
+
+
+export default logInfoApi

+ 19 - 0
src/api/login.js

@@ -0,0 +1,19 @@
+import service from '@/utils/service'
+
+const baseUrl = process.env.VUE_APP_HOST + '/system/user'
+
+const loginApi = {}
+
+loginApi.baseUrl = baseUrl
+
+loginApi.authCodeUrl = `${baseUrl}/authCode.json`
+
+loginApi.login = data => {
+  return service({
+    url: `${baseUrl}/loginSystem.json`,
+    method: 'post',
+    data: data
+  })
+}
+
+export default loginApi

+ 53 - 0
src/api/messageList.js

@@ -0,0 +1,53 @@
+import service from '@/utils/service'
+
+const baseUrl = process.env.VUE_APP_HOST + '/manager/api';
+
+const messageList = {};
+
+messageList.baseUrl = baseUrl;
+
+
+
+messageList.getMessageList = () => {
+    return service({
+        url: `${baseUrl}/message/v1/list`,
+        method: 'get',
+    })
+};
+messageList.getMessageById = id => {
+    return service({
+        url: `${baseUrl}/message/v1/${id}`,
+        method: 'get',
+    })
+};
+messageList.updateMessage = date => {
+    return service({
+        url: `${baseUrl}/message/v1/`,
+        method: 'put',
+        data:date
+    })
+};
+messageList.addMessage = date => {
+    return service({
+        url: `${baseUrl}/message/v1/`,
+        method: 'post',
+        data:date
+    })
+};
+
+messageList.deleteMessage = id => {
+    return service({
+        url: `${baseUrl}/message/v1/${id}`,
+        method: 'delete',
+    })
+};
+
+messageList.refreshMessage = () => {
+    return service({
+        url: `${baseUrl}/message/refreshMessage`,
+        method: 'post',
+    })
+};
+
+
+export default messageList

+ 24 - 0
src/api/miniTest.js

@@ -0,0 +1,24 @@
+import service from '@/utils/service'
+
+const baseUrl = process.env.VUE_APP_HOST + '/manager/api';
+
+const miniTestApi = {};
+
+miniTestApi.baseUrl = baseUrl;
+
+
+miniTestApi.getMiniTestList = () => {
+    return service({
+        url: `${baseUrl}/miniTest/list`,
+        method: 'get',
+    })
+};
+miniTestApi.getMiniClassList = () => {
+    return service({
+        url: `${baseUrl}/miniTest/v1/list`,
+        method: 'get',
+    })
+};
+
+
+export default miniTestApi

+ 89 - 0
src/api/mini_test.js

@@ -0,0 +1,89 @@
+import service from '@/utils/service'
+import miniTypeApi from './mini_type'
+
+const baseUrl = process.env.VUE_APP_HOST + '/manager/api';
+
+const miniApi = {};
+
+miniApi.baseUrl = baseUrl;
+
+
+
+miniApi.class_update = data => {
+    return service({
+        url: `${baseUrl}/miniClass/v1`,
+        method: 'put',
+        data: data
+    })
+};
+
+miniApi.type_update = data => {
+    return service({
+        url: `${baseUrl}/miniType/v1`,
+        method: 'put',
+        data: data
+    })
+};
+
+miniApi.result_update = data => {
+    return service({
+        url: `${baseUrl}/miniResult/v1`,
+        method: 'put',
+        data: data
+    })
+};
+
+miniApi.question_update = data => {
+    return service({
+        url: `${baseUrl}/miniQuestion/v1`,
+        method: 'put',
+        data: data
+    })
+};
+
+miniApi.option_update = data => {
+    return service({
+        url: `${baseUrl}/miniOption/v1`,
+        method: 'put',
+        data: data
+    })
+};
+
+
+
+
+miniApi.list = params => {
+    return service({
+        url: `${baseUrl}/miniClass/list2`,
+        method: 'get',
+        params: params
+    })
+};
+
+miniApi.class_list = params => {
+    return service({
+        url: `${baseUrl}/miniClass/v1/list`,
+        method: 'get',
+        params: params
+    })
+};
+
+
+
+miniApi.upload_excel = formData => {
+    return service({
+        url: `${baseUrl}/miniType/v1/upload/excel`,
+        method: 'post',
+        data: formData
+    })
+};
+
+miniApi.freshCDN = () =>{
+  return service({
+    url: `${baseUrl}/miniClass/refresh`,
+    method: 'post',
+  })
+};
+
+
+export default miniApi

+ 32 - 0
src/api/mini_type.js

@@ -0,0 +1,32 @@
+import service from '@/utils/service'
+
+const baseUrl = process.env.VUE_APP_HOST + '/manager/api';
+
+const miniTypeApi = {};
+
+miniTypeApi.baseUrl = baseUrl;
+
+
+
+
+miniTypeApi.list = params => {
+    return service({
+        url: `${baseUrl}/miniType/v1/list`,
+        method: 'get',
+        params: params
+    })
+};
+
+miniTypeApi.class_list = params => {
+    return service({
+        url: `${baseUrl}/miniClass/v1/list`,
+        method: 'get',
+        params: params
+    })
+};
+
+
+
+
+
+export default miniTypeApi

+ 42 - 0
src/api/order.js

@@ -0,0 +1,42 @@
+import service from '@/utils/service'
+
+// const baseUrl = 'http://localhost:8082/manager/api/order'
+
+const baseUrl = process.env.VUE_APP_HOST + '/manager/api/order'
+
+const orderApi = {}
+
+orderApi.baseUrl = baseUrl
+
+orderApi.getOrderList = params => {
+  return service({
+    url: `${baseUrl}/v1/list`,
+    method: 'get',
+    params: params
+  })
+};
+
+orderApi.getSelectOptions = () => {
+  return service({
+    url: `${baseUrl}/v1/select`,
+    method: 'get'
+  })
+};
+
+orderApi.getExcel = data => {
+  return service({
+    url: `${baseUrl}/v1/excel`,
+    method: 'post',
+    data: data
+  })
+};
+
+orderApi.getExcelV2 = params => {
+    return service({
+        url: `${baseUrl}/v2/excel`,
+        method: 'get',
+        params: params
+    })
+};
+
+export default orderApi

+ 47 - 0
src/api/sysVip.js

@@ -0,0 +1,47 @@
+import service from '@/utils/service'
+
+const baseUrl = process.env.VUE_APP_HOST + '/manager/api/vip'
+
+const vipApi = {}
+
+vipApi.baseUrl = baseUrl
+
+vipApi.getVipList = params => {
+  return service({
+    url: `${baseUrl}/v1/statistics`,
+    method: 'get',
+    params: params
+  })
+}
+
+vipApi.getSelectOptions = () => {
+  return service({
+    url: `${baseUrl}/v1/select`,
+    method: 'get'
+  })
+}
+
+vipApi.addVip = data => {
+  return service({
+    url: `${baseUrl}/v1`,
+    method: 'post',
+    data: data
+  })
+}
+
+vipApi.updateVip = data => {
+  return service({
+    url: `${baseUrl}/v1`,
+    method: 'put',
+    data: data
+  })
+}
+
+vipApi.getById = id => {
+  return service({
+    url: `${baseUrl}/v1/${id}`,
+    method: 'get'
+  })
+}
+
+export default vipApi

+ 108 - 0
src/api/table.js

@@ -0,0 +1,108 @@
+import service from '@/utils/service'
+
+const baseUrl = process.env.VUE_APP_HOST + '/manager/api';
+
+const tableApi = {};
+
+tableApi.baseUrl = baseUrl;
+
+
+
+tableApi.getButtonList = () => {
+    return service({
+        url: `${baseUrl}/button/list`,
+        method: 'get',
+    })
+};
+tableApi.addButton = data => {
+    return service({
+        url: `${baseUrl}/button/v1`,
+        method: 'post',
+        data:data
+    })
+};
+tableApi.addSubButton = data => {
+    return service({
+        url: `${baseUrl}/subButton/v1`,
+        method: 'post',
+        data:data
+    })
+};
+
+
+tableApi.deleteButton = id => {
+    return service({
+        url: `${baseUrl}/button/v1/${id}`,
+        method: 'delete',
+    })
+};
+tableApi.deleteSubButton = id => {
+    return service({
+        url: `${baseUrl}/subButton/v1/${id}`,
+        method: 'delete',
+    })
+};
+tableApi.getSubById = id =>{
+    return service({
+        url: `${baseUrl}/subButton/v1/${id}`,
+        method: 'get',
+    })
+};
+
+tableApi.updateSub = data =>{
+    return service({
+        url: `${baseUrl}/subButton/v1`,
+        method: 'put',
+        data:data
+    })
+};
+
+
+tableApi.setMenu = () =>{
+    return service({
+        url: `${baseUrl}/menu/setMenu`,
+        method: 'post',
+    })
+};
+
+
+tableApi.getMenuList = data =>{
+    return service({
+        url: `${baseUrl}/menu/v1/list`,
+        method: 'get',
+        data:data
+    })
+};
+tableApi.getMenuById = id =>{
+    return service({
+        url: `${baseUrl}/menu/v1/${id}`,
+        method: 'get',
+    })
+};
+tableApi.addMenu = data => {
+    return service({
+        url: `${baseUrl}/menu/v1`,
+        method: 'post',
+        data:data
+    })
+};
+tableApi.deleteMenu = id => {
+    return service({
+        url: `${baseUrl}/menu/v1/${id}`,
+        method: 'delete',
+    })
+};
+tableApi.updateSub = data =>{
+    return service({
+        url: `${baseUrl}/menu/v1`,
+        method: 'put',
+        data:data
+    })
+};
+
+
+
+
+
+
+export default tableApi

+ 28 - 0
src/api/verified.js

@@ -0,0 +1,28 @@
+import service from '@/utils/service'
+
+const baseUrl = process.env.VUE_APP_HOST + '/manager/api/verified_config';
+
+const verifiedApi = {};
+
+verifiedApi.baseUrl = baseUrl;
+
+
+
+verifiedApi.getVerifiedConfigList = params => {
+    return service({
+        url: `${baseUrl}/v1/list`,
+        method: 'get',
+        params: params
+    })
+};
+
+verifiedApi.getAdList = () => {
+    return service({
+        url: `${baseUrl}/ad/v1`,
+        method: 'get',
+    })
+};
+
+
+
+export default verifiedApi

+ 158 - 0
src/assets/css/global.less

@@ -0,0 +1,158 @@
+* {
+  padding: 0;
+  margin: 0;
+  border: 0;
+  box-sizing: border-box;
+}
+
+html, body {
+  height: 100%;
+  font: 12px/1.5 "Microsoft Yahei",Arial,"Helvetica Neue","Hiragino Sans GB","Heiti SC","WenQuanYi Micro Hei",sans-serif;
+}
+
+body {
+  margin: 0;
+  border: 0;
+  padding: 0;
+}
+
+a {
+  text-decoration: none;
+  color: #000;
+  outline: 0;
+}
+
+* {
+  &::-webkit-scrollbar {
+    width: 8px;
+    height: 6px;
+  }
+
+  &::-webkit-scrollbar-thumb {
+    height: 50px;
+    background: #ddd;
+    cursor: pointer;
+    border-radius: 10px;
+  }
+
+  &::-webkit-scrollbar-track {
+    width: 20px;
+    background-color: #fff;
+  }
+
+  outline: 0;
+}
+
+.headrow {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: space-between;
+  flex-wrap: nowrap;
+}
+
+.flex-start {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: flex-start;
+  flex-wrap: nowrap;
+}
+
+.content {
+  .el-form {
+    margin: 0 auto;
+  }
+}
+
+.list {
+  overflow: hidden;
+  margin: 8px;
+  flex: 1;
+}
+
+.page {
+  margin: 8px;
+  display: -webkit-flex;
+  display: flex;
+
+  .el-pagination {
+    align-self: flex-end;
+  }
+}
+
+.flex-space-between {
+  display: flex;
+  justify-content: space-between;
+}
+
+#login {
+  .el-input-group__prepend {
+    padding: 0 14px !important;
+  }
+}
+
+.my-bullet {
+  display: inline-block;
+  height: 12px;
+  width: 12px;
+  background: #ffffff;
+  margin-left: 10px;
+  border-radius: 100%;
+  cursor: pointer;
+  opacity: .3;
+  transition: width .4s ease-in;
+}
+
+.my-bullet-active {
+  display: inline-block;
+  height: 12px;
+  width: 45px;
+  opacity: 1;
+  background: #ffffff;
+  border-radius: 16px;
+}
+.swiper-container-horizontal > .swiper-pagination-bullets{
+  bottom: 60px !important;
+}
+.motion {
+    transition: all .3s ease-out;
+}
+.color-write {
+    color: #ffffff;
+}
+
+.flex-display {
+  height: 100%;
+  overflow: hidden;
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  .head {
+    margin: 4px;
+
+    .head-item {
+      display: inline-block;
+      margin: 4px;
+    }
+
+    .action {
+      margin: 4px;
+    }
+  }
+  .list {
+    overflow: hidden;
+    margin: 8px;
+    flex: 1;
+  }
+
+  .page {
+    margin: 8px;
+    display: -webkit-flex;
+    display: flex;
+
+    .el-pagination {
+      align-self: flex-end;
+    }
+  }
+}

+ 265 - 0
src/components/CommonList.vue

@@ -0,0 +1,265 @@
+<template>
+    <div class="common-list flex-display">
+        <div class="head">
+            <div class="text">
+                <div class="head-wrapper" v-for="head in head_list">
+                    <el-select
+                            v-if="head.type == 'select'"
+                            v-model="params[head.model]"
+                            :placeholder="head.placeholder"
+                            filterable
+                            clearable
+                    >
+                        <el-option
+                                v-for="item in head_data_map[head.list]"
+                                :key="item[head.prop.value]"
+                                :label="item[head.prop.text]"
+                                :value="item[head.prop.value]"
+                        ></el-option>
+                    </el-select>
+                </div>
+            </div>
+            <div class="action">
+                <div class="action-item" v-for="action in action_list">
+                    <el-button plain
+                               :type="action.type || 'primary'"
+                               :icon="action.icon"
+                               @click="handel_action(action.click,action.params)"
+                    >{{action.value}}
+                    </el-button>
+                </div>
+
+            </div>
+        </div>
+        <div class="list">
+            <el-table :data="table_data.slice((page.cur-1)*page.size,page.cur*page.size)"
+                      border stripe
+                      :fit="false"
+                      height="100%"
+            >
+
+                <div v-for="table_item in table_list">
+
+                    <el-table-column
+                            v-if="table_item.type && table_item.type === 'bool_tag'"
+                            :label="table_item.label"
+                            :prop="table_item.prop"
+                            :width="table_item.width || '150'"
+                            show-overflow-tooltip
+                    >
+
+                        <template slot-scope="scope">
+                            <el-tag :type="scope.row[table_item.prop] ? 'success': 'info'">
+                                {{bool_tag(scope.row[table_item.prop])}}
+                            </el-tag>
+                        </template>
+
+                    </el-table-column>
+
+
+                    <el-table-column
+                            v-else
+                            :label="table_item.label"
+                            :prop="table_item.prop"
+                            width="150"
+                            show-overflow-tooltip
+                    />
+                </div>
+
+
+                <el-table-column label="操作" width="180">
+                    <template slot-scope="scope">
+                        <div class="headrow">
+                            <el-button type="text" size="mini" @click="handel_update(scope.row[table_props.id])">编辑
+                            </el-button>
+                            <el-button size="mini" type="text" @click="handel_delete(scope.row[table_props.id])">删除
+                            </el-button>
+                        </div>
+                    </template>
+                </el-table-column>
+            </el-table>
+        </div>
+
+        <div class="page">
+            <el-pagination
+                    @size-change="handle_size_change"
+                    @current-change="handle_current_change"
+                    layout="total, sizes, prev, pager, next, jumper"
+                    :page-size="page.size"
+                    :pager-count="11"
+                    :total="page.total"
+            ></el-pagination>
+        </div>
+
+        <el-dialog :title="dialog.title" :visible.sync="dialog.visible" center @close="handel_dialog_cancel">
+            <div class="content">
+                <el-form label-width="100px" :model="dialog_dto" ref="ruleForm">
+
+                    <el-form-item
+                            v-for="dialog_item in dialog_list"
+                            :label="dialog_item.label"
+                            :prop="dialog_item.prop"
+                    >
+                        <el-input v-model.trim="dialog_data[dialog_item.prop]" :placeholder="dialog_item.placeholder"/>
+                    </el-form-item>
+
+                </el-form>
+
+            </div>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="handel_dialog_cancel">取 消</el-button>
+                <el-button type="primary" @click="handel_dialog_conform">确 定</el-button>
+            </span>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+    import {mapState, mapActions} from 'vuex'
+
+    export default {
+        name: "CommonList",
+        computed: {
+            ...mapState({
+                head_list: state => state.common_list.head_list,
+                head_data_map: state => state.common_list.head_data_map,
+
+                action_list: state => state.common_list.action_list,
+
+                table_list: state => state.common_list.table_list,
+                table_data: state => state.common_list.table_data,
+
+                dialog_list: state => state.common_list.dialog_list,
+                dialog_data: state => state.common_list.dialog_data,
+
+                page: state => state.common_list.page,
+
+                table_props: state => state.common_list.table_props,
+
+            }),
+        },
+        data() {
+            return {
+                params: {},
+                isUpdate: false,
+                total: 0,
+                pageSize: 20,
+                curPage: 1,
+                dialog: {
+                    title: 'dialog',
+                    visible: false
+                },
+                dialog_dto: {}
+            }
+        },
+        mounted() {
+            // this.init();
+        },
+        methods: {
+            ...mapActions(['set_page_size', 'set_cur_page']),
+
+            init() {
+
+            },
+
+            handel_action(click, params) {
+                if (params) {
+                    this.$emit(click, this[params]);
+                } else {
+                    this.$emit(click);
+                }
+
+            },
+
+
+            handel_search() {
+                this.$emit('handel_search', this.params);
+            },
+            handel_click_add() {
+
+            },
+            handel_update(id) {
+                this.$emit('handel_update', id, () => {
+                    this.dialog.visible = true
+                });
+
+            },
+            handel_delete(id) {
+                this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    type: 'warning'
+                }).then(() => {
+                    this.$emit('handel_search', id);
+                }).catch(() => {
+                    this.$message({
+                        type: 'info',
+                        message: '已取消删除'
+                    });
+                });
+            },
+            handel_dialog_cancel() {
+                this.dialog.visible = false;
+            },
+            handel_dialog_conform() {
+                console.log(this.dialog_data)
+            },
+            /**
+             * 处理前端分页
+             * @param val
+             */
+            handle_size_change(val) {
+                if (this.table_props.is_local_page) {
+                    this.set_page_size(val)
+                } else {
+                    this.params.size = val;
+                    this.handel_search()
+                }
+            },
+            handle_current_change(val) {
+
+                if (this.table_props.is_local_page) {
+                    this.set_cur_page(val)
+                } else {
+                    this.params.cur = val;
+                    this.handel_search()
+                }
+            },
+            file_uploader(params) {
+                this.$emit('handel_upload', params);
+            },
+            file_verified(params) {
+                let file_name = params.name;
+                let ext = file_name.substr(file_name.lastIndexOf('.') + 1, file_name.length - 1);
+                return ext === 'xls' || ext === 'xlsx';
+            },
+            bool_tag(item) {
+                return item ? "是" : "否"
+            },
+            load(tree, treeNode, resolve) {
+                console.log(tree)
+            }
+        }
+    }
+</script>
+
+<style lang="less" scoped>
+    .common-list {
+
+        .head {
+            .text {
+                padding: 4px;
+                .head-wrapper {
+                    display: inline-block;
+                }
+            }
+            .action {
+                display: flex;
+                justify-content: flex-start;
+                .action-item {
+                    margin-right: 8px;
+                }
+            }
+        }
+    }
+</style>

+ 110 - 0
src/config/router.config.js

@@ -0,0 +1,110 @@
+export const asyncRouterMap = [
+    {
+        path: '/order',
+        name: 'orderList',
+        component: () => import('@/views/order/orderList')
+    },
+    {
+        path: '/vip',
+        name: 'vipList',
+        component: () => import('@/views/vip/vipList')
+    },
+    {
+        path: '/cp',
+        name: 'cpList',
+        component: () => import('@/views/cp/cpList')
+    },
+    {
+        path: '/cp_game',
+        name: 'cpGame',
+        component: () => import('@/views/cpGame/cpGameList')
+    },
+    {
+        path: '/feedback_game',
+        name: 'feedbackGame',
+        component: () => import('@/views/feedbackGame/feedbackGame')
+    },
+    {
+        path: '/feedback_list',
+        name: 'feedbackList',
+        component: () => import('@/views/feedbackList/feedbackList')
+    },
+    {
+        path: '/feedback_detail',
+        name: 'feedbackDetail',
+        component: () => import('@/views/feedbackDetail/feedbackDetail')
+    },
+    {
+        path: '/gift_game_list',
+        name: 'giftGameList',
+        component: () => import('@/views/giftGameList/giftGameList')
+    },
+    {
+        path: '/gift_list',
+        name: 'giftList',
+        component: () => import('@/views/giftList/giftList')
+    },
+    {
+        path: '/gift_code_list',
+        name: 'giftCodeList',
+        component: () => import('@/views/giftCodeList/giftCodeList')
+    },
+    {
+        path: '/table',
+        name: 'tableList',
+        component: () => import('@/views/table/table')
+    },
+    {
+        path: '/message',
+        name: 'messageList',
+        component: () => import('@/views/message/messageList')
+    },
+    {
+        path: '/user_white_list',
+        name: 'userWhiteList',
+        component: () => import('@/views/userWhiteList/userWhiteList')
+    },
+    {
+        path: '/login_log_list',
+        name: 'loginLogList',
+        component: () => import('@/views/loginLogList/loginLogList')
+    },
+    {
+        path: '/verified',
+        name: 'verified',
+        component: () => import('@/views/verified/verified')
+    },
+    {
+        path: '/test',
+        name: 'test',
+        component: () => import('@/views/test/TestCommon.vue')
+    },
+    {
+        path: '/test2',
+        name: 'test2',
+        component: () => import('@/views/test/Test2.vue')
+    },
+    {
+        path: '/mini_type',
+        name: 'MiniTypeList',
+        component: () => import('@/views/miniTestList/MiniTypeList')
+    },
+    {
+      path: '/gameData',
+      name: 'gameData',
+      component: () => import('@/views/gameData/gameData')
+    },
+  {
+    path: '/appControlList',
+    name: 'appControlList',
+    component: () => import('@/views/appControlList/appControlList')
+  },
+
+
+];
+
+/**
+ * 基础路由
+ * @type { *[] }
+ */
+export const constantRouterMap = []

+ 106 - 0
src/core/lazy_lib/components_use.js

@@ -0,0 +1,106 @@
+import Vue from 'vue'
+import {
+  Anchor,
+  AutoComplete,
+  Alert,
+  Avatar,
+  Badge,
+  Breadcrumb,
+  Button,
+  Card,
+  Collapse,
+  Checkbox,
+  Col,
+  DatePicker,
+  Divider,
+  Dropdown,
+  Form,
+  Icon,
+  Input,
+  InputNumber,
+  Layout,
+  List,
+  LocaleProvider,
+  message,
+  Menu,
+  Modal,
+  notification,
+  Pagination,
+  Popconfirm,
+  Popover,
+  Progress,
+  Radio,
+  Row,
+  Select,
+  Spin,
+  Switch,
+  Table,
+  Tree,
+  TreeSelect,
+  Tabs,
+  Tag,
+  TimePicker,
+  Tooltip,
+  Upload,
+  Drawer,
+  Skeleton,
+  Comment,
+  ConfigProvider,
+  Timeline,
+  Steps
+} from 'ant-design-vue'
+
+Vue.use(Anchor)
+Vue.use(AutoComplete)
+Vue.use(Alert)
+Vue.use(Avatar)
+Vue.use(Badge)
+Vue.use(Breadcrumb)
+Vue.use(Button)
+Vue.use(Card)
+Vue.use(Collapse)
+Vue.use(Checkbox)
+Vue.use(Col)
+Vue.use(DatePicker)
+Vue.use(Divider)
+Vue.use(Drawer)
+Vue.use(Dropdown)
+Vue.use(Form)
+Vue.use(Icon)
+Vue.use(Input)
+Vue.use(InputNumber)
+Vue.use(Layout)
+Vue.use(List)
+Vue.use(LocaleProvider)
+Vue.use(Menu)
+Vue.use(Modal)
+Vue.use(Pagination)
+Vue.use(Popconfirm)
+Vue.use(Popover)
+Vue.use(Progress)
+Vue.use(Radio)
+Vue.use(Row)
+Vue.use(Select)
+Vue.use(Spin)
+Vue.use(Switch)
+Vue.use(Table)
+Vue.use(Tree)
+Vue.use(TreeSelect)
+Vue.use(Tabs)
+Vue.use(Tag)
+Vue.use(TimePicker)
+Vue.use(Tooltip)
+Vue.use(Upload)
+Vue.use(Skeleton)
+Vue.use(Comment)
+Vue.use(ConfigProvider)
+Vue.use(Timeline)
+Vue.use(Steps)
+
+Vue.prototype.$message = message
+Vue.prototype.$notification = notification
+Vue.prototype.$info = Modal.info
+Vue.prototype.$success = Modal.success
+Vue.prototype.$error = Modal.error
+Vue.prototype.$warning = Modal.warning
+Vue.prototype.$confirm = Modal.confirm

+ 164 - 0
src/core/lazy_lib/components_use_vue.js

@@ -0,0 +1,164 @@
+import Vue from 'vue';
+import {
+  Pagination,
+  Dialog,
+  Autocomplete,
+  Dropdown,
+  DropdownMenu,
+  DropdownItem,
+  Menu,
+  Submenu,
+  MenuItem,
+  MenuItemGroup,
+  Input,
+  InputNumber,
+  Radio,
+  RadioGroup,
+  RadioButton,
+  Checkbox,
+  CheckboxButton,
+  CheckboxGroup,
+  Switch,
+  Select,
+  Option,
+  OptionGroup,
+  Button,
+  ButtonGroup,
+  Table,
+  TableColumn,
+  DatePicker,
+  TimeSelect,
+  TimePicker,
+  Popover,
+  Tooltip,
+  Breadcrumb,
+  BreadcrumbItem,
+  Form,
+  FormItem,
+  Tabs,
+  TabPane,
+  Tag,
+  Tree,
+  Alert,
+  Slider,
+  Icon,
+  Row,
+  Col,
+  Upload,
+  Progress,
+  Spinner,
+  Badge,
+  Card,
+  Rate,
+  Steps,
+  Step,
+  Carousel,
+  CarouselItem,
+  Collapse,
+  CollapseItem,
+  Cascader,
+  ColorPicker,
+  Transfer,
+  Container,
+  Header,
+  Aside,
+  Main,
+  Footer,
+  Timeline,
+  TimelineItem,
+  Link,
+  Divider,
+  Image,
+  Calendar,
+  Backtop,
+  PageHeader,
+  CascaderPanel,
+  Loading,
+  MessageBox,
+  Message,
+  Notification
+} from 'element-ui';
+
+Vue.use(Pagination);
+Vue.use(Dialog);
+Vue.use(Autocomplete);
+Vue.use(Dropdown);
+Vue.use(DropdownMenu);
+Vue.use(DropdownItem);
+Vue.use(Menu);
+Vue.use(Submenu);
+Vue.use(MenuItem);
+Vue.use(MenuItemGroup);
+Vue.use(Input);
+Vue.use(InputNumber);
+Vue.use(Radio);
+Vue.use(RadioGroup);
+Vue.use(RadioButton);
+Vue.use(Checkbox);
+Vue.use(CheckboxButton);
+Vue.use(CheckboxGroup);
+Vue.use(Switch);
+Vue.use(Select);
+Vue.use(Option);
+Vue.use(OptionGroup);
+Vue.use(Button);
+Vue.use(ButtonGroup);
+Vue.use(Table);
+Vue.use(TableColumn);
+Vue.use(DatePicker);
+Vue.use(TimeSelect);
+Vue.use(TimePicker);
+Vue.use(Popover);
+Vue.use(Tooltip);
+Vue.use(Breadcrumb);
+Vue.use(BreadcrumbItem);
+Vue.use(Form);
+Vue.use(FormItem);
+Vue.use(Tabs);
+Vue.use(TabPane);
+Vue.use(Tag);
+Vue.use(Tree);
+Vue.use(Alert);
+Vue.use(Slider);
+Vue.use(Icon);
+Vue.use(Row);
+Vue.use(Col);
+Vue.use(Upload);
+Vue.use(Progress);
+Vue.use(Spinner);
+Vue.use(Badge);
+Vue.use(Card);
+Vue.use(Rate);
+Vue.use(Steps);
+Vue.use(Step);
+Vue.use(Carousel);
+Vue.use(CarouselItem);
+Vue.use(Collapse);
+Vue.use(CollapseItem);
+Vue.use(Cascader);
+Vue.use(ColorPicker);
+Vue.use(Transfer);
+Vue.use(Container);
+Vue.use(Header);
+Vue.use(Aside);
+Vue.use(Main);
+Vue.use(Footer);
+Vue.use(Timeline);
+Vue.use(TimelineItem);
+Vue.use(Link);
+Vue.use(Divider);
+Vue.use(Image);
+Vue.use(Calendar);
+Vue.use(Backtop);
+Vue.use(PageHeader);
+Vue.use(CascaderPanel);
+
+Vue.use(Loading.directive);
+
+Vue.prototype.$loading = Loading.service;
+Vue.prototype.$msgbox = MessageBox;
+Vue.prototype.$alert = MessageBox.alert;
+Vue.prototype.$confirm = MessageBox.confirm;
+Vue.prototype.$prompt = MessageBox.prompt;
+Vue.prototype.$notify = Notification;
+Vue.prototype.$message = Message;

+ 11 - 0
src/core/lazy_use.js

@@ -0,0 +1,11 @@
+
+// base library
+// import '@/core/lazy_lib/components_use'
+// import 'ant-design-vue/dist/antd.less'
+
+
+
+
+import '@/core/lazy_lib/components_use_vue'
+import 'element-ui/lib/theme-chalk/index.css';
+

+ 15 - 0
src/logger.js

@@ -0,0 +1,15 @@
+import Vue from 'vue'
+import VueLogger from 'vuejs-logger'
+
+const isProduction = process.env.NODE_ENV === 'production'
+const options = {
+  isEnabled: true,
+  logLevel: isProduction ? 'error' : 'debug',
+  stringifyArguments: false,
+  showLogLevel: true,
+  showMethodName: true,
+  separator: '|',
+  showConsoleColors: true
+}
+
+Vue.use(VueLogger, options)

+ 38 - 0
src/main.js

@@ -0,0 +1,38 @@
+import '@babel/polyfill'
+import Vue from 'vue'
+import App from './App.vue'
+import router from './router'
+import './logger'
+
+import './core/lazy_use'
+import { version } from '../package.json'
+import Element from 'element-ui';
+import locale from 'element-ui/lib/locale/lang/en'
+import VueAwesomeSwiper from 'vue-awesome-swiper'
+import Viewer from 'v-viewer'
+import 'viewerjs/dist/viewer.css'
+// require styles
+import 'swiper/dist/css/swiper.css'
+import store from './store/'
+// import VueMaterial from 'vue-material'
+// import 'vue-material/dist/theme/default.css'
+// import 'vue-material/dist/vue-material.css'
+
+Viewer.setDefaults({
+    zIndexInline: 9999
+});
+Vue.use(Viewer);
+
+// Vue.use(VueMaterial) //Required to boot vue material
+Vue.use(VueAwesomeSwiper, /* { default global options } */);
+Vue.use(Element, { size: 'small', zIndex: 3000},{locale});
+Vue.config.productionTip = false;
+Vue.prototype.VERSION = version;
+
+Vue.use(router);
+
+new Vue({
+  router,
+  store,
+  render: h => h(App)
+}).$mount('#app');

+ 17 - 0
src/router/index.js

@@ -0,0 +1,17 @@
+import Vue from 'vue'
+import Router from 'vue-router'
+import {
+  constantRouterMap,
+  asyncRouterMap
+} from '@/config/router.config'
+
+Vue.use(Router)
+
+export default new Router({
+  mode: 'hash',
+  base: process.env.BASE_URL,
+  scrollBehavior: () => ({
+    y: 0
+  }),
+  routes: constantRouterMap.concat(asyncRouterMap)
+})

+ 7 - 0
src/store/getters.js

@@ -0,0 +1,7 @@
+const getters = {
+    head_list: state => state.common_list.head_list,
+    table_list: state => state.common_list.table_list
+
+};
+
+export default getters

+ 18 - 0
src/store/index.js

@@ -0,0 +1,18 @@
+import Vue from 'vue'
+import Vuex from 'vuex'
+import common_list from './modules/common_list'
+
+import getters from './getters'
+
+
+Vue.use(Vuex);
+
+export default new Vuex.Store({
+    modules: {
+        common_list
+    },
+    state: {},
+    mutations: {},
+    actions: {},
+    getters
+})

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

@@ -0,0 +1 @@
+import Vue from 'vue'

+ 125 - 0
src/store/modules/common_list.js

@@ -0,0 +1,125 @@
+import Vue from 'vue'
+
+const default_state = {
+    head_list: [],
+    action_list: [],
+    table_list: [],
+    head_data_map: {},
+    table_data: [],
+    page: {
+        total: 0,
+        size: 20,
+        cur: 1,
+    },
+
+    table_props: {
+        is_local_page: true,
+        id: 'id',
+        load: 'load_tree'
+    },
+    dialog_list:[],
+    dialog_data:{}
+};
+
+const common_list = {
+    state: JSON.parse(JSON.stringify(default_state)),
+    mutations: {
+        SET_HEAD_LIST: (state, head_list) => {
+            state.head_list = head_list;
+        },
+
+        SET_ACTION_LIST: (state, action_list) => {
+            state.action_list = action_list;
+        },
+
+        SET_TABLE_LIST: (state, table_list) => {
+            state.table_list = table_list;
+        },
+
+        SET_HEAD_DATA_MAP: (state, head_data_map) => {
+            state.head_data_map = head_data_map;
+        },
+
+        SET_DIALOG_LIST: (state, dialog_list) => {
+            state.dialog_list = dialog_list;
+        },
+
+        SET_DIALOG_DATA: (state, dialog_data) => {
+            state.dialog_data = dialog_data;
+        },
+
+        SET_TABLE_DATA: (state, table_data) => {
+            state.table_data = table_data;
+            if (state.table_props.is_local_page) {
+                state.page.total = table_data.length
+            }
+        },
+
+        SET_TOTAL: (state, total) => {
+            state.page.total = total;
+        },
+
+        SET_PAGE_SIZE: (state, page_size) => {
+            state.page.size = page_size;
+        },
+
+        SET_CUR_PAGE: (state, cur_page) => {
+            state.page.cur = cur_page;
+        },
+
+        SET_IS_LOCAL_PAGE: (state, is_local_page) => {
+            state.table_props.is_local_page = is_local_page;
+        },
+
+        REFRESH_STATE: (state) => {
+            console.log("刷新了vuex");
+            state = JSON.parse(JSON.stringify(default_state));
+            console.log(state);
+        },
+
+    },
+    actions: {
+        set_head_list({commit}, item) {
+            commit('SET_HEAD_LIST', item)
+        },
+
+        set_action_list({commit}, item) {
+            commit('SET_ACTION_LIST', item)
+        },
+
+
+        set_table_list({commit}, item) {
+            commit('SET_TABLE_LIST', item)
+        },
+
+        set_head_data_map({commit}, item) {
+            commit('SET_HEAD_DATA_MAP', item)
+        },
+
+        set_table_data({commit}, item) {
+            commit('SET_TABLE_DATA', item)
+        },
+
+        set_dialog_list({commit}, item) {
+            commit('SET_DIALOG_LIST', item)
+        },
+
+        set_dialog_data({commit}, item) {
+            commit('SET_DIALOG_DATA', item)
+        },
+
+        set_page_size({commit}, item) {
+            commit('SET_PAGE_SIZE', item)
+        },
+
+        set_cur_page({commit}, item) {
+            commit('SET_CUR_PAGE', item)
+        },
+
+        refresh_state({commit}) {
+            commit('REFRESH_STATE');
+        },
+    },
+};
+
+export default common_list

+ 0 - 0
src/store/mutation-types.js


+ 33 - 0
src/utils/device.js

@@ -0,0 +1,33 @@
+import enquireJs from 'enquire.js'
+
+export const DEVICE_TYPE = {
+  DESKTOP: 'desktop',
+  TABLET: 'tablet',
+  MOBILE: 'mobile'
+}
+
+export const deviceEnquire = function(callback) {
+  const matchDesktop = {
+    match: () => {
+      callback && callback(DEVICE_TYPE.DESKTOP)
+    }
+  }
+
+  const matchLablet = {
+    match: () => {
+      callback && callback(DEVICE_TYPE.TABLET)
+    }
+  }
+
+  const matchMobile = {
+    match: () => {
+      callback && callback(DEVICE_TYPE.MOBILE)
+    }
+  }
+
+  // screen and (max-width: 1087.99px)
+  enquireJs
+    .register('screen and (max-width: 576px)', matchMobile)
+    .register('screen and (min-width: 576px) and (max-width: 1199px)', matchLablet)
+    .register('screen and (min-width: 1200px)', matchDesktop)
+}

+ 19 - 0
src/utils/domUtil.js

@@ -0,0 +1,19 @@
+export const setDocumentTitle = function(title) {
+  document.title = title
+  const ua = navigator.userAgent
+  // eslint-disable-next-line
+    const regex = /\bMicroMessenger\/([\d\.]+)/
+  if (regex.test(ua) && /ip(hone|od|ad)/i.test(ua)) {
+    const i = document.createElement('iframe')
+    i.src = '/favicon.ico'
+    i.style.display = 'none'
+    i.onload = function() {
+      setTimeout(function() {
+        i.remove()
+      }, 9)
+    }
+    document.body.appendChild(i)
+  }
+}
+
+export const domTitle = 'Halo Dashboard'

+ 38 - 0
src/utils/filter.js

@@ -0,0 +1,38 @@
+import Vue from 'vue'
+import moment from 'moment'
+import 'moment/locale/zh-cn'
+import {
+  timeAgo
+} from '@/utils/util'
+moment.locale('zh-cn')
+
+Vue.filter('NumberFormat', function(value) {
+  if (!value) {
+    return '0'
+  }
+  const intPartFormat = value.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,') // 将整数部分逢三一断
+  return intPartFormat
+})
+
+Vue.filter('dayjs', function(dataStr, pattern = 'YYYY-MM-DD HH:mm') {
+  return moment(dataStr).format(pattern)
+})
+
+Vue.filter('moment', function(dataStr, pattern = 'YYYY-MM-DD HH:mm') {
+  return moment(dataStr).format(pattern)
+})
+
+Vue.filter('timeAgo', timeAgo)
+
+Vue.filter('fileSizeFormat', function(value) {
+  if (!value) {
+    return '0 Bytes'
+  }
+  var unitArr = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
+  var index = 0
+  var srcsize = parseFloat(value)
+  index = Math.floor(Math.log(srcsize) / Math.log(1024))
+  var size = srcsize / Math.pow(1024, index)
+  size = size.toFixed(2)
+  return size + ' ' + unitArr[index]
+})

+ 51 - 0
src/utils/mixin.js

@@ -0,0 +1,51 @@
+// import Vue from 'vue'
+import { DEVICE_TYPE } from '@/utils/device'
+import { mapState } from 'vuex'
+
+// const mixinsComputed = Vue.config.optionMergeStrategies.computed
+// const mixinsMethods = Vue.config.optionMergeStrategies.methods
+
+const mixin = {
+  computed: {
+    ...mapState({
+      layoutMode: state => state.app.layout,
+      navTheme: state => state.app.theme,
+      primaryColor: state => state.app.color,
+      fixedHeader: state => state.app.fixedHeader,
+      fixSiderbar: state => state.app.fixSiderbar,
+      fixSidebar: state => state.app.fixSiderbar,
+      contentWidth: state => state.app.contentWidth,
+      autoHideHeader: state => state.app.autoHideHeader,
+      sidebarOpened: state => state.app.sidebar
+    })
+  },
+  methods: {
+    isTopMenu() {
+      return this.layoutMode === 'topmenu'
+    },
+    isSideMenu() {
+      return !this.isTopMenu()
+    }
+  }
+}
+
+const mixinDevice = {
+  computed: {
+    ...mapState({
+      device: state => state.app.device
+    })
+  },
+  methods: {
+    isMobile() {
+      return this.device === DEVICE_TYPE.MOBILE
+    },
+    isDesktop() {
+      return this.device === DEVICE_TYPE.DESKTOP
+    },
+    isTablet() {
+      return this.device === DEVICE_TYPE.TABLET
+    }
+  }
+}
+
+export { mixin, mixinDevice }

+ 8 - 0
src/utils/permissions.js

@@ -0,0 +1,8 @@
+export function actionToObject(json) {
+  try {
+    return JSON.parse(json)
+  } catch (e) {
+    
+  }
+  return []
+}

+ 50 - 0
src/utils/service.js

@@ -0,0 +1,50 @@
+import axios from 'axios'
+import NProgress from 'nprogress'
+import 'nprogress/nprogress.css'
+import {Message} from 'element-ui'
+
+const service = axios.create({
+    timeout: 60000,
+    // withCredentials: true
+});
+
+service.interceptors.request.use(
+    config => {
+        if (!config.mute) {
+            NProgress.start()
+        }
+        return config
+    },
+    error => {
+        NProgress.remove();
+        Message.error('服务异常');
+        return Promise.reject(error)
+    }
+);
+
+service.interceptors.response.use(
+    response => {
+        NProgress.done();
+        if (response.data.res_info) {
+            if (response.data.res_info.response_code !== '00000') {
+                Message.error(response.data.res_info.response_msg)
+            }
+            return response.data.body
+        } else {
+            if (response.data.code !== 200) {
+                Message.error(response.data.msg)
+            }
+            return response.data.data
+        }
+    },
+    error => {
+        Message.error('服务异常');
+        NProgress.done();
+        if (axios.isCancel(error)) {
+            return Promise.reject(error)
+        }
+        return Promise.reject(error)
+    }
+);
+
+export default service

+ 77 - 0
src/utils/storage.js

@@ -0,0 +1,77 @@
+/**
+ * Set storage
+ *
+ * @param name
+ * @param content
+ * @param maxAge
+ */
+export const setStore = (name, content, maxAge = null) => {
+  if (!global.window || !name) {
+    return
+  }
+
+  if (typeof content !== 'string') {
+    content = JSON.stringify(content)
+  }
+
+  const storage = global.window.localStorage
+
+  storage.setItem(name, content)
+  if (maxAge && !isNaN(parseInt(maxAge))) {
+    const timeout = parseInt(new Date().getTime() / 1000)
+    storage.setItem(`${name}_expire`, timeout + maxAge)
+  }
+}
+
+/**
+ * Get storage
+ *
+ * @param name
+ * @returns {*}
+ */
+export const getStore = name => {
+  if (!global.window || !name) {
+    return
+  }
+
+  const content = window.localStorage.getItem(name)
+  const _expire = window.localStorage.getItem(`${name}_expire`)
+
+  if (_expire) {
+    const now = parseInt(new Date().getTime() / 1000)
+    if (now > _expire) {
+      return
+    }
+  }
+
+  try {
+    return JSON.parse(content)
+  } catch (e) {
+    return content
+  }
+}
+
+/**
+ * Clear storage
+ *
+ * @param name
+ */
+export const clearStore = name => {
+  if (!global.window || !name) {
+    return
+  }
+
+  window.localStorage.removeItem(name)
+  window.localStorage.removeItem(`${name}_expire`)
+}
+
+/**
+ * Clear all storage
+ */
+export const clearAll = () => {
+  if (!global.window || !name) {
+    return
+  }
+
+  window.localStorage.clear()
+}

+ 195 - 0
src/utils/util.js

@@ -0,0 +1,195 @@
+import moment from 'moment'
+import 'moment/locale/zh-cn'
+import commonApi from '@/api/common'
+
+
+export async function uploadFile(file, callback) {
+
+    if (!file) {
+        return
+    }
+
+    let folder = 'giftIcon';
+    let path = folder + '/' + new Date().toLocaleDateString().split('/').join('-');
+    commonApi.getPolicy(path).then(res => {
+        console.log(res);
+        console.log(file);
+        let fileName = uuid(32) + file.name.substring(file.name.lastIndexOf("."), file.name.length);
+        console.log("fileName: ", fileName);
+        const fd = new FormData();
+        const {accessid, host, policy, signature, dir, cdnUrl} = res;
+        fd.append('OSSAccessKeyId', accessid);
+        fd.append('policy', policy);
+        fd.append('signature', signature);
+        fd.append('key', dir + '/' + fileName);
+        fd.append('success_action_status', 200);
+        fd.append('file', file, fileName);
+        const xhr = new XMLHttpRequest();
+        xhr.open('post', host, true);
+        //控制进度条的
+        // xhr.upload.addEventListener('progress', (evt) => {
+        //     let progress = Math.round((evt.loaded) * 100 / evt.total);
+        //     progressfn && progressfn(progress);
+        //
+        // }, false);
+        xhr.addEventListener('load', (e) => {
+            if (e.target.status !== 200) {
+                return
+            }
+            if (e.target.status === 200) {
+                callback && callback(cdnUrl + '/' + dir + '/' + fileName);
+            }
+        }, false);
+        xhr.send(fd)
+    })
+
+}
+
+export function uuid(len, radix) {
+    var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
+    var uuid = [], i;
+    radix = radix || chars.length;
+
+    if (len) {
+        // Compact form
+        for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
+    } else {
+        // rfc4122, version 4 form
+        var r;
+
+        // rfc4122 requires these characters
+        uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
+        uuid[14] = '4';
+
+        // Fill in random data.  At i==19 set the high bits of clock sequence as
+        // per rfc4122, sec. 4.1.5
+        for (i = 0; i < 36; i++) {
+            if (!uuid[i]) {
+                r = 0 | Math.random() * 16;
+                uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
+            }
+        }
+    }
+
+    return uuid.join('');
+}
+
+
+/**
+ * 触发 window.resize
+ */
+export function triggerWindowResizeEvent() {
+  const event = document.createEvent('HTMLEvents')
+  event.initEvent('resize', true, true)
+  event.eventType = 'message'
+  window.dispatchEvent(event)
+}
+
+/**
+ * Remove loading animate
+ * @param id parent element id or class
+ * @param timeout
+ */
+export function removeLoadingAnimate(id = '', timeout = 1500) {
+  if (id === '') {
+    return
+  }
+  setTimeout(() => {
+    document.body.removeChild(document.getElementById(id))
+  }, timeout)
+}
+
+export function timeAgo(time) {
+  var currentTime = new Date().getTime()
+  var between = currentTime - time
+  var days = Math.floor(between / (24 * 3600 * 1000))
+  if (days === 0) {
+    var leave1 = between % (24 * 3600 * 1000)
+    var hours = Math.floor(leave1 / (3600 * 1000))
+    if (hours === 0) {
+      var leave2 = leave1 % (3600 * 1000)
+      var minutes = Math.floor(leave2 / (60 * 1000))
+      if (minutes === 0) {
+        var leave3 = leave2 % (60 * 1000)
+        var seconds = Math.round(leave3 / 1000)
+        return seconds + ' 秒前'
+      }
+      return minutes + ' 分钟前'
+    }
+    return hours + ' 小时前'
+  }
+  if (days < 0) return '刚刚'
+  if (days < 5) {
+    return days + ' 天前'
+  } else {
+    return moment(time).format('YYYY-MM-DD HH:mm')
+  }
+}
+
+export function isObject(value) {
+  return value && typeof value === 'object' && value.constructor === Object
+}
+
+export function download (res,name) {
+  if (!res) {
+      return
+  }
+  let blob = new Blob([res.data],{type: res.headers['content-type']});
+  let downloadElement = document.createElement('a');
+  let href = window.URL.createObjectURL(blob); //创建下载的链接
+  downloadElement.href = href;
+  downloadElement.download = name; //下载后文件名
+  document.body.appendChild(downloadElement);
+  downloadElement.click(); //点击下载
+  document.body.removeChild(downloadElement); //下载完成移除元素
+  window.URL.revokeObjectURL(href); //释放掉blob对象
+}
+
+
+export function getLastDay(day) {
+  let today = new Date(new Date(new Date().toLocaleDateString()).getTime() + 24 * 60 * 60 * 1000 -1) //今天23:59:59
+  let lastDay = new Date(new Date(new Date(today.getFullYear(),today.getMonth(),today.getDate()-day).toLocaleDateString()).getTime()) //day天前的00:00:00
+  return [lastDay,today]
+}
+
+
+function formatNumber (n) {
+  n = n.toString()
+  return n[1] ? n : '0' + n
+}
+
+export function formatTime(date) {
+  const year = date.getFullYear()
+  const month = date.getMonth() + 1
+  const day = date.getDate()
+  const hour = date.getHours()
+  const minute = date.getMinutes()
+  const second = date.getSeconds()
+
+  return [year, month, day].map(formatNumber).join('-') + ' ' + [hour, minute, second].map(formatNumber).join(':')
+}
+
+//获取cookie、
+export function getCookie(name) {
+  var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
+  if (arr = document.cookie.match(reg))
+    return (arr[2]);
+  else
+    return null;
+}
+
+//设置cookie,增加到vue实例方便全局调用
+export function setCookie (c_name, value, expiredays) {
+  var exdate = new Date();
+  exdate.setDate(exdate.getDate() + expiredays);
+  document.cookie = c_name + "=" + escape(value) + ((expiredays == null) ? "" : ";expires=" + exdate.toGMTString());
+};
+
+//删除cookie
+export function delCookie (name) {
+  var exp = new Date();
+  exp.setTime(exp.getTime() - 1);
+  var cval = getCookie(name);
+  if (cval != null)
+   document.cookie = name + "=" + cval + ";expires=" + exp.toGMTString()
+};

+ 180 - 0
src/views/appControlList/appControlList.vue

@@ -0,0 +1,180 @@
+<template>
+    <div class="appControlList flex-display">
+        <div class="head">
+            <div class="text">
+
+                <el-button plain type="success" icon="el-icon-circle-plus-outline" @click="handelClickAdd">新增</el-button>
+            </div>
+        </div>
+
+        <div class="list">
+            <el-table :data="appControlList.slice((curPage-1)*pageSize,curPage*pageSize)" border stripe :fit="false" height="100%" >
+                <el-table-column label="编号" prop="id" width="150" show-overflow-tooltip/>
+                <el-table-column label="渠道id" prop="channelName" width="150" show-overflow-tooltip/>
+                <el-table-column label="游戏id" prop="gameName" width="150" show-overflow-tooltip/>
+                <el-table-column label="渠道标识" prop="adFlag" width="150" show-overflow-tooltip/>
+                <el-table-column label="类型" prop="type" width="150" show-overflow-tooltip/>
+                <el-table-column label="文本值" prop="text" width="150" show-overflow-tooltip/>
+                <el-table-column label="状态" prop="state" width="150"
+                                 :formatter="formatState" show-overflow-tooltip/>
+                <el-table-column label="操作" width="180">
+                    <template slot-scope="scope">
+                        <div class="headrow" >
+                            <el-button size="mini" type="success" @click="updateAppControlList(scope.row)" v-if="scope.row.state !== 1">开启</el-button>
+                            <el-button size="mini" type="danger" @click="updateAppControlList(scope.row)" v-if="scope.row.state !== 0">关闭</el-button>
+                        </div>
+                    </template>
+                </el-table-column>
+
+            </el-table>
+
+        </div>
+
+        <el-dialog :title="dialog.title" :visible.sync="dialog.visible" center @close="handelCancel">
+            <div class="content">
+                <el-form  label-width="80px">
+
+                    <el-form-item label="游戏">
+                        <el-select v-model="dialogDto.gameId" placeholder="请选择游戏" filterable clearable>
+                            <el-option
+                                    v-for="item in gameList"
+                                    :key="item.gameId"
+                                    :label="item.gameId + '_' +item.gameName"
+                                    :value="item.gameId"
+                            ></el-option>
+                        </el-select>
+                    </el-form-item>
+
+                    <el-form-item label="渠道">
+                        <el-select v-model="dialogDto.channelId" placeholder="请选择渠道" filterable clearable>
+                            <el-option
+                                    v-for="item in channelList"
+                                    :key="item.channelId"
+                                    :label="item.channelId + '_' +item.channelName"
+                                    :value="item.channelId"
+                            ></el-option>
+                        </el-select>
+                    </el-form-item>
+
+                    <el-form-item label="渠道标识">
+                        <el-input v-model="input" placeholder="请输入内容"></el-input>
+                    </el-form-item>
+
+                </el-form>
+
+            </div>
+
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="handelCancel">取 消</el-button>
+                <el-button type="primary" @click="handelClickConform">确 定</el-button>
+            </span>
+        </el-dialog>
+
+
+        <div class="page">
+            <el-pagination
+                    @size-change="handleSizeChange"
+                    @current-change="handleCurrentChange"
+                    layout="total, sizes, prev, pager, next, jumper"
+                    :page-size="pageSize"
+                    :current-page="curPage"
+                    :pager-count="11"
+                    :total="total"
+            ></el-pagination>
+        </div>
+
+    </div>
+</template>
+
+<script>
+
+    import appControlApi from "@/api/appControlList"
+
+  export default {
+    name: 'appControlList',
+    data(){
+      return{
+        appControlList:[],
+        dialog: {
+          title: "新增",
+          visible: false
+        },
+        total: 0,
+        pageSize: 20,
+        curPage: 1,
+        gameList:null,
+        dialogDto:{},
+        channelList:null
+      }
+
+    },
+    mounted(){
+      this.getAppControlList()
+
+    },
+    methods:{
+      getAppControlList(){
+        appControlApi.getAppControlList().then(res =>{
+          this.appControlList = res;
+          this.appControlList.map(m =>{
+            m.channelName = m.channelId + '_' + m.channelName;
+            m.gameName = m.gameId + '_' + m.gameName;
+          })
+          this.total = this.appControlList.length;
+          console.log(res)
+        })
+      },
+      updateAppControlList(param){
+        param.state = param.state^1;
+        appControlApi.updateAppControlList(param).then(this.getAppControlList)
+      },
+      /**
+       * 处理前端分页
+       * @param val
+       */
+      handleSizeChange(val) {
+        this.pageSize = val;
+      },
+      handleCurrentChange(val) {
+        this.curPage = val;
+      },
+      handelCancel(){
+        this.dialogDto = {}
+        this.dialog.visible = false;
+      },
+      handelClickConform(){
+        appControlApi.addAppControlList(this.dialogDto).then(res =>{
+          this.getAppControlList()
+          this.dialog.visible = false
+        })
+      },
+      handelClickAdd(){
+        if(this.gameList != null && this.channelList != null){
+          this.dialog.visible = true
+        }else {
+          appControlApi.getGameList().then(game =>{
+            appControlApi.getChannelList().then(channel =>{
+              this.gameList = game;
+              this.channelList= channel;
+              this.dialog.visible = true
+            })
+          })
+        }
+      },
+      formatState:function(row,column) {
+        return row.state === 0 ? '关闭' : '开启'
+
+      }
+
+    },
+  }
+</script>
+
+<style lang="less"  scoped>
+    .appControlList{
+        /deep/.el-dialog{
+            width:450px;
+        }
+    }
+
+</style>

+ 299 - 0
src/views/cp/cpList.vue

@@ -0,0 +1,299 @@
+<template>
+    <div class="cpList">
+        <div class="head">
+            <div class="text flex-start">
+                <el-input placeholder="请输入内容" v-model="params.cpName" clearable>
+                    <template slot="prepend">CP公司</template>
+                </el-input>
+
+                <el-input placeholder="请输入内容" v-model="params.linkMan" clearable>
+                    <template slot="prepend">联系人</template>
+                </el-input>
+            </div>
+            <div class="action">
+                <el-button plain type="primary" icon="el-icon-search" @click="getList">搜索</el-button>
+                <el-button
+                        plain
+                        type="success"
+                        icon="el-icon-circle-plus-outline"
+                        @click="handelOpenDialog"
+                >新增
+                </el-button>
+            </div>
+        </div>
+
+        <div class="list">
+            <el-table
+                    :data="cpList.slice((curPage-1)*pageSize,curPage*pageSize)"
+                    border
+                    stripe
+                    :fit="false"
+                    height="100%"
+            >
+                <el-table-column label="序号" type="index" width="80" show-overflow-tooltip/>
+                <el-table-column label="CP公司名称" prop="cpName" width="150" show-overflow-tooltip/>
+                <el-table-column label="联系人" prop="linkMan" width="150" show-overflow-tooltip/>
+                <el-table-column label="职位" prop="position" width="150" show-overflow-tooltip/>
+                <el-table-column label="联系电话" prop="linkPhone" width="150" show-overflow-tooltip/>
+                <el-table-column label="地址" prop="address" width="150" show-overflow-tooltip/>
+                <el-table-column label="备注" prop="remark" width="150" show-overflow-tooltip/>
+                <el-table-column label="创建时间" prop="createTime" width="150" show-overflow-tooltip/>
+                <el-table-column label="更新时间" prop="updateTime" width="150" show-overflow-tooltip/>
+
+                <el-table-column label="操作" width="150">
+                    <template slot-scope="scope">
+                        <div class="headrow">
+                            <el-button size="mini" @click="handelUpdate(scope.row.cpId)">编辑</el-button>
+                        </div>
+                    </template>
+                </el-table-column>
+            </el-table>
+        </div>
+
+        <div class="page">
+            <el-pagination
+                    @size-change="handleSizeChange"
+                    @current-change="handleCurrentChange"
+                    layout="total, sizes, prev, pager, next, jumper"
+                    :page-size="pageSize"
+                    :current-page="curPage"
+                    :pager-count="11"
+                    :total="total"
+            ></el-pagination>
+        </div>
+
+        <el-dialog
+                :title="dialogTitle"
+                :visible.sync="dialogVisible"
+                center
+                width="500px"
+                :rules="rules"
+                ref="ruleForm"
+        >
+            <div class="content">
+                <el-form
+                        label-width="100px"
+                        label-position="left"
+                        style="width:400px;"
+                        class="demo-ruleForm"
+                        :model="dialogModel"
+                        :rules="rules"
+                        ref="ruleForm"
+                >
+                    <el-form-item label="CP公司名称" prop="cpName">
+                        <el-input v-model="dialogModel.cpName"></el-input>
+                    </el-form-item>
+                    <el-form-item label="联系人" prop="linkMan">
+                        <el-input v-model="dialogModel.linkMan"></el-input>
+                    </el-form-item>
+                    <el-form-item label="职位" prop="position">
+                        <el-input v-model="dialogModel.position"></el-input>
+                    </el-form-item>
+                    <el-form-item label="联系电话" prop="linkPhone">
+                        <el-input v-model="dialogModel.linkPhone"></el-input>
+                    </el-form-item>
+                    <el-form-item label="地址" prop="address">
+                        <el-input v-model="dialogModel.address"></el-input>
+                    </el-form-item>
+                    <el-form-item label="备注" prop="remark">
+                        <el-input v-model="dialogModel.remark"></el-input>
+                    </el-form-item>
+
+                </el-form>
+            </div>
+            <span slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="handelDialogConform">确 定</el-button>
+        <el-button @click="handelCancel">取 消</el-button>
+      </span>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+  import cpApi from "@/api/cp";
+  import {getCookie, getLastDay, formatTime} from "@/utils/util";
+
+  export default {
+    name: "cpList",
+    data() {
+      return {
+        isUpdate: false,
+        rules: {
+          cpName: [{required: true, message: "请输入CP公司名称", trigger: "blur"}]
+        },
+        userId: "",
+        cpList: [],
+        total: 0,
+        pageSize: 20,
+        curPage: 1,
+        params: {},
+        dialogVisible: false,
+        dialogTitle: '',
+        dialogModel: {},
+      };
+    },
+    created() {
+      this.getList();
+    },
+    methods: {
+      getList() {
+        cpApi.getList(this.params).then(res => {
+          this.$log.debug(res);
+          this.total = res.length;
+          this.cpList = res;
+        });
+      },
+
+      handleSizeChange(val) {
+        this.pageSize = val;
+      },
+      handleCurrentChange(val) {
+        this.curPage = val;
+      },
+      handelLogTimeChange(val) {
+        this.params.logStartTime = val ? val[0] : null;
+        this.params.logEndTime = val ? val[1] : null;
+        this.$log.debug(this.params);
+      },
+      handelPayTimeChange(val) {
+        this.params.payStartTime = val ? val[0] : null;
+        this.params.payEndTime = val ? val[1] : null;
+        this.$log.debug(this.params);
+      },
+      handelLoginTimeChange(val) {
+        this.params.loginStartTime = val ? val[0] : null;
+        this.params.loginEndTime = val ? val[1] : null;
+        this.$log.debug(this.params);
+      },
+      handelOpenDialog() {
+        this.dialogTitle = '新增CP公司信息'
+        this.isUpdate = false
+        this.dialogVisible = true
+      },
+      handelDialogConform() {
+        if (this.isUpdate) {
+          cpApi.update(this.dialogModel).then(res => {
+            this.dialogVisible = false;
+            this.$refs["ruleForm"].resetFields();
+            this.getList();
+            this.isUpdate = false;
+            this.dialogModel = {};
+            this.$message({
+              type: "success",
+              message: "修改成功!"
+            });
+          });
+        } else {
+          this.dialogModel.logSysId = this.userId;
+          cpApi.add(this.dialogModel).then(res => {
+            this.dialogVisible = false;
+            this.$refs["ruleForm"].resetFields();
+            this.getList();
+            this.isUpdate = false;
+            this.dialogModel = {};
+            this.$message({
+              type: "success",
+              message: "添加成功!"
+            });
+          });
+        }
+      },
+      handelDelete(id) {
+        if (id) {
+          let dto = {};
+          dto.id = id;
+          dto.isDelete = 0;
+          this.$confirm("此操作将永久该数据, 是否继续?", "提示", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning"
+          })
+            .then(() => {
+              cpApi.updateVip(dto).then(res => {
+                this.$message({
+                  type: "success",
+                  message: "删除成功!"
+                });
+                this.getList();
+              });
+            })
+            .catch(() => {
+              this.$message({
+                type: "info",
+                message: "已取消删除"
+              });
+            });
+        }
+      },
+      handelUpdate(id) {
+        cpApi.getById(id).then(res => {
+          if (res) {
+            this.dialogModel = res;
+            this.isUpdate = true;
+            this.dialogVisible = true;
+          }
+        });
+      },
+      handelCancel() {
+        this.isUpdate = false;
+        this.dialogModel = {};
+        this.$refs["ruleForm"].resetFields();
+        this.dialogVisible = false;
+      }
+    }
+  };
+</script>
+
+<style lang="less" scoped>
+    .cpList {
+        height: 100%;
+        width: 100%;
+        overflow: hidden;
+        display: flex;
+        flex-direction: column;
+        justify-content: space-between;
+
+        .head {
+            margin: 4px;
+
+            .text {
+                .el-input {
+                    margin: 4px;
+                    width: 25%;
+                }
+
+                .range {
+                    margin: 4px;
+                    width: 25%;
+
+                    .el-input {
+                        width: 45%;
+                    }
+                }
+
+                .el-select {
+                    margin: 4px;
+                    width: 25%;
+                }
+            }
+
+            .select {
+                .el-select {
+                    margin: 4px;
+                    width: 25%;
+                }
+            }
+
+            .interval {
+                .el-range-editor {
+                    margin: 4px;
+                    width: 33%;
+                }
+            }
+
+            .action {
+                margin: 4px;
+            }
+        }
+    }
+</style>

+ 309 - 0
src/views/cpGame/cpGameList.vue

@@ -0,0 +1,309 @@
+<template>
+  <div class="cpGameList">
+    <div class="head">
+      <div class="text flex-start">
+         <el-select
+              v-model="params.cpId"
+              placeholder="请选择CP公司"
+              filterable
+              clearable
+              style="width:100%;"
+            >
+              <el-option
+                v-for="item in cpList"
+                :key="item.cpId"
+                :label="item.cpId + '_' +item.cpName"
+                :value="item.cpId"
+              ></el-option>
+            </el-select>
+
+        <el-input placeholder="请输入内容" v-model="params.cpGameName" clearable>
+          <template slot="prepend">CP游戏名</template>
+        </el-input>
+      </div>
+      <div class="action">
+        <el-button plain type="primary" icon="el-icon-search" @click="getList">搜索</el-button>
+        <el-button
+          plain
+          type="success"
+          icon="el-icon-circle-plus-outline"
+          @click="handelOpenDialog"
+        >新增</el-button>
+      </div>
+    </div>
+
+    <div class="list">
+      <el-table
+        :data="cpGameList.slice((curPage-1)*pageSize,curPage*pageSize)"
+        border
+        stripe
+        :fit="false"
+        height="100%"
+      >
+        <el-table-column label="序号" type="index" width="80" show-overflow-tooltip />
+        <el-table-column label="CP公司名称" prop="cpName" width="150" show-overflow-tooltip />
+        <el-table-column label="CP游戏名称" prop="cpGameName" width="150" show-overflow-tooltip />
+        <el-table-column label="游戏类型" prop="position" width="150" show-overflow-tooltip />
+        <el-table-column label="联系电话" prop="linkPhone" width="150" show-overflow-tooltip />
+        <el-table-column label="地址" prop="address" width="150" show-overflow-tooltip />
+        <el-table-column label="备注" prop="remark" width="150" show-overflow-tooltip />
+        <el-table-column label="创建时间" prop="createTime" width="150" show-overflow-tooltip />
+        <el-table-column label="更新时间" prop="updateTime" width="150" show-overflow-tooltip />
+
+        <el-table-column label="操作" width="150">
+          <template slot-scope="scope">
+            <div class="headrow">
+              <el-button size="mini" @click="handelUpdate(scope.row.cpId)">编辑</el-button>
+            </div>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+
+    <div class="page">
+      <el-pagination
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+        layout="total, sizes, prev, pager, next, jumper"
+        :page-size="pageSize"
+        :current-page="curPage"
+        :pager-count="11"
+        :total="total"
+      ></el-pagination>
+    </div>
+
+    <el-dialog
+      :title="dialongTitle"
+      :visible.sync="dialogVisible"
+      center
+      width="500px"
+      :rules="rules"
+      ref="ruleForm"
+    >
+      <div class="content">
+        <el-form
+          label-width="100px"
+          label-position="left"
+          style="width:400px;"
+          class="demo-ruleForm"
+          :model="dialogModel"
+          :rules="rules"
+          ref="ruleForm"
+        >
+
+          <el-form-item label="CP公司名称" prop="cpName">
+            <el-input v-model="dialogModel.cpName"></el-input>
+          </el-form-item>
+          <el-form-item label="联系人" prop="linkMan">
+            <el-input v-model="dialogModel.linkMan"></el-input>
+          </el-form-item>
+          <el-form-item label="职位" prop="position">
+            <el-input v-model="dialogModel.position"></el-input>
+          </el-form-item>
+          <el-form-item label="联系电话" prop="linkPhone">
+             <el-input v-model="dialogModel.linkPhone"></el-input>
+          </el-form-item>
+          <el-form-item label="地址" prop="address">
+            <el-input v-model="dialogModel.address"></el-input>
+          </el-form-item>
+          <el-form-item label="备注" prop="remark">
+            <el-input v-model="dialogModel.remark"></el-input>
+          </el-form-item>
+
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="handelDialogConform">确 定</el-button>
+        <el-button @click="handelCancel">取 消</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import cpGameApi from "@/api/cpGame";
+import cpApi from "@/api/cp";
+import { getCookie, getLastDay, formatTime } from "@/utils/util";
+
+export default {
+  name: "cpGameList",
+  data() {
+    return {
+      isUpdate: false,
+      rules: {
+        cpName: [{ required: true, message: "请输入CP公司名称", trigger: "blur" }]
+      },
+      userId: "",
+      cpGameList: [],
+      cpList: [],
+      total: 0,
+      pageSize: 20,
+      curPage: 1,
+      params: {},
+      dialogVisible: false,
+      dialogTitle: '',
+      dialogModel: {},
+    };
+  },
+  created() {
+    this.getList()
+    this.getCpList()
+  },
+  methods: {
+    getList() {
+      cpGameApi.getList(this.params).then(res => {
+        this.$log.debug(res);
+        this.total = res.length;
+        this.cpGameList = res;
+      });
+    },
+    getCpList() {
+      cpApi.getList().then(res => {
+        this.cpList = res;
+      });
+    },
+    handleSizeChange(val) {
+      this.pageSize = val;
+    },
+    handleCurrentChange(val) {
+      this.curPage = val;
+    },
+    handelLogTimeChange(val) {
+      this.params.logStartTime = val ? val[0] : null;
+      this.params.logEndTime = val ? val[1] : null;
+      this.$log.debug(this.params);
+    },
+    handelPayTimeChange(val) {
+      this.params.payStartTime = val ? val[0] : null;
+      this.params.payEndTime = val ? val[1] : null;
+      this.$log.debug(this.params);
+    },
+    handelLoginTimeChange(val) {
+      this.params.loginStartTime = val ? val[0] : null;
+      this.params.loginEndTime = val ? val[1] : null;
+      this.$log.debug(this.params);
+    },
+    handelOpenDialog() {
+      this.dialongTitle = '新增CP公司信息'
+      this.isUpdate = false
+      this.dialogVisible = true
+    },
+    handelDialogConform() {
+      if (this.isUpdate) {
+        cpGameApi.update(this.dialogModel).then(res => {
+          this.dialogVisible = false;
+          this.$refs["ruleForm"].resetFields();
+          this.getList();
+          this.isUpdate = false;
+          this.dialogModel = {};
+          this.$message({
+            type: "success",
+            message: "修改成功!"
+          });
+        });
+      } else {
+        this.dialogModel.logSysId = this.userId;
+        cpGameApi.add(this.dialogModel).then(res => {
+          this.dialogVisible = false;
+          this.$refs["ruleForm"].resetFields();
+          this.getList();
+          this.isUpdate = false;
+          this.dialogModel = {};
+          this.$message({
+            type: "success",
+            message: "添加成功!"
+          });
+        });
+      }
+    },
+    handelDelete(id) {
+      if (id) {
+        let dto = {};
+        dto.id = id;
+        dto.isDelete = 0;
+        this.$confirm("此操作将永久该数据, 是否继续?", "提示", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        })
+          .then(() => {
+            cpGameApi.updateVip(dto).then(res => {
+              this.$message({
+                type: "success",
+                message: "删除成功!"
+              });
+              this.getList();
+            });
+          })
+          .catch(() => {
+            this.$message({
+              type: "info",
+              message: "已取消删除"
+            });
+          });
+      }
+    },
+    handelUpdate(id) {
+      cpGameApi.getById(id).then(res => {
+        if (res) {
+          this.dialogModel = res;
+          this.isUpdate = true;
+          this.dialogVisible = true;
+        }
+      });
+    },
+    handelCancel() {
+      this.isUpdate = false;
+      this.dialogModel = {};
+      this.$refs["ruleForm"].resetFields();
+      this.dialogVisible = false;
+    }
+  }
+};
+</script>
+
+<style lang="less" scoped>
+.cpGameList {
+  height: 100%;
+  width: 100%;
+  overflow: hidden;
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  .head {
+    margin: 4px;
+    .text {
+      .el-input {
+        margin: 4px;
+        width: 25%;
+      }
+      .range {
+        margin: 4px;
+        width: 25%;
+        .el-input {
+          width: 45%;
+        }
+      }
+      .el-select {
+        margin: 4px;
+        width: 25%;
+      }
+    }
+    .select {
+      .el-select {
+        margin: 4px;
+        width: 25%;
+      }
+    }
+    .interval {
+      .el-range-editor {
+        margin: 4px;
+        width: 33%;
+      }
+    }
+    .action {
+      margin: 4px;
+    }
+  }
+}
+</style>

+ 111 - 0
src/views/feedbackDetail/feedbackDetail.vue

@@ -0,0 +1,111 @@
+<template>
+    <div class="feedbackDetail">
+        <el-form ref="form" label-width="80px">
+            <el-form-item label="游戏名称:">
+                <p>{{feedbackInfo.gameAlias}}</p>
+            </el-form-item>
+
+            <el-form-item label="联系方式:">
+                <el-tag>{{contactType(feedbackInfo.userContactType)}}
+                </el-tag> <p>{{feedbackInfo.userContact}}</p>
+            </el-form-item>
+
+            <el-form-item label="问题描述:">
+                <p>{{feedbackInfo.content}}</p>
+            </el-form-item>
+
+            <el-form-item label="游戏截图:">
+                <viewer :images="feedbackInfo.imageUrlList">
+                    <img v-for="(src,index) in feedbackInfo.imageUrlList" :src="src" :key="index"
+                         style="width: 100px; height: 100px" fill>
+                </viewer>
+            </el-form-item>
+
+            <div class="">
+                <el-button @click="handelReturn">返 回</el-button>
+                <el-button type="primary" @click="handelComplete" v-show="feedbackInfo && feedbackInfo.state===0">完 成
+                </el-button>
+            </div>
+
+
+        </el-form>
+    </div>
+</template>
+
+<script>
+    import feedbackApi from '@/api/feedback'
+
+    export default {
+        name: "feedbackDetail",
+        data() {
+            return {
+                params: {},
+                page:{},
+                feedbackInfo: {},
+                contactOption: [
+                    {text: '微信', value: 0, inputType: 'text'},
+                    {text: 'QQ', value: 1, inputType: 'number'},
+                    {text: '手机号', value: 2, inputType: 'tel'},
+                    {text: '邮箱', value: 3, inputType: 'email'}
+                ],
+            }
+        },
+        mounted() {
+            this.params = this.$route.params.params;
+            this.page = this.$route.params.page;
+            this.feedbackInfo.id = this.$route.params.id;
+            this.getFeedbackDetail()
+        },
+        methods: {
+            getFeedbackDetail() {
+                feedbackApi.getFeedbackById(this.feedbackInfo.id).then(res => {
+                    this.feedbackInfo = res;
+                    let imageUrls = this.feedbackInfo.imageUrl;
+                    if (imageUrls && imageUrls.length) {
+                        this.feedbackInfo.imageUrlList = imageUrls.split(',')
+                    }
+                    console.log(this.feedbackInfo);
+                })
+            },
+            handelReturn() {
+                this.$router.push({
+                    name: 'feedbackList',
+                    params: {
+                        params: this.params,
+                        page:this.page
+                    }
+                })
+            },
+            handelComplete() {
+                this.$confirm('您确定已经完成该条反馈信息了吗?', '提示', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    type: 'warning'
+                }).then(() => {
+                    feedbackApi.updateFeedback({id: this.feedbackInfo.id, state: 1}).then(res => {
+                        this.$message({
+                            type: 'success',
+                            message: '已完成!'
+                        });
+                        this.handelReturn()
+                    });
+
+                }).catch(() => {
+                    this.$message({
+                        type: 'info',
+                        message: '已取消'
+                    });
+                });
+            },
+            contactType(type) {
+                return this.contactOption.find(f => f.value == type).text
+            },
+        }
+    }
+</script>
+
+<style lang="less" scoped>
+    .feedbackDetail {
+        padding: 20px 20px 50px;
+    }
+</style>

+ 279 - 0
src/views/feedbackGame/feedbackGame.vue

@@ -0,0 +1,279 @@
+<template>
+    <div class="feedbackGame flex-display">
+        <div class="head">
+            <div class="text">
+                <el-select v-model="params.gameId" placeholder="请选择游戏" filterable clearable>
+                    <el-option
+                            v-for="item in gameList"
+                            :key="item.gameId"
+                            :label="item.gameId + '_' +item.gameName"
+                            :value="item.gameId"
+                    ></el-option>
+                </el-select>
+            </div>
+
+            <div class="action">
+                <el-button plain type="primary" icon="el-icon-search" @click="getFeedbackGameList">搜索</el-button>
+                <el-button plain type="success" icon="el-icon-circle-plus-outline" @click="handelClickAdd">新增
+                </el-button>
+            </div>
+        </div>
+        <div class="list">
+            <el-table :data="feedGameList.slice((curPage-1)*pageSize,curPage*pageSize)" border stripe :fit="false" height="100%">
+                <el-table-column label="游戏id" prop="gameId" width="150" show-overflow-tooltip/>
+                <el-table-column label="游戏名称" prop="gameName" width="150" show-overflow-tooltip/>
+                <el-table-column label="备注" prop="gameAlias" width="150" show-overflow-tooltip/>
+                <el-table-column label="操作" width="180">
+                    <template slot-scope="scope">
+                        <div class="headrow">
+                            <el-button size="mini" @click="handelUpdateFeedbackGame(scope.row.id)">编辑</el-button>
+                            <el-button size="mini" type="danger" @click="handelDelete(scope.row.id)">删除</el-button>
+                        </div>
+                    </template>
+                </el-table-column>
+            </el-table>
+        </div>
+
+        <div class="page">
+            <el-pagination
+                    @size-change="handleSizeChange"
+                    @current-change="handleCurrentChange"
+                    layout="total, sizes, prev, pager, next, jumper"
+                    :page-size="pageSize"
+                    :current-page="curPage"
+                    :pager-count="11"
+                    :total="total"
+            ></el-pagination>
+        </div>
+
+        <el-dialog :title="dialog.title" :visible.sync="dialog.visible" center>
+            <div class="content">
+
+                <div class="item">
+                    <el-select v-model="dialogDto.gameId" placeholder="请选择游戏" filterable clearable>
+                        <el-option
+                                v-for="item in gameList"
+                                :key="item.gameId"
+                                :label="item.gameId + '_' +item.gameName"
+                                :value="item.gameId"
+                        ></el-option>
+                    </el-select>
+                </div>
+
+                <div class="item">
+                    <el-input placeholder="请输入内容" v-model="dialogDto.gameAlias" clearable>
+                        <template slot="prepend">备注</template>
+                    </el-input>
+                </div>
+
+                <div class="item">
+                    <el-checkbox-group v-model="checkList" @change="handelChangeCheckBox">
+                        <el-checkbox v-for="item in requiredList" :label="item.value" >{{item.label}}</el-checkbox>
+                    </el-checkbox-group>
+                </div>
+
+            </div>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="handelCancel">取 消</el-button>
+                <el-button type="primary" @click="handelClickConform">确 定</el-button>
+            </span>
+        </el-dialog>
+
+    </div>
+</template>
+
+<script>
+    import feedbackApi from '@/api/feedback'
+
+    export default {
+        name: "feedbackGame",
+        data() {
+            return {
+                params: {},
+                feedGameList: [],
+                dialog: {
+                    title: '请选择需要反馈的游戏',
+                    visible: false
+                },
+                dialogDto: {
+                    gameId: '',
+                    gameAlias: ''
+                },
+                gameList: [],
+                isUpdate: false,
+                total: 0,
+                pageSize: 20,
+                curPage: 1,
+                checkList:[],
+                requiredList:[
+                    {label:'必填联系方式',value:'contact'},
+                    {label:'必填上传截图',value:'image'}
+                ]
+            }
+        },
+        mounted() {
+            this.getFeedbackGameList();
+            this.getGameList();
+        },
+        methods: {
+
+            /**
+             * 获取反馈游戏列表
+             */
+            getFeedbackGameList() {
+                feedbackApi.getFeedbackGameList().then(res => {
+                    this.feedGameList = this.params.gameId ? res.filter(f=>f.gameId == this.params.gameId) : res;
+                    this.total = this.feedGameList.length;
+                })
+            },
+
+            /**
+             * 获取游戏列表
+             */
+            getGameList() {
+                feedbackApi.getGameList().then(res => {
+                    this.gameList = this.params.gameId ? res.filter(f=>f.gameId == this.params.gameId) : res;
+                });
+            },
+
+            /**
+             * 点击新增按钮
+             */
+            handelClickAdd() {
+                this.isUpdate = false;
+                feedbackApi.getGameList().then(res => {
+                    this.gameList = res.filter(f => !this.feedGameList.find(d => f.gameId == d.gameId) || f.gameId == this.dialogDto.gameId);
+                    this.dialog.visible = true
+                });
+
+
+            },
+
+            /**
+             * 点击确认按钮
+             */
+            handelClickConform() {
+                this.dialogDto.gameName = this.gameList.find(f => f.gameId == this.dialogDto.gameId).gameName;
+                if (!this.dialogDto.gameAlias) {
+                    this.dialogDto.gameAlias = this.dialogDto.gameName
+                }
+
+                this.dialogDto.required = this.checkList.join(',');
+
+
+                this.isUpdate ? feedbackApi.updateFeedbackGame(this.dialogDto).then(this.refreshDto) :
+                    feedbackApi.addFeedbackGame(this.dialogDto).then(this.refreshDto)
+
+            },
+
+            /**
+             * 新增或者修改之后刷新dto
+             * @param res
+             */
+            refreshDto(res) {
+                this.handelCancel();
+                this.getFeedbackGameList()
+            },
+
+            /**
+             * 点击取消
+             */
+            handelCancel() {
+                this.dialog.visible = false;
+                this.dialogDto = {
+                    gameId: '',
+                    gameAlias: ''
+                };
+                this.checkList = []
+            },
+
+            /**
+             * 修改
+             * @param id
+             */
+            handelUpdateFeedbackGame(id) {
+                this.isUpdate = true;
+                feedbackApi.getFeedbackGameById(id).then(res=> {
+                    this.dialogDto = {
+                        id: res.id,
+                        gameId: res.gameId,
+                        gameName: res.gameName,
+                        gameAlias: res.gameAlias,
+                    };
+                    this.checkList = res.required && res.required.split(',');
+                    feedbackApi.getGameList().then(res => {
+                        this.gameList = res.filter(f => !this.feedGameList.find(d => f.gameId == d.gameId) || f.gameId == this.dialogDto.gameId);
+                        this.dialog.visible = true
+                    });
+                });
+            },
+
+            /**
+             * 删除
+             * @param id
+             */
+            handelDelete(id) {
+                this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    type: 'warning'
+                }).then(() => {
+                    feedbackApi.deleteFeedbackGame(id).then(res => {
+                        this.$message({
+                            type: 'success',
+                            message: '删除成功!'
+                        });
+                        this.handelCancel();
+                        this.getFeedbackGameList()
+                    });
+
+                }).catch(() => {
+                    this.$message({
+                        type: 'info',
+                        message: '已取消删除'
+                    });
+                });
+
+            },
+
+            /**
+             * 处理前端分页
+             * @param val
+             */
+            handleSizeChange(val) {
+                this.pageSize = val;
+            },
+            handleCurrentChange(val) {
+                this.curPage = val;
+            },
+            handelChangeCheckBox(val) {
+                console.log(val);
+                console.log(this.checkList)
+            }
+        }
+    }
+</script>
+
+<style lang="less" scoped>
+    .feedbackGame {
+        .head {
+            .el-select {
+                width: 300px;
+                margin: 4px;
+            }
+        }
+        /deep/ .el-dialog {
+            width: 300px;
+
+            .content {
+                .item {
+                    margin-bottom: 14px;
+                    .el-select {
+                        width: 100%;
+                    }
+                }
+            }
+        }
+
+    }
+</style>

+ 221 - 0
src/views/feedbackList/feedbackList.vue

@@ -0,0 +1,221 @@
+<template>
+    <div class="feedbackList flex-display">
+        <div class="head">
+            <div class="text">
+
+                <div class="head-item">
+                    <el-select v-model="params.gameId" placeholder="请选择游戏" filterable clearable>
+                        <el-option
+                                v-for="item in feedGameList"
+                                :key="item.gameId"
+                                :label="item.gameId + '_' +item.gameAlias"
+                                :value="item.gameId"
+                        ></el-option>
+                    </el-select>
+                </div>
+
+                <div class="head-item" placeholder="请选择创建时间">
+                    <el-date-picker
+                            v-model="createTime"
+                            @change="handelCreateTimeChange"
+                            type="datetimerange"
+                            :value-format="'yyyy-MM-dd HH:mm:ss'"
+                            start-placeholder="反馈日期"
+                            end-placeholder="反馈日期"
+                            :default-time="['00:00:00', '23:59:59']"
+                    ></el-date-picker>
+                </div>
+
+                <div class="head-item">
+                    <el-select v-model="params.state" placeholder="请选择完成状态">
+                        <el-option
+                                v-for="item in stateList"
+                                :key="item.text"
+                                :label="item.text"
+                                :value="item.value"
+                        ></el-option>
+                    </el-select>
+                </div>
+            </div>
+
+            <div class="action">
+                <el-button plain type="primary" icon="el-icon-search" @click="getFeedbackList">搜索</el-button>
+            </div>
+        </div>
+        <div class="list">
+            <el-table :data="feedbackList" border stripe :fit="false" height="100%" @sort-change="handelSortChange">
+                <el-table-column label="反馈编号" prop="id" width="150" show-overflow-tooltip/>
+                <el-table-column label="游戏名称" prop="gameAlias" width="150" show-overflow-tooltip/>
+                <el-table-column label="联系类型" width="150" show-overflow-tooltip>
+                    <template slot-scope="scope">
+                        <el-tag>{{contactType(scope.row.userContactType)}}
+                        </el-tag>
+                    </template>
+                </el-table-column>
+
+                <el-table-column label="联系方式" prop="userContact" width="150" show-overflow-tooltip/>
+
+                <el-table-column label="问题描述" prop="content" width="150" show-overflow-tooltip/>
+
+                <el-table-column label="反馈时间" prop="createTime" width="150" show-overflow-tooltip sortable="custom"/>
+
+                <el-table-column label="操作" width="120">
+                    <template slot-scope="scope">
+                        <div class="headrow">
+                            <el-button size="mini" @click="handelSelectFeedback(scope.row.id)">查看</el-button>
+                            <!--<el-button size="mini" type="success">完成</el-button>-->
+                        </div>
+                    </template>
+                </el-table-column>
+            </el-table>
+        </div>
+
+        <div class="page">
+            <el-pagination
+                    @size-change="handleSizeChange"
+                    @current-change="handleCurrentChange"
+                    layout="total, sizes, prev, pager, next, jumper"
+                    :page-size="page.size"
+                    :pager-count="11"
+                    :total="page.total"
+            ></el-pagination>
+        </div>
+
+        <el-dialog :title="dialog.title" :visible.sync="dialog.visible" center>
+            <div class="content">
+
+
+            </div>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="dialog.visible = false">关闭</el-button>
+            </span>
+        </el-dialog>
+
+    </div>
+</template>
+
+<script>
+
+    import feedbackApi from '@/api/feedback'
+    import {getLastDay, formatTime} from '@/utils/util'
+
+    export default {
+        name: "feedbackList",
+        data() {
+            return {
+                createTime: '',
+                params: {
+                    state: 0
+                },
+                feedbackList: [],
+                gameList: [],
+                state: 0,
+                feedGameList: [],
+                contactOption: [
+                    {text: '微信', value: 0, inputType: 'text'},
+                    {text: 'QQ', value: 1, inputType: 'number'},
+                    {text: '手机号', value: 2, inputType: 'tel'},
+                    {text: '邮箱', value: 3, inputType: 'email'}
+                ],
+                stateList: [
+                    {value: 0, text: '未完成'},
+                    {value: 1, text: '已完成'},
+                    {value: null, text: '全部'}
+                ],
+                dialog: {
+                    title: '反馈详情',
+                    visible: false
+                },
+                feedbackInfo: {},
+                page: {},
+
+            }
+        },
+        mounted() {
+            this.init();
+        },
+        methods: {
+            init() {
+                if (this.$route.params.params) {
+                    this.params = this.$route.params.params;
+                }
+
+                if (this.$route.params.page) {
+                    this.page = this.$route.params.page;
+                }
+
+                let lastDay = getLastDay(3);
+                this.createTime = lastDay;
+                this.params.createStartTime = lastDay ? formatTime(lastDay[0]) : null;
+                this.params.createEndTime = lastDay ? formatTime(lastDay[1]) : null;
+                feedbackApi.getFeedbackGameList().then(res => {
+                    this.feedGameList = res;
+                    this.getFeedbackList()
+                })
+            },
+
+            getFeedbackList() {
+                feedbackApi.getFeedbackList(this.params).then(res => {
+                    this.feedbackList = res.rows;
+                    this.page = res.page
+                })
+            },
+            /**
+             * 获取反馈游戏列表
+             */
+            getFeedbackGameList() {
+                feedbackApi.getFeedbackGameList().then(res => {
+                    this.feedGameList = res;
+                })
+            },
+            contactType(type) {
+                return this.contactOption.find(f => f.value == type).text
+            },
+            handelSelectFeedback(id) {
+                this.$router.push({
+                    name: 'feedbackDetail',
+                    params: {
+                        id: id,
+                        params: this.params,
+                        page:this.page
+                    }
+                })
+            },
+            handelCreateTimeChange(val) {
+                this.params.createStartTime = val ? val[0] : null;
+                this.params.createEndTime = val ? val[1] : null;
+                this.$log.debug(this.params)
+            },
+            handelSortChange({order}) {
+                console.log(order)
+                if (order == 'descending') {
+                    this.params.orderBy = 1
+                } else if (order == 'ascending') {
+                    this.params.orderBy = 0
+                } else {
+                    this.params.orderBy = null
+                }
+                this.getFeedbackList()
+            },
+            handleSizeChange(val) {
+                this.$log.debug(val);
+                this.params.size = val;
+                this.getFeedbackList()
+            },
+            handleCurrentChange(val) {
+                this.params.cur = val;
+                this.getFeedbackList()
+            },
+        }
+    }
+</script>
+
+<style lang="less" scoped>
+    .feedbackList {
+        .head {
+            .el-input {
+                width: 300px;
+            }
+        }
+    }
+</style>

+ 161 - 0
src/views/gameData/gameData.vue

@@ -0,0 +1,161 @@
+<template>
+    <div class="gameData flex-display">
+        <div class="head">
+            <div class="text">
+                <div class="head-item" placeholder="请选择创建时间">
+                    <el-date-picker
+                            v-model="createTime"
+                            @change="handelCreateTimeChange"
+                            type="datetimerange"
+                            :value-format="'yyyy-MM-dd HH:mm:ss'"
+                            start-placeholder="日期"
+                            end-placeholder="日期"
+                            :default-time="['00:00:00', '23:59:59']"
+                    ></el-date-picker>
+                </div>
+
+                <div class="head-item">
+                    <el-select v-model="params.plat" placeholder="请选择平台" clearable>
+                        <el-option
+                                v-for="item in plat"
+                                :key="item"
+                                :label="item"
+                                :value="item"
+                        ></el-option>
+                    </el-select>
+                </div>
+
+                <div class="head-item">
+                    <el-select v-model="params.type" placeholder="请选择类型" clearable>
+                        <el-option
+                                v-for="item in typeList"
+                                :key="item"
+                                :label="item"
+                                :value="item"
+                        ></el-option>
+                    </el-select>
+                </div>
+
+                <div class="head-item">
+                    <el-select v-model="params.item" placeholder="请选择类别" v-if=" params.type === 'category' || params.type === 'cellCategory'" clearable>
+                        <el-option
+                                v-for="item in items"
+                                :key="item"
+                                :label="item"
+                                :value="item"
+                        ></el-option>
+                    </el-select>
+                </div>
+
+                <div class="head-item">
+                    <el-select v-model="params.which" placeholder="请选择题号" v-if=" params.type === 'answer' " clearable>
+                        <el-option
+                                v-for="item in which"
+                                :key="item"
+                                :label="item"
+                                :value="item"
+                        ></el-option>
+                    </el-select>
+                </div>
+
+                <div class="action">
+                    <el-button plain type="primary" icon="el-icon-search" @click="getGameData">搜索</el-button>
+                </div>
+            </div>
+        </div>
+
+        <div class="list">
+            <el-table :data="gameData" border stripe :fit="false" show-summary >
+                <el-table-column label="日期Time" prop="id" width="150" show-overflow-tooltip sortable/>
+                <el-table-column label="点击总量/次" prop="amount" width="150" show-overflow-tooltip />
+                <el-table-column label="点击人数/次" prop="userAmount" width="150" show-overflow-tooltip />
+                <el-table-column label="平均" prop="average" width="150" show-overflow-tooltip/>
+            </el-table>
+        </div>
+
+
+
+        </div>
+</template>
+
+<script>
+
+  import gameDataApi from '@/api/gameData'
+  import {getLastDay, formatTime} from '@/utils/util'
+
+  export default {
+    name: 'gameData',
+    data(){
+      return{
+        createTime:'',
+        params:{},
+        typeList:{},
+        gameData:[],
+        items:{},
+        plat:{},
+        which:{}
+        // plat:[{label:'百度平台',value:'BAIDU_GAME'},
+        //   {label:'微信平台',value:'WECHAT_GAME'},
+        //   {label:'其他平台',value:'OTHER_GAME'}]
+      }
+    },
+    mounted(){
+      this.init()
+      this.getCollection();
+    },
+    methods:{
+      init(){
+        let lastDay = getLastDay(3)
+        this.createTime = lastDay
+        this.params.startTime = lastDay ? formatTime(lastDay[0]).replace(" ","-").replace(/:/g,"-"): null
+        this.params.endTime = lastDay ? formatTime(lastDay[1]).replace(" ","-").replace(/:/g,"-"): null
+      },
+      handelCreateTimeChange(val) {
+        this.params.startTime = val ? val[0] : null;
+        this.params.endTime = val ? val[1] : null;
+        if(this.params.startTime != null){
+          this.params.startTime = this.params.startTime.replace(" ","-").replace(/:/g,"-");
+          this.params.endTime = this.params.endTime.replace(" ","-").replace(/:/g,"-");;
+        }
+      },
+      getCollection(){
+        gameDataApi.getCollections().then(res => {
+          this.typeList = res.collection
+          this.plat = res.plat
+          this.items = res.item
+          this.which = res.which;
+        });
+
+      },
+      getGameData(){
+        if(this.params.type != null && this.params.type !== ''){
+          gameDataApi.getGameData(this.params).then(res => {
+            this.gameData = res;
+            this.gameData.map(m => m.average = (m.userAmount/m.amount*100).toFixed(2) + '%')
+            console.log(res)
+            // this.gameData.map(m => m.id = this.insertStr(this.insertStr(m.id, 4, "/"), 7, "/"))
+            //切割 this.insertStr(this.insertStr(m.id, 4, "/"), 7, "/")
+          })
+        }else{
+          this.open()
+        }
+      },
+      insertStr(soure, start, newStr) {
+        return soure.slice(0, start) + newStr + soure.slice(start);
+      },
+      open() {
+        this.$message({
+          message: '必须选择类型',
+          type: 'warning',
+          duration:1000
+        });
+      },
+
+
+    }
+  }
+</script>
+
+<style scoped>
+
+</style>

+ 217 - 0
src/views/giftCodeList/giftCodeList.vue

@@ -0,0 +1,217 @@
+<template>
+    <div class="giftCodeList flex-display">
+
+        <div class="head">
+            <div class="text">
+
+                <!--<div class="head-item">-->
+                    <!--<el-select v-model="params.gameId" placeholder="请选择所属游戏" filterable clearable>-->
+                        <!--<el-option-->
+                                <!--v-for="item in giftGameList"-->
+                                <!--:key="item.gameId"-->
+                                <!--:label="item.gameId + '_' +item.gameName"-->
+                                <!--:value="item.gameId"-->
+                        <!--&gt;</el-option>-->
+                    <!--</el-select>-->
+                <!--</div>-->
+
+                <div class="head-item">
+                    <el-select v-model="params.state" placeholder="请选择完成状态">
+                        <el-option
+                                v-for="item in stateList"
+                                :key="item.text"
+                                :label="item.text"
+                                :value="item.value"
+                        ></el-option>
+                    </el-select>
+                </div>
+            </div>
+
+            <div class="action">
+                <el-button plain type="primary" icon="el-icon-search" @click="getGiftCode">搜索</el-button>
+                <el-button plain type="primary" icon="el-icon-arrow-left" @click="back">返回</el-button>
+            </div>
+        </div>
+
+        <div class="list">
+            <el-table :data="giftCodeList" border stripe :fit="false" height="100%">
+                <el-table-column label="序号" prop="id" width="150" show-overflow-tooltip/>
+                <!--<el-table-column label="所属游戏" prop="gameName" width="150" show-overflow-tooltip/>-->
+                <el-table-column label="礼包码" prop="giftCode" width="150" show-overflow-tooltip/>
+                <el-table-column label="操作" width="180">
+                    <template slot-scope="scope"  >
+                        <div class="headrow">
+                            <el-button size="mini" @click="handelGift(scope.row.id)" v-if="scope.row.state==0" >编辑</el-button>
+                            <el-button size="mini" v-if="scope.row.state==1" disabled>编辑</el-button>
+                            <el-button size="mini" type="danger" @click="handelDelete(scope.row.id)">删除</el-button>
+                        </div>
+                    </template>
+                </el-table-column>
+            </el-table>
+        </div>
+
+        <div class="page">
+            <el-pagination
+                    @size-change="handleSizeChange"
+                    @current-change="handleCurrentChange"
+                    layout="total, sizes, prev, pager, next, jumper"
+                    :page-size="page.size"
+
+                    :pager-count="11"
+                    :total="page.total"
+            ></el-pagination>
+        </div>
+
+        <el-dialog :title="dialog.title" :visible.sync="dialog.visible" center @close="handelCancel">
+            <div class="content">
+
+                <el-form label-width="100px" :rules="rules" :model="codeDto" ref="giftForm">
+
+                    <el-form-item label="当前礼包码:" prop="oldGiftCode">
+                        <el-input
+                                type="textarea"
+                                :rows="2"
+                                placeholder="无"
+                                v-model="codeDto.oldGiftCode"
+                                :disabled="true">
+                        </el-input>
+                    </el-form-item>
+
+
+                    <el-form-item label="变更礼包码:" prop="updateGiftCode">
+                        <el-input
+                                type="textarea"
+                                :rows="2"
+                                placeholder="请输入内容"
+                                v-model="codeDto.giftCode">
+                        </el-input>
+                    </el-form-item>
+
+                </el-form>
+            </div>
+
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="handelCancel">取 消</el-button>
+                <el-button type="primary" @click="handelClickConform">确 定</el-button>
+            </span>
+        </el-dialog>
+    </div>
+</template>
+
+
+<script>
+    import giftListApi from '@/api/giftList'
+
+    export default {
+        name:"giftCodeList",
+        data(){
+            return {
+                params:{},
+                stateList: [
+                    {value: 0, text: '已领取'},
+                    {value: 1, text: '未领取'},
+                    {value: null, text: '全部'}
+                ],
+                giftGameList: [],
+                giftCodeList: [],
+                dialog: {
+                    title: "修改礼包码",
+                    visible: false
+                },
+                codeDto: {
+                    giftCode:''
+                },
+                rules:{
+                    giftCode:{required:true,message:'请输入新的礼包码',trigger:'blur'}
+                },
+                page:{}
+            }
+        },
+        mounted(){
+            this.params = this.$route.params;
+            this.getGiftCode()
+        },
+        methods:{
+            getGiftCode(){
+                console.log(this.params)
+                giftListApi.getGiftCodeList(this.params).then(res =>{
+                    this.giftCodeList = res.rows;
+                    this.giftCodeList.filter(f => f.deleted == 0)
+                    this.page = res.page
+                })
+            },
+            /**
+             * 编辑礼包码
+             */
+             handelGift(id){
+                giftListApi.getGiftCodeById(id).then(res =>{
+                    this.dialog.visible=true;
+                    this.codeDto = {
+                        id:res.id,
+                        oldGiftCode:res.giftCode
+                    }
+                })
+            },
+            handelDelete(id){
+                this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    type: 'warning'
+                }).then(() => {
+                    giftListApi.deleteGiftCode(id).then(res => {
+                        this.$message({
+                            type: 'success',
+                            message: '删除成功!'
+                        });
+                        this.refresh()
+                    });
+
+                }).catch(() => {
+                    this.$message({
+                        type: 'info',
+                        message: '已取消删除'
+                    });
+                });
+            },
+            refresh(){
+                this.handelCancel();
+                this.getGiftCode();
+            },
+            handelCancel(){
+                this.dialog.visible=false;
+                this.isAdd=false;
+                this.codeDto.giftCode='';
+
+            },
+            handelClickConform(){
+                giftListApi.updateGiftCode(this.codeDto).then(this.refresh)
+            },
+            /**
+             * 回退页面
+             */
+            back(){
+                this.$router.push({
+                    name:"giftList"
+                })
+            },
+            handleSizeChange(val){
+                this.params.size=val;
+                this.getGiftCode()
+            },
+            handleCurrentChange(val){
+                this.params.cur=val;
+                this.getGiftCode()
+            }
+
+        }
+
+    }
+</script>
+<style lang="less" scoped>
+    .giftCodeList{
+        /deep/.el-dialog{
+            width:400px;
+        }
+    }
+
+</style>

+ 296 - 0
src/views/giftGameList/giftGameList.vue

@@ -0,0 +1,296 @@
+<template>
+    <div class="giftGameList flex-display">
+        <div class="head">
+            <div class="text">
+                <el-select v-model="params.gameId" placeholder="请选择游戏" filterable clearable>
+                    <el-option
+                            v-for="item in gameList"
+                            :key="item.gameId"
+                            :label="item.gameId + '_' +item.gameName"
+                            :value="item.gameId"
+                    ></el-option>
+                </el-select>
+            </div>
+
+            <div class="action">
+                <el-button plain type="primary" icon="el-icon-search" @click="getGiftGameList">搜索</el-button>
+                <el-button plain type="success" icon="el-icon-circle-plus-outline" @click="handelClickAdd">新增
+                </el-button>
+            </div>
+        </div>
+        <div class="list">
+            <el-table :data="giftGameList.slice((curPage-1)*pageSize,curPage*pageSize)" border stripe :fit="false" height="100%">
+                <el-table-column label="游戏id" prop="gameId" width="150" show-overflow-tooltip/>
+                <el-table-column label="游戏名称" prop="gameName" width="150" show-overflow-tooltip/>
+                <el-table-column label="备注" prop="createTime" width="150" show-overflow-tooltip/>
+                <el-table-column label="操作" width="180">
+                    <template slot-scope="scope">
+                        <div class="headrow">
+                            <el-button size="mini" @click="handelUpdate(scope.row.id)">编辑</el-button>
+                            <el-button size="mini" type="danger" @click="handelDelete(scope.row.id)">删除</el-button>
+                        </div>
+                    </template>
+                </el-table-column>
+            </el-table>
+        </div>
+
+        <div class="page">
+            <el-pagination
+                    @size-change="handleSizeChange"
+                    @current-change="handleCurrentChange"
+                    layout="total, sizes, prev, pager, next, jumper"
+                    :page-size="pageSize"
+                    :current-page="curPage"
+                    :pager-count="11"
+                    :total="total"
+            ></el-pagination>
+        </div>
+
+        <el-dialog :title="dialog.title" :visible.sync="dialog.visible" center @close="handelCancel">
+            <div class="content">
+                <el-form label-width="100px" :rules="rules" :model="giftGameDto" ref="giftGameForm">
+
+                    <el-form-item label="游戏名称:" prop="gameId">
+                        <el-select v-model="giftGameDto.gameId" placeholder="请选择游戏" filterable clearable>
+                            <el-option
+                                    v-for="item in gameList"
+                                    :key="item.gameId"
+                                    :label="item.gameId + '_' +item.gameName"
+                                    :value="item.gameId"
+                            ></el-option>
+                        </el-select>
+                    </el-form-item>
+
+
+                    <el-form-item label="游戏别名:" prop="gameName">
+                        <el-input v-model.trim="giftGameDto.gameName" placeholder="请输入内容"></el-input>
+                    </el-form-item>
+
+                    <el-form-item label="游戏简介:" prop="gameIntroduction">
+
+                        <el-input
+                                type="textarea"
+                                :autosize="{ minRows: 2, maxRows: 4}"
+                                placeholder="请输入内容"
+                                v-model.trim="giftGameDto.gameIntroduction">
+                        </el-input>
+                    </el-form-item>
+
+
+                    <el-form-item label="下载链接:" prop="downloadUrl">
+                        <el-input v-model.trim="giftGameDto.downloadUrl" placeholder="请输入内容"></el-input>
+                    </el-form-item>
+
+                    <el-form-item label="游戏图标:" prop="imageUrl">
+                        <el-upload
+                                :class="{'hiddenIcon':hiddenIcon}"
+                                action
+                                list-type="picture-card"
+                                :http-request="fileUploader"
+                                :on-remove="handelRemoveFile"
+                                :limit="1"
+                                :file-list="fileList"
+                        >
+                            <i slot="default" class="el-icon-plus"></i>
+                        </el-upload>
+                    </el-form-item>
+
+                </el-form>
+
+            </div>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="handelCancel">取 消</el-button>
+                <el-button type="primary" @click="handelClickConform">确 定</el-button>
+            </span>
+        </el-dialog>
+    </div>
+
+
+</template>
+
+<script>
+
+    import {uploadFile} from '@/utils/util'
+    import feedbackApi from '@/api/feedback'
+    import giftApi from '@/api/gift'
+
+    export default {
+        name: "giftGameList",
+        data() {
+            return {
+                giftGameList: [],
+                gameList: [],
+                params: {},
+                dialog: {
+                    title: '请选择需要反馈的游戏',
+                    visible: false
+                },
+                giftGameDto: {},
+                uploadFile: {},
+                hiddenIcon:false,
+                isUpdate: false,
+                total: 0,
+                pageSize: 20,
+                curPage: 1,
+                rules: {
+                    gameId: [{required: true, message: '请选择游戏', trigger: 'change'}],
+                    gameName: [{required: true, message: '请输入游戏名称', trigger: 'blur'}],
+                    gameIntroduction: [{required: true, message: '请输入游戏简介', trigger: 'blur'}]
+                },
+                fileList:[]
+
+            }
+        },
+        mounted() {
+            this.getGameList();
+            this.getGiftGameList()
+        },
+        methods: {
+            /**
+             * 获取游戏列表
+             */
+            getGameList() {
+                feedbackApi.getGameList().then(res => {
+                    this.gameList = this.params.gameId ? res.filter(f => f.gameId == this.params.gameId) : res;
+                });
+            },
+
+            getGiftGameList() {
+                giftApi.getGiftGameList().then(res=> {
+                    this.giftGameList = this.params.gameId ? res.filter(f=>f.gameId == this.params.gameId) : res;
+                    this.total = this.giftGameList.length;
+                })
+            },
+
+
+            handelClickAdd() {
+                this.isUpdate = false;
+                feedbackApi.getGameList().then(res => {
+                    this.gameList = res.filter(f => !this.giftGameList.find(d => f.gameId == d.gameId) || f.gameId == this.giftGameDto.gameId);
+                    this.dialog.visible = true
+                });
+            },
+            fileUploader(params) {
+                this.hiddenIcon = true;
+                this.uploadFile = params.file;
+                this.handelUploadFile(this.uploadCallback)
+            },
+
+            /**
+             * 上传截图
+             * @param callback
+             */
+            handelUploadFile(callback) {
+                uploadFile(this.uploadFile, callback);
+            },
+
+            /**
+             * 上传成功之后的回调
+             * @param fileUrl
+             */
+            uploadCallback(fileUrl) {
+                //将文件url放入新的list中
+                console.log(fileUrl);
+                this.giftGameDto.imageUrl = fileUrl;
+                console.log(this.giftGameDto)
+            },
+            handelRemoveFile() {
+                this.hiddenIcon = false;
+                this.giftGameDto.imageUrl = ''
+            },
+
+            handelCancel() {
+                this.handelRemoveFile();
+                this.$refs['giftGameForm'].resetFields();
+                this.dialog.visible = false;
+                this.hiddenIcon = false;
+                this.fileList = []
+            },
+
+            handelClickConform() {
+                this.$refs['giftGameForm'].validate((valid) => {
+                    if (valid) {
+                        this.isUpdate ? giftApi.updateGiftGame(this.giftGameDto).then(this.refreshDto) :
+                        giftApi.addGiftGame(this.giftGameDto).then(this.refreshDto)
+                    } else {
+                        console.log('error submit!!');
+                        return false;
+                    }
+                });
+            },
+            refreshDto(res) {
+                this.handelCancel();
+                this.getGiftGameList()
+            },
+            handelDelete(id) {
+                this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    type: 'warning'
+                }).then(() => {
+                    giftApi.deleteGiftGame(id).then(res => {
+                        this.$message({
+                            type: 'success',
+                            message: '删除成功!'
+                        });
+                        this.handelCancel();
+                        this.getGiftGameList()
+                    });
+
+                }).catch(() => {
+                    this.$message({
+                        type: 'info',
+                        message: '已取消删除'
+                    });
+                });
+            },
+
+
+            handelUpdate(id) {
+                this.isUpdate = true;
+                giftApi.getGiftGameById(id).then(res=> {
+                    this.giftGameDto = res;
+                    feedbackApi.getGameList().then(res => {
+                        this.gameList = res.filter(f => !this.giftGameList.find(d => f.gameId == d.gameId) || f.gameId == this.giftGameDto.gameId);
+                        this.fileList= [{url:this.giftGameDto.imageUrl}];
+                        this.hiddenIcon = true;
+                        this.dialog.visible = true
+                    });
+                });
+            },
+            /**
+             * 处理前端分页
+             * @param val
+             */
+            handleSizeChange(val) {
+                this.pageSize = val;
+            },
+            handleCurrentChange(val) {
+                this.curPage = val;
+            },
+        }
+    }
+</script>
+
+<style lang="less" scoped>
+    .giftGameList {
+        .head {
+            .el-select {
+                width: 300px;
+                margin: 4px;
+            }
+        }
+
+        /deep/ .el-dialog {
+            width: 600px;
+            .el-select {
+                width: 100%;
+            }
+        }
+        .hiddenIcon {
+            /deep/ .el-upload--picture-card {
+                display: none;
+            }
+        }
+    }
+</style>

+ 486 - 0
src/views/giftList/giftList.vue

@@ -0,0 +1,486 @@
+<template>
+    <div class="giftList flex-display">
+
+        <div class="head">
+            <div class="text">
+
+                <div class="head-item">
+                    <el-select v-model="params.gameId" placeholder="请选择所属游戏" filterable clearable>
+                        <el-option
+                                v-for="item in giftGameList"
+                                :key="item.gameId"
+                                :label="item.gameId + '_' +item.gameName"
+                                :value="item.gameId"
+                        ></el-option>
+                    </el-select>
+                </div>
+
+                <div class="head-item" placeholder="请选择创建时间">
+                    <el-date-picker
+                            v-model="createTime"
+                            @change="handelCreateTimeChange"
+                            type="datetimerange"
+                            :value-format="'yyyy-MM-dd HH:mm:ss'"
+                            start-placeholder="日期"
+                            end-placeholder="日期"
+                            :default-time="['00:00:00', '23:59:59']"
+                    ></el-date-picker>
+                </div>
+
+                <div class="head-item">
+                    <el-select v-model="params.state" placeholder="请选择完成状态">
+                        <el-option
+                                v-for="item in stateList"
+                                :key="item.text"
+                                :label="item.text"
+                                :value="item.value"
+                        ></el-option>
+                    </el-select>
+                </div>
+
+                <div class="head-item">
+                    <el-select v-model="params.keywords" placeholder="请选择礼包类型">
+                        <el-option
+                                v-for="item in keywordsList"
+                                :key="item.text"
+                                :label="item.text"
+                                :value="item.value"
+                        ></el-option>
+                    </el-select>
+                </div>
+
+            </div>
+
+            <div class="action">
+                <el-button plain type="primary" icon="el-icon-search" @click="getGiftLists">搜索</el-button>
+                <el-button plain type="success" icon="el-icon-circle-plus-outline" @click="handelClickAdd">新增
+                </el-button>
+            </div>
+        </div>
+
+        <div class="list">
+            <el-table :data="giftList.slice((curPage-1)*pageSize,curPage*pageSize)" border stripe :fit="false" height="100%" @sort-change="handelSortChange">
+                <el-table-column label="礼包编号" prop="id" width="150" show-overflow-tooltip/>
+                <el-table-column label="礼包名称" prop="giftName" width="150" show-overflow-tooltip/>
+                <el-table-column label="礼包描述" prop="giftContent" width="150" show-overflow-tooltip/>
+                <el-table-column label="所属游戏" prop="gameName" width="150" show-overflow-tooltip/>
+                <el-table-column label="领取数量" prop="amount" width="150" show-overflow-tooltip sortable/>
+                <el-table-column label="剩余数量" prop="restAmount" width="150" show-overflow-tooltip sortable/>
+                <el-table-column label="礼包类型" width="150" show-overflow-tooltip >
+                    <template slot-scope="scope">
+                        <el-tag>{{convertType(scope.row.keywords)}}
+                        </el-tag>
+                    </template>
+                </el-table-column>
+                <el-table-column label="关键字" prop="keywords" width="150" show-overflow-tooltip />
+                <el-table-column label="创建时间" prop="createTime" width="150" show-overflow-tooltip sortable="custom"/>
+                <el-table-column label="是否开启" prop="state" width="150" show-overflow-tooltip :formatter="states"/>
+                <el-table-column label="操作" width="180">
+                    <template slot-scope="scope">
+                        <div class="headrow">
+                            <el-button size="mini" @click="handelGift(scope.row.id)">编辑</el-button>
+                            <el-button size="mini" type="danger" @click="handelDelete(scope.row.id)">删除</el-button>
+                        </div>
+                    </template>
+                </el-table-column>
+            </el-table>
+        </div>
+
+        <div class="page">
+            <el-pagination
+                    @size-change="handleSizeChange"
+                    @current-change="handleCurrentChange"
+                    layout="total, sizes, prev, pager, next, jumper"
+                    :page-size="pageSize"
+                    :current-page="curPage"
+                    :pager-count="11"
+                    :total="total"
+            ></el-pagination>
+        </div>
+
+        <el-dialog :title="dialog.title" :visible.sync="dialog.visible" center @close="handelCancel">
+            <div class="content">
+
+                <el-form label-width="100px" :rules="rules" :model="giftDto" ref="giftForm">
+                    <div class="item" v-if="!isUpdate">
+                        <el-form-item label="所属游戏:" prop="gameId">
+                        <el-select v-model="giftDto.gameId" placeholder="请选择所属游戏" filterable clearable>
+                            <el-option
+                                    v-for="item in giftGameList"
+                                    :key="item.gameId"
+                                    :label="item.gameId + '_' +item.gameName"
+                                    :value="item.gameId"
+                            ></el-option>
+                        </el-select>
+                        </el-form-item>
+                    </div>
+
+                    <el-form-item label="礼包名:" prop="giftName" >
+                        <el-input v-model.trim="giftDto.giftName" placeholder="请输入内容"></el-input>
+                    </el-form-item>
+
+                    <el-form-item label="礼包描述:" prop="giftContent" v-if="isUpdate">
+                        <el-input v-model.trim="giftDto.giftContent" placeholder="请输入内容"></el-input>
+                    </el-form-item>
+
+                    <el-form-item label="礼包码:" prop="giftCode" >
+                        <el-input
+                                type="textarea"
+                                :rows="2"
+                                placeholder="请输入内容"
+                                v-model="giftDto.giftCode">
+                        </el-input>
+                    </el-form-item>
+
+                    <div class="code" v-if="isUpdate">
+                        <el-button type="primary" size="medium" @click="handelCode">编辑礼包码</el-button>
+                    </div>
+
+                    <div class="dis">
+                        <el-radio-group v-model="giftDto.display" @change="o">
+                            <el-radio :label="0" border >页面展示</el-radio>
+                            <el-radio :label="1" border>关键字回复</el-radio>
+                        </el-radio-group>
+                    </div>
+
+                    <el-form-item label="关键字:" prop="keywords" v-show="giftDto.display === 1">
+                        <el-input v-model.trim="giftDto.keywords" placeholder="请输入关键字"></el-input>
+                    </el-form-item>
+
+                    <div class="dis" v-show="isUpdate">
+                    <template>
+                        <el-radio v-model="giftDto.state" :label="1">关闭</el-radio>
+                        <el-radio v-model="giftDto.state" :label="0">开启</el-radio>
+                    </template>
+                    </div>
+
+                    <div class="dis" v-show="giftDto.state == 0 && giftDto.display == 1">
+                        <el-checkbox-group v-model="checkList" @change="handelChangeCheckBox">
+                            <el-checkbox v-for="item in typeList" :label="item.value" border>{{item.label}}</el-checkbox>
+                        </el-checkbox-group>
+                    </div>
+
+                </el-form>
+
+            </div>
+
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="handelCancel">取 消</el-button>
+                <el-button type="primary" @click="handelClickConform">确 定</el-button>
+            </span>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+
+    import giftListApi from '@/api/giftList'
+    import {getLastDay, formatTime} from '@/utils/util'
+
+    export default {
+        name: "giftList",
+        data(){
+            return {
+                createTime:'',
+                params:{
+                },
+                giftList:[],
+                giftGameList:[],
+                total: 0,
+                pageSize: 20,
+                curPage: 1,
+                isUpdate:false,
+                stateList:[
+                    {value:0,text:'开启'},
+                    {value:1,text:'关闭'},
+                    {value:null,text:'全部'}
+                ],
+                keywordsList:[
+                    {value:0,text:'页面展示'},
+                    {value:1,text:'关键字回复'},
+                    {value:null,text:'全部'}
+                ],
+                // typeOptions:[
+                //     {value:0,text:''}
+                //     ],
+                dialog:{
+                    title:'请添加所属游戏礼包',
+                    visible:false
+                },
+                giftDto:{
+                    giftName:'',
+                    giftCode:'',
+                    giftContent:'',
+                    keywords:'',
+
+                },
+                dialogs:{
+                },
+                rules:{
+                    gameId:{required:true,message:'请选择游戏',trigger: 'blur'},
+                    giftName:{required:true,message:'请输入礼包名',trigger: 'blur'},
+                    giftCode:{required:true,message:'请输入礼包码',trigger: 'blur'}
+                },
+                param:{},
+                checkList:[],
+                typeList:[
+                    {label:'订阅号',value:'subscribe'},
+                    {label:'服务号',value:'service'}
+                ]
+            }
+        },
+        mounted(){
+            this.init()
+        },
+        methods:{
+            /**
+             * 初始化
+             */
+            init(){
+                /*let lastDay = getLastDay(3);
+                this.createTime = lastDay;
+                this.params.createStartTime = lastDay ? formatTime(lastDay[0]) : null;
+                this.params.createEndTime = lastDay ? formatTime(lastDay[1]) : null;*/
+                this.getGameList();
+                this.getGiftLists()
+            },
+            /**
+             * 游戏列表
+             */
+            getGameList(){
+                giftListApi.getGameList().then(res=>{
+                    console.log(res)
+                    this.giftGameList = this.params.gameId ? res.filter(f=> f.gameId == this.params.gameId) : res.filter(f => f.deleted != 1)
+                })
+            },
+            /**
+             * 礼包列表
+             */
+            getGiftLists(){
+                giftListApi.getGiftList(this.params).then(res=>{
+                    this.giftList = res.rows;
+                    this.giftList.map(m => {
+                        if(m.keywords != null && m.keywords !=''){
+                            m.display = 1;
+                        }
+                        else {
+                            m.display = 0;
+                        }
+                    });
+                    console.log(this.giftList)
+                    this.total = this.giftList.length;
+                })
+            },
+            /**
+             * 时间
+             */
+            handelCreateTimeChange(val) {
+                this.params.createStartTime = val ? val[0] : null;
+                this.params.createEndTime = val ? val[1] : null;
+            },
+            handelClickAdd(){
+                giftListApi.getGameList().then(res=>{
+                    this.giftGameList = this.params.gameId ? res.filter(f=>f.gameId == this.params.gameId) : res.filter(f => f.deleted != 1)
+                    this.dialog.visible=true
+                })
+            },
+            /**
+             * 确定按钮
+             */
+            handelClickConform(){
+
+                this.$refs['giftForm'].validate((valid =>{
+                    if(valid){
+                        if(this.giftDto.giftCode != undefined)
+                            this.giftDto.giftCode = (this.giftDto.giftCode).split('\n').join(',')
+
+                        if(this.giftDto.display == 0){
+                            this.giftDto.keywords = '';
+                        }
+
+                        this.giftDto.type = this.checkList.join(',')
+
+                        //this.giftDto.type.filter(f => f != )
+
+                        this.isUpdate ? giftListApi.updateGift(this.giftDto).then(this.refresh)
+                            : giftListApi.addGift(this.giftDto).then(this.refresh)
+                    }else{
+                        console.log('error submit');
+                        return false
+                    }
+                }))
+            },
+            /**
+             * 刷新
+             */
+            refresh(){
+                this.getGiftLists();
+                this.handelCancel()
+            },
+            /**
+             * 取消按钮
+             */
+            handelCancel(){
+                this.$refs['giftForm'].resetFields();
+                this.dialog.visible=false;
+                this.isUpdate=false;
+                this.giftDto = {
+                        giftName:'',
+                        giftCode:''
+                    }
+                this.checkList=[]
+                this.rules.giftCode={required:true,message:'请输入礼包码',trigger: 'blur'}
+            },
+            /**
+             * 编辑
+             * @param id
+             */
+            handelGift(id){
+                this.isUpdate=true;
+                giftListApi.getGiftById(id).then(res=> {
+                    this.giftDto={
+                        id:res.id,
+                        gameId:res.gameId,
+                        giftName:res.giftName,
+                        state:res.state,
+                        giftContent:res.giftContent,
+                        keywords:res.keywords,
+
+                        oldType:res.type,
+                        oldKeywords:res.keywords
+                    };
+
+                    if(res.type != '' && res.type != null)
+                        this.checkList = res.type.split(',');
+                    //this.check = this.checkList;
+                    console.log(this.checkList);
+
+                    if(res.keywords != null && res.keywords != '' ){
+                        this.giftDto.display = 1;
+                    }
+                    else
+                        this.giftDto.display = 0;
+
+                    let resListForm = 1;
+                    let ListForm = Object.assign({},this.giftDto,resListForm);//合并对象
+                    this.giftDto = ListForm;
+
+
+                    this.rules.giftCode='';
+
+                    this.param.giftId=res.id;
+                    this.param.gameId=res.gameId;
+                    this.dialog.visible=true
+                }
+                );
+            },
+            handelDelete(id){
+                this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    type: 'warning'
+                }).then(() => {
+                    giftListApi.deleteGift(id).then(res => {
+                        this.$message({
+                            type: 'success',
+                            message: '删除成功!'
+                        });
+                        this.refresh()
+                    });
+
+                }).catch(() => {
+                    this.$message({
+                        type: 'info',
+                        message: '已取消删除'
+                    });
+                });
+            },
+            /**
+             * 后端排序
+             * @param order
+             */
+            handelSortChange({ prop, order }) {
+                console.log(prop);
+
+                let orderBy = prop.replace(/([A-Z])/g,"_$1").toLowerCase() + ':';
+
+                if (order == 'descending') {
+                    this.params.orderBy = orderBy + 'desc'
+                } else if (order == 'ascending') {
+                    this.params.orderBy = orderBy + 'asc'
+                } else {
+                    this.params.orderBy = null
+                }
+
+
+
+                // console.log(order)
+                // if (order == 'descending') {
+                //     this.params.orderBy = 1
+                // } else if (order == 'ascending') {
+                //     this.params.orderBy = 0
+                // } else {
+                //     this.params.orderBy = null
+                // }
+                this.getGiftLists()
+            },
+            handelCode(){
+                this.$router.push({
+                    name: "giftCodeList",
+                    params:this.param,
+                })
+            },
+            handleSizeChange(val) {
+                this.pageSize = val;
+            },
+            handleCurrentChange(val) {
+                this.curPage = val;
+            },
+
+            states(row,column) {
+                if (row.state === 0) {
+                return '开启';
+                }
+                else if(row.state === 1) {
+                    return '关闭'
+                }
+            },
+            convertType(keywords){
+                if(keywords !== '' && keywords !== null){
+                    return "关键字回复"
+                }else
+                    return "页面展示"
+            },
+            handelChangeCheckBox(val){
+
+            },
+            o(val){
+
+            }
+
+        }
+    }
+</script >
+
+<style lang="less" scoped>
+    .giftList {
+
+        /deep/ .el-dialog {
+            width: 400px;
+            .el-select {
+                width: 100%;
+            }
+            .content{
+                .dis{
+                    text-align:center;
+                    margin: 20px 0
+                }
+                .code{
+                    text-align:center;
+
+                }
+            }
+        }
+    }
+
+</style>

+ 136 - 0
src/views/loginLogList/loginLogList.vue

@@ -0,0 +1,136 @@
+<template>
+    <div class="loginLogList flex-display">
+
+        <div class="head">
+            <div class="text">
+                <div class="head-item">
+                    <el-input v-model="params.uid" placeholder="请输入内容" clearable>
+                        <template slot="prepend">用户id</template>
+                    </el-input>
+                </div>
+                <div class="head-item">
+                    <el-input v-model="params.gameId" placeholder="请输入内容" clearable>
+                        <template slot="prepend">游戏id</template>
+                    </el-input>
+                </div>
+            </div>
+            <div class="action">
+                <el-button plain type="primary" icon="el-icon-search" @click="getLoginLogList">搜索</el-button>
+            </div>
+        </div>
+
+        <div class="list">
+            <el-table
+                    :data="loginLogList"
+                    style="width: 100%"
+                    row-key="logId"
+                    border
+                    lazy
+                    height="100%"
+                    :load="load"
+                    :tree-props="{children: 'children', hasChildren: 'hasChildren'}">
+                <el-table-column prop="uid" label="用户id" width="180"></el-table-column>
+                <el-table-column prop="gameId" label="游戏id" width="180"></el-table-column>
+                <el-table-column prop="adFlag" label="adFlag" width="180"></el-table-column>
+                <el-table-column prop="ip" label="ip" width="180"></el-table-column>
+                <el-table-column prop="imei" label="imei" width="180"></el-table-column>
+                <el-table-column prop="logTime" label="登陆时间" width="180"></el-table-column>
+                <el-table-column label="操作" width="180">
+                    <template slot-scope="scope">
+                        <div class="headrow">
+                            <el-button type="danger" icon="el-icon-edit" size="mini" @click="banUser(scope.row.uid)" v-show="scope.row.hasChildren">封号</el-button>
+                        </div>
+                    </template>
+                </el-table-column>
+            </el-table>
+        </div>
+
+        <div class="page">
+            <el-pagination
+                    @size-change="handleSizeChange"
+                    @current-change="handleCurrentChange"
+                    layout="total, sizes, prev, pager, next, jumper"
+                    :page-size="page.size"
+                    :pager-count="11"
+                    :total="page.total"
+            ></el-pagination>
+        </div>
+
+    </div>
+</template>
+
+<script>
+    import logInfoApi from '@/api/logInfo'
+
+    export default {
+        name: "loginLogList",
+        data(){
+            return{
+                params:{},
+                loginLogList:[],
+                personLoginLogList:[],
+                banPersonDto:{},
+                page: {},
+            }
+        },
+        mounted(){
+            this.getLoginLogList()
+        },
+        methods:{
+            getLoginLogList(){
+                logInfoApi.getLoginLogList(this.params).then(res =>{
+                    this.loginLogList = res.rows;
+                    this.page = res.page;
+                    this.loginLogList.map(m => m.hasChildren=true)
+                })
+            },
+            banUser(id) {
+                this.banPersonDto={
+                    uid:id,
+                    status:'1',
+                };
+                this.$confirm('此操作将永久封禁该用户, 是否继续?', '提示', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    type: 'warning'
+                }).then(() => {
+                    logInfoApi.banPerson(this.banPersonDto).then(res => {
+                        this.$message({
+                            type: 'success',
+                            message: '封禁成功!'
+                        });
+                        this.getLoginLogList()
+                    });
+                }).catch(() => {
+                    this.$message({
+                        type: 'info',
+                        message: '已取消封禁'
+                    });
+                });
+            },
+            load(tree, treeNode, resolve) {
+                console.log(tree);
+                logInfoApi.getLoginLogByUid(tree).then(res => {
+                    this.personLoginLogList = res;
+                    console.log(res);
+                    setTimeout(() => {
+                        resolve(res)
+                    }, 0)
+                });
+            },
+            handleSizeChange(val) {
+                this.$log.debug(val);
+                this.params.size = val;
+                this.getLoginLogList()
+            },
+            handleCurrentChange(val) {
+                this.params.cur = val;
+                this.getLoginLogList()
+            },
+        }
+    }
+</script>
+
+<style lang="less" scoped>
+
+</style>

+ 177 - 0
src/views/message/messageList.vue

@@ -0,0 +1,177 @@
+<template>
+    <div class="messageList flex-display">
+        <div class="head">
+            <div class="action">
+                <el-button plain type="success" icon="el-icon-circle-plus-outline" @click="dialog.visible=true">新增</el-button>
+                <el-button plain type="warning" icon="el-icon-edit" @click="updateMessage">确认变更</el-button>
+            </div>
+        </div>
+
+        <div class="list">
+            <el-table :data="messageList" border stripe :fit="false" height="100%">
+                <el-table-column label="消息类型" prop="msgType" width="150" show-overflow-tooltip/>
+                <el-table-column label="文本消息内容" prop="content" width="150" show-overflow-tooltip/>
+
+                <el-table-column label="图片消息id" prop="mediaId" width="150" show-overflow-tooltip/>
+
+                <el-table-column label="图文消息标题" prop="title" width="150" show-overflow-tooltip/>
+                <el-table-column label="图文消息描述" prop="description" width="150" show-overflow-tooltip/>
+                <el-table-column label="图文消息图片地址" prop="picUrl" width="150" show-overflow-tooltip/>
+                <el-table-column label="图文消息地址" prop="url" width="150" show-overflow-tooltip/>
+                <el-table-column label="关键字" prop="hinge" width="150" show-overflow-tooltip/>
+                <el-table-column label="操作" width="180">
+                    <template slot-scope="scope">
+                        <div class="headrow">
+                            <el-button size="mini" @click="handelMessage(scope.row.id)">编辑</el-button>
+                            <el-button size="mini" type="danger" @click="handelDelete(scope.row.id)">删除</el-button>
+                        </div>
+                    </template>
+                </el-table-column>
+            </el-table>
+        </div>
+
+        <el-dialog :title="dialog.title" :visible.sync="dialog.visible" center @close="handelCancel">
+            <div class="content">
+
+                <el-form label-width="100px" :model="messageDto" ref="buttonForm">
+
+                    <el-form-item label="消息类型:" prop="msgType">
+                        <template>
+                            <el-select v-model="messageDto.msgType" placeholder="请选择">
+                                <el-option
+                                        v-for="item in options"
+                                        :key="item.value"
+                                        :label="item.label"
+                                        :value="item.value">
+                                </el-option>
+                            </el-select>
+                        </template>
+                    </el-form-item>
+                    <el-form-item label="文本消息内容:" prop="content" v-show="messageDto.msgType == 'text'">
+                        <el-input
+                                type="textarea"
+                                :autosize="{ minRows: 2, maxRows: 4}"
+                                placeholder="请输入内容"
+                                v-model="messageDto.content">
+                        </el-input>
+                    </el-form-item>
+
+                    <el-form-item label="图片id:" prop="mediaId" v-show="messageDto.msgType == 'image'">
+                        <el-input v-model="messageDto.mediaId" placeholder="请输入关键字"></el-input>
+                    </el-form-item>
+
+                    <el-form-item label="图文标题:" prop="title" v-show="messageDto.msgType == 'news'">
+                        <el-input v-model="messageDto.title" placeholder="请输入内容"></el-input>
+                    </el-form-item>
+                    <el-form-item label="图文描述:" prop="description" v-show="messageDto.msgType == 'news'">
+                        <el-input v-model="messageDto.description" placeholder="请输入内容"></el-input>
+                    </el-form-item>
+                    <el-form-item label="图片地址:" prop="picUrl" v-show="messageDto.msgType == 'news'">
+                        <el-input v-model="messageDto.picUrl" placeholder="请输入内容"></el-input>
+                    </el-form-item>
+                    <el-form-item label="图文地址:" prop="url" v-show="messageDto.msgType == 'news'">
+                        <el-input v-model="messageDto.url" placeholder="请输入内容"></el-input>
+                    </el-form-item>
+                    <el-form-item label="关键字:" prop="hinge" >
+                        <el-input v-model="messageDto.hinge" placeholder="请输入关键字"></el-input>
+                    </el-form-item>
+                </el-form>
+
+            </div>
+
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="handelCancel">取 消</el-button>
+                <el-button type="primary" @click="handelClickConform">确 定</el-button>
+            </span>
+        </el-dialog>
+
+    </div>
+</template>
+
+<script>
+    import messageList from "@/api/messageList"
+    export default {
+        name: "messageList",
+        data(){
+            return{
+                messageList:[],
+                isUpdate:false,
+                dialog:{
+                    title:'新增',
+                    visible:false
+                },
+                messageDto:{},
+                options:[{value:'text',label:'文本消息'},
+                    {value:'news',label:'图文消息'},
+                        {value:'image',label:'图片消息'}],
+            }
+        },
+        mounted(){
+            this.getMessageList()
+        },
+        methods:{
+            getMessageList(){
+                messageList.getMessageList().then(res =>{
+                    this.messageList=res
+                    console.log(res)
+                })
+            },
+            refresh(){
+                this.getMessageList();
+                this.handelCancel();
+            },
+            handelCancel() {
+                this.isUpdate=false;
+                this.dialog.visible=false;
+                this.messageDto={}
+            },
+            handelDelete(id){
+                this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    type: 'warning'
+                }).then(() => {
+                    messageList.deleteMessage(id).then(res => {
+                        this.$message({
+                            type: 'success',
+                            message: '删除成功!'
+                        });
+                        this.refresh();
+                    });
+
+                }).catch(() => {
+                    this.$message({
+                        type: 'info',
+                        message: '已取消删除'
+                    });
+                });
+            },
+            handelMessage(id){
+                this.isUpdate=true;
+                messageList.getMessageById(id).then(res => {
+                    this.messageDto = res
+                    this.dialog.visible=true;
+                })
+
+            },
+            handelClickConform(){
+
+                this.isUpdate ? messageList.updateMessage(this.messageDto).then(this.refresh) :
+                    messageList.addMessage(this.messageDto).then(this.refresh)
+            },
+            updateMessage(){
+                messageList.refreshMessage().then(this.refresh)
+            }
+
+        }
+    }
+</script>
+
+<style lang="less" scoped>
+    .messageList{
+
+        /deep/ .el-dialog {
+            width: 500px;
+        }
+    }
+</style>

+ 134 - 0
src/views/miniTestList/MiniTypeList.vue

@@ -0,0 +1,134 @@
+<template>
+    <div class="mini-type-list">
+        <common-list
+                :table_data="table_data"
+                @handel_search="handel_search"
+                @handel_delete="handel_delete"
+                @handel_update="handel_update"
+        >
+        </common-list>
+    </div>
+</template>
+
+<script>
+    import CommonList from '@/components/CommonList'
+    import {mapActions} from 'vuex'
+    import miniTypeApi from '@/api/mini_type';
+
+    export default {
+        name: "MiniTypeList",
+        data() {
+            return {
+                head_list: [
+                    {
+                        type: 'select',
+                        model: 'classId',
+                        placeholder: '请选择类别',
+                        list: 'classList',
+                        prop: {
+                            value: 'id',
+                            text: 'className'
+                        }
+                    },
+                ],
+                action_list: [
+                    {
+                        type: 'primary',
+                        icon: 'el-icon-search',
+                        value: '搜索',
+                        click: 'handel_search',
+                        params: 'params'
+                    },
+
+                    {
+                        type: 'success',
+                        icon: 'el-icon-circle-plus-outline',
+                        value: '导入',
+                        upload: true
+                    },
+                ],
+                table_props: {},
+                table_list: [
+                    {label: 'id', prop: 'id'},
+                    {label: '题型名称', prop: 'typeName', type: 'text'},
+                    {label: '测试人数', prop: 'amount', type: 'text'},
+                    {label: '真实测试人数', prop: 'realAmount', type: 'text'},
+                    {label: '轮播', prop: 'carousel', type: 'bool_tag'},
+                    {label: '猜你喜欢', prop: 'love', type: 'bool_tag'},
+                    {label: '每日推荐', prop: 'recommend', type: 'bool_tag'},
+                    {label: '热点', prop: 'hot', type: 'bool_tag'},
+                ],
+                table_data: [],
+                dialog_list: [{label: 'id', prop: 'id', placeholder: '请输入id'}],
+                dialog_data: {}
+            }
+        },
+        components: {
+            CommonList
+        },
+        mounted() {
+            this.init();
+        },
+        methods: {
+            ...mapActions([
+                'set_head_list',
+                'set_table_list',
+                'set_head_data_map',
+                'set_table_data',
+                'set_action_list',
+                'set_dialog_list',
+                'set_dialog_data',
+            ]),
+            init() {
+                this.set_head_list(this.head_list);
+
+                this.set_action_list(this.action_list);
+
+                this.set_table_list(this.table_list);
+
+                this.handel_search();
+
+                this.get_head_data();
+            },
+            get_head_data() {
+                let that = this;
+                miniTypeApi.class_list().then(res => {
+                    this.set_head_data_map({classList: res});
+                })
+            },
+            handel_search(params) {
+                let that = this;
+                miniTypeApi.list(params).then(res => {
+                    this.set_table_data(res);
+                })
+
+            },
+
+            convert_tree(list) {
+                list.forEach(f => {
+                    if (f.question || f.option) {
+                        f.children = f.question || f.option;
+                        this.convert_tree(f.question || f.option)
+                    }
+                })
+            },
+
+            handel_delete(id) {
+                console.log(id)
+            },
+            handel_update(id, callback) {
+                let dto = {id: id};
+                this.set_dialog_list(this.dialog_list);
+                this.set_dialog_data(dto);
+                callback()
+            },
+
+        }
+    }
+</script>
+
+<style lang="less" scoped>
+    .mini-type-list {
+        height: 100%;
+    }
+</style>

+ 64 - 0
src/views/miniTestList/miniTestList.vue

@@ -0,0 +1,64 @@
+<template>
+    <div class="miniTestList flex-display">
+
+        <div class="head">
+            <div class="text">
+                <el-select v-model="params.className" placeholder="请选择游戏" filterable clearable>
+                    <el-option
+                            v-for="item in MiniClassNameList"
+                            :key="item.className"
+                            :label="item.id + '-' +item.className"
+                            :value="item.className"
+                    ></el-option>
+                </el-select>
+                </div>
+            </div>
+        </div>
+
+</template>
+
+<script>
+    import miniTestApi from '@/api/miniTest'
+    import { mapState, mapActions } from 'vuex'
+    import store from '@/store/'
+
+    export default {
+        name: "miniTestList",
+        data(){
+            return{
+                miniTestList: [],
+                params: {},
+                MiniClassNameList: {},
+
+            }
+        },
+        mounted(){
+            this.init();
+            // this.getMiniTestList()
+            // this.getMiniClassList()
+        },
+        methods:{
+
+            ...mapActions(['set_head_list']),
+
+            init() {
+                console.log(store);
+                console.log(this.set_head_list);
+            },
+
+            getMiniTestList(){
+                miniTestApi.getMiniTestList().then(res => console.log(res))
+            },
+            getMiniClassList(){
+                miniTestApi.getMiniClassList().then(res =>{
+                    this.MiniClassNameList = res;
+                });
+            }
+
+        }
+    }
+</script>
+
+<style lang="less" scoped>
+
+</style>

+ 412 - 0
src/views/order/orderList.vue

@@ -0,0 +1,412 @@
+<template>
+    <div class="orderList">
+        <div class="head">
+            <div class="text headrow">
+                <el-input placeholder="请输入内容" v-model="params.orderId" clearable>
+                    <template slot="prepend">订单编号</template>
+                </el-input>
+
+                <el-input placeholder="请输入内容" v-model="params.cpBillNo" clearable>
+                    <template slot="prepend">CP订单号</template>
+                </el-input>
+
+                <el-input placeholder="请输入内容" v-model="params.loginName" clearable>
+                    <template slot="prepend">用户账号</template>
+                </el-input>
+
+                <el-input placeholder="请输入内容" v-model="params.adFlag" clearable>
+                    <template slot="prepend">广告标识</template>
+                </el-input>
+            </div>
+
+            <div class="select headrow">
+                <el-select v-model="params.status" placeholder="请选择订单状态" clearable>
+                    <el-option
+                            v-for="item in statusOptions"
+                            :key="item.value"
+                            :label="item.label"
+                            :value="item.value"
+                    ></el-option>
+                </el-select>
+
+                <el-select v-model="params.orderPlatfrom" placeholder="请选择订单平台" filterable clearable>
+                    <el-option
+                            v-for="item in platfromOptions"
+                            :key="item.value"
+                            :label="item.value + '_' + item.text"
+                            :value="item.value"
+                    ></el-option>
+                </el-select>
+
+                <el-select v-model="params.payType" placeholder="请选择支付类型" filterable clearable>
+                    <el-option
+                            v-for="item in payTypeOptions"
+                            :key="item.value"
+                            :label="item.text"
+                            :value="item.value"
+                    ></el-option>
+                </el-select>
+
+                <el-select v-model="params.gameId" placeholder="请选择游戏" filterable clearable>
+                    <el-option
+                            v-for="item in gameList"
+                            :key="item.gameId"
+                            :label="item.gameId + '_' +item.name"
+                            :value="item.gameId"
+                    ></el-option>
+                </el-select>
+            </div>
+
+            <div class="interval headrow">
+                <el-date-picker
+                        v-model="pagTime"
+                        @change="handelPayTimeChange"
+                        type="datetimerange"
+                        :value-format="'yyyy-MM-dd HH:mm:ss'"
+                        start-placeholder="充值日期"
+                        end-placeholder="充值日期"
+                        :default-time="['00:00:00', '23:59:59']"
+                ></el-date-picker>
+
+                <el-date-picker
+                        v-model="regTime"
+                        @change="handelRegTimeChange"
+                        type="datetimerange"
+                        :value-format="'yyyy-MM-dd HH:mm:ss'"
+                        start-placeholder="注册日期"
+                        end-placeholder="注册日期"
+                        :default-time="['00:00:00', '23:59:59']"
+                ></el-date-picker>
+
+                <div class="range headrow">
+                    <el-input placeholder="充值金额范围" v-model="params.orderStartAmount" clearable/>
+                    -
+                    <el-input placeholder="充值金额范围" v-model="params.orderEndAmount" clearable/>
+                </div>
+
+                <el-select
+                        v-model="channleIdList"
+                        placeholder="请选择渠道"
+                        filterable
+                        clearable
+                        multiple
+                        @change="handelChannelChange"
+                >
+                    <el-option
+                            v-for="item in channelList"
+                            :key="item.channelId"
+                            :label="item.channelId + '_' +item.channelName"
+                            :value="item.channelId"
+                    ></el-option>
+                </el-select>
+            </div>
+
+            <div class="action">
+                <el-button plain type="primary" icon="el-icon-search" @click="getOrderList">搜索</el-button>
+                <el-button plain type="danger" icon="el-icon-coin" @click="dialogVisible = true">导出</el-button>
+            </div>
+        </div>
+
+        <div class="list">
+            <el-table :data="orderList" border stripe :fit="false" height="100%">
+                <el-table-column label="渠道广告ID" prop="channelAdid" width="150" show-overflow-tooltip/>
+                <el-table-column label="用户UID" prop="uid" width="150" show-overflow-tooltip fixed="left"/>
+                <el-table-column label="下单时间" prop="orderTime" width="150" show-overflow-tooltip/>
+                <el-table-column label="注册时间" prop="regTime" width="150" show-overflow-tooltip/>
+                <el-table-column label="订单金额" prop="orderAmount" width="150" show-overflow-tooltip fixed="right"/>
+                <el-table-column label="订单状态" prop="status" width="150" show-overflow-tooltip>
+                    <template slot-scope="scope">
+                        <el-tag
+                                :type="orderStatusType(scope.row.status)"
+                        >{{statusOptions.find(obj=> scope.row.status == obj['value'])['label']}}
+                        </el-tag>
+                    </template>
+                </el-table-column>
+                <el-table-column label="订单编号" prop="orderId" width="150" show-overflow-tooltip/>
+                <el-table-column label="CP订单号" prop="cpBillNo" width="150" show-overflow-tooltip/>
+                <el-table-column label="区服ID" prop="serverId" width="150" show-overflow-tooltip/>
+                <el-table-column label="用户账号" prop="loginName" width="150" show-overflow-tooltip/>
+                <el-table-column label="广告名称" prop="adName" width="150" show-overflow-tooltip/>
+                <el-table-column label="充值包标识" prop="adFlag" width="150" show-overflow-tooltip/>
+                <el-table-column label="注册包标识" prop="regFlag" width="150" show-overflow-tooltip/>
+                <el-table-column label="游戏名称" prop="gameName" width="150" show-overflow-tooltip/>
+                <el-table-column label="角色名称" prop="roleName" width="150" show-overflow-tooltip
+                                 fixed="left"
+                                 :formatter="formatRoleName"
+                />
+                <el-table-column label="支付方式" prop="payType" width="150" show-overflow-tooltip>
+                    <template slot-scope="scope" v-if="scope.row.payType">
+                        <el-tag>{{payTypeText(scope.row.payType)}}
+                        </el-tag>
+                    </template>
+                </el-table-column>
+                <el-table-column label="订单平台" prop="orderPlatfrom" width="150" show-overflow-tooltip>
+                    <template slot-scope="scope">
+                        <el-tag>{{platfromOptions.find(obj=> scope.row.orderPlatfrom == obj['value'])['text']}}
+                        </el-tag>
+                    </template>
+                </el-table-column>
+                <el-table-column label="支付成功时间" prop="payTime" width="150" show-overflow-tooltip fixed="right"/>
+                <el-table-column label="OPENID" prop="orderId" width="150" show-overflow-tooltip/>
+            </el-table>
+        </div>
+
+        <div class="page">
+            <el-pagination
+                    @size-change="handleSizeChange"
+                    @current-change="handleCurrentChange"
+                    layout="total, sizes, prev, pager, next, jumper"
+                    :page-size="page.size"
+                    :pager-count="11"
+                    :total="page.total"
+            ></el-pagination>
+        </div>
+
+        <el-dialog title="请选择要导出的字段" :visible.sync="dialogVisible" width="30%" center>
+            <div class="content">
+                <el-checkbox
+                        style="margin-left:4px;"
+                        :indeterminate="isIndeterminate"
+                        v-model="checkAll"
+                        @change="handleCheckAllChange"
+                >全选
+                </el-checkbox>
+                <div style="margin: 15px 0;"></div>
+                <el-checkbox-group v-model="checkedFieldList" @change="handleCheckedFieldChange">
+                    <el-checkbox
+                            style="width:200px; margin:4px;"
+                            v-for="item in fieldList"
+                            :label="item.javaField"
+                            :key="item.javaField"
+                    >{{item.label}}
+                    </el-checkbox>
+                </el-checkbox-group>
+            </div>
+            <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisible = false">取 消</el-button>
+        <el-button type="primary" @click="handelExcelExport">确 定</el-button>
+      </span>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+    import orderApi from '@/api/order'
+    import {getLastDay, formatTime} from '@/utils/util'
+
+    export default {
+        name: 'orderList',
+        data() {
+            return {
+                orderList: [],
+                page: {},
+                params: {},
+                statusOptions: [
+                    {label: '待支付', value: 1},
+                    {label: '充值成功', value: 2},
+                    {label: '已发货', value: 3},
+                    {label: '充值失败', value: -1},
+                    {label: '发货失败', value: -2},
+                    {label: '苹果验证失败', value: -3}
+                ],
+                tableHeight: (window.innerHeight / 3) * 2,
+                platfromOptions: [],
+                payTypeOptions: [],
+                gameList: [],
+                channelList: [],
+                pagTime: '',
+                regTime: '',
+                dialogVisible: false,
+                channleIdList: [],
+                fieldList: [
+                    {label: '订单编号', javaField: 'orderId'},
+                    {label: 'CP订单号', javaField: 'cpBillNo'},
+                    {label: '用户UID', javaField: 'uid'},
+                    {label: '区服ID', javaField: 'serverId'},
+                    {label: '用户账号', javaField: 'loginName'},
+                    {label: '广告名称', javaField: 'adName'},
+                    {label: '充值包标识', javaField: 'adFlag'},
+                    {label: '注册包标识', javaField: 'regFlag'},
+                    {label: '游戏名称', javaField: 'gameName'},
+                    {label: '角色名称', javaField: 'roleName'},
+                    {label: '支付方式', javaField: 'payType"'},
+                    {label: '订单平台', javaField: 'orderPlatfrom'},
+                    {label: '订单金额', javaField: 'orderAmount'},
+                    {label: '订单状态', javaField: 'status'},
+                    {label: '下单时间', javaField: 'orderTime'},
+                    {label: '注册时间', javaField: 'regTime'},
+                    {label: '支付成功时间', javaField: 'payTime'},
+                    {label: 'OPENID', javaField: 'openId'},
+                    {label: '渠道广告ID', javaField: 'channelAdid'},
+                    {label: '过滤notfound', javaField: 'filterNotfound'}
+                ],
+                checkAll: false,
+                checkedFieldList: ['uid', 'orderAmount', 'payTime', 'regTime'],
+                isIndeterminate: true
+            }
+        },
+        mounted() {
+            this.init()
+        },
+        methods: {
+            async init() {
+                let lastDay = getLastDay(3)
+                this.pagTime = lastDay
+                this.params.orderStartTime = lastDay ? formatTime(lastDay[0]) : null
+                this.params.orderEndTime = lastDay ? formatTime(lastDay[1]) : null
+                await this.getSelectOptions();
+                this.getOrderList()
+            },
+            getOrderList() {
+                orderApi.getOrderList(this.params).then(res => {
+                    this.$log.debug(res)
+                    this.orderList = res.rows
+                    this.page = res.page
+                })
+            },
+
+            async getSelectOptions() {
+                await orderApi.getSelectOptions().then(res => {
+                    this.$log.debug(res)
+                    this.gameList = res.game.map(m => {
+                        m.name = m.gameFlag + '_' + m.gameName
+                        return m
+                    })
+                    this.payTypeOptions = res.payType
+                    this.platfromOptions = res.payPlatform
+                    this.channelList = res.channel
+                })
+            },
+
+            handleSizeChange(val) {
+                this.$log.debug(val)
+                this.params.size = val
+                this.getOrderList()
+            },
+            handleCurrentChange(val) {
+                this.params.cur = val
+                this.getOrderList()
+            },
+            handelPayTimeChange(val) {
+                this.params.orderStartTime = val ? val[0] : null
+                this.params.orderEndTime = val ? val[1] : null
+                this.$log.debug(this.params)
+            },
+            handelRegTimeChange(val) {
+                this.params.regStartTime = val ? val[0] : null
+                this.params.regEndTime = val ? val[1] : null
+                this.$log.debug(this.params)
+            },
+            handleCheckedFieldChange(val) {
+                this.$log.debug(val)
+                let checkedCount = val.length
+                this.checkAll = checkedCount === this.fieldList.length
+                this.isIndeterminate =
+                    checkedCount > 0 && checkedCount < this.fieldList.length
+            },
+            handleCheckAllChange(val) {
+                this.$log.debug(val);
+                this.checkedFieldList = val
+                    ? this.fieldList.map(obj => {
+                        return obj.javaField
+                    })
+                    : [];
+                this.isIndeterminate = false
+            },
+            handelExcelExport() {
+                if (JSON.stringify(this.params) === '{}') {
+                    this.$message({message: '查询条件不能为空', type: 'warning'})
+                    return
+                }
+                let map = {};
+                map.vo = this.fieldList.filter(
+                    f => this.checkedFieldList.indexOf(f.javaField) != -1
+                );
+                map.dto = this.params;
+                let jsonData = JSON.stringify(map);
+                let a = document.createElement('a');
+                a.href = `${orderApi.baseUrl}/v2/excel?jsonData=${jsonData}`;
+                a.click();
+                this.dialogVisible = false
+            },
+            handelChannelChange(val) {
+                if (val && val.length && val.length != 0) {
+                    if (val.length === 1) {
+                        this.params.channelId = val[0]
+                    } else {
+                        this.params.channelId = val.join(',')
+                    }
+                } else {
+                    this.params.channelId = null
+                }
+            },
+            orderStatusType(status) {
+                if (status == '3') {
+                    return 'success'
+                } else if (status > 0 && status < 3) {
+                    return 'warning'
+                } else {
+                    return 'danger'
+                }
+            },
+            payTypeText(payType) {
+                if (!payType) {
+                    return ""
+                }
+                this.$log.debug(payType);
+                return this.payTypeOptions.find(obj => obj.value == payType).text
+            },
+            formatRoleName(row, column, cellValue, index) {
+                return decodeURI(cellValue)
+            }
+        }
+    }
+</script>
+
+<style lang="less" scoped>
+    .orderList {
+        height: 100%;
+        overflow: hidden;
+        display: flex;
+        flex-direction: column;
+        justify-content: space-between;
+
+        .head {
+            margin: 4px;
+
+            .text {
+                .el-input {
+                    margin: 4px;
+                }
+            }
+
+            .select {
+                .el-select {
+                    margin: 4px;
+                    width: 25%;
+                }
+            }
+
+            .interval {
+                .el-range-editor {
+                    margin: 4px;
+                    width: 25%;
+                }
+
+                .range {
+                    margin: 4px;
+                    width: 25%;
+                }
+
+                .el-select {
+                    margin: 4px;
+                    width: 25%;
+                }
+            }
+
+            .action {
+                margin: 4px;
+            }
+        }
+    }
+</style>

+ 235 - 0
src/views/table/table.vue

@@ -0,0 +1,235 @@
+<template>
+    <div class="table flex-display">
+
+        <div class="head">
+            <div class="action">
+                <el-button plain type="success" icon="el-icon-circle-plus-outline" @click="handelOneMenu">新增一级菜单
+                </el-button>
+                <el-button plain type="warning" icon="el-icon-edit" @click="handelWechatMenu">修改菜单</el-button>
+            </div>
+        </div>
+
+        <div class="list">
+            <el-table
+                    :data="MenuList"
+                    style="width: 100%;margin-bottom: 20px;"
+                    row-key="id"
+                    border
+                    height="100%"
+                    default-expand-all
+                    :tree-props="{children: 'children', hasChildren: 'hasChildren'}">
+                <el-table-column prop="sname" label="菜单" width="180"></el-table-column>
+                <el-table-column prop="type" label="type" width="180"></el-table-column>
+                <el-table-column prop="skey" label="key" width="180"></el-table-column>
+                <el-table-column prop="url" label="url" width="180"></el-table-column>
+                <el-table-column prop="mediaId" label="media_id" width="180"></el-table-column>
+                <el-table-column prop="appid" label="appid" width="180"></el-table-column>
+                <el-table-column prop="pagepath" label="pagepath" width="180"></el-table-column>
+                <el-table-column label="操作" width="180">
+                    <template slot-scope="scope">
+                        <div class="headrow">
+                            <el-button size="mini" @click="handelMenu(scope)">{{scope.row.isAdd?"新增":"编辑"}}</el-button>
+                            <el-button size="mini" type="danger" @click="handelDelete(scope)">删除</el-button>
+                        </div>
+                    </template>
+                </el-table-column>
+            </el-table>
+        </div>
+
+        <el-dialog :title="dialog.title" :visible.sync="dialog.visible" center @close="handelCancel">
+            <div class="content">
+
+                <el-form label-width="100px" :model="MenuDto" ref="buttonForm">
+
+                    <el-form-item label="响应动作类型:" prop="type">
+                        <template>
+                            <el-select v-model="MenuDto.type" placeholder="请选择">
+                                <el-option
+                                        v-for="item in options"
+                                        :key="item.value"
+                                        :label="item.label"
+                                        :value="item.value">
+                                </el-option>
+                            </el-select>
+                        </template>
+                    </el-form-item>
+
+                    <el-form-item label="菜单名称:" prop="sname">
+                        <el-input v-model="MenuDto.sname" placeholder="请输入内容"></el-input>
+                    </el-form-item>
+
+                    <el-form-item label="key:" prop="skey">
+                        <el-input v-model="MenuDto.skey" placeholder="请输入内容"></el-input>
+                    </el-form-item>
+
+                    <el-form-item label="url:" prop="url">
+                        <el-input v-model="MenuDto.url" placeholder="请输入内容"></el-input>
+                    </el-form-item>
+
+                    <el-form-item label="media_id:" prop="mediaId">
+                        <el-input v-model="MenuDto.mediaId" placeholder="请输入内容"></el-input>
+                    </el-form-item>
+
+                    <el-form-item label="appid:" prop="appid" v-show="MenuDto.type == 'miniprogram'">
+                        <el-input v-model="MenuDto.appid" placeholder="请输入内容"></el-input>
+                    </el-form-item>
+
+                    <el-form-item label="pagepath:" prop="pagepath" v-show="MenuDto.type == 'miniprogram'">
+                        <el-input v-model="MenuDto.pagepath" placeholder="请输入内容"></el-input>
+                    </el-form-item>
+                </el-form>
+
+            </div>
+
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="handelCancel">取 消</el-button>
+                <el-button type="primary" @click="handelClickConform">确 定</el-button>
+            </span>
+        </el-dialog>
+
+    </div>
+</template>
+
+<script>
+    import tableApi from '@/api/table'
+
+    export default {
+        name: "tableList",
+        data() {
+            return {
+                buttonList: [],
+                button: {},
+                dialog: {
+                    visible: false,
+                    title: '新增'
+                },
+                subButton: {},
+
+                isUpdate: false,
+                MenuList: [],
+                MenuDto: {},
+                options: [{value: 'view', label: '网页类型'},
+                    {value: 'click', label: '点击类型'},
+                    {value: 'miniprogram', label: '小程序类型'}]
+
+            }
+        },
+        mounted() {
+            this.getMenuList()
+        },
+        methods: {
+            getMenuList() {
+                tableApi.getMenuList().then(res => {
+                    let treeList = this.treeConver(res);
+                    this.MenuList = treeList[0].children;
+                    this.MenuList.map(m => m.isAdd = true);
+                })
+            },
+            treeConver(list) {
+                let parentList = list.filter(f => f.parentId == -1);
+                parentList.forEach(f => {
+                    this.findChildren(f, list);
+                });
+                return parentList;
+            },
+            findChildren(parent, list) {
+                let childrenList = list.filter(f => f.parentId == parent.id);
+                parent.children = childrenList;
+                if (childrenList && childrenList.length > 0) {
+                    childrenList.forEach(children => {
+                        this.findChildren(children, list)
+                    })
+                }
+            },
+            handelOneMenu() {
+                this.MenuDto.parentId = 1;
+                this.MenuList.length < 3 ? this.dialog.visible = true : this.open('公众号一级菜单最多3项,请删除再试!');
+            },
+            open(message) {
+                this.$alert(message, '警告', {
+                    confirmButtonText: '确定',
+                    callback: () => {
+                        this.$message({
+                            type: 'info',
+                            message: `请删除再试`
+                        });
+                    }
+                });
+            },
+            /**
+             *  新增/编辑
+             */
+            handelMenu(scope) {
+                this.dialog.visible = true;
+                if (!scope.row.isAdd) {
+                    tableApi.getMenuById(scope.row.id).then(res => {
+                        this.isUpdate = true;
+                        this.MenuDto = res;
+                    })
+                }
+                else if (scope.row.children.length < 6) {
+                    this.MenuDto.parentId = scope.row.id;
+                } else {
+                    this.open('公众号二级菜单最多6项,请删除再试!')
+                    this.dialog.visible = false;
+                }
+            },
+            handelDelete(scope) {
+                this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    type: 'warning'
+                }).then(() => {
+                    tableApi.deleteMenu(scope.row.id).then(res => {
+                        this.$message({
+                            type: 'success',
+                            message: '删除成功!'
+                        });
+                        this.refresh()
+                    });
+
+                }).catch(() => {
+                    this.$message({
+                        type: 'info',
+                        message: '已取消删除'
+                    });
+                });
+            },
+            handelClickConform() {
+                if (this.isUpdate) {
+                    tableApi.updateSub(this.MenuDto).then(this.refresh)
+                } else {
+                    tableApi.addMenu(this.MenuDto).then(this.refresh)
+                }
+            },
+            /**
+             * 刷新
+             */
+            refresh() {
+                this.getMenuList()
+                this.handelCancel()
+            },
+            /**
+             * 取消按钮
+             */
+            handelCancel() {
+                this.dialog.visible = false;
+                this.isUpdate = false;
+                this.MenuDto = {}
+            },
+
+            handelWechatMenu() {
+                tableApi.setMenu().then(this.refresh);
+            }
+        }
+
+    }
+</script>
+
+<style lang="less" scoped>
+    .table {
+        /deep/ .el-dialog {
+            width: 450px;
+        }
+    }
+</style>

+ 553 - 0
src/views/test/Test2.vue

@@ -0,0 +1,553 @@
+<template>
+    <div class="test2">
+
+        <div class="test2-wrapper">
+            <div class="header">
+                <el-button plain type="primary" icon="el-icon-search" @click="handel_search">刷 新</el-button>
+                <!--<el-button @click="checkedKeys">得到节点id</el-button>-->
+                <el-upload
+                        action
+                        :show-file-list="false"
+                        class="upload-demo"
+                        :http-request="file_uploader"
+                        :before-upload="file_verified"
+                >
+                    <el-button plain
+                               type="success"
+                               icon="el-icon-circle-plus-outline"
+                    >导 入
+                    </el-button>
+                </el-upload>
+
+                <!--<el-button plain type="info" icon="el-icon-arrow-up" @click="order_by_real_amount" style="margin-right:0px">真实人数排序</el-button>-->
+                <!--<el-button plain type="info" icon="el-icon-arrow-down" @click="order_by_false_amount">虚假人数排序</el-button>-->
+                <!--<el-button plain type="info" icon="el-icon-edit" @click="handel_type" >编辑</el-button>-->
+
+
+
+                <div class="head-item">
+                    <el-select v-model="params.orderByInfo" placeholder="请选择">
+                        <el-option
+                                v-for="item in selectList"
+                                :key="item.text"
+                                :label="item.label"
+                                :value="item.value"
+                        ></el-option>
+                    </el-select>
+                </div>
+
+                <div class="text headrow">
+                    <el-input v-model="params.typeName" placeholder="请输入题目内容内容" style="width:200px"></el-input>
+                    <el-input v-model="params.typeId" placeholder="请输入题型编号" style="width:200px"></el-input>
+                    <el-date-picker
+                            v-model="params.updateDate"
+                            style="width:200px"
+                            value-format="yyyyMMdd"
+                            type="date"
+                            placeholder="选择日期">
+                    </el-date-picker>
+                </div>
+
+                <div class="head-item">
+
+                    <el-select v-model="params.order" placeholder="请选择排序" @change="orderSelect">
+                        <el-option
+                                v-for="item in options"
+                                :key="item.value"
+                                :label="item.label"
+                                :value="item.value">
+                        </el-option>
+                    </el-select>
+
+                </div>
+
+                <el-button plain type="primary" icon="el-icon-search" @click="handel_search">搜索</el-button>
+
+                <el-button plain type="primary" icon="el-icon-search" @click="handel_cdn">刷新CDN</el-button>
+
+            </div>
+
+            <div class="data-wrapper">
+                <div class="left">
+
+                    <el-tree :data="table_data" :props="defaultProps" @node-click="handel_node_click" ref="tree"></el-tree>
+                             <!--node-key="id" show-checkbox :check-strictly="true"></el-tree>-->
+
+                </div>
+
+
+                <div class="center">
+                    <div class="content">
+                        <el-form label-width="100px" :model="dialog_dto" ref="ruleForm">
+
+                            <div v-for="dialog_item in dialog_list">
+                                <el-form-item
+                                        v-if="dialog_item.type === 'text'"
+                                        :label="dialog_item.label"
+                                        :prop="dialog_item.prop"
+                                >
+                                    <el-input v-model.trim="dialog_dto[dialog_item.prop]"
+                                              :placeholder="dialog_item.placeholder"/>
+                                </el-form-item>
+
+
+                                <el-form-item
+                                        v-if="dialog_item.type === 'text_disabled'"
+                                        :label="dialog_item.label"
+                                        :prop="dialog_item.prop"
+                                >
+                                    {{dialog_dto[dialog_item.prop]}}
+                                </el-form-item>
+
+                                <el-form-item
+                                        v-else-if="dialog_item.type === 'checkbox'"
+                                        :label="dialog_item.label"
+                                        :prop="dialog_item.prop"
+                                >
+                                    <el-checkbox :true-label="1" :false-label="0" v-model="dialog_dto[dialog_item.prop]"
+                                                 :checked="dialog_dto[dialog_item.prop] === 1" ></el-checkbox>
+                                </el-form-item>
+
+                                <el-form-item
+                                        v-if="dialog_item.type === 'date'"
+                                        :label="dialog_item.label"
+                                >
+                                    <el-date-picker
+                                            v-model="dialog_dto[dialog_item.prop]"
+                                            value-format="yyyyMMdd"
+                                            type="date"
+                                            placeholder="选择日期">
+                                    </el-date-picker>
+                                </el-form-item>
+
+                                <el-form-item
+                                        v-else-if="dialog_item.type === 'select'"
+                                        :label="dialog_item.label"
+                                >
+                                    <el-select v-model="dialog_dto[dialog_item.prop]"
+                                               :placeholder="dialog_item.placeholder">
+                                        <el-option
+                                                v-for="item in dialog_item.select"
+                                                :key="item.value"
+                                                :label="item.label"
+                                                :value="item.value"
+                                        ></el-option>
+                                    </el-select>
+                                </el-form-item>
+
+                                <el-form-item
+                                        v-if="dialog_item.type === 'select_number'"
+                                        :label="dialog_item.label"
+                                >
+                                    <!--<el-option -->
+                                            <!--v-for="item in options"-->
+                                            <!--:key="item.value"-->
+                                            <!--:label="item.label"-->
+                                            <!--:value="item.value">-->
+                                    <!--</el-option>-->
+
+                                    <el-select v-model="dialog_dto[dialog_item.prop]"
+                                               :placeholder="dialog_item.placeholder" clearable>
+                                        <el-option
+                                                v-for="item in options"
+                                                :key="item.value"
+                                                :label="item.label"
+                                                :value="item.value"
+                                        ></el-option>
+                                    </el-select>
+                                </el-form-item>
+
+                            </div>
+
+                        </el-form>
+
+                    </div>
+
+                    <div class="footer">
+                        <div class="footer-wrapper" v-if="dialog_list.length > 0">
+
+                            <el-button type="primary" @click="handel_dialog_conform(dialog_dto)">修 改</el-button>
+
+                        </div>
+                    </div>
+
+
+                </div>
+
+                <div class="right">
+
+                    <div class="right-wrapper" v-for="item in dialog_right_list">
+                        <div class="content">
+                            <el-form label-position="top">
+
+                                <el-form-item
+                                        :label="item.start + '-'+ item.end"
+                                >
+                                    <el-input
+                                            autosize
+                                            type="textarea"
+                                            v-model="item.resultName"
+                                            placeholder="请输入">
+                                    </el-input>
+                                </el-form-item>
+
+                            </el-form>
+
+                        </div>
+
+                        <div class="footer">
+                            <div class="footer-wrapper" v-if="dialog_right_list.length > 0">
+
+                                <el-button type="primary" @click="handel_dialog_conform(item)">修 改</el-button>
+
+                            </div>
+                        </div>
+                    </div>
+
+
+                </div>
+            </div>
+        </div>
+
+
+    </div>
+</template>
+
+<script>
+    import miniApi from '@/api/mini_test';
+    import {uploadFile} from '@/utils/util';
+
+    const class_dialog_list = [
+        {label: '类别名称', prop: 'className', placeholder: '请输入', type: 'text'}
+    ];
+
+    const type_dialog_list = [
+        {label: '类别', prop: 'classId', type: 'select'},
+        {label: '题型编号', prop: 'id', placeholder: '请输入', type: 'text_disabled'},
+        {label: '下题编号', prop: 'nextType', placeholder: '请输入', type: 'text'},
+        {label: '题型名称', prop: 'typeName', placeholder: '请输入', type: 'text'},
+        {label: '测试人数', prop: 'amount', placeholder: '请输入', type: 'text'},
+        {label: '真实测试人数', prop: 'realAmount', placeholder: '请输入', type: 'text_disabled'},
+        {label: '更新日期', prop: 'updateDate', placeholder: '请输入', type: 'date'},
+        {label: '首页图', prop: 'imageurlCarousel', placeholder: '请输入', type: 'text'},
+        {label: '轮播图', prop: 'carousel', placeholder: '请输入', type: 'checkbox'},
+        {label: '猜你喜欢', prop: 'love', placeholder: '请输入', type: 'checkbox'},
+        {label: '每日推荐', prop: 'recommend', placeholder: '请输入', type: 'checkbox'},
+        {label: '热点', prop: 'hot', placeholder: '请输入', type: 'checkbox'},
+        {label: '首页', prop: 'isFirst', placeholder: '请输入', type: 'checkbox'},
+        {label: '每日热点', prop: 'dayhot', placeholder: '请输入', type: 'checkbox'},
+        {label: '推荐', prop: 'daytuijian', placeholder: '请输入', type: 'checkbox'},
+        {label: '每日更新', prop: 'daynew', placeholder: '请输入', type: 'checkbox'},
+
+    ];
+
+    const question_dialog_list = [
+        {label: '问题名称', prop: 'questionName', placeholder: '请输入', type: 'text'}
+    ];
+
+    const option_dialog_list = [
+        {label: '选项名称', prop: 'optionName', placeholder: '请输入', type: 'text'},
+        {label: '选项分数', prop: 'optionScope', placeholder: '请输入', type: 'text'}
+    ];
+
+
+    export default {
+        name: "Test2",
+        data() {
+            return {
+              options: [{
+                value: '1',
+                label: '真实人数排序↓'
+              }, {
+                value: '2',
+                label: '虚假人数排序↓'
+              }, {
+                value: '3',
+                label: '更新时间排序↓'
+              }, {
+                value: '4',
+                label: '更新时间排序↑'
+              }],
+
+                fileList: [],
+                hiddenIcon: false,
+                uploadFile: {},
+
+                table_data: [],
+
+                dialog_list: [],
+                dialog_dto: {},
+
+                dialog_right_list: [],
+
+                defaultProps: {
+                    children: 'children',
+                    label: 'name'
+                },
+                params:{},
+              selectList:[
+                {label:'轮播图',value:'carousel'},
+                {label:'猜你喜欢',value:'love'},
+                {label:'每日推荐',value:'recommend'},
+                {label:'热点',value:'hot'},
+                {label:'首页',value:'isFirst'},
+                {label:'每日热点',value:'dayhot'},
+                {label:'推荐',value:'daytuijian'},
+                {label:'每日更新',value:'daynew'},
+                {label:'下题编号',value:'nextType'},
+              ],
+              classes:[]
+            }
+        },
+        mounted() {
+            this.init();
+        },
+        methods: {
+          checkedKeys(data) {
+            console.log(this.$refs.tree.getCheckedKeys())
+            alert(JSON.stringify(this.$refs.tree.getCheckedKeys()));
+          },
+            init() {
+                this.handel_search()
+            },
+
+            handel_search() {
+                const loading = this.$loading({
+                    lock: true,
+                    text: '拼命加载中',
+                    spinner: 'el-icon-loading',
+                    background: 'rgba(0, 0, 0, 0.7)'
+                });
+                this.dialog_right_list = [];
+                this.dialog_list = [];
+                miniApi.list(this.params).then(res => {
+                    this.convert_tree(res);
+                    this.table_data = res;
+                    console.log(res)
+                  this.classes = res;
+                    loading.close();
+                    this.params = {};
+                })
+            },
+
+            handel_node_click(item) {
+                this.dialog_dto = item;
+                let type = this.get_type(item);
+                this.dialog_right_list = [];
+                switch (type) {
+                    case 'class':
+                        this.dialog_list = class_dialog_list;
+                        break;
+                    case 'type':
+                        item.result.map(m => m.resultName = m.resultName.replace(/\\n/g,"\n"));
+                        miniApi.class_list().then(res => {
+                            let select = res.map(m => {
+                                return {
+                                    label: m.className,
+                                    value: m.id
+                                }
+                            });
+
+                            this.dialog_list = type_dialog_list;
+
+                            console.log(this.dialog_list)
+
+                            this.dialog_list.find(f => f.type = 'select').select = select;
+
+                            this.dialog_right_list = item.result;
+
+                            console.log(this.dialog_list)
+
+                        });
+
+                        break;
+                    case 'question':
+                        this.dialog_list = question_dialog_list;
+                        break;
+                    case 'option':
+                        this.dialog_list = option_dialog_list;
+                        break;
+                    case 'result':
+                        break;
+                    default:
+                        break;
+                }
+            },
+            convert_tree(list) {
+                list.forEach(f => {
+
+                    if (f.className && f.typeName) {
+                        f.name = f.typeName;
+                    } else if (f.questionName) {
+                        f.name = f.questionName;
+                    } else if (f.optionName) {
+                        f.name = f.optionName;
+                    } else {
+                        f.name = f.className;
+                    }
+
+                    if (f.type || f.question || f.option) {
+                        f.children = f.type || f.question || f.option;
+                        this.convert_tree(f.type || f.question || f.option)
+                    }
+                })
+            },
+            order_by_real_amount(){
+              this.params.realAmount = "true";
+              this.handel_search();
+            },
+            order_by_false_amount(){
+              this.params.amount = "true";
+              this.handel_search();
+            },
+            handel_dialog_cancel(item) {
+
+            },
+          orderSelect(val){
+            this.params.order = val;
+            this.handel_search();
+          },
+            get_type(item) {
+                if ('className' in item && 'typeName' in item) {
+                    return 'type';
+                } else if ('questionName' in item) {
+                    return 'question';
+                } else if ('optionName' in item) {
+                    return 'option';
+                } else if ('resultName' in item) {
+                    return 'result';
+                } else {
+                    return 'class';
+                }
+            },
+          handel_type(){
+
+          },
+            handel_dialog_conform(item) {
+
+
+                this.$confirm('此操作将修改数据, 是否继续?', '提示', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    type: 'warning'
+                }).then(() => {
+                    let type = this.get_type(item);
+                    switch (type) {
+                        case 'class':
+                            item.id = item.classId;
+                            miniApi.class_update(item).then(this.call_back);
+                            break;
+                        case 'type':
+                            console.log(item)
+                            miniApi.type_update(item).then(this.call_back);
+                            break;
+                        case 'question':
+                            miniApi.question_update(item).then(this.call_back);
+                            break;
+                        case 'option':
+                            miniApi.option_update(item).then(this.call_back);
+                            break;
+                        case 'result':
+                            miniApi.result_update(item).then(this.call_back);
+                            break;
+                        default:
+                            break;
+                    }
+                }).catch(() => {
+                    this.$message({
+                        type: 'info',
+                        message: '已取消'
+                    });
+                });
+            },
+            call_back(res) {
+                // this.handel_search();
+                this.$message({
+                    type: 'success',
+                    message: '修改成功!'
+                });
+            },
+            file_uploader(params) {
+                let formData = new FormData();
+                // 向 formData 对象中添加文件
+                formData.append('file', params.file);
+                miniApi.upload_excel(formData).then(res => {
+                   this.handel_search();
+                })
+            },
+            file_verified(params) {
+                let file_name = params.name;
+                let ext = file_name.substr(file_name.lastIndexOf('.') + 1, file_name.length - 1);
+                return ext === 'xls' || ext === 'xlsx';
+            },
+          handel_cdn(){
+            miniApi.freshCDN().then( this.init() )
+          }
+        }
+    }
+</script>
+
+<style lang="less" scoped>
+    .test2 {
+        position: relative;
+        padding: 4px 8px;
+        height: 100%;
+        background-color: #eee;
+        overflow: hidden;
+
+        .test2-wrapper {
+            height: 91%;
+            background-color: #fff;
+            border-radius: 4px;
+            .header {
+                margin: 0 0 10px;
+                padding: 10px;
+                display: flex;
+                justify-content: flex-start;
+                /deep/ .el-button {
+                    margin-right: 10px;
+                }
+            }
+
+            .data-wrapper {
+                display: flex;
+                justify-content: flex-start;
+                background-color: #fff;
+
+                padding: 4px;
+                height: 100%;
+                .left {
+                    overflow: auto;
+                    width: 33%;
+                }
+
+                /deep/ .el-form-item {
+
+                    width: 80%;
+                }
+                .content {
+
+                    width: 100%;
+
+                }
+                .footer {
+                    .footer-wrapper {
+                        display: flex;
+                        justify-content: space-around;
+                    }
+                }
+                .center {
+                    width: 40%;
+
+                    overflow: auto;
+
+                }
+                .right {
+                    overflow: auto;
+                    width: 26%;
+                }
+            }
+        }
+
+    }
+</style>

+ 141 - 0
src/views/test/TestCommon.vue

@@ -0,0 +1,141 @@
+<template>
+    <div class="test-common">
+        <common-list
+                :table_data="table_data"
+                @handel_search="handel_search"
+                @handel_delete="handel_delete"
+                @handel_update="handel_update"
+                @handel_upload="handel_upload"
+        >
+        </common-list>
+    </div>
+</template>
+
+<script>
+    import miniApi from '@/api/mini_test'
+    import CommonList from '@/components/CommonList'
+    import {mapActions} from 'vuex'
+
+    export default {
+        name: "TestCommon",
+        data() {
+            return {
+                head_list: [
+                    {
+                        model: 'gameId',
+                        placeholder: '请选择游戏',
+                        list: 'gameList',
+                        prop: {
+                            value: 'gameId',
+                            text: 'gameName'
+                        }
+                    }
+                ],
+                action_list: [
+                    {
+                        type: 'primary',
+                        icon: 'el-icon-search',
+                        value: '搜索',
+                        click: 'handel_search',
+                        params: 'params'
+                    },
+
+                    {
+                        type: 'success',
+                        icon: 'el-icon-circle-plus-outline',
+                        value: '导入',
+                        upload: true
+                    },
+                ],
+                table_props: {},
+                table_list: [
+                    {label: '类型', prop: 'className'},
+                    {label: '题型', prop: 'typeName'},
+                    {label: '问题', prop: 'questionName'},
+                    {label: '选项', prop: 'optionName'},
+                    {label: '分数', prop: 'optionScope'},
+                    {label: '轮播图', prop: 'carousel', type: 'bool_tag'},
+                    {label: '猜你喜欢', prop: 'like', type: 'bool_tag'},
+                    {label: '推荐', prop: 'recommend', type: 'bool_tag'},
+                ],
+                table_data: [],
+                dialog_list: [{label: 'id', prop: 'id', placeholder: '请输入id'}],
+                dialog_data: {}
+            }
+        },
+        components: {
+            CommonList
+        },
+        mounted() {
+            this.init();
+        },
+        methods: {
+            ...mapActions([
+                'set_head_list',
+                'set_table_list',
+                'set_head_data_map',
+                'set_table_data',
+                'set_action_list',
+                'set_dialog_list',
+                'set_dialog_data',
+            ]),
+            init() {
+                this.set_head_list(this.head_list);
+
+                this.set_action_list(this.action_list);
+
+                this.set_table_list(this.table_list);
+
+                this.handel_search();
+
+
+            },
+            get_head_data() {
+
+            },
+            handel_search(params) {
+                let that = this;
+                miniApi.list(params).then(res => {
+                    res[0].hasChildren = true;
+                    that.convert_tree(res);
+                    this.set_table_data(res);
+                })
+
+            },
+
+            convert_tree(list) {
+                list.forEach(f => {
+                    if (f.question || f.option) {
+                        f.children = f.question || f.option;
+                        this.convert_tree(f.question || f.option)
+                    }
+                })
+            },
+
+            handel_delete(id) {
+                console.log(id)
+            },
+            handel_update(id, callback) {
+                let dto = {id: id};
+                this.set_dialog_list(this.dialog_list);
+                this.set_dialog_data(dto);
+                callback()
+            },
+            handel_upload(params) {
+                let formData = new FormData();
+                // 向 formData 对象中添加文件
+                formData.append('file', params.file);
+                miniApi.upload_excel(formData).then(res => {
+                    console.log(res);
+                })
+            }
+
+        }
+    }
+</script>
+
+<style lang="less" scoped>
+    .test-common {
+        height: 100%;
+    }
+</style>

+ 111 - 0
src/views/userWhiteList/userWhiteList.vue

@@ -0,0 +1,111 @@
+<template>
+    <div class="userWhiteList flex-display">
+
+        <template>
+        <div class="head">
+            <div class="text">
+                <div class="head-item">
+                    <el-input v-model="params.uid" placeholder="请输入内容" clearable>
+                        <template slot="prepend">用户id</template>
+                    </el-input>
+                </div>
+            </div>
+
+            <div class="action">
+                <el-button plain type="primary" icon="el-icon-search" @click="getWhiteList">搜索</el-button>
+                <el-button plain type="success" icon="el-icon-edit" @click="addWhiteList">增加</el-button>
+            </div>
+        </div>
+        </template>
+
+        <div class="list">
+            <el-table :data="whiteList" border stripe :fit="false" height="100%">
+                <el-table-column label="白名单id" prop="id" width="150" show-overflow-tooltip/>
+                <el-table-column label="用户id" prop="uid" width="150" show-overflow-tooltip/>
+                <el-table-column label="创建时间" prop="createTime" width="150" show-overflow-tooltip/>
+                <el-table-column label="操作" width="180">
+                    <template slot-scope="scope">
+                        <div class="headrow">
+                                <el-button size="mini" @click="relieveUser(scope.row.id)">解除白名单</el-button>
+                        </div>
+                    </template>
+                </el-table-column>
+            </el-table>
+        </div>
+
+        <div class="page">
+            <el-pagination
+                    @size-change="handleSizeChange"
+                    @current-change="handleCurrentChange"
+                    layout="total, sizes, prev, pager, next, jumper"
+                    :page-size="page.size"
+                    :pager-count="11"
+                    :total="page.total"
+            ></el-pagination>
+        </div>
+
+    </div>
+</template>
+
+<script>
+    import logInfoApi from '@/api/logInfo'
+
+    export default {
+        name: "userWhiteList",
+        data(){
+            return{
+                whiteList:[],
+                params:{},
+                page: {},
+            }
+        },
+        mounted(){
+            this.getWhiteList();
+        },
+        methods: {
+            getWhiteList(){
+                logInfoApi.getWhiteList(this.params).then(res =>{
+                    this.whiteList = res.rows;
+                    this.page = res.page;
+                })
+            },
+            addWhiteList(){
+                logInfoApi.addWhiteList(this.params).then(this.getWhiteList)
+            },
+            relieveUser(id){
+                this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    type: 'warning'
+                }).then(() => {
+                    logInfoApi.deleteWhiteList(id).then(res => {
+                        this.$message({
+                            type: 'success',
+                            message: '删除成功!'
+                        });
+                        this.getWhiteList()
+                    });
+
+                }).catch(() => {
+                    this.$message({
+                        type: 'info',
+                        message: '已取消删除'
+                    });
+                });
+            },
+            handleSizeChange(val) {
+                this.$log.debug(val);
+                this.params.size = val;
+                this.getWhiteList()
+            },
+            handleCurrentChange(val) {
+                this.params.cur = val;
+                this.getWhiteList()
+            },
+        }
+    }
+</script>
+
+<style lang="less" scoped>
+
+</style>

+ 299 - 0
src/views/verified/verified.vue

@@ -0,0 +1,299 @@
+<template>
+    <div class="verified flex-display">
+        <div class="head">
+            <div class="text">
+                <el-select v-model="params.gameId" placeholder="请选择游戏" filterable clearable>
+                    <el-option
+                            v-for="item in gameList"
+                            :key="item.gameId"
+                            :label="item.gameId + '_' +item.gameName"
+                            :value="item.gameId"
+                    ></el-option>
+                </el-select>
+            </div>
+
+            <div class="action">
+                <el-button plain type="primary" icon="el-icon-search" @click="getGiftGameList">搜索</el-button>
+                <el-button plain type="success" icon="el-icon-circle-plus-outline" @click="handelClickAdd">新增
+                </el-button>
+            </div>
+        </div>
+        <div class="list">
+            <el-table :data="verifiedConfigList.slice((curPage-1)*pageSize,curPage*pageSize)" border stripe :fit="false" height="100%">
+                <!--<el-table-column label="游戏id" prop="gameId" width="150" show-overflow-tooltip/>-->
+                <!--<el-table-column label="游戏名称" prop="gameName" width="150" show-overflow-tooltip/>-->
+                <!--<el-table-column label="备注" prop="createTime" width="150" show-overflow-tooltip/>-->
+                <!--<el-table-column label="操作" width="180">-->
+                    <!--<template slot-scope="scope">-->
+                        <!--<div class="headrow">-->
+                            <!--<el-button size="mini" @click="handelUpdate(scope.row.id)">编辑</el-button>-->
+                            <!--<el-button size="mini" type="danger" @click="handelDelete(scope.row.id)">删除</el-button>-->
+                        <!--</div>-->
+                    <!--</template>-->
+                <!--</el-table-column>-->
+            </el-table>
+        </div>
+
+        <div class="page">
+            <el-pagination
+                    @size-change="handleSizeChange"
+                    @current-change="handleCurrentChange"
+                    layout="total, sizes, prev, pager, next, jumper"
+                    :page-size="pageSize"
+                    :current-page="curPage"
+                    :pager-count="11"
+                    :total="total"
+            ></el-pagination>
+        </div>
+
+        <el-dialog :title="dialog.title" :visible.sync="dialog.visible" center>
+            <div class="content">
+                <el-form label-width="100px" :rules="rules" :model="verifiedDto" ref="verifiedForm">
+
+                    <el-form-item label="广告名称:" prop="adId">
+                        <el-select v-model="verifiedDto.adId" placeholder="请选择" filterable clearable>
+                            <el-option
+                                    v-for="item in adList"
+                                    :key="item.adId"
+                                    :label="item.adId + '_' +item.adName"
+                                    :value="item.adId"
+                            ></el-option>
+                        </el-select>
+                    </el-form-item>
+
+                    <el-form-item label="是否弹出:" prop="showVerified">
+                        <el-select v-model="verifiedDto.showVerified" placeholder="请选择" filterable>
+                            <el-option
+                                    v-for="item in showVerifiedList"
+                                    :key="item.value"
+                                    :label="item.text"
+                                    :value="item.value"
+                            ></el-option>
+                        </el-select>
+                    </el-form-item>
+
+
+                    <el-form-item label="弹出地址:" prop="verifiedH5Url">
+                        <el-input v-model.trim="verifiedDto.verifiedH5Url" placeholder="请输入内容"></el-input>
+                    </el-form-item>
+
+                    <el-form-item label="条件:" prop="verifiedShowDetail">
+                        <div class="button">
+                            <el-button  icon="el-icon-edit" circle @click="handelClickAddCondition"></el-button>
+                        </div>
+                        <div class="detail-list">
+                            <div class="detail-item" v-for="items in verifiedShowDetail">
+
+                                <div class="item-top">
+                                    <el-select v-model="items.changeType" placeholder="请选择" filterable>
+                                        <el-option
+                                                v-for="item in conditionList"
+                                                :key="item.value"
+                                                :label="item.text"
+                                                :value="item.value"
+                                        ></el-option>
+                                    </el-select>
+                                </div>
+
+                                <div class="item-bottom">
+                                    <el-input
+                                            v-if="items.changeType && items.changeType == 3"
+                                            type="text"
+                                            placeholder="请输入内容"
+                                            v-model.trim="items.changeContent">
+                                    </el-input>
+
+                                    <el-select
+                                            v-else-if="items.changeType && items.changeType == 5"
+                                            v-model="items.changeContent"
+                                            placeholder="请选择"
+                                            filterable
+                                            multiple
+                                            clearable
+                                    >
+                                        <el-option
+                                                v-for="item in provinceList"
+                                                :key="item"
+                                                :label="item"
+                                                :value="item"
+                                        ></el-option>
+                                    </el-select>
+
+                                </div>
+                            </div>
+                        </div>
+                    </el-form-item>
+
+                </el-form>
+
+            </div>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="handelCancel">取 消</el-button>
+                <el-button type="primary" @click="handelClickConform">确 定</el-button>
+            </span>
+        </el-dialog>
+
+    </div>
+</template>
+
+<script>
+    import feedbackApi from '@/api/feedback'
+    import verifiedApi from '@/api/verified'
+    export default {
+        name: "verified",
+        data() {
+            return {
+                verifiedConfigList: [],
+                gameList: [],
+                adList:[],
+                params: {},
+                dialog: {
+                    title: '请选择需要反馈的游戏',
+                    visible: false
+                },
+                verifiedDto: {
+                    showVerified: 0
+                },
+                showVerifiedList:[
+                    {value: 0, text: '不弹出'},
+                    {value: 1, text: '弹出'},
+                    {value: 2, text: '条件弹出'}
+                ],
+                conditionList: [
+                    {text:'省份',value: 5},
+                    {text:'充值金额',value: 3},
+                    {text:'未绑定手机号',value: 9},
+                ],
+                verifiedShowDetail: [
+
+                ],
+                uploadFile: {},
+                hiddenIcon:false,
+                isUpdate: false,
+                total: 0,
+                pageSize: 20,
+                curPage: 1,
+                rules: {
+                    adId: [{required: true, message: '请选择广告', trigger: 'change'}]
+                },
+                provinceList:[
+                    '北京市',
+                    '天津市',
+                    '河北省',
+                    '山西省',
+                    '内蒙古自治区',
+                    '辽宁省',
+                    '吉林省',
+                    '黑龙江省',
+                    '上海市',
+                    '江苏省',
+                    '浙江省',
+                    '安徽省',
+                    '福建省',
+                    '江西省',
+                    '山东省',
+                    '河南省',
+                    '湖北省',
+                    '湖南省',
+                    '广东省',
+                    '广西壮族自治区',
+                    '海南省',
+                    '重庆市',
+                    '四川省',
+                    '贵州省',
+                    '云南省',
+                    '西藏自治区',
+                    '陕西省',
+                    '甘肃省',
+                    '青海省',
+                    '宁夏回族自治区',
+                    '新疆维吾尔自治区',
+                ]
+            }
+        },
+        mounted() {
+            this.getGameList();
+        },
+        methods: {
+            /**
+             * 获取游戏列表
+             */
+            getGameList() {
+                feedbackApi.getGameList().then(res => {
+                    this.gameList = this.params.gameId ? res.filter(f => f.gameId == this.params.gameId) : res;
+                });
+            },
+
+            getVerifiedConfigList() {
+                verifiedApi.getVerifiedConfigList().then(res=> {
+                    this.giftGameList = this.params.gameId ? res.filter(f=>f.gameId == this.params.gameId) : res;
+                    this.total = this.giftGameList.length;
+                })
+            },
+
+            getAdList(callback) {
+                verifiedApi.getAdList().then(res=> {
+                    this.adList = res;
+                    callback()
+                })
+            },
+
+            handelClickAddCondition() {
+                if (this.verifiedShowDetail.length >= 3) {
+                    this.$message({
+                        message: '最多只能选三个条件',
+                        type: 'warning'
+                    });
+                    return
+                }
+                this.verifiedShowDetail.push({})
+
+            },
+            handelClickAdd() {
+                this.getAdList(this.dialog.visible = true)
+            },
+            handelClickConform() {
+                this.$refs['verifiedForm'].validate((valid) => {
+                    if (valid) {
+                        this.isUpdate ? giftApi.updateGiftGame(this.giftGameDto).then(this.refreshDto) :
+                            giftApi.addGiftGame(this.giftGameDto).then(this.refreshDto)
+                    } else {
+                        console.log('error submit!!');
+                        return false;
+                    }
+                });
+            },
+            handelCancel() {
+                this.dialog.visible = false
+            }
+
+        }
+    }
+</script>
+
+<style lang="less" scoped>
+.verified {
+    .head {
+        .el-select {
+            width: 300px;
+            margin: 4px;
+        }
+    }
+    /deep/ .el-dialog {
+        width: 600px;
+        .el-select {
+            width: 100%;
+        }
+    }
+    .detail-list {
+        margin-top: 20px;
+        .detail-item {
+            margin-bottom: 20px;
+            .item-bottom {
+                margin-top: 10px;
+            }
+        }
+
+    }
+}
+</style>

+ 555 - 0
src/views/vip/Test2.vue

@@ -0,0 +1,555 @@
+<template>
+    <div class="test2">
+
+        <div class="test2-wrapper">
+            <div class="header">
+                <el-button plain type="primary" icon="el-icon-search" @click="handel_search">刷 新</el-button>
+                <!--<el-button @click="checkedKeys">得到节点id</el-button>-->
+                <el-upload
+                        action
+                        :show-file-list="false"
+                        class="upload-demo"
+                        :http-request="file_uploader"
+                        :before-upload="file_verified"
+                >
+                    <el-button plain
+                               type="success"
+                               icon="el-icon-circle-plus-outline"
+                    >导 入
+                    </el-button>
+                </el-upload>
+
+                <div class="head-item">
+                    <el-select v-model="params.orderByInfo" placeholder="请选择">
+                        <el-option
+                                v-for="item in selectList"
+                                :key="item.text"
+                                :label="item.label"
+                                :value="item.value"
+                        ></el-option>
+                    </el-select>
+                </div>
+                <div class="text headrow">
+                <el-input v-model="params.typeName" placeholder="请输入题目内容内容" style="width:200px"></el-input>
+                <el-input v-model="params.typeId" placeholder="请输入题型编号" style="width:200px"></el-input>
+                    <el-date-picker
+                            v-model="params.updateDate"
+                            style="width:200px"
+                            value-format="yyyyMMdd"
+                            type="date"
+                            placeholder="选择日期">
+                    </el-date-picker>
+                </div>
+
+
+                <el-button plain type="primary" icon="el-icon-search" @click="handel_search">搜索</el-button>
+
+                <el-button plain type="primary" icon="el-icon-search" @click="handel_cdn">刷新CDN</el-button>
+                <!--<el-button plain type="info" icon="el-icon-arrow-down" @click="order_by_real_amount" style="margin-right:0px">真实人数排序</el-button>-->
+                <!--<el-button plain type="info" icon="el-icon-arrow-down" @click="order_by_false_amount">虚假人数排序</el-button>-->
+                <!--<el-button plain type="info" icon="el-icon-arrow-up" @click="order_by_update_date_up">更新时间排序</el-button>-->
+                <!--<el-button plain type="info" icon="el-icon-arrow-down" @click="order_by_update_date_down">更新时间排序</el-button>-->
+                <!--&lt;!&ndash;<el-button plain type="info" icon="el-icon-edit" @click="handel_type" >编辑</el-button>&ndash;&gt;-->
+                <div class="head-item">
+
+                    <el-select v-model="params.order" placeholder="请选择排序" @change="orderSelect">
+                        <el-option
+                                v-for="item in options"
+                                :key="item.value"
+                                :label="item.label"
+                                :value="item.value">
+                        </el-option>
+                    </el-select>
+
+                </div>
+
+
+            </div>
+
+            <div class="data-wrapper">
+                <div class="left">
+
+                    <el-tree :data="table_data" :props="defaultProps" @node-click="handel_node_click" ref="tree"></el-tree>
+                    <!--node-key="id" show-checkbox :check-strictly="true"></el-tree>-->
+
+                </div>
+
+
+                <div class="center">
+                    <div class="content">
+                        <el-form label-width="100px" :model="dialog_dto" ref="ruleForm">
+
+                            <div v-for="dialog_item in dialog_list">
+                                <el-form-item
+                                        v-if="dialog_item.type === 'text'"
+                                        :label="dialog_item.label"
+                                        :prop="dialog_item.prop"
+                                >
+                                    <el-input v-model.trim="dialog_dto[dialog_item.prop]"
+                                              :placeholder="dialog_item.placeholder"/>
+                                </el-form-item>
+
+
+                                <el-form-item
+                                        v-if="dialog_item.type === 'text_disabled'"
+                                        :label="dialog_item.label"
+                                        :prop="dialog_item.prop"
+                                >
+                                    {{dialog_dto[dialog_item.prop]}}
+                                </el-form-item>
+
+                                <el-form-item
+                                        v-else-if="dialog_item.type === 'checkbox'"
+                                        :label="dialog_item.label"
+                                        :prop="dialog_item.prop"
+                                >
+                                    <el-checkbox :true-label="1" :false-label="0" v-model="dialog_dto[dialog_item.prop]"
+                                                 :checked="dialog_dto[dialog_item.prop] === 1" ></el-checkbox>
+                                </el-form-item>
+
+                                <el-form-item
+                                        v-else-if="dialog_item.type === 'select'"
+                                        :label="dialog_item.label"
+                                >
+                                    <el-select v-model="dialog_dto[dialog_item.prop]"
+                                               :placeholder="dialog_item.placeholder">
+                                        <el-option
+                                                v-for="item in dialog_item.select"
+                                                :key="item.value"
+                                                :label="item.label"
+                                                :value="item.value"
+                                        ></el-option>
+                                    </el-select>
+                                </el-form-item>
+
+                                <el-form-item
+                                        v-if="dialog_item.type === 'date'"
+                                        :label="dialog_item.label"
+                                >
+                                <el-date-picker
+                                        v-model="dialog_dto[dialog_item.prop]"
+                                        value-format="yyyyMMdd"
+                                        type="date"
+                                        placeholder="选择日期">
+                                </el-date-picker>
+                                </el-form-item>
+
+                                <el-form-item
+                                        v-if="dialog_item.type === 'select_number'"
+                                        :label="dialog_item.label"
+                                >
+                                    <!--<el-option -->
+                                    <!--v-for="item in options"-->
+                                    <!--:key="item.value"-->
+                                    <!--:label="item.label"-->
+                                    <!--:value="item.value">-->
+                                    <!--</el-option>-->
+
+                                    <el-select v-model="dialog_dto[dialog_item.prop]"
+                                               :placeholder="dialog_item.placeholder" clearable>
+                                        <el-option
+                                                v-for="item in options"
+                                                :key="item.value"
+                                                :label="item.label"
+                                                :value="item.value"
+                                        ></el-option>
+                                    </el-select>
+                                </el-form-item>
+
+                            </div>
+
+                        </el-form>
+
+                    </div>
+
+                    <div class="footer">
+                        <div class="footer-wrapper" v-if="dialog_list.length > 0">
+
+                            <el-button type="primary" @click="handel_dialog_conform(dialog_dto)">修 改</el-button>
+
+                        </div>
+                    </div>
+
+
+                </div>
+
+                <div class="right">
+
+                    <div class="right-wrapper" v-for="item in dialog_right_list">
+                        <div class="content">
+                            <el-form label-position="top">
+
+                                <el-form-item
+                                        :label="item.start + '-'+ item.end"
+                                >
+                                    <el-input
+                                            autosize
+                                            type="textarea"
+                                            v-model="item.resultName"
+                                            placeholder="请输入">
+                                    </el-input>
+                                </el-form-item>
+
+                            </el-form>
+
+                        </div>
+
+                        <div class="footer">
+                            <div class="footer-wrapper" v-if="dialog_right_list.length > 0">
+
+                                <el-button type="primary" @click="handel_dialog_conform(item)">修 改</el-button>
+
+                            </div>
+                        </div>
+                    </div>
+
+
+                </div>
+            </div>
+        </div>
+
+
+    </div>
+</template>
+
+<script>
+    import miniApi from '@/api/mini_test';
+    import {uploadFile} from '@/utils/util';
+
+    const class_dialog_list = [
+        {label: '类别名称', prop: 'className', placeholder: '请输入', type: 'text'}
+    ];
+
+    const type_dialog_list = [
+        {label: '类别', prop: 'classId', type: 'select'},
+        {label: '题型编号', prop: 'id', placeholder: '请输入', type: 'text_disabled'},
+        {label: '下题编号', prop: 'nextType', placeholder: '请输入', type: 'text'},
+        {label: '题型名称', prop: 'typeName', placeholder: '请输入', type: 'text'},
+        {label: '测试人数', prop: 'amount', placeholder: '请输入', type: 'text'},
+        {label: '真实测试人数', prop: 'realAmount', placeholder: '请输入', type: 'text_disabled'},
+        {label: '更新日期', prop: 'updateDate', placeholder: '请输入', type: 'date'},
+        {label: '首页图', prop: 'imageurlCarousel', placeholder: '请输入', type: 'text'},
+        {label: '轮播图', prop: 'carousel', placeholder: '请输入', type: 'checkbox'},
+        {label: '猜你喜欢', prop: 'love', placeholder: '请输入', type: 'checkbox'},
+        {label: '每日推荐', prop: 'recommend', placeholder: '请输入', type: 'checkbox'},
+        {label: '热点', prop: 'hot', placeholder: '请输入', type: 'checkbox'},
+        {label: '首页', prop: 'isFirst', placeholder: '请输入', type: 'checkbox'},
+        {label: '每日热点', prop: 'dayhot', placeholder: '请输入', type: 'checkbox'},
+        {label: '推荐', prop: 'daytuijian', placeholder: '请输入', type: 'checkbox'},
+        {label: '每日更新', prop: 'daynew', placeholder: '请输入', type: 'checkbox'},
+
+    ];
+
+    const question_dialog_list = [
+        {label: '问题名称', prop: 'questionName', placeholder: '请输入', type: 'text'}
+    ];
+
+    const option_dialog_list = [
+        {label: '选项名称', prop: 'optionName', placeholder: '请输入', type: 'text'},
+        {label: '选项分数', prop: 'optionScope', placeholder: '请输入', type: 'text'}
+    ];
+
+
+    export default {
+        name: "Test2",
+        data() {
+            return {
+                options: [{
+                    value: '1',
+                    label: '真实人数排序↓'
+                }, {
+                    value: '2',
+                    label: '虚假人数排序↓'
+                }, {
+                    value: '3',
+                    label: '更新时间排序↓'
+                }, {
+                    value: '4',
+                    label: '更新时间排序↑'
+                }],
+
+
+                fileList: [],
+                hiddenIcon: false,
+                uploadFile: {},
+
+                table_data: [],
+
+                dialog_list: [],
+                dialog_dto: {},
+
+                dialog_right_list: [],
+
+                defaultProps: {
+                    children: 'children',
+                    label: 'name'
+                },
+                params:{},
+                selectList:[
+                    {label:'轮播图',value:'carousel'},
+                    {label:'猜你喜欢',value:'love'},
+                    {label:'每日推荐',value:'recommend'},
+                    {label:'热点',value:'hot'},
+                    {label:'首页',value:'isFirst'},
+                    {label:'每日热点',value:'dayhot'},
+                    {label:'推荐',value:'daytuijian'},
+                    {label:'每日更新',value:'daynew'},
+                    {label:'下题编号',value:'nextType'},
+                ],
+                classes:[]
+            }
+        },
+        mounted() {
+            this.init();
+        },
+        methods: {
+            checkedKeys(data) {
+                console.log(this.$refs.tree.getCheckedKeys())
+                alert(JSON.stringify(this.$refs.tree.getCheckedKeys()));
+            },
+            init() {
+                this.handel_search()
+            },
+
+            handel_search() {
+                const loading = this.$loading({
+                    lock: true,
+                    text: '拼命加载中',
+                    spinner: 'el-icon-loading',
+                    background: 'rgba(0, 0, 0, 0.7)'
+                });
+                this.dialog_right_list = [];
+                this.dialog_list = [];
+                miniApi.list(this.params).then(res => {
+                    this.convert_tree(res);
+                    this.table_data = res;
+                    console.log(res)
+                    this.classes = res;
+                    loading.close();
+                    this.params = {};
+                })
+            },
+
+            handel_node_click(item) {
+                this.dialog_dto = item;
+                let type = this.get_type(item);
+                this.dialog_right_list = [];
+                switch (type) {
+                    case 'class':
+                        this.dialog_list = class_dialog_list;
+                        break;
+                    case 'type':
+                        item.result.map(m => m.resultName = m.resultName.replace(/\\n/g,"\n"));
+                        miniApi.class_list().then(res => {
+                            let select = res.map(m => {
+                                return {
+                                    label: m.className,
+                                    value: m.id
+                                }
+                            });
+
+                            this.dialog_list = type_dialog_list;
+
+                            console.log(this.dialog_list)
+
+                            this.dialog_list.find(f => f.type = 'select').select = select;
+
+                            this.dialog_right_list = item.result;
+
+
+                        });
+
+                        break;
+                    case 'question':
+                        this.dialog_list = question_dialog_list;
+                        break;
+                    case 'option':
+                        this.dialog_list = option_dialog_list;
+                        break;
+                    case 'result':
+                        break;
+                    default:
+                        break;
+                }
+            },
+            convert_tree(list) {
+                list.forEach(f => {
+
+                    if (f.className && f.typeName) {
+                        f.name = f.typeName;
+                    } else if (f.questionName) {
+                        f.name = f.questionName;
+                    } else if (f.optionName) {
+                        f.name = f.optionName;
+                    } else {
+                        f.name = f.className;
+                    }
+
+                    if (f.type || f.question || f.option) {
+                        f.children = f.type || f.question || f.option;
+                        this.convert_tree(f.type || f.question || f.option)
+                    }
+                })
+            },
+            // order_by_real_amount(){
+            //     this.params.realAmount = "true";
+            //     this.handel_search();
+            // },
+            // order_by_false_amount(){
+            //     this.params.amount = "true";
+            //     this.handel_search();
+            // },
+            // order_by_update_date(){
+            //     this.params.updateDate = "true";
+            //     this.handel_search();
+            // },
+            orderSelect(val){
+                this.params.order = val;
+                this.handel_search();
+            },
+            handel_dialog_cancel(item) {
+
+            },
+            get_type(item) {
+                if ('className' in item && 'typeName' in item) {
+                    return 'type';
+                } else if ('questionName' in item) {
+                    return 'question';
+                } else if ('optionName' in item) {
+                    return 'option';
+                } else if ('resultName' in item) {
+                    return 'result';
+                } else {
+                    return 'class';
+                }
+            },
+            handel_type(){
+
+            },
+            handel_dialog_conform(item) {
+                console.log(item)
+
+                this.$confirm('此操作将修改数据, 是否继续?', '提示', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    type: 'warning'
+                }).then(() => {
+                    let type = this.get_type(item);
+                    switch (type) {
+                        case 'class':
+                            item.id = item.classId;
+                            miniApi.class_update(item).then(this.call_back);
+                            break;
+                        case 'type':
+                            // item.updateDate = item.updateDate.replace(/-/g,'');
+
+                            miniApi.type_update(item).then(this.call_back);
+                            break;
+                        case 'question':
+                            miniApi.question_update(item).then(this.call_back);
+                            break;
+                        case 'option':
+                            miniApi.option_update(item).then(this.call_back);
+                            break;
+                        case 'result':
+                            miniApi.result_update(item).then(this.call_back);
+                            break;
+                        default:
+                            break;
+                    }
+                }).catch(() => {
+                    this.$message({
+                        type: 'info',
+                        message: '已取消'
+                    });
+                });
+            },
+            call_back(res) {
+                // this.handel_search();
+                this.$message({
+                    type: 'success',
+                    message: '修改成功!'
+                });
+            },
+            file_uploader(params) {
+                let formData = new FormData();
+                // 向 formData 对象中添加文件
+                formData.append('file', params.file);
+                miniApi.upload_excel(formData).then(res => {
+                    this.handel_search();
+                })
+            },
+            file_verified(params) {
+                let file_name = params.name;
+                let ext = file_name.substr(file_name.lastIndexOf('.') + 1, file_name.length - 1);
+                return ext === 'xls' || ext === 'xlsx';
+            },
+        }
+    }
+</script>
+
+<style lang="less" scoped>
+    .test2 {
+        position: relative;
+        padding: 4px 8px;
+        height: 100%;
+        background-color: #eee;
+        overflow: hidden;
+
+        .test2-wrapper {
+            height: 91%;
+            background-color: #fff;
+            border-radius: 4px;
+
+            .header {
+                margin: 0 0 10px;
+                padding: 10px;
+                display: flex;
+                justify-content: flex-start;
+                /deep/ .el-button {
+                    margin-right: 10px;
+                }
+            }
+
+            .data-wrapper {
+                display: flex;
+                justify-content: flex-start;
+                background-color: #fff;
+
+                padding: 4px;
+                height: 100%;
+                .left {
+                    overflow: auto;
+                    width: 33%;
+                }
+
+                /deep/ .el-form-item {
+
+                    width: 80%;
+                }
+                .content {
+
+                    width: 100%;
+
+                }
+                .footer {
+                    .footer-wrapper {
+                        display: flex;
+                        justify-content: space-around;
+                    }
+                }
+                .center {
+                    width: 40%;
+
+                    overflow: auto;
+
+                }
+                .right {
+                    overflow: auto;
+                    width: 26%;
+                }
+            }
+        }
+
+    }
+</style>

+ 667 - 0
src/views/vip/vipList.vue

@@ -0,0 +1,667 @@
+<template>
+  <div class="vipList">
+    <div class="head">
+      <div class="text headrow">
+        <el-input placeholder="请输入内容" v-model="params.uid" clearable>
+          <template slot="prepend">用户UID</template>
+        </el-input>
+
+        <el-input placeholder="请输入内容" v-model="params.loginName" clearable>
+          <template slot="prepend">用户账号</template>
+        </el-input>
+
+        <div class="range headrow">
+          <el-input placeholder="累充金额" v-model="params.payStartRange" clearable />-
+          <el-input placeholder="累充金额" v-model="params.payEndRange" clearable />
+        </div>
+
+        <el-select v-model="params.cpGameId" placeholder="请选择CP游戏" filterable clearable>
+          <el-option
+            v-for="item in cpGameList"
+            :key="item.cpGameId"
+            :label="item.cpGameId + '_' +item.cpGameName"
+            :value="item.cpGameId"
+          ></el-option>
+        </el-select>
+      </div>
+
+      <div class="select headrow">
+        <el-select v-model="params.lossWarning" placeholder="流失预警" clearable>
+          <el-option
+            v-for="item in warningOptions"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value"
+          ></el-option>
+        </el-select>
+
+        <el-select v-model="params.payStatus" placeholder="充值状态" filterable clearable>
+          <el-option
+            v-for="item in warningOptions"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value"
+          ></el-option>
+        </el-select>
+
+        <el-select v-model="params.userLossStatus" placeholder="用户流失状态" filterable clearable>
+          <el-option
+            v-for="item in lossOptions"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value"
+          ></el-option>
+        </el-select>
+
+        <el-select
+          v-model="params.logSysId"
+          placeholder="负责人"
+          filterable
+          clearable
+          v-if="userId == '10000'"
+        >
+          <el-option
+            v-for="item in sysUserList"
+            :key="item.userId"
+            :label="item.loginName+'_'+item.userName"
+            :value="item.userId"
+          ></el-option>
+        </el-select>
+      </div>
+
+      <div class="interval headrow">
+        <el-date-picker
+          v-model="logTime"
+          @change="handelLogTimeChange"
+          type="datetimerange"
+          :value-format="'yyyy-MM-dd HH:mm:ss'"
+          start-placeholder="录入日期"
+          end-placeholder="录入日期"
+          :default-time="['00:00:00', '23:59:59']"
+        ></el-date-picker>
+
+        <el-date-picker
+          v-model="payTime"
+          @change="handelPayTimeChange"
+          type="datetimerange"
+          :value-format="'yyyy-MM-dd HH:mm:ss'"
+          start-placeholder="充值日期"
+          end-placeholder="充值日期"
+          :default-time="['00:00:00', '23:59:59']"
+        ></el-date-picker>
+
+        <el-date-picker
+          v-model="loginTime"
+          @change="handelLoginTimeChange"
+          type="datetimerange"
+          :value-format="'yyyy-MM-dd HH:mm:ss'"
+          start-placeholder="登陆日期"
+          end-placeholder="登陆日期"
+          :default-time="['00:00:00', '23:59:59']"
+        ></el-date-picker>
+      </div>
+
+      <div class="action">
+        <el-button plain type="primary" icon="el-icon-search" @click="getVipList">搜索</el-button>
+        <el-button
+          plain
+          type="success"
+          icon="el-icon-circle-plus-outline"
+          @click="handelOpenDialog"
+        >新增</el-button>
+        <el-button plain type="danger" icon="el-icon-coin">导出</el-button>
+      </div>
+    </div>
+
+    <div class="list">
+      <el-table
+        :data="vipList.slice((curPage-1)*pageSize,curPage*pageSize)"
+        border
+        stripe
+        :fit="false"
+        height="100%"
+      >
+        <el-table-column label="序号" type="index" width="80" show-overflow-tooltip />
+        <el-table-column label="用户UID" prop="uid" width="150" show-overflow-tooltip />
+        <el-table-column label="账号" prop="loginName" width="150" show-overflow-tooltip />
+        <el-table-column label="CP原游戏名" prop="cpGameName" width="150" show-overflow-tooltip />
+        <el-table-column label="区服" prop="serverName" width="150" show-overflow-tooltip />
+        <el-table-column label="角色名" prop="roleName" width="150" show-overflow-tooltip />
+        <el-table-column
+          label="平台币余额"
+          prop="jqCurrency"
+          width="100"
+          show-overflow-tooltip
+          :formatter="formatNum"
+        />
+        <el-table-column
+          label="赠币余额"
+          prop="jqGiftCurrency"
+          width="100"
+          show-overflow-tooltip
+          :formatter="formatNum"
+        />
+        <el-table-column
+          label="累计赠币"
+          prop="sendCoinTotal"
+          width="100"
+          show-overflow-tooltip
+          :formatter="formatNum"
+        />
+        <el-table-column
+          label="累充平台币"
+          prop="coinTotal"
+          width="100"
+          show-overflow-tooltip
+          :formatter="formatNum"
+        />
+        <el-table-column
+          label="当日币充值"
+          prop="dayCoinTotal"
+          width="100"
+          show-overflow-tooltip
+          :formatter="formatNum"
+        />
+        <el-table-column
+          label="周平台币累充"
+          prop="weekCoinTotal"
+          width="100"
+          show-overflow-tooltip
+          :formatter="formatNum"
+        />
+        <el-table-column
+          label="维护平台币累充"
+          prop="maintainCoinTotal"
+          width="120"
+          show-overflow-tooltip
+          :formatter="formatNum"
+        />
+        <el-table-column
+          label="历史累充平台币"
+          prop="historyCoinTotal"
+          width="120"
+          show-overflow-tooltip
+          :formatter="formatNum"
+        />
+        <el-table-column
+          label="当日渠道充值"
+          prop="dayChannelPayTotal"
+          width="100"
+          show-overflow-tooltip
+          :formatter="formatNum"
+        />
+        <el-table-column
+          label="当日维护充值"
+          prop="allDayVipTotal"
+          width="100"
+          show-overflow-tooltip
+          :formatter="formatNum"
+        />
+        <el-table-column
+          label="平台币支付"
+          prop="coinPay"
+          width="100"
+          show-overflow-tooltip
+          :formatter="formatNum"
+        />
+        <el-table-column
+          label="渠道周累充"
+          prop="weekChannelPayTotal"
+          width="100"
+          show-overflow-tooltip
+          :formatter="formatNum"
+        />
+        <el-table-column
+          label="维护周累充"
+          prop="weekVipPayTotal"
+          width="100"
+          show-overflow-tooltip
+          :formatter="formatNum"
+        />
+        <el-table-column
+          label="维护累充"
+          prop="vipPayTotal"
+          width="150"
+          show-overflow-tooltip
+          :formatter="formatNum"
+        />
+        <el-table-column
+          label="历史累充"
+          prop="allPayTotal"
+          width="150"
+          show-overflow-tooltip
+          :formatter="formatNum"
+        />
+        <el-table-column label="录入时间" prop="logTime" width="150" show-overflow-tooltip />
+        <el-table-column label="最近一次登录时间" prop="lastLoginTime" width="150" show-overflow-tooltip />
+        <el-table-column label="最后一次支付时间" prop="lastPayTime" width="150" show-overflow-tooltip />
+
+        <el-table-column label="流失预警" prop="userLossStatus" width="150" show-overflow-tooltip>
+          <template slot-scope="scope">
+            <el-tag
+              :type="tagType(scope.row.userLossStatus)"
+            >{{tagWarningText(scope.row.userLossStatus)}}</el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="用户支付状态" prop="payStatus" width="150" show-overflow-tooltip>
+          <template slot-scope="scope">
+            <el-tag :type="tagType(scope.row.payStatus)">{{tagPayText(scope.row.payStatus)}}</el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="用户登录状态" prop="userLossStatus" width="150" show-overflow-tooltip>
+          <template slot-scope="scope">
+            <el-tag
+              :type="tagType(scope.row.userLossStatus)"
+            >{{tagStatusText(scope.row.userLossStatus)}}</el-tag>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="负责人" prop="userName" width="150" show-overflow-tooltip />
+
+        <el-table-column label="操作" width="150" fixed="right">
+          <template slot-scope="scope">
+            <div class="headrow">
+              <el-button size="mini" @click="handelUpdate(scope.row.id)">编辑</el-button>
+              <el-button size="mini" type="danger" @click="handelDelete(scope.row.id)">删除</el-button>
+            </div>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+
+    <div class="page">
+      <el-pagination
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+        layout="total, sizes, prev, pager, next, jumper"
+        :page-size="pageSize"
+        :current-page="curPage"
+        :pager-count="11"
+        :total="total"
+      ></el-pagination>
+    </div>
+
+    <el-dialog
+      :title="dialogTitle"
+      :visible.sync="dialogVisible"
+      center
+      width="500px"
+      :rules="rules"
+      ref="ruleForm"
+    >
+      <div class="content">
+        <el-form
+          label-width="100px"
+          label-position="left"
+          style="width:400px;"
+          class="demo-ruleForm"
+          :model="addModel"
+          :rules="rules"
+          ref="ruleForm"
+        >
+          <el-form-item label="UID" prop="uid">
+            <el-input v-model="addModel.uid" :disabled="disabled"></el-input>
+          </el-form-item>
+          <el-form-item label="CP游戏原名称" prop="cpGameId">
+            <el-select
+              v-model="addModel.cpGameId"
+              placeholder="请选择CP游戏"
+              filterable
+              clearable
+              style="width:100%;"
+            >
+              <el-option
+                v-for="item in cpGameList"
+                :key="item.cpGameId"
+                :label="item.cpGameId + '_' +item.cpGameName"
+                :value="item.cpGameId"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="区服" prop="serverName">
+            <el-input v-model="addModel.serverName"></el-input>
+          </el-form-item>
+          <el-form-item label="角色名" prop="roleName">
+            <el-input v-model="addModel.roleName"></el-input>
+          </el-form-item>
+          <el-form-item label="称呼" prop="realName">
+            <el-input v-model="addModel.realName"></el-input>
+          </el-form-item>
+          <el-form-item label="生日" prop="birthday">
+            <el-date-picker
+              v-model="addModel.birthday"
+              type="date"
+              :value-format="'yyyy-MM-dd'"
+              style="width:100%"
+              placeholder="选择日期"
+            ></el-date-picker>
+          </el-form-item>
+          <el-form-item label="手机号" prop="phone">
+            <el-input v-model="addModel.phone"></el-input>
+          </el-form-item>
+          <el-form-item label="微信号" prop="wxNum">
+            <el-input v-model="addModel.wxNum"></el-input>
+          </el-form-item>
+          <el-form-item label="QQ号" prop="qqNum">
+            <el-input v-model="addModel.qqNum"></el-input>
+          </el-form-item>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="handelAddVip">确 定</el-button>
+        <el-button @click="handelCancel">取 消</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import vipApi from "@/api/sysVip";
+import { getCookie, getLastDay, formatTime } from "@/utils/util";
+import { truncate } from "fs";
+
+export default {
+  name: "vipList",
+  data() {
+    return {
+      dialogTitle: "",
+      disabled: false,
+      rules: {
+        uid: [{ required: true, message: "请输入UID", trigger: "blur" }],
+        serverName: [
+          { required: true, message: "请输入区服名称", trigger: "blur" }
+        ],
+        roleName: [
+          { required: true, message: "请输入角色名称", trigger: "blur" }
+        ]
+      },
+      addModel: {},
+      userId: "",
+      vipList: [],
+      total: 0,
+      pageSize: 20,
+      curPage: 1,
+      params: {},
+      warningOptions: [
+        {
+          label: "3天未登录",
+          value: 3
+        },
+        {
+          label: "5天未登录",
+          value: 5
+        },
+        {
+          label: "7天未登录",
+          value: 7
+        }
+      ],
+      lossOptions: [
+        {
+          label: "活跃",
+          value: 1
+        },
+        {
+          label: "疑似流失",
+          value: 2
+        },
+        {
+          label: "已流失",
+          value: 3
+        }
+      ],
+      cpGameList: [],
+      sysUserList: [],
+      logTime: "",
+      payTime: "",
+      loginTime: "",
+      dialogVisible: false
+    };
+  },
+  created() {
+    this.init();
+    this.getVipList();
+  },
+  methods: {
+    init() {
+      this.userId = getCookie("user_id");
+      let lastDay = getLastDay(7);
+      this.logTime = lastDay;
+      this.params.logStartTime = lastDay ? formatTime(lastDay[0]) : null;
+      this.params.logEndTime = lastDay ? formatTime(lastDay[1]) : null;
+      this.getSelectOptions();
+    },
+    getVipList() {
+      if (this.userId != "10000") {
+        this.params.logSysId = this.userId;
+      }
+      vipApi.getVipList(this.params).then(res => {
+        this.$log.debug(res);
+        this.total = res.length;
+        this.vipList = res;
+      });
+    },
+
+    getSelectOptions() {
+      vipApi.getSelectOptions().then(res => {
+        this.$log.debug(res);
+        this.cpGameList = res.cpGame;
+        this.sysUserList = res.sysUser;
+      });
+    },
+
+    formatNum(row, column, cellValue, index) {
+      return cellValue ? cellValue : 0;
+    },
+
+    tagType(val) {
+      if (val < 1) {
+        return "success";
+      } else if (val < 3) {
+        return "warning";
+      } else {
+        return "danger";
+      }
+    },
+    tagWarningText(val) {
+      if (val < 1) {
+        return "活跃";
+      } else {
+        return val + "天未登录";
+      }
+    },
+    tagPayText(val) {
+      if (val < 1) {
+        return "活跃";
+      } else {
+        return val + "天未充值";
+      }
+    },
+    tagStatusText(val) {
+      if (val < 1) {
+        return "活跃";
+      } else if (val < 3) {
+        return "疑似流失";
+      } else {
+        return "已流失";
+      }
+    },
+
+    handleSizeChange(val) {
+      this.pageSize = val;
+    },
+    handleCurrentChange(val) {
+      this.curPage = val;
+    },
+    handelLogTimeChange(val) {
+      this.params.logStartTime = val ? val[0] : null;
+      this.params.logEndTime = val ? val[1] : null;
+      this.$log.debug(this.params);
+    },
+    handelPayTimeChange(val) {
+      this.params.payStartTime = val ? val[0] : null;
+      this.params.payEndTime = val ? val[1] : null;
+      this.$log.debug(this.params);
+    },
+    handelLoginTimeChange(val) {
+      this.params.loginStartTime = val ? val[0] : null;
+      this.params.loginEndTime = val ? val[1] : null;
+      this.$log.debug(this.params);
+    },
+    handelAddVip() {
+      if (this.disabled) {
+        vipApi.updateVip(this.addModel).then(res => {
+          this.dialogVisible = false;
+          this.$refs["ruleForm"].resetFields();
+          this.getVipList();
+          this.disabled = false;
+          this.$message({
+            type: "success",
+            message: "修改成功!"
+          });
+        });
+      } else {
+        this.addModel.logSysId = this.userId;
+        vipApi.addVip(this.addModel).then(res => {
+          this.dialogVisible = false;
+          this.$refs["ruleForm"].resetFields();
+          this.getVipList();
+          this.disabled = false;
+          this.$message({
+            type: "success",
+            message: "添加成功!"
+          });
+        });
+      }
+    },
+    handelOpenDialog() {
+      this.dialogTitle = "新增VIP用户";
+      this.dialogVisible = true;
+    },
+    handelDelete(id) {
+      if (id) {
+        let dto = {};
+        dto.id = id;
+        dto.isDelete = 0;
+        this.$confirm("此操作将永久该数据, 是否继续?", "提示", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        })
+          .then(() => {
+            vipApi.updateVip(dto).then(res => {
+              this.$message({
+                type: "success",
+                message: "删除成功!"
+              });
+              this.getVipList();
+            });
+          })
+          .catch(() => {
+            this.$message({
+              type: "info",
+              message: "已取消删除"
+            });
+          });
+      }
+    },
+    handelUpdate(id) {
+      vipApi.getById(id).then(res => {
+        if (res) {
+          this.addModel = res;
+          this.dialogTitle = "编辑VIP用户";
+          this.disabled = true;
+          this.dialogVisible = true;
+        }
+      });
+    },
+    handelCancel() {
+      this.disabled = false;
+      this.addModel = {};
+      this.$refs["ruleForm"].resetFields();
+      this.dialogVisible = false;
+    }
+    // handleCheckedFieldChange(val) {
+    //   this.$log.debug(val)
+    //   let checkedCount = val.length
+    //   this.checkAll = checkedCount === this.fieldList.length
+    //   this.isIndeterminate = checkedCount > 0 && checkedCount < this.fieldList.length
+    // },
+    // handleCheckAllChange(val) {
+    //   this.$log.debug(val)
+    //   this.checkedFieldList = val
+    //     ? this.fieldList.map(obj => {
+    //         return obj.javaField
+    //       })
+    //     : []
+    //   this.isIndeterminate = false
+    // },
+    // handelExcelExport() {
+    //   if (JSON.stringify(this.params) === '{}') {
+    //     this.$message({ message: '查询条件不能为空', type: 'warning' })
+    //     return
+    //   }
+    //   let map = {}
+    //   map.vo = this.fieldList.filter(f => this.checkedFieldList.indexOf(f.javaField) != -1)
+    //   map.dto = this.params
+    //   this.$log.debug(map)
+    //   orderApi.getExcel(map).then(body=> {
+    //     this.$log.debug(body)
+    //     let a = document.createElement('a')
+    //     a.href = `${orderApi.baseUrl}/v1/excel/${body}`
+    //     a.click();
+    //   })
+    //   this.dialogVisible = false;
+    // },
+    // handelChannelChange(val) {
+    //   this.params.channelId = val.join(",")
+    // }
+  }
+};
+</script>
+
+<style lang="less" scoped>
+.vipList {
+  height: 100%;
+  width: 100%;
+  overflow: hidden;
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  .head {
+    margin: 4px;
+    .text {
+      .el-input {
+        margin: 4px;
+        width: 25%;
+      }
+      .range {
+        margin: 4px;
+        width: 25%;
+        .el-input {
+          width: 45%;
+        }
+      }
+      .el-select {
+        margin: 4px;
+        width: 25%;
+      }
+    }
+    .select {
+      .el-select {
+        margin: 4px;
+        width: 25%;
+      }
+    }
+    .interval {
+      .el-range-editor {
+        margin: 4px;
+        width: 33%;
+      }
+    }
+    .action {
+      margin: 4px;
+    }
+  }
+}
+</style>

Разлика између датотеке није приказан због своје велике величине
+ 1 - 0
test.css


+ 82 - 0
vue.config.js

@@ -0,0 +1,82 @@
+const path = require('path')
+const webpack = require('webpack')
+// const GenerateAssetPlugin = require('generate-asset-webpack-plugin')
+
+function resolve(dir) {
+  return path.join(__dirname, dir)
+}
+
+// var createServerConfig = function(compilation) {
+//   const configJson = {
+//     apiUrl: 'http://localhost:8090'
+//   }
+//   return JSON.stringify(configJson)
+// }
+
+// vue.config.js
+module.exports = {
+
+  publicPath: '/',
+  outputDir: 'dist',
+  assetsDir: 'static_vue',
+
+  configureWebpack: {
+    plugins: [
+      new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
+      // new GenerateAssetPlugin({
+      //   filename: 'config.json',
+      //   fn: (compilation, cb) => {
+      //     cb(null, createServerConfig(compilation))
+      //   },
+      //   extraFiles: []
+      // })
+    ]
+  },
+
+  chainWebpack: (config) => {
+    config.resolve.alias
+      .set('@$', resolve('src'))
+      .set('@api', resolve('src/api'))
+      .set('@assets', resolve('src/assets'))
+      .set('@comp', resolve('src/components'))
+      .set('@views', resolve('src/views'))
+      .set('@layout', resolve('src/layout'))
+      .set('@static', resolve('src/static'))
+
+    const svgRule = config.module.rule('svg')
+    svgRule.uses.clear()
+    svgRule
+      .oneOf('inline')
+      .resourceQuery(/inline/)
+      .use('vue-svg-icon-loader')
+      .loader('vue-svg-icon-loader')
+      .end()
+      .end()
+      .oneOf('external')
+      .use('file-loader')
+      .loader('file-loader')
+      .options({
+        name: 'assets/[name].[hash:8].[ext]'
+      })
+  },
+
+  css: {
+    loaderOptions: {
+      less: {
+        modifyVars: {
+          /*
+          'primary-color': '#F5222D',
+          'link-color': '#F5222D',
+          'border-radius-base': '4px',
+          */
+        },
+        javascriptEnabled: true
+      }
+    }
+  },
+
+  lintOnSave: undefined,
+  // babel-loader no-ignore node_modules/*
+  transpileDependencies: [],
+  productionSourceMap: false
+}