Browse Source

新批量提交

朱鑫波 4 years ago
parent
commit
efd6288a1a
39 changed files with 8831 additions and 266 deletions
  1. 4 4
      package.json
  2. 12 4
      src/components/layouts/UserLayout.vue
  3. 348 0
      src/components/uploadFileMd5Push.vue
  4. 13 3
      src/config/router.config.js
  5. 72 2
      src/filters.js
  6. 16 12
      src/permission.js
  7. 1 0
      src/utils/request.js
  8. 1 0
      src/views/modules/Statistics/KSAccountReport.vue
  9. 7 0
      src/views/modules/Statistics/components/Treeselect.vue
  10. 19 4
      src/views/modules/Statistics/components/ratioModal.vue
  11. 19 2
      src/views/modules/Statistics/materialStatistics.vue
  12. 44 2
      src/views/modules/Statistics/newPlanStatic/newPlanStatic.vue
  13. 49 16
      src/views/modules/advertiser/AdvertiserList.vue
  14. 2 1
      src/views/modules/advertiser/ProjectList.vue
  15. 2 0
      src/views/modules/advertiser/ProjectMemberList.vue
  16. 77 30
      src/views/modules/advertiser/modules/ProjectModal.vue
  17. 1 1
      src/views/modules/advertiser/modules/projectListModal.vue
  18. 1 1
      src/views/modules/autoLaunch/appIdList.vue
  19. 252 58
      src/views/modules/autoLaunch/configLaunchInfo.vue
  20. 82 9
      src/views/modules/autoLaunch/configLaunchList.vue
  21. 1 2
      src/views/modules/autoLaunch/newAppId.vue
  22. 8 0
      src/views/modules/columnConst/accountConst.js
  23. 22 9
      src/views/modules/kuaishouapp/account/accountIndex.vue
  24. 22 8
      src/views/modules/kuaishouapp/account/advertisingGroup.vue
  25. 16 18
      src/views/modules/kuaishouapp/account/copyAllUnit.vue
  26. 58 21
      src/views/modules/kuaishouapp/account/stepForm/Step2.vue
  27. 4 4
      src/views/modules/kuaishouapp/account/stepForm/Step4.vue
  28. 44 38
      src/views/modules/kuaishouapp/account/stepForm/stepModule/test.vue
  29. 9 1
      src/views/modules/kuaishouapp/batchCreation/campaignList.vue
  30. 2 4
      src/views/modules/kuaishouapp/batchCreation/creat/creatUnit.vue
  31. 1 3
      src/views/modules/kuaishouapp/crossAccount/createUnit.vue
  32. 4786 0
      src/views/modules/kuaishouapp/newBatch/index.vue
  33. 1110 0
      src/views/modules/kuaishouapp/newBatch/lookPreview.vue
  34. 1532 0
      src/views/modules/stockWatch/accountPage.vue
  35. 9 2
      src/views/modules/workBench/materialList.vue
  36. 9 1
      src/views/modules/workBench/orderDetail.vue
  37. 10 2
      src/views/modules/workBench/placeOrder.vue
  38. 4 4
      vue.config.js
  39. 162 0
      面试题.md

+ 4 - 4
package.json

@@ -25,7 +25,7 @@
     "codemirror": "^5.46.0",
     "cos-js-sdk-v5": "^0.5.26",
     "dayjs": "^1.8.0",
-    "echarts": "^4.3.0",
+    "echarts": "^4.9.0",
     "element-ui": "^2.13.0",
     "enquire.js": "^2.1.6",
     "html2canvas": "^1.0.0-rc.3",
@@ -48,6 +48,7 @@
     "vue-i18n": "^8.7.0",
     "vue-infinite-scroll": "^2.0.2",
     "vue-layer": "^1.0.2",
+    "vue-lazyload": "^1.3.3",
     "vue-loader": "^15.7.0",
     "vue-ls": "^3.2.0",
     "vue-oss-uploader": "^0.1.10",
@@ -61,8 +62,7 @@
     "vue-waterfall-easy": "^2.4.3",
     "vuedraggable": "^2.20.0",
     "vuex": "^3.0.1",
-    "vuex-class": "^0.3.1",
-    "vue-lazyload": "^1.3.3"
+    "vuex-class": "^0.3.1"
   },
   "devDependencies": {
     "@babel/polyfill": "^7.2.5",
@@ -131,4 +131,4 @@
     "last 2 versions",
     "not ie <= 8"
   ]
-}
+}

+ 12 - 4
src/components/layouts/UserLayout.vue

@@ -1,7 +1,7 @@
 <template>
   <div id="userLayout" :class="['user-layout-wrapper', device]">
-    <div class="container">
-      <div class="top" style="margin-bottom:30px">
+    <div class="container"  v-if="showTitle">
+      <div class="top" style="margin-bottom: 30px" >
         <div class="header">
           <a href="/">
             <img src="~@/assets/logo.png" class="logo" alt="logo" style="height: 50px" />
@@ -24,6 +24,7 @@
         <div class="copyright">Copyright &copy; 2019 上海有腾</div>
       </div>
     </div>
+    <route-view v-else></route-view>
   </div>
 </template>
 
@@ -36,14 +37,21 @@ export default {
   components: { RouteView },
   mixins: [mixinDevice],
   data() {
-    return {}
+    return {
+      showTitle: true,
+    }
   },
   mounted() {
     document.body.classList.add('userLayout')
+    if (this.$route.path == '/user/new-batch'||this.$route.path=='/user/lookPreview') {
+      this.showTitle = false
+    } else {
+      this.showTitle = true
+    }
   },
   beforeDestroy() {
     document.body.classList.remove('userLayout')
-  }
+  },
 }
 </script>
 

+ 348 - 0
src/components/uploadFileMd5Push.vue

@@ -0,0 +1,348 @@
+<style>
+</style>
+<style lang="scss">
+.md5-file {
+  width: 100%;
+  height: 100%;
+}
+.md5-file .ant-upload-picture-card-wrapper {
+  height: 100% !important;
+}
+.md5-file .ant-upload.ant-upload-select-picture-card {
+  height: 100% !important;
+  width: 100%;
+}
+
+</style>
+<template>
+  <div class="upload-file md5-file">
+    <a-upload
+      name="file"
+      :multiple="multiple"
+      list-type="picture-card"
+      class="avatar-uploader"
+      action="https://media-1301855440.cos.ap-chongqing.myqcloud.com/"
+      :before-upload="beforeUpload"
+      @change="handleChange"
+      :accept="uploadType + '/' + (uploadType == 'image' ? 'jpeg,image/jpg' : 'mp4')"
+      :file-list="fileList"
+      :remove="removeFile"
+      @preview="handlePreview"
+      :disabled="loadingElse || disabled"
+    >
+      <div v-if="fileList.length < fileCount || fileList.length < 1">
+        <a-progress v-if="loadingElse" :percent="percent" :show-info="false" />
+        <div>点击上传</div>
+      </div>
+    </a-upload>
+    <!-- <div style="color: red" v-if="sizeCheck">
+      {{ uploadType == 'image' ? '请上传jpg格式的图片,并且大小在2m之内' : '请上传mp4格式,大小在100m之内' }}
+    </div> -->
+    <a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
+      <img alt="example" style="width: 100%" :src="previewImage" v-if="uploadType == 'image'" />
+      <video :src="previewImage" v-else style="width: 100%" controls="controls">您的浏览器不支持 video 标签。</video>
+    </a-modal>
+  </div>
+</template>
+
+<script>
+import { stopOtherVideo, closeAllVideoFun } from '@/utils/videoControl' // 停止除当前外的其他视频播放,及停止所有视频播放的方法
+import { mapGetters } from 'vuex'
+import moment from 'moment'
+
+import BMF from 'browser-md5-file'
+
+import qs from 'qs'
+var COS = require('cos-js-sdk-v5')
+var cos = new COS({
+  SecretId: 'AKIDE6IpMi8fJQRCg1iuWzFajjRs43kbbets',
+  SecretKey: 'tXzuwMfplTTK3c9GFUyETilasvQfePu9',
+})
+var i = 0
+const oneKB = 1024
+
+function getBase64(file) {
+  return new Promise((resolve, reject) => {
+    const reader = new FileReader()
+    reader.readAsDataURL(file)
+    reader.onload = () => resolve(reader.result)
+    reader.onerror = (error) => reject(error)
+  })
+}
+export default {
+  name: 'upload-file',
+  components: {},
+  props: {
+    uploadType: {
+      //上传类型  值为  image/video,同时目录名称也是这样
+      type: String,
+      default() {
+        return 'image'
+      },
+    },
+    multiple: {
+      // true 可以批量上传  false 不可以
+      type: Boolean,
+      default() {
+        return true
+      },
+    },
+    fileCount: {
+      //最大上传数量
+      type: Number,
+      default() {
+        return 10
+      },
+    },
+    checkFile: {
+      //返回promise方法,判读文件是否上传过,进行上传拦截
+      type: Function,
+      default() {
+        return Promise.resolve()
+      },
+    },
+    disabled: {
+      type: Boolean,
+      default() {
+        return false
+      },
+    },
+    value: {
+      required: true,
+      default() {
+        return ''
+      },
+    },
+    size: {
+      type: Number,
+      default() {
+        if (this.sizeCheck) {
+          if (this.uploadType == 'image') {
+            return 2048
+          } else {
+            return 102400
+          }
+        }
+      },
+    },
+    sizeCheck: {
+      type: Boolean,
+      default() {
+        return true
+      },
+    },
+    onOversize: {
+      type: Function,
+      default() {
+        alert(`请选择${this.size}KB内的文件!`)
+      },
+    },
+  },
+  data() {
+    return {
+      fileList: [],
+      loadingElse: false,
+      imageUrl: '',
+      percent: 0,
+      previewVisible: false,
+      previewImage: '',
+      md5: '',
+      accountId: '',
+    }
+  },
+  filters: {},
+  computed: {},
+  mounted() {},
+  watch: {
+    //    fileListAll
+    // value: {
+    //   immediate: true,
+    //   handler(n, o) {
+    //     this.$nextTick(() => {
+    //       if (this.fileList && this.fileList.length == 0) {
+    //         if (typeof n == 'object') {
+    //           this.fileList = n.map((item, index) => {
+    //             return {
+    //               uid: index + 1,
+    //               name: index + 1,
+    //               status: 'done',
+    //               url: item,
+    //             }
+    //           })
+    //         } else {
+    //           if (n == '') {
+    //             this.fileList = []
+    //           } else {
+    //             this.fileList = [
+    //               {
+    //                 uid: 1,
+    //                 name: 1,
+    //                 status: 'done',
+    //                 url: n,
+    //               },
+    //             ]
+    //           }
+    //         }
+    //       } else {
+    //         if (n.length == 0 || n == '') {
+    //           this.clearAll()
+    //         }
+    //       }
+    //     })
+    //   },
+    //   deep: true,
+    // },
+  },
+  methods: {
+    handleCancel() {
+      closeAllVideoFun()
+      this.previewVisible = false
+    },
+    handleChange(info) {
+      if (info.file.status === 'uploading') {
+        this.loading = true
+        return
+      }
+      if (info.file.status === 'done') {
+        // Get this url from response in real world.
+        getBase64(info.file.originFileObj, (imageUrl) => {
+          this.imageUrl = imageUrl
+          this.loading = false
+        })
+      }
+    },
+    removeFile(file) {
+      // console.log(file)
+      var index = this.fileList.findIndex((v) => v.uid === file.uid)
+      this.fileList.splice(index, 1)
+      this.$emit('removeUpload', file)
+    },
+    async handlePreview(file) {
+      if (!file.url && !file.preview) {
+        file.preview = await getBase64(file.originFileObj)
+      }
+      this.previewImage = file.url || file.preview
+      this.previewVisible = true
+    },
+    beforeUpload(file) {
+      this.percent = 0
+      this.loadingElse = true
+      const fileOvesize = file.size > this.size * oneKB
+      // console.log(fileOvesize)
+      if (fileOvesize && this.sizeCheck) {
+        this.onOversize()
+        this.loadingElse = false
+        return
+      } else {
+        this.checkFile(file)
+          .then((res) => {
+            this.md5 = res.md5
+            this.accountId = res.accountId
+            this.cosUpload(file)
+          })
+          .catch(() => {
+            this.loadingElse = false
+          })
+        return new Promise(function (resolve, reject) {
+          reject()
+        })
+      }
+    },
+    clearAll() {
+      this.fileList = []
+    },
+    cosUpload(file) {
+      var that = this
+      let date = new Date()
+      let y = date.getFullYear()
+      let MM = date.getMonth() + 1
+      MM = MM < 10 ? '0' + MM : MM
+      let d = date.getDate()
+      d = d < 10 ? '0' + d : d
+      var timeElse = new Date().getTime()
+      var arr = file.name.split('.')
+
+      var str = ''
+      for (let i = 0; i < arr.length; i++) {
+        if (i == arr.length - 1) {
+        } else {
+          if (i == arr.length - 2) {
+            str += arr[i]
+          } else {
+            str += arr[i] + '.'
+          }
+        }
+      }
+      // console.log(str + '-' + timeElse + '.' + arr[arr.length - 1])
+      cos.putObject(
+        {
+          Bucket: 'media-1301855440',
+          /* 必须 */
+          Region: 'ap-chongqing',
+          /* 存储桶所在地域,必须字段 */
+          Key: that.uploadType + '/' + y + '-' + MM + '-' + d + '/' + str + '-' + timeElse + '.' + arr[arr.length - 1],
+          /* 必须 */
+          StorageClass: 'STANDARD',
+          Body: file, // 上传文件对象
+          onProgress: function (progressData) {
+            //进度条方法
+
+            that.percent = progressData.percent * 100
+          },
+          onTaskReady: function (tid) {
+            // console.log('onTaskReady', tid);
+          },
+          onTaskStart: function (info) {
+            //开始上传
+            // console.log('onTaskStart', info);
+          },
+        },
+        function (err, data) {
+          if (err) {
+            that.loadingElse = false
+            that.$message.error('上传失败!!!' + err)
+            return
+          }
+          // alert('成功')
+          that.loadingElse = false
+          if (that.fileList.length < that.fileCount) {
+            that.fileList.push({
+              uid: file.name,
+              name: file.name,
+              status: 'done',
+              url: '//' + data.Location,
+            })
+
+            // that.$emit('overUpload', that.fileList.map(item => {
+            //                 return item.url
+            //               }))
+            that.$emit('overUpload', that.fileList)
+
+            if (that.multiple) {
+              that.$emit(
+                'update:value',
+                that.fileList.map((item) => {
+                  return item.url
+                })
+              )
+            } else {
+              that.$emit(
+                'update:value',
+                that.fileList.map((item) => {
+                  return { url: item.url, signature: that.md5 }
+                })[0]
+              )
+             
+            }
+          } else {
+            that.$message.error('上传已达上限' + that.fileCount + '张')
+          }
+        }
+      )
+    },
+  },
+}
+</script>
+<style scoped>
+@import '~@assets/less/common.less';
+</style>

