Browse Source

Merge remote-tracking branch 'origin/test' into test

syh 5 years ago
parent
commit
6f783ef457

+ 14 - 5
babel.config.js

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

+ 3 - 0
package.json

@@ -25,6 +25,7 @@
     "codemirror": "^5.46.0",
     "dayjs": "^1.8.0",
     "echarts": "^4.3.0",
+    "element-ui": "^2.13.0",
     "enquire.js": "^2.1.6",
     "html2canvas": "^1.0.0-rc.3",
     "iview": "2.0.0-rc.17",
@@ -62,11 +63,13 @@
   },
   "devDependencies": {
     "@babel/polyfill": "^7.2.5",
+    "@babel/preset-env": "^7.7.7",
     "@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",
+    "babel-plugin-component": "^1.1.1",
     "eslint": "^5.16.0",
     "eslint-plugin-vue": "^5.1.0",
     "html-webpack-plugin": "^3.2.0",

+ 117 - 117
src/components/AvatarList/List.vue

@@ -1,118 +1,118 @@
-<!--
-<template>
-  <div :class="[prefixCls]">
-    <ul>
-      <slot></slot>
-      <template v-for="item in filterEmpty($slots.default).slice(0, 3)"></template>
-
-
-      <template v-if="maxLength > 0 && filterEmpty($slots.default).length > maxLength">
-        <avatar-item :size="size">
-          <avatar :size="size !== 'mini' && size || 20" :style="excessItemsStyle">{{ `+${maxLength}` }}</avatar>
-        </avatar-item>
-      </template>
-    </ul>
-  </div>
-</template>
--->
-
-<script>
-  import Avatar from 'ant-design-vue/es/avatar'
-  import AvatarItem from './Item'
-  import {filterEmpty} from '@/components/_util/util'
-
-  export default {
-    AvatarItem,
-    name: "AvatarList",
-    components: {
-      Avatar,
-      AvatarItem
-    },
-    props: {
-      prefixCls: {
-        type: String,
-        default: 'ant-pro-avatar-list'
-      },
-      /**
-       * 头像大小 类型: large、small 、mini, default
-       * 默认值: default
-       */
-      size: {
-        type: [String, Number],
-        default: 'default'
-      },
-      /**
-       * 要显示的最大项目
-       */
-      maxLength: {
-        type: Number,
-        default: 0
-      },
-      /**
-       * 多余的项目风格
-       */
-      excessItemsStyle: {
-        type: Object,
-        default: () => {
-          return {
-            color: '#f56a00',
-            backgroundColor: '#fde3cf'
-          }
-        }
-      }
-    },
-    data() {
-      return {}
-    },
-    methods: {
-      getItems(items) {
-        const classString = {
-          [`${this.prefixCls}-item`]: true,
-          [`${this.size}`]: true
-        }
-
-        if (this.maxLength > 0) {
-          items = items.slice(0, this.maxLength)
-          items.push(( < Avatar
-          size = {this.size}
-          style = {this.excessItemsStyle} > {`+${this.maxLength}`
-        }<
-          /Avatar>))
-        }
-        const itemList = items.map((item) => (
-          < li
-      class
-        = {classString} > {item} < /li>
-      ))
-        return itemList
-      }
-    },
-    render() {
-      const {prefixCls, size} = this.$props
-      const classString = {
-        [`${prefixCls}`]: true,
-        [`${size}`]: true,
-      }
-      const items = filterEmpty(this.$slots.default)
-      const itemsDom = items && items.length ?
-    <
-      ul
-    class
-      = {`${prefixCls}-items`
-    }>
-      {
-        this.getItems(items)
-      }
-    <
-      /ul> : null
-
-      return (
-        < div
-    class
-      = {classString} >
-        {itemsDom}
-        < /div>
-    )
-    }
-  }
+<!--
+<template>
+  <div :class="[prefixCls]">
+    <ul>
+      <slot></slot>
+      <template v-for="item in filterEmpty($slots.default).slice(0, 3)"></template>
+
+
+      <template v-if="maxLength > 0 && filterEmpty($slots.default).length > maxLength">
+        <avatar-item :size="size">
+          <avatar :size="size !== 'mini' && size || 20" :style="excessItemsStyle">{{ `+${maxLength}` }}</avatar>
+        </avatar-item>
+      </template>
+    </ul>
+  </div>
+</template>
+-->
+
+<script>
+  import Avatar from 'ant-design-vue/es/avatar'
+  import AvatarItem from './Item'
+  import {filterEmpty} from '@/components/_util/util'
+
+  export default {
+    AvatarItem,
+    name: "AvatarList",
+    components: {
+      Avatar,
+      AvatarItem
+    },
+    props: {
+      prefixCls: {
+        type: String,
+        default: 'ant-pro-avatar-list'
+      },
+      /**
+       * 头像大小 类型: large、small 、mini, default
+       * 默认值: default
+       */
+      size: {
+        type: [String, Number],
+        default: 'default'
+      },
+      /**
+       * 要显示的最大项目
+       */
+      maxLength: {
+        type: Number,
+        default: 0
+      },
+      /**
+       * 多余的项目风格
+       */
+      excessItemsStyle: {
+        type: Object,
+        default: () => {
+          return {
+            color: '#f56a00',
+            backgroundColor: '#fde3cf'
+          }
+        }
+      }
+    },
+    data() {
+      return {}
+    },
+    methods: {
+      getItems(items) {
+        const classString = {
+          [`${this.prefixCls}-item`]: true,
+          [`${this.size}`]: true
+        }
+
+        if (this.maxLength > 0) {
+          items = items.slice(0, this.maxLength)
+          items.push(( < Avatar
+          size = {this.size}
+          style = {this.excessItemsStyle} > {`+${this.maxLength}`
+        }<
+          /Avatar>))
+        }
+        const itemList = items.map((item) => (
+          < li
+      class
+        = {classString} > {item} < /li>
+      ))
+        return itemList
+      }
+    },
+    render() {
+      const {prefixCls, size} = this.$props
+      const classString = {
+        [`${prefixCls}`]: true,
+        [`${size}`]: true,
+      }
+      const items = filterEmpty(this.$slots.default)
+      const itemsDom = items && items.length ?
+    <
+      ul
+    class
+      = {`${prefixCls}-items`
+    }>
+      {
+        this.getItems(items)
+      }
+    <
+      /ul> : null
+
+      return (
+        < div
+    class
+      = {classString} >
+        {itemsDom}
+        < /div>
+    )
+    }
+  }
 </script>

+ 70 - 70
src/components/Ellipsis/Ellipsis.vue

@@ -1,71 +1,71 @@
-<script>
-  import Tooltip from 'ant-design-vue/es/tooltip'
-  import {cutStrByFullLength, getStrFullLength} from '@/components/_util/StringUtil'
-  /*
-    const isSupportLineClamp = document.body.style.webkitLineClamp !== undefined;
-
-    const TooltipOverlayStyle = {
-      overflowWrap: 'break-word',
-      wordWrap: 'break-word',
-    };
-  */
-
-  export default {
-    name: 'Ellipsis',
-    components: {
-      Tooltip
-    },
-    props: {
-      prefixCls: {
-        type: String,
-        default: 'ant-pro-ellipsis'
-      },
-      tooltip: {
-        type: Boolean
-      },
-      length: {
-        type: Number,
-        required: true
-      },
-      lines: {
-        type: Number,
-        default: 1
-      },
-      fullWidthRecognition: {
-        type: Boolean,
-        default: false
-      }
-    },
-    methods: {
-      getStrDom(str) {
-        return (
-          < span > {cutStrByFullLength(str, this.length
-      )
-        +'...'
-      }<
-        /span>
-      )
-      },
-      getTooltip(fullStr) {
-        return (
-          < Tooltip >
-          < template
-        slot = "title" > {fullStr} < /template>
-        {
-          this.getStrDom(fullStr)
-        }
-      <
-        /Tooltip>
-      )
-      }
-    },
-    render() {
-      const {tooltip, length} = this.$props
-      let str = this.$slots.default.map(vNode => vNode.text).join("")
-      const strDom = tooltip && getStrFullLength(str) > length ? this.getTooltip(str) : this.getStrDom(str);
-      return (
-        strDom
-      )
-    }
-  }
+<script>
+  import Tooltip from 'ant-design-vue/es/tooltip'
+  import {cutStrByFullLength, getStrFullLength} from '@/components/_util/StringUtil'
+  /*
+    const isSupportLineClamp = document.body.style.webkitLineClamp !== undefined;
+
+    const TooltipOverlayStyle = {
+      overflowWrap: 'break-word',
+      wordWrap: 'break-word',
+    };
+  */
+
+  export default {
+    name: 'Ellipsis',
+    components: {
+      Tooltip
+    },
+    props: {
+      prefixCls: {
+        type: String,
+        default: 'ant-pro-ellipsis'
+      },
+      tooltip: {
+        type: Boolean
+      },
+      length: {
+        type: Number,
+        required: true
+      },
+      lines: {
+        type: Number,
+        default: 1
+      },
+      fullWidthRecognition: {
+        type: Boolean,
+        default: false
+      }
+    },
+    methods: {
+      getStrDom(str) {
+        return (
+          < span > {cutStrByFullLength(str, this.length
+      )
+        +'...'
+      }<
+        /span>
+      )
+      },
+      getTooltip(fullStr) {
+        return (
+          < Tooltip >
+          < template
+        slot = "title" > {fullStr} < /template>
+        {
+          this.getStrDom(fullStr)
+        }
+      <
+        /Tooltip>
+      )
+      }
+    },
+    render() {
+      const {tooltip, length} = this.$props
+      let str = this.$slots.default.map(vNode => vNode.text).join("")
+      const strDom = tooltip && getStrFullLength(str) > length ? this.getTooltip(str) : this.getStrDom(str);
+      return (
+        strDom
+      )
+    }
+  }
 </script>

+ 3 - 2
src/components/layouts/TabLayout.vue

@@ -80,7 +80,7 @@
       this.linkList.push(this.$route.fullPath)
       this.activePage = this.$route.fullPath
 
-      if(!this.linkList.includes("/account/StepForm")){
+      if(!this.linkList.includes("/account/stepForm")){
           localStorage.removeItem("step")
       }
     },
@@ -119,6 +119,7 @@
         this[action](key)
       },
       remove(key) {
+          console.log(key)
         if (key == indexKey) {
           this.$message.warning('首页不能关闭!')
           return
@@ -131,7 +132,7 @@
             localStorage.removeItem("advertisingGroup")
             localStorage.removeItem("advertisingGroupKey")
         }
-        if(key == "/account/StepForm"){
+        if(key == "/account/stepForm"){
             localStorage.removeItem("step")
         }
         if(key == "/account/originality"){

+ 233 - 233
src/components/menu/index.js

@@ -1,233 +1,233 @@
-import Menu from 'ant-design-vue/es/menu'
-import Icon from 'ant-design-vue/es/icon'
-
-const {Item, SubMenu} = Menu
-
-export default {
-  name: 'SMenu',
-  props: {
-    menu: {
-      type: Array,
-      required: true
-    },
-    theme: {
-      type: String,
-      required: false,
-      default: 'dark'
-    },
-    mode: {
-      type: String,
-      required: false,
-      default: 'inline'
-    },
-    collapsed: {
-      type: Boolean,
-      required: false,
-      default: false
-    }
-  },
-  data() {
-    return {
-      openKeys: [],
-      selectedKeys: [],
-      cachedOpenKeys: []
-    }
-  },
-  computed: {
-    rootSubmenuKeys: vm => {
-      const keys = []
-      vm.menu.forEach(item => keys.push(item.path))
-      return keys
-    }
-  },
-  mounted() {
-    this.updateMenu()
-  },
-  watch: {
-    collapsed(val) {
-      if (val) {
-        this.cachedOpenKeys = this.openKeys.concat()
-        this.openKeys = []
-      } else {
-        this.openKeys = this.cachedOpenKeys
-      }
-    },
-    $route: function () {
-      this.updateMenu()
-    }
-  },
-  methods: {
-    // select menu item
-    onOpenChange(openKeys) {
-
-      // 在水平模式下时执行,并且不再执行后续
-      if (this.mode === 'horizontal') {
-        this.openKeys = openKeys
-        return
-      }
-      // 非水平模式时
-      const latestOpenKey = openKeys.find(key => !this.openKeys.includes(key))
-      if (!this.rootSubmenuKeys.includes(latestOpenKey)) {
-        this.openKeys = openKeys
-      } else {
-        this.openKeys = latestOpenKey ? [latestOpenKey] : []
-      }
-    },
-    updateMenu() {
-      const routes = this.$route.matched.concat()
-      const {hidden} = this.$route.meta
-      if (routes.length >= 3 && hidden) {
-        routes.pop()
-        this.selectedKeys = [routes[routes.length - 1].path]
-      } else {
-        this.selectedKeys = [routes.pop().path]
-      }
-      const openKeys = []
-      if (this.mode === 'inline') {
-        routes.forEach(item => {
-          openKeys.push(item.path)
-        })
-      }
-      //update-begin-author:taoyan date:20190510 for:online表单菜单点击展开的一级目录不对
-      if (!this.selectedKeys || this.selectedKeys[0].indexOf(":") < 0) {
-        this.collapsed ? (this.cachedOpenKeys = openKeys) : (this.openKeys = openKeys)
-      }
-      //update-end-author:taoyan date:20190510 for:online表单菜单点击展开的一级目录不对
-    },
-
-    // render
-    renderItem(menu) {
-      if (!menu.hidden) {
-        return menu.children && !menu.alwaysShow ? this.renderSubMenu(menu) : this.renderMenuItem(menu)
-      }
-      return null
-    },
-    renderMenuItem(menu) {
-      const target = menu.meta.target || null
-      const tag = target && 'a' || 'router-link'
-      let props = {to: {name: menu.name}}
-      if (menu.route && menu.route === '0') {
-        props = {to: {path: menu.path}}
-      }
-
-      const attrs = {href: menu.path, target: menu.meta.target}
-
-      if (menu.children && menu.alwaysShow) {
-        // 把有子菜单的 并且 父菜单是要隐藏子菜单的
-        // 都给子菜单增加一个 hidden 属性
-        // 用来给刷新页面时, selectedKeys 做控制用
-        menu.children.forEach(item => {
-          item.meta = Object.assign(item.meta, {hidden: true})
-        })
-      }
-
-      return (
-        < Item
-      {...
-        {
-          key: menu.path
-        }
-      }
-    >
-    <
-      tag
-      {...
-        {
-          props, attrs
-        }
-      }
-    >
-      {
-        this.renderIcon(menu.meta.icon)
-      }
-    <
-      span > {menu.meta.title} < /span>
-      < /tag>
-      < /Item>
-    )
-    },
-    renderSubMenu(menu) {
-      const itemArr = []
-      if (!menu.alwaysShow) {
-        menu.children.forEach(item => itemArr.push(this.renderItem(item)))
-      }
-      return (
-        < SubMenu
-      {...
-        {
-          key: menu.path
-        }
-      }
-    >
-    <
-      span
-      slot = "title" >
-        {this.renderIcon(menu.meta.icon)}
-        < span > {menu.meta.title} < /span>
-        < /span>
-      {
-        itemArr
-      }
-    <
-      /SubMenu>
-    )
-    },
-    renderIcon(icon) {
-      if (icon === 'none' || icon === undefined) {
-        return null
-      }
-      const props = {}
-      typeof (icon) === 'object' ? props.component = icon : props.type = icon
-      return (
-        < Icon
-      {...
-        {
-          props
-        }
-      }
-      />
-    )
-    }
-  },
-
-  render() {
-    const {mode, theme, menu} = this
-    const props = {
-      mode: mode,
-      theme: theme,
-      openKeys: this.openKeys
-    }
-    const on = {
-      select: obj => {
-        this.selectedKeys = obj.selectedKeys
-        this.$emit('select', obj)
-      },
-      openChange: this.onOpenChange
-    }
-
-    const menuTree = menu.map(item => {
-      if (item.hidden) {
-        return null
-      }
-      return this.renderItem(item)
-    })
-    // {...{ props, on: on }}
-    return (
-      < Menu
-    vModel = {this.selectedKeys}
-    {...
-      {
-        props, on
-      :
-        on
-      }
-    }
-  >
-    {
-      menuTree
-    }
-  <
-    /Menu>
-  )
-  }
-}
+import Menu from 'ant-design-vue/es/menu'
+import Icon from 'ant-design-vue/es/icon'
+
+const {Item, SubMenu} = Menu
+
+export default {
+  name: 'SMenu',
+  props: {
+    menu: {
+      type: Array,
+      required: true
+    },
+    theme: {
+      type: String,
+      required: false,
+      default: 'dark'
+    },
+    mode: {
+      type: String,
+      required: false,
+      default: 'inline'
+    },
+    collapsed: {
+      type: Boolean,
+      required: false,
+      default: false
+    }
+  },
+  data() {
+    return {
+      openKeys: [],
+      selectedKeys: [],
+      cachedOpenKeys: []
+    }
+  },
+  computed: {
+    rootSubmenuKeys: vm => {
+      const keys = []
+      vm.menu.forEach(item => keys.push(item.path))
+      return keys
+    }
+  },
+  mounted() {
+    this.updateMenu()
+  },
+  watch: {
+    collapsed(val) {
+      if (val) {
+        this.cachedOpenKeys = this.openKeys.concat()
+        this.openKeys = []
+      } else {
+        this.openKeys = this.cachedOpenKeys
+      }
+    },
+    $route: function () {
+      this.updateMenu()
+    }
+  },
+  methods: {
+    // select menu item
+    onOpenChange(openKeys) {
+
+      // 在水平模式下时执行,并且不再执行后续
+      if (this.mode === 'horizontal') {
+        this.openKeys = openKeys
+        return
+      }
+      // 非水平模式时
+      const latestOpenKey = openKeys.find(key => !this.openKeys.includes(key))
+      if (!this.rootSubmenuKeys.includes(latestOpenKey)) {
+        this.openKeys = openKeys
+      } else {
+        this.openKeys = latestOpenKey ? [latestOpenKey] : []
+      }
+    },
+    updateMenu() {
+      const routes = this.$route.matched.concat()
+      const {hidden} = this.$route.meta
+      if (routes.length >= 3 && hidden) {
+        routes.pop()
+        this.selectedKeys = [routes[routes.length - 1].path]
+      } else {
+        this.selectedKeys = [routes.pop().path]
+      }
+      const openKeys = []
+      if (this.mode === 'inline') {
+        routes.forEach(item => {
+          openKeys.push(item.path)
+        })
+      }
+      //update-begin-author:taoyan date:20190510 for:online表单菜单点击展开的一级目录不对
+      if (!this.selectedKeys || this.selectedKeys[0].indexOf(":") < 0) {
+        this.collapsed ? (this.cachedOpenKeys = openKeys) : (this.openKeys = openKeys)
+      }
+      //update-end-author:taoyan date:20190510 for:online表单菜单点击展开的一级目录不对
+    },
+
+    // render
+    renderItem(menu) {
+      if (!menu.hidden) {
+        return menu.children && !menu.alwaysShow ? this.renderSubMenu(menu) : this.renderMenuItem(menu)
+      }
+      return null
+    },
+    renderMenuItem(menu) {
+      const target = menu.meta.target || null
+      const tag = target && 'a' || 'router-link'
+      let props = {to: {name: menu.name}}
+      if (menu.route && menu.route === '0') {
+        props = {to: {path: menu.path}}
+      }
+
+      const attrs = {href: menu.path, target: menu.meta.target}
+
+      if (menu.children && menu.alwaysShow) {
+        // 把有子菜单的 并且 父菜单是要隐藏子菜单的
+        // 都给子菜单增加一个 hidden 属性
+        // 用来给刷新页面时, selectedKeys 做控制用
+        menu.children.forEach(item => {
+          item.meta = Object.assign(item.meta, {hidden: true})
+        })
+      }
+
+      return (
+        < Item
+      {...
+        {
+          key: menu.path
+        }
+      }
+    >
+    <
+      tag
+      {...
+        {
+          props, attrs
+        }
+      }
+    >
+      {
+        this.renderIcon(menu.meta.icon)
+      }
+    <
+      span > {menu.meta.title} < /span>
+      < /tag>
+      < /Item>
+    )
+    },
+    renderSubMenu(menu) {
+      const itemArr = []
+      if (!menu.alwaysShow) {
+        menu.children.forEach(item => itemArr.push(this.renderItem(item)))
+      }
+      return (
+        < SubMenu
+      {...
+        {
+          key: menu.path
+        }
+      }
+    >
+    <
+      span
+      slot = "title" >
+        {this.renderIcon(menu.meta.icon)}
+        < span > {menu.meta.title} < /span>
+        < /span>
+      {
+        itemArr
+      }
+    <
+      /SubMenu>
+    )
+    },
+    renderIcon(icon) {
+      if (icon === 'none' || icon === undefined) {
+        return null
+      }
+      const props = {}
+      typeof (icon) === 'object' ? props.component = icon : props.type = icon
+      return (
+        < Icon
+      {...
+        {
+          props
+        }
+      }
+      />
+    )
+    }
+  },
+
+  render() {
+    const {mode, theme, menu} = this
+    const props = {
+      mode: mode,
+      theme: theme,
+      openKeys: this.openKeys
+    }
+    const on = {
+      select: obj => {
+        this.selectedKeys = obj.selectedKeys
+        this.$emit('select', obj)
+      },
+      openChange: this.onOpenChange
+    }
+
+    const menuTree = menu.map(item => {
+      if (item.hidden) {
+        return null
+      }
+      return this.renderItem(item)
+    })
+    // {...{ props, on: on }}
+    return (
+      < Menu
+    vModel = {this.selectedKeys}
+    {...
+      {
+        props, on
+      :
+        on
+      }
+    }
+  >
+    {
+      menuTree
+    }
+  <
+    /Menu>
+  )
+  }
+}

+ 159 - 159
src/components/tools/DetailList.vue

@@ -1,160 +1,160 @@
-<template>
-  <div :class="['detail-list', size, layout === 'vertical' ? 'vertical': 'horizontal']">
-    <div v-if="title" class="title">{{ title }}</div>
-    <a-row>
-      <slot></slot>
-    </a-row>
-  </div>
-</template>
-
-<script>
-  import {Col} from 'ant-design-vue/es/grid/'
-
-  const Item = {
-    name: 'DetailListItem',
-    props: {
-      term: {
-        type: String,
-        default: '',
-        required: false
-      },
-    },
-    inject: {
-      col: {
-        type: Number
-      }
-    },
-    render() {
-      return (
-        < Col
-      {...
-        {
-          props: responsive[this.col]
-        }
-      }
-    >
-    <
-      div
-    class
-      = "term" > {this.$props.term} < /div>
-        < div
-    class
-      = "content" > {this.$slots.default} < /div>
-        < /Col>
-    )
-    }
-  }
-
-  const responsive = {
-    1: {xs: 24},
-    2: {xs: 24, sm: 12},
-    3: {xs: 24, sm: 12, md: 8},
-    4: {xs: 24, sm: 12, md: 6}
-  }
-
-  export default {
-    name: "DetailList",
-    Item: Item,
-    components: {
-      Col
-    },
-    props: {
-      title: {
-        type: String,
-        default: '',
-        required: false
-      },
-      col: {
-        type: Number,
-        required: false,
-        default: 3
-      },
-      size: {
-        type: String,
-        required: false,
-        default: 'large'
-      },
-      layout: {
-        type: String,
-        required: false,
-        default: 'horizontal'
-      }
-    },
-    provide() {
-      return {
-        col: this.col > 4 ? 4 : this.col
-      }
-    }
-  }
-</script>
-
-<style lang="scss">
-
-  .detail-list {
-
-    .title {
-      color: rgba(0, 0, 0, .85);
-      font-size: 14px;
-      font-weight: 500;
-      margin-bottom: 16px;
-    }
-
-    .term {
-      color: rgba(0, 0, 0, .85);
-      display: table-cell;
-      line-height: 20px;
-      margin-right: 8px;
-      padding-bottom: 16px;
-      white-space: nowrap;
-
-      &:after {
-        content: ":";
-        margin: 0 8px 0 2px;
-        position: relative;
-        top: -.5px;
-      }
-    }
-
-    .content {
-      color: rgba(0, 0, 0, .65);
-      display: table-cell;
-      line-height: 22px;
-      padding-bottom: 16px;
-      width: 100%;
-    }
-
-    &.small {
-
-      .title {
-        font-size: 14px;
-        color: rgba(0, 0, 0, .65);
-        font-weight: normal;
-        margin-bottom: 12px;
-      }
-
-      .term, .content {
-        padding-bottom: 8px;
-      }
-    }
-
-    &.large {
-      .term, .content {
-        padding-bottom: 16px;
-      }
-
-      .title {
-        font-size: 16px;
-      }
-    }
-
-    &.vertical {
-      .term {
-        padding-bottom: 8px;
-      }
-
-      .term, .content {
-        display: block;
-      }
-    }
-  }
+<template>
+  <div :class="['detail-list', size, layout === 'vertical' ? 'vertical': 'horizontal']">
+    <div v-if="title" class="title">{{ title }}</div>
+    <a-row>
+      <slot></slot>
+    </a-row>
+  </div>
+</template>
+
+<script>
+  import {Col} from 'ant-design-vue/es/grid/'
+
+  const Item = {
+    name: 'DetailListItem',
+    props: {
+      term: {
+        type: String,
+        default: '',
+        required: false
+      },
+    },
+    inject: {
+      col: {
+        type: Number
+      }
+    },
+    render() {
+      return (
+        < Col
+      {...
+        {
+          props: responsive[this.col]
+        }
+      }
+    >
+    <
+      div
+    class
+      = "term" > {this.$props.term} < /div>
+        < div
+    class
+      = "content" > {this.$slots.default} < /div>
+        < /Col>
+    )
+    }
+  }
+
+  const responsive = {
+    1: {xs: 24},
+    2: {xs: 24, sm: 12},
+    3: {xs: 24, sm: 12, md: 8},
+    4: {xs: 24, sm: 12, md: 6}
+  }
+
+  export default {
+    name: "DetailList",
+    Item: Item,
+    components: {
+      Col
+    },
+    props: {
+      title: {
+        type: String,
+        default: '',
+        required: false
+      },
+      col: {
+        type: Number,
+        required: false,
+        default: 3
+      },
+      size: {
+        type: String,
+        required: false,
+        default: 'large'
+      },
+      layout: {
+        type: String,
+        required: false,
+        default: 'horizontal'
+      }
+    },
+    provide() {
+      return {
+        col: this.col > 4 ? 4 : this.col
+      }
+    }
+  }
+</script>
+
+<style lang="scss">
+
+  .detail-list {
+
+    .title {
+      color: rgba(0, 0, 0, .85);
+      font-size: 14px;
+      font-weight: 500;
+      margin-bottom: 16px;
+    }
+
+    .term {
+      color: rgba(0, 0, 0, .85);
+      display: table-cell;
+      line-height: 20px;
+      margin-right: 8px;
+      padding-bottom: 16px;
+      white-space: nowrap;
+
+      &:after {
+        content: ":";
+        margin: 0 8px 0 2px;
+        position: relative;
+        top: -.5px;
+      }
+    }
+
+    .content {
+      color: rgba(0, 0, 0, .65);
+      display: table-cell;
+      line-height: 22px;
+      padding-bottom: 16px;
+      width: 100%;
+    }
+
+    &.small {
+
+      .title {
+        font-size: 14px;
+        color: rgba(0, 0, 0, .65);
+        font-weight: normal;
+        margin-bottom: 12px;
+      }
+
+      .term, .content {
+        padding-bottom: 8px;
+      }
+    }
+
+    &.large {
+      .term, .content {
+        padding-bottom: 16px;
+      }
+
+      .title {
+        font-size: 16px;
+      }
+    }
+
+    &.vertical {
+      .term {
+        padding-bottom: 8px;
+      }
+
+      .term, .content {
+        display: block;
+      }
+    }
+  }
 </style>

+ 6 - 0
src/main.js

@@ -47,6 +47,12 @@ import vueBus from '@/utils/vueBus';
 import JeecgComponents from '@/components/jeecg/index'
 // import iView from 'iview'
 import '!style-loader!css-loader!less-loader!./theme/index.less'
+
+import ElementUI from 'element-ui';
+import 'element-ui/lib/theme-chalk/index.css';
+
+Vue.use(ElementUI);
+
 Vue.config.productionTip = false
 // Vue.use(iView)
 Vue.use(Storage, config.storageOptions)

+ 87 - 87
src/views/account/settings/Custom.vue

@@ -1,88 +1,88 @@
-<script>
-  import {colorList} from '@/components/tools/setting'
-  import ASwitch from 'ant-design-vue/es/switch'
-  import AList from "ant-design-vue/es/list"
-  import AListItem from "ant-design-vue/es/list/Item"
-  import {mixin} from '@/utils/mixin.js'
-
-  const Meta = AListItem.Meta
-
-  export default {
-    components: {
-      AListItem,
-      AList,
-      ASwitch,
-      Meta
-    },
-    mixins: [mixin],
-    data() {
-      return {}
-    },
-    filters: {
-      themeFilter(theme) {
-        const themeMap = {
-          'dark': '暗色',
-          'light': '白色'
-        }
-        return themeMap[theme]
-      },
-    },
-    methods: {
-      colorFilter(color) {
-        const c = colorList.filter(o => o.color === color)[0]
-        return c && c.key
-      },
-
-      onChange(checked) {
-        if (checked) {
-          this.$store.dispatch('ToggleTheme', 'dark')
-        } else {
-          this.$store.dispatch('ToggleTheme', 'light')
-        }
-      }
-    },
-    render() {
-      return (
-        < AList
-      itemLayout = "horizontal" >
-        < AListItem >
-        < Meta >
-        < a
-      slot = "title" > 风格配色 < /a>
-        < span
-      slot = "description" >
-        整体风格配色设置
-        < /span>
-        < /Meta>
-        < div
-      slot = "actions" >
-        < ASwitch
-      checkedChildren = "暗色"
-      unCheckedChildren = "白色"
-      defaultChecked = {this.navTheme === 'dark' && true || false}
-      onChange = {this.onChange}
-      />
-      < /div>
-      < /AListItem>
-      < AListItem >
-      < Meta >
-      < a
-      slot = "title" > 主题色 < /a>
-        < span
-      slot = "description" >
-        页面风格配色: <
-      a
-      domPropsInnerHTML = {this.colorFilter(this.primaryColor)}
-      />
-      < /span>
-      < /Meta>
-      < /AListItem>
-      < /AList>
-    )
-    }
-  }
-</script>
-
-<style scoped>
-
+<script>
+  import {colorList} from '@/components/tools/setting'
+  import ASwitch from 'ant-design-vue/es/switch'
+  import AList from "ant-design-vue/es/list"
+  import AListItem from "ant-design-vue/es/list/Item"
+  import {mixin} from '@/utils/mixin.js'
+
+  const Meta = AListItem.Meta
+
+  export default {
+    components: {
+      AListItem,
+      AList,
+      ASwitch,
+      Meta
+    },
+    mixins: [mixin],
+    data() {
+      return {}
+    },
+    filters: {
+      themeFilter(theme) {
+        const themeMap = {
+          'dark': '暗色',
+          'light': '白色'
+        }
+        return themeMap[theme]
+      },
+    },
+    methods: {
+      colorFilter(color) {
+        const c = colorList.filter(o => o.color === color)[0]
+        return c && c.key
+      },
+
+      onChange(checked) {
+        if (checked) {
+          this.$store.dispatch('ToggleTheme', 'dark')
+        } else {
+          this.$store.dispatch('ToggleTheme', 'light')
+        }
+      }
+    },
+    render() {
+      return (
+        < AList
+      itemLayout = "horizontal" >
+        < AListItem >
+        < Meta >
+        < a
+      slot = "title" > 风格配色 < /a>
+        < span
+      slot = "description" >
+        整体风格配色设置
+        < /span>
+        < /Meta>
+        < div
+      slot = "actions" >
+        < ASwitch
+      checkedChildren = "暗色"
+      unCheckedChildren = "白色"
+      defaultChecked = {this.navTheme === 'dark' && true || false}
+      onChange = {this.onChange}
+      />
+      < /div>
+      < /AListItem>
+      < AListItem >
+      < Meta >
+      < a
+      slot = "title" > 主题色 < /a>
+        < span
+      slot = "description" >
+        页面风格配色: <
+      a
+      domPropsInnerHTML = {this.colorFilter(this.primaryColor)}
+      />
+      < /span>
+      < /Meta>
+      < /AListItem>
+      < /AList>
+    )
+    }
+  }
+</script>
+
+<style scoped>
+
 </style>

+ 6 - 5
src/views/modules/Statistics/components/Treeselect.vue

@@ -16,7 +16,11 @@
       @select="update"
       @input="emitValue"
       :limit="2"
-      :limitText="(count)=>{return '隐藏'+count+'条'}"
+      :limitText="
+        count => {
+          return '隐藏' + count + '条'
+        }
+      "
       noChildrenText="该项目下暂无账号"
       noOptionsText="暂无项目"
     />
@@ -51,9 +55,7 @@ export default {
   },
   components: { Treeselect },
   watch: {
-    $route(n, o) {
-      console.log(n, o)
-    }
+    $route(n, o) {}
   },
   methods: {
     ...mapGetters(['nickname', 'avatar', 'userInfo']),
@@ -111,7 +113,6 @@ export default {
       //我参与的
       getAction('/ctop/projectMember/participateList', { userId: this.userInfo().id }).then(res => {
         if (res.code == 0) {
-          console.log(res.result)
           this.options = res.result.map(item => {
             return {
               id: item.projectId,

+ 130 - 57
src/views/modules/achievements/design.vue

@@ -3,16 +3,19 @@
   display: flex;
   justify-content: space-around;
 }
+.design .ant-table-middle tr.ant-table-expanded-row td > .ant-table-wrapper {
+  margin: -12px -9px -13px;
+}
 </style>
 <template>
   <div class="design">
     <a-row :gutter="24" style="margin-top:15px">
-      <a-col :sm="24" :md="12" :xl="8" :style="{ marginBottom: '24px' }">
-        <chart-card :loading="loading" title="有效数" :total="dataCount.waitAudit + ''">
+      <a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
+        <chart-card :loading="loading" title="有效数" :total="dataCount.effiVideoCount + ''">
           <a-tooltip title="指标说明" slot="action">
             <a-icon type="info-circle-o" />
           </a-tooltip>
-          <div>
+          <!-- <div>
             <trend flag="up" style="margin-right: 16px;">
               <span slot="term">周同比</span>
               12%
@@ -21,16 +24,16 @@
               <span slot="term">日同比</span>
               11%
             </trend>
-          </div>
+          </div> -->
           <template slot="footer"> </template>
         </chart-card>
       </a-col>
-      <a-col :sm="24" :md="12" :xl="8" :style="{ marginBottom: '24px' }">
-        <chart-card :loading="loading" title="素材总数" :total="dataCount.passAudit + ''">
+      <a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
+        <chart-card :loading="loading" title="素材总数" :total="dataCount.videoCount + ''">
           <a-tooltip title="指标说明" slot="action">
             <a-icon type="info-circle-o" />
           </a-tooltip>
-          <div>
+          <!-- <div>
             <trend flag="up" style="margin-right: 16px;">
               <span slot="term">周同比</span>
               12%
@@ -39,24 +42,16 @@
               <span slot="term">日同比</span>
               11%
             </trend>
-          </div>
+          </div> -->
           <template slot="footer"> </template>
         </chart-card>
       </a-col>
-      <a-col :sm="24" :md="12" :xl="8" :style="{ marginBottom: '24px' }">
-        <chart-card
-          :loading="loading"
-          title="有效率"
-          :total="
-            dataCount.refuseAudit + dataCount.passAudit > 0
-              ? ((dataCount.passAudit / (dataCount.refuseAudit + dataCount.passAudit)) * 100).toFixed(2) + '%'
-              : '0%'
-          "
-        >
+      <a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
+        <chart-card :loading="loading" title="有效率" :total="dataCount.effiRate ? dataCount.effiRate + '%' : '0%'">
           <a-tooltip title="指标说明" slot="action">
             <a-icon type="info-circle-o" />
           </a-tooltip>
-          <div>
+          <!-- <div>
             <trend flag="up" style="margin-right: 16px;">
               <span slot="term">周同比</span>
               12%
@@ -65,7 +60,25 @@
               <span slot="term">日同比</span>
               11%
             </trend>
-          </div>
+          </div> -->
+          <template slot="footer"> </template>
+        </chart-card>
+      </a-col>
+      <a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
+        <chart-card :loading="loading" title="总消耗" :total="dataCount.cost + ''">
+          <a-tooltip title="指标说明" slot="action">
+            <a-icon type="info-circle-o" />
+          </a-tooltip>
+          <!-- <div>
+            <trend flag="up" style="margin-right: 16px;">
+              <span slot="term">周同比</span>
+              12%
+            </trend>
+            <trend flag="down">
+              <span slot="term">日同比</span>
+              11%
+            </trend>
+          </div> -->
           <template slot="footer"> </template>
         </chart-card>
       </a-col>
@@ -73,7 +86,12 @@
 
     <a-row :gutter="10" style="margin-top:10px">
       <a-col :span="24">
-        <a-card style="width:100%;">
+        <a-card
+          style="width:100%;"
+          :tabList="tabListNoTitle"
+          :activeTabKey="noTitleKey"
+          @tabChange="key => onTabChange(key, 'noTitleKey')"
+        >
           <a-table
             :columns="columns"
             :dataSource="dataList"
@@ -82,6 +100,13 @@
             size="middle"
             :pagination="false"
           >
+            <span slot-scope="text" slot="videoUrl">
+              <video class="video" :src="text" controls="controls" style="height:200px">
+                您的浏览器不支持 video 标签。
+              </video>
+            </span>
+            <a-table slot="expandedRowRender" :columns="innerColumns" :dataSource="innerData" :pagination="false">
+            </a-table>
           </a-table>
           <template class="ant-card-actions" slot="actions" v-if="dataList.length > 3">
             <div @click="getAll('visibleVideo')">查看更多</div>
@@ -93,7 +118,7 @@
       <a-col :span="8">
         <a-card :loading="loading" :bordered="false" title="当前可获得绩效" :style="{ marginTop: '24px' }">
           <div style="height:250px;text-align:center;line-height:230px;font-size:80px">
-            100
+            {{ dataCount.performance }}
           </div>
         </a-card>
       </a-col>
@@ -103,10 +128,8 @@
             <a-list itemLayout="horizontal" :dataSource="data">
               <a-list-item slot="renderItem" slot-scope="item, index">
                 <a-list-item-meta style="width:50%">
-                  <div slot="description">
-                    有效率
-                  </div>
-                  <a slot="title" href="https://vue.ant.design/">{{ item.title }}</a>
+                  <div slot="description">有效率{{ item.effiRate + '%' }}</div>
+                  <a slot="title" href="https://vue.ant.design/">{{ item.name }}</a>
                   <a-avatar slot="avatar" src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
                 </a-list-item-meta>
                 <div></div>
@@ -143,9 +166,7 @@
       <a-list itemLayout="horizontal" :dataSource="data">
         <a-list-item slot="renderItem" slot-scope="item, index">
           <a-list-item-meta style="width:50%">
-            <div slot="description">
-              有效率1%
-            </div>
+            <div slot="description">有效率{{ index }}%</div>
             <a slot="title" href="https://vue.ant.design/">{{ item.title }}</a>
             <a-avatar slot="avatar" src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
           </a-list-item-meta>
@@ -195,38 +216,32 @@ const columns = [
     dataIndex: 'videoUrl',
     key: 'videoUrl',
     align: 'center',
-    scopedSlots: { customRender: 'videoUrl' }
+    scopedSlots: { customRender: 'videoUrl' },
+    width: 200
   },
   {
     title: '素材跑量',
-    dataIndex: 'reviewDetail',
-    key: 'reviewDetail',
+    dataIndex: 'videoCost',
+    key: 'videoCost',
     align: 'center'
   },
   {
-    title: '投放平台',
-    dataIndex: 'reviewDetail',
-    key: 'reviewDetail',
+    title: '封面点击数',
+    dataIndex: 'pageClickCount',
+    key: 'pageClickCount',
     align: 'center'
   },
   {
-    title: '投放账户',
-    dataIndex: 'reviewDetail',
-    key: 'reviewDetail',
+    title: '封面曝光数',
+    dataIndex: 'pageExposureCount',
+    key: 'pageExposureCount',
     align: 'center'
   },
   {
-    title: '封面点击数',
-    dataIndex: 'reviewDetail',
-    key: 'reviewDetail',
+    title: '行为数',
+    dataIndex: 'behaviorCount',
+    key: 'behaviorCount',
     align: 'center'
-  },
-  {
-    title: '广告语',
-    dataIndex: 'description',
-    key: 'description',
-    align: 'center',
-    scopedSlots: { customRender: 'description' }
   }
 ]
 
@@ -255,21 +270,75 @@ export default {
       visitFields: ['ip', 'visit'],
       loading: false,
       rankList: [],
-      dataCount: {},
+      tabListNoTitle: [
+        {
+          key: 'kuaishou',
+          tab: '快手'
+        },
+        {
+          key: 'toutiao',
+          tab: '头条'
+        }
+      ],
+      noTitleKey: 'kuaishou',
+      dataCount: {
+        effiVideoCount: 70, //有效数
+        videoCount: 200, //素材总数
+        effiRate: 40, //有效率
+        performance: 20000, //当前绩效
+        cost: 20000 // 总消耗
+      },
       a: '',
       columns,
-      dataList: [],
-      data: [
+      dataList: [
+        {
+          key: 1,
+          videoUrl:
+            'https://ctop-media.oss-cn-beijing.aliyuncs.com/video/2019-12-14/%E9%AB%98%E6%B8%85-1576318874426.mp4',
+          videoCost: 34.56,
+          pageClickCount: 1200,
+          pageExposureCount: 3939,
+          behaviorCount: 5000
+        }
+      ],
+      innerColumns: [
         {
-          title: '人员1'
+          title: '素材账户',
+          dataIndex: 'videoAccount',
+          key: 'videoAccount',
+          align: 'center'
         },
         {
-          title: '人员2'
+          title: '投放账户',
+          dataIndex: 'servingAccount',
+          key: 'servingAccount',
+          align: 'center'
         },
         {
-          title: '人员3'
+          title: '跑量',
+          dataIndex: 'cost',
+          key: 'cost',
+          align: 'center'
         }
       ],
+      innerData: [
+        { key: 1, videoAccount: 'aabbcc', servingAccount: 'ttyyhh', cost: 34234.43 },
+        { key: 2, videoAccount: 'aabbcc', servingAccount: 'ttyyhh', cost: 34234.43 }
+      ],
+      data: [
+        // {
+        //   title: '人员1'
+        // },
+        // {
+        //   title: '人员2'
+        // },
+        // {
+        //   title: '人员3'
+        // },
+        { name: 'pipi', effiRate: 50 },
+        { name: 'pipixia', effiRate: 40 },
+        { name: 'pipiqiu', effiRate: 30 }
+      ],
       visible: false,
       visibleVideo: false
     }
@@ -285,12 +354,16 @@ export default {
     handleCancel(item) {
       console.log('Clicked cancel button')
       this[item] = false
+    },
+    onTabChange(key, type) {
+      console.log(key, type)
+      this[type] = key
     }
   },
   created() {
-    getAction('/ctop/materialInfo/report', { userId: this.userInfo().id }).then(res => {
-      this.dataCount = res
-    })
+    // getAction('/ctop/materialInfo/report', { userId: this.userInfo().id }).then(res => {
+    //   this.dataCount = res
+    // })
     //   /ctop/materialInfo/report
   }
 }

+ 349 - 0
src/views/modules/achievements/optimize.vue

@@ -0,0 +1,349 @@
+<style>
+.design .ant-list-item-content {
+  display: flex;
+  justify-content: space-around;
+}
+.design .ant-table-middle tr.ant-table-expanded-row td > .ant-table-wrapper {
+  margin: -12px -9px -13px;
+}
+</style>
+<template>
+  <div class="design">
+    <a-row :gutter="10" style="margin-top:10px">
+      <a-col :span="24">
+        <a-card
+          style="width:100%;"
+          :tabList="tabListNoTitle"
+          :activeTabKey="noTitleKey"
+          @tabChange="key => onTabChange(key, 'noTitleKey')"
+        >
+          媒体任务:{{ dataCount.mediaTask }}元
+          <a-row :gutter="24" style="margin-top:15px">
+            <a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
+              <chart-card
+                :loading="loading"
+                title="总消耗(元)"
+                :total="dataCount.totalCost + ''"
+                style="border: 1px solid #e8e8e8;"
+              >
+                <a-tooltip title="指标说明" slot="action">
+                  <a-icon type="info-circle-o" />
+                </a-tooltip>
+                <template slot="footer"> </template>
+              </chart-card>
+            </a-col>
+            <a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
+              <chart-card
+                :loading="loading"
+                title="季度任务(元)"
+                :total="dataCount.personalTask + ''"
+                style="border: 1px solid #e8e8e8;"
+              >
+                <a-tooltip title="指标说明" slot="action">
+                  <a-icon type="info-circle-o" />
+                </a-tooltip>
+                <template slot="footer"> </template>
+              </chart-card>
+            </a-col>
+            <a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
+              <chart-card
+                :loading="loading"
+                title="提点比例"
+                :total="dataCount.royaltyRatio ? dataCount.royaltyRatio : '0‰'"
+                style="border: 1px solid #e8e8e8;"
+              >
+                <a-tooltip title="指标说明" slot="action">
+                  <a-icon type="info-circle-o" />
+                </a-tooltip>
+                <template slot="footer"> </template>
+              </chart-card>
+            </a-col>
+            <a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
+              <chart-card
+                :loading="loading"
+                title="当前可获绩效"
+                :total="dataCount.totalRoyalty + ''"
+                style="border: 1px solid #e8e8e8;"
+              >
+                <a-tooltip title="指标说明" slot="action">
+                  <a-icon type="info-circle-o" />
+                </a-tooltip>
+                <template slot="footer"> </template>
+              </chart-card>
+            </a-col>
+          </a-row>
+          <a-table
+            :columns="columns"
+            :dataSource="dataList"
+            bordered
+            :loading="loading"
+            size="middle"
+            :pagination="false"
+          >
+            <span slot-scope="text" slot="videoUrl">
+              <video class="video" :src="text" controls="controls" style="height:200px">
+                您的浏览器不支持 video 标签。
+              </video>
+            </span>
+            <a-table slot="expandedRowRender" :columns="innerColumns" :dataSource="innerData" :pagination="false">
+            </a-table>
+          </a-table>
+          <template class="ant-card-actions" slot="actions" v-if="dataList.length > 3">
+            <div @click="getAll('visibleVideo')">查看更多</div>
+          </template>
+        </a-card>
+      </a-col>
+    </a-row>
+    <a-row :gutter="24">
+      <!-- <a-col :span="8">
+        <a-card :loading="loading" :bordered="false" title="当前可获得绩效" :style="{ marginTop: '24px' }">
+          <div style="height:250px;text-align:center;line-height:230px;font-size:80px">
+            {{ dataCount.performance }}
+          </div>
+        </a-card>
+      </a-col> -->
+      <a-col :span="24">
+        <a-card :loading="loading" :bordered="false" title="消耗排行" :style="{ marginTop: '24px' }">
+          <div style="height:200px">
+            <a-list itemLayout="horizontal" :dataSource="dataRanking">
+              <a-list-item slot="renderItem" slot-scope="item, index">
+                <a-list-item-meta style="width:50%">
+                  <div slot="description"></div>
+                  <a slot="title" style="font-size:16px"
+                    ><span style="display:inline-block;width:100px">{{ item.realName }}</span
+                    ><span style="margin-left:20px">总消耗:{{ item.totalCost }}</span></a
+                  >
+                  <a-avatar slot="avatar" src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
+                </a-list-item-meta>
+                <div></div>
+                <div style="text-align:center">
+                  <img
+                    v-if="index == 0"
+                    src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1576727589&di=a65392c20b9187cab794c2d5c0bb836b&imgtype=jpg&er=1&src=http%3A%2F%2F58pic.ooopic.com%2F58pic%2F12%2F83%2F98%2F42R58PICEnd.jpg"
+                    alt=""
+                    style="height:40px;"
+                  />
+                  <img
+                    v-if="index == 1"
+                    src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1576137652175&di=d648da94b779e32a96233faa7b6ae64b&imgtype=0&src=http%3A%2F%2Fwww.51pptmoban.com%2Fd%2Ffile%2F2017%2F05%2F31%2F14c7fdd5e99d7159b9fc21dbba2d5583.png"
+                    alt=""
+                    style="height:40px;"
+                  />
+                  <img
+                    v-if="index == 2"
+                    src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=748734891,2113250735&fm=26&gp=0.jpg"
+                    alt=""
+                    style="height:40px"
+                  />
+                </div>
+              </a-list-item>
+            </a-list>
+          </div>
+          <template class="ant-card-actions" slot="actions">
+            <div @click="getAll('visible')">查看更多</div>
+          </template>
+        </a-card>
+      </a-col>
+    </a-row>
+    <a-modal title="人员排名" :visible="visible" @ok="handleOk('visible')" @cancel="handleCancel('visible')">
+      <a-list itemLayout="horizontal" :dataSource="dataRanking">
+        <a-list-item slot="renderItem" slot-scope="item, index">
+          <a-list-item-meta style="width:50%">
+            {{ item }}
+            <div slot="description">总消耗:{{ item.totalCost }}</div>
+            <a slot="title" href="https://vue.ant.design/">{{ item.realName }}</a>
+            <a-avatar slot="avatar" src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
+          </a-list-item-meta>
+          <div></div>
+        </a-list-item>
+      </a-list>
+    </a-modal>
+    <a-modal
+      title="有效视频"
+      :visible="visibleVideo"
+      @ok="handleOk('visibleVideo')"
+      @cancel="handleCancel('visibleVideo')"
+    >
+      <a-table :columns="columns" :dataSource="dataList" bordered :loading="loading" size="middle" :pagination="false">
+      </a-table>
+    </a-modal>
+  </div>
+</template>
+
+<script>
+import ChartCard from '@/components/ChartCard'
+import ACol from 'ant-design-vue/es/grid/Col'
+import ATooltip from 'ant-design-vue/es/tooltip/Tooltip'
+import MiniArea from '@/components/chart/MiniArea'
+import MiniBar from '@/components/chart/MiniBar'
+import MiniProgress from '@/components/chart/MiniProgress'
+import RankList from '@/components/chart/RankList'
+import Bar from '@/components/chart/Bar'
+import LineChartMultid from '@/components/chart/LineChartMultid'
+import HeadInfo from '@/components/tools/HeadInfo.vue'
+
+import Trend from '@/components/Trend'
+
+import { getAction } from '@/api/manage'
+import { mapGetters } from 'vuex'
+const barData = []
+for (let i = 0; i < 12; i += 1) {
+  barData.push({
+    x: `${i + 1}月`,
+    y: Math.floor(Math.random() * 1000) + 200
+  })
+}
+
+const columns = [
+  {
+    title: '素材',
+    dataIndex: 'videoUrl',
+    key: 'videoUrl',
+    align: 'center',
+    scopedSlots: { customRender: 'videoUrl' },
+    width: 200
+  },
+  {
+    title: '素材跑量',
+    dataIndex: 'videoCost',
+    key: 'videoCost',
+    align: 'center'
+  },
+  {
+    title: '封面点击数',
+    dataIndex: 'pageClickCount',
+    key: 'pageClickCount',
+    align: 'center'
+  },
+  {
+    title: '封面曝光数',
+    dataIndex: 'pageExposureCount',
+    key: 'pageExposureCount',
+    align: 'center'
+  },
+  {
+    title: '行为数',
+    dataIndex: 'behaviorCount',
+    key: 'behaviorCount',
+    align: 'center'
+  }
+]
+
+export default {
+  name: 'design',
+  components: {
+    ATooltip,
+    ACol,
+    ChartCard,
+    MiniArea,
+    MiniBar,
+    MiniProgress,
+    RankList,
+    Bar,
+    Trend,
+    LineChartMultid,
+    HeadInfo
+  },
+
+  data: function() {
+    return {
+      title: '工作台',
+      loginfo: {},
+      barData,
+      visitInfo: [],
+      visitFields: ['ip', 'visit'],
+      loading: false,
+      rankList: [],
+      tabListNoTitle: [
+        {
+          key: 'kuaishou',
+          tab: '快手'
+        },
+        {
+          key: 'toutiao',
+          tab: '头条'
+        }
+      ],
+      noTitleKey: 'kuaishou',
+      dataCount: {
+        effiVideoCount: 70, //有效数
+        videoCount: 200, //素材总数
+        effiRate: 40, //有效率
+        performance: 20000, //当前绩效
+        cost: 20000 // 总消耗
+      },
+      a: '',
+      columns,
+      dataList: [
+        {
+          key: 1,
+          videoUrl:
+            'https://ctop-media.oss-cn-beijing.aliyuncs.com/video/2019-12-14/%E9%AB%98%E6%B8%85-1576318874426.mp4',
+          videoCost: 34.56,
+          pageClickCount: 1200,
+          pageExposureCount: 3939,
+          behaviorCount: 5000
+        }
+      ],
+      innerColumns: [
+        {
+          title: '素材账户',
+          dataIndex: 'videoAccount',
+          key: 'videoAccount',
+          align: 'center'
+        },
+        {
+          title: '投放账户',
+          dataIndex: 'servingAccount',
+          key: 'servingAccount',
+          align: 'center'
+        },
+        {
+          title: '跑量',
+          dataIndex: 'cost',
+          key: 'cost',
+          align: 'center'
+        }
+      ],
+      innerData: [
+        { key: 1, videoAccount: 'aabbcc', servingAccount: 'ttyyhh', cost: 34234.43 },
+        { key: 2, videoAccount: 'aabbcc', servingAccount: 'ttyyhh', cost: 34234.43 }
+      ],
+      dataRanking: [],
+      visible: false,
+      visibleVideo: false
+    }
+  },
+  methods: {
+    ...mapGetters(['nickname', 'avatar', 'userInfo']),
+    getAll(item) {
+      this[item] = true
+    },
+    handleOk(item) {
+      this[item] = false
+    },
+    handleCancel(item) {
+      console.log('Clicked cancel button')
+      this[item] = false
+    },
+    onTabChange(key, type) {
+      console.log(key, type)
+      this[type] = key
+    }
+  },
+  created() {
+    getAction('/ctop/performanceOptimizer/detail', { mediaType: 2 }).then(res => {
+      console.log(res)
+      this.dataCount = res.userDetail
+    })
+    getAction('/ctop/performanceOptimizer/ranking/list').then(res => {
+      console.log(res)
+      if (res.success) {
+        this.dataRanking.push(...res.data)
+      }
+    })
+
+    //   /ctop/materialInfo/report
+  }
+}
+</script>

+ 15 - 73
src/views/modules/advertiser/ProjectMemberList.vue

@@ -228,9 +228,19 @@ export default {
           dataIndex: 'projectName'
         },
         {
-          title: '成员',
+          title: '广告主名称',
           align: 'center',
-          dataIndex: 'userName'
+          dataIndex: 'advertiserName'
+        },
+        {
+          title: '运营负责人',
+          align: 'center',
+          dataIndex: 'responsibleName'
+        },
+        {
+          title: '设计负责人',
+          align: 'center',
+          dataIndex: 'designResponsibleName'
         },
         {
           title: '媒体类型',
@@ -323,7 +333,8 @@ export default {
         plane: '平面',
         admin: '管理员',
         operator: '运营专员',
-        kuaishouOperationManager: '快手运营经理'
+        kuaishouOperationManager: '快手运营经理',
+        designTeamLeader: '设计组长'
       }
 
       if (value) {
@@ -381,41 +392,7 @@ export default {
       this.loading = true
       getAction('/ctop/project/responsibleList', { userId: this.userInfo().id }).then(res => {
         if (res.code == 0) {
-          this.columns = [
-            {
-              title: '项目名称',
-              align: 'center',
-              dataIndex: 'projectName'
-            },
-            {
-              title: '广告主名称',
-              align: 'center',
-              dataIndex: 'advertiserName'
-            },
-            {
-              title: '管理人',
-              align: 'center',
-              dataIndex: 'responsibleName'
-            },
-            {
-              title: '媒体类型',
-              align: 'center',
-              dataIndex: 'mediaId',
-              scopedSlots: { customRender: 'mediaId' }
-            },
-            {
-              title: '最高出价',
-              align: 'center',
-              dataIndex: 'maxBid',
-              scopedSlots: { customRender: 'maxBid' }
-            },
-            {
-              title: '操作',
-              dataIndex: 'action',
-              align: 'center',
-              scopedSlots: { customRender: 'action' }
-            }
-          ]
+         
           this.dataSource = res.result
           this.dataElse = res.result
           this.loading = false
@@ -431,41 +408,6 @@ export default {
         if (res.code == 0) {
           this.dataSource = res.result
           this.dataElse = res.result
-          this.columns = [
-            {
-              title: '项目名称',
-              align: 'center',
-              dataIndex: 'projectName'
-            },
-            {
-              title: '广告主',
-              align: 'center',
-              dataIndex: 'advertiserName'
-            },
-            {
-              title: '管理者',
-              align: 'center',
-              dataIndex: 'responsibleName'
-            },
-            {
-              title: '媒体类型',
-              align: 'center',
-              dataIndex: 'mediaId',
-              scopedSlots: { customRender: 'mediaId' }
-            },
-            {
-              title: '最高出价',
-              align: 'center',
-              dataIndex: 'maxBid',
-              scopedSlots: { customRender: 'maxBid' }
-            },
-            {
-              title: '操作',
-              dataIndex: 'action',
-              align: 'center',
-              scopedSlots: { customRender: 'action' }
-            }
-          ]
           this.loading = false
         }
       })

+ 38 - 5
src/views/modules/advertiser/modules/ProjectModal.vue

@@ -29,7 +29,7 @@
         <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="最高出价">
           <a-input placeholder="请输入最高出价" v-decorator="['maxBid', validatorRules.maxBid]" addonAfter="元" />
         </a-form-item>
-        <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="负责人">
+        <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="运营负责人">
           <a-select
             showSearch
             optionFilterProp="children"
@@ -38,7 +38,26 @@
             @blur="handleBlur"
             @change="handleChange"
             :filterOption="filterOption"
-            v-model="resId"
+            v-decorator="['responsibleId', { rules: [{ required: true, message: '请选择运营负责人' }] }]"
+          >
+            <a-select-option
+              v-for="appModel in options"
+              :key="appModel.userId + new Date().getTime()"
+              :value="appModel.userId"
+              >{{ appModel.realName }}&#12288;&#12288;{{ appModel.roleName }}</a-select-option
+            >
+          </a-select>
+        </a-form-item>
+        <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="设计负责人">
+          <a-select
+            showSearch
+            optionFilterProp="children"
+            style="width: 100%"
+            @focus="handleFocus"
+            @blur="handleBlur"
+            @change="handleChange"
+            :filterOption="filterOption"
+            v-decorator="['designResponsibleId', { rules: [{ required: true, message: '请选择运营负责人' }] }]"
           >
             <a-select-option
               v-for="appModel in options"
@@ -96,6 +115,7 @@ export default {
       },
       list: [],
       resId: '',
+      shejiId: '',
       options: []
     }
   },
@@ -157,8 +177,20 @@ export default {
       this.model.maxBid = this.model.maxBid ? this.model.maxBid / 1000 : 0
       this.visible = true
       this.$nextTick(() => {
-        this.form.setFieldsValue(pick(this.model, 'projectName', 'advertiserId', 'responsibleName', 'maxBid', 'userId'))
-        this.resId = record.responsibleId
+        this.form.setFieldsValue(
+          pick(
+            this.model,
+            'projectName',
+            'advertiserId',
+            'responsibleName',
+            'maxBid',
+            'userId',
+            'designResponsibleId',
+            'responsibleId'
+          )
+        )
+        // this.resId = record.responsibleId
+        // this.shejiId = record.designResponsibleId
         getAction('/sys/user/getAllUserList', '').then(res => {
           console.log(res)
           if (res.success) {
@@ -193,7 +225,8 @@ export default {
           //时间格式化
           formData.advertiserId = data.key
           formData.advertiserName = data.label
-          formData.responsibleId = that.resId
+          formData.responsibleId = values.responsibleId
+          formData.designResponsibleId = values.designResponsibleId
           formData.userId = formData.userId ? formData.userId : that.userInfo().id
           httpAction(httpurl, formData, method)
             .then(res => {

+ 199 - 22
src/views/modules/kuaishouapp/account/accountIndex.vue

@@ -1,12 +1,15 @@
 <style>
-.account-statistics .ant-card-body .count {
+.account-index .ant-card-body .count {
   display: inline-block;
   height: 32px;
   line-height: 32px;
 }
+.account-index .ant-table td {
+  white-space: nowrap;
+}
 </style>
 <template>
-  <div class="account-statistics">
+  <div class="account-index">
     <a-row class="image-list-heading vm-panel">
       <a-col :span="24" style="display:flex">
         <Treeselect :appId.sync="appId" :multiple="false" style="margin:8px 20px" />
@@ -48,19 +51,62 @@
     </a-row>
     <a-row style="margin-top:15px">
       <a-card>
-        <a-button @click="dianji" style="margin-bottom:15px">新增广告计划</a-button>
+        <a-button @click="dianji" style="margin-bottom:15px;">新增广告计划</a-button>
+        <div v-show="selectedRowKeys.length > 0">
+          请输入修改金额:<a-input-number :min="0" :step="0.01" v-model="allMoney" style="width:150px" @fouse.stop />
+          <a-button @click="editMoney" style="margin:0 15px 15px 15px" type="primary">修改</a-button>
+
+          批量操作:
+          <a-select style="width: 120px" v-model="allType">
+            <a-select-option value="1">启动</a-select-option>
+            <a-select-option value="2">暂停</a-select-option>
+            <a-select-option value="3">删除</a-select-option>
+          </a-select>
+          <a-button @click="editStatus" style="margin:0 0 15px 15px" type="primary">确认</a-button>
+        </div>
+        <a-modal v-model="visible" title="错误信息" onOk="handleOk" :footer="null">
+          <div v-if="visibleData">
+            修改条数:{{ visibleData.totalCount }} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;失败条数:{{
+              visibleData.failCount
+            }}
+            <div style="margin-top:20px">
+              <p v-for="(item, index) of visibleData.failInfo" :key="index">
+                <span>名称:{{ item.campaignName }}</span
+                ><br />
+                <span>错误信息:{{ item.message }}</span>
+              </p>
+            </div>
+          </div>
+        </a-modal>
         <a-table
           size="middle"
           :columns="columns"
           :dataSource="dataList"
           bordered
-          :scroll="{ x: 1900 }"
+          :scroll="{ x: true }"
           :customRow="rowClick"
           :pagination="ipagination"
+          :rowSelection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
         >
+          <span slot="action" slot-scope="text, record">
+            <a-switch v-model="record.showSwich" @change="onChangeSwitch(record)" />
+          </span>
+          <span slot="campaignType" slot-scope="text">
+            {{ text | typeStatus }}
+          </span>
+          <span slot="status" slot-scope="text">
+            {{ text | status }}
+          </span>
+          <span slot="putStatus" slot-scope="text">
+            {{ text | putStatus }}
+          </span>
+          <span slot="createChannel" slot-scope="text">
+            {{ text | createChannel }}
+          </span>
+
           <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>
+              <span v-show="!record.edit" class="count">{{ text ? (text / 1000).toFixed(2) : '不限制预算' }}</span>
               <a-input-number
                 :min="0"
                 :step="0.01"
@@ -97,12 +143,21 @@ import Treeselect from '@/views/modules/Statistics/components/Treeselect.vue'
 
 var columns = [
   {
+    title: '操作',
+    align: 'center',
+    dataIndex: 'action',
+    fixed: 'left',
+    width: 100,
+    scopedSlots: { customRender: 'action' }
+  },
+  {
     title: '广告计划名称',
     align: 'center',
     dataIndex: 'campaignName',
     fixed: 'left',
     width: 200
   },
+
   {
     title: '计划单日预算金额',
     align: 'center',
@@ -111,26 +166,40 @@ var columns = [
     width: 250
   },
   {
+    title: '计划状态',
+    align: 'center',
+    dataIndex: 'status',
+    scopedSlots: { customRender: 'status' }
+  },
+  {
     title: '计划类型',
     align: 'center',
-    dataIndex: 'campaignType'
+    dataIndex: 'campaignType',
+    scopedSlots: { customRender: 'campaignType' }
   },
+
   {
-    title: '应用创建id',
+    title: '渠道',
     align: 'center',
-    dataIndex: 'appId'
+    dataIndex: 'createChannel',
+    scopedSlots: { customRender: 'createChannel' }
   },
   {
-    title: 'url类型 ',
+    title: '投放状态',
     align: 'center',
-    dataIndex: 'urlType'
+    dataIndex: 'putStatus',
+    scopedSlots: { customRender: 'putStatus' }
   },
-
   {
-    title: '推广url',
+    title: '创建时间',
     align: 'center',
-    dataIndex: 'url'
+    dataIndex: 'putCreateTime'
   },
+  {
+    title: '更新时间',
+    align: 'center',
+    dataIndex: 'putUpdateTime'
+  }
 ]
 export default {
   name: 'account-statistics',
@@ -142,6 +211,7 @@ export default {
   },
   data: function() {
     return {
+      allType: '1',
       duration: 1000,
       showEdit: false,
       many: 0,
@@ -152,12 +222,18 @@ export default {
       dataList: [],
       appId: '',
       options: [],
+      selectedRowKeys: [],
+      selectedRowKeysValue: [],
+      allMoney: null,
+      visible: false,
+      visibleData: null,
       rowClick: (record, index) => ({
         // 事件
         on: {
           dblclick: () => {
             // 点击改行时要做的事情
-            localStorage.setItem('advertisingGroupKey', record.id)
+            localStorage.setItem('advertisingGroupKey', record.campaignId)
+            localStorage.setItem('accountId', this.appId)
             if (localStorage.getItem('advertisingGroup')) {
               var dataElse = JSON.parse(localStorage.getItem('advertisingGroup'))
               console.log(dataElse)
@@ -195,7 +271,40 @@ export default {
       url: {}
     }
   },
+  filters: {
+    typeStatus(type) {
+      // 2 - 提升应用安装;
+      // 3 - 获取电商下单;
+      // 4 - 推广品牌活动;
+      // 5 - 收集销售线索;
+      var data = ['', '', '提升应用安装', '获取电商下单', '推广品牌活动', '收集销售线索']
+      return data[type]
+    },
+    status(sta) {
+      var data = { '-1': '不限', 1: '已暂停', 3: '计划超预算', 4: '有效', 6: '余额不足' }
+      return data[sta]
+    },
+    putStatus(sta) {
+      var data = { 1: '投放中', 2: '暂停' }
+      return data[sta]
+    },
+    createChannel(sta) {
+      var data = { 0: '投放后台', 1: '汇创助手' }
+      return data[sta]
+    }
+  },
   methods: {
+    onChangeSwitch(item) {
+      console.log(item)
+      var params = {}
+      params.accountId = this.appId + ''
+      params.putStatus = item.showSwich ? 1 : 2
+      params.userId = this.userInfo().id
+      params.campaignIds = [item.campaignId]
+      postAction('/kuaishou/batch/batchUpdateStatus', params).then(res => {
+        console.log(res)
+      })
+    },
     ...mapGetters(['nickname', 'avatar', 'userInfo']),
     addUser() {
       this.loading = true
@@ -211,6 +320,45 @@ export default {
         this.$message.error('请选择账户')
       }
     },
+    onSelectChange(selectedRowKeys, selectionRows) {
+      this.selectedRowKeys = selectedRowKeys
+      this.selectedRowKeysValue = selectionRows.map(item => {
+        return item.campaignId
+      })
+      //    this.selectedRowKeysValue.length > 0 ? this.selectedRowKeysValue :
+    },
+    editStatus() {
+      var params = {}
+      params.accountId = this.appId + ''
+      params.putStatus = this.allType
+      params.userId = this.userInfo().id
+      params.campaignIds = this.selectedRowKeysValue
+      postAction('/kuaishou/batch/batchUpdateStatus', params).then(res => {
+        console.log(res)
+        this.addUser()
+        this.selectedRowKeysValue = []
+        this.selectedRowKeys = []
+      })
+    },
+    editMoney() {
+      var params = {}
+      params.accountId = this.appId + ''
+      params.dayBudget = this.allMoney * 1000
+      params.userId = this.userInfo().id
+      params.campaignIds = this.selectedRowKeysValue
+      postAction('/kuaishou/batch/batchUpdateDayBudget', params).then(res => {
+        console.log(res)
+        if (res.result.failCount > 0) {
+          this.visible = true
+          this.visibleData = res.result
+          this.addUser()
+        } else {
+          this.addUser()
+          this.selectedRowKeysValue = []
+          this.selectedRowKeys = []
+        }
+      })
+    },
     getCampaignList(params) {
       getAction('/kuaishou/batch/getCampaignList', params).then(res => {
         if (res.code == 0) {
@@ -218,7 +366,8 @@ export default {
             return {
               ...v,
               key: index,
-              edit: false
+              edit: false,
+              showSwich: v.putStatus == 1 ? true : false
             }
           })
           this.ipagination.total = res.result.total
@@ -247,18 +396,46 @@ export default {
     },
     editShow(item) {
       if (!item.edit) {
-        item.dayBudget = item.elseMoney
+        if (item.elseMoney < 500 || item.elseMoney > 100000000) {
+          this.$message.error('请输入大于500并且小于100000000的预算')
+          return
+        } else {
+          item.dayBudget = item.elseMoney * 1000
+          var params = {}
+          params.accountId = this.appId + ''
+          params.dayBudget = item.elseMoney * 1000
+          params.userId = this.userInfo().id
+          params.campaignIds = [item.campaignId]
+          postAction('/kuaishou/batch/batchUpdateDayBudget', params).then(res => {
+            console.log(res)
+            if (res.result.failCount > 0) {
+              this.$message.error(
+                '广告计划:' +
+                  res.result.failInfo[0].campaignName +
+                  '          ' +
+                  '错误:' +
+                  res.result.failInfo[0].message
+              )
+            }
+          })
+        }
       } else {
-        item.elseMoney = item.dayBudget
+        item.elseMoney = item.dayBudget / 1000
       }
+      console.log(item)
     },
     dianji() {
-      if (localStorage.getItem('step')) {
-        this.$message.error('正在进行广告组创建,请关闭创建页面后,重新进行创建')
-        return
+      if (this.appId == '') {
+        this.$message.error('尚未选择需要创建的账户')
       } else {
-        localStorage.setItem('step', 0)
-        this.$router.replace({ name: 'account-StepForm' })
+        localStorage.setItem('accountId', this.appId)
+        if (localStorage.getItem('step')) {
+          this.$message.error('正在进行广告组创建,请关闭创建页面后,重新进行创建')
+          return
+        } else {
+          localStorage.setItem('step', 0)
+          this.$router.replace({ path: '/account/stepForm' })
+        }
       }
     }
   },

+ 176 - 107
src/views/modules/kuaishouapp/account/advertisingGroup.vue

@@ -7,52 +7,45 @@
 .checked .ant-checkbox-wrapper {
   width: 140px;
 }
+.advertising-group .ant-table td {
+  white-space: nowrap;
+}
 </style>
 <template>
-  <div class="account-statistics">
+  <div class="advertising-group">
     <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-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 :indeterminate="indeterminate" @change="onCheckAllChange" :checked="checkAll">全选</a-checkbox>
           <a-checkbox-group :options="showList" v-model="dataValue" class="checked" />
         </a-modal>
 
         <a-table
+          size="middle"
           :columns="columns"
           :dataSource="dataList"
           bordered
           :customRow="rowClick"
           :pagination="ipagination"
+          :scroll="{ x: true }"
         >
-          <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>
+          <span slot="status" slot-scope="text">{{ text | status }}</span>
+          <span slot="putStatus" slot-scope="text">{{ text | putStatus }}</span>
+          <span slot="createChannel" slot-scope="text">{{ text | createChannel }}</span>
+          <span slot="bidType" slot-scope="text">{{ text | bidType }}</span>
+          <span slot="ocpxActionType" slot-scope="text">{{ text | ocpxActionType }}</span>
+          <span slot="speed" slot-scope="text">{{ text | speed }}</span>
+          <span slot="sceneId" slot-scope="text"
+            ><span v-for="item of text" :key="item">{{ item | sceneId }}</span></span
+          >
+          <span slot="showModel" slot-scope="text">{{ text | showModel }}</span>
+          <span slot="unitType" slot-scope="text">{{ text == 4 ? '自定义' : '' }}</span>
+          <span slot="urlType" slot-scope="text">{{ text | urlType }}</span>
+          <!-- <span slot=""></span>
+          <span slot=""></span> -->
         </a-table>
       </a-card>
     </a-row>
@@ -70,32 +63,48 @@ var columns = [
   {
     title: '广告计划ID',
     align: 'center',
-    dataIndex: 'campaignTemplateId',
+    dataIndex: 'campaignId',
     colSpan: 1
   },
   {
-    title: '账户',
+    title: '广告组名称',
     align: 'center',
-    dataIndex: 'accountId',
+    dataIndex: 'unitName',
     colSpan: 1
   },
   {
-    title: '广告活动ID',
+    title: '广告组状态',
     align: 'center',
-    dataIndex: 'campaignId',
-    colSpan: 1
+    dataIndex: 'status',
+    colSpan: 1,
+    scopedSlots: { customRender: 'status' }
   },
   {
-    title: '广告组名称',
+    title: '投放状态',
     align: 'center',
-    dataIndex: 'unitName',
+    dataIndex: 'putStatus',
+    colSpan: 1,
+    scopedSlots: { customRender: 'putStatus' }
+  },
+  {
+    title: '创建渠道',
+    align: 'center',
+    dataIndex: 'createChannel',
+    colSpan: 1,
+    scopedSlots: { customRender: 'createChannel' }
+  },
+  {
+    title: '审核拒绝理由',
+    align: 'center',
+    dataIndex: 'reviewDetail',
     colSpan: 1
   },
   {
     title: '出价类型',
     align: 'center',
     dataIndex: 'bidType',
-    colSpan: 1
+    colSpan: 1,
+    scopedSlots: { customRender: 'bidType' }
   },
   {
     title: '出价',
@@ -107,87 +116,79 @@ var columns = [
     title: 'OCPC出价',
     align: 'center',
     dataIndex: 'cpaBid',
-    colSpan: 0
+    colSpan: 1
   },
   {
     title: '优化目标',
     align: 'center',
     dataIndex: 'ocpxActionType',
-    colSpan: 0
+    colSpan: 1,
+    scopedSlots: { customRender: 'ocpxActionType' }
   },
+  //   {
+  //     title: '深度转换目标',
+  //     align: 'center',
+  //     dataIndex: 'deepConversionType',
+  //     colSpan:1
+  //   },
+  //   {
+  //     title: '深度转换目标出价',
+  //     align: 'center',
+  //     dataIndex: 'deepConversionBid',
+  //     colSpan:1
+  //   },
   {
-    title: '深度转化目标',
+    title: '单日预算',
     align: 'center',
-    dataIndex: 'deepConversionType',
-    colSpan: 0
+    dataIndex: 'dayBudget',
+    colSpan: 1
   },
   {
-    title: '资源位置',
+    title: '投放方式',
     align: 'center',
-    dataIndex: 'page',
-    colSpan: 0
+    dataIndex: 'speed',
+    colSpan: 1,
+    scopedSlots: { customRender: 'speed' }
   },
   {
     title: '投放开始时间',
     align: 'center',
     dataIndex: 'beginTime',
-    colSpan: 0
+    colSpan: 1
   },
   {
     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
+    colSpan: 1
   },
   {
-    title: '投放链接',
+    title: '广告位',
     align: 'center',
-    dataIndex: 'url',
-    colSpan: 0
+    dataIndex: 'sceneId',
+    colSpan: 1,
+    scopedSlots: { customRender: 'sceneId' }
   },
-
   {
     title: '创意展现方式',
     align: 'center',
     dataIndex: 'showModel',
-    colSpan: 0
+    colSpan: 1,
+    scopedSlots: { customRender: 'showModel' }
   },
   {
-    title: '投放方式',
+    title: '创意制作方式',
     align: 'center',
-    dataIndex: 'speed',
-    colSpan: 0
+    dataIndex: 'unitType',
+    colSpan: 1,
+    scopedSlots: { customRender: 'unitType' }
   },
   {
-    title: '广告组ID',
+    title: '落地页链接',
     align: 'center',
-    dataIndex: 'unitId',
-    colSpan: 0
-  },
-  {
-    title: '操作',
-    dataIndex: 'action',
-    align: 'center',
-    scopedSlots: { customRender: 'action' },
-    colSpan: 0
+    dataIndex: 'url',
+    colSpan: 1,
+    scopedSlots: { customRender: 'url' }
   }
 ]
 
@@ -201,9 +202,18 @@ export default {
 
   data: function() {
     return {
+      three: {
+        title: 'url类型',
+        align: 'center',
+        dataIndex: 'urlType',
+        colSpan: 1,
+        scopedSlots: { customRender: 'urlType' }
+      },
+
       duration: 1000,
       showEdit: false,
       columns,
+      columnsElse: columns,
       dataList: [],
       rowClick: (record, index) => ({
         // 事件
@@ -213,7 +223,6 @@ export default {
             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' })
@@ -233,13 +242,19 @@ export default {
       ipagination: {
         current: 1,
         pageSize: 10,
-        pageSizeOptions: ['10', '20', '30'],
+        //   pageSizeOptions: ['10', '20', '30'],
         showTotal: (total, range) => {
           return range[0] + '-' + range[1] + ' 共' + total + '条'
         },
         showQuickJumper: true,
-        showSizeChanger: true,
-        total: 0
+        //   showSizeChanger: true,
+        total: 0,
+        onChange: current => {
+          // 切换分页时的回调,
+          // 当在页面定义change事件时,切记要把此处的事件清除,因为这两个事件重叠了,可能到时候会导致一些莫名的bug
+          this.ipagination.current = current
+          this.getDataList(this.titleKey)
+        }
       },
       url: {
         list: '/kuaishou/kuaiShouGroupCreateLog/list',
@@ -257,6 +272,44 @@ export default {
       checkAll: false
     }
   },
+  filters: {
+    status(sta) {
+      var data = { '-1': '不限', 1: '已暂停', 3: '计划超预算', 4: '有效', 6: '余额不足' }
+      return data[sta]
+    },
+    putStatus(sta) {
+      var data = { 1: '投放中', 2: '暂停' }
+      return data[sta]
+    },
+    createChannel(sta) {
+      var data = { 0: '投放后台创建', 1: '汇创助手创建' }
+      return data[sta]
+    },
+    bidType(sta) {
+      var data = { 1: 'CPM', 2: 'CPC', 6: 'OCPC', 20: 'eCPC' }
+      return data[sta]
+    },
+    ocpxActionType(sta) {
+      var data = { 0: '未知', 2: '点击转化链接', 10: '曝光', 11: '点击', 31: '下载完成', 53: '提交线索', 180: '激活' }
+      return data[sta]
+    },
+    speed(sta) {
+      var data = { 0: '未知', 1: '正常', 2: '点击转化链接' }
+      return data[sta]
+    },
+    sceneId(sta) {
+      var data = { 1: '优选广告位', 2: '按场景选择广告位-信息流广告', 3: '按场景选择广告位-视频后贴片广告' }
+      return data[sta]
+    },
+    showModel(sta) {
+      var data = { 0: '未知', 1: '轮播', 2: '优选' }
+      return data[sta]
+    },
+    urlType(sta) {
+      var data = { 1: '淘宝商品短链', 2: '淘宝商品itemID' }
+      return data[sta]
+    }
+  },
   methods: {
     handleOk(e) {
       console.log(e)
@@ -265,33 +318,52 @@ export default {
     },
     onCheckAllChange(e) {
       Object.assign(this, {
-        dataValue: e.target.checked ? this.showList.map(item=>{return item.value}) : [],
+        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
+      var data = []
+      for (let j = 0; j < this.columnsElse.length; j++) {
+        if (checkedValues.indexOf(this.columnsElse[j].dataIndex) != -1) {
+          data.push(this.columnsElse[j])
         } else {
-          this.columns[j].colSpan = 0
+          //   this.columns[j].colSpan = 0
         }
       }
+      this.columns = data
+    },
+    titleArr() {
+      var data = JSON.parse(localStorage.getItem('advertisingGroup'))
+      var one = data.filter(item => {
+        return item.campaignId == localStorage.getItem('advertisingGroupKey')
+      })
+      if (one[0].campaignType == 3) {
+        this.columns = this.columnsElse.concat(this.three)
+      } else {
+        this.columns = this.columnsElse
+      }
     },
     onTabChange(key, type) {
-      console.log(key, type)
+      this.ipagination.current = 1
       this[type] = key
       localStorage.setItem('advertisingGroupKey', key)
+      this.titleArr()
       this.getDataList(key)
     },
     getDataList(id) {
       this.dataList = []
       var params = {}
       params.campaignId = id
+      params.accountId = localStorage.getItem('accountId')
       params.pageNo = this.ipagination.current
       params.pageSize = this.ipagination.pageSize
-      getAction(this.url.list, params).then(res => {
+      getAction('/kuaishou/batch/getUnitList', params).then(res => {
         if (res.code == 0) {
           this.dataList = res.result.records.map((v, index) => {
             return {
@@ -309,39 +381,36 @@ export default {
         return
       } else {
         localStorage.setItem('step', 1)
-        this.$router.replace({ name: 'account-StepForm' })
+        localStorage.setItem('campaignId', this.titleKey)
+        this.$router.replace({ path: '/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() {
+    var data = JSON.parse(localStorage.getItem('advertisingGroup'))
     this.titleKey = localStorage.getItem('advertisingGroupKey')
-    this.title = JSON.parse(localStorage.getItem('advertisingGroup')).map(item => {
+    this.title = data.map(item => {
       return {
-        key: item.id + '',
+        key: item.campaignId + '',
         tab: '广告计划:' + item.campaignName
       }
     })
     this.getDataList(localStorage.getItem('advertisingGroupKey'))
+    this.titleArr()
     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 => {
+    this.dataValue = this.columns.map(item => {
       return item.dataIndex
     })
   }

+ 70 - 76
src/views/modules/kuaishouapp/account/stepForm/Step1.vue

@@ -1,32 +1,36 @@
 <template>
-  <a-card :body-style="{padding: '24px 32px'}" :bordered="false">
+  <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} }"
+        :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
+        <a-radio-group @change="typeChange" v-model="type" buttonStyle="solid">
+          <!-- <a-radio-button
             v-for="purpose in typeList"
             :key="purpose.itemText"
             :value="purpose.itemValue"
-          >{{purpose.itemText}}</a-radio-button>
+          >{{purpose.itemText}}</a-radio-button> -->
+          <a-radio-button value="2">提升应用安装</a-radio-button>
+          <a-radio-button value="3">获取电商下单</a-radio-button>
+          <a-radio-button value="4">推广品牌活动</a-radio-button>
+          <a-radio-button value="5">收集销售线索</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} }"
+        :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} }"
+        :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>
@@ -36,27 +40,26 @@
       <a-form-item
         label="预算金额"
         v-if="showBudgetDaily"
-        :labelCol="{lg: {span: 7}, sm: {span: 7}}"
-        :wrapperCol="{lg: {span: 10}, sm: {span: 17} }"
+        :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}]}
-                ]"
+            'dayBudget',
+            { rules: [{ required: true, message: 'error:' }, { validator: handleConfirmValue }] }
+          ]"
           placeholder="不小于500,不超过100000000,仅支持输入自然数"
           type="number"
           style="width: 70%"
-        ></a-input>元
+        ></a-input
+        >元
       </a-form-item>
 
-      <a-form-item
+      <!-- <a-form-item
         v-if="showApp"
         label="目标应用"
-        :labelCol="{lg: {span: 7}, sm: {span: 7}}"
-        :wrapperCol="{lg: {span: 10}, sm: {span: 17} }"
+        :labelCol="{ lg: { span: 7 }, sm: { span: 7 } }"
+        :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }"
       >
         <a-select
           v-model="appId"
@@ -70,20 +73,18 @@
           @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-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} }"
+        :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>
@@ -94,8 +95,8 @@
       <a-form-item
         v-if="showChannelType"
         label="转化类型"
-        :labelCol="{lg: {span: 7}, sm: {span: 7}}"
-        :wrapperCol="{lg: {span: 10}, sm: {span: 17} }"
+        :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>
@@ -106,11 +107,11 @@
       <a-form-item
         v-if="showRedirect"
         label="链接地址"
-        :labelCol="{lg: {span: 7}, sm: {span: 7}}"
-        :wrapperCol="{lg: {span: 10}, sm: {span: 17} }"
+        :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> -->
 
       <a-form-item :wrapperCol="{ span: 24 }" style="text-align: center">
         <a-button htmlType="submit" type="primary">下一步</a-button>
@@ -150,14 +151,14 @@ export default {
       url: {
         dictListUrl: 'toutiao/dictitem/list',
         appListUrl: '/kuaishou/kuaiShouCreateAppTemplate/list',
-        insertTemplateUrl: '/kuaishou/kuaiShouCampaignTemplate/insert'
+        insertTemplateUrl: '/kuaishou/batch/campaignCreate'
       }
     }
   },
   methods: {
     ...mapGetters(['nickname', 'avatar', 'userInfo']),
     handleConfirmValue(rule, value, callback) {
-      if (this.dayBudget == '' || this.dayBudget < 500 || this.dayBudget >= 100000000) {
+      if (value == '' || value < 500 || value >= 100000000) {
         callback('请输入正确预算金额')
       }
       callback()
@@ -176,27 +177,21 @@ export default {
           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.campaignBudget = this.campaignBudget
+          params.dayBudget = this.campaignBudget == 'UNLIMITED' ? 0 : values.dayBudget
           params.campaignName = this.campaignName
-          params.loginId = this.userInfo().id
+          params.accountId = localStorage.getItem('accountId')
           console.log(params)
-          this.nextStep()
-          //   postAction(this.url.insertTemplateUrl, params).then(res => {
-          //     console.log(res)
-          //     if (res.success) {
-          //       alert('广告组模板创建成功')
-          //     }
-          //   })
+
+          postAction(this.url.insertTemplateUrl, params).then(res => {
+            console.log(res)
+            if (res.success) {
+              this.$message.success('创建成功')
+              this.nextStep(res.result)
+            } else {
+              this.$message.error(res.message)
+            }
+          })
         }
       })
     },
@@ -260,27 +255,26 @@ export default {
     }
   },
   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)
-      }
-    })
+    // //出价方式
+    // 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 suppressed because it is too large
+ 298 - 709
src/views/modules/kuaishouapp/account/stepForm/Step2.vue


+ 12 - 9
src/views/modules/kuaishouapp/account/stepForm/StepForm.vue

@@ -8,8 +8,8 @@
     </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" />
+      <step2 v-if="currentTab === 1" :campaignId="campaignId" @nextStep="nextStepTwo" @prevStep="prevStep" />
+      <step3 :pans="pans" v-show="currentTab === 2" @prevStep="prevStepTwo" />
       <!-- <step4 v-if="currentTab === 3" @prevStep="prevStep" @finish="finish" /> -->
     </div>
   </a-card>
@@ -34,12 +34,14 @@ export default {
 
       // form
       form: null,
-      pans: []
+      pans: [],
+      campaignId: null
     }
   },
   methods: {
     // handler
-    nextStep() {
+    nextStep(campaignId) {
+      this.campaignId = campaignId
       if (this.currentTab < 2) {
         this.currentTab += 1
       }
@@ -55,6 +57,11 @@ export default {
         this.currentTab -= 1
       }
     },
+    prevStepTwo() {
+      if (this.currentTab > 0) {
+        this.currentTab -= 1
+      }
+    },
     finish() {
       this.currentTab = 0
     }
@@ -65,13 +72,9 @@ export default {
 }
 </script>
 
-
-
-
-
 <style lang="scss" scoped>
 .steps {
   max-width: 750px;
   margin: 16px auto;
 }
-</style>
+</style>

+ 344 - 0
src/views/modules/kuaishouapp/account/stepForm/stepModule/creatApplication.vue

@@ -0,0 +1,344 @@
+<template>
+  <div>
+    <a-modal
+      title="添加应用"
+      :visible="application"
+      @ok="handleOk"
+      :confirmLoading="confirmLoading"
+      @cancel="handleCancel"
+      width="600px"
+    >
+      <a-card :body-style="{ padding: '24px 32px' }" :bordered="false">
+        <a-form :form="form">
+          <a-form-item
+            label="设备类型"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-radio-group v-model="appType" @change="changePlatform">
+              <a-radio-button value="android">安卓</a-radio-button>
+              <a-radio-button value="ios">IOS</a-radio-button>
+            </a-radio-group>
+          </a-form-item>
+          <!-- <a-form-item v-if="appType == 'android'"> -->
+          <a-form-item
+            label="推广类型"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-radio-group v-model="platform" @change="changeShowUploadType">
+              <a-radio value="1">应用下载</a-radio>
+              <a-radio value="2">网页游戏</a-radio>
+            </a-radio-group>
+          </a-form-item>
+
+          <a-form-item
+            label="上传应用"
+            v-if="appType == 'android' && platform == '1'"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-radio-group v-model="uploadType" @change="changeShowUpload">
+              <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
+            label="上传文件"
+            v-if="appType == 'android' && uploadType == '1' && platform == '1'"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <upload-to-ali
+              v-model="file"
+              :customDomain="customDomain"
+              preview
+              :region="region"
+              :bucket="bucket"
+              :accept="acceptVideo"
+              :max="10"
+              :size="1024000"
+              :accessKeyId="accessKeyId"
+              :accessKeySecret="accessKeySecret"
+            ></upload-to-ali>
+          </a-form-item>
+
+          <a-form-item
+            v-if="uploadType == '2' || appType == 'ios' || platform == '2'"
+            label="下载链接"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-input
+              placeholder="请填写应用链接"
+              v-decorator="[
+                'downloadUrl',
+                {
+                  rules: [{ required: true, validator: handleConfirmValue }]
+                }
+              ]"
+            />
+          </a-form-item>
+
+          <a-form-item
+            label="应用包名"
+            v-if="appType == 'android'"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-input
+              v-decorator="[
+                'packageName',
+                {
+                  rules: [{ required: true, message: '请填写正确的应用包名称' }]
+                }
+              ]"
+              placeholder="请填写包名称,如com.smile.gifmaker"
+            />
+          </a-form-item>
+
+          <a-form-item
+            label="应用名称"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-input
+              v-decorator="[
+                'appName',
+                {
+                  rules: [{ required: true, message: '请填写应用名称' }]
+                }
+              ]"
+              placeholder="请填写应用名称"
+            />
+          </a-form-item>
+
+          <a-form-item
+            v-if="appType == 'android'"
+            label="上传图标"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 19 } }"
+          >
+            <upload-to-ali
+              v-model="imageUrl"
+              :customDomain="customDomain"
+              preview
+              :region="region"
+              :bucket="bucket"
+              :accept="acceptVideo"
+              :max="10"
+              :size="1024000"
+              :accessKeyId="accessKeyId"
+              :accessKeySecret="accessKeySecret"
+            ></upload-to-ali>
+            <span>请上传png/jpg/jpeg图片,尺寸450*450,小于100KB</span>
+          </a-form-item>
+
+          <a-form-item
+            label="应用标记"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-input
+              v-decorator="[
+                'appVersion',
+                {
+                  rules: [{ required: true, message: '请填写应用标记' }]
+                }
+              ]"
+              placeholder="请填写应用标记,必填且不可重复,如快手-5.6.1.66"
+            />
+          </a-form-item>
+          <!-- <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-item> -->
+        </a-form>
+      </a-card>
+    </a-modal>
+  </div>
+</template>
+
+<script>
+import { deleteAction, postAction, getAction } from '@/api/manage'
+import UploadToAli from '@femessage/upload-to-ali'
+import { mapActions, mapGetters } from 'vuex'
+
+export default {
+  name: 'BaseForm',
+  components: {
+    UploadToAli
+  },
+  data() {
+    return {
+      accountId: '',
+      accountList: {},
+      appType: 'android', //设备类型
+      platform: '1', //应用类型   : 1 Android 应用下载,2: Android 网页游戏,3: iOS 应用下载, 4:iOS 网页游戏
+      uploadType: '1', //上传类型 1 本地上传 2 填写链接
+      appVersion: '', //应用标记
+      appName: '', // 应用名称
+      packageName: '', //应用包名
+      file: '', // 上传文件
+      imageUrl: '', // 上传图标链接链接
+      downloadUrl: '', //下载链接
+      showUploadFile: true,
+      showDownLoad: false,
+      showUpload: true,
+      showAndroid: true,
+      showIOS: false,
+      customDomain: '',
+      acceptVideo: '/*.apk,/*.png,/*.jpg,/*.jpeg,/*.mp4',
+      accessKeyId: 'LTAIbNbqWzSOklQV',
+      accessKeySecret: '1rkPz7JNoXk8sJevPaeYHWqfkQXBGh',
+      region: 'oss-cn-beijing',
+      bucket: 'ctop-media',
+      form: this.$form.createForm(this),
+      url: {
+        insertTemplateUrl: '/kuaishou/kuaiShouCreateAppTemplate/insert',
+        userAllocationList: '/ctop/userAllocation/list'
+      },
+      application: false,
+      confirmLoading: false
+    }
+  },
+  methods: {
+    handleOk() {
+      this.handleSubmit()
+    },
+    handleCancel() {
+      this.form.resetFields()
+      this.imageUrl = ''
+      this.file = ''
+      this.platform = '1'
+      this.application = false
+    },
+    showApplication() {
+      this.application = true
+    },
+    handleConfirmValue(rule, value, callback) {
+      if (/(http|https):\/\/([\w.]+\/?)\S*/.test(value) && value != '') {
+        callback()
+      } else {
+        callback('链接不能为空且开头为http://或https://')
+      }
+    },
+    ...mapGetters(['nickname', 'avatar', 'userInfo']),
+    changePlatform() {
+      this.form.resetFields()
+      if (this.appType == 'android') {
+        this.showAndroid = true
+        this.showIOS = false
+        this.platform = '1'
+      } else {
+        this.showAndroid = false
+        this.showIOS = true
+        this.showDownLoad = true
+        this.platform = '1'
+      }
+    },
+    changeShowUpload() {
+      this.form.resetFields()
+      if (this.uploadType == '1') {
+        this.showUploadFile = true
+        this.showDownLoad = false
+      } else {
+        this.showUploadFile = false
+        this.showDownLoad = true
+      }
+    },
+    changeShowUploadType() {
+      this.form.resetFields()
+      if (this.platform == '2') {
+        this.showUpload = false
+        this.showUploadFile = false
+        this.showDownLoad = true
+        this.uploadType = '1'
+      } else {
+        this.showUpload = true
+        this.showUploadFile = true
+        this.showDownLoad = false
+      }
+    },
+
+    handleSubmit() {
+      //   console.log('设备类型:' + this.appType)
+      //   console.log('应用类型:' + this.platform)
+      //   console.log('上传类型:' + this.uploadType)
+      //   console.log('应用标记:' + this.appVersion)
+      //   console.log('应用名称:' + this.appName)
+      //   console.log('包名称:' + this.packageName)
+      //   console.log('文件地址:' + this.file)
+      //   console.log('图片地址:' + this.imageUrl)
+      //   e.preventDefault()
+      this.form.validateFields((err, values) => {
+        console.log('Received values of form: ', values)
+        if (!err) {
+          let params = {}
+          params.accountId = localStorage.getItem('accountId')
+          if (this.appType == 'android') {
+            if (this.imageUrl != '') {
+              params.imageUrl = this.imageUrl
+            }
+            if (this.platform == '2') {
+              params.url = values.downloadUrl
+            } else {
+              if (this.uploadType == '1') {
+                if (this.file != '') {
+                  params.file = this.file
+                }
+              } else if (this.uploadType == '2') {
+                params.url = values.downloadUrl
+              }
+            }
+            params.platform = this.platform
+            params.uploadType = values.uploadType
+            params.appType = 'android'
+            params.packageName = values.packageName
+            params.appName = values.appName
+            params.appVersion = values.appVersion
+            params.loginId = this.userInfo().id
+          } else {
+            params.appType = 'ios'
+            params.platform = this.platform
+            params.uploadType = '2'
+            params.url = values.downloadUrl
+            params.appName = values.appName
+            params.appVersion = values.appVersion
+            params.loginId = this.userInfo().id
+          }
+
+          console.log(params)
+          postAction(this.url.insertTemplateUrl, params).then(res => {
+            console.log(res)
+            if (res.success) {
+              this.$message.success('创建成功')
+              this.handleCancel()
+            } else {
+              this.$message.error(res.message)
+            }
+          })
+        }
+      })
+    },
+
+    onChange(value) {
+      console.log(value)
+    }
+  },
+  created: function() {
+    let params = {}
+    params.pageSize = '1000'
+    params.mediaId = '2'
+    params.userId = this.userInfo().id
+    getAction(this.url.userAllocationList, params).then(res => {
+      if (res.success) {
+        this.accountList = res.result.records
+      }
+    })
+  }
+}
+</script>

+ 775 - 0
src/views/modules/kuaishouapp/account/stepForm/stepModule/targetedPopulation.vue

@@ -0,0 +1,775 @@
+<style>
+#table_time_selected1 tr {
+  border: 1px solid rgb(102, 162, 243);
+}
+
+.plug-timer-grid th {
+  line-height: 25px;
+}
+
+.module-form .ant-form-item-required::before {
+  display: inline-block;
+  margin-right: 4px;
+  color: #f5222d;
+  font-size: 14px;
+  font-family: SimSun, sans-serif;
+  line-height: 1;
+  content: '';
+}
+</style>
+<template>
+  <a-form :form="form" class="module-form">
+    <a-form-item
+      label="地区"
+      :labelCol="{ lg: { span: 7 }, sm: { span: 7 } }"
+      :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }"
+    >
+      <a-radio-group @change="regionChange" v-model="allForm.regionType" buttonStyle="solid">
+        <a-radio-button value="noLimit">不限</a-radio-button>
+        <a-radio-button value="limit">指定地区</a-radio-button>
+      </a-radio-group>
+      <div v-if="allForm.regionType == 'limit'" style="margin-top:10px">
+        <!-- v-model="allForm.region" -->
+        <el-cascader
+          ref="cascader"
+          v-decorator="['region', { rules: [{ required: true, message: '请选择地区' }] }]"
+          :options="options"
+          :props="optionProps"
+          clearable
+          filterable
+          style="width:100%"
+        ></el-cascader>
+      </div>
+    </a-form-item>
+    <a-form-item
+      label="年龄"
+      :labelCol="{ lg: { span: 7 }, sm: { span: 7 } }"
+      :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }"
+    >
+      <a-radio-group v-model="allForm.ageType" buttonStyle="solid" @change="ageChange">
+        <a-radio-button value="noLimit">不限</a-radio-button>
+        <a-radio-button value="ageLimit">限定年龄段</a-radio-button>
+        <a-radio-button value="ageCustom">自定义年龄段</a-radio-button>
+      </a-radio-group>
+      <div v-if="allForm.ageType == 'ageLimit'">
+        <!-- v-model="allForm.ages_range" -->
+        <a-checkbox-group v-decorator="['ages_range', { rules: [{ required: true, message: '请选择年龄段' }] }]">
+          <a-checkbox value="0">0-11岁</a-checkbox>
+          <a-checkbox value="12">12-27岁</a-checkbox>
+          <a-checkbox value="18">18-23岁</a-checkbox>
+          <a-checkbox value="24">24-30岁</a-checkbox>
+          <a-checkbox value="31">31-40岁</a-checkbox>
+          <a-checkbox value="41">41-49岁</a-checkbox>
+          <a-checkbox value="50">50+</a-checkbox>
+        </a-checkbox-group>
+      </div>
+      <div v-if="allForm.ageType == 'ageCustom'">
+        <a-slider
+          range
+          :marks="marks"
+          :min="5"
+          :max="55"
+          v-decorator="[
+            'age',
+            {
+              rules: [{ required: true, message: '请选择年龄段' }, { validator: handleConfirmValue }],
+              initialValue: [10, 50]
+            }
+          ]"
+        />
+      </div>
+    </a-form-item>
+    <a-form-item
+      label="性别"
+      :labelCol="{ lg: { span: 7 }, sm: { span: 7 } }"
+      :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }"
+    >
+      <a-radio-group
+        buttonStyle="solid"
+        v-decorator="[
+          'gender',
+          {
+            initialValue: '0'
+          }
+        ]"
+      >
+        <a-radio-button value="0">不限</a-radio-button>
+        <a-radio-button value="1">女性</a-radio-button>
+        <a-radio-button value="2">男性</a-radio-button>
+      </a-radio-group>
+    </a-form-item>
+  </a-form>
+</template>
+
+<script>
+import { getAction, postAction } from '@/api/manage'
+import moment from 'moment'
+import { mapGetters } from 'vuex'
+import jq from 'jquery'
+
+let dateQuantumRangeConst = ''
+
+export default {
+  name: 'BaseForm',
+  components: {},
+  props: {
+    campaignId: {
+      type: String,
+      default() {
+        return null
+      }
+    }
+  },
+  data() {
+    return {
+      form: this.$form.createForm(this),
+      marks: {
+        5: '5岁',
+        10: '10岁',
+        15: '15岁',
+        20: '20岁',
+        25: '25岁',
+        30: '30岁',
+        35: '35岁',
+        40: '40岁',
+        45: '45岁',
+        50: '50岁',
+        55: '55岁'
+      },
+      step: 0,
+      people: '2',
+      targeted: '2',
+      appList: [],
+      appId: '',
+      loading: false,
+      campaignTemplateId: '',
+      allForm: {
+        regionType: 'noLimit',
+        region: [
+          [12, 120102],
+          [12, 120103]
+        ],
+        ageType: 'noLimit',
+        ages_range: [],
+        age: []
+      },
+      options: [],
+      optionsAll: [],
+      optionProps: {
+        value: 'regionId',
+        label: 'name',
+        children: 'children',
+        multiple: true
+      }
+    }
+  },
+  computed: {
+    count() {}
+  },
+  methods: {
+    handleConfirmValue(rule, value, callback) {
+      console.log(value)
+      if (Math.abs(value[0] - value[1]) < 5) {
+        callback('自定义年龄段需要间隔大于5岁')
+      }
+      callback()
+    },
+    regionChange() {
+      this.allForm.region = []
+    },
+    ageChange() {
+      this.allForm.ages_range = []
+    },
+    search(e) {},
+    put() {
+      var data = this.allForm.region.map(item => {
+        return item[1] + ''
+      })
+      console.log(data)
+      var dataElse = data.map(item => {
+        return [item.substring(0, 2), item]
+      })
+      console.log(dataElse)
+    }
+  },
+  mounted: function() {
+    getAction('/kuaishou/batch/getRegion').then(res => {
+      console.log(res)
+      this.options = res.result
+      this.optionsAll = res.result
+    })
+  }
+}
+
+var box_id
+var StartTD = null
+var StartIndex = null
+var EndTD = null
+var EndIndex = null
+var Selected = 'Selected'
+var Start_x = null
+var Start_y = null
+//点击中表格的小时值
+var hour
+//点击选中的星期值
+var week
+//1为这个格子在此次鼠标拖拽过程中被选中(不执行选中方法),0为没选中过
+var td_state = 0
+//生成星期数组
+var num = ['一', '二', '三', '四', '五', '六', '日']
+//生成时间值数组
+var arr_hour = get_hour_arr()
+
+//按下鼠标左键拖动选中单元格
+function SelectTD(StartIndex, EndIndex, Selected) {
+  var MinX = null
+  var MaxX = null
+  var MinY = null
+  var MaxY = null
+
+  var coordinate = get_coordinate(StartIndex, EndIndex)
+  MinX = coordinate[0]
+  MaxX = coordinate[1]
+  MinY = coordinate[2]
+  MaxY = coordinate[3]
+
+  for (var i = MinY; i <= MaxY; i++) {
+    for (var j = MinX; j <= MaxX; j++) {
+      var SelectTR = jq('#' + box_id + ' table tbody tr ').eq(i)
+      var td_class = jq('td', SelectTR)
+        .eq(j)
+        .attr('class')
+      td_state = jq('td', SelectTR)
+        .eq(j)
+        .attr('td_state')
+
+      //在同一次鼠标按下的过程中,选中过的表格不进行选中或取消操作
+      if (!td_state) {
+        if (td_class == Selected) {
+          jq('td', SelectTR)
+            .eq(j)
+            .removeClass(Selected)
+        } else {
+          //筛选掉标明为星期的表格
+          jq('td', SelectTR)
+            .eq(j)
+            .attr('class', Selected)
+        }
+        jq('td', SelectTR)
+          .eq(j)
+          .attr('td_state', '1')
+      }
+    }
+  }
+
+  //改变二进制值
+  get_time_val()
+  //改变日期显示
+  convert_date()
+}
+
+//点击选中或去掉选中整行、整列
+function SelectTD_click(StartIndex, EndIndex, Selected) {
+  var MinX = null
+  var MaxX = null
+  var MinY = null
+  var MaxY = null
+  var Selected_true = 0
+  var Selected_false = 0
+
+  var coordinate = get_coordinate(StartIndex, EndIndex)
+  MinX = coordinate[0]
+  MaxX = coordinate[1]
+  MinY = coordinate[2]
+  MaxY = coordinate[3]
+
+  //列出此列当中的表格选中状态
+  for (var i = MinY; i <= MaxY; i++) {
+    for (var j = MinX; j <= MaxX; j++) {
+      var SelectTR = jq('#' + box_id + ' table tbody tr ').eq(i)
+      var td_class = jq('td', SelectTR)
+        .eq(j)
+        .attr('class')
+
+      if (td_class == Selected) {
+        //表格里存在已选中的元素
+        Selected_true = 1
+      } else {
+        //表格里存在未选中的元素
+        Selected_false = 1
+      }
+    }
+  }
+
+  //执行选中或去掉选中方法
+  for (var i = MinY; i <= MaxY; i++) {
+    for (var j = MinX; j <= MaxX; j++) {
+      var SelectTR = jq('#' + box_id + ' table tbody tr ').eq(i)
+      var td_class = jq('td', SelectTR)
+        .eq(j)
+        .attr('class')
+
+      //一列当中存在已选中与未选中的表格处理:整列全部选中
+      if (Selected_true == 1 && Selected_false == 1) {
+        jq('td', SelectTR)
+          .eq(j)
+          .attr('class', Selected)
+      } else if (Selected_false == 1) {
+        //一列当中只存在未选中的表格处理:整列全部选中
+        jq('td', SelectTR)
+          .eq(j)
+          .attr('class', Selected)
+      } else {
+        //一列当中只存在已选中的表格处理:整列全部去掉选中
+        jq('td', SelectTR)
+          .eq(j)
+          .removeClass(Selected)
+      }
+    }
+  }
+  //改变二进制值
+  get_time_val()
+  //改变日期显示
+  convert_date()
+}
+
+//获取选中范围的开始与结束的坐标
+function get_coordinate(StartIndex, EndIndex) {
+  var MinX = null
+  var MaxX = null
+  var MinY = null
+  var MaxY = null
+
+  if (StartIndex.x < EndIndex.x) {
+    MinX = StartIndex.x
+    MaxX = EndIndex.x
+  } else {
+    MinX = EndIndex.x
+    MaxX = StartIndex.x
+  }
+  if (StartIndex.y < EndIndex.y) {
+    MinY = StartIndex.y
+    MaxY = EndIndex.y
+  } else {
+    MinY = EndIndex.y
+    MaxY = StartIndex.y
+  }
+  return [MinX, MaxX, MinY, MaxY]
+}
+
+//改变二进制值
+function get_time_val() {
+  var time_type = ''
+  jq('#' + box_id + ' table tbody')
+    .find('td')
+    .each(function(k) {
+      var Selected_type = jq(this).attr('class')
+      var week = jq(this).attr('week')
+
+      if (Selected_type == Selected && !week) {
+        time_type += '1'
+      } else if (!week) {
+        time_type += '0'
+      }
+    })
+  jq('#' + box_id + '_time_num').val(time_type)
+  // convert_date();
+}
+
+//二进制数转换日期
+function convert_date(external_binary) {
+  //初始化周数数组
+  var time_week_arr = []
+  if (!external_binary) {
+    //内部调用,进行选中表格和输出时间操作。
+    var binary = jq('#' + box_id + '_time_num').val()
+  } else {
+    //存在外部参入传入,此函数进行返回时间操作。
+    var date_html = ''
+    var binary = external_binary
+  }
+
+  for (var y = 0; y < 7; y++) {
+    //初始化小时数组
+    var time_hour_arr = []
+
+    for (var x = 0; x < 24; x++) {
+      //获取当前点击元素的位置
+      if (y == 0) {
+        var index = x
+      } else {
+        var index = y * 24 + x
+      }
+      //获取td对应的二进制值
+      var Selected_val = binary.charAt(index)
+
+      if (Selected_val == 1) {
+        //组装保存进数组里
+        if (time_hour_arr == []) {
+          //表格的第一个位置的值
+          time_hour_arr = arr_hour[x]
+        } else if (binary.charAt(index - 1) == 1 && binary.charAt(index - 2) == 1) {
+          //此位置(包含上一行)的前两个都为选中时
+
+          if (x == 0 && binary.charAt(index + 1) == 0) {
+            //选中行里第一个,后一个表格没选中,加逗号
+            time_hour_arr[time_hour_arr.length] = arr_hour[x] + ', '
+          } else if (x == 0 && binary.charAt(index + 1) == 1) {
+            //选中行里第一个,后一个表格已选中,不加逗号
+            time_hour_arr[time_hour_arr.length] = arr_hour[x]
+          } else if (x == 1 && binary.charAt(index - 1) == 0) {
+            //选中行里第二个,上一个表格没选中,加逗号
+            time_hour_arr[time_hour_arr.length] = arr_hour[x] + ', '
+          } else if (x == 1 && binary.charAt(index - 1) == 1) {
+            //选中行里第二个,上一个表格已选中,前加-号,后加逗号
+            time_hour_arr[time_hour_arr.length] = '-' + arr_hour[x] + ', '
+          } else {
+            //选中行里除第一、二的表格以外,前一个表格已经选中,此元素前加- 后加逗号
+            time_hour_arr[time_hour_arr.length - 1] = '-' + arr_hour[x] + ', '
+          }
+        } else if (binary.charAt(index - 1) == 1 && x > 0) {
+          //选中的前一个已选中,且此次选中的不是行里第一个,此次选中的元素前加-后加逗号
+          time_hour_arr[time_hour_arr.length] = '-' + arr_hour[x] + ', '
+        } else if (binary.charAt(index + 1) != 1 || x == 23) {
+          //选中的后一个没选中,或者此次选中的是行里最后一个,此次选中的元素加逗号
+          time_hour_arr[time_hour_arr.length] = arr_hour[x] + ', '
+        } else {
+          //选中的后一已选中,此次选中的元素不加逗号
+          time_hour_arr[time_hour_arr.length] = arr_hour[x]
+        }
+      }
+    }
+
+    time_week_arr[y] = time_hour_arr
+  }
+  // console.info(box_id);
+  if (!external_binary) {
+    jq('#' + box_id + '_time_seled').html('')
+  }
+  //再次组装并输出数组
+  var time_html = []
+  for (var y = 0; y < 7; y++) {
+    for (var x = 0; x < time_week_arr[y].length; x++) {
+      if (!time_html[y]) {
+        time_html[y] = time_week_arr[y][x]
+      } else {
+        time_html[y] += time_week_arr[y][x]
+      }
+    }
+
+    if (time_html[y]) {
+      time_html[y] = time_html[y].substring(0, time_html[y].length - 2)
+
+      if (!external_binary) {
+        jq('#' + box_id + '_time_seled').append('<div>星期' + num[y] + ' (' + time_html[y] + ')' + '</div>')
+      } else {
+        date_html += '星期' + num[y] + ' (' + time_html[y] + ')' + ', '
+      }
+    }
+  }
+
+  if (external_binary) {
+    return date_html
+  }
+  // console.info(time_html);
+}
+
+//生成时间值数组
+function get_hour_arr() {
+  var arr_hour = []
+  var oDate = new Date('2016/07/01 00:00:00') //实例一个时间对象;
+  var oDate_hour = oDate.getHours()
+  var oDate_minute = oDate.getMinutes()
+  for (var i = 0; i < 24; i++) {
+    if (oDate_minute < 10) {
+      var oDate_minute = '0' + oDate_minute
+    }
+    if (i >= 1) {
+      oDate.setMinutes(oDate.getMinutes() + 60)
+      oDate_hour = oDate.getHours()
+      oDate_minute = oDate.getMinutes()
+      if (oDate_minute < 10) {
+        var oDate_minute = '0' + oDate_minute
+      }
+    }
+    arr_hour[i] = oDate_hour + ':' + oDate_minute
+  }
+  return arr_hour
+}
+
+//更新操作
+function renewal(id) {
+  if (id) {
+    box_id = id
+  }
+  //解绑鼠标移动监听事件
+  jq('#' + box_id + ' table tbody tr td').unbind('mouseover')
+  //初始化表格的在此次选中状态
+  jq('#' + box_id + ' table tbody tr td').attr('td_state', '')
+  //改变二进制值
+  get_time_val()
+  //改变日期显示
+  convert_date()
+}
+
+//二进制数赋值选中表格
+function binary_selected() {
+  var default_time_val = jq('#' + box_id + ' .default_time_val').val()
+  if (default_time_val) {
+    for (var i = 0; i < 168; i++) {
+      var td_selected = default_time_val.charAt(i)
+      if (td_selected != 0) {
+        jq('#' + box_id + ' table tbody tr td')
+          .eq(i)
+          .attr('class', 'Selected')
+        //更新操作,显示文字形日期
+        renewal()
+      }
+    }
+  }
+}
+
+//实例化程序
+function load_time_table(id, value) {
+  //包住table的元素id
+  box_id = id
+  var html
+  html = '<input type="hidden" class="default_time_val" value="' + value + '"/>'
+  html +=
+    '<table cellspacing="0" cellpadding="0" border="0" class="plug-timer-grid"  onselectstart="return false" onselect="document.selection.empty()">'
+  html += '<thead>'
+  html += '<tr>'
+  html += '<th></th>'
+  html += '<th colSpan="12">上午</th>'
+  html += '<th colSpan="12">下午</th>'
+  html += '</tr>'
+  html += '<tr class="hour">'
+  html += '<th></th>'
+  html += '</tr>'
+  html += '</thead>'
+  html += '<tbody></tbody>'
+  html += '</table>'
+  html += '<input class="focus" type="hidden" style="opacity: 0;">'
+  html += '<div id="' + box_id + '_time_seled" style="line-height: 15px;font-size:10px;"></div>'
+  html +=
+    '<input type="hidden" id="' +
+    box_id +
+    '_time_num" name="time" caption="每日投放时段" switchname="selectTime"  value="' +
+    value +
+    '">'
+  jq('#' + box_id).html('')
+  jq('#' + box_id).append(html)
+  var html_tbody_td = ''
+  var html_thead_td = ''
+  //创建表格
+  for (var i = 0; i < 7; i++) {
+    var week = i + 1
+    html_tbody_td += '<tr>'
+    for (var j = 0; j < 25; j++) {
+      if (j == 0) {
+        html_tbody_td += '<th week="' + week + '">星期' + num[i] + '</th>'
+      } else {
+        html_tbody_td += '<td>' + '</td>'
+      }
+    }
+    html_tbody_td += '</tr>'
+  }
+
+  //创建表格小时栏目
+  for (var i = 0; i <= 23; i++) {
+    html_thead_td += '<td  hour="' + i + '">' + i + '</td>'
+  }
+  jq('#' + box_id + ' table thead .hour').append(html_thead_td)
+  jq('#' + box_id + ' table tbody').html(html_tbody_td)
+  //检查是否有赋有二进制值,如有,将选中相应的表格
+  binary_selected()
+
+  //控制器,控制当前在哪个表格进行操作
+  jq('.plug-timer-grid').hover(function(e) {
+    if (1 != e.which) {
+      //判断是否为左击
+      var id = jq(this)
+        .parent()
+        .attr('id')
+      box_id = id
+    }
+  })
+
+  //清除所有选中项
+  jq('.clear').click(function() {
+    jq(this)
+      .parent()
+      .find('td')
+      .removeClass(Selected)
+    var id = jq(this)
+      .parent()
+      .attr('id')
+    renewal(id)
+  })
+
+  //点击小时选中或去掉整列处理块
+  jq('#' + box_id + ' table thead tr td').click(function() {
+    hour = jq(this).attr('hour')
+    if (hour >= 0) {
+      var rows = jq('#' + box_id + ' table tbody tr').length
+      Start_x = jq(this).index() * 2 - 1
+      Start_y = 0
+
+      StartIndex = { x: Start_x, y: Start_y }
+
+      EndTD = jq(this)
+      var x = jq(this).index() * 2 - 2
+      var y = rows - 1 //为了配合for计算公式-1
+
+      EndIndex = { x: x, y: y }
+      //改变第一次按下鼠标时候的改变选中状态
+      SelectTD_click(StartIndex, EndIndex, Selected)
+    }
+  })
+
+  //点击星期选中或去掉整行处理块
+  jq('#' + box_id + ' table tbody tr th').click(function() {
+    var week = jq(this).attr('week')
+    if (week >= 0) {
+      var line = jq('#' + box_id + ' table tbody tr td').length / jq('#' + box_id + ' table tbody tr').length
+
+      Start_x = 0
+      Start_y = jq(this)
+        .parent()
+        .index()
+
+      StartIndex = { x: Start_x, y: Start_y }
+
+      EndTD = jq(this)
+      var y = jq(this)
+        .parent()
+        .index()
+      var x = line - 1 //为了配合for计算公式-1
+
+      EndIndex = { x: x, y: y }
+
+      //改变第一次按下鼠标时候的改变选中状态
+      SelectTD_click(StartIndex, EndIndex, Selected)
+    }
+  })
+
+  //监听鼠标按下事件(鼠标按下左键拖动选中处理块)
+  jq('#' + box_id + ' table tbody tr td')
+    .unbind('mousedown')
+    .bind('mousedown', function() {
+      //记录刚开始点击的元素位置
+      Start_x = jq(this).index() - 1
+      Start_y = jq(this)
+        .parent()
+        .index()
+      StartIndex = { x: Start_x, y: Start_y }
+
+      EndTD = jq(this)
+      var x = jq(this).index() - 1
+      var y = jq(this)
+        .parent()
+        .index()
+      EndIndex = { x: x, y: y }
+      //改变第一次按下鼠标时候的改变选中状态
+      SelectTD(StartIndex, EndIndex, Selected)
+
+      StartTD = jq(this)
+
+      StartIndex = { x: Start_x, y: Start_y }
+
+      //监听鼠标移动事件,实现改变后续鼠标拖拽时候的表格选中状态
+      jq('#' + box_id + ' table tbody tr td').mouseover(function(e) {
+        EndTD = jq(this)
+        var x = jq(this).index() - 1
+        var y = jq(this)
+          .parent()
+          .index()
+        EndIndex = { x: x, y: y }
+        if (1 != e.which) {
+          //判断是否为左击
+          jq('#' + box_id + ' table tbody tr td').unbind('mouseover')
+        }
+        //去除停留在td上的光标
+        jq('#' + box_id + ' .focus').focus()
+        SelectTD(StartIndex, EndIndex, Selected)
+      })
+
+      //放开鼠标左键时,初始化相关参数和解绑相关监听
+      jq('html')
+        .unbind('mouseup')
+        .bind('mouseup', function() {
+          renewal()
+        })
+    })
+}
+
+/*外部调用接口*/
+
+//解绑鼠标松开监听事件
+function unbundle_mouseover() {
+  jq('html').unbind('mouseup')
+}
+
+/*二进制获取转换后的时间*/
+function get_time_html(binary) {
+  return convert_date(binary)
+}
+
+jq(function() {
+  load_time_table('table_time_selected1', this.dateQuantumRange)
+})
+</script>
+
+<style type="text/css">
+.plug-timer-grid {
+  width: 100%;
+}
+
+.plug-timer-grid td,
+.plug-timer-grid th {
+  border: 1px solid #97b4d1;
+  text-align: center; /*cursor:pointer;*/
+  font-size: 10px;
+  line-height: 10px;
+}
+
+.Selected {
+  background-color: rgb(102, 162, 243);
+  opacity: 0.5;
+}
+
+.plug-timer-grid {
+  border-collapse: collapse;
+  z-index: 4;
+}
+
+.plug-timer-grid thead tr {
+  display: table-row;
+  vertical-align: inherit;
+  border-color: inherit;
+}
+
+.group-creat table td {
+  height: 20px;
+  max-width: 5px;
+  border: 1px solid #dfe6ec;
+  font-size: 12px;
+  text-align: center;
+  vertical-align: middle;
+  overflow: hidden;
+  transition: background 0.5s;
+  -webkit-transition: background 0.5s;
+}
+
+.plug-timer-grid tbody th {
+  width: 4%;
+}
+
+.plug-timer-grid tbody tr td {
+  width: 2%;
+}
+
+/*.clear{*/
+/*  margin:20px 0px 20px 0px;*/
+/*}*/
+</style>

+ 2 - 3
src/views/modules/material/videoMaterial.vue

@@ -428,8 +428,7 @@ a {
           <a-form-item :label-col="labelCol" :wrapper-col="wrapperCol" label="拍摄" v-if="activeKey == 'video'">
             <a-select
               v-decorator="[
-                'shotId', // 给表单赋值或拉取表单时,该input对应的key
-                { rules: [{ required: true, message: '请选择策划!' }] }
+                'shotId' // 给表单赋值或拉取表单时,该input对应的key
               ]"
             >
               <a-select-option :value="item.userId" v-for="item of ascription.shotId" :key="item.userId">
@@ -441,7 +440,7 @@ a {
             <a-select
               v-decorator="[
                 'clipId', // 给表单赋值或拉取表单时,该input对应的key
-                { rules: [{ required: true, message: '请选择策划!' }] }
+                { rules: [{ required: true, message: '请选择剪辑!' }] }
               ]"
             >
               <a-select-option :value="item.userId" v-for="item of ascription.clipId" :key="item.userId">

+ 1 - 31
src/views/performance/OptimizerRoleInfoList.vue

@@ -11,7 +11,7 @@
               <a-input placeholder="请输入部门代码" v-model="queryParam.orgCode"></a-input>
             </a-form-item>
           </a-col>
-        <template v-if="toggleSearchStatus">
+        <template>
         <a-col :md="6" :sm="8">
             <a-form-item label="用户id">
               <a-input placeholder="请输入用户id" v-model="queryParam.userId"></a-input>
@@ -32,10 +32,6 @@
             <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
               <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
               <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
-              <a @click="handleToggleSearch" style="margin-left: 8px">
-                {{ toggleSearchStatus ? '收起' : '展开' }}
-                <a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
-              </a>
             </span>
           </a-col>
 
@@ -46,25 +42,10 @@
     <!-- 操作按钮区域 -->
     <div class="table-operator">
       <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
-      <a-button type="primary" icon="download" @click="handleExportXls('优化师角色关系表')">导出</a-button>
-      <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
-        <a-button type="primary" icon="import">导入</a-button>
-      </a-upload>
-      <a-dropdown v-if="selectedRowKeys.length > 0">
-        <a-menu slot="overlay">
-          <a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
-        </a-menu>
-        <a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /></a-button>
-      </a-dropdown>
     </div>
 
     <!-- table区域-begin -->
     <div>
-      <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
-        <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
-        <a style="margin-left: 24px" @click="onClearSelected">清空</a>
-      </div>
-
       <a-table
         ref="table"
         size="middle"
@@ -74,7 +55,6 @@
         :dataSource="dataSource"
         :pagination="ipagination"
         :loading="loading"
-        :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
         @change="handleTableChange">
 
         <span slot="action" slot-scope="text, record">
@@ -117,16 +97,6 @@
         description: '优化师角色关系表管理页面',
         // 表头
         columns: [
-          {
-            title: '#',
-            dataIndex: '',
-            key:'rowIndex',
-            width:60,
-            align:"center",
-            customRender:function (t,r,index) {
-              return parseInt(index)+1;
-            }
-           },
 		   {
             title: '部门代码',
             align:"center",

+ 2 - 2
vue.config.js

@@ -66,8 +66,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://192.168.2.130:8080', //请求本地 需要jeecg-boot后台项目  蒙蒙
-        target: 'http://192.168.2.133:8080', //请求本地 需要jeecg-boot后台项目  英豪
+        target: 'http://192.168.2.130:8080', //请求本地 需要jeecg-boot后台项目  蒙蒙
+        // target: 'http://192.168.2.133:8080', //请求本地 需要jeecg-boot后台项目  英豪
         // target: 'http://192.168.2.132:8080', //请求本地 需要jeecg-boot后台项目
         // target: 'http://192.168.2.185:8080', //请求本地 需要jeecg-boot后台项目  祚云
         ws: false,