Jelajahi Sumber

修改账户报表展示以及提交创意创建

zhuxinbo 5 tahun lalu
induk
melakukan
c44aa3c50a

+ 123 - 122
package.json

@@ -1,126 +1,127 @@
 {
-    "name": "ant-design-vue-jeecg",
-    "version": "2.0.2",
-    "private": true,
-    "scripts": {
-      "serve": "vue-cli-service serve --open",
-      "build": "vue-cli-service build",
-      "lint": "vue-cli-service lint",
-      "test:unit": "vue-cli-service test:unit",
-      "test:e2e": "vue-cli-service test:e2e"
+  "name": "ant-design-vue-jeecg",
+  "version": "2.0.2",
+  "private": true,
+  "scripts": {
+    "serve": "vue-cli-service serve --open",
+    "build": "vue-cli-service build",
+    "lint": "vue-cli-service lint",
+    "test:unit": "vue-cli-service test:unit",
+    "test:e2e": "vue-cli-service test:e2e"
+  },
+  "dependencies": {
+    "@antv/data-set": "^0.10.2",
+    "@femessage/upload-to-ali": "^1.8.1",
+    "@riophae/vue-treeselect": "^0.4.0",
+    "@tinymce/tinymce-vue": "^2.0.0",
+    "ali-oss": "^6.1.1",
+    "ant-design-vue": "^1.3.9",
+    "apexcharts": "^3.6.5",
+    "axios": "^0.18.0",
+    "babel-loader": "^8.0.6",
+    "blueimp-md5": "^2.11.0",
+    "browser-md5-file": "^1.1.1",
+    "clipboard": "^2.0.4",
+    "codemirror": "^5.46.0",
+    "dayjs": "^1.8.0",
+    "echarts": "^4.3.0",
+    "enquire.js": "^2.1.6",
+    "html2canvas": "^1.0.0-rc.3",
+    "iview": "2.0.0-rc.17",
+    "jquery": "^3.4.1",
+    "js-cookie": "^2.2.0",
+    "lodash.get": "^4.4.2",
+    "lodash.pick": "^4.4.0",
+    "mcanvas": "^1.3.9",
+    "md5": "^2.2.1",
+    "nprogress": "^0.2.0",
+    "promise.prototype.finally": "^3.1.1",
+    "tinymce": "^5.0.2",
+    "viser-vue": "^2.4.4",
+    "vue": "^2.6.10",
+    "vue-apexcharts": "^1.3.2",
+    "vue-class-component": "^6.0.0",
+    "vue-count-to": "^1.0.13",
+    "vue-cropper": "^0.4.8",
+    "vue-i18n": "^8.7.0",
+    "vue-layer": "^1.0.2",
+    "vue-loader": "^15.7.0",
+    "vue-ls": "^3.2.0",
+    "vue-oss-uploader": "^0.1.10",
+    "vue-photo-preview": "^1.1.3",
+    "vue-preview": "^1.1.3",
+    "vue-print-nb-jeecg": "^1.0.8",
+    "vue-property-decorator": "^7.3.0",
+    "vue-router": "^3.0.1",
+    "vue-splitpane": "^1.0.4",
+    "vue-video-player": "^5.0.2",
+    "vue-waterfall-easy": "^2.4.3",
+    "vuedraggable": "^2.20.0",
+    "vuex": "^3.0.1",
+    "vuex-class": "^0.3.1"
+  },
+  "devDependencies": {
+    "@babel/polyfill": "^7.2.5",
+    "@vue/cli-plugin-babel": "^3.3.0",
+    "@vue/cli-plugin-eslint": "^3.3.0",
+    "@vue/cli-service": "^3.3.0",
+    "@vue/eslint-config-standard": "^4.0.0",
+    "babel-eslint": "^10.0.1",
+    "eslint": "^5.16.0",
+    "eslint-plugin-vue": "^5.1.0",
+    "html-webpack-plugin": "^3.2.0",
+    "less": "^3.9.0",
+    "less-loader": "^4.1.0",
+    "node-sass": "^4.11.0",
+    "sass-loader": "^7.0.1",
+    "vue-template-compiler": "^2.6.10"
+  },
+  "eslintConfig": {
+    "root": true,
+    "env": {
+      "node": true
     },
-    "dependencies": {
-      "@antv/data-set": "^0.10.2",
-      "@femessage/upload-to-ali": "^1.8.1",
-      "@tinymce/tinymce-vue": "^2.0.0",
-      "ali-oss": "^6.1.1",
-      "ant-design-vue": "^1.3.9",
-      "apexcharts": "^3.6.5",
-      "axios": "^0.18.0",
-      "babel-loader": "^8.0.6",
-      "blueimp-md5": "^2.11.0",
-      "browser-md5-file": "^1.1.1",
-      "clipboard": "^2.0.4",
-      "codemirror": "^5.46.0",
-      "dayjs": "^1.8.0",
-      "echarts": "^4.3.0",
-      "enquire.js": "^2.1.6",
-      "html2canvas": "^1.0.0-rc.3",
-      "iview": "2.0.0-rc.17",
-      "jquery": "^3.4.1",
-      "js-cookie": "^2.2.0",
-      "lodash.get": "^4.4.2",
-      "lodash.pick": "^4.4.0",
-      "mcanvas": "^1.3.9",
-      "md5": "^2.2.1",
-      "nprogress": "^0.2.0",
-      "promise.prototype.finally": "^3.1.1",
-      "tinymce": "^5.0.2",
-      "viser-vue": "^2.4.4",
-      "vue": "^2.6.10",
-      "vue-apexcharts": "^1.3.2",
-      "vue-class-component": "^6.0.0",
-      "vue-count-to": "^1.0.13",
-      "vue-cropper": "^0.4.8",
-      "vue-i18n": "^8.7.0",
-      "vue-layer": "^1.0.2",
-      "vue-loader": "^15.7.0",
-      "vue-ls": "^3.2.0",
-      "vue-oss-uploader": "^0.1.10",
-      "vue-photo-preview": "^1.1.3",
-      "vue-preview": "^1.1.3",
-      "vue-print-nb-jeecg": "^1.0.8",
-      "vue-property-decorator": "^7.3.0",
-      "vue-router": "^3.0.1",
-      "vue-splitpane": "^1.0.4",
-      "vue-video-player": "^5.0.2",
-      "vue-waterfall-easy": "^2.4.3",
-      "vuedraggable": "^2.20.0",
-      "vuex": "^3.0.1",
-      "vuex-class": "^0.3.1"
+    "extends": [
+      "plugin:vue/strongly-recommended",
+      "eslint:recommended"
+    ],
+    "parserOptions": {
+      "parser": "babel-eslint"
     },
-    "devDependencies": {
-      "@babel/polyfill": "^7.2.5",
-      "@vue/cli-plugin-babel": "^3.3.0",
-      "@vue/cli-plugin-eslint": "^3.3.0",
-      "@vue/cli-service": "^3.3.0",
-      "@vue/eslint-config-standard": "^4.0.0",
-      "babel-eslint": "^10.0.1",
-      "eslint": "^5.16.0",
-      "eslint-plugin-vue": "^5.1.0",
-      "html-webpack-plugin": "^3.2.0",
-      "less": "^3.9.0",
-      "less-loader": "^4.1.0",
-      "node-sass": "^4.11.0",
-      "sass-loader": "^7.0.1",
-      "vue-template-compiler": "^2.6.10"
-    },
-    "eslintConfig": {
-      "root": true,
-      "env": {
-        "node": true
-      },
-      "extends": [
-        "plugin:vue/strongly-recommended",
-        "eslint:recommended"
-      ],
-      "parserOptions": {
-        "parser": "babel-eslint"
-      },
-      "rules": {
-        "generator-star-spacing": "off",
-        "no-mixed-operators": 0,
-        "vue/max-attributes-per-line": [
-          2,
-          {
-            "singleline": 5,
-            "multiline": {
-              "max": 1,
-              "allowFirstLine": false
-            }
+    "rules": {
+      "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
-      }
-    },
-    "postcss": {
-      "plugins": {
-        "autoprefixer": {}
-      }
-    },
-    "browserslist": [
-      "> 1%",
-      "last 2 versions",
-      "not ie <= 8"
-    ]
-  }
+        }
+      ],
+      "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
+    }
+  },
+  "postcss": {
+    "plugins": {
+      "autoprefixer": {}
+    }
+  },
+  "browserslist": [
+    "> 1%",
+    "last 2 versions",
+    "not ie <= 8"
+  ]
+}

+ 104 - 104
src/components/jeecg/JEditor.vue

@@ -1,105 +1,105 @@
-<template>
-  <div class="tinymce-editor">
-    <editor
-      v-model="myValue"
-      :init="init"
-      :disabled="disabled"
-      @onClick="onClick">
-    </editor>
-  </div>
-</template>
-
-<script>
-  import tinymce from 'tinymce/tinymce'
-  import Editor from '@tinymce/tinymce-vue'
-  import 'tinymce/themes/silver/theme'
-  import 'tinymce/plugins/image'
-  import 'tinymce/plugins/media'
-  import 'tinymce/plugins/table'
-  import 'tinymce/plugins/lists'
-  import 'tinymce/plugins/contextmenu'
-  import 'tinymce/plugins/wordcount'
-  import 'tinymce/plugins/colorpicker'
-  import 'tinymce/plugins/textcolor'
-  import 'tinymce/plugins/fullscreen'
-
-  export default {
-    components: {
-      Editor
-    },
-    props: {
-      value: {
-        type: String,
-        required: false
-      },
-      triggerChange: {
-        type: Boolean,
-        default: false,
-        required: false
-      },
-      disabled: {
-        type: Boolean,
-        default: false
-      },
-      plugins: {
-        type: [String, Array],
-        default: 'lists image media table textcolor wordcount contextmenu fullscreen'
-      },
-      toolbar: {
-        type: [String, Array],
-        default: 'undo redo |  formatselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | lists image media table | removeformat | fullscreen'
-      }
-    },
-    data() {
-      return {
-        //初始化配置
-        init: {
-          language_url: '/tinymce/langs/zh_CN.js',
-          language: 'zh_CN',
-          skin_url: '/tinymce/skins/lightgray',
-          height: 300,
-          plugins: this.plugins,
-          toolbar: this.toolbar,
-          branding: false,
-          menubar: false,
-          images_upload_handler: (blobInfo, success) => {
-            const img = 'data:image/jpeg;base64,' + blobInfo.base64()
-            success(img)
-          }
-        },
-        myValue: this.value
-      }
-    },
-    mounted() {
-      tinymce.init({})
-    },
-    methods: {
-
-      onClick(e) {
-        this.$emit('onClick', e, tinymce)
-      },
-      //可以添加一些自己的自定义事件,如清空内容
-      clear() {
-        this.myValue = ''
-      }
-    },
-    watch: {
-      value(newValue) {
-        this.myValue = newValue
-      },
-      myValue(newValue) {
-        console.log(newValue)
-        if (this.triggerChange) {
-          console.log(1)
-          this.$emit('change', newValue)
-        } else {
-          console.log(2)
-          this.$emit('input', newValue)
-        }
-      }
-    }
-  }
-
-</script>
-<style scoped>
+<template>
+  <div class="tinymce-editor">
+    <editor
+      v-model="myValue"
+      :init="init"
+      :disabled="disabled"
+      @onClick="onClick">
+    </editor>
+  </div>
+</template>
+
+<script>
+  import tinymce from 'tinymce/tinymce'
+  import Editor from '@tinymce/tinymce-vue'
+  import 'tinymce/themes/silver/theme'
+  import 'tinymce/plugins/image'
+  import 'tinymce/plugins/media'
+  import 'tinymce/plugins/table'
+  import 'tinymce/plugins/lists'
+  import 'tinymce/plugins/contextmenu'
+  import 'tinymce/plugins/wordcount'
+  import 'tinymce/plugins/colorpicker'
+  import 'tinymce/plugins/textcolor'
+  import 'tinymce/plugins/fullscreen'
+
+  export default {
+    components: {
+      Editor
+    },
+    props: {
+      value: {
+        type: String,
+        required: false
+      },
+      triggerChange: {
+        type: Boolean,
+        default: false,
+        required: false
+      },
+      disabled: {
+        type: Boolean,
+        default: false
+      },
+      plugins: {
+        type: [String, Array],
+        default: 'lists image media table textcolor wordcount contextmenu fullscreen'
+      },
+      toolbar: {
+        type: [String, Array],
+        default: 'undo redo |  formatselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | lists image media table | removeformat | fullscreen'
+      }
+    },
+    data() {
+      return {
+        //初始化配置
+        init: {
+          language_url: '/tinymce/langs/zh_CN.js',
+          language: 'zh_CN',
+          skin_url: '/tinymce/skins/lightgray',
+          height: 300,
+          plugins: this.plugins,
+          toolbar: this.toolbar,
+          branding: false,
+          menubar: false,
+          images_upload_handler: (blobInfo, success) => {
+            const img = 'data:image/jpeg;base64,' + blobInfo.base64()
+            success(img)
+          }
+        },
+        myValue: this.value
+      }
+    },
+    mounted() {
+      tinymce.init({})
+    },
+    methods: {
+
+      onClick(e) {
+        this.$emit('onClick', e, tinymce)
+      },
+      //可以添加一些自己的自定义事件,如清空内容
+      clear() {
+        this.myValue = ''
+      }
+    },
+    watch: {
+      value(newValue) {
+        this.myValue = newValue
+      },
+      myValue(newValue) {
+        console.log(newValue)
+        if (this.triggerChange) {
+          console.log(1)
+          this.$emit('change', newValue)
+        } else {
+          console.log(2)
+          this.$emit('input', newValue)
+        }
+      }
+    }
+  }
+
+</script>
+<style scoped>
 </style>

+ 315 - 299
src/components/layouts/TabLayout.vue

@@ -1,300 +1,316 @@
-<template>
-  <global-layout @dynamicRouterShow="dynamicRouterShow">
-    <contextmenu :itemList="menuItemList" :visible.sync="menuVisible" @select="onMenuSelect"/>
-    <a-tabs
-      @contextmenu.native="e => onContextmenu(e)"
-      v-if="multipage"
-      :active-key="activePage"
-      class="tab-layout-tabs"
-      style="height:52px"
-      :hide-add="true"
-      type="editable-card"
-      @change="changePage"
-      @edit="editPage">
-      <a-tab-pane :id="page.fullPath" :key="page.fullPath" v-for="page in pageList">
-        <span slot="tab" :pagekey="page.fullPath">{{ page.meta.title }}</span>
-      </a-tab-pane>
-    </a-tabs>
-    <div style="margin: 12px 12px 0;">
-      <transition name="page-toggle">
-        <keep-alive v-if="multipage">
-          <router-view/>
-        </keep-alive>
-        <router-view v-else/>
-      </transition>
-    </div>
-  </global-layout>
-</template>
-
-<script>
-  import GlobalLayout from '@/components/page/GlobalLayout'
-  import Contextmenu from '@/components/menu/Contextmenu'
-  import {mixin, mixinDevice} from '@/utils/mixin.js'
-
-  const indexKey = '/dashboard/analysis'
-
-  export default {
-    name: 'TabLayout',
-    components: {
-      GlobalLayout,
-      Contextmenu
-    },
-    mixins: [mixin, mixinDevice],
-    data() {
-      return {
-        pageList: [],
-        linkList: [],
-        activePage: '',
-        menuVisible: false,
-        menuItemList: [
-          {key: '1', icon: 'arrow-left', text: '关闭左侧'},
-          {key: '2', icon: 'arrow-right', text: '关闭右侧'},
-          {key: '3', icon: 'close', text: '关闭其它'}
-        ]
-      }
-    },
-    computed: {
-      multipage() {
-        //判断如果是手机模式,自动切换为单页面模式
-        if (this.isMobile()) {
-          return false
-        } else {
-          return this.$store.state.app.multipage
-        }
-      }
-    },
-    created() {
-      if (this.$route.path != indexKey) {
-        this.pageList.push({
-          name: 'dashboard-analysis',
-          path: indexKey,
-          fullPath: indexKey,
-          meta: {
-            icon: 'dashboard',
-            title: '首页'
-          }
-        })
-        this.linkList.push(indexKey)
-      }
-      this.pageList.push(this.$route)
-      this.linkList.push(this.$route.fullPath)
-      this.activePage = this.$route.fullPath
-    },
-    watch: {
-      '$route': function (newRoute) {
-        this.activePage = newRoute.fullPath
-        if (!this.multipage) {
-          this.linkList = [newRoute.fullPath]
-          this.pageList = [Object.assign({}, newRoute)]
-        } else if (this.linkList.indexOf(newRoute.fullPath) < 0) {
-          this.linkList.push(newRoute.fullPath)
-          this.pageList.push(Object.assign({}, newRoute))
-        } else if (this.linkList.indexOf(newRoute.fullPath) >= 0) {
-          let oldIndex = this.linkList.indexOf(newRoute.fullPath)
-          let oldPositionRoute = this.pageList[oldIndex]
-          this.pageList.splice(oldIndex, 1, Object.assign({}, newRoute, {meta: oldPositionRoute.meta}))
-        }
-      },
-      'activePage': function (key) {
-        let index = this.linkList.lastIndexOf(key)
-        let waitRouter = this.pageList[index]
-        this.$router.push(Object.assign({}, waitRouter));
-      },
-      'multipage': function (newVal) {
-        if (!newVal) {
-          this.linkList = [this.$route.fullPath]
-          this.pageList = [this.$route]
-        }
-      }
-    },
-    methods: {
-      changePage(key) {
-        this.activePage = key
-      },
-      editPage(key, action) {
-        this[action](key)
-      },
-      remove(key) {
-        if (key == indexKey) {
-          this.$message.warning('首页不能关闭!')
-          return
-        }
-        if (this.pageList.length === 1) {
-          this.$message.warning('这是最后一页,不能再关闭了啦')
-          return
-        }
-        this.pageList = this.pageList.filter(item => item.fullPath !== key)
-        let index = this.linkList.indexOf(key)
-        this.linkList = this.linkList.filter(item => item !== key)
-        index = index >= this.linkList.length ? this.linkList.length - 1 : index
-        this.activePage = this.linkList[index]
-      },
-      onContextmenu(e) {
-        const pagekey = this.getPageKey(e.target)
-        if (pagekey !== null) {
-          e.preventDefault()
-          this.menuVisible = true
-        }
-      },
-      getPageKey(target, depth) {n
-        depth = depth || 0
-        if (depth > 2) {
-          return null
-        }
-        let pageKey = target.getAttribute('pagekey')
-        pageKey = pageKey || (target.previousElementSibling ? target.previousElementSibling.getAttribute('pagekey') : null)
-        return pageKey || (target.firstElementChild ? this.getPageKey(target.firstElementChild, ++depth) : null)
-      },
-      onMenuSelect(key, target) {
-        let pageKey = this.getPageKey(target)
-        switch (key) {
-          case '1':
-            this.closeLeft(pageKey)
-            break
-          case '2':
-            this.closeRight(pageKey)
-            break
-          case '3':
-            this.closeOthers(pageKey)
-            break
-          default:
-            break
-        }
-      },
-      closeOthers(pageKey) {
-        let index = this.linkList.indexOf(pageKey)
-        if (pageKey == indexKey) {
-          this.linkList = this.linkList.slice(index, index + 1)
-          this.pageList = this.pageList.slice(index, index + 1)
-          this.activePage = this.linkList[0]
-        } else {
-          let indexContent = this.pageList.slice(0, 1)[0]
-          this.linkList = this.linkList.slice(index, index + 1)
-          this.pageList = this.pageList.slice(index, index + 1)
-          this.linkList.unshift(indexKey)
-          this.pageList.unshift(indexContent)
-          this.activePage = this.linkList[1]
-        }
-      },
-      closeLeft(pageKey) {
-        if (pageKey == indexKey) {
-          return
-        }
-        let tempList = [...this.pageList]
-        let indexContent = tempList.slice(0, 1)[0]
-        let index = this.linkList.indexOf(pageKey)
-        this.linkList = this.linkList.slice(index)
-        this.pageList = this.pageList.slice(index)
-        this.linkList.unshift(indexKey)
-        this.pageList.unshift(indexContent)
-        if (this.linkList.indexOf(this.activePage) < 0) {
-          this.activePage = this.linkList[0]
-        }
-      },
-      closeRight(pageKey) {
-        let index = this.linkList.indexOf(pageKey)
-        this.linkList = this.linkList.slice(0, index + 1)
-        this.pageList = this.pageList.slice(0, index + 1)
-        if (this.linkList.indexOf(this.activePage < 0)) {
-          this.activePage = this.linkList[this.linkList.length - 1]
-        }
-      },
-      //update-begin-author:taoyan date:20190430 for:动态路由title显示配置的菜单title而不是其对应路由的title
-      dynamicRouterShow(key, title) {
-        let keyIndex = this.linkList.indexOf(key)
-        if (keyIndex >= 0) {
-          let currRouter = this.pageList[keyIndex]
-          let meta = Object.assign({}, currRouter.meta, {title: title})
-          this.pageList.splice(keyIndex, 1, Object.assign({}, currRouter, {meta: meta}))
-        }
-      }
-      //update-end-author:taoyan date:20190430 for:动态路由title显示配置的菜单title而不是其对应路由的title
-    }
-  }
-</script>
-
-<style lang="scss">
-
-  /*
- * The following styles are auto-applied to elements with
- * transition="page-transition" when their visibility is toggled
- * by Vue.js.
- *
- * You can easily play with the page transition by editing
- * these styles.
- */
-
-  .page-transition-enter {
-    opacity: 0;
-  }
-
-  .page-transition-leave-active {
-    opacity: 0;
-  }
-
-  .page-transition-enter .page-transition-container,
-  .page-transition-leave-active .page-transition-container {
-    -webkit-transform: scale(1.1);
-    transform: scale(1.1);
-  }
-
-  /*美化弹出Tab样式*/
-  .ant-tabs-nav-container {
-    margin-top: 4px;
-  }
-
-  /* 修改 ant-tabs 样式 */
-  .tab-layout-tabs.ant-tabs {
-    border-bottom: 1px solid #ccc;
-    border-left: 1px solid #ccc;
-    background-color: white;
-    padding: 0 20px;
-
-    .ant-tabs-bar {
-      margin: 4px 0 0;
-      border: none;
-    }
-
-  }
-
-  .ant-tabs {
-
-    &.ant-tabs-card .ant-tabs-tab {
-
-      padding: 0 24px !important;
-      background-color: white !important;
-      margin-right: 10px !important;
-
-      .ant-tabs-close-x {
-        width: 12px !important;
-        height: 12px !important;
-        opacity: 0 !important;
-        cursor: pointer !important;
-        font-size: 12px !important;
-        margin: 0 !important;
-        position: absolute;
-        top: 36%;
-        right: 6px;
-      }
-
-      &:hover .ant-tabs-close-x {
-        opacity: 1 !important;
-      }
-
-    }
-
-  }
-
-  .ant-tabs.ant-tabs-card > .ant-tabs-bar {
-    .ant-tabs-tab {
-      border: none !important;
-      border-bottom: 1px solid transparent !important;
-    }
-
-    .ant-tabs-tab-active {
-      border-color: #1890ff !important;
-    }
-  }
-
-
+<template>
+  <global-layout @dynamicRouterShow="dynamicRouterShow">
+    <contextmenu :itemList="menuItemList" :visible.sync="menuVisible" @select="onMenuSelect"/>
+    <a-tabs
+      @contextmenu.native="e => onContextmenu(e)"
+      v-if="multipage"
+      :active-key="activePage"
+      class="tab-layout-tabs"
+      style="height:52px"
+      :hide-add="true"
+      type="editable-card"
+      @change="changePage"
+      @edit="editPage">
+      <a-tab-pane :id="page.fullPath" :key="page.fullPath" v-for="page in pageList">
+        <span slot="tab" :pagekey="page.fullPath">{{ page.meta.title }}</span>
+      </a-tab-pane>
+    </a-tabs>
+    <div style="margin: 12px 12px 0;">
+      <transition name="page-toggle">
+        <keep-alive v-if="multipage">
+          <router-view/>
+        </keep-alive>
+        <router-view v-else/>
+      </transition>
+    </div>
+  </global-layout>
+</template>
+
+<script>
+  import GlobalLayout from '@/components/page/GlobalLayout'
+  import Contextmenu from '@/components/menu/Contextmenu'
+  import {mixin, mixinDevice} from '@/utils/mixin.js'
+
+  const indexKey = '/dashboard/analysis'
+
+  export default {
+    name: 'TabLayout',
+    components: {
+      GlobalLayout,
+      Contextmenu
+    },
+    mixins: [mixin, mixinDevice],
+    data() {
+      return {
+        pageList: [],
+        linkList: [],
+        activePage: '',
+        menuVisible: false,
+        menuItemList: [
+          {key: '1', icon: 'arrow-left', text: '关闭左侧'},
+          {key: '2', icon: 'arrow-right', text: '关闭右侧'},
+          {key: '3', icon: 'close', text: '关闭其它'}
+        ]
+      }
+    },
+    computed: {
+      multipage() {
+        //判断如果是手机模式,自动切换为单页面模式
+        if (this.isMobile()) {
+          return false
+        } else {
+          return this.$store.state.app.multipage
+        }
+      }
+    },
+    created() {
+      if (this.$route.path != indexKey) {
+        this.pageList.push({
+          name: 'dashboard-analysis',
+          path: indexKey,
+          fullPath: indexKey,
+          meta: {
+            icon: 'dashboard',
+            title: '首页'
+          }
+        })
+        this.linkList.push(indexKey)
+      }
+      this.pageList.push(this.$route)
+      this.linkList.push(this.$route.fullPath)
+      this.activePage = this.$route.fullPath
+
+      if(!this.linkList.includes("/account/StepForm")){
+          localStorage.removeItem("step")
+      }
+    },
+    watch: {
+      '$route': function (newRoute) {
+        this.activePage = newRoute.fullPath
+        if (!this.multipage) {
+          this.linkList = [newRoute.fullPath]
+          this.pageList = [Object.assign({}, newRoute)]
+        } else if (this.linkList.indexOf(newRoute.fullPath) < 0) {
+          this.linkList.push(newRoute.fullPath)
+          this.pageList.push(Object.assign({}, newRoute))
+        } else if (this.linkList.indexOf(newRoute.fullPath) >= 0) {
+          let oldIndex = this.linkList.indexOf(newRoute.fullPath)
+          let oldPositionRoute = this.pageList[oldIndex]
+          this.pageList.splice(oldIndex, 1, Object.assign({}, newRoute, {meta: oldPositionRoute.meta}))
+        }
+      },
+      'activePage': function (key) {
+        let index = this.linkList.lastIndexOf(key)
+        let waitRouter = this.pageList[index]
+        this.$router.push(Object.assign({}, waitRouter));
+      },
+      'multipage': function (newVal) {
+        if (!newVal) {
+          this.linkList = [this.$route.fullPath]
+          this.pageList = [this.$route]
+        }
+      }
+    },
+    methods: {
+      changePage(key) {
+        this.activePage = key
+      },
+      editPage(key, action) {
+        this[action](key)
+      },
+      remove(key) {
+        if (key == indexKey) {
+          this.$message.warning('首页不能关闭!')
+          return
+        }
+        if (this.pageList.length === 1) {
+          this.$message.warning('这是最后一页,不能再关闭了啦')
+          return
+        }
+        if(key == "/account/advertisingGroup"){
+            localStorage.removeItem("advertisingGroup")
+            localStorage.removeItem("advertisingGroupKey")
+        }
+        if(key == "/account/StepForm"){
+            localStorage.removeItem("step")
+        }
+        if(key == "/account/originality"){
+            localStorage.removeItem("originality")
+            localStorage.removeItem("originalityKey")
+        }
+        
+        this.pageList = this.pageList.filter(item => item.fullPath !== key)
+        let index = this.linkList.indexOf(key)
+        this.linkList = this.linkList.filter(item => item !== key)
+        index = index >= this.linkList.length ? this.linkList.length - 1 : index
+        this.activePage = this.linkList[index]
+      },
+      onContextmenu(e) {
+        const pagekey = this.getPageKey(e.target)
+        if (pagekey !== null) {
+          e.preventDefault()
+          this.menuVisible = true
+        }
+      },
+      getPageKey(target, depth) {n
+        depth = depth || 0
+        if (depth > 2) {
+          return null
+        }
+        let pageKey = target.getAttribute('pagekey')
+        pageKey = pageKey || (target.previousElementSibling ? target.previousElementSibling.getAttribute('pagekey') : null)
+        return pageKey || (target.firstElementChild ? this.getPageKey(target.firstElementChild, ++depth) : null)
+      },
+      onMenuSelect(key, target) {
+        let pageKey = this.getPageKey(target)
+        switch (key) {
+          case '1':
+            this.closeLeft(pageKey)
+            break
+          case '2':
+            this.closeRight(pageKey)
+            break
+          case '3':
+            this.closeOthers(pageKey)
+            break
+          default:
+            break
+        }
+      },
+      closeOthers(pageKey) {
+        let index = this.linkList.indexOf(pageKey)
+        if (pageKey == indexKey) {
+          this.linkList = this.linkList.slice(index, index + 1)
+          this.pageList = this.pageList.slice(index, index + 1)
+          this.activePage = this.linkList[0]
+        } else {
+          let indexContent = this.pageList.slice(0, 1)[0]
+          this.linkList = this.linkList.slice(index, index + 1)
+          this.pageList = this.pageList.slice(index, index + 1)
+          this.linkList.unshift(indexKey)
+          this.pageList.unshift(indexContent)
+          this.activePage = this.linkList[1]
+        }
+      },
+      closeLeft(pageKey) {
+        if (pageKey == indexKey) {
+          return
+        }
+        let tempList = [...this.pageList]
+        let indexContent = tempList.slice(0, 1)[0]
+        let index = this.linkList.indexOf(pageKey)
+        this.linkList = this.linkList.slice(index)
+        this.pageList = this.pageList.slice(index)
+        this.linkList.unshift(indexKey)
+        this.pageList.unshift(indexContent)
+        if (this.linkList.indexOf(this.activePage) < 0) {
+          this.activePage = this.linkList[0]
+        }
+      },
+      closeRight(pageKey) {
+        let index = this.linkList.indexOf(pageKey)
+        this.linkList = this.linkList.slice(0, index + 1)
+        this.pageList = this.pageList.slice(0, index + 1)
+        if (this.linkList.indexOf(this.activePage < 0)) {
+          this.activePage = this.linkList[this.linkList.length - 1]
+        }
+      },
+      //update-begin-author:taoyan date:20190430 for:动态路由title显示配置的菜单title而不是其对应路由的title
+      dynamicRouterShow(key, title) {
+        let keyIndex = this.linkList.indexOf(key)
+        if (keyIndex >= 0) {
+          let currRouter = this.pageList[keyIndex]
+          let meta = Object.assign({}, currRouter.meta, {title: title})
+          this.pageList.splice(keyIndex, 1, Object.assign({}, currRouter, {meta: meta}))
+        }
+      }
+      //update-end-author:taoyan date:20190430 for:动态路由title显示配置的菜单title而不是其对应路由的title
+    }
+  }
+</script>
+
+<style lang="scss">
+
+  /*
+ * The following styles are auto-applied to elements with
+ * transition="page-transition" when their visibility is toggled
+ * by Vue.js.
+ *
+ * You can easily play with the page transition by editing
+ * these styles.
+ */
+
+  .page-transition-enter {
+    opacity: 0;
+  }
+
+  .page-transition-leave-active {
+    opacity: 0;
+  }
+
+  .page-transition-enter .page-transition-container,
+  .page-transition-leave-active .page-transition-container {
+    -webkit-transform: scale(1.1);
+    transform: scale(1.1);
+  }
+
+  /*美化弹出Tab样式*/
+  .ant-tabs-nav-container {
+    margin-top: 4px;
+  }
+
+  /* 修改 ant-tabs 样式 */
+  .tab-layout-tabs.ant-tabs {
+    border-bottom: 1px solid #ccc;
+    border-left: 1px solid #ccc;
+    background-color: white;
+    padding: 0 20px;
+
+    .ant-tabs-bar {
+      margin: 4px 0 0;
+      border: none;
+    }
+
+  }
+
+  .ant-tabs {
+
+    &.ant-tabs-card .ant-tabs-tab {
+
+      padding: 0 24px !important;
+      background-color: white !important;
+      margin-right: 10px !important;
+
+      .ant-tabs-close-x {
+        width: 12px !important;
+        height: 12px !important;
+        opacity: 0 !important;
+        cursor: pointer !important;
+        font-size: 12px !important;
+        margin: 0 !important;
+        position: absolute;
+        top: 36%;
+        right: 6px;
+      }
+
+      &:hover .ant-tabs-close-x {
+        opacity: 1 !important;
+      }
+
+    }
+
+  }
+
+  .ant-tabs.ant-tabs-card > .ant-tabs-bar {
+    .ant-tabs-tab {
+      border: none !important;
+      border-bottom: 1px solid transparent !important;
+    }
+
+    .ant-tabs-tab-active {
+      border-color: #1890ff !important;
+    }
+  }
+
+
 </style>

+ 71 - 71
src/components/menu/Contextmenu.vue

@@ -1,71 +1,71 @@
-<template>
-  <a-menu :style="style" class="contextmenu" v-show="visible" @click="handleClick" :selectedKeys="selectedKeys">
-    <a-menu-item :key="item.key" v-for="item in itemList">
-      <a-icon role="menuitemicon" v-if="item.icon" :type="item.icon"/>{{ item.text }}
-    </a-menu-item>
-  </a-menu>
-</template>
-
-<script>
-  export default {
-    name: 'Contextmenu',
-    props: {
-      visible: {
-        type: Boolean,
-        required: false,
-        default: false
-      },
-      itemList: {
-        type: Array,
-        required: true,
-        default: () => []
-      }
-    },
-    data() {
-      return {
-        left: 0,
-        top: 0,
-        target: null,
-        selectedKeys: []
-      }
-    },
-    computed: {
-      style() {
-        return {
-          left: this.left + 'px',
-          top: this.top + 'px'
-        }
-      }
-    },
-    created() {
-      window.addEventListener('mousedown', e => this.closeMenu(e))
-      window.addEventListener('contextmenu', e => this.setPosition(e))
-    },
-    methods: {
-      closeMenu(e) {
-        if (['menuitemicon', 'menuitem'].indexOf(e.target.getAttribute('role')) < 0) {
-          this.$emit('update:visible', false)
-        }
-      },
-      setPosition(e) {
-        this.left = e.clientX
-        this.top = e.clientY
-        this.target = e.target
-      },
-      handleClick({key}) {
-        this.$emit('select', key, this.target)
-        this.$emit('update:visible', false)
-      }
-    }
-  }
-</script>
-
-<style lang="less" scoped>
-  .contextmenu {
-    position: fixed;
-    z-index: 1;
-    border: 1px solid #9e9e9e;
-    border-radius: 4px;
-    box-shadow: 2px 2px 10px #aaaaaa !important;
-  }
-</style>
+<template>
+  <a-menu :style="style" class="contextmenu" v-show="visible" @click="handleClick" :selectedKeys="selectedKeys">
+    <a-menu-item :key="item.key" v-for="item in itemList">
+      <a-icon role="menuitemicon" v-if="item.icon" :type="item.icon"/>{{ item.text }}
+    </a-menu-item>
+  </a-menu>
+</template>
+
+<script>
+  export default {
+    name: 'Contextmenu',
+    props: {
+      visible: {
+        type: Boolean,
+        required: false,
+        default: false
+      },
+      itemList: {
+        type: Array,
+        required: true,
+        default: () => []
+      }
+    },
+    data() {
+      return {
+        left: 0,
+        top: 0,
+        target: null,
+        selectedKeys: []
+      }
+    },
+    computed: {
+      style() {
+        return {
+          left: this.left + 'px',
+          top: this.top + 'px'
+        }
+      }
+    },
+    created() {
+      window.addEventListener('mousedown', e => this.closeMenu(e))
+      window.addEventListener('contextmenu', e => this.setPosition(e))
+    },
+    methods: {
+      closeMenu(e) {
+        if (['menuitemicon', 'menuitem'].indexOf(e.target.getAttribute('role')) < 0) {
+          this.$emit('update:visible', false)
+        }
+      },
+      setPosition(e) {
+        this.left = e.clientX
+        this.top = e.clientY
+        this.target = e.target
+      },
+      handleClick({key}) {
+        this.$emit('select', key, this.target)
+        this.$emit('update:visible', false)
+      }
+    }
+  }
+</script>
+
+<style lang="less" scoped>
+  .contextmenu {
+    position: fixed;
+    z-index: 1;
+    border: 1px solid #9e9e9e;
+    border-radius: 4px;
+    box-shadow: 2px 2px 10px #aaaaaa !important;
+  }
+</style>

+ 0 - 1
src/router/index.js

@@ -6,7 +6,6 @@ Vue.use(Router)
 
 const originalPush = Router.prototype.push;
 Router.prototype.push = function push(location) {
-  console.log(location,10001000,this,Router)
   if(location.name){
     return originalPush.call(this, location).catch(err => err)
   }

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

@@ -22,6 +22,7 @@ function hasPermission(permission, route) {
 }
 
 /**
+ * 
  * 单账户多角色时,使用该方法可过滤角色不存在的菜单
  *
  * @param roles

+ 6 - 1
src/views/modules/Statistics/Statistics.vue

@@ -542,7 +542,12 @@ export default {
           })
         } else {
           this.dataAllTableTwo = res[0]
-          this.dataTableTwo = res[0].beComparedDetail
+          this.dataTableTwo = res[0].beComparedDetail.map((item,index)=>{
+              return {
+                  ...item,
+                  key:index
+              }
+          })
         }
       })
     },

+ 7 - 1
src/views/modules/Statistics/components/lifting.vue

@@ -60,7 +60,13 @@
 <template>
   <div class="data-display-statistics">
     <a-card :title="title" :bordered="false">
-      <countTo :startVal="0" :endVal="kuaishou[typeName]" :duration="duration" :decimals="2"></countTo>
+      <countTo
+        :startVal="0"
+        :endVal="kuaishou[typeName]"
+        :duration="duration"
+        :decimals="2"
+        style="overflow:auto"
+      ></countTo>
       <a-icon
         v-if="kuaishou[typeThan]>0&&active==1"
         type="rise"

+ 11 - 1
src/views/modules/Statistics/dataDisplayStatistics.vue

@@ -185,7 +185,14 @@ th div {
             </a-select>
             <a-button type="primary" @click="exportExcel" style="margin-left:15px">导出</a-button>
           </div>
-          <a-table :columns="columns" :dataSource="data" bordered id="outTable" :pagination="false"></a-table>
+          <a-table
+            :columns="columns"
+            :dataSource="data"
+            bordered
+            id="outTable"
+            :pagination="false"
+            :scroll="{ x: 1900 }"
+          ></a-table>
         </a-card>
       </a-col>
     </a-row>
@@ -221,6 +228,7 @@ const columns = [
     title: '时间',
     dataIndex: 'date',
     align: 'center',
+    width: 150,
     customRender: function(text, record, index) {
       const obj = {
         children: text,
@@ -242,6 +250,7 @@ const columns = [
     title: '账户Id',
     dataIndex: 'accountId',
     align: 'center',
+    width: 150,
     customRender: function(text, record, index) {
       const obj = {
         children: text,
@@ -262,6 +271,7 @@ const columns = [
     dataIndex: 'accountName',
     scopedSlots: { customRender: 'cost' },
     align: 'center',
+    width: 150,
     customRender: function(text, record, index) {
       const obj = {
         children: text,

+ 2 - 1
src/views/modules/Statistics/materialStatistics.vue

@@ -95,6 +95,7 @@
           >
             <div slot="url" slot-scope="url">
               <video
+                @click.stop
                 class="video"
                 :src="url"
                 controls="controls"
@@ -372,7 +373,7 @@ export default {
             // this.detail = record
             // this.visible = true
             // this.getMineList(record.signature)
-            this.$refs.ratio.getMineList(record,this.active)
+            this.$refs.ratio.getMineList(record, this.active)
           }
         }
       })

+ 48 - 16
src/views/modules/appium/modules/AppiumTaskItemModal.vue

@@ -126,12 +126,20 @@
 </template>
 
 <script>
-import { httpAction } from '@/api/manage'
+import { getAction } from '@/api/manage'
 import pick from 'lodash.pick'
 import moment from 'moment'
 
+// import the component
+import Treeselect from '@riophae/vue-treeselect'
+// import the styles
+import '@riophae/vue-treeselect/dist/vue-treeselect.css'
+
+import { transformTozTreeFormat } from '@/utils/util.js'
+
 export default {
   name: 'AppiumTaskItemModal',
+  components: { Treeselect },
   data() {
     return {
       title: '操作',
@@ -157,10 +165,33 @@ export default {
       url: {
         add: '/appium/appiumTaskItem/add',
         edit: '/appium/appiumTaskItem/edit'
-      }
+      },
+      list: '/appium/appiumTask/list',
+      listTwo: '/appium/appiumTaskItem/list',
+      options:[]
     }
   },
   created() {},
+  mounted() {
+    this.$nextTick(() => {
+      var params = {}
+      params.pageNo = 1
+      params.pageSize = 100
+      var dataList = []
+      getAction(this.list, params).then(res => {
+        if (res.success) {
+          dataList.push(...res.result.records)
+          getAction(this.listTwo, params).then(item => {
+            if (res.success) {
+              dataList.push(...item.result.records)
+              dataList = transformTozTreeFormat(dataList)
+              this.options = dataList
+            }
+          })
+        }
+      })
+    })
+  },
   methods: {
     switchShow(check) {},
     switchShowTwo(check) {},
@@ -175,7 +206,8 @@ export default {
         loopType: false,
         isMust: true,
         waitTime: 1000,
-        isClose: false
+        isClose: false,
+        parentId:""
       })
     },
     edit(record) {
@@ -253,19 +285,19 @@ export default {
           //时间格式化
 
           console.log(params, this.model)
-            httpAction(httpurl, params, method)
-              .then(res => {
-                if (res.success) {
-                  that.$message.success(res.message)
-                  that.$emit('ok')
-                } else {
-                  that.$message.warning(res.message)
-                }
-              })
-              .finally(() => {
-                that.confirmLoading = false
-                that.close()
-              })
+          httpAction(httpurl, params, method)
+            .then(res => {
+              if (res.success) {
+                that.$message.success(res.message)
+                that.$emit('ok')
+              } else {
+                that.$message.warning(res.message)
+              }
+            })
+            .finally(() => {
+              that.confirmLoading = false
+              that.close()
+            })
         }
       })
     },

+ 284 - 0
src/views/modules/kuaishouapp/account/accountIndex.vue

@@ -0,0 +1,284 @@
+<style>
+.account-statistics .ant-card-body .count {
+  display: inline-block;
+  height: 32px;
+  line-height: 32px;
+}
+</style>
+<template>
+  <div class="account-statistics">
+    <a-row class="image-list-heading vm-panel">
+      <a-row>
+        <!-- <div class="panel-heading">{{ title }}</div> -->
+        <!-- <a-select defaultValue="jack" style="width:30%" class="panel-heading">
+          <a-select-option value="jack">账户1</a-select-option>
+          <a-select-option value="lucy">账户2</a-select-option>
+          <a-select-option value="Yiminghe">账户3</a-select-option>
+        </a-select>-->
+        <a-select
+          v-model="appId"
+          showSearch
+          allowClear
+          placeholder="请选择账户"
+          optionFilterProp="children"
+          style="width:600px;margin-left:20px"
+        >
+          <a-select-option
+            v-for="appModel in options"
+            :key="appModel.id+new Date().getTime()"
+            :value="appModel.accountId"
+          >{{appModel.advertiserName}}&#12288;&#12288;{{appModel.accountId}}&#12288;&nbsp;&#12288;{{appModel.authName}}&#12288;&#12288;{{appModel.operationName}}</a-select-option>
+        </a-select>
+        <a-button type="primary" style="margin:10px" @click="addUser">搜索</a-button>
+      </a-row>
+    </a-row>
+    <a-row :gutter="15" style="margin-top:15px">
+      <a-col :span="8">
+        <a-card hoverable title="总花费">
+          <countTo :startVal="0" :endVal="1000" :duration="duration" :decimals="2" class="count"></countTo>
+        </a-card>
+      </a-col>
+      <a-col :span="8">
+        <a-card hoverable title="预算">
+          <countTo
+            :startVal="0"
+            :endVal="many"
+            :duration="duration"
+            :decimals="2"
+            v-show="!showEdit"
+            class="count"
+          ></countTo>
+          <a-input-number
+            :min="0"
+            :step="0.01"
+            v-show="showEdit"
+            v-model="manyTwo"
+            style="width:200px"
+          />
+          <!-- <a-input v-show="showEdit" v-model="manyTwo" style="width:200px"></a-input> -->
+          <a-icon
+            :type="showEdit?'check':'edit'"
+            @click="showEdit=!showEdit,show()"
+            style="margin-left:10px"
+          />
+        </a-card>
+      </a-col>
+      <a-col :span="8">
+        <a-card hoverable title="余额">
+          <countTo :startVal="0" :endVal="1000" :duration="duration" :decimals="2" class="count"></countTo>
+        </a-card>
+      </a-col>
+    </a-row>
+    <a-row style="margin-top:15px">
+      <a-card>
+        <a-button @click="dianji" style="margin-bottom:15px">新增广告计划</a-button>
+        <a-table
+          :columns="columns"
+          :dataSource="dataList"
+          bordered
+          :scroll="{ x: 1900 }"
+          :customRow="rowClick"
+          :pagination="ipagination"
+        >
+          <template slot="dayBudget" slot-scope="text,record">
+            <div style="display:flex;justify-content: center;">
+              <span v-show="!record.edit" class="count">{{text?text.toFixed(2):'不限制预算'}}</span>
+              <a-input-number
+                :min="0"
+                :step="0.01"
+                v-show="record.edit"
+                v-model="record.elseMoney"
+                style="width:150px"
+              />
+              <a-icon
+                :type="record.edit?'check':'edit'"
+                @click.stop="record.edit=!record.edit,editShow(record)"
+                style="margin-left:10px"
+                class="count"
+              />
+            </div>
+          </template>
+        </a-table>
+      </a-card>
+    </a-row>
+  </div>
+</template>
+
+<script>
+import ARow from 'ant-design-vue/es/grid/Row'
+import ACol from 'ant-design-vue/es/grid/Col'
+import moment from 'moment'
+import countTo from 'vue-count-to'
+import { mapGetters } from 'vuex'
+import { deleteAction, getAction } from '@/api/manage'
+
+import { getMaterialAccount } from '@api/statistics'
+
+// import lifting from './components/lifting'
+var columns = [
+  {
+    title: '广告计划名称',
+    align: 'center',
+    dataIndex: 'campaignName',
+    fixed: 'left',
+    width: 200
+  },
+  {
+    title: '计划单日预算金额',
+    align: 'center',
+    dataIndex: 'dayBudget',
+    scopedSlots: { customRender: 'dayBudget' },
+    width: 250
+  },
+  {
+    title: '计划类型',
+    align: 'center',
+    dataIndex: 'type'
+  },
+  {
+    title: '应用创建id',
+    align: 'center',
+    dataIndex: 'appId'
+  },
+  {
+    title: 'url类型 ',
+    align: 'center',
+    dataIndex: 'urlType'
+  },
+
+  {
+    title: '推广url',
+    align: 'center',
+    dataIndex: 'url'
+  },
+
+  {
+    title: '操作',
+    dataIndex: 'action',
+    align: 'center',
+    scopedSlots: { customRender: 'action' }
+  }
+]
+export default {
+  name: 'account-statistics',
+  components: {
+    ACol,
+    ARow,
+    countTo
+  },
+
+  data: function() {
+    return {
+      duration: 1000,
+      showEdit: false,
+      many: 1200,
+      manyTwo: null,
+      columns,
+      dataList: [],
+      appId: '',
+      options: [],
+      rowClick: (record, index) => ({
+        // 事件
+        on: {
+          dblclick: () => {
+            // 点击改行时要做的事情
+            localStorage.setItem('advertisingGroupKey', record.id)
+            if (localStorage.getItem('advertisingGroup')) {
+              var dataElse = JSON.parse(localStorage.getItem('advertisingGroup'))
+              console.log(dataElse)
+              for (let i = 0; i < dataElse.length; i++) {
+                if (dataElse[i].key == record.key) {
+                  this.$router.replace({ path: '/account/advertisingGroup' })
+                  return
+                }
+              }
+              dataElse.push(record)
+              localStorage.setItem('advertisingGroup', JSON.stringify(dataElse))
+            } else {
+              var data = [record]
+              localStorage.setItem('advertisingGroup', JSON.stringify(data))
+            }
+            this.$router.replace({ path: '/account/advertisingGroup' })
+          }
+        }
+      }),
+      ipagination: {
+        current: 1,
+        pageSize: 10,
+        pageSizeOptions: ['10', '20', '30'],
+        showTotal: (total, range) => {
+          return range[0] + '-' + range[1] + ' 共' + total + '条'
+        },
+        showQuickJumper: true,
+        showSizeChanger: true,
+        total: 0
+      },
+      url: {
+        list: '/kuaishou/kuaiShouCampaignTemplate/list',
+        delete: '/kuaishou/kuaiShouCampaignTemplate/delete',
+        deleteBatch: '/kuaishou/kuaiShouCampaignTemplate/deleteBatch',
+        exportXlsUrl: 'kuaishou/kuaiShouCampaignTemplate/exportXls',
+        importExcelUrl: 'kuaishou/kuaiShouCampaignTemplate/importExcel'
+      }
+    }
+  },
+  methods: {
+    ...mapGetters(['nickname', 'avatar', 'userInfo']),
+    addUser() {
+      this.loading = true
+      this.dataList = []
+      var params = {}
+    //   params.accountId = this.appId + ''
+      params.pageNo = this.ipagination.current
+      params.pageSize = this.ipagination.pageSize
+      if (this.appId) {
+        getAction(this.url.list, params).then(res => {
+          if (res.code == 0) {
+            this.dataList = res.result.records.map((v, index) => {
+              return {
+                ...v,
+                key: index,
+                edit: false
+              }
+            })
+          }
+        })
+      } else {
+        this.$message.error('请选择账户')
+      }
+    },
+    show() {
+      if (!this.showEdit) {
+        this.many = this.manyTwo
+      } else {
+        this.manyTwo = this.many
+      }
+    },
+    editShow(item) {
+      if (!item.edit) {
+        item.dayBudget = item.elseMoney
+      } else {
+        item.elseMoney = item.dayBudget
+      }
+    },
+    dianji() {
+      if (localStorage.getItem('step')) {
+        this.$message.error('正在进行广告组创建,请关闭创建页面后,重新进行创建')
+        return
+      } else {
+        localStorage.setItem('step', 0)
+        this.$router.replace({ name: 'account-StepForm' })
+      }
+    }
+  },
+  watch: {},
+
+  computed: {},
+  activated() {
+    this.manyTwo = this.many
+    getMaterialAccount({ userId: this.userInfo().id }).then(res => {
+      this.options = res
+    })
+  }
+}
+</script>

+ 349 - 0
src/views/modules/kuaishouapp/account/advertisingGroup.vue

@@ -0,0 +1,349 @@
+<style>
+.account-statistics .ant-card-body .count {
+  display: inline-block;
+  height: 32px;
+  line-height: 32px;
+}
+.checked .ant-checkbox-wrapper {
+  width: 140px;
+}
+</style>
+<template>
+  <div class="account-statistics">
+    <a-row style="margin-top:15px">
+      <a-card
+        :tabList="title"
+        :activeTabKey="titleKey"
+        @tabChange="key => onTabChange(key, 'titleKey')"
+      >
+        <a-button @click="dianji" style="margin-bottom:15px">新增广告组</a-button>
+        <a-button @click="showEdit=true" style="margin:0 0 15px 15px">列表项筛选</a-button>
+
+        <a-modal title="列表项筛选" v-model="showEdit" @ok="handleOk">
+          <a-checkbox
+            :indeterminate="indeterminate"
+            @change="onCheckAllChange"
+            :checked="checkAll"
+          >全选</a-checkbox>
+          <a-checkbox-group :options="showList" v-model="dataValue" class="checked" />
+        </a-modal>
+
+        <a-table
+          :columns="columns"
+          :dataSource="dataList"
+          bordered
+          :customRow="rowClick"
+          :pagination="ipagination"
+        >
+          <template slot="money" slot-scope="text,record">
+            <div style="display:flex">
+              <span v-show="!record.edit" class="count">{{text?text.toFixed(2):'不限制预算'}}</span>
+              <a-input-number
+                :min="0"
+                :step="0.01"
+                v-show="record.edit"
+                v-model="record.elseMoney"
+                style="width:150px"
+              />
+              <a-icon
+                :type="record.edit?'check':'edit'"
+                @click.stop="record.edit=!record.edit,editShow(record)"
+                style="margin-left:10px"
+                class="count"
+              />
+            </div>
+          </template>
+        </a-table>
+      </a-card>
+    </a-row>
+  </div>
+</template>
+
+<script>
+import ARow from 'ant-design-vue/es/grid/Row'
+import ACol from 'ant-design-vue/es/grid/Col'
+import moment from 'moment'
+import countTo from 'vue-count-to'
+import { deleteAction, getAction } from '@/api/manage'
+// import lifting from './components/lifting'
+var columns = [
+  {
+    title: '广告计划ID',
+    align: 'center',
+    dataIndex: 'campaignTemplateId',
+    colSpan: 1
+  },
+  {
+    title: '账户',
+    align: 'center',
+    dataIndex: 'accountId',
+    colSpan: 1
+  },
+  {
+    title: '广告活动ID',
+    align: 'center',
+    dataIndex: 'campaignId',
+    colSpan: 1
+  },
+  {
+    title: '广告组名称',
+    align: 'center',
+    dataIndex: 'unitName',
+    colSpan: 1
+  },
+  {
+    title: '出价类型',
+    align: 'center',
+    dataIndex: 'bidType',
+    colSpan: 1
+  },
+  {
+    title: '出价',
+    align: 'center',
+    dataIndex: 'bid',
+    colSpan: 1
+  },
+  {
+    title: 'OCPC出价',
+    align: 'center',
+    dataIndex: 'cpaBid',
+    colSpan: 0
+  },
+  {
+    title: '优化目标',
+    align: 'center',
+    dataIndex: 'ocpxActionType',
+    colSpan: 0
+  },
+  {
+    title: '深度转化目标',
+    align: 'center',
+    dataIndex: 'deepConversionType',
+    colSpan: 0
+  },
+  {
+    title: '资源位置',
+    align: 'center',
+    dataIndex: 'page',
+    colSpan: 0
+  },
+  {
+    title: '投放开始时间',
+    align: 'center',
+    dataIndex: 'beginTime',
+    colSpan: 0
+  },
+  {
+    title: '投放结束时间',
+    align: 'center',
+    dataIndex: 'endTime',
+    colSpan: 0
+  },
+  {
+    title: '投放时段',
+    align: 'center',
+    dataIndex: 'scheduleTime',
+    colSpan: 0
+  },
+  {
+    title: '单日预算',
+    align: 'center',
+    dataIndex: 'dayBudget',
+    colSpan: 0
+  },
+  {
+    title: 'url类型',
+    align: 'center',
+    dataIndex: 'urlType',
+    colSpan: 0
+  },
+  {
+    title: '投放链接',
+    align: 'center',
+    dataIndex: 'url',
+    colSpan: 0
+  },
+
+  {
+    title: '创意展现方式',
+    align: 'center',
+    dataIndex: 'showModel',
+    colSpan: 0
+  },
+  {
+    title: '投放方式',
+    align: 'center',
+    dataIndex: 'speed',
+    colSpan: 0
+  },
+  {
+    title: '广告组ID',
+    align: 'center',
+    dataIndex: 'unitId',
+    colSpan: 0
+  },
+  {
+    title: '操作',
+    dataIndex: 'action',
+    align: 'center',
+    scopedSlots: { customRender: 'action' },
+    colSpan: 0
+  }
+]
+
+export default {
+  name: 'account-statistics',
+  components: {
+    ACol,
+    ARow,
+    countTo
+  },
+
+  data: function() {
+    return {
+      duration: 1000,
+      showEdit: false,
+      columns,
+      dataList: [],
+      rowClick: (record, index) => ({
+        // 事件
+        on: {
+          dblclick: () => {
+            // 点击改行时要做的事情
+            localStorage.setItem('originalityKey', record.campaignName)
+            if (localStorage.getItem('originality')) {
+              var dataElse = JSON.parse(localStorage.getItem('originality'))
+              console.log(dataElse)
+              for (let i = 0; i < dataElse.length; i++) {
+                if (dataElse[i].key == record.key) {
+                  this.$router.replace({ path: '/account/originality' })
+                  return
+                }
+              }
+              dataElse.push(record)
+              localStorage.setItem('originality', JSON.stringify(dataElse))
+            } else {
+              var data = [record]
+              localStorage.setItem('originality', JSON.stringify(data))
+            }
+            this.$router.replace({ path: '/account/originality' })
+          }
+        }
+      }),
+      ipagination: {
+        current: 1,
+        pageSize: 10,
+        pageSizeOptions: ['10', '20', '30'],
+        showTotal: (total, range) => {
+          return range[0] + '-' + range[1] + ' 共' + total + '条'
+        },
+        showQuickJumper: true,
+        showSizeChanger: true,
+        total: 0
+      },
+      url: {
+        list: '/kuaishou/kuaiShouGroupCreateLog/list',
+        delete: '/kuaishou/kuaiShouGroupCreateLog/delete',
+        deleteBatch: '/kuaishou/kuaiShouGroupCreateLog/deleteBatch',
+        exportXlsUrl: 'kuaishou/kuaiShouGroupCreateLog/exportXls',
+        importExcelUrl: 'kuaishou/kuaiShouGroupCreateLog/importExcel'
+      },
+      name: null,
+      title: [],
+      titleKey: null,
+      showList: null,
+      dataValue: [],
+      indeterminate: true,
+      checkAll: false
+    }
+  },
+  methods: {
+    handleOk(e) {
+      console.log(e)
+      this.showEdit = false
+      this.onChange(this.dataValue)
+    },
+    onCheckAllChange(e) {
+      Object.assign(this, {
+        dataValue: e.target.checked ? this.showList.map(item=>{return item.value}) : [],
+        indeterminate: false,
+        checkAll: e.target.checked
+      })
+    },
+    onChange(checkedValues) {
+      for (let j = 0; j < this.columns.length; j++) {
+        if (checkedValues.indexOf(this.columns[j].dataIndex) != -1) {
+          this.columns[j].colSpan = 1
+        } else {
+          this.columns[j].colSpan = 0
+        }
+      }
+    },
+    onTabChange(key, type) {
+      console.log(key, type)
+      this[type] = key
+      localStorage.setItem('advertisingGroupKey', key)
+      this.getDataList(key)
+    },
+    getDataList(id) {
+      this.dataList = []
+      var params = {}
+      params.campaignId = id
+      params.pageNo = this.ipagination.current
+      params.pageSize = this.ipagination.pageSize
+      getAction(this.url.list, params).then(res => {
+        if (res.code == 0) {
+          this.dataList = res.result.records.map((v, index) => {
+            return {
+              ...v,
+              key: index,
+              edit: false
+            }
+          })
+        }
+      })
+    },
+    dianji() {
+      if (localStorage.getItem('step')) {
+        this.$message.error('正在进行广告计划创建,请关闭创建页面后,重新进行创建')
+        return
+      } else {
+        localStorage.setItem('step', 1)
+        this.$router.replace({ name: 'account-StepForm' })
+      }
+    }
+  },
+  watch: {
+    dataValue(n, o) {
+      console.log(n)
+      this.indeterminate = !!this.dataValue.length && this.dataValue.length < this.showList.length
+      this.checkAll = this.dataValue.length === this.showList.length
+    }
+  },
+  computed: {},
+  activated() {
+    this.titleKey = localStorage.getItem('advertisingGroupKey')
+    this.title = JSON.parse(localStorage.getItem('advertisingGroup')).map(item => {
+      return {
+        key: item.id + '',
+        tab: '广告计划:' + item.campaignName
+      }
+    })
+    this.getDataList(localStorage.getItem('advertisingGroupKey'))
+    this.showList = this.columns.map(item => {
+      return {
+        label: item.title,
+        value: item.dataIndex
+      }
+    })
+    this.dataValue = this.columns.filter(item => {
+      if (item.colSpan == 1) {
+        return item
+      }
+    })
+    this.dataValue = this.dataValue.map(item => {
+      return item.dataIndex
+    })
+  }
+}
+</script>

+ 150 - 0
src/views/modules/kuaishouapp/account/originality.vue

@@ -0,0 +1,150 @@
+<style>
+.account-statistics .ant-card-body .count {
+  display: inline-block;
+  height: 32px;
+  line-height: 32px;
+}
+</style>
+<template>
+  <div class="account-statistics">
+    <a-row style="margin-top:15px">
+      <a-card
+        :tabList="title"
+        :activeTabKey="titleKey"
+        @tabChange="key => onTabChange(key, 'titleKey')"
+      >
+        <a-button @click="dianji" style="margin-bottom:15px">新增创意</a-button>
+        <a-table
+          :columns="columns"
+          :dataSource="data"
+          bordered
+          :scroll="{ x: 1900 }"
+          :customRow="rowClick"
+        >
+          <template slot="money" slot-scope="text,record">
+            <div style="display:flex">
+              <span v-show="!record.edit" class="count">{{text?text.toFixed(2):'不限制预算'}}</span>
+              <a-input-number
+                :min="0"
+                :step="0.01"
+                v-show="record.edit"
+                v-model="record.elseMoney"
+                style="width:150px"
+              />
+              <a-icon
+                :type="record.edit?'check':'edit'"
+                @click.stop="record.edit=!record.edit,editShow(record)"
+                style="margin-left:10px"
+                class="count"
+              />
+            </div>
+          </template>
+        </a-table>
+      </a-card>
+    </a-row>
+  </div>
+</template>
+
+<script>
+import ARow from 'ant-design-vue/es/grid/Row'
+import ACol from 'ant-design-vue/es/grid/Col'
+import moment from 'moment'
+import countTo from 'vue-count-to'
+// import lifting from './components/lifting'
+const columns = [
+  {
+    title: '账户',
+    dataIndex: 'campaignName',
+    scopedSlots: { customRender: 'name' },
+    fixed: 'left',
+    width: 200
+  },
+  {
+    title: '预算(不输入为不限制预算)',
+    className: 'column-money',
+    dataIndex: 'money',
+    fixed: 'left',
+    width: 250,
+    scopedSlots: { customRender: 'money' }
+  },
+  {
+    title: '其他',
+    dataIndex: 'address'
+  }
+]
+
+export default {
+  name: 'account-statistics',
+  components: {
+    ACol,
+    ARow,
+    countTo
+  },
+
+  data: function() {
+    return {
+      duration: 1000,
+      showEdit: false,
+      many: 1200,
+      manyTwo: null,
+      columns,
+      data: [],
+      rowClick: (record, index) => ({
+        // 事件
+        on: {
+          dblclick: () => {
+            // 点击改行时要做的事情
+            // alert(index)
+          }
+        }
+      }),
+      name: null,
+      title: [],
+      titleKey: null
+    }
+  },
+  methods: {
+    onTabChange(key, type) {
+      console.log(key, type)
+      this[type] = key
+      localStorage.setItem('originalityKey',key)
+    },
+    show() {
+      if (!this.showEdit) {
+        this.many = this.manyTwo
+      } else {
+        this.manyTwo = this.many
+      }
+    },
+    editShow(item) {
+      if (!item.edit) {
+        item.money = item.elseMoney
+      } else {
+        item.elseMoney = item.money
+      }
+    },
+    dianji() {
+      if (localStorage.getItem('step')) {
+        this.$message.error('请关闭创建页面后,重新进行创建')
+        return
+      } else {
+        localStorage.setItem('step', 2)
+        this.$router.replace({ name: 'account-StepForm' })
+      }
+    }
+  },
+  watch: {},
+  computed: {},
+  activated() {
+    this.titleKey = localStorage.getItem('originalityKey')
+    console.log(this.$route.params)
+    this.title = JSON.parse(localStorage.getItem('originality')).map(item => {
+      return {
+        key: item.campaignName,
+        tab: '广告组:' + item.campaignName
+      }
+    })
+    this.data = JSON.parse(localStorage.getItem('originality'))
+  }
+}
+</script>

+ 286 - 0
src/views/modules/kuaishouapp/account/stepForm/Step1.vue

@@ -0,0 +1,286 @@
+<template>
+  <a-card :body-style="{padding: '24px 32px'}" :bordered="false">
+    <a-form @submit="handleSubmit" :form="form">
+      <a-form-item
+        label="推广目的"
+        :labelCol="{lg: {span: 7}, sm: {span: 7}}"
+        :wrapperCol="{lg: {span: 10}, sm: {span: 17} }"
+      >
+        <a-radio-group @change="typeChange" v-model="type">
+          <a-radio-button
+            v-for="purpose in typeList"
+            :key="purpose.itemText"
+            :value="purpose.itemValue"
+          >{{purpose.itemText}}</a-radio-button>
+        </a-radio-group>
+      </a-form-item>
+
+      <a-form-item
+        label="计划名称"
+        :labelCol="{lg: {span: 7}, sm: {span: 7}}"
+        :wrapperCol="{lg: {span: 10}, sm: {span: 17} }"
+      >
+        <a-input v-model="campaignName"></a-input>
+      </a-form-item>
+
+      <a-form-item
+        label="单日预算"
+        :labelCol="{lg: {span: 7}, sm: {span: 7}}"
+        :wrapperCol="{lg: {span: 10}, sm: {span: 17} }"
+      >
+        <a-radio-group @change="showBudgetStatusChange" v-model="campaignBudget">
+          <a-radio-button value="UNLIMITED">不限</a-radio-button>
+          <a-radio-button value="AS_BUDGET">统一预算</a-radio-button>
+        </a-radio-group>
+      </a-form-item>
+      <a-form-item
+        label="预算金额"
+        v-if="showBudgetDaily"
+        :labelCol="{lg: {span: 7}, sm: {span: 7}}"
+        :wrapperCol="{lg: {span: 10}, sm: {span: 17} }"
+      >
+        <a-input
+          v-model="dayBudget"
+          v-decorator="[
+                  'confirm_dayBudget',
+                  {rules: [{ required: true, message: 'error:' },
+                  {validator: handleConfirmValue}]}
+                ]"
+          placeholder="不小于500,不超过100000000,仅支持输入自然数"
+          type="number"
+          style="width: 70%"
+        ></a-input>元
+      </a-form-item>
+
+      <a-form-item
+        v-if="showApp"
+        label="目标应用"
+        :labelCol="{lg: {span: 7}, sm: {span: 7}}"
+        :wrapperCol="{lg: {span: 10}, sm: {span: 17} }"
+      >
+        <a-select
+          v-model="appId"
+          showSearch
+          allowClear
+          placeholder="选择应用目标"
+          optionFilterProp="children"
+          style="width: 600px"
+          @focus="handleFocus"
+          @blur="handleBlur"
+          @change="handleChange"
+          :filterOption="filterOption"
+        >
+          <!-- <a-select-option value="0">请选择目标应用</a-select-option> -->
+          <a-select-option
+            v-for="appModel in appList"
+            :key="appModel.id"
+            :value="appModel.id"
+          >{{appModel.appName}}&#12288;&nbsp;&#12288;{{appModel.appType}}&#12288;&#12288; {{appModel.appVersion}}</a-select-option>
+        </a-select>
+      </a-form-item>
+
+      <a-form-item
+        v-if="showUrlType"
+        label="转化类型"
+        :labelCol="{lg: {span: 7}, sm: {span: 7}}"
+        :wrapperCol="{lg: {span: 10}, sm: {span: 17} }"
+      >
+        <a-radio-group v-model="urlType">
+          <a-radio-button value="1">淘宝商品短链</a-radio-button>
+          <a-radio-button value="2">淘宝商品</a-radio-button>
+        </a-radio-group>
+      </a-form-item>
+
+      <a-form-item
+        v-if="showChannelType"
+        label="转化类型"
+        :labelCol="{lg: {span: 7}, sm: {span: 7}}"
+        :wrapperCol="{lg: {span: 10}, sm: {span: 17} }"
+      >
+        <a-radio-group v-model="channelType">
+          <a-radio-button value="1">填写链接</a-radio-button>
+          <a-radio-button value="2" disabled="disabled">落地页工具</a-radio-button>
+        </a-radio-group>
+      </a-form-item>
+
+      <a-form-item
+        v-if="showRedirect"
+        label="链接地址"
+        :labelCol="{lg: {span: 7}, sm: {span: 7}}"
+        :wrapperCol="{lg: {span: 10}, sm: {span: 17} }"
+      >
+        <a-input v-model="redirectUrl"></a-input>
+      </a-form-item>
+
+      <a-form-item :wrapperCol="{ span: 24 }" style="text-align: center">
+        <a-button htmlType="submit" type="primary">下一步</a-button>
+        <!-- <a-button style="margin-left: 8px">保存</a-button> -->
+      </a-form-item>
+    </a-form>
+  </a-card>
+</template>
+
+<script>
+import { deleteAction, postAction, getAction } from '@/api/manage'
+import moment from 'moment'
+import { mapActions, mapGetters } from 'vuex'
+
+export default {
+  name: 'BaseForm',
+  data() {
+    return {
+      promotionName: '',
+      type: '2',
+      typeList: {},
+      appList: {},
+      showBudgetDaily: false,
+      campaignName: '提升应用安装_' + moment(new Date()),
+      campaignBudget: 'UNLIMITED',
+      dayBudget: 0,
+      appId: '0', //应用目标
+      showApp: true,
+      redirectUrl: '', // 链接地址
+      showRedirect: false,
+      urlType: '1',
+      showUrlType: false,
+      channelType: '1',
+      showChannelType: false,
+
+      form: this.$form.createForm(this),
+      url: {
+        dictListUrl: 'toutiao/dictitem/list',
+        appListUrl: '/kuaishou/kuaiShouCreateAppTemplate/list',
+        insertTemplateUrl: '/kuaishou/kuaiShouCampaignTemplate/insert'
+      }
+    }
+  },
+  methods: {
+    ...mapGetters(['nickname', 'avatar', 'userInfo']),
+    handleConfirmValue(rule, value, callback) {
+      if (this.dayBudget == '' || this.dayBudget < 500 || this.dayBudget >= 100000000) {
+        callback('请输入正确预算金额')
+      }
+      callback()
+    },
+
+    handleConfirmAppId(rule, value, callback) {
+      if (this.type == 2 && (this.appId == '0' || this.appId == '')) {
+        callback('请选择目标应用')
+      }
+      callback()
+    },
+    handleSubmit(e) {
+      e.preventDefault()
+      this.form.validateFields((err, values) => {
+        if (!err) {
+          console.log('Received values of form: ', values)
+          let params = {}
+          params.type = this.type
+          if (this.type == '2') {
+            params.appId = this.appId
+          }
+          if (this.type == '3') {
+            params.urlType = this.urlType
+          }
+          if (this.type == '5' || this.type == '4' || this.type == '3') {
+            params.url = this.redirectUrl
+          }
+          // params.campaignBudget = this.campaignBudget;
+          params.dayBudget = this.dayBudget
+          params.campaignName = this.campaignName
+          params.loginId = this.userInfo().id
+          console.log(params)
+          this.nextStep()
+          //   postAction(this.url.insertTemplateUrl, params).then(res => {
+          //     console.log(res)
+          //     if (res.success) {
+          //       alert('广告组模板创建成功')
+          //     }
+          //   })
+        }
+      })
+    },
+    onChange(value) {
+      console.log(value)
+    },
+    showBudgetStatusChange() {
+      if (this.campaignBudget == 'UNLIMITED') {
+        this.showBudgetDaily = false
+        this.dayBudget = 0
+      } else {
+        this.showBudgetDaily = true
+        this.dayBudget = ''
+      }
+    },
+    typeChange() {
+      if (this.type == 2) {
+        this.promotionName = '提升应用安装'
+        this.showApp = true
+        this.showRedirect = false
+        this.showUrlType = false
+        this.showChannelType = false
+      }
+      if (this.type == 3) {
+        this.promotionName = '获取电商下单'
+        this.showApp = false
+        this.showRedirect = true
+        this.showUrlType = true
+        this.showChannelType = false
+      }
+      if (this.type == 4) {
+        this.promotionName = '推广品牌活动'
+        this.showApp = false
+        this.showRedirect = true
+        this.showUrlType = false
+        this.showChannelType = false
+      }
+      if (this.type == 5) {
+        this.promotionName = '收集销售线索'
+        this.showApp = false
+        this.showRedirect = true
+        this.showUrlType = false
+        this.showChannelType = true
+      }
+      this.campaignName = this.promotionName + '_' + moment(new Date())
+    },
+    handleChange(value) {
+      console.log(`selected ${value}`)
+    },
+    handleBlur() {
+      console.log('blur')
+    },
+    handleFocus() {
+      console.log('focus')
+    },
+    filterOption(input, option) {
+      return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
+    },
+    nextStep() {
+      this.$emit('nextStep')
+    }
+  },
+  activated: function() {
+    //出价方式
+    let params = {}
+    params.dictId = '181afbae847dd3bc7e27795d8958956'
+    params.pageSize = '1000'
+    getAction(this.url.dictListUrl, params).then(res => {
+      if (res.success) {
+        this.typeList = res.result.records
+      }
+    })
+
+    // 应用列表
+    //出价方式
+    let params2 = {}
+    params2.loginId = this.userInfo().id
+    params2.pageSize = '1000'
+    getAction(this.url.appListUrl, params).then(res => {
+      if (res.success) {
+        this.appList = res.result.records
+        console.log(this.appList)
+      }
+    })
+  }
+}
+</script>

File diff ditekan karena terlalu besar
+ 1414 - 0
src/views/modules/kuaishouapp/account/stepForm/Step2.vue


File diff ditekan karena terlalu besar
+ 1447 - 0
src/views/modules/kuaishouapp/account/stepForm/Step3.vue


+ 52 - 0
src/views/modules/kuaishouapp/account/stepForm/Step4.vue

@@ -0,0 +1,52 @@
+<template>
+  <div>
+    <a-form style="margin: 40px auto 0;">
+      <result title="操作成功" :is-success="true" description="预计两小时内到账">
+        <div slot="action">
+          <a-button type="primary" @click="finish">再转一笔</a-button>
+          <a-button style="margin-left: 8px" @click="toOrderList">查看账单</a-button>
+        </div>
+      </result>
+    </a-form>
+  </div>
+</template>
+
+<script>
+  import Result from '../../../../result/Result'
+
+  export default {
+    name: "Step3",
+    components: {
+      Result
+    },
+    data() {
+      return {
+        loading: false
+      }
+    },
+    methods: {
+      finish() {
+        this.$emit('finish')
+      },
+      toOrderList() {
+        this.$router.push('/list/query-list')
+      }
+    }
+  }
+</script>
+<style lang="scss" scoped>
+  .information {
+    line-height: 22px;
+
+    .ant-row:not(:last-child) {
+      margin-bottom: 24px;
+    }
+  }
+
+  .money {
+    font-family: "Helvetica Neue", sans-serif;
+    font-weight: 500;
+    font-size: 20px;
+    line-height: 14px;
+  }
+</style>

+ 77 - 0
src/views/modules/kuaishouapp/account/stepForm/StepForm.vue

@@ -0,0 +1,77 @@
+<template>
+  <a-card :bordered="false">
+    <a-steps class="steps" :current="currentTab">
+      <a-step title="创建计划" />
+      <a-step title="创建广告组" />
+      <a-step title="创建创意" />
+      <!-- <a-step title="完成" /> -->
+    </a-steps>
+    <div class="content">
+      <step1 v-if="currentTab === 0" @nextStep="nextStep" />
+      <step2 v-if="currentTab === 1" @nextStep="nextStepTwo" @prevStep="prevStep" />
+      <step3 :pans="pans" v-show="currentTab === 2" @nextStep="nextStep" @prevStep="prevStep" />
+      <!-- <step4 v-if="currentTab === 3" @prevStep="prevStep" @finish="finish" /> -->
+    </div>
+  </a-card>
+</template>
+
+<script>
+import Step1 from './Step1'
+import Step2 from './Step2'
+import Step3 from './Step3'
+import Step4 from './Step4'
+export default {
+  name: 'StepForm',
+  components: {
+    Step1,
+    Step2,
+    Step3,
+    Step4
+  },
+  data() {
+    return {
+      currentTab: 0,
+
+      // form
+      form: null,
+      pans: []
+    }
+  },
+  methods: {
+    // handler
+    nextStep() {
+      if (this.currentTab < 2) {
+        this.currentTab += 1
+      }
+    },
+    nextStepTwo(item) {
+      this.pans = item
+      if (this.currentTab < 2) {
+        this.currentTab += 1
+      }
+    },
+    prevStep() {
+      if (this.currentTab > 0) {
+        this.currentTab -= 1
+      }
+    },
+    finish() {
+      this.currentTab = 0
+    }
+  },
+  activated() {
+    this.currentTab = parseInt(localStorage.getItem('step'))
+  }
+}
+</script>
+
+
+
+
+
+<style lang="scss" scoped>
+.steps {
+  max-width: 750px;
+  margin: 16px auto;
+}
+</style>

+ 3 - 0
src/views/modules/kuaishouapp/campaignCreate.vue

@@ -275,6 +275,9 @@
       });
 
 
+    },
+    nextStep() {
+        this.$emit('nextStep')
     }
   }
 </script>

+ 8 - 1
src/views/modules/kuaishouapp/groupCreate.vue

@@ -745,7 +745,14 @@
       filterOption(input, option) {
         return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
       },
-
+      nextStep() {
+        setTimeout(function () {
+          that.$emit('nextStep')
+        }, 1500)
+      },
+      prevStep() {
+        this.$emit('prevStep')
+      }
     },
     created: function () {
       let params = {};

+ 168 - 168
src/views/system/modules/DepartWindow.vue

@@ -1,169 +1,169 @@
-<template>
-  <a-modal
-    :width="modalWidth"
-    :visible="visible"
-    title="部门搜索"
-    :confirmLoading="confirmLoading"
-    @ok="handleSubmit"
-    @cancel="handleCancel"
-    cancelText="关闭"
-    wrapClassName="ant-modal-cust-warp"
-  >
-    <!--部门树-->
-    <template>
-      <a-form :form="form">
-        <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="上级部门">
-          <a-tree
-            multiple
-            treeCheckable="tree"
-            checkable
-            :checkedKeys="checkedKeys"
-            allowClear="true"
-            :checkStrictly="true"
-            @check="onCheck"
-            :dropdownStyle="{maxHeight:'200px',overflow:'auto'}"
-            :treeData="departTree"
-            placeholder="请选择上级部门"
-          >
-          </a-tree>
-        </a-form-item>
-      </a-form>
-    </template>
-  </a-modal>
-</template>
-
-<script>
-  import pick from 'lodash.pick'
-  import {getAction} from '@/api/manage'
-  import {queryIdTree} from '@/api/api'
-  import userModal from './UserModal'
-
-  export default {
-    name: "DepartWindow",
-    components: {
-      userModal,
-    },
-    data() {
-      return {
-        checkedKeys: [], // 存储选中的部门id
-        userId: "", // 存储用户id
-        model: {}, // 存储SysUserDepartsVO表
-        userDepartModel: {userId: '', departIdList: []}, // 存储用户id一对多部门信息的对象
-        departList: [], // 存储部门信息
-        modalWidth: 400,
-        departTree: [],
-        title: "操作",
-        visible: false,
-        labelCol: {
-          xs: {span: 24},
-          sm: {span: 5},
-        },
-        wrapperCol: {
-          xs: {span: 24},
-          sm: {span: 16},
-        },
-        confirmLoading: false,
-        headers: {},
-        form: this.$form.createForm(this),
-        url: {
-          userId: "/sys/user/generateUserId", // 引入生成添加用户情况下的url
-        },
-      }
-    },
-    methods: {
-      add(checkedDepartKeys, userId) {
-        this.checkedKeys = checkedDepartKeys;
-        this.userId = userId;
-        this.edit({});
-      },
-      edit(record) {
-        this.departList = [];
-        this.queryDepartTree();
-        this.form.resetFields();
-        this.visible = true;
-        this.model = Object.assign({}, record);
-        let filedsVal = pick(this.model, 'id', 'userId', 'departIdList');
-        this.$nextTick(() => {
-          this.form.setFieldsValue(filedsVal);
-        });
-      },
-      close() {
-        this.$emit('close');
-        this.visible = false;
-        this.departList = [];
-        this.checkedKeys = [];
-      },
-      handleSubmit() {
-        const that = this;
-        // 触发表单验证
-        this.form.validateFields((err) => {
-          if (!err) {
-            that.confirmLoading = true;
-            if (this.userId == null) {
-              getAction(this.url.userId).then((res) => {
-                if (res.success) {
-                  let formData = {
-                    userId: res.result,
-                    departIdList: this.departList
-                  }
-                  console.log(formData)
-                  that.$emit('ok', formData);
-                }
-              }).finally(() => {
-                that.departList = [];
-                that.confirmLoading = false;
-                that.close();
-              })
-            } else {
-              let formData = {
-                userId: this.userId,
-                departIdList: this.departList
-              }
-              console.log(formData)
-              that.departList = [];
-              that.$emit('ok', formData);
-              that.confirmLoading = false;
-              that.close();
-            }
-          }
-        })
-      },
-      handleCancel() {
-        this.close()
-      },
-
-      // 选择部门时作用的API
-      onCheck(checkedKeys, info) {
-        this.departList = [];
-        this.checkedKeys = checkedKeys.checked;
-        let checkedNodes = info.checkedNodes;
-        for (let i = 0; i < checkedNodes.length; i++) {
-          let de = checkedNodes[i].data.props;
-          let depart = {key: "", value: "", title: ""};
-          depart.key = de.value;
-          depart.value = de.value;
-          depart.title = de.title;
-          this.departList.push(depart);
-        }
-        console.log('onCheck', checkedKeys, info);
-      },
-      queryDepartTree() {
-        queryIdTree().then((res) => {
-          if (res.success) {
-            this.departTree = res.result;
-          }
-        })
-      },
-      modalFormOk() {
-
-      }
-    },
-  }
-</script>
-
-<style scoped>
-  .ant-table-tbody .ant-table-row td {
-    padding-top: 10px;
-    padding-bottom: 10px;
-  }
+<template>
+  <a-modal
+    :width="modalWidth"
+    :visible="visible"
+    title="部门搜索"
+    :confirmLoading="confirmLoading"
+    @ok="handleSubmit"
+    @cancel="handleCancel"
+    cancelText="关闭"
+    wrapClassName="ant-modal-cust-warp"
+  >
+    <!--部门树-->
+    <template>
+      <a-form :form="form">
+        <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="上级部门">
+          <a-tree
+            multiple
+            treeCheckable="tree"
+            checkable
+            :checkedKeys="checkedKeys"
+            allowClear="true"
+            :checkStrictly="true"
+            @check="onCheck"
+            :dropdownStyle="{maxHeight:'200px',overflow:'auto'}"
+            :treeData="departTree"
+            placeholder="请选择上级部门"
+          >
+          </a-tree>
+        </a-form-item>
+      </a-form>
+    </template>
+  </a-modal>
+</template>
+
+<script>
+  import pick from 'lodash.pick'
+  import {getAction} from '@/api/manage'
+  import {queryIdTree} from '@/api/api'
+  import userModal from './UserModal'
+
+  export default {
+    name: "DepartWindow",
+    components: {
+      userModal,
+    },
+    data() {
+      return {
+        checkedKeys: [], // 存储选中的部门id
+        userId: "", // 存储用户id
+        model: {}, // 存储SysUserDepartsVO表
+        userDepartModel: {userId: '', departIdList: []}, // 存储用户id一对多部门信息的对象
+        departList: [], // 存储部门信息
+        modalWidth: 400,
+        departTree: [],
+        title: "操作",
+        visible: false,
+        labelCol: {
+          xs: {span: 24},
+          sm: {span: 5},
+        },
+        wrapperCol: {
+          xs: {span: 24},
+          sm: {span: 16},
+        },
+        confirmLoading: false,
+        headers: {},
+        form: this.$form.createForm(this),
+        url: {
+          userId: "/sys/user/generateUserId", // 引入生成添加用户情况下的url
+        },
+      }
+    },
+    methods: {
+      add(checkedDepartKeys, userId) {
+        this.checkedKeys = checkedDepartKeys;
+        this.userId = userId;
+        this.edit({});
+      },
+      edit(record) {
+        this.departList = [];
+        this.queryDepartTree();
+        this.form.resetFields();
+        this.visible = true;
+        this.model = Object.assign({}, record);
+        let filedsVal = pick(this.model, 'id', 'userId', 'departIdList');
+        this.$nextTick(() => {
+          this.form.setFieldsValue(filedsVal);
+        });
+      },
+      close() {
+        this.$emit('close');
+        this.visible = false;
+        this.departList = [];
+        this.checkedKeys = [];
+      },
+      handleSubmit() {
+        const that = this;
+        // 触发表单验证
+        this.form.validateFields((err) => {
+          if (!err) {
+            that.confirmLoading = true;
+            if (this.userId == null) {
+              getAction(this.url.userId).then((res) => {
+                if (res.success) {
+                  let formData = {
+                    userId: res.result,
+                    departIdList: this.departList
+                  }
+                  console.log(formData)
+                  that.$emit('ok', formData);
+                }
+              }).finally(() => {
+                that.departList = [];
+                that.confirmLoading = false;
+                that.close();
+              })
+            } else {
+              let formData = {
+                userId: this.userId,
+                departIdList: this.departList
+              }
+              console.log(formData)
+              that.departList = [];
+              that.$emit('ok', formData);
+              that.confirmLoading = false;
+              that.close();
+            }
+          }
+        })
+      },
+      handleCancel() {
+        this.close()
+      },
+
+      // 选择部门时作用的API
+      onCheck(checkedKeys, info) {
+        this.departList = [];
+        this.checkedKeys = checkedKeys.checked;
+        let checkedNodes = info.checkedNodes;
+        for (let i = 0; i < checkedNodes.length; i++) {
+          let de = checkedNodes[i].data.props;
+          let depart = {key: "", value: "", title: ""};
+          depart.key = de.value;
+          depart.value = de.value;
+          depart.title = de.title;
+          this.departList.push(depart);
+        }
+        console.log('onCheck', checkedKeys, info);
+      },
+      queryDepartTree() {
+        queryIdTree().then((res) => {
+          if (res.success) {
+            this.departTree = res.result;
+          }
+        })
+      },
+      modalFormOk() {
+
+      }
+    },
+  }
+</script>
+
+<style scoped>
+  .ant-table-tbody .ant-table-row td {
+    padding-top: 10px;
+    padding-bottom: 10px;
+  }
 </style>

File diff ditekan karena terlalu besar
+ 553 - 553
src/views/system/modules/UserModal.vue


+ 1 - 1
src/views/template/creative/modules/material.vue

@@ -32,7 +32,7 @@
           :numberStyle="{backgroundColor: '#52c41a'} "
         >
           <a-radio-button value="CREATIVE_IMAGE_MODE_SMALL">小图</a-radio-button>
-        </a-badge>
+        </a-badge> 
         <a-badge
           :count="HorizontalLargeImageListBigShu.length"
           :numberStyle="{backgroundColor: '#52c41a'} "

+ 2 - 2
vue.config.js

@@ -64,8 +64,8 @@ module.exports = {
          }
        },*/
       '/jeecg-boot': {
-        // target: 'http://39.97.120.42:8080', //请求本地 需要jeecg-boot后台项目  生产环境
-        target: 'http://39.106.184.70:8080', //请求本地 需要jeecg-boot后台项目
+        target: 'http://39.97.120.42:8080', //请求本地 需要jeecg-boot后台项目  生产环境
+        // target: 'http://39.106.184.70:8080', //请求本地 需要jeecg-boot后台项目
         // target: 'http://192.168.2.130:8080', //请求本地 需要jeecg-boot后台项目  蒙蒙
         // target: 'http://192.168.2.132:8080', //请求本地 需要jeecg-boot后台项目
         ws: false,