+ 13 - 3
src/config/router.config.js

@@ -1,4 +1,4 @@
-import {UserLayout, TabLayout, RouteView, BlankLayout, PageView} from '@/components/layouts'
+import { UserLayout, TabLayout, RouteView, BlankLayout, PageView } from '@/components/layouts'
 
 /**
  * 走菜单,走权限控制
@@ -10,7 +10,7 @@ export const asyncRouterMap = [
     path: '/',
     name: 'dashboard',
     component: TabLayout,
-    meta: {title: '首页'},
+    meta: { title: '首页' },
     redirect: '/dashboard/workplace',
     children: []
   },
@@ -65,6 +65,16 @@ export const constantRouterMap = [
         name: 'FStransfer',
         component: () => import(/* webpackChunkName: "fail" */ '@/views/user/FStransfer')
       },
+      {
+        path: 'new-batch',
+        name: 'newBatch',
+        component: () => import(/* webpackChunkName: "fail" */ '@/views/modules/kuaishouapp/newBatch')
+      },
+      {
+        path: 'lookPreview',
+        name: 'lookPreview',
+        component: () => import(/* webpackChunkName: "fail" */ '@/views/modules/kuaishouapp/newBatch/lookPreview')
+      }
     ]
   },
 
@@ -90,5 +100,5 @@ export const constantRouterMap = [
     name: 'errorPage',
     component: () => import(/* webpackChunkName: "fail" */ '@/views/errorPage')
   },
-  
+
 ]

+ 72 - 2
src/filters.js

@@ -81,9 +81,9 @@ const filters = {
         var data = {
             null: '-',
             1: 'CPM',
-            2: 'CPC',
+            2: '封面点击(CPC)',
             6: 'OCPC',
-            10: 'OCPM',
+            10: '转化(OCPM)',
         }
         return data[sta]
     },
@@ -104,6 +104,12 @@ const filters = {
             383: '授信',
             384: '完件',
             394: '订单提交',
+            324: '唤起应用',
+            715: '微信复制优化目标',
+            716: '多转化事件',
+            396:'注册优化目标',
+            731:'广告观看5次',
+            732:'广告观看10次',
         }
         return data[sta]
     },
@@ -256,6 +262,70 @@ const filters = {
 
         return data[val]
     },
+    //快手年龄
+    kuaishouAge(val) {
+        var data = {
+            18: '18-23岁',//'等于',
+            24: '24-30岁',//不等于,
+            31: '31-40岁',//大于
+            41: '41-49岁',//小于
+            50: '50+',//大于等于
+        }
+
+        return data[val]
+    },
+    //快手手机价格
+    kuaishouPrice(val) {
+        var data = {
+            1: '1500以下',
+            2: '1501~2000',
+            3: '2001~2500',
+            4: '2501~3000',
+            5: '3001~3500',
+            6: '3501~4000',
+            7: '4001~4500',
+            8: '4501~5000',
+            9: '5001~5500',
+            10: '5500以上',
+        }
+
+        return data[val]
+    },
+    //快手过滤以转化用户
+    kuaishouFilterConvertedLevel(val) {
+        var data = {
+            0: '不限',
+            1: '广告组',
+            2: '广告计划',
+            3: '本账户',
+            4: '公司主体',
+            5: 'APP'
+        }
+
+        return data[val]
+    },
+    //场景广告位
+    kuaishouSceneId(val) {
+        var data = {
+            1: '优选广告位',
+            3: '视频播放页广告',
+            6: '上下滑大屏广告',
+            7: '信息流广告',
+            5: "联盟广告"
+        }
+
+        return data[val]
+    },
+    platform(str) {
+        var data = {
+            1: 'Android应用下载',
+            2: 'Android网页游戏',
+            3: 'iOS应用下载',
+            4: 'iOS网页游戏'
+        }
+        return data[str]
+    }
+
 }
 
 // 获取当前月的第一天

+ 16 - 12
src/permission.js

@@ -4,44 +4,48 @@ import store from './store'
 import NProgress from 'nprogress' // progress bar
 import 'nprogress/nprogress.css' // progress bar style
 import notification from 'ant-design-vue/es/notification'
-import {ACCESS_TOKEN} from '@/store/mutation-types'
-import {generateIndexRouter} from "@/utils/util"
+import { ACCESS_TOKEN } from '@/store/mutation-types'
+import { generateIndexRouter } from "@/utils/util"
 
-NProgress.configure({showSpinner: false}) // NProgress Configuration
+NProgress.configure({ showSpinner: false }) // NProgress Configuration
 
 
-const whiteList = ['/user/login', '/user/register', '/user/register-result', '/user/alteration','/user/transfer-local','/errorPage','http://192.168.0.111:8088/jeecg-boot/sys/feishu/url','/user/FStransfer'] // no redirect whitelist
+const whiteList = ['/user/login', '/user/register', '/user/register-result', '/user/alteration', '/user/transfer-local', '/errorPage', '/user/new-batch', '/user/lookPreview', 'http://192.168.0.111:8088/jeecg-boot/sys/feishu/url', '/user/FStransfer'] // no redirect whitelist
 
 router.beforeEach((to, from, next) => {
   NProgress.start() // start progress bar
-
+  //if (whiteList.indexOf(to.path) !== -1) {
+    // 在免登录白名单,直接进入
+   // next()
+ //}
   if (Vue.ls.get(ACCESS_TOKEN)) {
     /* has token */
+
     if (to.path === '/user/login') {
-      next({path: '/dashboard/workplace'})
+      next({ path: '/dashboard/workplace' })
       NProgress.done()
     } else {
       if (store.getters.permissionList.length === 0) {
         store.dispatch('GetPermissionList').then(res => {
           const menuData = res.result.menu;
-          localStorage.setItem("roleCode",res.result.roleCode)
+          localStorage.setItem("roleCode", res.result.roleCode)
           if (menuData === null || menuData === "" || menuData === undefined) {
             return;
           }
           let constRoutes = [];
           constRoutes = generateIndexRouter(menuData);
           // 添加主界面路由
-          store.dispatch('UpdateAppRouter', {constRoutes}).then(() => {
+          store.dispatch('UpdateAppRouter', { constRoutes }).then(() => {
             // 根据roles权限生成可访问的路由表
             // 动态添加可访问路由表
             router.addRoutes(store.getters.addRouters)
             const redirect = decodeURIComponent(from.query.redirect || to.path)
             if (to.path === redirect) {
               // hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record
-              next({...to, replace: true})
+              next({ ...to, replace: true })
             } else {
               // 跳转到目的路由
-              next({path: redirect})
+              next({ path: redirect })
             }
           })
         })
@@ -51,7 +55,7 @@ router.beforeEach((to, from, next) => {
                description: '请求用户信息失败,请重试!'
              })*/
             store.dispatch('Logout').then(() => {
-              next({path: '/user/login', query: {redirect: to.fullPath}})
+              next({ path: '/user/login', query: { redirect: to.fullPath } })
             })
           })
       } else {
@@ -63,7 +67,7 @@ router.beforeEach((to, from, next) => {
       // 在免登录白名单,直接进入
       next()
     } else {
-      next({path: '/user/login', query: {redirect: to.fullPath}})
+      next({ path: '/user/login', query: { redirect: to.fullPath } })
       NProgress.done() // if current page is login will not trigger afterEach hook, so manually handle it
     }
   }

+ 1 - 0
src/utils/request.js

@@ -9,6 +9,7 @@ const key = "1"
 
 if (process.env.NODE_ENV == 'development') { 
     axios.defaults.baseURL = '/jeecg-boot'
+    
 } 
 else if (process.env.NODE_ENV == 'debug') { 
 } 

+ 1 - 0
src/views/modules/Statistics/KSAccountReport.vue

@@ -1094,6 +1094,7 @@ export default {
     //请求table的数据
     tableHttp(params){
       this.loading=true;
+      this.tableData=[]
           postAction('/ctop/kuaishou/dailyPage/report/list', {
               mediaId:this.mediaId,
               discount:this.discount,

+ 7 - 0
src/views/modules/Statistics/components/Treeselect.vue

@@ -19,6 +19,7 @@
       @input="emitValue"
       :limit="limit"
       :default-options="true"
+      :disabled="disabled"
       :limitText="
         (count) => {
           return '隐藏' + count + '条'
@@ -90,6 +91,12 @@ export default {
         return 2
       },
     },
+    disabled:{
+      type: Boolean,
+      default() {
+        return false
+      },
+    }
   },
   components: {
     Treeselect,

+ 19 - 4
src/views/modules/Statistics/components/ratioModal.vue

@@ -5,7 +5,7 @@ th div {
 </style>
 <template>
   <div class="data-display-statistics">
-    <a-modal title="环比展示" v-model="visible" @ok="handleOk" width="90%">
+    <a-modal title="环比展示" v-model="visible" @ok="handleOk" width="90%" :footer='null'>
       <div v-if="url">
         <video class="video" :src="url" controls="controls" style="height:200px;" v-show="showVideo">
           您的浏览器不支持 video 标签。
@@ -42,6 +42,10 @@ th div {
             <span v-if="record.statDate == '环比'">{{ conversionPrice | getBo }}</span>
             <span v-else>{{ conversionPrice | toFixtwo }}</span>
           </span>
+           <span slot="play3sRate" slot-scope="play3sRate,record">
+             <span v-if="record.statDate == '环比'">{{ play3sRate }}</span>
+            <span v-else>{{ play3sRate | getBo }}</span>
+           </span>
         </a-table>
       </a-card>
     </a-modal>
@@ -145,7 +149,15 @@ const columnsDetail = [
     key: 'conversionPrice',
     scopedSlots: { customRender: 'conversionPrice' },
     align: 'center'
-  }
+  },
+  {
+    title: '3s播放率',
+    dataIndex: 'play3sRate',
+    key: 'play3sRate',
+    scopedSlots: { customRender: 'play3sRate' },
+    align: 'center',
+    
+  },
 ]
 export default {
   name: 'ration-modal',
@@ -227,7 +239,8 @@ export default {
               conversionPrice: res.result.chainRatio.conversionPriceProportion,
               actionRatio: res.result.chainRatio.actionRatioProportion,
               actionCost: res.result.chainRatio.actionCostProportion,
-              photoShow: (res.result.chainRatio.showProportion * 100).toFixed(2) + '%'
+              photoShow: (res.result.chainRatio.showProportion * 100).toFixed(2) + '%',
+              play3sRate: (res.result.chainRatio.conversionPlay3sRate * 100).toFixed(2) + '%'
             }
             this.dataDetail.push(now)
             this.dataDetail.push(yesterday)
@@ -240,7 +253,9 @@ export default {
         }
       })
     },
-    handleOk() {}
+    handleOk() {
+      this.visible = true
+    }
   },
   watch: {},
   distoryed() {}

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

@@ -93,7 +93,7 @@
             size="middle"
             :customRow="rowClick"
             :loading="loading"
-            :scroll="{ x: 2300 }"
+            :scroll="{ x: 2600 }"
           >
             <div slot="url" slot-scope="url">
               <video @click.stop class="video" :src="url" controls="controls" style="height:200px;width:112.5px">
@@ -106,6 +106,7 @@
             <span slot="photoClickCost" slot-scope="photoClickCost">{{ photoClickCost | toFixtwo }}</span>
             <span slot="actionCost" slot-scope="actionCost">{{ actionCost | toFixtwo }}</span>
             <span slot="conversionPrice" slot-scope="conversionPrice">{{ conversionPrice | toFixtwo }}</span>
+            <span slot="play3sRate" slot-scope="play3sRate">{{ play3sRate | getBo }}</span>
             <span slot="operation" slot-scope="text,record">
                 <a href="javascript:;" @click.stop="showRelevantPeople(record)">查看相关人员</a>
             </span>
@@ -248,6 +249,14 @@ const columns = [
     sorter: (a, b) => a.conversionPrice - b.conversionPrice
   },
   {
+    title: '3s播放率',
+    dataIndex: 'play3sRate',
+    key: 'play3sRate',
+    scopedSlots: { customRender: 'play3sRate' },
+    align: 'center',
+    sorter: (a, b) => a.play3sRate - b.play3sRate
+  },
+  {
     title:'相关人员',
     dataIndex:'operation',
     key:'operation',
@@ -341,7 +350,15 @@ const columnsDetail = [
     key: 'conversionPrice',
     scopedSlots: { customRender: 'conversionPrice' },
     align: 'center'
-  }
+  },
+  {
+    title: '3s播放率',
+    dataIndex: 'play3sRate',
+    key: 'play3sRate',
+    scopedSlots: { customRender: 'play3sRate' },
+    align: 'center',
+    
+  },
 ]
 export default {
   name: 'data-display-statistics',

+ 44 - 2
src/views/modules/Statistics/newPlanStatic/newPlanStatic.vue

@@ -304,6 +304,10 @@
             </a-tab-pane>
             <a-tab-pane :key="2" :tab="(tabKey==1||tabKey==2&&value==1)?'有效计划数':'有效推广组'">       
             </a-tab-pane>
+
+            <a-button slot="tabBarExtraContent" @click="exportExcel" :loading="exportloading" v-show="tabKey==2">
+              导出报表
+            </a-button>
           </a-tabs>
           <a-table :columns="columns" :dataSource="dataTable" :pagination="false" :loading="loading" bordered>             
           </a-table> 
@@ -325,7 +329,7 @@ import moment from 'moment'
 import countTo from 'vue-count-to'
 import lifting from '../components/lifting'
 import {  getKsAccountReport, getKsDetail, getReportList } from '@api/video.js'
-import { getAction, postAction } from '@/api/manage'
+import { getAction, postAction ,downFile, downFilePost } from '@/api/manage'
 
 import timeCheck from '../components/timeCheck'
 
@@ -747,8 +751,9 @@ export default {
      datePick
   },
 
-  data: function() {
+  data() {
     return {
+      exportloading:false,
       value:2,
       KSaccountList:[],
       TTaccountList:[],
@@ -794,6 +799,43 @@ export default {
     }
   },
   methods: {
+    //导出报表
+        exportExcel() {
+            this.exportloading=true;
+            let url='';
+            let nameType=''
+            if(this.value==2){
+              url='/ctop/kuaishou/newGroup/report/excel'
+            }else{
+              url='/ctop/kuaishou/newPlan/report/excel'
+            }
+            if(this.value==2){
+                nameType='广告组'
+            }else if(this.value==1){
+                nameType='广告计划'
+            }
+            downFilePost(url,{
+              accountIds:this.accountId,
+              userId:this.operate || '',
+              startDate:this.dateValue[0].format('YYYY-MM-DD'),
+              endDate:this.dateValue[1].format('YYYY-MM-DD'),
+              target:this.tableTab=='1'?'new':'valid',
+              order:this.order
+            }).then(res => {
+                this.exportloading=false;
+                let blob = new Blob([res], {
+                    type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
+                })
+                let downloadElement = document.createElement('a')
+                let href = window.URL.createObjectURL(blob) //创建下载的链接
+                downloadElement.href = href
+                downloadElement.download = moment().format('YYYY-MM-DD') + nameType+'.xlsx' //下载后文件名
+                document.body.appendChild(downloadElement)
+                downloadElement.click() //点击下载
+                document.body.removeChild(downloadElement) //下载完成移除元素
+                window.URL.revokeObjectURL(href) //释放掉blob对象
+            })
+        },
     dataTypeChange(e){
       console.log(e.target.value)
         if(this.value==2){

+ 49 - 16
src/views/modules/advertiser/AdvertiserList.vue

@@ -19,15 +19,13 @@
                 @search="getList"
               >
                 <a-select-option :value="item.id" v-for="(item, index) of list" :key="index">
-                  {{
-                  item.name
-                  }}
+                  {{ item.name }}
                 </a-select-option>
               </a-select>
             </a-form-item>
           </a-col>
           <a-col :md="8" :sm="8">
-            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+            <span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
               <a-button type="primary" @click="searchQueryOne" icon="search">查询</a-button>
               <a-button type="primary" @click="searchRe" icon="reload" style="margin-left: 8px">重置</a-button>
             </span>
@@ -44,18 +42,18 @@
       <a-tab-pane key="product" tab="产品列表">
         <a-tag
           color="blue"
-          style="height:30px;line-height:30px;font-size:14px;margin-bottom:20px"
+          style="height: 30px; line-height: 30px; font-size: 14px; margin-bottom: 20px"
           v-if="queryParam.advertiserId"
         >
-          {{advertiserName}}
+          {{ advertiserName }}
           <a-icon type="close" @click="clear('advertiserId')" />
         </a-tag>
-        <a-row :gutter="24" style="margin-bottom:20px">
+        <a-row :gutter="24" style="margin-bottom: 20px">
           <a-col :md="8" :sm="8">
             <a-input placeholder="请输入产品名称" v-model="queryParam.productName"></a-input>
           </a-col>
           <a-col :md="8" :sm="8">
-            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+            <span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
               <a-button type="primary" @click="searchQueryOne" icon="search">查询</a-button>
             </span>
           </a-col>
@@ -64,18 +62,18 @@
       <a-tab-pane key="project" tab="项目列表">
         <a-tag
           color="blue"
-          style="height:30px;line-height:30px;font-size:14px;margin-bottom:20px"
+          style="height: 30px; line-height: 30px; font-size: 14px; margin-bottom: 20px"
           v-if="queryParam.productId"
         >
-          {{advertiserName?advertiserName+' / '+productName:productName}}
+          {{ advertiserName ? advertiserName + ' / ' + productName : productName }}
           <a-icon type="close" @click="clear('productId')" />
         </a-tag>
-        <a-row :gutter="24" style="margin-bottom:20px">
+        <a-row :gutter="24" style="margin-bottom: 20px">
           <a-col :md="8" :sm="8">
             <a-input placeholder="请输入项目名称" v-model="queryParam.projectName"></a-input>
           </a-col>
           <a-col :md="8" :sm="8">
-            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+            <span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
               <a-button type="primary" @click="searchQueryOne" icon="search">查询</a-button>
             </span>
           </a-col>
@@ -96,6 +94,25 @@
         :loading="loading"
         @change="handleTableChange"
       >
+        <span slot="ocpxActionType" slot-scope="text">
+          <div v-if="text">
+            <span v-for="(item, index) of JSON.parse(text)" :key="index"
+              >{{ item | ocpxActionType }}{{ index == JSON.parse(text).length - 1 ? '' : ',' }}</span
+            >
+          </div>
+          <div v-else>-</div>
+
+          <!-- {{ text | ocpxActionType }} -->
+        </span>
+        <span slot="bidType" slot-scope="text">
+          <div v-if="text && JSON.parse(text).length > 0">
+            <span v-for="(item, index) of JSON.parse(text)" :key="index"
+              >{{ item | bidType }}{{ index == JSON.parse(text).length - 1 ? '' : ',' }}</span
+            >
+          </div>
+          <div v-else>-</div>
+        </span>
+
         <span slot="action" slot-scope="text, record">
           <a @click="handleEdit(record)">编辑</a>
 
@@ -105,7 +122,7 @@
           </a-popconfirm>
         </span>
         <span slot="actionProduct" slot-scope="text, record">
-          <a @click="handleEditElse(record,'product')">编辑</a>
+          <a @click="handleEditElse(record, 'product')">编辑</a>
 
           <a-divider type="vertical" />
           <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
@@ -113,7 +130,7 @@
           </a-popconfirm>
         </span>
         <span slot="actionProject" slot-scope="text, record">
-          <a @click="handleEditElse(record,'project')">编辑</a>
+          <a @click="handleEditElse(record, 'project')">编辑</a>
 
           <a-divider type="vertical" />
           <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
@@ -122,8 +139,8 @@
         </span>
         <span slot="maxBid" slot-scope="text">{{ text / 1000 }}</span>
         <span slot="maxDeepCpaBid" slot-scope="text">{{ text / 1000 }}</span>
-        <a slot="name" slot-scope="text,record" @click="toProduct(record,'product')">{{text}}</a>
-        <a slot="productName" slot-scope="text,record" @click="toProduct(record,'project')">{{text}}</a>
+        <a slot="name" slot-scope="text, record" @click="toProduct(record, 'product')">{{ text }}</a>
+        <a slot="productName" slot-scope="text, record" @click="toProduct(record, 'project')">{{ text }}</a>
       </a-table>
     </div>
     <!-- table区域-begin -->
@@ -256,6 +273,22 @@ const projectColumns = [
     },
   },
   {
+    title: '优化目标',
+    align: 'center',
+    dataIndex: 'bidType',
+    scopedSlots: {
+      customRender: 'bidType',
+    },
+  },
+  {
+    title: '转化目标',
+    align: 'center',
+    dataIndex: 'ocpxActionType',
+    scopedSlots: {
+      customRender: 'ocpxActionType',
+    },
+  },
+  {
     title: '供应商',
     align: 'center',
     dataIndex: 'supplierCode_dictText',

+ 2 - 1
src/views/modules/advertiser/ProjectList.vue

@@ -301,7 +301,8 @@ export default {
         715: '微信复制优化目标',
         716: '多转化事件',
         396:'注册优化目标',
-        732: '广告观看10次'
+        731:'广告观看5次',
+        732:'广告观看10次',
       }
       return data[sta]
     },

+ 2 - 0
src/views/modules/advertiser/ProjectMemberList.vue

@@ -850,6 +850,7 @@ export default {
     },
     searchReset() {
       this.keyWord = ''
+      this.ipagination.current = 1
       // this.dataSource = this.dataElse
       if (this.noTitleKey == 'participation') {
         this.getParticipateList()
@@ -858,6 +859,7 @@ export default {
       }
     },
     searchQuery() {
+      this.ipagination.current=1
       if (this.noTitleKey == 'participation') {
         this.getParticipateList()
       } else {

+ 77 - 30
src/views/modules/advertiser/modules/ProjectModal.vue

@@ -30,7 +30,7 @@
           :labelCol="labelCol"
           :wrapperCol="wrapperCol"
           label="供应商"
-          v-if="model.mediaId=='2'||model.mediaId=='4'"
+          v-if="model.mediaId == '2' || model.mediaId == '4'"
         >
           <a-select
             optionFilterProp="children"
@@ -38,14 +38,8 @@
             :filterOption="filterOption"
             v-decorator="['supplierCode', validatorRules.supplierCode]"
           >
-            <a-select-option
-              :value="item.supplierCode"
-              v-for="(item, index) of supplierList"
-              :key="index"
-            >
-              {{
-              item.supplierName
-              }}
+            <a-select-option :value="item.supplierCode" v-for="(item, index) of supplierList" :key="index">
+              {{ item.supplierName }}
             </a-select-option>
           </a-select>
         </a-form-item>
@@ -59,9 +53,7 @@
             v-decorator="['advertiserId', validatorRules.advertiserId]"
           >
             <a-select-option :value="item.id" v-for="(item, index) of list" :key="index">
-              {{
-              item.name
-              }}
+              {{ item.name }}
             </a-select-option>
           </a-select>
         </a-form-item>
@@ -71,38 +63,64 @@
             showSearch
             :filterOption="filterOption"
             v-decorator="['productId', validatorRules.productId]"
-            :disabled="getFormFieldValue('advertiserId')==''||getFormFieldValue('advertiserId')==null"
+            :disabled="getFormFieldValue('advertiserId') == '' || getFormFieldValue('advertiserId') == null"
           >
             <a-select-option :value="item.id" v-for="(item, index) of listProduct" :key="index">
-              {{
-              item.productName
-              }}
+              {{ item.productName }}
             </a-select-option>
           </a-select>
         </a-form-item>
         <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="最高出价">
-          <a-input
-            placeholder="请输入最高出价"
-            v-decorator="['maxBid', validatorRules.maxBid]"
-            addonAfter="元"
-          />
+          <a-input placeholder="请输入最高出价" v-decorator="['maxBid', validatorRules.maxBid]" addonAfter="元" />
         </a-form-item>
         <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="最高转化出价">
           <a-input placeholder="最高转化出价" v-decorator="['maxDeepCpaBid']" addonAfter="元" />
         </a-form-item>
+        <div v-if="model.mediaId == '2' || model.mediaId == '4'">
+          <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="优化目标">
+            <a-select
+              v-decorator="['bidType', { rules: [{ required: true, message: '请输入表单名称' }], initialValue: 2 }]"
+              mode="multiple"
+            >
+              <a-select-option :value="2">点击数</a-select-option>
+              <a-select-option :value="10">OCPM</a-select-option>
+              <a-select-option :value="6">OCPC</a-select-option>
+            </a-select>
+          </a-form-item>
+          <div v-if="Array.isArray(getFormFieldValue('bidType'))">
+            <a-form-item
+              label="转化目标"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              v-show="
+                getFormFieldValue('bidType').findIndex((item) => item == 10) > -1 ||
+                getFormFieldValue('bidType').findIndex((item) => item == 6) > -1
+              "
+            >
+              <a-select v-model="model.ocpxActionType" mode="multiple">
+                <a-select-option :value="2">行为数</a-select-option>
+                <a-select-option :value="item.ocpxActionType" v-for="(item, index) in ocpxList" :key="index">{{
+                  item.ocpxActionName
+                }}</a-select-option>
+              </a-select>
+            </a-form-item>
+          </div>
+        </div>
+
         <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="销售">
           <a-select
             showSearch
             optionFilterProp="children"
             style="width: 100%"
             :filterOption="filterOption"
-            v-decorator="['saleId', { rules: [{  required: true,message: '请选择销售' }] }]"
+            v-decorator="['saleId', { rules: [{ required: true, message: '请选择销售' }] }]"
           >
             <a-select-option
               v-for="appModel in optionsElse"
               :key="appModel.userId + new Date().getTime()"
               :value="appModel.userId"
-            >{{ appModel.realName }}&#12288;&#12288;{{ appModel.roleName }}</a-select-option>
+              >{{ appModel.realName }}&#12288;&#12288;{{ appModel.roleName }}</a-select-option
+            >
           </a-select>
         </a-form-item>
         <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="运营负责人">
@@ -119,7 +137,8 @@
               v-for="appModel in options"
               :key="appModel.userId + new Date().getTime()"
               :value="appModel.userId"
-            >{{ appModel.realName }}&#12288;&#12288;{{ appModel.roleName }}</a-select-option>
+              >{{ appModel.realName }}&#12288;&#12288;{{ appModel.roleName }}</a-select-option
+            >
           </a-select>
         </a-form-item>
         <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="设计负责人">
@@ -136,7 +155,8 @@
               v-for="appModel in options"
               :key="appModel.userId + new Date().getTime()"
               :value="appModel.userId"
-            >{{ appModel.realName }}&#12288;&#12288;{{ appModel.roleName }}</a-select-option>
+              >{{ appModel.realName }}&#12288;&#12288;{{ appModel.roleName }}</a-select-option
+            >
           </a-select>
         </a-form-item>
       </a-form>
@@ -197,6 +217,7 @@ export default {
       optionsElse: [],
       supplierList: [],
       editAll: false,
+      ocpxList: [],
     }
   },
   created() {
@@ -204,7 +225,7 @@ export default {
   },
   methods: {
     validateInputCode(rule, value, callback) {
-      if ( value > 0) {
+      if (value > 0) {
         callback()
       } else {
         callback('请输入大于0的最高报价!')
@@ -237,7 +258,7 @@ export default {
       params.pageSize = 1000
       params.pageNo = 1
       console.log(params)
-      getAction(this.url.getList,params)
+      getAction(this.url.getList, params)
         .then((res) => {
           if (res.success) {
             console.log(res)
@@ -268,6 +289,7 @@ export default {
     edit(record) {
       this.getSupplierList()
       this.getList()
+      this.getOcpxList()
       if (record.advertiserId) {
         this.editAll = true
         getAction('/ctop/product/list', { advertiserId: record.advertiserId, pageSize: 1000 }).then((res) => {
@@ -276,7 +298,18 @@ export default {
           }
         })
       }
-      var params = { ...record }
+
+      // var params = { ...record }
+      if (record.mediaId == '2' || record.mediaId == '4') {
+        console.log(record)
+        var params = { ...record }
+        params.bidType = record.bidType == null || record.bidType == '' ? [] : JSON.parse(record.bidType)
+        params.ocpxActionType =
+          record.ocpxActionType == null || record.ocpxActionType == '' ? [] : JSON.parse(record.ocpxActionType)
+      } else {
+        var { ocpxActionType, bidType, ...params } = record
+        this.showDian = false
+      }
 
       console.log(record)
       this.form.resetFields()
@@ -303,7 +336,8 @@ export default {
               'industryCode',
               'supplierCode',
               // 'advertiserType',
-              'saleId'
+              'saleId',
+              'bidType'
             )
           )
         } else {
@@ -322,7 +356,9 @@ export default {
               'industryCode',
               'supplierCode',
               // 'advertiserType',
-              'saleId'
+              'saleId',
+              'bidType',
+              'ocpxActionType'
             )
           )
         }
@@ -374,6 +410,10 @@ export default {
           formData.responsibleId = values.responsibleId
           formData.designResponsibleId = values.designResponsibleId
           formData.userId = formData.userId ? formData.userId : that.userInfo().id
+
+          formData.ocpxActionType =
+            formData.bidType == 2 ? JSON.stringify([0]) : JSON.stringify(formData.ocpxActionType)
+          formData.bidType = JSON.stringify(formData.bidType)
           httpAction(httpurl, formData, method)
             .then((res) => {
               if (res.success) {
@@ -400,6 +440,13 @@ export default {
       console.log(valueName, key)
       this.resId = key
     },
+    getOcpxList() {
+      this.getAction('/ocpx/kuaiShouOcpxActionTypeConfig/list').then((res) => {
+        if (res.success) {
+          this.ocpxList = res.result
+        }
+      })
+    },
   },
 }
 </script>

+ 1 - 1
src/views/modules/advertiser/modules/projectListModal.vue

@@ -115,7 +115,7 @@
 
                  <a-select-option :value="715">微信复制优化目标</a-select-option>
                  <a-select-option :value="716">多转化事件</a-select-option>
-
+                 <a-select-option :value="731">广告观看5次</a-select-option>
                  <a-select-option :value="732">广告观看10次</a-select-option>
               </a-select>
             </a-form-item>

+ 1 - 1
src/views/modules/autoLaunch/appIdList.vue

@@ -244,7 +244,7 @@ export default {
             editID:0,
 
             url: {               
-                list:'/ai/aiKuaiShouAppInfo/list',
+                list:'/ai/aiKuaiShouAppInfo/pageList',
                 delete:'/ctop/aiKuaishouAdvertiserStrategy/delete',
             },
 

+ 252 - 58
src/views/modules/autoLaunch/configLaunchInfo.vue

@@ -133,13 +133,14 @@
                                 <a-select v-decorator="['appId', { rules: [{ required: true, message: '请选择目标应用' }] }]" showSearch allowClear
                                     placeholder="选择应用目标" optionFilterProp="children" style="width: 500px"  
                                    :filterOption="filterOption" @change="appIdChange" :mode="getFormData('singleAppid')==1?'defalut':'multiple'" :maxTagCount='1'>
-                                    <!-- <a-select-option value="0">请选择目标应用</a-select-option> -->
+                                    <a-select-option v-if="getFormData('singleAppid')==0" :value='0' @click="selectAllAppId">选择以下全部</a-select-option>
                                     <a-select-option v-for="appModel in appList" :key="appModel.appId" :value="appModel.appId">
                                         {{ appModel.appName }}&#12288;&nbsp;&#12288; {{ appModel.appVersion }}&#12288;&#12288;&#12288;{{
                                         appModel.platform | platform
                                         }}
                                     </a-select-option>
                                 </a-select>
+                                <a-button type="primary" @click="addApplication" style="margin-left:10px" :loading="tongbuLoading">刷新应用</a-button>
                             </a-form-item>
                         
                         </div>
@@ -179,7 +180,7 @@
                         <div class="hint-item"></div>
                         <div class="label-item">
                         <div class="text-item">转化追踪</div>
-                        <div class="required-item"></div>
+                        <!-- <div class="required-item"></div> -->
                         </div>
                         <div class="input-item">
                             <a-form-item  >
@@ -354,7 +355,7 @@
                                                 <template slot="populationType" slot-scope="populationType"> {{ populationType |customCrowdHandler}} </template>
                                             </a-table>
                                         </a-tab-pane>
-                                       
+                                        <a-button slot="tabBarExtraContent" type='primary' @click="refreshPopulation" :loading='refreshPopulationLoading'>刷新人群包</a-button>
                                     </a-tabs>
                                     
                             </div>  
@@ -380,7 +381,28 @@
                         </div>
                     </div>
                     
-                    
+                    <div class="row-item" >
+                        <div class="hint-item"></div>
+                        <div class="label-item">
+                        <div class="text-item">是否开启智能扩量</div>
+                        <div class="required-item"></div>
+                        </div>
+                        <div class="input-item">
+                        <a-form-item>
+                            <a-radio-group v-decorator="['isOpen', { initialValue: 0 }]" @change="isOpenChange">
+                                <a-radio-button :value='0'>关闭</a-radio-button>
+                                <a-radio-button :value="1">开启</a-radio-button>                            
+                            </a-radio-group>
+                        </a-form-item>
+                        <div style="width: 400px; margin-top: 24px;" class="inventoryTypes" v-show="getFormData('isOpen')==1">
+                            <div class="inventory-tags-lists-container">
+                                <a-checkbox v-model="noAgeBreak">不可突破年龄</a-checkbox>
+                                <a-checkbox v-model="noGenderBreak">不可突破性别</a-checkbox>
+                                <a-checkbox v-model="noAreaBreak">不可突破地域</a-checkbox>
+                            </div>
+                        </div>                  
+                        </div>
+                    </div>
             </div>
             <div class="ad-range2" v-if="useDirectional==0">
                 <div style="position:relative" class="ad-range2-title">
@@ -521,6 +543,7 @@
                             
 
                                 <a-select-option :value="2">行为数</a-select-option>
+                                <!-- v-if="getFormData('campaignType') == 2 && groupTypeData.isActivate == 1 -->
                                 <a-select-option :value="180"
                                 v-if="getFormData('campaignType') == 2 && groupTypeData.isActivate == 1">激活</a-select-option>
                                 <a-select-option :value="53" v-if="
@@ -554,7 +577,7 @@
                         </a-form-item>
                         </div>
                     </div>
-                    <div class="row-item" v-if="(getFormData('ocpxActionType') == 180 || getFormData('ocpxActionType') == 53) &&groupTypeData.deepConversionTypes&&groupTypeData.deepConversionTypes.length > 0 ">
+                    <div class="row-item" v-if="(getFormData('ocpxActionType') == 180 || getFormData('ocpxActionType') == 53) && groupTypeData.deepConversionTypes && groupTypeData.deepConversionTypes.length > 0 ">
                         <div class="hint-item"></div>
                         <div class="label-item">
                         <div class="text-item">深度转化目标</div>
@@ -563,7 +586,7 @@
                         <div class="input-item">
                         <a-form-item>
                             <a-select v-decorator="['deepConversionType']" allowClear style="width: 200px">
-                                <a-select-option v-for="(items, index) of groupTypeData.deepConversionTypes" :key="index">
+                                <a-select-option v-for="(items, index) of groupTypeData.deepConversionTypes" :key="index" :value='items.deepConversionType'>
                                 {{ items.desc }}</a-select-option>
                             </a-select>
                         </a-form-item>
@@ -637,12 +660,13 @@
                         </div>    
                     </div>
                     
-                    <div class="row-item" v-if="(getFormData('ocpxActionType') == 180 || getFormData('ocpxActionType') == 53) &&groupTypeData.deepConversionTypes&&groupTypeData.deepConversionTypes.length > 0 ">
+                    <div class="row-item" v-if="(getFormData('ocpxActionType') == 180 || getFormData('ocpxActionType') == 53) && groupTypeData.deepConversionTypes && groupTypeData.deepConversionTypes.length > 0 ">
                         <div class="hint-item">
                         </div>
                         <div class="label-item">
                             <div class="text-item">深度转化目标出价</div>
                             <!-- <div class="required-item"></div> -->
+                            <!-- {{getFormData('deepConversionBid')}} -->
                         </div>
                         <div class="input-item">
                             <a-form-item>
@@ -699,6 +723,22 @@
                     <div class="row-item">
                         <div class="hint-item"></div>
                         <div class="label-item">
+                        <div class="text-item">创意制作方式</div>
+                        <div class="required-item"></div>
+                        </div>
+                        <div class="input-item">
+                        <a-form-item>
+                            <a-radio-group v-decorator="['openProgramCreate', { initialValue:2 }]">
+                                <a-radio-button :value='2'>不限</a-radio-button>
+                                <a-radio-button :value="0">自定义</a-radio-button>                            
+                                <a-radio-button :value="1">程序化</a-radio-button>                            
+                            </a-radio-group>
+                        </a-form-item>                       
+                        </div>
+                    </div>
+                    <div class="row-item">
+                        <div class="hint-item"></div>
+                        <div class="label-item">
                         <div class="text-item">是否开启历史素材挖掘</div>
                         <div class="required-item"></div>
                         </div>
@@ -835,7 +875,7 @@
                         <a-form-item >
                             <a-cascader
                                 :options="createOptions"
-                                v-decorator="['creativeCategory',{ rules: [{ required: whiteList.creative_category_switch, message: '创意分类必填' }] }]"
+                                v-decorator="['creativeCategory',{ rules: [{ initialValue:[],required: whiteList.creative_category_switch==1, message: '创意分类必填' }] }]"
                                 :fieldNames="fieldNames"
                                 placeholder="请选择创意分类"
                                 
@@ -855,7 +895,7 @@
                             mode="tags"
                             style="width: 100%"
                             placeholder="按回车生成标签"
-                            v-decorator="['creativeTag', { validator: creativeTagValid }]"
+                            v-decorator="['creativeTag',{rules: [ {initialValue:[],required: whiteList.creative_category_switch==1, validator: creativeTagValid }]}]"
                             dropdownClassName="display-none-selset"
                             :token-separators="[',', ' ', ',']"
                             >
@@ -1137,10 +1177,10 @@ let retargetColumns=[
     },
     {
         title: '所属账号',
-        dataIndex: 'accountName',
+        dataIndex: 'accountId',
         sorter: true,
         width: '40%',
-        scopedSlots: { customRender: 'accountName' },
+        scopedSlots: { customRender: 'accountId' },
     },
     
 ]
@@ -1158,7 +1198,12 @@ const plainOptions = [
       value: 3,
       label: '视频播放页广告'
     },
+    {
+      value: 5,
+      label: '联盟广告'
+    },
 ];
+
 export default {
     components: {
         // selectCheckAll,
@@ -1171,6 +1216,11 @@ export default {
     },
     data() {
         return {
+            tongbuLoading:false,
+            refreshPopulationLoading:false,
+            noAreaBreak:false,
+            noGenderBreak:false,
+            noAgeBreak:false,
             regionList:[],
             editRecordId:'',
             spinning:false,
@@ -1197,7 +1247,7 @@ export default {
                 children: 'child',
             },
             createOptions: [],
-            appStore: ['huawei', 'oppo', 'vivo', 'xiaomi', 'meizu', 'smartisan'],
+            appStore: ["huawei", "oppo", "vivo", "xiaomi", "meizu", "smartisan"],
             sysType:1,
             indeterminateDirectional:false,
             checkAllDirectional:false,
@@ -1318,13 +1368,8 @@ export default {
                 //     }
                 // })
                 this.getAppList()
-                getAction('/kuaishou/batch/getIsActivate', {
-                    accountId: this.accountId
-                }).then(res => {
-                    if (res.success) {
-                        this.groupTypeData = res.result
-                    }
-                })
+                
+               
 
                 getAction('/kuaishou/batch/getCreativeCategory', {
                     accountId:this.accountId,
@@ -1339,7 +1384,8 @@ export default {
             }else{
 
             }
-        }
+        },
+        
     },
     computed: {
             
@@ -1383,8 +1429,71 @@ export default {
             },
     },
     methods: {
+        refreshPopulation(){
+            if(this.accountId){
+                this.refreshPopulationLoading = true
+                // this.$refs.application.showApplication()
+                getAction('/kuaishou/batch/pullPopulationList', {
+                    accountId: this.accountId
+                }).then(res => {
+                    if (res.success) {
+                        this.refreshPopulationLoading = false
+                        this.$message.success(res.message)
+                        this.retargetTabChange()
+                    } else {
+                        this.refreshPopulationLoading = false
+                        this.$message.error(res.message)
+                    }
+                })
+            }else{
+                this.$message.error('请先选择账户')
+            }
+        },
+        addApplication() {
+            if(this.accountId){
+                this.tongbuLoading = true
+                // this.$refs.application.showApplication()
+                getAction('/kuaishou/batch/syncAppList', {
+                accountId: this.accountId
+                }).then(res => {
+                if (res.success) {
+                    this.tongbuLoading = false
+                    this.$message.success(res.message)
+                    this.getAppList()
+                } else {
+                    this.tongbuLoading = false
+                    this.$message.error(res.message)
+                }
+                })
+            }else{
+                this.$message.error('请先选择账户')
+            }
+            
+        },
+        getIsActivate(val){
+            let params={};
+                params.accountId=this.accountId;
+                params.campaignType=this.getFormData('campaignType');
+                params.appId=val
+                
+                getAction('/kuaishou/batch/getIsActivate',params).then(res => {
+                    if (res.success) {
+                        this.groupTypeData = res.result
+                    }
+                })
+        },
+
+        isOpenChange(e){
+            this.noAreaBreak=false;
+            this.noGenderBreak=false;
+            this.noAgeBreak=false;
+        },
+        selectAllAppId(){
+           
+            console.log(this.getFormData('appId'))
+        },
         singleAppidChange(e){
-            console.log(e.target.value,this.getFormData('appId'));
+            // console.log(e.target.value,this.getFormData('appId'));
             this.form.setFieldsValue({
                 appId:undefined
             })
@@ -1489,13 +1598,15 @@ export default {
 
 
         creativeTagValid(rule, value, callback) {
-            if (value.length > 10) {
-                callback('创意标签最多填写10个,请删减')
-            } else if(value.length == 0){
-                if(this.whiteList.creative_category_switch==1){
+            console.log(rule, value, callback)
+            if(value.length == 0 || value==undefined){
+                // console.log(1)
                    callback('创意标签必须填写') 
-                }
-            }else {
+                
+            }else if (value.length > 10) {
+                callback('创意标签最多填写10个,请删减')
+            }else{
+                // console.log(2)
                 callback()
             }
         },
@@ -1540,7 +1651,38 @@ export default {
             this.siteList=[]
             
             // this.getPageList(val)
+            if(this.getFormData('singleAppid')==0){
+                if(val.indexOf(0)>-1){
+                    let appidArr=this.appList.map(item=>{
+                        return item.appId
+                    })
+                    // setTimeout(()=>{
+                        
+                    //     this.form.setFieldsValue({
+                    //         appId:appidArr
+                    //     })
+                    // },0)
+                    this.$nextTick(()=>{
+                        this.form.setFieldsValue({
+                            appId:appidArr
+                        })
+                    })
+                
+                }
+            }
             
+           if(val!=undefined || val.length>0){
+                if(this.getFormData('campaignType')==2){
+                    
+                    if(this.getFormData('singleAppid')==1){
+                        this.getIsActivate(val)
+                    }else{
+                        this.getIsActivate(val[0])
+                    }
+                    
+                }
+               
+           }
         },
         disabledDate(current) {
            
@@ -1624,7 +1766,7 @@ export default {
                                 ele.key=ele.orientationId   
                                 ele.id= ele.orientationId 
                                 ele.name=ele.orientationName+"("+ele.orientationId+")"
-                                ele.accountName=this.accountInfo.title
+                                // ele.accountName=this.accountInfo.title
                                 ele.accountId=this.accountId               
                             })
                             // this.retargetData=res.data;
@@ -1759,7 +1901,7 @@ export default {
         this.$nextTick(()=>{
   
             this.form.validateFields((err, values) => {
-                   
+                console.log(values) 
                 if (!err) {                   
                     this.goNextloading=true;
                     if(this.district!='NONE'){
@@ -1815,10 +1957,15 @@ export default {
                     // }
                     if(this.sysType==1&&this.getData('useAppMarket')){
                         values.appStore=JSON.stringify(this.appStore)
+                    }else if(this.sysType==1&&!this.getData('useAppMarket')){
+                        values.appStore="[]"
                     }
                     if(values.cpaBid){
                         values.cpaBid=parseInt(values.cpaBid*1000)
                     }
+                    if(values.deepConversionBid){
+                        values.deepConversionBid=parseInt(values.deepConversionBid*1000)
+                    }
                  
                     if(values.creativeCategory&&values.creativeCategory.length>0){
                         values.creativeCategory=values.creativeCategory[values.creativeCategory.length-1]
@@ -1829,6 +1976,11 @@ export default {
                     values.accountId = this.accountId
                    
                     values.creativeTag=values.creativeTag?JSON.stringify(values.creativeTag):undefined
+
+                    values.noAreaBreak=this.noAreaBreak?1:0
+                    values.noGenderBreak=this.noGenderBreak?1:0
+                    values.noAgeBreak=this.noAgeBreak?1:0
+
                     console.log('Received values of form: ', values)
                     let url=''
                     if(this.editRecordId){
@@ -2039,17 +2191,49 @@ export default {
                     
                     this.accountId=res.result.accountId;
                     this.description=res.result.description
-                    res.result.creativeCategory=[parseInt(res.result.creativeCategory/10000),parseInt(res.result.creativeCategory/100),res.result.creativeCategory]
+                    res.result.creativeCategory=res.result.creativeCategory?[parseInt(res.result.creativeCategory/10000),parseInt(res.result.creativeCategory/100),res.result.creativeCategory]:[]
+                    //  res.result.creativeTag=res.result.creativeTag?res.result.creativeTag:[]
+                    new Promise((resolve,reject)=>{
+                        getAction('/kuaishou/batch/getIsActivate', {
+                            accountId: this.accountId
+                        }).then(res => {
+                            if (res.success) {
+                                this.groupTypeData = res.result
+                                resolve()
+                            }
+                        })
+                    }).then(r=>{
+
+                    
                     this.form.setFieldsValue({
                         ...res.result,
-                        creativeTag:res.result.creativeTag?JSON.parse(res.result.creativeTag):undefined,
+                        creativeTag:res.result.creativeTag?JSON.parse(res.result.creativeTag):[],
                         useAppMarket:res.result.useAppMarket==1?true:false,
-                        
+                        isOpen:res.result.isOpen?res.result.isOpen:0,
                         cpaBid:res.result.cpaBid/1000,
                         appId:res.singleAppid?JSON.parse(res.result.appIdArray)[0]:JSON.parse(res.result.appIdArray)
                     })
+                    if((this.getFormData('ocpxActionType') == 180 || this.getFormData('ocpxActionType') == 53) && this.groupTypeData.deepConversionTypes&&this.groupTypeData.deepConversionTypes.length > 0){
+                        setTimeout(()=>{
+                        this.form.setFieldsValue({
+                            deepConversionType:res.result.deepConversionType,
+                        })
+                        if(res.result.deepConversionBid!=null){
+                            this.form.setFieldsValue({
+                                deepConversionBid:res.result.deepConversionBid/1000,  
+                            }) 
+                        }
+                    },0)
+                    }
+                    
+                    console.log(this.getFormData('deepConversionBid'))
+                    this.noAreaBreak=res.result.noAreaBreak?true:false
+                    this.noGenderBreak=res.result.noGenderBreak?true:false
+                    this.noAgeBreak=res.result.noAgeBreak?true:false
+                    this.appStore=res.result.appStore?JSON.parse(res.result.appStore):this.appStore
                     this.ageArr=[];
                     this.ageArr=JSON.parse(JSON.stringify(ageArr))
+                    
                     let agesRange=res.result.agesRange?JSON.parse(res.result.agesRange):[]
                     if(agesRange.length>0){
                         agesRange.forEach((item,index)=>{                   
@@ -2111,11 +2295,15 @@ export default {
 
                     
                     this.spinning=false;
+                                                     
+               
+                    })
                 })
             }
         },
 
         getpopulationlist(){
+            this.retargetDataAll=[]
             getAction('/kuaishou/batch/getPopulationList',{
                 accountId:this.accountId
             }).then((res)=>{
@@ -2130,13 +2318,22 @@ export default {
                         ele.accountId=this.accountId               
                     })
                     // this.retargetData=res.data;
-                    this.retargetDataAll=[...this.retargetDataAll,...res.result];
+                    // this.retargetDataAll=[...this.retargetDataAll,...res.result];
+                     this.retargetDataAll=[...res.result];
                     
                 }
             })
         }
     },
-    
+    created() {
+        if(this.$route){
+            let editRecordId=this.$route.query.id;
+            if(editRecordId){
+                this.editRecordId=editRecordId;
+                this.editEchoPage()
+            }
+        }
+    },
     mounted() {
         this.accountHttp()
         
@@ -2146,13 +2343,7 @@ export default {
         
         this.strategyName ='[预设]_'+ strategyNamepart+'_' + moment().format('MM_DD_hh:mm') ;
         this.getActionBarText()
-        if(this.$route){
-            let editRecordId=this.$route.query.id;
-            if(editRecordId){
-                this.editRecordId=editRecordId;
-                this.editEchoPage()
-            }
-        }
+        
         
     },
 
@@ -2178,55 +2369,55 @@ export default {
         customCrowdHandler(val){
             let str=''
             switch (val) {
-                case '1':
+                case 1:
                     str='上传人群'
                     break;
-                case '2':
+                case 2:
                     str='广告人群'
                     break;
-                case '3':
+                case 3:
                     str='主题专区'
                     break;
-                case '4':
+                case 4:
                     str='逻辑规则'
                     break;
-                case '5':
+                case 5:
                     str='人群扩展'
                     break;
-                case '6':
+                case 6:
                     str='平台定制'
                     break;
-                case '7':
+                case 7:
                     str='定制付费'
                     break;
-                case '8':
+                case 8:
                     str='网红粉丝类别'
                     break;
-                case '9':
+                case 9:
                     str='内容付费行为'
                     break;
-                case '10':
+                case 10:
                     str='移动应用安装'
                     break;
-                case '11':
+                case 11:
                     str='快手使用活跃度'
                     break;
-                case '12':
+                case 12:
                     str='行业分类'
                     break;
-                case '13':
+                case 13:
                     str='商业兴趣'
                     break;
-                case '14':
+                case 14:
                     str='固化标签'
                     break;
-                case '15':
+                case 15:
                     str='行业偏好'
                     break;
-                case '16':
+                case 16:
                     str='第三方标签'
                     break;
-                case '17':
+                case 17:
                     str='产品关键词'
                     break;
             
@@ -2297,6 +2488,9 @@ export default {
     .ant-checkbox-wrapper:first-child {
         padding: 0 15px 5px;
     }
+    .ant-checkbox-wrapper + .ant-checkbox-wrapper {
+        margin-left: 0px; 
+    }
   }
 }
 </style>

+ 82 - 9
src/views/modules/autoLaunch/configLaunchList.vue

@@ -32,7 +32,22 @@
                     :scroll="{'x':scrollX}"
                     
                 >
-
+                    <span slot="status" slot-scope="text,record">
+                        <a-spin :spinning="record.spin" size="small" >
+                            <div class="spin-content">
+                                <a-switch size="default" :checked='text==1'  @change="switchChange(text,record)"/>
+                            </div>
+                        </a-spin>    
+                        
+                    </span>
+                    <span slot="openProgramCreate" slot-scope="text,record">
+                        <a-spin :spinning="record.openProgramCreateSpin" size="small" >
+                            <div class="spin-content">
+                                <a-switch size="default" :checked='text==1'  @change="openProgramCreateSwitchChange(text,record)"/>
+                            </div>
+                        </a-spin>    
+                        
+                    </span>
                     <span slot="cpaBid" slot-scope="text">
                         {{text/1000}}
                     </span>
@@ -102,15 +117,15 @@ let typeValue='预算'
 
 const strategyColumns = [
   
-//   {
-//     title: 'ID',
-//     dataIndex: 'id',
-//     key: 'id',
-//     align: 'center',
-//     scopedSlots: { customRender: 'id' },
-//     width:110,
+  {
+    title: '开关',
+    dataIndex: 'status',
+    key: 'status',
+    align: 'center',
+    scopedSlots: { customRender: 'status' },
+    width:110,
     
-//   },
+  },
    {
     title: '所属账户名称',
     dataIndex: 'authName',
@@ -142,6 +157,14 @@ const strategyColumns = [
         scopedSlots: { customRender: 'cpaBid' },
         // sorter:() => {}
     },
+//   {
+//         title: '是否开启程序化创建',
+//         dataIndex: 'openProgramCreate',
+//         align: 'center',    
+//         scopedSlots: { customRender: 'openProgramCreate' },
+//         sorter:() => {},
+//         width:180,
+//     },
  {
     title: '操作',
     dataIndex: 'operator',
@@ -231,6 +254,54 @@ export default {
         },
     },
     methods: {
+        //状态改变
+        switchChange(text,record){
+            // this.spinning=true;
+            console.log(text,record)
+            record.spin=true;
+            
+            
+            let status=text==1?0:1;
+            getAction(`/ctop/aiKuaishouAdvertiserStrategy/oprateStatus`,{
+                id:record.id,
+                status
+            }).then((res)=>{
+                
+                    record.spin=false;
+                if(res.success){
+                    this.getStrategyList()
+                    this.$message.success(res.message)
+                }else{
+                    this.$message.error(res.message)
+                }
+            })
+           
+
+        },
+        //是否开启程序化创意状态改变
+        openProgramCreateSwitchChange(text,record){
+            // this.spinning=true;
+            console.log(text,record)
+            record.openProgramCreateSpin=true;
+            
+            
+            let status=text==1?0:1;
+            getAction(`/ctop/aiKuaishouAdvertiserStrategy/oprateCreativeStatus`,{
+                id:record.id,
+                status
+            }).then((res)=>{
+                
+                    record.openProgramCreateSpin=false;
+                if(res.success){
+                    this.getStrategyList()
+                    this.$message.success(res.message)
+                }else{
+                    this.$message.error(res.message)
+                }
+            })
+           
+
+        },
         examineAgainMethod(record){
             console.log(record)
             this.examineAgain=true;
@@ -355,6 +426,8 @@ export default {
                         item.key=item.id;
                         item.show=false;
                         item.visible=false;
+                        item.spin=false;
+                        item.openProgramCreateSpin=false;
                     })
 
                     this.data = res.result.records;

+ 1 - 2
src/views/modules/autoLaunch/newAppId.vue

@@ -277,7 +277,7 @@ export default {
         beforeUpload(file) {
             // ${this.form.project}
             if (process.env.NODE_ENV == 'development') { 
-                this.uploadAction= `http://139.186.151.174:8804/jeecg-boot/ai/aiKuaiShouAppInfo/importAppExcel?accountId=${this.accountId}&platform=${this.platform}&imageToken=${this.urlListImage.imageToken}`
+                this.uploadAction= `/jeecg-boot/ai/aiKuaiShouAppInfo/importAppExcel?accountId=${this.accountId}&platform=${this.platform}&imageToken=${this.urlListImage.imageToken}`
             } 
             else if (process.env.NODE_ENV == 'debug') { 
             } 
@@ -366,7 +366,6 @@ export default {
   mounted() {
     this.accountHttp()
    
-    
   },
 }
 </script>

+ 8 - 0
src/views/modules/columnConst/accountConst.js

@@ -1218,6 +1218,14 @@ export const KScustomFields= [
           scopedSlots: { customRender: 'eventCreditGrantAppRate' },
           sorter:() => {}
         },
+        {
+          title: '3s播放率',
+          dataIndex: 'play3sRate',
+          tip: '3s播放数/素材曝光数',
+          align: 'center',    
+          scopedSlots: { customRender: 'play3sRate' },
+          sorter:() => {}
+        },
       ]
     },
     {

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

@@ -15,6 +15,7 @@
       <a-col :span="24" style="display: flex">
         <Treeselect :appId.sync="appId" :multiple="false" request="2,4" ref="treeSelect" style="margin: 8px 20px" />
         <a-button type="primary" style="margin: 10px" @click="addUser">搜索</a-button>
+        <a-button type="primary" style="margin: 10px; float: right" @click="newCreat">批量创建</a-button>
       </a-col>
     </a-row>
     <a-form layout="inline">
@@ -226,7 +227,14 @@
     </a-modal>
 
     <!-- 实时数据 -->
-    <a-modal v-model="realTimeVisiable" title="广告计划实时数据" @afterClose="clear" width="80%" :maskClosable="false" :footer='false'>
+    <a-modal
+      v-model="realTimeVisiable"
+      title="广告计划实时数据"
+      @afterClose="clear"
+      width="80%"
+      :maskClosable="false"
+      :footer="false"
+    >
       <div class="optBody">
         <a-range-picker
           :disabled-date="disabledDate"
@@ -746,6 +754,13 @@ export default {
     },
   },
   methods: {
+    newCreat() {
+      if (this.appId) {
+        window.open('/user/new-batch?accountId=' + this.appId, '_blank')
+      } else {
+        window.open('/user/new-batch', '_blank')
+      }
+    },
     disabledDate(current) {
       // console.log(current)
       return (current && current > moment()) || (current && current < moment().subtract(7, 'days'))
@@ -869,12 +884,11 @@ export default {
       }
     },
     handleSubmit(e) {
-      if(this.unitId){
+      if (this.unitId) {
         this.$refs.copyGroup.handleSubmit(e)
-      }else{
+      } else {
         this.$message.error('请选择广告组后操作')
       }
-      
     },
     toDetail(record) {
       localStorage.setItem('advertisingGroupKey', record.campaignId)
@@ -983,7 +997,6 @@ export default {
       this.searchLabel()
     },
     addUser() {
-      
       this.loading = true
       this.dataList = []
       var params = {}
@@ -993,7 +1006,7 @@ export default {
       if (this.appId) {
         this.getSpend(params)
         this.getCampaignList(params)
-        localStorage.setItem('accountId',this.appId)
+        localStorage.setItem('accountId', this.appId)
       } else {
         this.$message.error('请选择账户')
       }
@@ -1199,11 +1212,11 @@ export default {
     },
   },
   watch: {
-    allUnitCopy:function(n,o){
-      if(!n){
+    allUnitCopy: function (n, o) {
+      if (!n) {
         this.editUnit = '2'
       }
-    }
+    },
   },
 
   computed: {},

+ 22 - 8
src/views/modules/kuaishouapp/account/advertisingGroup.vue

@@ -1176,18 +1176,32 @@ let realTimeColumn=[
               ...res.result.appInfo,
               ...res.result.target
             }
-
+          if(this.campaignType=='2'||this.campaignType==2){
+            getAction('/kuaishou/batch/getIsActivate', {
+              accountId: localStorage.getItem('accountId'),
+              appId:this.copyData.appId,
+              campaignType:2
+            }).then(res => {
+              if (res.success) {
+                this.allForm.groupTypeData = res.result
+              }
+            })
+          }else{
+            getAction('/kuaishou/batch/getIsActivate', {
+              accountId: localStorage.getItem('accountId'),
+              campaignType:this.campaignType
+            }).then(res => {
+              if (res.success) {
+                this.allForm.groupTypeData = res.result
+              }
+            })
+          }
             this.copyLoading = false
           }
 
         })
-        getAction('/kuaishou/batch/getIsActivate', {
-          accountId: localStorage.getItem('accountId')
-        }).then(res => {
-          if (res.success) {
-            this.allForm.groupTypeData = res.result
-          }
-        })
+        
+       
       },
       toDetail(record) {
         // 点击改行时要做的事情

+ 16 - 18
src/views/modules/kuaishouapp/account/copyAllUnit.vue

@@ -671,22 +671,22 @@ export default {
         }
       })
 
-        getAction('/kuaishou/batch/getWhiteList', {
-          accountId: item.accountId,
-        }).then((res) => {
-          if (res.success) {
-            // console.log(res)
-            if (res.result) {
-              // this.creativeCategorySwitch = res.result.creative_category_switch == 1 ? true : false
-              this.allianceAccount = res.result.alliance_account == 1 ? true : false
-              // this.actionbarClickUrlSwitch = res.result.actionbar_click_url_switch == 1 ? true : false
-            } else {
-              this.allianceAccount = false
-              // this.creativeCategorySwitch = false
-              // this.actionbarClickUrlSwitch = false
-            }
+      getAction('/kuaishou/batch/getWhiteList', {
+        accountId: item.accountId,
+      }).then((res) => {
+        if (res.success) {
+          // console.log(res)
+          if (res.result) {
+            // this.creativeCategorySwitch = res.result.creative_category_switch == 1 ? true : false
+            this.allianceAccount = res.result.alliance_account == 1 ? true : false
+            // this.actionbarClickUrlSwitch = res.result.actionbar_click_url_switch == 1 ? true : false
+          } else {
+            this.allianceAccount = false
+            // this.creativeCategorySwitch = false
+            // this.actionbarClickUrlSwitch = false
           }
-        })
+        }
+      })
       getAction('/kuaishou/batch/getProjectMaxBid', {
         accountId: item.accountId,
       }).then((res) => {
@@ -728,11 +728,9 @@ export default {
       this.templateList = []
       getAction('/batch/kuaishouTemplate/list', {
         accountId: accountId,
-        pageSize: 1000,
-        pageNo: 1,
       }).then((res) => {
         if (res.success) {
-          this.templateList = res.result.records.map((item, index) => {
+          this.templateList = res.result.map((item, index) => {
             return {
               ...item,
               key: index,

+ 58 - 21
src/views/modules/kuaishouapp/account/stepForm/Step2.vue

@@ -45,7 +45,7 @@
         <creat-application ref="application" />
       </a-form-item>
       <a-form-item label="转化类型" :labelCol="{ lg: { span: 7 }, sm: { span: 7 } }"
-        :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }" v-if="campaignType == '3'">
+        :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }" v-if="campaignType == 3">
         <a-radio-group buttonStyle="solid"
           v-decorator="['urlType', { rules: [{ required: true, message: '请选择目标应用' }], initialValue: '1' }]">
           <a-radio-button value="1">淘宝商品</a-radio-button>
@@ -672,18 +672,38 @@
         this.checkedTrue = e.target.checked
       },
       addGroup() {
-        this.allForm.group.push({
-          bidType:  10,
-          bid: '',
-          cpaBid: '',
-          showTipCheck: false,
-          deepConversionBidCheck: false,
-          unitName: '',
-          unitNameCheck: false,
-          deepConversionType: '',
-          deepConversionBid: '',
-          ocpxActionType:this.campaignType == '2' && this.allForm.groupTypeData.isActivate == '1' ? 180 : 2,
-        })
+        if(this.campaignType=='2'||this.campaignType==2){
+          if(this.getData('appId')){
+            this.allForm.group.push({
+              bidType:  10,
+              bid: '',
+              cpaBid: '',
+              showTipCheck: false,
+              deepConversionBidCheck: false,
+              unitName: '',
+              unitNameCheck: false,
+              deepConversionType: '',
+              deepConversionBid: '',
+              ocpxActionType:this.campaignType == '2' && this.allForm.groupTypeData.isActivate == '1' ? 180 : 2,
+            })
+          }else{
+            this.$message.error('请选择目标应用之后添加广告组')
+          }
+        }else{
+           this.allForm.group.push({
+              bidType:  10,
+              bid: '',
+              cpaBid: '',
+              showTipCheck: false,
+              deepConversionBidCheck: false,
+              unitName: '',
+              unitNameCheck: false,
+              deepConversionType: '',
+              deepConversionBid: '',
+              ocpxActionType:this.campaignType == '2' && this.allForm.groupTypeData.isActivate == '1' ? 180 : 2,
+            })
+        }
+
       },
       resData(index) {
         this.allForm.group[index].bid = ''
@@ -974,6 +994,16 @@
       },
       handleChange(value) {
         //   this.$refs.population.getAppList(value)
+        this.allForm.group = []
+        getAction('/kuaishou/batch/getIsActivate', {
+          accountId: localStorage.getItem('accountId'),
+          appId:this.getData('appId'),
+          campaignType:2
+        }).then(res => {
+          if (res.success) {
+            this.allForm.groupTypeData = res.result
+          }
+        })
       },
       handleChangeMould(value) {
         if (value) {
@@ -1044,7 +1074,19 @@
         getAction('/kuaishou/batch/getCampaignList', params).then(res => {
           if (res.success) {
             this.campaignType = res.result.records[0].campaignType
-            console.log(this.campaignType)
+
+
+            if(this.campaignType!=2){
+              getAction('/kuaishou/batch/getIsActivate', {
+                accountId: localStorage.getItem('accountId'),
+                campaignType:this.campaignType
+              }).then(res => {
+                if (res.success) {
+                  this.allForm.groupTypeData = res.result
+                }
+              })
+            }
+            // console.log(this.campaignType)
           }
         })
       },
@@ -1062,13 +1104,8 @@
       this.getAppList()
       this.getCampaignList()
       this.getMould()
-      getAction('/kuaishou/batch/getIsActivate', {
-        accountId: localStorage.getItem('accountId')
-      }).then(res => {
-        if (res.success) {
-          this.allForm.groupTypeData = res.result
-        }
-      })
+
+
 
       getAction('/kuaishou/batch/getWhiteList',{
         accountId:localStorage.getItem('accountId')

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

@@ -63,8 +63,8 @@
 .display-none-selset {
   display: none !important;
 }
-.only-step4 .ant-form-item-label {
-  text-align: left;
+.only-step4 .ant-form-item-label {
+  text-align: left;
 }
 </style>
 <style scoped lang="scss">
@@ -262,8 +262,8 @@ li.chouzhen.first:before {
                             >推荐封面</a
                           >
                           <br />
-                          <span v-for="(item, deleteIndex) of item.imageList" style="position: relative">
-                            <img :src="item.url" style="width: 18%; margin: 1%" :key="item.url" />
+                          <span v-for="(itemImg, deleteIndex) of item.imageList" style="position: relative">
+                            <img :src="itemImg.url" style="width: 18%; margin: 1%" :key="itemImg.url" />
                             <a-icon
                               type="close-circle"
                               @click="deleteData(index, bestIndex, deleteIndex)"

+ 44 - 38
src/views/modules/kuaishouapp/account/stepForm/stepModule/test.vue

@@ -3,10 +3,10 @@
     <table class="time_table table" v-on:mouseleave="mouseleave">
       <thead>
         <tr>
-          <th rowspan="2" style="width:120px">日期/时间</th>
+          <th rowspan="2" style="width: 120px">日期/时间</th>
         </tr>
         <tr>
-          <th class="unselectable" v-for="(num, index) in numData" :key="index" style="width:30px">{{ num }}</th>
+          <th class="unselectable" v-for="(num, index) in numData" :key="index" style="width: 30px">{{ num }}</th>
         </tr>
       </thead>
       <tbody>
@@ -41,8 +41,8 @@ export default {
       type: String,
       default() {
         return '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
-      }
-    }
+      },
+    },
   },
   data() {
     return {
@@ -52,39 +52,39 @@ export default {
       timeData: [
         {
           date: '周一',
-          time: []
+          time: [],
         },
         {
           date: '周二',
-          time: []
+          time: [],
         },
         {
           date: '周三',
-          time: []
+          time: [],
         },
         {
           date: '周四',
-          time: []
+          time: [],
         },
         {
           date: '周五',
-          time: []
+          time: [],
         },
         {
           date: '周六',
-          time: []
+          time: [],
         },
         {
           date: '周日',
-          time: []
-        }
+          time: [],
+        },
       ],
       selectFlag: false,
       max: {
         x: 0,
-        y: 0
+        y: 0,
       },
-      dataString: ''
+      dataString: '',
     }
   },
   methods: {
@@ -102,7 +102,7 @@ export default {
     showOne(index, key) {
       //   this.timeData[index].time[key].isSelected = !this.timeData[index].time[key].isSelected
     },
-    mousedown: function(index, key) {
+    mousedown: function (index, key) {
       this.selectStart = []
       this.selectFlag = true
       if (this.timeData[index].time[key].value == false) {
@@ -114,10 +114,10 @@ export default {
       }
       this.selectStart.push({
         index: index,
-        key: key
+        key: key,
       })
     },
-    mouseover: function(index, key) {
+    mouseover: function (index, key) {
       // x 垂直方向  y 水平方向
       if (this.selectFlag) {
         if (index >= this.max.x) {
@@ -128,11 +128,11 @@ export default {
         }
         var start = {
           x: this.selectStart[0].index,
-          y: this.selectStart[0].key
+          y: this.selectStart[0].key,
         }
         var end = {
           x: index,
-          y: key
+          y: key,
         }
         for (var i = end.x; i <= this.max.x; i++) {
           for (var j = end.y; j <= this.max.y; j++) {
@@ -153,14 +153,14 @@ export default {
         }
       }
     },
-    mouseup: function(index, key) {
+    mouseup: function (index, key) {
       var start = {
         x: this.selectStart[0].index,
-        y: this.selectStart[0].key
+        y: this.selectStart[0].key,
       }
       var end = {
         x: index,
-        y: key
+        y: key,
       }
       /* 渲染选中的区域 */
       var data = []
@@ -179,7 +179,7 @@ export default {
         this.timeData[5].time,
         this.timeData[6].time
       )
-      this.dataString = arr.map(item => {
+      this.dataString = arr.map((item) => {
         if (item.isSelected) {
           return 1
         } else {
@@ -191,10 +191,10 @@ export default {
       this.selectFlag = false
       this.max = {
         x: 0,
-        y: 0
+        y: 0,
       }
     },
-    mouseleave: function() {
+    mouseleave: function () {
       this.selectFlag = false
     },
     setItemDate(sum) {
@@ -216,37 +216,43 @@ export default {
       }
     },
     init() {
-      var str = this.scheduleTime
+      var str = ''
+      if (this.scheduleTime) {
+        str = this.scheduleTime
+      } else {
+        str =
+          '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
+      }
       var arr = str.split('')
       this.timeData = [
         {
           date: '周一',
-          time: []
+          time: [],
         },
         {
           date: '周二',
-          time: []
+          time: [],
         },
         {
           date: '周三',
-          time: []
+          time: [],
         },
         {
           date: '周四',
-          time: []
+          time: [],
         },
         {
           date: '周五',
-          time: []
+          time: [],
         },
         {
           date: '周六',
-          time: []
+          time: [],
         },
         {
           date: '周日',
-          time: []
-        }
+          time: [],
+        },
       ]
       for (let i = 0; i < arr.length; i++) {
         if (i < 24) {
@@ -265,16 +271,16 @@ export default {
           this.timeData[6].time.push({ isSelected: arr[i] == 1 ? true : false, move: false, value: false })
         }
       }
-    }
+    },
   },
   watch: {
     scheduleTime: {
       immediate: true, // immediate选项可以开启首次赋值监听
       handler(newVal, oldVal) {
         this.init()
-      }
-    }
-  }
+      },
+    },
+  },
 }
 </script>
 

+ 9 - 1
src/views/modules/kuaishouapp/batchCreation/campaignList.vue

@@ -15,6 +15,7 @@
       <a-col :span="24" style="display: flex">
         <Treeselect :appId.sync="appId" :multiple="false" request="2,4" ref="treeSelect" style="margin: 8px 20px" />
         <a-button type="primary" style="margin: 10px" @click="addUser">搜索</a-button>
+        <!-- <a-button type="primary" style="margin: 10px; float: right" @click="newCreat">批量创建</a-button> -->
       </a-col>
     </a-row>
     <a-form layout="inline">
@@ -671,6 +672,13 @@ export default {
     },
   },
   methods: {
+    newCreat() {
+      if (this.appId) {
+        window.open('/user/new-batch?accountId=' + this.appId, '_blank')
+      } else {
+        window.open('/user/new-batch', '_blank')
+      }
+    },
     getUnitData() {
       this.addUser()
       this.allUnitCopy = false
@@ -882,7 +890,7 @@ export default {
       if (this.appId) {
         this.getSpend(params)
         this.getCampaignList(params)
-        localStorage.setItem('campaignAccountId',this.appId)
+        localStorage.setItem('campaignAccountId', this.appId)
       } else {
         this.$message.error('请选择账户')
       }

+ 2 - 4
src/views/modules/kuaishouapp/batchCreation/creat/creatUnit.vue

@@ -1882,11 +1882,9 @@ export default {
       this.templateList = []
       getAction('/batch/kuaishouTemplate/list', {
         accountId: accountId,
-        pageSize: 1000,
-        pageNo: 1,
       }).then((res) => {
         if (res.success) {
-          this.templateList = res.result.records.map((item, index) => {
+          this.templateList = res.result.map((item, index) => {
             return {
               ...item,
               key: index,
@@ -2348,7 +2346,7 @@ export default {
         viewComp: 7,
       }).then((res) => {
         if (res.success) {
-          this.siteList = res.result
+          this.siteLiRst = res.result
           if (this.siteList.length > 0) {
             this.showSite = true
           }

+ 1 - 3
src/views/modules/kuaishouapp/crossAccount/createUnit.vue

@@ -1418,11 +1418,9 @@ export default {
       this.templateList = []
       getAction('/batch/kuaishouTemplate/list', {
         accountId: accountId,
-        pageSize: 1000,
-        pageNo: 1,
       }).then((res) => {
         if (res.success) {
-          this.templateList = res.result.records.map((item, index) => {
+          this.templateList = res.result.map((item, index) => {
             return {
               ...item,
               key: index,

File diff suppressed because it is too large
+ 4786 - 0
src/views/modules/kuaishouapp/newBatch/index.vue


File diff suppressed because it is too large
+ 1110 - 0
src/views/modules/kuaishouapp/newBatch/lookPreview.vue


File diff suppressed because it is too large
+ 1532 - 0
src/views/modules/stockWatch/accountPage.vue


+ 9 - 2
src/views/modules/workBench/materialList.vue

@@ -1497,8 +1497,15 @@ export default {
 
 
         beforeUpload(file) {
-
-            this.uploadAction= `http://api.tjyourong.com.cn/jeecg-boot/platform/file/uploadScript?materialId=${this.currentMaterial.materialId}&projectId=${this.currentMaterial.projectId}`
+            if (process.env.NODE_ENV == 'development') { 
+                this.uploadAction= `/jeecg-boot/platform/file/uploadScript?materialId=${this.currentMaterial.materialId}&projectId=${this.currentMaterial.projectId}`
+            } 
+            else if (process.env.NODE_ENV == 'debug') { 
+            } 
+            else if (process.env.NODE_ENV == 'production') { 
+              this.uploadAction= `${this.axios.defaults.baseURL}/platform/file/uploadScript?materialId=${this.currentMaterial.materialId}&projectId=${this.currentMaterial.projectId}`
+            }
+            // this.uploadAction= `http://api.tjyourong.com.cn/jeecg-boot/platform/file/uploadScript?materialId=${this.currentMaterial.materialId}&projectId=${this.currentMaterial.projectId}`
             // this.uploadAction= `http://139.186.151.174:8804/jeecg-boot/platform/file/uploadScript?materialId=${this.currentMaterial.materialId}&projectId=${this.currentMaterial.projectId}`
             // this.uploadAction= `http://192.168.1.43:8088/jeecg-boot/platform/file/uploadScript?materialId=${this.currentMaterial.materialId}&projectId=${this.currentMaterial.projectId}`
             this.loadDisabled = true

+ 9 - 1
src/views/modules/workBench/orderDetail.vue

@@ -1884,7 +1884,15 @@ export default {
 
 
         beforeUpload(file) {
-            this.uploadAction= `http://api.tjyourong.com.cn/jeecg-boot/platform/file/uploadScript?materialId=${this.currentMaterial.id}&projectId=${this.currentMaterial.projectId}`
+            if (process.env.NODE_ENV == 'development') { 
+                this.uploadAction= `/jeecg-boot/platform/file/uploadScript?materialId=${this.currentMaterial.id}&projectId=${this.currentMaterial.projectId}`
+            } 
+            else if (process.env.NODE_ENV == 'debug') { 
+            } 
+            else if (process.env.NODE_ENV == 'production') { 
+              this.uploadAction= `${this.axios.defaults.baseURL}/platform/file/uploadScript?materialId=${this.currentMaterial.id}&projectId=${this.currentMaterial.projectId}`
+            }
+            //  this.uploadAction= `http://api.tjyourong.com.cn/jeecg-boot/platform/file/uploadScript?materialId=${this.currentMaterial.id}&projectId=${this.currentMaterial.projectId}`
             // this.uploadAction= `http://192.168.1.43:8088/jeecg-boot/platform/file/uploadScript?materialId=${this.currentMaterial.id}&projectId=${this.currentMaterial.projectId}`
             // this.uploadAction= `http://139.186.151.174:8804/jeecg-boot/platform/file/uploadScript?materialId=${this.currentMaterial.id}&projectId=${this.currentMaterial.projectId}`
 

+ 10 - 2
src/views/modules/workBench/placeOrder.vue

@@ -715,8 +715,16 @@ export default {
 
         beforeUpload(file) {
             // ${this.form.project}
-            this.uploadAction= `http://api.tjyourong.com.cn/jeecg-boot/platform/file/uploadAttachment?projectId=${this.form.project}`
-            // this.uploadAction= `http://139.186.151.174:8804/jeecg-boot/platform/file/uploadAttachment?projectId=772`
+            // this.uploadAction= `http://api.tjyourong.com.cn/jeecg-boot/platform/file/uploadAttachment?projectId=${this.form.project}`
+            // this.uploadAction= `http://139.186.151.174:8804/jeecg-boot/platform/file/uploadAttachment?projectId=${this.form.project}`
+            if (process.env.NODE_ENV == 'development') { 
+                this.uploadAction= `/jeecg-boot/platform/file/uploadAttachment?projectId=${this.form.project}`
+            } 
+            else if (process.env.NODE_ENV == 'debug') { 
+            } 
+            else if (process.env.NODE_ENV == 'production') { 
+              this.uploadAction= `${this.axios.defaults.baseURL}/platform/file/uploadAttachment?projectId=${this.form.project}`
+            }
             this.loadDisabled = true
             const size = (Number(file.size) / (1024 * 1024)).toFixed(2)
             const fileName = file.name

+ 4 - 4
vue.config.js

@@ -68,7 +68,7 @@ module.exports = {
     open : true,
     proxy: {
       '/jeecg-boot': {
-        //  target: 'http://192.168.1.8:8080', //请求本地 需要jeecg-boot后台项目  蒙蒙
+          // target: 'http://192.168.1.8:8080', //请求本地 需要jeecg-boot后台项目  蒙蒙
         // target: 'http://192.168.0.59:8088', //请求本地 需要jeecg-boot后台项目  英豪
         // target: 'http://192.168.1.188:8088', //请求本地 需要jeecg-boot后台项目  英豪
         // target: 'http://192.168.2.115:8080', //请求本地 需要jeecg-boot后台项目  祚云
@@ -79,13 +79,13 @@ module.exports = {
         // target: 'http://192.168.1.219:8080', //请求本地 需要jeecg-boot后台项目  赵西安
         // target: 'http://192.168.1.193:8080', //请求本地 需要jeecg-boot后台项目  李煜一
         // target: 'http://192.168.1.193:31012', //请求本地 需要jeecg-boot后台项目  李煜一
-         target: 'http://api.tjyourong.com.cn', //请求本地 需要jeecg-boot后台项目
+        //  target: 'http://api.tjyourong.com.cn', //请求本地 需要jeecg-boot后台项目
         // target: 'https://trac.tjyourong.com.cn', //请求本地 需要jeecg-boot后台项目
         // target: 'http://39.106.184.70:8088/', //请求本地 需要jeecg-boot后台项目
         //  target: 'http://adsp.tjyourong.com.cn/', //请求本地 需要jeecg-boot后台项目
         // target: 'http://192.168.1.251/', //请求本地 需要jeecg-boot后台项目
         // target:'http://118.24.244.213:8804',
-        // target:'http://139.186.151.174:8804', //测试
+       target:'http://139.186.151.174:8804', //测试
 
         ws: false,
 
@@ -106,5 +106,5 @@ module.exports = {
   },
 
   lintOnSave: undefined,
-//   publicPath:'./'
+//   publicPath:'./',
 }

+ 162 - 0
面试题.md

@@ -0,0 +1,162 @@
+#  2月22日 
+
+- 基础题
+  - 编写一个方法,该方法接收两个参数,分别为 k 和 一个无序的纯数字数组。该方法在执行后,会返回数组中第 k 大的数字。特别注意,如果数组中,有两位数值一样的数字,同数值数字排名并列。如 [3,1,3,2,5,4,5] 中,第 1 大的数字为 5,第2大的数字为 4,第5大的数字为 1?
+  - `__proto__`  和 prototype 之前有什么关系?
+  - call(), .apply() .bind() 的区别和作用?bind 方法如何来实现?
+
+- 附加题
+  - `JS`中基础数据类型有哪几种?了解包装对象么?
+  - 2、如何判断this?箭头函数的this是什么?
+
+# 2月23日
+
+- 基础题 
+  - 如何中断ajax请求?
+  - 什么是同步?什么是异步?
+  - 什么是宏任务?什么是微任务?
+
+- 附加题
+
+# 2月24日
+
+- 基础题
+  - 
+
+- 附加题
+
+# 2月25日
+
+- 基础题
+  - 
+
+- 附加题
+
+# 2月26日
+
+- 基础题
+  - 
+
+- 附加题
+
+# 2月27日
+
+- 基础题
+  - 
+
+- 附加题
+
+# 2月28日
+
+- 基础题
+  - 
+
+- 附加题
+
+# 3月1日
+
+- 基础题
+  - 
+
+- 附加题
+
+# 3月2日
+
+- 基础题
+  - 
+
+- 附加题
+
+# 3月3日
+
+- 基础题
+  - 
+
+- 附加题
+
+# 3月3日
+
+- 基础题
+  - 
+
+- 附加题
+
+# 3月4日
+
+- 基础题
+  - 
+
+- 附加题
+
+# 3月5日
+
+- 基础题
+  - 
+
+- 附加题
+
+# 3月6日
+
+- 基础题
+  - 
+
+- 附加题
+
+# 3月7日
+
+- 基础题
+  - 
+
+- 附加题
+
+# 3月8日
+
+- 基础题
+  - 
+
+- 附加题
+
+# 3月9日
+
+- 基础题
+  - 
+
+- 附加题
+
+# 3月10日
+
+- 基础题
+  - 
+
+- 附加题
+
+# 3月11日
+
+- 基础题
+  - 
+
+- 附加题
+
+# 3月12日
+
+- 基础题
+  - 
+
+- 附加题
+
+# 3月13日
+
+- 基础题
+  - 
+
+- 附加题
+
+# 3月14日
+
+- 基础题
+  - 
+
+- 附加题
+
+
+