瀏覽代碼

爆款视频 bug 分支

jiayufei 3 年之前
父節點
當前提交
859845ab14
共有 80 個文件被更改,包括 24037 次插入5031 次删除
  1. 9 9
      .editorconfig
  2. 1 1
      src/api/manage.js
  3. 1 0
      src/components/formComponents/checkBoxGroup.vue
  4. 5 1
      src/config/router.config.js
  5. 30 0
      src/filters.js
  6. 1 1
      src/mixins/JeecgListMixin.js
  7. 1 1
      src/permission.js
  8. 106 103
      src/utils/request.js
  9. 13 2
      src/views/modules/BatchCreate/linkMultiSelect.vue
  10. 4 1
      src/views/modules/Statistics/Statistics.vue
  11. 53 0
      src/views/modules/Statistics/change-face/change-face.less
  12. 374 0
      src/views/modules/Statistics/change-face/change-face.vue
  13. 1 1
      src/views/modules/Statistics/components/Treeselect.vue
  14. 33 33
      src/views/modules/Statistics/components/selectPagination.vue
  15. 311 0
      src/views/modules/Statistics/designerReport/designerReport.vue
  16. 42 34
      src/views/modules/autoLaunch/application/directional-service.js
  17. 225 0
      src/views/modules/Statistics/designerReport/material.less
  18. 25 7
      src/views/modules/Statistics/imageStatics/imageCostReport.vue
  19. 1235 940
      src/views/modules/Statistics/materialReport/materialReport.vue
  20. 1 1
      src/views/modules/Statistics/newPlanStatic/newPlanStatic.vue
  21. 580 586
      src/views/modules/Statistics/popularVideo.vue
  22. 216 208
      src/views/modules/Statistics/videoStatics/TTvideoStatics.vue
  23. 4 3
      src/views/modules/account-config/account-config-server.js
  24. 92 10
      src/views/modules/account-config/account-config.vue
  25. 3256 0
      src/views/modules/account-config/components/configuration-copy.vue
  26. 74 13
      src/views/modules/account-config/components/configuration-modal.less
  27. 1611 976
      src/views/modules/account-config/components/configuration-modal.vue
  28. 1 1
      src/views/modules/account-config/components/directional-logic/directional-logic.less
  29. 18 16
      src/views/modules/account-config/components/directional-logic/directional-logic.vue
  30. 24 0
      src/views/modules/account-config/components/tree-select/tree-select.vue
  31. 33 0
      src/views/modules/advertiser/ProjectList.vue
  32. 131 42
      src/views/modules/advertiser/ProjectMemberList.vue
  33. 1 1
      src/views/modules/advertiser/modules/ProjectModal.vue
  34. 1 1
      src/views/modules/advertiser/modules/productModal.vue
  35. 1 1
      src/views/modules/advertiser/modules/projectListModal.vue
  36. 222 0
      src/views/modules/autoLaunch/application/application-service.js
  37. 8 3
      src/views/modules/autoLaunch/application/directional.less
  38. 831 374
      src/views/modules/autoLaunch/application/application.vue
  39. 652 0
      src/views/modules/autoLaunch/application/components/creatApplication.vue
  40. 603 0
      src/views/modules/autoLaunch/application/components/editApplication.vue
  41. 6 0
      src/views/modules/autoLaunch/application/components/tree-select.less
  42. 56 25
      src/views/modules/autoLaunch/application/components/tree-select.vue
  43. 365 0
      src/views/modules/autoLaunch/application/components/uploadFile.vue
  44. 87 44
      src/views/modules/autoLaunch/configLaunchInfo.vue
  45. 14 0
      src/views/modules/autoLaunch/configProject/configProject-service.js
  46. 6 0
      src/views/modules/autoLaunch/configProject/configProject.less
  47. 3480 0
      src/views/modules/autoLaunch/configProject/creatConfig.vue
  48. 96 0
      src/views/modules/autoLaunch/configProject/editablCell.vue
  49. 1428 0
      src/views/modules/autoLaunch/configProject/index.vue
  50. 1 0
      src/views/modules/autoLaunch/directional/components/tree-select.vue
  51. 1 0
      src/views/modules/autoLaunch/directional/directional.vue
  52. 429 0
      src/views/modules/autoLaunch/material-all/components/selectRegion.vue
  53. 1414 0
      src/views/modules/autoLaunch/material-all/components/targetedPopulation.vue
  54. 262 0
      src/views/modules/autoLaunch/material-all/components/templateModal.vue
  55. 982 0
      src/views/modules/autoLaunch/material-all/material-detail.vue
  56. 213 0
      src/views/modules/autoLaunch/material-all/material-service.js
  57. 225 0
      src/views/modules/autoLaunch/material-all/material.less
  58. 310 0
      src/views/modules/autoLaunch/material-all/material.vue
  59. 4 4
      src/views/modules/autoLaunch/material-pool/material.vue
  60. 1 0
      src/views/modules/autoLaunch/url/components/tree-select.vue
  61. 3 3
      src/views/modules/copy-library/copy-library-server.js
  62. 7 3
      src/views/modules/copy-library/copy-library.less
  63. 492 117
      src/views/modules/copy-library/copy-library.vue
  64. 16 3
      src/views/modules/creative-copywrit/creative-copywrit.less
  65. 700 122
      src/views/modules/creative-copywrit/creative-copywrit.vue
  66. 1 0
      src/views/modules/crowd-control/components/tree-select/tree-select.vue
  67. 70 10
      src/views/modules/crowd-control/crowd-control.vue
  68. 2 2
      src/views/modules/headline-view/headline-view-server.js
  69. 398 216
      src/views/modules/headline-view/headline-view.vue
  70. 90 2
      src/views/modules/kuaishouapp/batchCreation/creat/creatUnit.vue
  71. 51 7
      src/views/modules/material/accountCheck.vue
  72. 3 3
      src/views/modules/material/accountCheckBytedance.vue
  73. 423 0
      src/views/modules/material/comment/selectTable.vue
  74. 157 49
      src/views/modules/material/videoMaterial.vue
  75. 10 0
      src/views/modules/user-manage-operation/user-manage-operation-server.js
  76. 289 0
      src/views/modules/user-manage-operation/user-manage-operation.vue
  77. 575 587
      src/views/system/modules/UserModal.vue
  78. 487 415
      src/views/user/Login.vue
  79. 8 4
      src/views/user/transferLocal.vue
  80. 45 45
      vue.config.js

+ 9 - 9
.editorconfig

@@ -3,37 +3,37 @@ charset = utf-8
 end_of_line = crlf
 insert_final_newline = false
 indent_style = space
-indent_size = 2
+indent_size = 4
 
 [{*.ng, *.sht, *.html, *.shtm, *.shtml, *.htm}]
 indent_style = space
-indent_size = 2
+indent_size = 4
 
 [{*.jhm, *.xslt, *.xul, *.rng, *.xsl, *.xsd, *.ant, *.tld, *.fxml, *.jrxml, *.xml, *.jnlp, *.wsdl}]
 indent_style = space
-indent_size = 2
+indent_size = 4
 
 [{.babelrc, .stylelintrc, jest.config, .eslintrc, .prettierrc, *.json, *.jsb3, *.jsb2, *.bowerrc}]
 indent_style = space
-indent_size = 2
+indent_size = 4
 
 [*.svg]
 indent_style = space
-indent_size = 2
+indent_size = 4
 
 [*.js.map]
 indent_style = space
-indent_size = 2
+indent_size = 4
 
 [*.less]
 indent_style = space
-indent_size = 2
+indent_size = 4
 
 [*.vue]
 indent_style = space
-indent_size = 2
+indent_size = 4
 
 [{.analysis_options, *.yml, *.yaml}]
 indent_style = space
-indent_size = 2
+indent_size = 4
 

+ 1 - 1
src/api/manage.js

@@ -20,7 +20,7 @@ export function postNoCacheAction(url, parameter) {
     }
   })
 }
-//post---文件
+// post---文件
 export function postFileAction(url,parameter) {
   return axios({
     headers: {

+ 1 - 0
src/components/formComponents/checkBoxGroup.vue

@@ -129,6 +129,7 @@
     <a-checkbox-group v-model="selectedVal" :disabled="disabled" style="width: 100%">
       <a-checkbox
         v-for="item of selectOption"
+        :disabled="item.disabled"
         :label="item.label"
         :key="item.value"
         :value="item.value"

+ 5 - 1
src/config/router.config.js

@@ -77,7 +77,11 @@ export const constantRouterMap = [
       }
     ]
   },
-
+  {
+    path: '/creat-config',
+    name: 'creatConfig',
+    component: () => import(/* webpackChunkName: "fail" */ '@/views/modules/autoLaunch/configProject/creatConfig')
+  },
 
   {
     path: '/test',

+ 30 - 0
src/filters.js

@@ -3,6 +3,20 @@ import moment from 'moment';
 function fixedZero(val) {
     return val * 1 < 10 ? `0${val}` : val;
 }
+// function getrandom(minnum , maxnum ,total,size){
+//     var num = total; //定义整数
+//     var length= size;  //定义多个整数的数量
+//     var numArr = [];
+//     while(length > 1){
+//         var rnd = Math.floor(Math.random() * num); //通过JS的随机函数生成随机数
+//         num -= rnd;
+//         numArr.push(rnd);
+//         length --;
+//     }
+//     numArr.push(num);
+//     console.info(numArr);
+//     return numArr;
+// };getrandom(6,30,45,6)
 const filters = {
     // 格式化时间展示多长时间之前
     formatTime(time) {
@@ -421,6 +435,22 @@ const filters = {
                 break;
         }
         return str
+    },
+    deviceBrand(str) {
+        var data = {
+            1:"OPPO",
+            2:"VIVO",
+            3:"华为",
+            4:"小米",
+            5:"荣耀",
+            6:"三星",
+            7:"金立",
+            8:"魅族",
+            9:"乐视",
+            10:"其他",
+            11:"苹果",
+        }
+        return data[str]
     }
 
 }

+ 1 - 1
src/mixins/JeecgListMixin.js

@@ -321,7 +321,7 @@ export const JeecgListMixin = {
     },
     modalFormOk() {
       // 新增/修改 成功时,重载列表
-      this.loadData(1);
+      this.loadData(this.ipagination.current);
     },
     handleDetail: function (record) {
       this.$nextTick(()=>{

+ 1 - 1
src/permission.js

@@ -10,7 +10,7 @@ import { generateIndexRouter } from "@/utils/util"
 NProgress.configure({ showSpinner: false }) // NProgress Configuration
 
 
-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
+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','/creat-config'] // no redirect whitelist
 
 router.beforeEach((to, from, next) => {
   NProgress.start() // start progress bar

+ 106 - 103
src/utils/request.js

@@ -1,130 +1,133 @@
-import Vue from 'vue'
-import axios from 'axios'
-import store from '@/store'
-import {VueAxios} from './axios'
-import {Modal, notification} from 'ant-design-vue'
-import {ACCESS_TOKEN} from "@/store/mutation-types"
-const key = "1"
+/**
+ * @file reauest 配置
+ * @author zhuxinbo
+ */
+
+import Vue from 'vue';
+import axios from 'axios';
+import store from '@/store';
+import {VueAxios} from './axios';
+import {Modal, notification} from 'ant-design-vue';
+import {ACCESS_TOKEN} from '@/store/mutation-types';
+const key = '1';
 // 创建 axios 实例
 
-if (process.env.NODE_ENV == 'development') { 
-    axios.defaults.baseURL = '/jeecg-boot'
-    
-} 
-else if (process.env.NODE_ENV == 'debug') { 
-} 
-else if (process.env.NODE_ENV == 'production') { 
-  
-  // axios.defaults.baseURL = 'http://apipre.tjyourong.com.cn/jeecg-boot';//预生产
-  // axios.defaults.baseURL = 'http://139.186.165.84:8806/jeecg-boot';     
-  axios.defaults.baseURL = 'http://api.tjyourong.com.cn/jeecg-boot';//生产环境
+if (process.env.NODE_ENV === 'development') {
+    axios.defaults.baseURL = '/jeecg-boot';
+}
+else if (process.env.NODE_ENV === 'debug') {
+}
+else if (process.env.NODE_ENV === 'production') {
+	// axios.defaults.baseURL = 'http://apipre.tjyourong.com.cn/jeecg-boot'; // 预生产
+    // axios.defaults.baseURL = 'http://139.186.165.84:8806/jeecg-boot';
+	axios.defaults.baseURL = 'http://api.tjyourong.com.cn/jeecg-boot'; // 生产环境
 }
 const service = axios.create({
-//   baseURL: '/jeecg-boot', // api base_url
-  timeout: 6000000 // 请求超时时间
-})
+	// baseURL: '/jeecg-boot', // api base_url
+    timeout: 6000000 // 请求超时时间
+});
 
 
 
 
 const err = (error) => {
-  if (error.esponse) {
-    let data = error.response.data
-    const token = Vue.ls.get(ACCESS_TOKEN)
-    // console.log("------异常响应------", token)
-    // console.log("------异常响应------", error.response.status)
-    switch (error.response.status) {
-      case 403:
-        notification.error({key,message: '系统提示', description: '拒绝访问', duration: 4})
-        break
-      case 500:
-        //notification.error({ message: '系统提示', description:'Token失效,请重新登录!',duration: 4})
-        if (token && data.message == "Token失效,请重新登录") {
-          // update-begin- --- author:scott ------ date:20190225 ---- for:Token失效采用弹框模式,不直接跳转----
-          // store.dispatch('Logout').then(() => {
-          //     window.location.reload()
-          // })
-          Modal.error({
-            title: '登录已过期',
-            content: '很抱歉,登录已过期,请重新登录',
-            okText: '重新登录',
-            mask: false,
-            onOk: () => {
-              store.dispatch('Logout').then(() => {
-                Vue.ls.remove(ACCESS_TOKEN)
-                window.location.reload()
-              })
-            }
-          })
-          // update-end- --- author:scott ------ date:20190225 ---- for:Token失效采用弹框模式,不直接跳转----
-        }
-        break
-      case 404:
-        notification.error({key,message: '系统提示', description: '很抱歉,资源未找到!', duration: 4})
-        break
-      case 504:
-        notification.error({key,message: '系统提示', description: '网络超时'})
-        break
-      case 401:
-        notification.error({key,message: '系统提示', description: '未授权,请重新登录', duration: 4})
-        if (token) {
-          store.dispatch('Logout').then(() => {
-            setTimeout(() => {
-              window.location.reload()
-            }, 1500)
-          })
-        }
-        break
-      default:
-        notification.error({
-          key,
-          message: '系统提示',
-          description: data.message,
-          duration: 4
-        })
-        break
-    }
-  }
-  return Promise.reject(error)
+    if (error.esponse) {
+		let data = error.response.data
+		const token = Vue.ls.get(ACCESS_TOKEN)
+		// console.log("------异常响应------", token)
+		// console.log("------异常响应------", error.response.status)
+		switch (error.response.status) {
+		case 403:
+			notification.error({key,message: '系统提示', description: '拒绝访问', duration: 4})
+			break
+		case 500:
+			//notification.error({ message: '系统提示', description:'Token失效,请重新登录!',duration: 4})
+			if (token && data.message == "Token失效,请重新登录") {
+			// update-begin- --- author:scott ------ date:20190225 ---- for:Token失效采用弹框模式,不直接跳转----
+			// store.dispatch('Logout').then(() => {
+			//     window.location.reload()
+			// })
+			Modal.error({
+				title: '登录已过期',
+				content: '很抱歉,登录已过期,请重新登录',
+				okText: '重新登录',
+				mask: false,
+				onOk: () => {
+				store.dispatch('Logout').then(() => {
+					Vue.ls.remove(ACCESS_TOKEN)
+					window.location.reload()
+				})
+				}
+			})
+			// update-end- --- author:scott ------ date:20190225 ---- for:Token失效采用弹框模式,不直接跳转----
+			}
+			break
+		case 404:
+			notification.error({key,message: '系统提示', description: '很抱歉,资源未找到!', duration: 4})
+			break
+		case 504:
+			notification.error({key,message: '系统提示', description: '网络超时'})
+			break
+		case 401:
+			notification.error({key,message: '系统提示', description: '未授权,请重新登录', duration: 4})
+			if (token) {
+			store.dispatch('Logout').then(() => {
+				setTimeout(() => {
+				window.location.reload()
+				}, 1500)
+			})
+			}
+			break
+		default:
+			notification.error({
+			key,
+			message: '系统提示',
+			description: data.message,
+			duration: 4
+			})
+			break
+		}
+	}
+	return Promise.reject(error)
 };
 
 // request interceptor
 service.interceptors.request.use(config => {
-  const token = Vue.ls.get(ACCESS_TOKEN)
-  if (token) {
-    config.headers['X-Access-Token'] = token // 让每个请求携带自定义 token 请根据实际情况自行修改
-  }
-  if (config.method == 'get') {
-    config.params = {
-      _t: Date.parse(new Date()) / 1000,
-      ...config.params
+	const token = Vue.ls.get(ACCESS_TOKEN);
+    if (token) {
+		config.headers['X-Access-Token'] = token; // 让每个请求携带自定义 token 请根据实际情况自行修改
     }
-  }
-  return config
+    if (config.method === 'get') {
+		config.params = {
+			_t: Date.parse(new Date()) / 1000,
+			...config.params
+		};
+    }
+	return config;
 }, (error) => {
-  return Promise.reject(error)
-})
+  	return Promise.reject(error);
+});
 
 // response interceptor
 service.interceptors.response.use((response) => {
-  return response.data
+    return response.data;
 }, (error) => {
     notification.error({
         key,
         message: '系统提示',
         description: '网络超时,请刷新页面'
-      })
-    return 
-  })
+    });
+    return;
+});
 
 const installer = {
-  vm: {},
-  install(Vue, router = {}) {
-    Vue.use(VueAxios, router, service)
-  }
-}
+	vm: {},
+	install(Vue, router = {}) {
+		Vue.use(VueAxios, router, service);
+	}
+};
 
 export {
-  installer as VueAxios,
-  service as axios
-}
+    installer as VueAxios,
+	service as axios
+};

+ 13 - 2
src/views/modules/BatchCreate/linkMultiSelect.vue

@@ -62,7 +62,19 @@
         checkedShowList:[],
       }
     },
-    watch: {},
+    watch: {
+		listArr(newVal) {
+			if (newVal) {
+				newVal.forEach(item => {
+					this.listArr1.forEach(ele => {
+						if (ele.value == item) {
+							ele.checked = true;
+						}
+					});
+				});
+			}
+		}
+	},
     methods: {
       getItemData(val) {
         this.$nextTick(() => {
@@ -569,7 +581,6 @@
                 parentCode:0,
                 level:this.maxLayers
             }).then((res)=>{
-                console.log(res);
                 if(res.success){
                     res.data.forEach((item,index)=>{
                         item.value=item.code

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

@@ -118,7 +118,7 @@ p{
           :activeTabKey="noTitleKey"
           @tabChange="key => onTabChange(key, 'noTitleKey')"
         >
-          <div id="chart" style="width:100%;height:500px"></div>
+          <div id="chart" style="width:100%;height:500px" :style="{ width: clientWidth - 48 - 24 + 'px' }"></div>
           <a-button class="duibi" type='primary'  @click="visible = true">数据对比</a-button>
         </a-card>
       </a-col>
@@ -363,6 +363,7 @@ export default {
 
   data: function() {
     return {
+      clientWidth: 0,
       loading: true,
       columns: [
         { title: '时间', dataIndex: 'statDate', align: 'center' },
@@ -1484,6 +1485,7 @@ export default {
       chart.clear()
       chart.setOption(option, true)
       window.onresize = function() {
+			  this.clientWidth = document.documentElement.clientWidth - 224;
         chart.resize()
       }
       // this.chart.on('click', param => {
@@ -1507,6 +1509,7 @@ export default {
   },
   activated: function() {
     this.$nextTick(() => {
+			this.clientWidth = document.documentElement.clientWidth - 224;
         postAction('/v1/api/file/getFileListByPage',{page: 1,size: 10}).then(res=>{
             console.log(res)
         })

+ 53 - 0
src/views/modules/Statistics/change-face/change-face.less

@@ -0,0 +1,53 @@
+.change-face-modal {
+    width: 800px !important;
+    .policy-operation-form,
+    .face-right-div,
+    .face-right-table {
+        margin-top: 20px;
+    }
+    .face-right-div-p {
+        display: flex;
+        justify-content: space-between;
+    }
+    .pagin-table-class {
+        display: flex;
+        justify-content: flex-end;
+        margin-top: 20px;
+    }
+    .avatar-uploader > .ant-upload {
+        width: 128px;
+        height: 128px;
+        position: relative;
+    }
+    .upload-img-class {
+        position: absolute;
+        top: 0;
+        left: 0;
+        height: 100%;
+        .img-flex-url {
+            width: 128px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            height: 100%;
+            img {
+                max-width: 100%;
+                max-height: 100%;
+            }
+        }
+        .cover-img-div {
+            position: absolute;
+            top: 0;
+            left: 0;
+            width: 100%;
+            height: 100%;
+            line-height: 120px;;
+            background: rgba(10, 10, 10, 0.5);
+            z-index: 10000;
+            .delete-icon-class {
+                font-size: 20px;
+                color: #1890ff;
+            }
+        }
+    }
+}

+ 374 - 0
src/views/modules/Statistics/change-face/change-face.vue

@@ -0,0 +1,374 @@
+<template>
+    <!-- 换脸弹窗 -->
+    <a-modal
+        v-if="faceShowStatus"
+        title="换脸操作"
+        :visible="faceShowStatus"
+        dialog-class="change-face-modal"
+        @ok="handlePolicyOperationSure"
+        @cancel="handlePolicyOperationCancel"
+    >  
+        <div class="face-right-div-p">
+            <a-radio-group v-model="faceType" button-style="solid" @change="handleFaceTypeChange">
+                <a-radio-button value="a">人脸合成</a-radio-button>
+                <a-radio-button value="b">合成列表</a-radio-button>
+            </a-radio-group>
+            <span v-if="faceType === 'b'" class="add-acount-policy-btn"><a-button type="primary" @click="handleRefresh">刷新</a-button></span>
+        </div>
+        <a-form-model
+            v-if="faceType === 'a'"
+            class="policy-operation-form"
+            ref="policyOperationForm"
+            :model="policyOperationForm"
+            :label-col="labelCol"
+            :wrapper-col="wrapperCol"
+        >
+            <a-form-model-item label="图片上传">
+                <a-upload
+                    name="avatar"
+                    list-type="picture-card"
+                    class="avatar-uploader"
+                    :show-upload-list="false"
+                    :before-upload="beforeUpload"
+                >
+                    <div v-if="imageUrl" class="upload-img-class">
+                        <div class="img-flex-url">
+                            <img :src="imageUrl" alt="avatar"/>
+                        </div>
+                    </div>
+                    <div v-else>
+                        <a-icon type="plus" style="margin-top: 10px;"/>
+                        <div class="ant-upload-text">Upload</div>
+                    </div>
+                </a-upload>
+                <p>提示:上传人脸照片只会识别一次</p>
+            </a-form-model-item>
+        </a-form-model>
+        <div v-else-if="faceType === 'b'" class="face-right-div">
+            <a-table
+                class="face-right-table"
+                ref="table"
+                size="middle"
+                bordered
+                :columns="settlementColumns"
+                :dataSource="dataSource"
+                :pagination="false"
+            >
+                <span slot="input_video_url" slot-scope="text, record">
+                    <video :src="record.input_video_url" style="width:100px" controls></video>
+                </span>
+                <span slot="input_image_url" slot-scope="text, record">
+                    <img v-if="text" :src="text" style="width:60px">
+                    <img v-if="!text" src="@/assets/noImg.png" style="width:60px">
+                </span>
+                <span slot="actions" slot-scope="text, record">
+                    <a @click="handlePushData(record)">推送</a>
+                    <a-divider type="vertical"/>
+                    <a @click="handleDownLoadData(record)">下载</a>
+                </span>
+            </a-table>
+            <a-pagination
+                class="pagin-table-class"
+                :total="totalAll"
+                :show-total="total => `共 ${totalAll} 条`"
+                size="small"
+                :current="defaultCurrent"
+                :defaultPageSize="2"
+                @change="onShowSizeChange"
+                @showSizeChange="onShowSizeChange"
+            />
+        </div>
+    </a-modal>
+</template>
+<script>
+import {mapGetters} from 'vuex';
+import {fileInsertV2} from '@/api/actor';
+import {getAction, postAction, putAction, deleteAction} from '@/api/manage';
+
+import BMF from 'browser-md5-file';
+let COS = require('cos-js-sdk-v5');
+let cos = new COS({
+    SecretId: 'AKIDE6IpMi8fJQRCg1iuWzFajjRs43kbbets',
+    SecretKey: 'tXzuwMfplTTK3c9GFUyETilasvQfePu9'
+});
+export default {
+    name: 'change-face',
+    props: {
+        status: {
+            type: Boolean,
+            default: false
+        },
+        defaultList: {
+            type: Object,
+            default: () => {}
+        }
+    },
+    data() {
+        return {
+            defaultCurrent: 1,
+            dataAllList: [],
+            totalAll: 100,
+            uploadType: 'face',
+            dataSource: [],
+            settlementColumns: [
+                {
+                    title: '视频',
+                    dataIndex: 'input_video_url',
+                    align: 'center',
+                    width: 150,
+                    scopedSlots: {customRender: 'input_video_url'}
+                },
+                {
+                    title: '人脸',
+                    dataIndex: 'input_image_url',
+                    align: 'center',
+                    width: 150,
+                    scopedSlots: {customRender: 'input_image_url'}
+                },
+                {
+                    title: '状态',
+                    align: 'center',
+                    dataIndex: 'status',
+                    width: 100
+                },
+                {
+                    title: '操作',
+                    align: 'center',
+                    dataIndex: 'actions',
+                    width: 130,
+                    scopedSlots: {customRender: 'actions'}
+                }
+            ],
+            labelCol: {span: 4},
+            wrapperCol: {span: 16},
+            imageUrl: '',
+            faceShowStatus: false,
+            faceType: 'a',
+            policyOperationForm: {},
+            urlResult: '',
+            md5Result: ''
+        };
+    },
+    watch: {
+        status(newVal) {
+            this.faceShowStatus = newVal;
+        },
+        defaultList(newVal) {
+            if (newVal) {
+                console.log(newVal, 'newVal--newVal');
+                this.faceShowList = newVal;
+            }
+        }
+    },
+    methods: {
+        ...mapGetters(['userInfo']),
+        // 分页操作按钮
+        onShowSizeChange(current, pageSize) {
+            console.log(this.dataAllList, current, '-------00000');
+            this.defaultCurrent = current;
+            const defaultData = [...this.dataAllList];
+            this.dataSource = [...defaultData.slice(2 * current - 2, 2 * current)];
+        },
+        handleFaceTypeChange(e) {
+            if (e.target.value === 'b') {
+                this.handleInitTable();
+            }
+        },
+        handleInitTable() {
+            const paramsData = {
+                videoMd5: this.faceShowList.videoCode
+            };
+            postAction('http://192.168.1.34:8000/jeecg-boot/task/query', paramsData).then(result => {
+                if (result.code === 0) {
+                    this.dataAllList = result.data;
+                    this.dataSource = result.data.slice(0, 2);
+                    this.totalAll = result.data.length ? result.data.length : 0;
+                }
+                else {
+                    this.$message.error(result.message);
+                }
+            }).catch(error => {
+                console.log(error, 'eeee');
+            });
+        },
+        // 推送操作
+        handlePushData(list) {
+            console.log(list, '推送操作');
+            const paramsData = {};
+            fileInsertV2(paramsData).then(res => {
+                if (res.success) {
+                    console.log(res, 'res---res推送');
+                }
+            });
+        },
+        // 下载操作
+        handleDownLoadData(list) {
+            const randomTime = new Time().getTime() + '_check.mp4';
+            fetch(list.input_video_url)
+                .then(res => res.blob())
+                .then(blob => {
+                    const a = document.createElement('a');
+                    document.body.appendChild(a);
+                    a.style.display = 'none';
+                    // 使用获取到的blob对象创建的url
+                    const url = window.URL.createObjectURL(blob);
+                    a.href = url;
+                    // 指定下载的文件名
+                    a.download = randomTime;
+                    a.click()
+                    document.body.removeChild(a);
+                    // 移除blob对象的url
+                    window.URL.revokeObjectURL(url);
+                });
+        },
+        // 刷新按钮
+        handleRefresh() {
+            this.defaultCurrent = 1;
+            this.handleInitTable();
+        },
+        // 确定按钮
+        handlePolicyOperationSure() {
+            console.log(this.urlResult, this.md5Result, '确定按钮');
+            if (this.faceType === 'a') {
+                if (!this.md5Result) {
+                    this.$message.error('请上传图片');
+                    return;
+                }
+                const paramsData = {
+                    inputVideoUrl: 'https://media-1301855440.cos.ap-chongqing.myqcloud.com/video/2021-08-05/%E4%BC%9A%E7%8E%A9-%E6%B1%9F%E6%96%8C%E7%BB%84-%E7%BC%96%E6%9C%B1%E6%B1%9F%E6%96%8C-%E6%91%84%E6%9D%A8%E5%A8%81-%E5%89%AA%E9%83%91%E7%BF%94%E7%82%9C-08.03%20%282%29-1628164520693.mp4',
+                    inputImageUrl: this.urlResult,
+                    videoMd5: this.faceShowList.videoCode,
+                    imageMd5: this.md5Result,
+                    createBy: this.userInfo().id
+                };
+                postAction('http://192.168.1.34:8000/jeecg-boot/task/single', paramsData).then(result => {
+                    console.log(result, 'v--确定按钮');
+                    if (result.code === 0) {
+                        this.$emit('sureface');
+                    }
+                    else {
+                        this.$message.error(result.message);
+                    }
+                }).catch(error => {
+                    console.log(error, 'eeee');
+                });
+            }
+            else {
+                this.handlePolicyOperationCancel();
+            }
+        },
+        // 取消按钮
+        handlePolicyOperationCancel() {
+            this.faceType = 'a';
+            this.imageUrl = '';
+            this.urlResult = '';
+            this.md5Result = '';
+            this.$emit('closeface');
+        },
+        getBase64(img, callback) {
+            const reader = new FileReader();
+            reader.addEventListener('load', () => callback(reader.result));
+            reader.readAsDataURL(img);
+        },
+        beforeUpload(info) {
+            const isZip = info.type.includes('png') || info.type.includes('jpeg');
+            // const fileOvesize = info.size > (1024 * 1024);
+            if (!isZip) {
+                this.$message.error('请上传正确类型的图片');
+                this.imageUrl = '';
+                this.urlResult = '';
+                this.md5Result = '';
+                return;
+            }
+            this.handleMd5(info);
+            this.cosUpload(info);
+            this.getBase64(info, imageUrl => {
+                this.imageUrl = imageUrl;
+            });
+            // if (fileOvesize) {
+            //     this.$message.error('图片大小不能超过1M');
+            //     this.imageUrl = '';
+            //     this.urlResult = '';
+            //     this.md5Result = '';
+            //     return;
+            // }
+            // new Promise(function (resolve, reject) {
+            //     let width = 108;
+            //     let height = 108;
+            //     let _URL = window.URL || window.webkitURL;
+            //     let img = new Image();
+            //     img.onload = function () {
+            //         let valid = img.width === width && img.height === height;
+            //         valid ? resolve() : reject();
+            //     };
+            //     img.src = _URL.createObjectURL(info);
+            // }).then(() => {
+            //     this.handleMd5(info);
+            //     this.getBase64(info, imageUrl => {
+            //         this.imageUrl = imageUrl;
+            //     });
+            // }, () => {
+            //     this.$message.error('图片尺寸必须是108*108!');
+            //     this.imageUrl = '';
+            //     this.urlResult = '';
+            //     this.md5Result = '';
+            //     return Promise.reject();
+            // });
+        },
+        handleMd5(file) {
+            let bmf = new BMF();
+            let that = this;
+            return new Promise(function (resolve, reject) {
+                bmf.md5(file, (err, md5) => {
+                    that.md5Result = md5;
+                });
+            });
+        },
+        cosUpload(file) {
+            let 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;
+            let timeElse = new Date().getTime();
+            let arr = file.name.split('.');
+            let 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] + '.';
+                    }
+                }
+            }
+            cos.putObject(
+                {
+                    Bucket: 'media-1301855440',
+                    Region: 'ap-chongqing',
+                    // 存储桶所在地域,必须字段
+                    Key: that.uploadType + '/' + y + '-' + MM + '-' + d + '/' + str + '-' + timeElse + '.' + arr[arr.length - 1],
+                    StorageClass: 'STANDARD',
+                    Body: file // 上传文件对象
+                },
+                function (err, data) {
+                    if (err) {
+                        that.$message.error('上传失败!!!' + err);
+                        return;
+                    }
+                    that.loadingElse = false;
+                    that.urlResult = 'http://' + data.Location;
+                }
+            );
+        },
+    }
+}
+</script>
+<style lang="less">
+    @import "change-face";
+</style>

+ 1 - 1
src/views/modules/Statistics/components/Treeselect.vue

@@ -123,7 +123,7 @@ export default {
   methods: {
     ...mapGetters(['nickname', 'avatar', 'userInfo']),
     update(node, id) {
-      // console.log(node)
+	  this.$emit('select-value', node);
       // getAction('/ctop/userAllocation/getAccountListByProjectId', {
       //   projectId: node.id,
       // }).then((res) => {

+ 33 - 33
src/views/modules/Statistics/components/selectPagination.vue

@@ -43,13 +43,13 @@
     v-clickoutside="handleClose"
     style="width: 100%"
     class="select-table"
-    :class="{'require-check':requireCheck} "
+    :class="{ 'require-check': requireCheck }"
   >
     <a-input
       placeholder="请选择项目名称"
       @focus="topMiddle = true"
       v-model="keyValue"
-      @change="getData"
+      @change="getData(productId)"
       :disabled="disabled"
     />
     <div
@@ -160,31 +160,32 @@ export default {
       default() {
         return false
       },
-    }
+    },
   },
 
   data() {
     return {
       taobaoSpecialOfferList: {
-        advertiserId: "fd41614705a047dd65ab0e34e9150cfe",
-        advertiserName: " 淘宝(中国)软件有限公司",
-        createTime: "2021-03-03 10:15:30",
-        designResponsibleName: "辛巴特",
+        advertiserId: 'fd41614705a047dd65ab0e34e9150cfe',
+        advertiserName: ' 淘宝(中国)软件有限公司',
+        createTime: '2021-03-03 10:15:30',
+        designResponsibleName: '辛巴特',
         id: 3660879,
         maxBid: 30000,
-        mediaId: "1",
+        mediaId: '1',
         productId: 1410280,
-        productName: "头条-淘宝特价版",
+        productName: '头条-淘宝特价版',
         projectId: 1530887,
-        projectName: "头条-淘宝特价版",
-        responsibleName: "董琪",
-        roleCode: "operator",
+        projectName: '头条-淘宝特价版',
+        responsibleName: '董琪',
+        roleCode: 'operator',
         saleId: null,
         saleName: null,
-        updateTime: "2021-03-03 21:23:04",
-        userId: "a0d58df3392c4583b55ce3b041792aa7",
-        userName: "王晓娟"
+        updateTime: '2021-03-03 21:23:04',
+        userId: 'a0d58df3392c4583b55ce3b041792aa7',
+        userName: '王晓娟',
       },
+      productId: '',
       loading: false,
       busy: false,
       wrapperCol: {
@@ -245,7 +246,8 @@ export default {
         return { orientationId: item.orientationId, orientationName: item.orientationName }
       })
     },
-    getData() {
+    getData(productId) {
+      this.productId = productId
       if (this.keyValue == '') {
         this.$emit('update:projectId', '')
       }
@@ -254,6 +256,7 @@ export default {
         userId: this.userInfo().id,
         pageNo: this.ipagination.current,
         projectName: this.keyValue,
+        productId: productId?productId:'',
       }).then((res) => {
         if (res.code == 0) {
           let defaultList = res.result.records.map((item, index) => {
@@ -261,13 +264,12 @@ export default {
               ...item,
               projectId: item.projectId + '',
               key: index,
-            };
+            }
           })
           if (this.type === 'taobao') {
-            this.data = defaultList.filter(item => item.productId === 1410280);
-          }
-          else {
-            this.data = defaultList;
+            this.data = defaultList.filter((item) => item.productId === 1410280)
+          } else {
+            this.data = defaultList
           }
           // this.dataElse = res.result.records.map((item, index) => {
           //   return {
@@ -319,23 +321,21 @@ export default {
         pageSize: this.ipagination.pageSize,
         pageNo: this.ipagination.current,
         projectName: this.keyValue,
+        productId: this.productId?this.productId:null,
       }).then((res) => {
         if (res.code == 0) {
           this.busy = true
           let defaultList = res.result.records.map((item, index) => {
-              return {
-                ...item,
-                projectId: item.projectId + '',
-              }
-            })
-          this.data = data.concat(
-            
-          )
+            return {
+              ...item,
+              projectId: item.projectId + '',
+            }
+          })
+          this.data = data.concat()
           if (this.type === 'taobao') {
-            this.data = defaultList.filter(item => item.productId === 1410280);
-          }
-          else {
-            this.data = data.concat(defaultList);
+            this.data = defaultList.filter((item) => item.productId === 1410280)
+          } else {
+            this.data = data.concat(defaultList)
           }
           // this.data = res.result.records.map((item, index) => {
           //   return {

+ 311 - 0
src/views/modules/Statistics/designerReport/designerReport.vue

@@ -0,0 +1,311 @@
+<template>
+  <div class="directional-content">
+    <a-card style="width: 100%"> 
+        <div class="table-page-search-wrapper">
+            <a-form layout="inline"  :form="form"
+                hide-required-mark :selfUpdate="true" 
+                @submit="handleQueryList">
+                <a-row :gutter="24">
+                    <a-col :md="8" :sm="8" :xxl="6">
+                       <a-form-item label="人员名称">
+                            <a-input
+                                v-decorator="['realname']" type="text"
+                                placeholder="请输入想要搜索的人员名称"
+                            />
+                        </a-form-item>
+                    </a-col>
+                    <a-col :md="8" :sm="8" :xxl="6">
+                        <a-form-item label="岗位">
+                            <a-select
+                                v-decorator="['roleCode',{initialValue:''}]"
+                                placeholder="请选择"
+                                allow-clear
+                            >
+                                <a-select-option :value="''">不限</a-select-option>
+                                <a-select-option value="clip">剪辑</a-select-option>
+                                <a-select-option value="shot">拍摄</a-select-option>
+                                <a-select-option value="plan">策划</a-select-option>
+                            </a-select>
+                        </a-form-item>
+                    </a-col>
+                     <!--  -->
+                    <a-col :md="8" :sm="8" :xxl="6">
+                        <a-form-item label="时间">
+                            <a-range-picker
+                                :disabled-date="disabledDate"
+                                format="YYYY-MM-DD" 
+                                v-model="timeRange"
+                            />
+                        </a-form-item>
+                    </a-col>
+                    <a-col :md="8" :sm="8" :xxl="6">
+                        <a-form-item label="公司">
+                            <a-select
+                                v-decorator="['companyId',{initialValue:''}]"
+                                placeholder="请选择"
+                                allow-clear
+                            >
+                                <a-select-option :value="''">不限</a-select-option>
+                                <a-select-option v-for="(item, index) in allCompany" :value="item.companyId" :key="index">{{ item.companyName }} </a-select-option>
+                            </a-select>
+                        </a-form-item>
+                    </a-col>
+                    <a-col :md="8" :sm="8" :xxl="6">
+                        <span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
+                            <a-button type="primary" icon="search" @click="handleQueryList">查询</a-button>
+                            <a-button type="primary" @click="handleResetForm" icon="reload" class="middle-button">重置</a-button>
+                        </span>
+                        
+                    </a-col>
+                </a-row>
+            </a-form>
+        </div>
+    </a-card>
+    <a-card  class="material-main">
+        <a-table
+            ref="table"
+            size="middle"
+            bordered
+            :dataSource="dataSource"
+            :pagination="false"
+            :loading="dataLoading"
+        >
+            <a-table-column key="realname" data-index="realname" title="设计人员"  align="center"/>
+            <a-table-column key="roleName" data-index="roleName" title="岗位"  align="center"/>
+            <a-table-column key="zhenrenNumber" data-index="zhenrenNumber"  align="center">
+                <span slot="title">视频数量(真人)
+                    <a-tooltip>
+                        <template slot="title">
+                        显示上传视频数量
+                        </template>
+                        <a-icon type="question-circle" />
+                    </a-tooltip>
+                </span>
+            </a-table-column>
+             <a-table-column key="zhenrenCharge" data-index="zhenrenCharge"  align="center">
+                <span slot="title">消耗(真人)
+                    <a-tooltip>
+                        <template slot="title">
+                        显示该人员所有视频的消耗数据
+                        </template>
+                        <a-icon type="question-circle" />
+                    </a-tooltip>
+                </span>
+            </a-table-column>
+            <a-table-column key="zhenrenCost" data-index="zhenrenCost" title="消耗/视频数量(真人)"  align="center"/>
+            <a-table-column key="zhizuoNumber" data-index="zhizuoNumber" align="center">
+                 <span slot="title">视频数量(制作)
+                    <a-tooltip>
+                        <template slot="title">
+                        显示上传视频数量
+                        </template>
+                        <a-icon type="question-circle" />
+                    </a-tooltip>
+                </span>
+            </a-table-column>
+            <a-table-column key="zhizuoCharge" data-index="zhizuoCharge" align="center">
+                 <span slot="title">消耗(制作)
+                    <a-tooltip>
+                        <template slot="title">
+                        显示该人员所有视频的消耗数据
+                        </template>
+                        <a-icon type="question-circle" />
+                    </a-tooltip>
+                </span>
+            </a-table-column>
+            <a-table-column key="zhizuoCost" data-index="zhizuoCost" title="消耗/视频数量(制作)"  align="center"/>
+        </a-table>
+        <a-pagination
+        size="small"
+        :showTotal="ipagination.showTotal"
+        style="float: right;margin-top:10px"
+        v-if="dataSource.length > 0"
+        showQuickJumper
+        :pageSize.sync="ipagination.pageSize"
+        :total="ipagination.total"
+        v-model="ipagination.current"
+        @change="getDataSource"
+        />
+    </a-card>
+    
+  </div>
+</template>
+
+<script>
+import moment from 'moment';
+import selectTable from '@/views/modules/Statistics/components/selectPagination.vue';
+import ChartCard from '@/components/ChartCard';
+import Trend from '@/components/Trend';
+import { stopOtherVideo, closeAllVideoFun } from '@/utils/videoControl'; // 停止除当前外的其他视频播放,及停止所有视频播放的方法
+import { getAction } from '../../../../api/manage';
+export default {
+    components: {
+        selectTable,
+        ChartCard,
+        Trend
+    },
+    data() {
+        return {
+            timeRange: [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
+            visibleVideo: false,
+            videoUrlShow: null,
+            spinning: false,
+            form: this.$form.createForm(this),
+            projectId: '',
+            dataSource: [],
+            dataLoading: false,
+            allCompany: [],
+            columns: [ {
+                    title: '设计人员',
+                    dataIndex: 'realname',
+                    align: 'center',
+                    scopedSlots: { customRender: 'realname' },
+                },
+                {
+                    title: '岗位',
+                    dataIndex: 'roleName',
+                    align: 'center',
+                    scopedSlots: { customRender: 'roleName' },
+                },
+                {
+                    title: '视频数量(真人)',
+                    dataIndex: 'zhenrenNumber',
+                    align: 'center',
+                    scopedSlots: { customRender: 'zhenrenNumber' },
+                },
+                {
+                    title: '消耗(真人)',
+                    dataIndex: 'zhenrenCharge',
+                    align: 'center',
+                    scopedSlots: { customRender: 'zhenrenCharge' },
+                },
+                {
+                    title: '消耗/视频数量(真人)',
+                    dataIndex: 'zhenrenCost',
+                    align: 'center',
+                    scopedSlots: { customRender: 'zhenrenCost' },
+                },
+                {
+                    title: '视频数量(制作)',
+                    dataIndex: 'zhizuoNumber',
+                    align: 'center',
+                    scopedSlots: { customRender: 'zhizuoNumber' },
+                },
+                {
+                    title: '消耗(制作)',
+                    dataIndex: 'zhizuoCharge',
+                    align: 'center',
+                    scopedSlots: { customRender: 'zhizuoCharge' },
+                },
+                {
+                    title: '消耗/视频数量(制作)',
+                    dataIndex: 'zhizuoCost',
+                    align: 'center',
+                    scopedSlots: { customRender: 'zhizuoCost' },
+                },
+            ],
+            ipagination: {
+                current: 1,
+                pageSize: 10,
+                //   pageSizeOptions: ['10', '20', '30'],
+                showTotal: (total, range) => {
+                    return range[0] + "-" + range[1] + " 共" + total + "条"
+                },
+                showQuickJumper: true,
+                showSizeChanger:false,
+                pageSizeOptions: ['10', '30', '50'],
+                total: 0,
+                onChange: (current, pageSize) => {
+                    // 切换分页时的回调,
+                    // 当在页面定义change事件时,切记要把此处的事件清除,因为这两个事件重叠了,可能到时候会导致一些莫名的bug
+                    this.ipagination.current = current;
+                    this.ipagination.pageSize= pageSize;
+                    const paramsData = this.form.getFieldsValue();
+                    this.handleGetTableList(paramsData)
+                }
+            },
+            totalData: null
+        }
+    },
+    watch: {
+        visibleVideo(n, o) {
+            if (!n) {
+                closeAllVideoFun()
+            }
+        },
+    },
+    methods: {
+        disabledDate(current) {
+            // Can not select days before today and today
+            return current && current > moment().endOf('day');
+        },
+        getDataSource(current, pageSize) {
+            // 切换分页时的回调,
+            // 当在页面定义change事件时,切记要把此处的事件清除,因为这两个事件重叠了,可能到时候会导致一些莫名的bug
+            this.ipagination.current = current;
+            this.ipagination.pageSize= pageSize;
+            const paramsData = this.form.getFieldsValue();
+            this.handleGetTableList(paramsData)
+        },
+        handleQueryList() {
+            this.ipagination.current = 1;
+            const paramsData = this.form.getFieldsValue();
+            this.handleGetTableList(paramsData);
+        },
+        handleResetForm() {
+            this.totalData = null;
+            this.ipagination.current = 1;
+            this.form.resetFields();
+            this.timeRange = [moment().subtract(1, 'days'), moment().subtract(1, 'days')];
+            this.handleGetTableList({});
+        },
+        handleGetTableList(data) {
+            this.spinning = true;
+            const paramsData = {
+                realname: data.realname,
+                roleCode: data.roleCode ? data.roleCode === '' ? null : data.roleCode : null,
+                companyId: data.companyId ? data.companyId === '' ? null : data.companyId : null,
+                startTime: this.timeRange&&this.timeRange.length === 2 ?  moment(this.timeRange[0]).format('YYYY-MM-DD') : null,
+                endTime: this.timeRange&&this.timeRange.length === 2 ?  moment(this.timeRange[1]).format('YYYY-MM-DD') : null,
+                pageNo:  this.ipagination.current,
+                pageSize: this.ipagination.pageSize
+            };
+            this.dataSource = []
+            this.dataLoading = true;
+            this.getAction('/kuaishou/kuaiShouVideoGet/labelMaterialList', paramsData).then(result => {
+                this.dataLoading = false;
+                this.spinning = false;
+                if (result.code === 200) {
+                    this.dataSource = result.result.pageInfo.list || [];
+                    if(result.result.total) {
+                        this.dataSource.unshift(result.result.total);
+                    }
+                    
+                    this.ipagination.total = result.result.pageInfo.total || 0;
+                }
+                else {
+                    this.$message.error(result.message);
+                }
+            }).catch(error => {
+                this.spinning = false;
+                this.dataLoading = false;
+                console.log(error, 'eeee');
+            });
+        },
+        getAllCompany() {
+            getAction('/system/userCompany/allCompany').then(res => {
+                if(res.success) {
+                    this.allCompany = res.result;
+                }
+            })
+        }
+    },
+    mounted() {
+        this.handleGetTableList({});
+        this.getAllCompany();
+    },
+}
+</script>
+<style lang="less" scoped>
+    @import "material";
+</style>

+ 42 - 34
src/views/modules/autoLaunch/application/directional-service.js

@@ -11,23 +11,16 @@
         return [
             {
                 title: '账户名称',
-                dataIndex: 'accountName',
-                width: '30%'
+                dataIndex: 'authName',
+                width: '50%',
+                align: 'center'
             },
             {
-                title: '所属项目',
-                dataIndex: 'projectName',
-                width: '30%'
-            },
-            {
-                title: '人群包数量',
-                dataIndex: 'count',
-                width: '20%'
-            },
-            {
-                title: '状态',
-                dataIndex: 'statusStr',
-                width: '20%'
+                title: '编辑',
+                dataIndex: 'action',
+                scopedSlots: {customRender: 'action'},
+                width: '50%',
+                align: 'center'
             }
         ]
     }
@@ -36,19 +29,37 @@
     setCauseColumns() {
         return [
             {
-                title: '项目名称',
-                dataIndex: 'projectName',
-                width: '30%'
+                title: '账户名称',
+                dataIndex: 'authName',
+                width: '25%',
+                align: 'center'
             },
             {
-                title: '账户名称',
-                dataIndex: 'accountName',
-                width: '30%'
+                title: '推送结果',
+                dataIndex: 'result',
+                width: '25%',
+                align: 'center'
             },
             {
-                title: '原因',
+                title: '失败原因',
                 dataIndex: 'message',
-                width: '40%'
+                width: '25%',
+                align: 'center',
+                customRender(t) {
+                    if(t === 'OK') {
+                        return '-';
+                    }
+                    else {
+                        return t;
+                    }
+                }
+            },
+            {
+                title: '操作',
+                dataIndex: 'action',
+                scopedSlots: {customRender: 'action'},
+                width: '25%',
+                align: 'center'
             }
         ]
     }
@@ -57,19 +68,16 @@
     setDepColumns() {
         return [
             {
-                title: '项目名称',
-                dataIndex: 'projectName',
-                width: '40%'
-            },
-            {
-                title: '账户数量',
-                dataIndex: 'accountCount',
-                width: '20%'
+                title: '广告组名称',
+                dataIndex: 'unitName',
+                width: '50%',
+                align: 'center'
             },
             {
-                title: '人群包数量',
-                dataIndex: 'count',
-                width: '20%'
+                title: '所属账户',
+                dataIndex: 'authName',
+                width: '50%',
+                align: 'center'
             }
         ]
     }

+ 225 - 0
src/views/modules/Statistics/designerReport/material.less

@@ -0,0 +1,225 @@
+.directional-content {
+    // background: #fff;
+    // height: calc(100vh - 137px);
+    // padding: 20px;
+    overflow: hidden;
+    /deep/.chart-card-content {
+        height: 0;
+    }
+    .middle-button {
+        margin: 0 8px;
+    }
+    .control-con-header {
+        margin-bottom: 20px;
+        position: relative;
+        /deep/ .ant-form-inline .ant-form-item > .ant-form-item-control-wrapper, .ant-form-inline .ant-form-item > .ant-form-item-label {
+            width: 200px !important;
+        }
+        .reset-class {
+            margin-right: 10px !important;
+        }
+        .upload-person {
+            position: absolute;
+            right: 10px;
+            top: 0;
+        }
+    }
+    .cause-text-class {
+        cursor: pointer;
+    }
+    .pagin-table-class {
+        display: flex;
+        justify-content: flex-end;
+        margin-top: 20px;
+    }
+    .acount-search-class {
+        width: 200% !important;
+    }
+    .grid-form-type {
+        margin-left: 210px;
+    }
+}
+/deep/ .push-modal {
+    width: 600px !important;
+    .acount-title {
+        display: flex;
+        font-size: 14px;
+        height: 40px;
+        line-height: 40px;
+        .acount-title-left {
+            margin-right: 20px;
+            width: 100px;
+        }
+    }
+    .push-plate {
+        margin-bottom: 20px;
+    }
+}
+.person-modal {
+    width: 500px;
+    /deep/ .ant-form-item {
+        display: flex;
+    }
+    /deep/ .ant-form-item-label {
+        width: 20%;
+    }
+    /deep/ .ant-form-item-control-wrapper {
+        width: 80%;
+    }
+    .acount-search-class {
+        width: 100% !important;
+    }
+    .upload-txt-rules {
+        margin-top: 10px;
+        margin-bottom: 10px;
+        line-height: 1.5;
+    }
+    /deep/ .ant-radio-group {
+        line-height: 30px;
+    }
+}
+/deep/ .cause-modal {
+    width: 600px !important;
+    .cause-modal-table-class {
+        height: 500px;
+        overflow-y: auto;
+    }
+    .pagin-table-class {
+        display: flex;
+        justify-content: flex-end;
+        margin-top: 20px;
+    }
+}
+/deep/ .relax-modal {
+    width: 600px !important;
+    .acount-title {
+        display: flex;
+        font-size: 14px;
+        height: 40px;
+        line-height: 40px;
+        .acount-title-left {
+            margin-right: 20px;
+            width: 100px;
+        }
+    }
+    .push-plate {
+        margin-bottom: 20px;
+    }
+}
+
+.grid-form-item-account {
+    /deep/ .ant-form-item-control {
+        line-height: inherit;
+    }
+}
+.material-total {
+    width: 100%;
+    min-height:100px;
+    margin-top:15px;
+    /deep/ .ant-card-body {
+        padding: 0;
+    }
+}
+.material-main {
+    width: 100%;
+    min-height:300px;
+    margin-top:15px;
+    .home-card {
+        width: 100%;
+        overflow: hidden;
+        padding: 10px 0px;
+        display: flex;
+        flex-wrap: wrap;
+        margin-left: 25px;
+        min-height: 300px;
+        .home-right {
+            width: 100%;
+        }
+      
+        .bg:after {
+            content: '';
+            width: 110%;
+            height: 110%;
+            position: absolute;
+            left: -5%;
+            top: -5%;
+            background: inherit;
+            filter: blur(10px);
+            z-index: 2;
+        }
+    }
+    .home-item {
+        overflow: hidden;
+        position: relative;
+        img {
+            width: 100%;
+            height: auto;
+        }
+        .bottom-details {
+            width: 100%;
+            height: 37%;
+            background: rgba(0, 0, 0, .7);
+            position: absolute;
+            bottom: 0;
+            left: 0;
+            z-index: 10;
+            padding: 10px;
+            .bottom-title {
+                display: flex;
+                justify-content: space-between;
+            }
+            h3 {
+                color: whitesmoke;
+                line-height: 25px;
+                width: 60%;
+                overflow: hidden; //超出的文本隐藏
+                text-overflow: ellipsis; //溢出用省略号显示
+                white-space: nowrap; //溢出不换行  
+            }
+            p {
+                color: whitesmoke;
+                line-height: 1;
+                width: 100%;
+                overflow: hidden; //超出的文本隐藏
+                text-overflow: ellipsis; //溢出用省略号显示
+                white-space: nowrap; //溢出不换行
+            }
+        }
+    }
+      
+    @media only screen and (min-width: 1200px) {
+        .home-item {
+            border-style: solid;
+            border-width: 1px;
+            border-color: #e4e4e4;
+            width: calc(25% - 50px);
+            padding: 10px;
+            margin-right: 50px;
+            margin-bottom: 10px;
+            display: flex;
+            align-items: center;
+            background: #fff;
+            position: relative;
+            z-index: 99;
+        }
+    }
+      
+    @media only screen and (min-width: 1530px) {
+        .home-item {
+            border-style: solid;
+            border-width: 1px;
+            border-color: #e4e4e4;
+            width: calc(20% - 50px);
+            padding: 10px;
+            margin-right: 50px;
+            margin-bottom: 10px;
+            display: flex;
+            align-items: center;
+            background: #fff;
+            position: relative;
+            z-index: 99;
+        }
+    }
+}
+
+

+ 25 - 7
src/views/modules/Statistics/imageStatics/imageCostReport.vue

@@ -8,10 +8,10 @@
             </a-tab-pane>
         </a-tabs>
       </div>
-    <div class="xiangmuxuanze">
+    <div class="xiangmuxuanze" style="display:flex;margin-top:20px" >
       <span>项目选择:</span>
        
-        <a-tree-select
+        <!-- <a-tree-select
             v-model="accountIds"
             show-search
             style="width: 600px;height:30px"
@@ -29,7 +29,8 @@
             :filterOption='filterOption'
         >
         
-        </a-tree-select>
+        </a-tree-select> -->
+        <Treeselect v-if="forceUpdate" :appId.sync="accountIds" :request.sync="medioId" ref="treeSelect" style="width: 600px;height:30px;position: relative;top: -10px;"/>
         
     </div>
     <div class="timeDiv">
@@ -142,9 +143,10 @@ import moment from 'moment'
 // import { JeecgListMixin } from '@/mixins/ipagination'
 import { getAction, postAction, downFile, downFilePost } from '@/api/manage'
 
-import { TreeSelect } from 'ant-design-vue';
-const SHOW_PARENT = TreeSelect.SHOW_PARENT;
+// import { TreeSelect } from 'ant-design-vue';
+// const SHOW_PARENT = TreeSelect.SHOW_PARENT;
 import DatePicker from '@/components/DatePicker'
+import Treeselect from '@/views/modules/Statistics/components/Treeselect.vue'
 // import selectComponent from './selectComponent'
 // import Treeselect from '../components/Treeselect'
 const TTcolumns = [
@@ -418,6 +420,8 @@ let show = 0
 export default {
   data() {
     return {
+        medioId: '1,3',
+        forceUpdate:true,
         type:0,
         dateValue:[moment().subtract(1,'days'),moment().subtract(1,'days')],
         openOptions:false,
@@ -428,7 +432,7 @@ export default {
         
         accountIds:[],
         treeData:[],
-        SHOW_PARENT,
+        // SHOW_PARENT,
         KSaccountList:[],
         TTaccountList:[],
         accountID:undefined,
@@ -514,7 +518,7 @@ export default {
   // mixins: [JeecgListMixin],
   components: {
     // selectComponent,
-    // Treeselect
+    Treeselect,
     DatePicker,
   },
     methods: {
@@ -523,18 +527,32 @@ export default {
           this.data=[]
           this.ipagination.current=1;
           this.totalCost={}
+          this.forceUpdate = false
           if(this.tabKeys==1){
+                
                 this.treeData=this.TTaccountList;
                 this.columns=this.TTcolumns;
                 this.target='cost';
                 this.scrollX=0;
                 this.getTableData(this.bytedanceUrl)
+                setTimeout(()=>{
+                  this.forceUpdate = true
+                  this.medioId = '1,3'
+                  this.$refs.treeSelect.getParticipateList()
+                },100)
+               
             }else if (this.tabKeys==2){
+              
                 this.treeData=this.KSaccountList;
                 this.columns=this.KScolumns
                 this.target='cost'
                 this.scrollX=2500
                 this.getTableData(this.kuaishouUrl)
+                 setTimeout(()=>{
+                  this.forceUpdate = true
+                  this.medioId = '2,4'
+                  this.$refs.treeSelect.getParticipateList()
+                },100)
             } 
         },
         treeChange(val) {

File diff suppressed because it is too large
+ 1235 - 940
src/views/modules/Statistics/materialReport/materialReport.vue


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

@@ -954,7 +954,7 @@ export default {
       return moment().endOf('day');
     },
     filterOption(input, option){
-      console.log(input, option)
+
       return (
           option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
         );

File diff suppressed because it is too large
+ 580 - 586
src/views/modules/Statistics/popularVideo.vue


+ 216 - 208
src/views/modules/Statistics/videoStatics/TTvideoStatics.vue

@@ -1,209 +1,210 @@
 <template>
-  <div class="vsummary">
-    <div class="xiangmuxuanze" >
-      <!-- <div> -->
-        <span>项目选择:</span>
-        <Treeselect  :appId.sync="appId" request="1,3"   style="display: inline-block;position: relative;"/>
-      <!-- </div> -->
-      
-      
-    </div>
-    <div class="timeDiv">
-      <div style='display:flex;align-items: center;'>
-        <span>时间范围:</span>
-        <div  @click="opendate">
-          <DatePicker :openOptions='openOptions'  :parentDate='dateValue' left='-100px'></DatePicker>
-        </div>    
-        <!-- <a-range-picker
-          :disabled-date="disabledDate"
-          format="YYYY-MM-DD"
-          style="width: 250px;"
-          @change="dateChange"
-          v-model="dateRange"
-        />
-        <span v-show="daysFlag">共{{totalSelect}}天</span> -->
-        <span style="margin-left:15px">剪辑:</span> 
-        <span  >
-            <a-input placeholder="请输入剪辑的名字" v-model="clip" style="width:140px"  />
-        </span>         
-        <span style="margin-left:15px">拍摄:</span> 
-        <span  >
-            <a-input placeholder="请输入拍摄的名字" v-model="shot" style="width:140px" />
-        </span>         
-        <span style="margin-left:15px">编导:</span> 
-        <span  >
-            <a-input placeholder="请输入编导的名字" v-model="plan" style="width:140px"  />
-        </span>          
-      </div>
-      <!-- <div>
-        <span>消耗:</span>
-        <a-input-number id="inputNumber" v-model="consumeValue" :min="0" @change="consumeOnChange" />
+	<div class="vsummary">
+		<div class="xiangmuxuanze" >
+			<span>项目选择:</span>
+			<Treeselect  :appId.sync="appId" request="1,3"   style="display: inline-block;position: relative;"/>
+			<span style="margin-left:15px">设计负责人:</span> 
+			<span>
+				<a-input placeholder="请输入设计负责人" v-model="designDirector" style="width:160px"  />
+			</span>
+		</div>
+		<div class="timeDiv">
+		<div style='display:flex;align-items: center;'>
+			<span>时间范围:</span>
+			<div  @click="opendate">
+			<DatePicker :openOptions='openOptions'  :parentDate='dateValue' left='-100px'></DatePicker>
+			</div>    
+			<!-- <a-range-picker
+			:disabled-date="disabledDate"
+			format="YYYY-MM-DD"
+			style="width: 250px;"
+			@change="dateChange"
+			v-model="dateRange"
+			/>
+			<span v-show="daysFlag">共{{totalSelect}}天</span> -->
+			<span style="margin-left:15px">剪辑:</span> 
+			<span  >
+				<a-input placeholder="请输入剪辑的名字" v-model="clip" style="width:140px"  />
+			</span>         
+			<span style="margin-left:15px">拍摄:</span> 
+			<span  >
+				<a-input placeholder="请输入拍摄的名字" v-model="shot" style="width:140px" />
+			</span>         
+			<span style="margin-left:15px">编导:</span> 
+			<span  >
+				<a-input placeholder="请输入编导的名字" v-model="plan" style="width:140px"  />
+			</span>
+		</div>
+		<!-- <div>
+			<span>消耗:</span>
+			<a-input-number id="inputNumber" v-model="consumeValue" :min="0" @change="consumeOnChange" />
 
-        <span>视频ID:</span>
-        <a-input class="myinput" v-model="videoID" style="width:250px" />
-      </div> -->
+			<span>视频ID:</span>
+			<a-input class="myinput" v-model="videoID" style="width:250px" />
+		</div> -->
 
-      <a-button type="primary" @click="searchRes">查询</a-button>
-    </div>
+		<a-button type="primary" @click="searchRes">查询</a-button>
+		</div>
 
-    <div style="margin:15px 0" class="btndiv">
-      <a-button type="primary" @click="customColumns">自定义列</a-button>
-      <a-button type="default" style="float:right" @click="exportExcel('exportTable')" id="mybtn"  :loading='exportLoading'>导出报表</a-button>
-    </div>
+		<div style="margin:15px 0" class="btndiv">
+		<a-button type="primary" @click="customColumns">自定义列</a-button>
+		<a-button type="default" style="float:right" @click="exportExcel('exportTable')" id="mybtn"  :loading='exportLoading'>导出报表</a-button>
+		</div>
 
-    
-    <a-table
-      size="middle"
-      :columns="columns"
-      :dataSource="data"
-      bordered
-      id="outTable"
-      :pagination="ipagination"
-      :scroll="{ x: scrollX }"
-      :loading="loading"
-      ref="vSummaryTable"
-      :width="tableWidth"
-      @customHeaderCell="customHeaderCell(columns)"
-      @change="sort"
-      style="word-break: break-all;font-size:16px;font-weight:600"
-    >
-      <div slot="videoU" slot-scope="test,records">
-        <!-- records.converUrl||'@/assets/noImg.png' -->
-        <img
-          :src="records.converUrl||noImg"
-          alt
-          style="width:80px"
-          @click="openVideo(records.url)"
-          @load="loadShow"
-        />
-        <!-- <video :src="records.converUrl"  style="width:80px" controls  @click="openVideo(records.url)"
-          @load="loadShow" ></video> -->
-      </div>
-        <span slot="operation" slot-scope="text, record">
-          <a href="javascript:;" @click="opendetail(text, record)" style="margin-right:5px">查看明细</a>
-        </span>
-      <!-- <span slot="ctr" slot-scope="ctr">{{ ctr | toPercentage }}</span> -->
-                <span slot="cost" slot-scope="cost">{{ cost | decimalsHandle }}</span>
-                <span slot="clickMaterial" slot-scope="clickMaterial">{{ clickMaterial | formatCurrency }}</span>
-                <span slot="showMaterial" slot-scope="showMaterial">{{ showMaterial | formatCurrency }}</span>
-                <span slot="convertMaterial" slot-scope="convertMaterial">{{ convertMaterial | formatCurrency }}</span>
-                <span slot="play25FeedBreak" slot-scope="play25FeedBreak">{{ play25FeedBreak | formatCurrency }}</span>
-                <span slot="play50FeedBreak" slot-scope="play50FeedBreak">{{ play50FeedBreak | formatCurrency }}</span>
-                <span slot="play75FeedBreak" slot-scope="play75FeedBreak">{{ play75FeedBreak | formatCurrency }}</span>
-                <span slot="play100FeedBreak" slot-scope="play100FeedBreak">{{ play100FeedBreak | formatCurrency }}</span>
-                <span slot="nextDayOpen" slot-scope="nextDayOpen">{{ nextDayOpen | formatCurrency }}</span>
-                <span slot="downloadFinish" slot-scope="downloadFinish">{{ downloadFinish | formatCurrency }}</span>
-                <span slot="downloadStart" slot-scope="downloadStart">{{ downloadStart | formatCurrency }}</span>
-                <span slot="likeMaterial" slot-scope="likeMaterial">{{ likeMaterial | formatCurrency }}</span>
-                <span slot="shareMaterial" slot-scope="shareMaterial">{{ shareMaterial | formatCurrency }}</span>
-                <span slot="register" slot-scope="register">{{ register | formatCurrency }}</span>
-                <span slot="follow" slot-scope="follow">{{ follow | formatCurrency }}</span>
-                <span slot="form" slot-scope="form">{{ form | formatCurrency }}</span>
-                <span slot="active" slot-scope="active">{{ active | formatCurrency }}</span>
-                <span slot="activePayAmount" slot-scope="activePayAmount">{{ activePayAmount | formatCurrency }}</span>
-                <!-- <span
-                  slot="play25FeedBreakRate"
-                  slot-scope="play25FeedBreakRate"
-                >{{ play25FeedBreakRate | toPercentage }}</span>
-                <span slot="playOverRate" slot-scope="playOverRate">{{ playOverRate | toPercentage }}</span> -->
-                <!-- 新加数据 -->
-                <!-- <span slot="convertRate" slot-scope="convertRate">{{ convertRate | toPercentage }}</span>
-                <span slot="nextDayOpenRate" slot-scope="nextDayOpenRate">{{ nextDayOpenRate | toPercentage }}</span>
-                <span slot="ctr" slot-scope="ctr">{{ ctr | toPercentage }}</span> -->
-                <span slot="cpc" slot-scope="cpc">{{ cpc | decimalsHandle }}</span>
-                <span slot="cpm" slot-scope="cpm">{{ cpm | decimalsHandle }}</span>
-                <span slot="activeRate" slot-scope="activeRate">{{ activeRate | toPercentage }}</span>
-                <!-- <span
-                  slot="installFinishRate"
-                  slot-scope="installFinishRate"
-                >{{ installFinishRate | toPercentage }}</span>
-                <span slot="validPlayRate" slot-scope="validPlayRate">{{ validPlayRate | toPercentage }}</span> -->
-                <span slot="activePayCost" slot-scope="activePayCost">{{ activePayCost | decimalsHandle }}</span>
-                <span slot="nextDayOpenCost" slot-scope="nextDayOpenCost">{{ nextDayOpenCost | decimalsHandle }}</span>
-                <span slot="validPlayCost" slot-scope="validPlayCost">{{ validPlayCost | decimalsHandle }}</span>
-                <span slot="activeCost" slot-scope="activeCost">{{ activeCost | decimalsHandle }}</span>
-                <span
-                  slot="gameAddictionCost"
-                  slot-scope="gameAddictionCost"
-                >{{ gameAddictionCost | decimalsHandle }}</span>
-                <span
-                  slot="downloadFinishCost"
-                  slot-scope="downloadFinishCost"
-                >{{ downloadFinishCost | decimalsHandle }}</span>
-                <span
-                  slot="downloadStartCost"
-                  slot-scope="downloadStartCost"
-                >{{ downloadStartCost | decimalsHandle }}</span>
-                <span
-                  slot="installFinishCost"
-                  slot-scope="installFinishCost"
-                >{{ installFinishCost | decimalsHandle }}</span>
-                <span slot="convertCost" slot-scope="convertCost">{{ convertCost | decimalsHandle }}</span>
+		
+		<a-table
+		size="middle"
+		:columns="columns"
+		:dataSource="data"
+		bordered
+		id="outTable"
+		:pagination="ipagination"
+		:scroll="{ x: scrollX }"
+		:loading="loading"
+		ref="vSummaryTable"
+		:width="tableWidth"
+		@customHeaderCell="customHeaderCell(columns)"
+		@change="sort"
+		style="word-break: break-all;font-size:16px;font-weight:600"
+		>
+		<div slot="videoU" slot-scope="test,records">
+			<!-- records.converUrl||'@/assets/noImg.png' -->
+			<img
+			:src="records.converUrl||noImg"
+			alt
+			style="width:80px"
+			@click="openVideo(records.url)"
+			@load="loadShow"
+			/>
+			<!-- <video :src="records.converUrl"  style="width:80px" controls  @click="openVideo(records.url)"
+			@load="loadShow" ></video> -->
+		</div>
+			<span slot="operation" slot-scope="text, record">
+			<a href="javascript:;" @click="opendetail(text, record)" style="margin-right:5px">查看明细</a>
+			</span>
+		<!-- <span slot="ctr" slot-scope="ctr">{{ ctr | toPercentage }}</span> -->
+					<span slot="cost" slot-scope="cost">{{ cost | decimalsHandle }}</span>
+					<span slot="clickMaterial" slot-scope="clickMaterial">{{ clickMaterial | formatCurrency }}</span>
+					<span slot="showMaterial" slot-scope="showMaterial">{{ showMaterial | formatCurrency }}</span>
+					<span slot="convertMaterial" slot-scope="convertMaterial">{{ convertMaterial | formatCurrency }}</span>
+					<span slot="play25FeedBreak" slot-scope="play25FeedBreak">{{ play25FeedBreak | formatCurrency }}</span>
+					<span slot="play50FeedBreak" slot-scope="play50FeedBreak">{{ play50FeedBreak | formatCurrency }}</span>
+					<span slot="play75FeedBreak" slot-scope="play75FeedBreak">{{ play75FeedBreak | formatCurrency }}</span>
+					<span slot="play100FeedBreak" slot-scope="play100FeedBreak">{{ play100FeedBreak | formatCurrency }}</span>
+					<span slot="nextDayOpen" slot-scope="nextDayOpen">{{ nextDayOpen | formatCurrency }}</span>
+					<span slot="downloadFinish" slot-scope="downloadFinish">{{ downloadFinish | formatCurrency }}</span>
+					<span slot="downloadStart" slot-scope="downloadStart">{{ downloadStart | formatCurrency }}</span>
+					<span slot="likeMaterial" slot-scope="likeMaterial">{{ likeMaterial | formatCurrency }}</span>
+					<span slot="shareMaterial" slot-scope="shareMaterial">{{ shareMaterial | formatCurrency }}</span>
+					<span slot="register" slot-scope="register">{{ register | formatCurrency }}</span>
+					<span slot="follow" slot-scope="follow">{{ follow | formatCurrency }}</span>
+					<span slot="form" slot-scope="form">{{ form | formatCurrency }}</span>
+					<span slot="active" slot-scope="active">{{ active | formatCurrency }}</span>
+					<span slot="activePayAmount" slot-scope="activePayAmount">{{ activePayAmount | formatCurrency }}</span>
+					<!-- <span
+					slot="play25FeedBreakRate"
+					slot-scope="play25FeedBreakRate"
+					>{{ play25FeedBreakRate | toPercentage }}</span>
+					<span slot="playOverRate" slot-scope="playOverRate">{{ playOverRate | toPercentage }}</span> -->
+					<!-- 新加数据 -->
+					<!-- <span slot="convertRate" slot-scope="convertRate">{{ convertRate | toPercentage }}</span>
+					<span slot="nextDayOpenRate" slot-scope="nextDayOpenRate">{{ nextDayOpenRate | toPercentage }}</span>
+					<span slot="ctr" slot-scope="ctr">{{ ctr | toPercentage }}</span> -->
+					<span slot="cpc" slot-scope="cpc">{{ cpc | decimalsHandle }}</span>
+					<span slot="cpm" slot-scope="cpm">{{ cpm | decimalsHandle }}</span>
+					<span slot="activeRate" slot-scope="activeRate">{{ activeRate | toPercentage }}</span>
+					<!-- <span
+					slot="installFinishRate"
+					slot-scope="installFinishRate"
+					>{{ installFinishRate | toPercentage }}</span>
+					<span slot="validPlayRate" slot-scope="validPlayRate">{{ validPlayRate | toPercentage }}</span> -->
+					<span slot="activePayCost" slot-scope="activePayCost">{{ activePayCost | decimalsHandle }}</span>
+					<span slot="nextDayOpenCost" slot-scope="nextDayOpenCost">{{ nextDayOpenCost | decimalsHandle }}</span>
+					<span slot="validPlayCost" slot-scope="validPlayCost">{{ validPlayCost | decimalsHandle }}</span>
+					<span slot="activeCost" slot-scope="activeCost">{{ activeCost | decimalsHandle }}</span>
+					<span
+					slot="gameAddictionCost"
+					slot-scope="gameAddictionCost"
+					>{{ gameAddictionCost | decimalsHandle }}</span>
+					<span
+					slot="downloadFinishCost"
+					slot-scope="downloadFinishCost"
+					>{{ downloadFinishCost | decimalsHandle }}</span>
+					<span
+					slot="downloadStartCost"
+					slot-scope="downloadStartCost"
+					>{{ downloadStartCost | decimalsHandle }}</span>
+					<span
+					slot="installFinishCost"
+					slot-scope="installFinishCost"
+					>{{ installFinishCost | decimalsHandle }}</span>
+					<span slot="convertCost" slot-scope="convertCost">{{ convertCost | decimalsHandle }}</span>
 
-                <!--  -->
-                <!-- <span
-                  slot="downloadStartRate"
-                  slot-scope="downloadStartRate"
-                >{{ downloadStartRate | toPercentage }}</span>
-                <span
-                  slot="downloadFinishRate"
-                  slot-scope="downloadFinishRate"
-                >{{ downloadFinishRate | toPercentage }}</span>
-                <span slot="activeRate" slot-scope="activeRate">{{ activeRate | toPercentage }}</span>
-                <span
-                  slot="activeRegisterRate"
-                  slot-scope="activeRegisterRate"
-                >{{ activeRegisterRate | toPercentage }}</span>
-                <span
-                  slot="gameAddictionRate"
-                  slot-scope="gameAddictionRate"
-                >{{ gameAddictionRate | toPercentage }}</span>
-                <span slot="nextDayOpenRate" slot-scope="nextDayOpenRate">{{ nextDayOpenRate | toPercentage }}</span> -->
-                
-      
-        <span slot="relativePeople" slot-scope="text,record">
-           <!-- <a href="javascript:;" @click.stop="showRelevantPeople(record)">查看相关人员</a> -->
-            <p>剪辑:{{record.clip || '无'}}</p>
-            <p>拍摄:{{record.shot || '无'}}</p>
-            <p>编导:{{record.plan ||'无'}}</p>
-       </span>
+					<!--  -->
+					<!-- <span
+					slot="downloadStartRate"
+					slot-scope="downloadStartRate"
+					>{{ downloadStartRate | toPercentage }}</span>
+					<span
+					slot="downloadFinishRate"
+					slot-scope="downloadFinishRate"
+					>{{ downloadFinishRate | toPercentage }}</span>
+					<span slot="activeRate" slot-scope="activeRate">{{ activeRate | toPercentage }}</span>
+					<span
+					slot="activeRegisterRate"
+					slot-scope="activeRegisterRate"
+					>{{ activeRegisterRate | toPercentage }}</span>
+					<span
+					slot="gameAddictionRate"
+					slot-scope="gameAddictionRate"
+					>{{ gameAddictionRate | toPercentage }}</span>
+					<span slot="nextDayOpenRate" slot-scope="nextDayOpenRate">{{ nextDayOpenRate | toPercentage }}</span> -->
+					
+		
+			<span slot="relativePeople" slot-scope="text,record">
+			<!-- <a href="javascript:;" @click.stop="showRelevantPeople(record)">查看相关人员</a> -->
+				<p>剪辑:{{record.clip || '无'}}</p>
+				<p>拍摄:{{record.shot || '无'}}</p>
+				<p>编导:{{record.plan || '无'}}</p>
+				<p>负责人:{{record.leader || '无'}}</p>
+		</span>
 
-    </a-table>
-    <a-modal v-model="relevantPeopleVisible" title="相关人员" :footer="null" :centered='true'>
-        <p>编导:{{relevantPeopleData.planName || '暂无数据'}}</p>
-        <p>剪辑:{{relevantPeopleData.clipName || '暂无数据'}}</p>
-        <p>拍摄:{{relevantPeopleData.shotName || '暂无数据'}}</p>
-      </a-modal>
-    <a-modal v-model="Videovisible" title="视频详情" @ok="videoOk" :footer="null" width="50%">
-      <video
-        @click.stop
-        class="video"
-        :src="videoUrl"
-        controls="controls"
-        style="height:600px;width:100%"
-      >您的浏览器不支持 video 标签。</video>
-    </a-modal>
-    <customColumn :visible='visible'  :listNum='listNum' :fiexColumn='columnsFixd' :mediaType='1'  @closeCustomColumn='closeCustomColumn' @changeColumn='changeColumn' />
+		</a-table>
+		<a-modal v-model="relevantPeopleVisible" title="相关人员" :footer="null" :centered='true'>
+			<p>编导:{{relevantPeopleData.planName || '暂无数据'}}</p>
+			<p>剪辑:{{relevantPeopleData.clipName || '暂无数据'}}</p>
+			<p>拍摄:{{relevantPeopleData.shotName || '暂无数据'}}</p>
+		</a-modal>
+		<a-modal v-model="Videovisible" title="视频详情" @ok="videoOk" :footer="null" width="50%">
+		<video
+			@click.stop
+			class="video"
+			:src="videoUrl"
+			controls="controls"
+			style="height:600px;width:100%"
+		>您的浏览器不支持 video 标签。</video>
+		</a-modal>
+		<customColumn :visible='visible'  :listNum='listNum' :fiexColumn='columnsFixd' :mediaType='1'  @closeCustomColumn='closeCustomColumn' @changeColumn='changeColumn' />
 
 
-    <!-- 明细表 -->
+		<!-- 明细表 -->
 
-      <a-modal v-model="visibleDetail" title="详细信息" width="50%" :footer="null" >
-        <a-button type="default" @click="exportExcel('exportDetail')" id="mybtn" :loading="visibleLoading">导出报表</a-button>
-        <a-table
-          :columns="detailColumn"
-          :data-source="detailData"
-          bordered
-          tableLayout="auto"
-          :loading='detailLoading'
-          :pagination="false"
-          style="word-break: break-all;"
-        >
-          <span slot="advertiserName" slot-scope="text">{{ text || '暂未填写该数据' }}</span>
-          <span slot="cost" slot-scope="cost">{{ cost | decimalsHandle }}</span>
-        </a-table>
-      </a-modal>
-  </div>
+		<a-modal v-model="visibleDetail" title="详细信息" width="50%" :footer="null" >
+			<a-button type="default" @click="exportExcel('exportDetail')" id="mybtn" :loading="visibleLoading">导出报表</a-button>
+			<a-table
+			:columns="detailColumn"
+			:data-source="detailData"
+			bordered
+			tableLayout="auto"
+			:loading='detailLoading'
+			:pagination="false"
+			style="word-break: break-all;"
+			>
+			<span slot="advertiserName" slot-scope="text">{{ text || '暂未填写该数据' }}</span>
+			<span slot="cost" slot-scope="cost">{{ cost | decimalsHandle }}</span>
+			</a-table>
+		</a-modal>
+	</div>
 </template>
 
 <script>
@@ -231,6 +232,13 @@ const columnsFixd = [
     width: 120,
     fixed: 'left'
   },
+  // {
+  //   title: '设计负责人',
+  //   dataIndex: 'leader',
+  //   align: 'center',
+  //   width: 120,
+  //   fixed: 'left'
+  // },
   {
     title: '视频ID',
     dataIndex: 'signature',
@@ -359,6 +367,7 @@ const initVariableColimns=[
 export default {
   data() {
     return {
+		designDirector: '',
       visibleLoading:false,
       noImg:require('@/assets/noImg.png'),
       detailLoading:false,
@@ -585,24 +594,23 @@ export default {
         accountIds:this.appId,
         target:this.target,
         order:this.order,
-         clip:this.clip?this.clip:'',
+		leader: this.designDirector,
+        clip:this.clip?this.clip:'',
         shot:this.shot?this.shot:'',
         plan:this.plan?this.plan:'',
       }).then(res => {
         let resArr = []
         this.data=[];
-         this.loading = false
+        this.loading = false
         if (res.success) {
-        
-          this.data = res.result.list.map((item,index)=>{
-              return {
-                  ...item,
-                  key:index
-              }
-          })
-          this.ipagination.total = res.result.total
-          this.loading = false
-          
+			this.data = res.result.list.map((item,index)=>{
+				return {
+					...item,
+					key:index
+				}
+			})
+			this.ipagination.total = res.result.total
+			this.loading = false
         }
       })
     },

+ 4 - 3
src/views/modules/account-config/account-config-server.js

@@ -3,7 +3,8 @@
  * @author jiayufei
  */
 
-export const urlAcount = 'http://118.24.244.213:8080'; // 线上
+export const urlAcount = 'http://118.24.244.213:8808'; // 线上
 // export const urlAcount = 'http://apipre.tjyourong.com.cn'; // 预生产
-// export const urlAcount = 'http://192.168.1.43:8080'; // 子安
-// export const urlAcount = 'http://139.186.165.84:8080'; // 测试
+// export const urlAcount = 'http://192.168.1.43:8808'; // 子安
+// export const urlAcount = 'http://139.186.165.84:8808'; // 测试
+// export const urlAcount = 'http://192.168.1.8:8080'; // 学超

+ 92 - 10
src/views/modules/account-config/account-config.vue

@@ -16,6 +16,22 @@
                     >
                         <acount-search class="acount-search-class" :appId.sync="acountId" :multiple="false" request="1,3"></acount-search>
                     </a-form-item>
+                    <a-form-item label="素材类型">
+                        <a-select v-model="creativeStatus" style="width: 100px">
+                            <a-select-option :value="2">不限</a-select-option>
+                            <a-select-option value="CREATIVE_IMAGE_MODE_VIDEO_VERTICAL">竖版视频</a-select-option>
+                            <a-select-option value="CREATIVE_IMAGE_MODE_LARGE">大图横图</a-select-option>
+                            <a-select-option value="CREATIVE_IMAGE_MODE_LARGE_VERTICAL">大图竖图</a-select-option>
+                            <a-select-option value="CREATIVE_IMAGE_MODE_UNION_SPLASH">开屏</a-select-option>
+                        </a-select>
+                    </a-form-item>
+                    <a-form-item label="状态">
+                        <a-select v-model="searchStatus" style="width: 100px">
+                            <a-select-option :value="2">不限</a-select-option>
+                            <a-select-option :value="0">开启</a-select-option>
+                            <a-select-option :value="1">关闭</a-select-option>
+                        </a-select>
+                    </a-form-item>
                     <a-form-item class="form-handle-btn">
                         <a-button type="default" class="reset-class" @click="handleResetList">重置</a-button>
                         <a-button type="primary" html-type="submit">查询</a-button>
@@ -29,6 +45,7 @@
                 ref="table"
                 size="middle"
                 bordered
+                :loading="controlLoading"
                 :columns="columns"
                 :dataSource="dataSource"
                 :pagination="false"
@@ -45,10 +62,15 @@
                 <span slot="acountRelax" slot-scope="text, record">
                     <a-switch :checked="text === 0" @change="handleSwitchChang($event, record)"/>
                 </span>
+                <span slot="creativeImageMode" slot-scope="text">
+                    <span>{{ handleChangeCreativeImage(text) }}</span>
+                </span>
                 <span solt="accountBudget" slot-scope="text, record">
                     {{ record.accountBudgetMode === '1' ? '不限' : text }}
                 </span>
                 <span slot="action" slot-scope="text, record">
+                    <a @click="handleCopy(record)">复制</a>
+                    <a-divider type="vertical"/>
                     <a @click="handleEdit(record)">编辑</a>
                     <a-divider type="vertical"/>
                     <a @click="handleListDelete(record)">删除</a>
@@ -263,6 +285,35 @@ export default {
             }
         };
         return {
+            creativeImageOption: [
+                {
+                    id: 'CREATIVE_IMAGE_MODE_VIDEO_VERTICAL',
+                    value: '竖版视频'
+                },
+                {
+                    id: 'CREATIVE_IMAGE_MODE_VIDEO',
+                    value: '横版视频'
+                },
+                {
+                    id: 'CREATIVE_IMAGE_MODE_LARGE',
+                    value: '大图横图'
+                },
+                {
+                    id: 'CREATIVE_IMAGE_MODE_SMALL',
+                    value: '小图'
+                },
+                {
+                    id: 'CREATIVE_IMAGE_MODE_LARGE_VERTICAL',
+                    value: '大图竖图'
+                },
+                {
+                    id: 'CREATIVE_IMAGE_MODE_UNION_SPLASH',
+                    value: '开屏'
+                }
+            ],
+            searchStatus: 0,
+            creativeStatus: 2,
+            controlLoading: true,
             adBudgetShowTitle: false,
             budgetVisible: false,
             budgetForm: {
@@ -325,6 +376,12 @@ export default {
                     dataIndex: 'accountId_dictText'
                 },
                 {
+                    title: '素材类型',
+                    align: 'center',
+                    dataIndex: 'creativeImageMode',
+                    scopedSlots: {customRender: 'creativeImageMode'}
+                },
+                {
                     title: '账户ID',
                     align: 'center',
                     dataIndex: 'accountId'
@@ -360,7 +417,7 @@ export default {
                     title: '操作',
                     dataIndex: 'action',
                     align: 'center',
-                    width: '20%',
+                    width: '23%',
                     scopedSlots: {customRender: 'action'}
                 }
             ]
@@ -374,6 +431,9 @@ export default {
     },
     methods: {
         ...mapGetters(['nickname', 'avatar', 'userInfo']),
+        handleChangeCreativeImage(val) {
+            return val ? this.creativeImageOption.filter(item => item.id === val)[0].value : '-';
+        },
         handleAccountMode(e) {
             this.budgetForm.budget = 1000;
             this.adBudgetShowTitle = false;
@@ -404,6 +464,7 @@ export default {
             }
             this.$refs.ruleForm.validate(valid => {
                 if (valid) {
+                    this.controlLoading = true;
                     this.handlePopoverChange(paramsData);
                 }
                 else {
@@ -447,6 +508,7 @@ export default {
             }
             this.$refs.budgetForm.validate(valid => {
                 if (valid) {
+                    this.controlLoading = true;
                     this.handlePopoverChange(paramsData);
                 }
                 else {
@@ -481,11 +543,16 @@ export default {
         },
         handleResetList() {
             this.acountId = '';
+            this.searchStatus = 0;
+            this.creativeStatus = 2;
+            this.controlLoading = true;
             this.handleInitTable();
         },
         handleInitTable() {
             const paramsData = {
                 accountId: this.acountId,
+                status: this.searchStatus === 2 ? '' : this.searchStatus,
+                creativeImageMode: this.creativeStatus === 2 ? '' : this.creativeStatus,
                 loginUserId: this.userInfo().id,
                 pageNo: this.tablePag.page,
                 pageSize: this.tablePag.size
@@ -493,12 +560,11 @@ export default {
             getAction(urlAcount + '/bytedance-api/advertiser/aiBytedanceAdvertiserStrategy/list', paramsData).then(result => {
                 if (result.code === 0) {
                     result.result.records.forEach(item => {
-                        item.show = false;
-                        item.visible = false;
                         if (item.accountBudgetMode === '1') {
                             item.accountBudget = '不限';
                         }
                     });
+                    this.controlLoading = false;
                     this.dataSource = result.result.records;
                     this.totalAll = result.result.total;
                 }
@@ -509,12 +575,28 @@ export default {
                 console.log(error, 'eeee');
             });
         },
+        handleCopy(data) {
+            let that = this;
+            this.$confirm({
+                title: '复制提示',
+                content: '请确认是否复制该账户配置',
+                onOk() {
+                    let params = {
+                        accountModal: 'copy',
+                        id: data.id
+                    };
+                    localStorage.setItem('queryList', JSON.stringify(params));
+                    that.$router.push('/account-config/components/configuration-copy');
+                }
+            });
+        },
         handleListDelete(data) {
             let that = this;
             this.$confirm({
                 title: '删除提示',
                 content: '是否删除该条数据',
                 onOk() {
+                    that.controlLoading = true;
                     deleteAction(urlAcount + '/bytedance-api/advertiser/aiBytedanceAdvertiserStrategy/delete', {id: data.id}).then(result => {
                         if (result.code === 0) {
                             that.handleInitTable();
@@ -529,14 +611,9 @@ export default {
                 }
             });
         },
-        handleBudgetPopover(record) {
-            record.show = false;
-        },
-        handleModPopover(record) {
-            record.visible = false;
-        },
         handleQueryList(event) {
             event.preventDefault();
+            this.controlLoading = true;
             this.handleInitTable();
         },
         onShowSizeChange(current, pageSize) {
@@ -544,18 +621,23 @@ export default {
                 page: current,
                 size: pageSize
             };
+            this.controlLoading = true;
             this.handleInitTable();
         },
         handleSwitchChang(checked, data) {
+            this.controlLoading = true;
             const paramsData = {
                 id: data.id,
                 state: checked ? 0 : 1,
-                accountId: data.accountId
+                creativeImageMode: this.creativeStatus === 2 ? '' : this.creativeStatus,
+                accountId: data.accountId,
+                creativeImageMode: data.creativeImageMode
             };
             const forDate = new FormData();
             forDate.append('id', paramsData.id);
             forDate.append('state', paramsData.state);
             forDate.append('accountId', paramsData.accountId);
+            forDate.append('creativeImageMode', paramsData.creativeImageMode);
             putAction(urlAcount + '/bytedance-api/advertiser/aiBytedanceAdvertiserStrategy/updStaById', forDate).then(result => {
                 if (result.code === 0) {
                     this.$message.success(result.message);

File diff suppressed because it is too large
+ 3256 - 0
src/views/modules/account-config/components/configuration-copy.vue


+ 74 - 13
src/views/modules/account-config/components/configuration-modal.less

@@ -81,24 +81,12 @@
                 margin-left: 40px !important;
             }
             .select-orientation-class {
-                // /deep/ .ant-select-selection--single .ant-select-selection__rendered {
-                //     display: flex;
-                //     justify-content: space-between;
-                // }
-                // /deep/ .ant-select-selection-selected-value {
-                //     clear: both;
-                //     width: 320px;
-                // }
                 .orient-list {
                     display: flex;
                     justify-content: space-between;
                     width: 240px;
                     .orient-option-left {
                         float: left;
-                        // width: 150px;
-                        // white-space: nowrap;
-                        // overflow: hidden;
-                        // text-overflow: ellipsis;
                     }
                     .orient-option-right {
                         float: right;
@@ -144,7 +132,7 @@
                 display: inline-block;
                 .ant-form-item-label {
                     width: 160px;
-                    margin-left: 73px;
+                    margin-left: 53px;
                 }
                 .ant-form-item-control-wrapper {
                     width: 110px;
@@ -234,6 +222,25 @@
             .adver-position-radio {
                 margin-left: 140px;
                 margin-bottom: 15px;
+                .create-web-url-class {
+                    width: 320px;
+                    height: 110px;
+                    background-color: #f9f8f8;
+                    display: flex;
+                    .web-url-img {
+                        width: 53px;
+                        img {
+                            width: 100%;
+                        }
+                    }
+                    .web-url-content {
+                        margin-top: 10px;
+                        margin-left: 10px;
+                        .url-content-id {
+                            margin-top: 10px;
+                        }
+                    }
+                }
                 .creative-label-content {
                     width: 400px;
                     height: 200px;
@@ -269,4 +276,58 @@
             }
         }
     }
+}
+.web-url-modal {
+    width: 1000px !important;
+    .mater-viedo-content {
+        .viedo-header-class {
+            display: flex;
+            justify-content: space-between;
+            border-bottom: 1px solid #eee;
+            .refush-btn-mat {
+                margin-left: 20px;
+            }
+        }
+        .viedo-serach-class {
+            margin-top: 20px;
+        }
+        .viedo-content-class {
+            .viedo-content-group {
+                display: flex;
+                flex-wrap: wrap;
+            }
+            .no-data-group {
+                height: 200px;
+                line-height: 200px;
+                text-align: center;
+            }
+            .content-modal-li {
+                border: 1px solid #e4e4e4;
+                width: 180px;
+                height: 425px;
+                text-align: center;
+                position: relative;
+                margin: 0 10px 10px 0;
+                .checkbox-select-show,
+                .checkbox-select-time {
+                    text-align: left;
+                    margin-top: 14px;
+                    padding-left: 10px;
+                    white-space: nowrap;
+                    overflow: hidden;
+                    text-overflow: ellipsis;
+                }
+                img {
+                    width: 90%;
+                    margin-top: 20px;
+                }
+                .viedo-content-checkbox {
+                    position: absolute;
+                    z-index: 100;
+                    left: 0;
+                    top: 0;
+                }
+            }
+        }
+    }
 }

File diff suppressed because it is too large
+ 1611 - 976
src/views/modules/account-config/components/configuration-modal.vue


+ 1 - 1
src/views/modules/account-config/components/directional-logic/directional-logic.less

@@ -1,7 +1,7 @@
 .directional-logic-content {
     .input-search {
         width: 240px;
-        margin: 10px 0 10px 0;
+        margin: 0 0 10px 0;
     }
     .tree-select-class {
         display: flex;

+ 18 - 16
src/views/modules/account-config/components/directional-logic/directional-logic.vue

@@ -4,7 +4,12 @@
             <div class="select-class-left">
                 <a-tabs v-model="selectPackageTabs" @change="handleTabsChange">
                     <a-tab-pane key="1" tab="定向池">
-                        <a-input-search class="input-search" v-model="directInput" placeholder="请输入人群包名称" @change="handleSearchPack($event, 'all', 'direct')" />
+                        <a-input-search
+                            class="input-search"
+                            v-model="directInput"
+                            placeholder="请输入人群包名称"
+                            @change="handleSearchPack($event, 'all', 'direct')"
+                        />
                         <a-table
                             :columns="columns"
                             :data-source="tableDataAllDirect"
@@ -18,7 +23,12 @@
                         </a-table>
                     </a-tab-pane>
                     <a-tab-pane key="2" tab="排除池">
-                        <a-input-search class="input-search" v-model="excludeInput" placeholder="请输入人群包名称" @change="handleSearchPack($event, 'all', 'exclude')" />
+                        <a-input-search
+                            class="input-search"
+                            v-model="excludeInput"
+                            placeholder="请输入人群包名称"
+                            @change="handleSearchPack($event, 'all', 'exclude')"
+                        />
                         <a-table
                             :columns="columns"
                             :data-source="tableDataAllExclude"
@@ -82,7 +92,12 @@
             </div>
         </div>
         <div v-else>
-            <a-input-search class="input-search" v-model="aloneInput" placeholder="请输入人群包名称" @change="handleSearchPack($event, 'alone')" />
+            <a-input-search
+                class="input-search"
+                v-model="aloneInput"
+                placeholder="请输入人群包名称"
+                @change="handleSearchPack($event, 'alone')"
+            />
             <div class="tree-select-class">
                 <div class="select-class-left">
                     <a-table
@@ -256,7 +271,6 @@ export default {
         rowSelectionAllDirect() {
             return {
                 onChange: (selectedRowKeys, selectedRows) => {
-                    console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
                     this.tableSelectDirectIds = selectedRows && selectedRows.map(item => item.key);
                     this.tableSelectDirectData = selectedRows;
                     this.$emit('selection-direct-event', this.tableSelectDirectIds);
@@ -274,7 +288,6 @@ export default {
         rowSelectionAllExclude() {
             return {
                 onChange: (selectedRowKeys, selectedRows) => {
-                    console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
                     this.tableSelectExcludeIds = selectedRows && selectedRows.map(item => item.key);
                     this.tableSelectExcludeData = selectedRows;
                     this.$emit('selection-exclude-event', this.tableSelectExcludeIds);
@@ -291,17 +304,6 @@ export default {
         }
     },
     watch: {
-        // updatelistinclude(newVal) {
-        //     if (newVal) {
-        //         console.log(newVal, '---00---000----000');
-        //         this.tableSelectDirectIds = newVal;
-        //     }
-        // },
-        // updatelistexclude(newVal) {
-        //     if (newVal) {
-        //         this.tableSelectExcludeIds = newVal;
-        //     }
-        // },
         defaultlist(newVal) {
             if (newVal) {
                 this.tableDataAllDirect = newVal;

+ 24 - 0
src/views/modules/account-config/components/tree-select/tree-select.vue

@@ -67,6 +67,30 @@ export default {
             changeCheckData: []
         };
     },
+    watch: {
+        editdata(newVal) {
+            if (newVal.length) {
+                this.checkedValue = [...newVal];
+                const rightSelectList = [];
+                this.updateTreeData.forEach(item => {
+                    if (newVal.includes(item.value)) {
+                        rightSelectList.push(item);
+                    }
+                });
+                this.applyTypeOption = rightSelectList;
+            }
+        },
+        defaultlist(newVal) {
+            if (newVal.length) {
+                this.changeCheckData = this.defaultlist;
+                this.updateTreeData = this.defaultlist;
+            }
+            else {
+                this.changeCheckData = [];
+                this.updateTreeData = [];
+            }
+        }
+    },
     mounted() {
         this.changeCheckData = this.defaultlist;
         this.updateTreeData = this.defaultlist;

+ 33 - 0
src/views/modules/advertiser/ProjectList.vue

@@ -152,6 +152,10 @@
           <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
             <a>删除</a>
           </a-popconfirm>
+          <!-- /ctop/project/edit -->
+        </span>
+        <span slot="materialShare" slot-scope="text, record">
+            <a-switch :checked='text==0' @change="onChange(text,record)" :loading="spinning"/>
         </span>
       </a-table>
     </div>
@@ -251,6 +255,14 @@ export default {
           },
         },
         {
+          title: '是否共享素材',
+          align: 'center',
+          dataIndex: 'materialShare',
+          scopedSlots: {
+            customRender: 'materialShare',
+          },
+        },
+        {
           title: '操作',
           dataIndex: 'action',
           align: 'center',
@@ -268,6 +280,7 @@ export default {
       },
       list: [],
       options: [],
+      spinning: false
     }
   },
   filters: {
@@ -313,6 +326,26 @@ export default {
     },
   },
   methods: {
+    onChange(text,record) {
+      this.spinning=true;
+      console.log(text,record)
+      let materialShare=text==1?0:1;
+      httpAction(`/ctop/project/edit`,{
+          id:record.id,
+          materialShare
+      },'put').then((res)=>{
+        
+        if(res.success) {
+          this.spinning=false;
+          this.$message.success('修改成功')
+          this.modalFormOk()
+        }else {
+          this.spinning=false;
+          this.$message.success(res.message)
+          this.modalFormOk()
+        }
+      })
+    },
     getList() {
       var params = {}
       // params.userId = this.userInfo().id

+ 131 - 42
src/views/modules/advertiser/ProjectMemberList.vue

@@ -17,7 +17,7 @@
     :bordered="false"
     :tabList="tabListNoTitle"
     :activeTabKey="noTitleKey"
-    @tabChange="key => onTabChange(key, 'noTitleKey')"
+    @tabChange="(key) => onTabChange(key, 'noTitleKey')"
     class="my-project"
   >
     <!-- 查询区域 -->
@@ -30,14 +30,9 @@
             </a-form-item>
           </a-col>
           <a-col :md="6" :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="searchQuery" icon="search">查询</a-button>
-              <a-button
-                type="primary"
-                @click="searchReset"
-                icon="reload"
-                style="margin-left: 8px"
-              >重置</a-button>
+              <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
             </span>
           </a-col>
         </a-row>
@@ -57,10 +52,9 @@
         :loading="loading"
       >
         <span slot="maxBid" slot-scope="maxBid">{{ maxBid / 1000 }}</span>
-        <span
-          slot="mediaId"
-          slot-scope="mediaId"
-        >{{ mediaId == 1 ? '头条' :mediaId == 2? '快手':mediaId == 3?'头条内广':'快手内广' }}</span>
+        <span slot="mediaId" slot-scope="mediaId">{{
+          mediaId == 1 ? '头条' : mediaId == 2 ? '快手' : mediaId == 3 ? '头条内广' : '快手内广'
+        }}</span>
         <span slot="action" slot-scope="text, record">
           <a @click="handleEdit(record)">{{ noTitleKey == 'myProject' ? '查看成员' : '账号绑定' }}</a>
           <a-divider type="vertical" />
@@ -70,8 +64,9 @@
             <a
               @click="projectLook(record)"
               v-if="noTitleKey == 'myProject'"
-              :disabled="record.needExamine == 0||record.needExamine == null"
-            >待办事项</a>
+              :disabled="record.needExamine == 0 || record.needExamine == null"
+              >待办事项</a
+            >
           </a-badge>
         </span>
       </a-table>
@@ -87,8 +82,8 @@
       width="800px"
       class="close-account-my-project"
     >
-      <div style="display:flex;line-height:50px;flex-wrap: wrap;">
-        <div style="width:25%;text-align:center;" v-for="(item, index) of memberList" :key="index">
+      <div style="display: flex; line-height: 50px; flex-wrap: wrap">
+        <div style="width: 25%; text-align: center" v-for="(item, index) of memberList" :key="index">
           <a-tag color="#2db7f5" @close="log(item.id)" closable>
             {{ item.userName }}
             <a-divider type="vertical" />
@@ -139,11 +134,12 @@
       title="账号绑定"
       v-model="visibleBind"
       @ok="handleSubmit"
+      @cancel="handleCancel"
       :width="800"
       :okButtonProps="{ props: { disabled: false } }"
       :cancelButtonProps="{ props: { disabled: false } }"
     >
-      <a-form :form="form">
+      <a-form :form="formEdit">
         <a-form-item
           label="选择方式"
           :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
@@ -154,7 +150,7 @@
             <a-radio-button value="login">登录</a-radio-button>
           </a-radio-group>
         </a-form-item>
-        <div v-if="mode=='authorization'">
+        <div v-if="mode == 'authorization'">
           <a-form-item
             label="媒体:"
             :label-col="{ xs: { span: 24 }, sm: { span: 5 } }"
@@ -165,7 +161,23 @@
               <a-radio-button value="bytedance">头条</a-radio-button>
             </a-radio-group>
             <br />
-            <span style="color:red;" v-if="loginType == 'bytedance'">*重要:如存在一户多开情况,请勾选所有子账号进行授权!!!</span>
+            <span style="color: red" v-if="loginType == 'bytedance'"
+              >*重要:如存在一户多开情况,请勾选所有子账号进行授权!!!</span
+            >
+          </a-form-item>
+          <a-form-item
+            label="授权时间:"
+            :label-col="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapper-col="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-date-picker 
+				v-model="dateValue"
+				style="width: 180px;"
+				:allowClear="false"
+				format="YYYY-MM-DD"
+				:disabled-date="disabledDate"
+				@change="handleCostTimeChange" 
+			/>
           </a-form-item>
           <a-form-item
             label="开户代理商:"
@@ -176,7 +188,9 @@
             <a-radio-group buttonStyle="outline" v-model="id">
               <!-- <a-radio-button value="0">否</a-radio-button>
               <a-radio-button value="1">是</a-radio-button> -->
-              <a-radio-button v-for="item in authConfigList" :key="item.id" :value='item.id'>{{item.agentName}}</a-radio-button>
+              <a-radio-button v-for="item in authConfigList" :key="item.id" :value="item.id">{{
+                item.agentName
+              }}</a-radio-button>
             </a-radio-group>
           </a-form-item>
           <a-form-item
@@ -199,11 +213,11 @@
           >
             <!-- <a-input v-decorator="['warningAmount', { rules: [{ required: true, message: '请输入预警金额' }] }]" /> -->
             <a-input-number
-              style="width:50%"
+              style="width: 50%"
               v-decorator="[
-              'warningAmount',
-              { rules: [{ required: true, message: '请输入预警金额' }], initialValue: 5000 }
-            ]"
+                'warningAmount',
+                { rules: [{ required: true, message: '请输入预警金额' }], initialValue: 5000 },
+              ]"
             />
           </a-form-item>
           <a-form-item
@@ -213,11 +227,11 @@
           >
             <a-input-number
               :step="0.1"
-              style="width:50%"
+              style="width: 50%"
               v-decorator="[
-              'warningProportion',
-              { rules: [{ required: true, message: '请输入预警比例' }], initialValue: 1.5 }
-            ]"
+                'warningProportion',
+                { rules: [{ required: true, message: '请输入预警比例' }], initialValue: 1.5 },
+              ]"
             />
           </a-form-item>
         </div>
@@ -248,6 +262,38 @@
             <a-input type="password" v-model="password" placeholder="请输入密码" />
           </a-form-item>
         </div>
+        <a-form-item
+          label="自动投放"
+          :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+          :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+        >
+          <a-radio-group
+            buttonStyle="outline"
+            v-decorator="[
+              'autoDelivery',
+              { rules: [{ required: true, message: '请选择是否自动投放' }], initialValue: 1 },
+            ]"
+          >
+            <a-radio-button :value="1">允许</a-radio-button>
+            <a-radio-button :value="3">禁止</a-radio-button>
+          </a-radio-group>
+        </a-form-item>
+        <a-form-item
+          label="物料同步"
+          :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+          :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+        >
+          <checkBoxGroup
+                :options="[
+                  { label: '不同步', value: 0 },
+                  { label: '应用包', value: 1 },
+                  { label: '人群包', value: 2, disabled:true},
+                  { label: '定向包', value: 3, disabled:true },
+                ]"
+                v-decorator="['materialType', { rules: [{ required: true, message: '请选择同步物料' }], initialValue: [0] }]"
+                @change="changeData"
+              />
+        </a-form-item>
       </a-form>
     </a-modal>
 
@@ -305,6 +351,7 @@
 </template>
 
 <script>
+import moment from 'moment';
 import { httpAction, getAction, deleteAction, putAction } from '@/api/manage'
 
 import { mapGetters } from 'vuex'
@@ -312,7 +359,7 @@ import { mapGetters } from 'vuex'
 import JSelectUserByDep from '@/components/jeecgbiz/JSelectUserByDep'
 
 import { JeecgListMixin } from '@/mixins/ipagination'
-
+import checkBoxGroup from '@/components/formComponents/checkBoxGroup'
 const myProjectColumns = [
   {
     title: '项目名称',
@@ -420,10 +467,13 @@ export default {
   name: 'ProjectMemberList',
   components: {
     JSelectUserByDep,
+    checkBoxGroup
   },
   mixins: [JeecgListMixin],
   data() {
     return {
+      moment,
+      dateValue: '',
       authConfigList:[],
       title: '',
       titleAccount: '',
@@ -437,7 +487,7 @@ export default {
       password: '',
       loginType: 'kuaishou',
       id: undefined,
-      form: this.$form.createForm(this),
+      formEdit: this.$form.createForm(this),
       record: '',
       systemType: '不限',
       systemTypeName: '',
@@ -605,7 +655,38 @@ export default {
     },
   },
   methods: {
+    changeData(data) {
+      if (data.length > 1 && data.findIndex((item) => item == 1) == 0) {
+        data.splice(
+          data.findIndex((item) => item == 1),
+          1
+        )
+      } else if (data.length > 1 && data.findIndex((item) => item == 1) == data.length - 1) {
+        data.splice(0, data.length - 1)
+      } else if (data.length == 0) {
+        data.push(1)
+      }
+    },
+    getFormFieldValue(field) {
+      return this.formEdit.getFieldValue(field)
+    },
     //   /ctop/userAllocation/getAccountsByProjectId    projectId  userId
+	handleCostTimeChange(date, dateString) {
+		console.log(dateString, 'dateString');
+		this.dateValue = dateString;
+	},
+	disabledDate(current) {
+		if (this.loginType == 'kuaishou') {
+			return current && !(current > moment().subtract(7, 'days'));
+		}
+		else if (this.loginType == 'bytedance') {
+			return false;
+		}
+		// TODO 时间限制格式
+		// return current && !(current > moment().subtract(7, 'days'));
+		// return current && !(current > (moment().subtract(7, 'days')) && current < moment());
+		// return false;
+	},
     projectLook(item) {
       var params = {}
       params.projectId = item.id
@@ -796,6 +877,10 @@ export default {
         this.systemType = '不限'
       }
     },
+    handleCancel() {
+      this.visibleBind = false
+      this.formEdit.resetFields();
+    },
     handleSubmit() {
       let params = {}
       params.advertiserId = this.record.advertiserId
@@ -805,10 +890,13 @@ export default {
       params.projectId = this.record.projectId
       params.projectName = this.record.projectName
       params.systemType = this.systemType == '4' ? this.systemTypeName : this.systemType
+	    params.authBeginTime = this.dateValue;
       
       // 触发表单验证
-      this.form.validateFields((err, values) => {
+      this.formEdit.validateFields((err, values) => {
         if (!err) {
+          params.materialType = values.materialType
+          params.autoDelivery = values.autoDelivery
           if (this.mode == 'login') {
             params.accountName = this.accountName
             params.password = this.password
@@ -836,10 +924,12 @@ export default {
             }
             params.warningAmount = values.warningAmount
             params.warningProportion = values.warningProportion
+
             httpAction(this.bindAuthorizationUrl, params, 'post').then((res) => {
               if (res.success) {
                 window.open(res.message, '_blank')
                 this.visibleBind = false
+                this.formEdit.resetFields();
               } else {
                 alert('绑定失败')
               }
@@ -859,7 +949,7 @@ export default {
       }
     },
     searchQuery() {
-      this.ipagination.current=1
+      this.ipagination.current = 1
       if (this.noTitleKey == 'participation') {
         this.getParticipateList()
       } else {
@@ -891,19 +981,18 @@ export default {
         this.getAllUserList()
       }
     },
-    getauthConfigList(){
-      getAction('/auth/oauthConfig/list',{
-        status:0,
-        mediaId:2
-      }).then(res=>{
+    getauthConfigList() {
+      getAction('/auth/oauthConfig/list', {
+        status: 0,
+        mediaId: 2,
+      }).then((res) => {
         console.log(res)
-        this.authConfigList=res.result;
-        if(res.result.length>0){
-          this.id=res.result[0].id
+        this.authConfigList = res.result
+        if (res.result.length > 0) {
+          this.id = res.result[0].id
         }
-        
       })
-    }
+    },
   },
   mounted() {
     this.$nextTick(() => {

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

@@ -278,7 +278,7 @@ export default {
     },
     getSupplierList() {
       var params = {}
-      getAction('/ctop/supplierList/list').then((res) => {
+      getAction('/ctop/supplierList/list',{pageNo:1,pageSize:100}).then((res) => {
         if (res.success) {
           this.supplierList = res.result.records
         } else {

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

@@ -183,7 +183,7 @@
       },
       getSupplierList() {
         var params = {}
-        getAction('/ctop/supplierList/list').then(res => {
+        getAction('/ctop/supplierList/list',{pageNo:1,pageSize:100}).then(res => {
           if (res.success) {
             this.supplierList = res.result.records
           } else {

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

@@ -289,7 +289,7 @@ export default {
     },
     getSupplierList() {
       var params = {}
-      getAction('/ctop/supplierList/list').then((res) => {
+      getAction('/ctop/supplierList/list',{pageNo:1,pageSize:100}).then((res) => {
         if (res.success) {
           this.supplierList = res.result.records
         } else {

+ 222 - 0
src/views/modules/autoLaunch/application/application-service.js

@@ -0,0 +1,222 @@
+/**
+ * @file 人群包管理基础服务
+ * @author jiayufei(jiayufei@c-top.com.cn)
+ */
+
+ class AppMarketService {
+    constructor() {}
+
+    // 相关账户的table列表
+    setAcountColumns() {
+        return [
+            {
+                title: '账户名称',
+                dataIndex: 'authName',
+                width: '50%',
+                align: 'center'
+            },
+           
+            {
+                title: '应用数量',
+                dataIndex: 'appCount',
+                width: '50%',
+                align: 'center'
+            },
+        ]
+            
+    }
+
+    // 原因的table列表
+    setCauseColumns() {
+        return [
+            {
+                title: '账户名称',
+                dataIndex: 'authName',
+                width: '25%',
+                align: 'center'
+            },
+            {
+                title: '推送结果',
+                dataIndex: 'result',
+                width: '25%',
+                align: 'center'
+            },
+            {
+                title: '失败原因',
+                dataIndex: 'message',
+                width: '25%',
+                align: 'center',
+                customRender(t) {
+                    if(t === 'OK') {
+                        return '-';
+                    }
+                    else {
+                        return t;
+                    }
+                }
+            },
+            {
+                title: '操作',
+                dataIndex: 'action',
+                scopedSlots: {customRender: 'action'},
+                width: '25%',
+                align: 'center'
+            }
+        ]
+    }
+
+    // 相关项目的table列表
+    setDepColumns() {
+        return [
+            {
+                title: '广告组名称',
+                dataIndex: 'unitName',
+                width: '50%',
+                align: 'center'
+            },
+            {
+                title: '所属账户',
+                dataIndex: 'authName',
+                width: '50%',
+                align: 'center'
+            }
+        ]
+    }
+
+    // 状态枚举
+    setPlatform() {
+        return [
+            {
+                label: '',
+                value: '不限'
+            },
+            {
+                label: 1,
+                value: 'Android 应用下载'
+            },
+            {
+                label: 2,
+                value: 'Android 网页游戏'
+            },
+            {
+                label: 3,
+                value: 'iOS 应用下载'
+            },
+            {
+                label: 4,
+                value: 'iOS 网页游戏'
+            }
+        ]
+    }
+
+    // 上传人去报的校验规则
+    setPersonRules() {
+        return {
+            name: [
+                {required: true, message: '人群包名称不能为空', trigger: 'blur'},
+                {min: 1, max: 20, message: '人群包名称不能超过20个字符', trigger: 'blur'}
+            ],
+            resource: [
+                {required: true, message: '请选择匹配类型', trigger: 'change'}
+            ]
+        }
+    }
+
+    // 人群包类型枚举值
+    setPopulationTypeTasks() {
+        return [
+            {
+                label: 1,
+                value: '上传人群'
+            }, {
+                label: 2,
+                value: '广告人群'
+            }, {
+                label: 3,
+                value: '主题专区'
+            }, {
+                label: 4,
+                value: '逻辑规则'
+            }, {
+                label: 5,
+                value: '人群扩展'
+            }, {
+                label: 6,
+                value: '平台制定'
+            }, {
+                label: 7,
+                value: '定制付费'
+            }, {
+                label: 8,
+                value: '网红粉丝类别'
+            }, {
+                label: 9,
+                value: '内容付费行为'
+            }, {
+                label: 10,
+                value: '移动应用安装'
+            }, {
+                label: 11,
+                value: '快手使用活跃度'
+            }, {
+                label: 12,
+                value: '行业分类'
+            }, {
+                label: 13,
+                value: '商业兴趣'
+            }, {
+                label: 14,
+                value: '固话标签'
+            }, {
+                label: 15,
+                value: '行业偏好'
+            }, {
+                label: 16,
+                value: '第三方标签'
+            }, {
+                label: 17,
+                value: '产品关键词'
+            }, {
+                label: 19,
+                value: '应用渗透率'
+            }, {
+                label: 22,
+                value: '指定网红'
+            }, {
+                label: 23,
+                value: '行业分类'
+            }
+        ]
+    }
+
+    // 匹配类型枚举值
+    setMateTypeTasks() {
+        return [
+            {
+                label: 1,
+                value: 'IMEI'
+            }, {
+                label: 2,
+                value: 'IDFA'
+            }, {
+                label: 3,
+                value: 'IMEI_MD5'
+            }, {
+                label: 4,
+                value: 'IDFA_MD5'
+            }, {
+                label: 5,
+                value: '手机号-MD5'
+            }, {
+                label: 7,
+                value: 'OAID'
+            }, {
+                label: 8,
+                value: 'OAID_MD5'
+            }
+        ]
+    }
+
+}
+
+export default new AppMarketService();

+ 8 - 3
src/views/modules/autoLaunch/application/directional.less

@@ -1,8 +1,11 @@
 .directional-content {
     background: #fff;
-    height: calc(100vh - 137px);
+    // height: calc(100vh - 137px);
     padding: 20px;
     overflow-y: auto;
+    .middle-button {
+        margin: 0 8px;
+    }
     .control-con-header {
         margin-bottom: 20px;
         position: relative;
@@ -92,8 +95,10 @@
         height: 40px;
         line-height: 40px;
         .acount-title-left {
-            margin-right: 20px;
-            width: 100px;
+            width: 80px;
+        }
+        .acount-title-left::after {
+            content: " : ";
         }
     }
     .push-plate {

File diff suppressed because it is too large
+ 831 - 374
src/views/modules/autoLaunch/application/application.vue


+ 652 - 0
src/views/modules/autoLaunch/application/components/creatApplication.vue

@@ -0,0 +1,652 @@
+<style lang="less" scoped>
+.require-class {
+  /deep/ .ant-form-item-label {
+    label::before {
+      display: inline-block;
+      margin-right: 4px;
+      color: #f5222d;
+      font-size: 14px;
+      font-family: SimSun, sans-serif;
+      line-height: 1;
+      content: '*';
+    }
+  }
+}
+</style>
+<template>
+  <div>
+    <a-modal
+      title="添加应用"
+      :visible="application"
+      @ok="handleOk"
+      :confirmLoading="confirmLoading"
+      @cancel="handleCancel"
+      width="800px"
+    >
+      <a-card :body-style="{ padding: '24px 32px' }" :bordered="false">
+        <a-form :form="form">
+          <selectTable :projectId.sync="projectId" ref="selectTable" :requireCheck="true"></selectTable>
+          <a-form-item
+            label="设备类型"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-radio-group v-model="appType" @change="changePlatform">
+              <a-radio-button value="android">安卓</a-radio-button>
+              <a-radio-button value="ios">IOS</a-radio-button>
+            </a-radio-group>
+          </a-form-item>
+          <!-- <a-form-item v-if="appType == 'android'"> -->
+          <a-form-item
+            label="推广类型"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-radio-group v-model="platform" @change="changeShowUploadType">
+              <a-radio value="1">应用下载</a-radio>
+              <a-radio value="2">网页游戏</a-radio>
+            </a-radio-group>
+          </a-form-item>
+
+          <a-form-item
+            label="上传应用"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-radio-group v-model="uploadType" @change="changeShowUpload">
+              <a-radio-button value="1">本地上传</a-radio-button>
+              <a-radio-button value="2">填写链接</a-radio-button>
+            </a-radio-group>
+          </a-form-item>
+
+          <a-form-item
+            v-if="uploadType == '2'"
+            label="下载链接"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-input
+              placeholder="请填写应用下载链接"
+              v-decorator="[
+                'url',
+                {
+                  rules: [{ required: true, validator: handleConfirmValue }],
+                },
+              ]"
+            />
+          </a-form-item>
+
+          <a-form-item
+            label="应用包名"
+            v-if="uploadType == '2' && appType == 'android'"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-input
+              v-decorator="[
+                'packageName',
+                {
+                  rules: [{ required: true, message: '请填写正确的应用包名称' }],
+                },
+              ]"
+              placeholder="请填写包名称,如com.smile.gifmaker"
+            />
+          </a-form-item>
+
+          <a-form-item
+            label="应用名称"
+            v-if="uploadType == '2'"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-input
+              v-decorator="[
+                'appName',
+                {
+                  rules: [{ required: true, message: '请填写应用名称' }],
+                },
+              ]"
+              placeholder="请填写应用名称"
+            />
+          </a-form-item>
+
+          <a-form-item
+            label="上传图标"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 19 } }"
+            v-if="application"
+            class="require-class"
+          >
+            <uploadFile
+              v-if="application"
+              :value.sync="fileUrl"
+              :multiple="false"
+              :fileCount="1"
+              uploadType="image"
+              @overUpload="overUpload"
+              :size="100"
+            ></uploadFile>
+            <p class="upload-txt-rules">文件格式:支持上传png/jpg/jpeg图片,尺寸450*450,小于100kb</p>
+          </a-form-item>
+          <a-form-item
+            label="上传文件"
+            v-if="uploadType == '1'"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+            class="require-class fileUpload"
+            id="fileUpload"
+          >
+            <!-- <a-upload name="file" :file-list="fileList" :before-upload="beforeUpload" @change="handleChange">
+              <a-button><a-icon type="upload" />文件上传</a-button>
+            </a-upload> -->
+            <!-- :action="uploadAction" -->
+            <a-upload
+              name="file"
+              :multiple="false"
+              :headers="tokenHeader"
+              :file-list="fileList"
+              :showUploadList="false"
+              :beforeUpload="beforeUpload"
+              @change="handleChange"
+              style="margin-right: 20px"
+            >
+              <a-button :disabled="fileUrl == '' && !projectId">
+                <a-icon type="upload" />
+                {{ loadDisabled ? '上传中,请稍后' : '文件上传' }}
+              </a-button>
+            </a-upload>
+            <a @click="downLoadFile">文件格式下载</a>
+          </a-form-item>
+          <a-form-item
+            label="应用标记"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+            v-if="uploadType == '2'"
+          >
+            <a-input
+              v-decorator="[
+                'appVersion',
+                {
+                  rules: [{ required: true, message: ' ' }, { validator: checkAppVersion }],
+                },
+              ]"
+              placeholder="请填写应用标记,必填且不可重复,如快手-5.6.1.66"
+            />
+          </a-form-item>
+          <!-- <a-form-item>
+            <a-form-item :wrapperCol="{ span: 24 }" style="text-align: center">
+              <a-button htmlType="submit" type="primary">提交</a-button>
+              <a-button style="margin-left: 8px">保存</a-button>
+            </a-form-item>
+          </a-form-item> -->
+          <a-form-item
+            label=""
+            :labelCol="{ span: 5 }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 }, offset: 5 }"
+            v-if="uploadType == '2' && appType == 'android'"
+          >
+            <!-- <a-radio-group
+              v-decorator="[
+                'useSdk',
+                {
+                  rules: [{ required: true }],
+                  initialValue: '0',
+                },
+              ]"
+            >
+              <a-radio value="0">未接入</a-radio>
+              <a-radio value="1">已接入</a-radio>
+            </a-radio-group> -->
+            <a-checkbox-group
+              v-decorator="[
+                'useSdk',
+                {
+                  rules: [{ message: '安卓应用已接入快手广告监测SDK必选' }],
+                },
+              ]"
+            >
+              <a-checkbox :value="0"> 该应用已接入快手广告监测SDK </a-checkbox>
+            </a-checkbox-group>
+          </a-form-item>
+          <a-form-item
+            label="隐私政策链接"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+            v-if="uploadType == '2' && appType == 'android'"
+          >
+            <a-input
+              v-decorator="[
+                'appPrivacyUrl',
+                {
+                  rules: [{ required: true, message: '请填写隐私政策链接' }, { validator: handleConfirmValue }],
+                },
+              ]"
+              placeholder="请填写隐私政策链接"
+            />
+          </a-form-item>
+
+          <a-form-item
+            label="监测链接"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+            v-if="uploadType == '2' && appType == 'android'"
+          >
+            <a-input v-decorator="['trackUrl']" placeholder="请填写监测链接" />
+          </a-form-item>
+        </a-form>
+      </a-card>
+    </a-modal>
+  </div>
+</template>
+
+<script>
+import Vue from 'vue'
+import { ACCESS_TOKEN } from '@/store/mutation-types'
+import { deleteAction, postAction, getAction, downFilePost, downFile } from '@/api/manage'
+import uploadFile from './uploadFile.vue'
+import { mapActions, mapGetters } from 'vuex'
+import BMF from 'browser-md5-file'
+import selectTable from '@/views/modules/Statistics/components/selectPagination.vue'
+import $ from 'jquery'
+const fileSuffix = ['xlsx', 'xls', 'zip']
+export default {
+  name: 'BaseForm',
+  components: {
+    uploadFile,
+    selectTable,
+  },
+  data() {
+    return {
+      useSdk: [],
+      loadDisabled: false,
+      projectId: '',
+      accountId: '',
+      fileList: [],
+      fileUrl: '',
+      accountList: {},
+      appType: 'android', //设备类型
+      platform: '1', //应用类型   : 1 Android 应用下载,2: Android 网页游戏,3: iOS 应用下载, 4:iOS 网页游戏
+      uploadType: '1', //上传类型 1 本地上传 2 填写链接
+      appVersion: '', //应用标记
+      appName: '', // 应用名称
+      packageName: '', //应用包名
+      file: '', // 上传文件
+      imageUrl: '', // 上传图标链接链接
+      downloadUrl: '', //下载链接
+      showUploadFile: true,
+      showDownLoad: false,
+      showUpload: true,
+      showAndroid: true,
+      showIOS: false,
+      customDomain: '',
+      acceptVideo: '/*.apk,/*.png,/*.jpg,/*.jpeg,/*.mp4',
+      accessKeyId: 'LTAIbNbqWzSOklQV',
+      accessKeySecret: '1rkPz7JNoXk8sJevPaeYHWqfkQXBGh',
+      region: 'oss-cn-beijing',
+      bucket: 'ctop-media',
+      form: this.$form.createForm(this),
+      url: {
+        insertTemplateUrl: '/kuaishouAppPackage/fillInLink',
+        userAllocationList: '/ctop/userAllocation/list',
+      },
+      application: false,
+      confirmLoading: false,
+      imageToken: '',
+      // uploadAction: '/kuaishouAppPackage/importAppExcel',
+      tokenHeader: { 'X-Access-Token': Vue.ls.get(ACCESS_TOKEN) },
+      okCreated: false,
+      dataFile: null,
+    }
+  },
+  methods: {
+    checkAppVersion(rule, value, callback) {
+      if (value != '') {
+        if (this.projectId) {
+          let params = {}
+          params.projectId = this.projectId
+          params.appVersion = value
+          getAction('/kuaishouAppPackage/checkAppVersion', params).then((res) => {
+            if (res.success) {
+              callback()
+            } else {
+              callback(res.message)
+            }
+          })
+        }
+      } else {
+        callback('应用标记必填')
+      }
+    },
+    overUpload(file) {},
+    downLoadFile() {
+      downFile('/kuaishouAppPackage/exportAppTemplate').then((res) => {
+        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 = '应用模板' //下载后文件名
+        document.body.appendChild(downloadElement)
+        downloadElement.click() //点击下载
+        document.body.removeChild(downloadElement) //下载完成移除元素
+        window.URL.revokeObjectURL(href) //释放掉blob对象
+      })
+    },
+    handleChange(info) {
+      // let fileList = [...info.fileList]
+
+      // // 1. Limit the number of uploaded files
+      // //    Only to show two recent uploaded files, and old ones will be replaced by the new
+      // fileList = fileList.slice(-2)
+
+      // // 2. read from response and show file link
+      // fileList = fileList.map((file) => {
+      //   if (file.response) {
+      //     // Component will show file.url as link
+      //     file.url = file.response.url
+      //   }
+      //   return file
+      // })
+      // if (fileList.length > 0) {
+      //   this.fileList = [
+      //     {
+      //       ...fileList[fileList.length - 1],
+      //     },
+      //   ]
+      // } else {
+      //   this.fileList = []
+      // }
+      this.loadDisabled = false
+      this.$message.success('文件导入成功')
+      // if (info.file.status !== 'uploading') {
+      //   console.log(info.file, info.fileList)
+      // }
+      // if (info.file.status === 'done') {
+      //   this.loadDisabled = false
+      //   if (info.file.response.code == 200) {
+      //     // this.application = true
+      //     // this.$emit('getDataList')
+      //     this.okCreated = true
+      //     this.$message.success(info.file.response.message)
+      //   } else {
+      //     this.okCreated = false
+      //     this.$message.error(info.file.response.message)
+      //   }
+      // } else if (info.file.status === 'error') {
+      //   this.$message.error(`${info.file.name}上传失败`)
+      //   this.loadDisabled = false
+      // }
+
+      // console.log(this.form)
+    },
+    beforeUpload(file) {
+      // this.cosUpload(file)
+      // if (process.env.NODE_ENV == 'development') {
+      //   this.uploadAction = `/jeecg-boot/kuaishouAppPackage/importAppExcel?projectId=${this.projectId}&platform=${
+      //     this.appType == 'ios' ? +this.platform + 2 : +this.platform
+      //   }&imageUrl=${this.fileUrl}`
+      // } else if (process.env.NODE_ENV == 'debug') {
+      // } else if (process.env.NODE_ENV == 'production') {
+      //   this.uploadAction = `${this.axios.defaults.baseURL}/kuaishouAppPackage/importAppExcel?projectId=${
+      //     this.projectId
+      //   }&platform=${this.appType == 'ios' ? +this.platform + 2 : +this.platform}&imageUrl=${this.fileUrl}`
+      // }
+      // this.dataFile = file
+      this.dataFile = $('.fileUpload').eq(0).find('input')[0].files[0]
+      this.loadDisabled = true
+      const size = (Number(file.size) / (1024 * 1024)).toFixed(2)
+      const fileName = file.name
+      const fileStrArr = fileName.split('.')
+      const suffix = fileStrArr[fileStrArr.length - 1]
+
+      let result = fileSuffix.some((item) => {
+        return item === suffix
+      })
+
+      if (!result) {
+        this.$message.error('不支持该文件类型')
+        this.loadDisabled = false
+        return false
+      }
+    },
+    cosUpload(file) {
+      let 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
+      let timeElse = new Date().getTime()
+      let arr = file.name.split('.')
+      let 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] + '.'
+          }
+        }
+      }
+      cos.putObject(
+        {
+          Bucket: 'media-1301855440',
+          Region: 'ap-chongqing',
+          // 存储桶所在地域,必须字段
+          Key: that.appType + '/' + y + '-' + MM + '-' + d + '/' + str + '-' + timeElse + '.' + arr[arr.length - 1],
+          StorageClass: 'STANDARD',
+          Body: file, // 上传文件对象
+        },
+        function (err, data) {
+          if (err) {
+            that.$message.error('上传失败!!!' + err)
+            return
+          }
+          that.loadingElse = false
+          that.fileList.push({
+            uid: file.name,
+            name: file.name,
+            status: 'done',
+            url: '//' + data.Location,
+          })
+          if (that.fileList.length > 1) {
+            that.fileList = that.fileList.slice(-1)
+          }
+          const isZip = file.type.includes('zip') || file.type.includes('text')
+          const fileOvesize = file.size > 1024 * 1024 * 1024
+          if (!isZip) {
+            that.$message.error('只能上传zip格式的文件或者txt文件')
+            return
+          }
+          if (fileOvesize) {
+            that.$message.error('文件大小不能超过1G')
+            return
+          }
+          that.handleMd5(file)
+        }
+      )
+    },
+    handleMd5(file) {
+      let bmf = new BMF()
+      let that = this
+      return new Promise(function (resolve, reject) {
+        bmf.md5(file, (err, md5) => {
+          // getAction('kuaishouPopulationPackage/checkPopulationPackage', { signature: md5 })
+          //   .then((result) => {
+          //     if (result.code === 200) {
+          that.personNameDisabled = false
+          that.personResourceDisabled = false
+          resolve()
+          //   } else if (result.code === 201) {
+          //     that.$message.error(result.message)
+          //     that.personForm.name = result.result.orientationName
+          //     that.personForm.resource = result.result.type
+          //     that.personNameDisabled = true
+          //     that.personResourceDisabled = true
+          //     reject()
+          //   }
+          // })
+          // .catch((error) => {
+          //   console.log(error, 'eeee')
+          //   reject()
+          // })
+        })
+      })
+    },
+    handleOk() {
+      this.handleSubmit()
+    },
+    handleCancel() {
+      this.dataFile = null
+      this.appType = 'android'
+      this.okCreated = false
+      this.form.resetFields()
+      this.fileUrl = ''
+      this.projectId = undefined
+      this.$refs.selectTable.keyValue = ''
+      this.$refs.selectTable.getData()
+      this.file = ''
+      this.platform = '1'
+      this.application = false
+      this.uploadType = '1'
+    },
+    showApplication() {
+      this.application = true
+    },
+    handleConfirmValue(rule, value, callback) {
+      if (/(http|https):\/\/([\w.]+\/?)\S*/.test(value) && value != '') {
+        callback()
+      } else {
+        callback('链接不能为空且开头为http://或https://')
+      }
+    },
+    ...mapGetters(['nickname', 'avatar', 'userInfo']),
+    changePlatform() {
+      this.form.resetFields()
+      if (this.appType == 'android') {
+        this.showAndroid = true
+        this.showIOS = false
+        this.platform = '1'
+      } else {
+        this.showAndroid = false
+        this.showIOS = true
+        this.showDownLoad = true
+        this.platform = '1'
+      }
+    },
+    changeShowUpload() {
+      this.form.resetFields()
+      this.fileUrl = ''
+    },
+    changeShowUploadType() {
+      this.form.resetFields()
+      if (this.platform == '2') {
+        this.showUpload = false
+        this.showUploadFile = false
+        this.showDownLoad = true
+        this.uploadType = '1'
+      } else {
+        this.showUpload = true
+        this.showUploadFile = true
+        this.showDownLoad = false
+      }
+    },
+
+    handleSubmit() {
+      //   console.log('设备类型:' + this.appType)
+      //   console.log('应用类型:' + this.platform)
+      //   console.log('上传类型:' + this.uploadType)
+      //   console.log('应用标记:' + this.appVersion)
+      //   console.log('应用名称:' + this.appName)
+      //   console.log('包名称:' + this.packageName)
+      //   console.log('文件地址:' + this.file)
+      //   console.log('图片地址:' + this.imageUrl)
+      //   e.preventDefault()
+
+      this.form.validateFields((err, values) => {
+        if (!err) {
+          if (this.fileUrl && this.projectId) {
+            this.confirmLoading = true
+            let params = {}
+            params.projectId = this.projectId
+            if (this.uploadType == '1') {
+              // var file = document.getElementById('fileId').files[0] //获取文件流
+              this.url.insertTemplateUrl = '/kuaishouAppPackage/importAppExcel'
+              params.platform = this.appType == 'ios' ? +this.platform + 2 : +this.platform
+              params.imageUrl = this.fileUrl
+              if (this.dataFile) {
+                let formData = new FormData()
+                formData.append('file', this.dataFile)
+                formData.append('projectId', this.projectId)
+                formData.append('platform', this.appType == 'ios' ? +this.platform + 2 : +this.platform)
+                formData.append('imageUrl', this.fileUrl)
+                // if (process.env.NODE_ENV == 'development') {
+                //   this.uploadAction = `/jeecg-boot/kuaishouAppPackage/importAppExcel?projectId=${
+                //     this.projectId
+                //   }&platform=${this.appType == 'ios' ? +this.platform + 2 : +this.platform}&imageUrl=${this.fileUrl}`
+                // } else if (process.env.NODE_ENV == 'debug') {
+                // } else if (process.env.NODE_ENV == 'production') {
+                //   this.uploadAction = `${this.axios.defaults.baseURL}/kuaishouAppPackage/importAppExcel?projectId=${
+                //     this.projectId
+                //   }&platform=${this.appType == 'ios' ? +this.platform + 2 : +this.platform}&imageUrl=${this.fileUrl}`
+                // }
+
+                postAction('/kuaishouAppPackage/importAppExcel', formData).then((res) => {
+                  this.confirmLoading = false
+                  if (res.code === 200) {
+                    this.$message.success('创建成功')
+                    this.handleCancel()
+                    this.$emit('getDataList')
+                  } else {
+                    this.$message.error(res.message)
+                  }
+                })
+              } else {
+                this.$message.error('请上传文件')
+              }
+
+              return
+            } else {
+              this.url.insertTemplateUrl = '/kuaishouAppPackage/fillInLink'
+              params = { ...values }
+              params.useSdk = params.useSdk ? (params.useSdk.length > 0 ? 1 : 0) : null
+              params.projectId = this.projectId
+              params.appIconUrl = this.fileUrl
+              params.platform = this.appType == 'ios' ? +this.platform + 2 : +this.platform
+            }
+
+            postAction(this.url.insertTemplateUrl, params).then((res) => {
+              this.confirmLoading = false
+              if (res.success) {
+                this.$message.success('创建成功')
+                this.handleCancel()
+                this.$emit('getDataList')
+              } else {
+                this.$message.error(res.message)
+              }
+            })
+          } else {
+            this.$message.error('请填写必填项')
+          }
+        }
+      })
+    },
+
+    onChange(value) {},
+  },
+  created: function () {
+    let params = {}
+    params.pageSize = '1000'
+    params.mediaId = '2'
+    params.userId = this.userInfo().id
+    getAction(this.url.userAllocationList, params).then((res) => {
+      if (res.success) {
+        this.accountList = res.result.records
+      }
+    })
+  },
+}
+</script>

+ 603 - 0
src/views/modules/autoLaunch/application/components/editApplication.vue

@@ -0,0 +1,603 @@
+<template>
+  <div>
+    <a-modal
+      title="编辑应用"
+      :visible="application"
+      @ok="handleOk"
+      :confirmLoading="confirmLoading"
+      @cancel="handleCancel"
+      width="800px"
+    >
+      <a-card :body-style="{ padding: '24px 32px' }" :bordered="false">
+        <a-form :form="form">
+          <!-- <selectTable :projectId.sync="projectId" ref="selectTable" :requireCheck="true"></selectTable> -->
+          <a-form-item
+            label="项目名称"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-input
+              disabled
+              v-decorator="[
+                'projectName',
+                {
+                  rules: [{ required: true }],
+                },
+              ]"
+            />
+          </a-form-item>
+          <a-form-item
+            label="设备类型"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-radio-group v-model="appType" @change="changePlatform" disabled>
+              <a-radio-button value="android">安卓</a-radio-button>
+              <a-radio-button value="ios">IOS</a-radio-button>
+            </a-radio-group>
+          </a-form-item>
+          <!-- <a-form-item v-if="appType == 'android'"> -->
+          <a-form-item
+            label="推广类型"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-radio-group v-model="platform" disabled>
+              <a-radio value="1">应用下载</a-radio>
+              <a-radio value="2">网页游戏</a-radio>
+            </a-radio-group>
+          </a-form-item>
+
+          <a-form-item
+            label="上传应用"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-radio-group v-model="uploadType">
+              <a-radio-button value="1" disabled>本地上传</a-radio-button>
+              <a-radio-button value="2">填写链接</a-radio-button>
+            </a-radio-group>
+          </a-form-item>
+
+          <a-form-item
+            label="上传文件"
+            v-if="uploadType == '1'"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <!-- <a-upload name="file" :file-list="fileList" :before-upload="beforeUpload" @change="handleChange">
+              <a-button><a-icon type="upload" />文件上传</a-button>
+            </a-upload> -->
+            <a-upload
+              name="file"
+              :multiple="false"
+              :action="uploadAction"
+              :headers="tokenHeader"
+              :file-list="fileList"
+              :showUploadList="false"
+              :beforeUpload="beforeUpload"
+              @change="handleChange"
+              style="margin-right: 20px"
+            >
+              <a-button :disabled="(!projectId && !fileUrl) || loadDisabled">
+                <a-icon type="upload" />
+                {{ loadDisabled ? '上传中,请稍后' : '文件上传' }}
+              </a-button>
+            </a-upload>
+            <a @click="downLoadFile">文件格式下载</a>
+          </a-form-item>
+
+          <a-form-item
+            v-if="uploadType == '2'"
+            label="下载链接"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-input
+              placeholder="请填写应用下载链接"
+              v-decorator="[
+                'url',
+                {
+                  rules: [{ required: true, validator: handleConfirmValue }],
+                },
+              ]"
+            />
+          </a-form-item>
+
+          <a-form-item
+            label="应用包名"
+            v-if="uploadType == '2' && appType == 'android'"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-input
+              v-decorator="[
+                'packageName',
+                {
+                  rules: [{ required: true, message: '请填写正确的应用包名称' }],
+                },
+              ]"
+              placeholder="请填写包名称,如com.smile.gifmaker"
+            />
+          </a-form-item>
+
+          <a-form-item
+            label="应用名称"
+            v-if="uploadType == '2'"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-input
+              v-decorator="[
+                'appName',
+                {
+                  rules: [{ required: true, message: '请填写应用名称' }],
+                },
+              ]"
+              placeholder="请填写应用名称"
+            />
+          </a-form-item>
+
+          <a-form-item
+            label="上传图标"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 19 } }"
+            v-if="application"
+          >
+            <uploadFile
+              v-if="application"
+              :value.sync="fileUrl"
+              :multiple="false"
+              :fileCount="1"
+              uploadType="image"
+              @overUpload="overUpload"
+              :size="100"
+            ></uploadFile>
+            <p class="upload-txt-rules">文件格式:支持上传png/jpg/jpeg图片,尺寸450*450,小于100kb</p>
+          </a-form-item>
+
+          <a-form-item
+            label="应用标记"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+            v-if="uploadType == '2'"
+          >
+            <a-input
+              v-decorator="[
+                'appVersion',
+                {
+                  rules: [{ required: true, message: ' ' }, { validator: checkAppVersion }],
+                },
+              ]"
+              placeholder="请填写应用标记,必填且不可重复,如快手-5.6.1.66"
+            />
+          </a-form-item>
+          <!-- <a-form-item>
+            <a-form-item :wrapperCol="{ span: 24 }" style="text-align: center">
+              <a-button htmlType="submit" type="primary">提交</a-button>
+              <a-button style="margin-left: 8px">保存</a-button>
+            </a-form-item>
+          </a-form-item> -->
+          <a-form-item
+            label=""
+            :labelCol="{ span: 5 }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 }, offset: 5 }"
+            v-if="uploadType == '2' && appType == 'android'"
+          >
+            <a-checkbox-group v-decorator="['useSdk']">
+              <a-checkbox :value="0"> 该应用已接入快手广告监测SDK </a-checkbox>
+            </a-checkbox-group>
+          </a-form-item>
+          <a-form-item
+            label="隐私政策链接"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+            v-if="uploadType == '2' && appType == 'android'"
+          >
+            <a-input
+              v-decorator="[
+                'appPrivacyUrl',
+                {
+                  rules: [{ required: true, message: '请填写隐私政策链接' }, { validator: handleConfirmValue }],
+                },
+              ]"
+              placeholder="请填写隐私政策链接"
+            />
+          </a-form-item>
+
+          <a-form-item
+            label="监测链接"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+            v-if="uploadType == '2' && appType == 'android'"
+          >
+            <a-input v-decorator="['trackUrl']" placeholder="请填写监测链接" />
+          </a-form-item>
+        </a-form>
+      </a-card>
+    </a-modal>
+  </div>
+</template>
+
+<script>
+import Vue from 'vue'
+import { ACCESS_TOKEN } from '@/store/mutation-types'
+import { deleteAction, postAction, getAction, downFilePost, downFile } from '@/api/manage'
+import uploadFile from './uploadFile.vue'
+import { mapActions, mapGetters } from 'vuex'
+import BMF from 'browser-md5-file'
+import selectTable from '@/views/modules/Statistics/components/selectPagination.vue'
+import pick from 'lodash.pick'
+const fileSuffix = ['xlsx', 'xls', 'zip']
+export default {
+  name: 'BaseForm',
+  components: {
+    uploadFile,
+    selectTable,
+  },
+  data() {
+    return {
+      loadDisabled: false,
+      projectId: '',
+      accountId: '',
+      fileList: [],
+      fileUrl: '',
+      accountList: {},
+      appType: 'android', //设备类型
+      platform: '1', //应用类型   : 1 Android 应用下载,2: Android 网页游戏,3: iOS 应用下载, 4:iOS 网页游戏
+      uploadType: '2', //上传类型 1 本地上传 2 填写链接
+      appVersion: '', //应用标记
+      appName: '', // 应用名称
+      packageName: '', //应用包名
+      file: '', // 上传文件
+      imageUrl: '', // 上传图标链接链接
+      downloadUrl: '', //下载链接
+      showUploadFile: true,
+      showDownLoad: false,
+      showUpload: true,
+      showAndroid: true,
+      showIOS: false,
+      customDomain: '',
+      acceptVideo: '/*.apk,/*.png,/*.jpg,/*.jpeg,/*.mp4',
+      accessKeyId: 'LTAIbNbqWzSOklQV',
+      accessKeySecret: '1rkPz7JNoXk8sJevPaeYHWqfkQXBGh',
+      region: 'oss-cn-beijing',
+      bucket: 'ctop-media',
+      form: this.$form.createForm(this),
+      url: {
+        insertTemplateUrl: '/kuaishouAppPackage/fillInLink',
+        userAllocationList: '/ctop/userAllocation/list',
+      },
+      application: false,
+      confirmLoading: false,
+      imageToken: '',
+      uploadAction: '/kuaishouAppPackage/importAppExcel',
+      tokenHeader: { 'X-Access-Token': Vue.ls.get(ACCESS_TOKEN) },
+      appId: null,
+    }
+  },
+  methods: {
+    checkAppVersion(rule, value, callback) {
+      if (value != '') {
+        if (this.projectId) {
+          let params = {}
+          params.projectId = this.projectId
+          params.appVersion = value
+          params.id = this.appId
+          getAction('/kuaishouAppPackage/checkAppVersion', params).then((res) => {
+            if (res.success) {
+              callback()
+            } else {
+              callback(res.message)
+            }
+          })
+        }
+      } else {
+        callback('应用标记必填')
+      }
+    },
+    overUpload(file) {
+      console.log(file)
+    },
+    downLoadFile() {
+      downFile('/kuaishouAppPackage/exportAppTemplate').then((res) => {
+        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 = '应用模板' //下载后文件名
+        document.body.appendChild(downloadElement)
+        downloadElement.click() //点击下载
+        document.body.removeChild(downloadElement) //下载完成移除元素
+        window.URL.revokeObjectURL(href) //释放掉blob对象
+      })
+    },
+    handleChange(info) {
+      console.log(info)
+      let fileList = [...info.fileList]
+
+      // 1. Limit the number of uploaded files
+      //    Only to show two recent uploaded files, and old ones will be replaced by the new
+      fileList = fileList.slice(-2)
+
+      // 2. read from response and show file link
+      fileList = fileList.map((file) => {
+        if (file.response) {
+          // Component will show file.url as link
+          file.url = file.response.url
+        }
+        return file
+      })
+      if (fileList.length > 0) {
+        this.fileList = [
+          {
+            ...fileList[fileList.length - 1],
+          },
+        ]
+      } else {
+        this.fileList = []
+      }
+      // this.loadDisabled = false
+      // this.$message.success('文件导入成功,异步创建中,请稍后查看...')
+      if (info.file.status !== 'uploading') {
+        console.log(info.file, info.fileList)
+      }
+      if (info.file.status === 'done') {
+        this.loadDisabled = false
+        if (info.file.response.code == 200) {
+          this.application = true
+          this.$emit('getDataList')
+          this.$message.success(info.file.response.message)
+        } else {
+          this.$message.error(info.file.response.message)
+        }
+      } else if (info.file.status === 'error') {
+        this.$message.error(`${info.file.name}上传失败`)
+        this.loadDisabled = false
+      }
+
+      // console.log(this.form)
+    },
+    beforeUpload(file) {
+      // this.cosUpload(file)
+      if (process.env.NODE_ENV == 'development') {
+        this.uploadAction = `/jeecg-boot/kuaishouAppPackage/importAppExcel?projectId=${this.projectId}&platform=${
+          this.appType == 'ios' ? +this.platform + 2 : +this.platform
+        }&imageUrl=${this.fileUrl}`
+      } else if (process.env.NODE_ENV == 'debug') {
+      } else if (process.env.NODE_ENV == 'production') {
+        this.uploadAction = `${this.axios.defaults.baseURL}/kuaishouAppPackage/importAppExcel?projectId=${
+          this.projectId
+        }&platform=${this.appType == 'ios' ? +this.platform + 2 : +this.platform}&imageUrl=${this.fileUrl}`
+      }
+      this.loadDisabled = true
+      const size = (Number(file.size) / (1024 * 1024)).toFixed(2)
+      const fileName = file.name
+      const fileStrArr = fileName.split('.')
+      const suffix = fileStrArr[fileStrArr.length - 1]
+
+      let result = fileSuffix.some((item) => {
+        return item === suffix
+      })
+
+      if (!result) {
+        this.$message.error('不支持该文件类型')
+        this.loadDisabled = false
+        return false
+      }
+    },
+    cosUpload(file) {
+      let 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
+      let timeElse = new Date().getTime()
+      let arr = file.name.split('.')
+      let 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] + '.'
+          }
+        }
+      }
+      cos.putObject(
+        {
+          Bucket: 'media-1301855440',
+          Region: 'ap-chongqing',
+          // 存储桶所在地域,必须字段
+          Key: that.appType + '/' + y + '-' + MM + '-' + d + '/' + str + '-' + timeElse + '.' + arr[arr.length - 1],
+          StorageClass: 'STANDARD',
+          Body: file, // 上传文件对象
+        },
+        function (err, data) {
+          if (err) {
+            that.$message.error('上传失败!!!' + err)
+            return
+          }
+          that.loadingElse = false
+          that.fileList.push({
+            uid: file.name,
+            name: file.name,
+            status: 'done',
+            url: '//' + data.Location,
+          })
+          if (that.fileList.length > 1) {
+            that.fileList = that.fileList.slice(-1)
+          }
+          const isZip = file.type.includes('zip') || file.type.includes('text')
+          const fileOvesize = file.size > 1024 * 1024 * 1024
+          if (!isZip) {
+            that.$message.error('只能上传zip格式的文件或者txt文件')
+            return
+          }
+          if (fileOvesize) {
+            that.$message.error('文件大小不能超过1G')
+            return
+          }
+          that.handleMd5(file)
+        }
+      )
+    },
+    handleMd5(file) {
+      let bmf = new BMF()
+      let that = this
+      return new Promise(function (resolve, reject) {
+        bmf.md5(file, (err, md5) => {
+          // getAction('kuaishouPopulationPackage/checkPopulationPackage', { signature: md5 })
+          //   .then((result) => {
+          //     if (result.code === 200) {
+          that.personNameDisabled = false
+          that.personResourceDisabled = false
+          resolve()
+          //   } else if (result.code === 201) {
+          //     that.$message.error(result.message)
+          //     that.personForm.name = result.result.orientationName
+          //     that.personForm.resource = result.result.type
+          //     that.personNameDisabled = true
+          //     that.personResourceDisabled = true
+          //     reject()
+          //   }
+          // })
+          // .catch((error) => {
+          //   console.log(error, 'eeee')
+          //   reject()
+          // })
+        })
+      })
+    },
+    handleOk() {
+      this.handleSubmit()
+    },
+    handleCancel() {
+      this.form.resetFields()
+      this.imageUrl = ''
+      this.fileUrl = ''
+      this.platform = '1'
+      this.application = false
+      this.uploadType = '2'
+    },
+    showApplication(val) {
+      this.application = true
+      this.appId = val.id
+      getAction('/kuaishouAppPackage/queryById', { id: val.id }).then((res) => {
+        //   'appIconUrl',
+        if (res.success) {
+          this.fileUrl = res.result.appIconUrl
+          this.appType = res.result.platform > 2 ? 'ios' : 'android'
+          this.platform = res.result.platform > 2 ? res.result.platform - 2 + '' : res.result.platform + ''
+          res.result.useSdk = res.result.useSdk ? (res.result.useSdk == 0 ? [] : [0]) : null
+          this.projectId = res.result.projectId
+          if (this.appType == 'android') {
+            this.$nextTick(() => {
+              this.form.setFieldsValue(
+                pick(res.result, 'url', 'packageName', 'appPrivacyUrl', 'useSdk', 'trackUrl', 'appName', 'projectName')
+              )
+              setTimeout(() => {
+                this.form.setFieldsValue(pick(res.result, 'appVersion'))
+              }, 150)
+            })
+          } else {
+            setTimeout(() => {
+              this.form.setFieldsValue(pick(res.result, 'url', 'appVersion', 'projectName'))
+            }, 100)
+            setTimeout(() => {
+              this.form.setFieldsValue(pick(res.result, 'appName'))
+            }, 150)
+          }
+        }
+      })
+    },
+    handleConfirmValue(rule, value, callback) {
+      if (/(http|https):\/\/([\w.]+\/?)\S*/.test(value) && value != '') {
+        callback()
+      } else {
+        callback('链接不能为空且开头为http://或https://')
+      }
+    },
+    ...mapGetters(['nickname', 'avatar', 'userInfo']),
+    changePlatform() {
+      // this.form.resetFields()
+      // if (this.appType == 'android') {
+      //   this.showAndroid = true
+      //   this.showIOS = false
+      //   this.platform = '1'
+      // } else {
+      //   this.showAndroid = false
+      //   this.showIOS = true
+      //   this.showDownLoad = true
+      //   this.platform = '1'
+      // }
+    },
+
+    handleSubmit() {
+      //   console.log('设备类型:' + this.appType)
+      //   console.log('应用类型:' + this.platform)
+      //   console.log('上传类型:' + this.uploadType)
+      //   console.log('应用标记:' + this.appVersion)
+      //   console.log('应用名称:' + this.appName)
+      //   console.log('包名称:' + this.packageName)
+      //   console.log('文件地址:' + this.file)
+      //   console.log('图片地址:' + this.imageUrl)
+      //   e.preventDefault()
+      this.form.validateFields((err, values) => {
+        if (!err) {
+          if (this.fileUrl && this.projectId) {
+            this.confirmLoading = true
+            let params = {}
+            params.projectId = this.projectId
+            if (this.uploadType == '1') {
+              this.url.insertTemplateUrl = '/kuaishouAppPackage/importAppExcel'
+              params.platform = this.appType == 'ios' ? +this.platform + 2 : +this.platform
+              params.imageUrl = this.fileUrl
+            } else {
+              this.url.insertTemplateUrl = '/kuaishouAppPackage/fillInLink'
+              params = { ...values }
+              params.useSdk = params.useSdk ? (params.useSdk.length > 0 ? 1 : 0) : null
+              params.id = this.appId
+              params.projectId = this.projectId
+              params.appIconUrl = this.fileUrl
+              params.platform = this.appType == 'ios' ? +this.platform + 2 : +this.platform
+            }
+            postAction(this.url.insertTemplateUrl, params).then((res) => {
+              this.confirmLoading = false
+              if (res.success) {
+                this.$message.success('修改成功')
+                this.handleCancel()
+                this.$emit('getDataList')
+              } else {
+                this.$message.error(res.message)
+              }
+            })
+          } else {
+            this.$message.error('请填写必填项')
+          }
+        }
+      })
+    },
+
+    onChange(value) {
+      console.log(value)
+    },
+  },
+  created: function () {
+    let params = {}
+    params.pageSize = '1000'
+    params.mediaId = '2'
+    params.userId = this.userInfo().id
+    getAction(this.url.userAllocationList, params).then((res) => {
+      if (res.success) {
+        this.accountList = res.result.records
+      }
+    })
+  },
+}
+</script>

+ 6 - 0
src/views/modules/autoLaunch/application/components/tree-select.less

@@ -21,6 +21,12 @@
             .class-left-content {
                 overflow-y: auto;
                 height: 340px;
+                position: relative;
+                .pagin-table-class {
+                    position: absolute;
+                    bottom: 0;
+                    right: 0;
+                }
             }
             .example {
                 text-align: center;

+ 56 - 25
src/views/modules/autoLaunch/application/components/tree-select.vue

@@ -16,6 +16,14 @@
                             @check="onCheck"
                             @expand="onExpand"
                         />
+                        <!-- <a-pagination
+                            class="pagin-table-class"
+                            :total="totalAll"
+                            :show-total="total => `共 ${totalAll} 条`"
+                            size="small"
+                            @change="onShowSizeChange"
+                            @showSizeChange="onShowSizeChange"
+                        /> -->
                     </template>
                     <div class="example">
                         <a-spin :spinning="spinning"/>
@@ -54,12 +62,33 @@
 </template>
 <script>
 import {mapGetters} from 'vuex';
-import {postAction} from '@/api/manage';
+import {postAction,getAction} from '@/api/manage';
 
 export default {
     name: 'tree-select',
+    props: {
+        projectId: {
+            type: [String,Number],
+            default() {
+                return null
+            },
+        },
+        templateId: {
+            type: [String,Number],
+            default() {
+                return null
+            },
+        },
+        httpSrc: {
+            type: String,
+            default() {
+                return '/kuaishouDirectionalPackage/getAccountByProjectId'
+            }
+        }
+    },
     data() {
         return {
+            totalAll: 20,
             expandedKeys: [],
             autoExpandParent: true,
             checkedKeys: [],
@@ -69,7 +98,11 @@ export default {
             applyTypeOption: [],
             selectRightData: new Set(),
             spinning: true,
-            leftTreeNoData: false
+            leftTreeNoData: false,
+            tablePag: {
+                page: 1,
+                size: 100
+            },
         };
     },
     mounted() {
@@ -77,36 +110,32 @@ export default {
     },
     methods: {
         ...mapGetters(['userInfo']),
+        onShowSizeChange(current, pageSize) {
+            this.tablePag = {
+                page: current,
+                size: pageSize
+            };
+            this.getAccountId();
+        },
         getAccountId() {
-            postAction('/ctop/projectMember/participateListByMediaId', {
-                userId: this.userInfo().id,
-                type: 'kuaishou'
+            getAction(this.httpSrc, {
+                projectId: this.projectId,
+                id: this.templateId,
+                pageNo: this.tablePag.page,
+                pageSize: this.tablePag.size
             }).then(result => {
-                if (result.result.length) {
+                if (result.result.list.length) {
                     this.spinning = false;
-                    this.treeData = result.result.map(item => {
+                    this.treeData = result.result.list.map(item => {
                         return {
-                            key: item.projectId + 'projectId',
-                            title: item.projectName + '\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0' + item.advertiserName,
-                            children: item.accountList
-                            ? item.accountList.map(i => {
-                                return {
-                                    key: i.accountId,
-                                    title:
-                                    (i.userName.length === 2
-                                        ? i.userName + '\xa0\xa0\xa0\xa0\xa0'
-                                        : i.userName.length === 3
-                                        ? i.userName + '\xa0\xa0\xa0\xa0'
-                                        : i.userName)
-                                        + '\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0'
-                                        + i.accountId
-                                        + '\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0'
-                                        + i.authName
-                                };
-                            }) : []
+                            key: item.accountId,
+                            title: item.authName,
+                            disabled: item.state === 1,
+                            children: null
                         };
                     });
                     this.updateTreeData = [...this.treeData];
+                    this.totalAll = result.result.total || 0;
                 }
                 else {
                     this.spinning = false;
@@ -142,6 +171,7 @@ export default {
             }
             defaultCheckKey.splice(value, 1);
             this.checkedKeys = defaultCheckKey;
+            this.$emit('applyType', this.applyTypeOption);
         },
         onChange(e) {
             const value = e.target.value;
@@ -231,6 +261,7 @@ export default {
         },
         onCheck(checkedKeys) {
             // this.checkedKeys = checkedKeys;
+            console.log(checkedKeys)
             this.nodes(this.treeData, checkedKeys);
             const filterCheckKey = this.checkedKeys.filter(item=>typeof item ==='number');
             let filterCheckKeySet = new Set(filterCheckKey);

+ 365 - 0
src/views/modules/autoLaunch/application/components/uploadFile.vue

@@ -0,0 +1,365 @@
+<style>
+</style>
+<style lang="scss" scoped>
+</style>
+<template>
+  <div class="upload-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/*' : '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 class="ant-upload-text">点击上传</div>
+      </div>
+    </a-upload>
+    <!-- <div style="color: red" v-if="sizeCheck">
+      {{ uploadType == 'image' ? '请上传jpg格式的图片,并且大小在2m之内' : '请上传mp4格式,大小在'+(size/1024)+'m之内' }}
+    </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: '',
+    }
+  },
+  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 = []
+                var data = {
+                  uid: 1,
+                  name: '回显',
+                  status: 'done',
+                  url: n,
+                }
+                this.fileList.push(data)
+              }
+            }
+          } 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(file)
+      var image = new Image()
+      var reader = new FileReader()
+      var height = 0
+      var width = 0
+      reader.readAsDataURL(file)
+      //文件读取结束时间
+      reader.onload = function (e) {
+        image.src = reader.result
+      }
+      var that = this
+      //图片读取事件
+      image.onload = function () {
+        height = image.naturalHeight
+        width = image.naturalWidth
+      }
+      if (image.complete) {
+        height = image.naturalHeight
+        width = image.naturalWidth
+      }
+
+      setTimeout(() => {
+        if (height != 450 || width != 450) {
+          that.$message.error('请上传450*450大小的图片')
+          this.loadingElse = false
+          return
+        }
+        // console.log(fileOvesize)
+        if (fileOvesize && this.sizeCheck) {
+          this.onOversize()
+          this.loadingElse = false
+          return
+        } else {
+          if (file.type.includes('jpg') || file.type.includes('png') || file.type.includes('jpeg')) {
+            this.checkFile(file)
+              .then((res) => {
+                this.cosUpload(file)
+              })
+              .catch(() => {
+                this.loadingElse = false
+              })
+          } else {
+            this.$message.error('请上传正确格式')
+            this.loadingElse = false
+          }
+
+          return new Promise(function (resolve, reject) {
+            reject()
+          })
+        }
+      }, 200)
+    },
+    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 item.url
+                })[0]
+              )
+            }
+          } else {
+            that.$message.error('上传已达上限' + that.fileCount + '张')
+          }
+        }
+      )
+    },
+  },
+}
+</script>
+<style scoped>
+@import '~@assets/less/common.less';
+</style>

+ 87 - 44
src/views/modules/autoLaunch/configLaunchInfo.vue

@@ -93,7 +93,22 @@
                 </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>
+                <div class="input-item">
+                <a-form-item>                
+                <a-radio-group v-decorator="['campaignStatus', {initialValue:1 }]">
+                    <a-radio-button :value="1">投放</a-radio-button>
+                    <a-radio-button :value="2">暂停</a-radio-button>
+                </a-radio-group>
+                </a-form-item>
+                </div>
+            </div>  
+
             <div class="row-item">
                 <div class="hint-item"> </div>
                 <div class="label-item">
@@ -180,6 +195,21 @@
             <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="['groupStatus', {initialValue:-1 }]">
+                    <a-radio-button :value="-1">投放</a-radio-button>
+                    <a-radio-button :value="2">暂停</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>
@@ -704,7 +734,31 @@
                         </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-model="scheduleTimeType" >
+                                <a-radio-button value=''>不限</a-radio-button>
+                                <a-radio-button value="SpecifiedTImePeriod">指定时间段</a-radio-button>
+                            </a-radio-group>
+                            <div
+                            v-show="scheduleTimeType=='SpecifiedTImePeriod'"
+                            style="margin-top:15px"
+                            >
+                            <scheduleTime
+                                style="width:100%"
+                                :scheduleTime.sync="scheduleTimeData"
+                                ref="selectCheck"
+                            />
+                            </div>
+                        </a-form-item>
+                        </div>
+                    </div>
 
 
                     <div class="row-item" v-if="getFormData('platformOs')==1">
@@ -910,7 +964,7 @@
                 </a-spin>
             </div>
         </div>
-        
+
         <!-- <div class="moduler">
             <div class="moduler-title">预算和排期</div>
             <div class="ad-range">
@@ -937,31 +991,7 @@
                         </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>
-                        <div class="input-item">
-                        <a-form-item>
-                            <a-radio-group v-decorator="['scheduleTimes', { initialValue:'' }]" >
-                              <a-radio-button value=''>不限</a-radio-button>
-                              <a-radio-button value="SpecifiedTImePeriod">指定时间段</a-radio-button>
-                            </a-radio-group>
-                            <div
-                            v-show="getFormData('scheduleTimes')=='SpecifiedTImePeriod'"
-                            style="margin-top:15px"
-                            >
-                            <scheduleTime
-                                style="width:100%"
-                                :scheduleTime.sync="scheduleTimeData"
-                                ref="selectCheck"
-                            />
-                            </div>
-                        </a-form-item>
-                        </div>
-                    </div>
+
                     <div class="row-item">
                       <div class="hint-item">
                       </div>
@@ -1822,10 +1852,10 @@ const plainOptions = [
       value: 6,
       label: '上下滑大屏广告'
     },
-    {
-      value: 7,
-      label: '信息流广告'
-    },
+    // {
+    //   value: 7,
+    //   label: '信息流广告'
+    // },
     {
       value: 3,
       label: '视频播放页广告'
@@ -1911,7 +1941,7 @@ export default {
             appList: [],
             appListAll:[],
             dateRange: [moment(), moment()],
-            scheduleTime: '',
+            scheduleTimeType: '',
             scheduleTimeData:str,
             projectInfo:[],
         
@@ -2566,6 +2596,9 @@ export default {
                                 +'\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0'+
                                 item.appName+'\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0'+item.appVersion}
                     })
+                    //  if(val!=undefined && (val&&val.length>1)){
+                            this.getIsActivate(appidArr[0].key)
+                        // }
                     // setTimeout(()=>{
                         
                     //     this.form.setFieldsValue({
@@ -2608,14 +2641,14 @@ export default {
                     })
                 }
             }
-            
-           if(val!=undefined && (val&&val.length>0) ){
+           if(val!=undefined &&val){
                 if(this.getFormData('campaignType')==2){
                     
                     if(this.getFormData('singleAppid')==1){
                         this.getIsActivate(val.key)
                     }else{
-                        this.getIsActivate(val[0].key)
+                       
+                        
                     }
                     
                 }
@@ -2899,11 +2932,12 @@ export default {
                         values.sceneId=JSON.stringify(this.checkedList)
                     }
                     // 时间段值
-                    // if(this.getFormData('scheduleTime')!=''){
-                    //     values.scheduleTime=this.scheduleTimeData
-                    // }else{
-                    //     values.scheduleTime=''
-                    // }
+                    
+                    if(this.scheduleTimeType!=''){
+                        values.scheduleTime=this.scheduleTimeData
+                    }else{
+                        values.scheduleTime=str
+                    }
 
                     // 投放时间的值
                     // if(this.getFormData('scheduleType')=='SCHEDULE_FROM_NOW'){
@@ -2971,9 +3005,9 @@ export default {
                     values.useAppMarket=values.useAppMarket?'1':'0'
                     
                     
-                    // if(this.useDirectional==0){
-                    //     values.templateId=this.directionalCheckedList
-                    // }
+                    if(this.useDirectional==0){
+                        values.templateId=this.directionalCheckedList
+                    }
                     if(this.sysType==1&&this.getData('useAppMarket')){
                         values.appStore=JSON.stringify(this.appStore)
                     }else if(this.sysType==1&&!this.getData('useAppMarket')){
@@ -3350,6 +3384,15 @@ export default {
                         return {value:item}
                     }):[{value:res.result.description}]
                    
+                   if(res.result.scheduleTime&&res.result.scheduleTime != str) {
+                        this.scheduleTimeType='SpecifiedTImePeriod'
+                        this.scheduleTimeData = res.result.scheduleTime
+                       
+                   }else{
+                        this.scheduleTimeType = ''
+                        this.scheduleTimeData = str
+                   }
+                   
                     this.multipleBidData = res.result.appInfoList ? res.result.appInfoList.map(item=>{
                         
                         return {

+ 14 - 0
src/views/modules/autoLaunch/configProject/configProject-service.js

@@ -0,0 +1,14 @@
+/**
+ * @file 项目配置列表
+ * @author zhuxinbo(zhuxinbo@c-top.com.cn)
+ */
+
+class AppMarketService {
+    constructor() { }
+
+
+
+
+}
+
+export default new AppMarketService();

+ 6 - 0
src/views/modules/autoLaunch/configProject/configProject.less

@@ -0,0 +1,6 @@
+.config-project {
+    .middle-button {
+        margin: 0 8px;
+    }
+  
+}

File diff suppressed because it is too large
+ 3480 - 0
src/views/modules/autoLaunch/configProject/creatConfig.vue


+ 96 - 0
src/views/modules/autoLaunch/configProject/editablCell.vue

@@ -0,0 +1,96 @@
+<template>
+    <div class="editable-cell">
+        <div v-if="editable" class="editable-cell-input-wrapper">
+            <a-input :value="value" @change="handleChange" @pressEnter="check" /><a-icon
+                type="check"
+                class="editable-cell-icon-check"
+                @click="check"
+            />
+        </div>
+        <div v-else class="editable-cell-text-wrapper">
+            <div
+                style="width:90%;
+                overflow:hidden;
+                text-overflow:ellipsis;
+                white-space:nowrap;"
+                :title="value"
+            >
+                {{ value || '' }}
+            </div>
+
+            <a-icon type="edit" class="editable-cell-icon" :style="{ top: value ? '10px' : '0px' }" @click="edit" />
+        </div>
+    </div>
+</template>
+
+<script>
+export default {
+    props: {
+        text: String
+    },
+    data() {
+        return {
+            value: this.text,
+            editable: false
+        }
+    },
+    methods: {
+        handleChange(e) {
+            const value = e.target.value
+            this.value = value
+        },
+        check() {
+            this.editable = false
+            this.$emit('change', this.value)
+        },
+        edit() {
+            this.editable = true
+        }
+    }
+}
+</script>
+<style lang="scss" scoped>
+.editable-cell {
+    position: relative;
+}
+
+.editable-cell-input-wrapper,
+.editable-cell-text-wrapper {
+    padding-right: 24px;
+}
+
+.editable-cell-text-wrapper {
+    padding: 5px 24px 5px 5px;
+}
+
+.editable-cell-icon,
+.editable-cell-icon-check {
+    position: absolute;
+    right: 0;
+    width: 20px;
+    top: 10px;
+    cursor: pointer;
+}
+
+.editable-cell-icon {
+    line-height: 18px;
+    display: none;
+}
+
+.editable-cell-icon-check {
+    line-height: 28px;
+}
+
+.editable-cell:hover .editable-cell-icon {
+    display: inline-block;
+}
+
+.editable-cell-icon:hover,
+.editable-cell-icon-check:hover {
+    color: #108ee9;
+}
+
+.editable-add-btn {
+    margin-bottom: 8px;
+}
+</style>

File diff suppressed because it is too large
+ 1428 - 0
src/views/modules/autoLaunch/configProject/index.vue


+ 1 - 0
src/views/modules/autoLaunch/directional/components/tree-select.vue

@@ -171,6 +171,7 @@ export default {
             }
             defaultCheckKey.splice(value, 1);
             this.checkedKeys = defaultCheckKey;
+            this.$emit('applyType', this.applyTypeOption);
         },
         onChange(e) {
             const value = e.target.value;

+ 1 - 0
src/views/modules/autoLaunch/directional/directional.vue

@@ -502,6 +502,7 @@ export default {
                     title: '操作',
                     dataIndex: 'action',
                     align: 'center',
+                    width: 150,
                     scopedSlots: {customRender: 'action'}
                 },
                 {

+ 429 - 0
src/views/modules/autoLaunch/material-all/components/selectRegion.vue

@@ -0,0 +1,429 @@
+<style scoped>
+  .transfer {
+    display: flex;
+  }
+
+  .transfer .transfer-box {
+    width: 350px;
+    height: 250px;
+    border: 1px solid #dadfe3;
+    display: flex;
+    overflow-x: auto;
+    overflow-y: hidden;
+    box-sizing: border-box;
+    margin-right: 25px;
+  }
+
+  .content-box {
+    min-width: 174px;
+    width: 100%;
+    height: 100%;
+    border-right: 1px solid #dadfe3;
+  }
+
+  .content-box .content-title {
+    width: 100%;
+    background: #f8f9fa;
+    border-bottom: 1px solid #dadfe3;
+    padding: 5px 15px;
+    font-size: 16px;
+    font-weight: 700;
+    line-height: 30px;
+  }
+
+  .content-box .content {
+    width: 100%;
+    height: 85%;
+    overflow: auto;
+  }
+
+  .content-box .content p:hover {
+    background: #edf1f5;
+    cursor: pointer;
+  }
+
+  .content-box .content p:hover span {
+    display: inline-block;
+  }
+
+  .content-box .content p span {
+    display: none;
+  }
+
+  p {
+    padding: 5px;
+    margin-bottom: 0;
+    border-bottom: 1px solid #f2f2f2;
+  }
+
+  .backgroundOnly {
+    background: #edf1f5;
+  }
+</style>
+<style>
+  .transfer .ant-checkbox-group {
+    width: 100px;
+    overflow-x: hidden;
+  }
+
+  .transfer .ant-checkbox-group-item {
+    display: inline-block;
+    margin-right: 8px;
+    width: 100%;
+  }
+</style>
+
+<template>
+  <div class="transfer">
+    <div class="transfer-box">
+      <div class="content-box">
+        <p class="content-title">省份</p>
+        <div class="content" style="position:relative">
+          <!-- <div style="position:absolute;top:0;left:0;width:100%;height:100%;background: rgba(0, 0, 0, 0.5)"
+            v-if="loading"></div> -->
+          <p><input type="checkbox" class="select_all" @change="checkAllBox" v-model="checkAll" /> 全选</p>
+
+          <p v-for="(item, index) of province" :key="item.value" :class="{ backgroundOnly: provinceIndex == index }">
+            <input class="checkItem" type="checkbox" :value="item.value" :id="item.value" v-model="checkMatched"
+              @change="checkOne(item, index)" />
+            <span @click="showCity(item, index)" style="color:black;display:inline-block;margin-left:5px;width:80%">{{
+              item.label
+            }}</span>
+          </p>
+        </div>
+      </div>
+      <div class="content-box" :style="{ borderRight: !showClass ? '0px' : '1px solid #dadfe3' }" v-show="showCityData">
+        <p class="content-title">城市</p>
+        <div class="content">
+          <!-- <p>
+            <input
+              type="checkbox"
+              class="select_all"
+              @change="checkAllBoxCity"
+              v-model="checkAllCity"
+            /> 全选
+          </p>-->
+          <p v-for="(item, index) of city" :key="item.id" :class="{ backgroundOnly: cityIndex == index }">
+            <input class="checkItem" type="checkbox" :value="item.value" :id="item.value" v-model="checkMatchedCity"
+              @change="checkOneCity(item, index)" />
+            {{ item.label }}
+          </p>
+        </div>
+      </div>
+    </div>
+    <div class="transfer-box" style="width:176px">
+      <div class="content-box">
+        <p class="content-title">
+          已选
+          <span style="float:right;font-weight:normal;color:blue;cursor: pointer;font-size:14px"
+            @click="clear">清空</span>
+        </p>
+        <div class="content">
+          <p v-for="(item, index) of checkData" :key="index">
+            {{ item.label }}
+            <!-- <span
+              style="float:right;font-weight:normal;color:blue;cursor: pointer;font-size:14px"
+              @click="detele(item,index)"
+            >删除</span>-->
+          </p>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+  import {
+    JeecgListMixin
+  } from '@/mixins/JeecgListMixin'
+  import {
+    getProvince,
+    postAction
+  } from '@/api/manage'
+  import $ from 'jquery'
+  export default {
+    name: 'ByteDanceUserOrientationTemplateList',
+    components: {},
+    props: ['dataValue'],
+    data() {
+      return {
+        showClass: false,
+        showCityData: false,
+        checkData: [],
+        checkMatched: [],
+        province: [],
+        city: [],
+        area: [],
+        CityData: '/kuaishou/batch/getRegion',
+        provinceIndex: null,
+        cityIndex: null,
+        checkAll: false,
+        checkMatchedCity: [],
+        checkAllCity: false,
+        nowProvince: null,
+        loading: false
+      }
+    },
+    computed: {},
+    mounted() {
+      this.$nextTick(() => {
+        this.getData().then(() => {
+            console.log(this.dataValue)
+          if (this.dataValue.length>0&&this.dataValue[0].value) {
+            return
+          } else {
+            postAction('/kuaishou/batch/getRegionDetail', {
+              regionArr: this.dataValue
+            }).then(res => {
+              if (res.success) {
+                //   this.populationData.allForm.region = res.result
+                this.checkData = res.result
+                this.checkMatched = res.result.map(item => {
+                  return item.value
+                })
+                this.checkMatchedCity = res.result.map(item => {
+                  return item.value
+                })
+                this.$emit('update:checkData', this.checkData)
+              }
+            })
+          }
+
+          //   if (this.dataValue.length > 0) {
+
+          //   }
+        })
+
+      })
+    },
+    watch: {
+      dataValue: {
+        deep: true,
+        immediate: true, // immediate选项可以开启首次赋值监听
+        handler(n, o) {
+          if (n.length > 0 && n[0].value) {
+            // this.getData().then(() => {
+            console.log(1)
+            //   if (n.length > 0) {
+            this.$nextTick(() => {
+              this.checkData = n
+              this.checkMatched = n.map(item => {
+                return item.value
+              })
+              this.checkMatchedCity = n.map(item => {
+                return item.value
+              })
+              this.$emit('update:checkData', this.checkData)
+            })
+            //   }
+            // })
+
+          }
+
+        }
+      }
+    },
+    methods: {
+      getData() {
+        this.loading = true
+        var that = this
+        return new Promise(function (resolve, reject) {
+          getProvince(that.CityData, {
+            level: 1
+          }).then(res => {
+            if (res.code == '0') {
+              //   this.province.push(...res.result.records)
+              that.province = res.result.map(item => {
+                return {
+                  label: item.name,
+                  value: item.regionId
+                }
+              })
+              that.province = that.province.filter(item => {
+                return item.label != '台湾' && item.label != '香港' && item.label != '澳门'
+              })
+              that.loading = false
+              resolve()
+            }
+          })
+        })
+
+      },
+      showCity(item, index) {
+        this.city = []
+        this.showCityData = false
+        this.showClass = false
+        this.provinceIndex = index
+        this.cityIndex = null
+        this.nowProvince = item
+        this.checkMatchedCity = []
+        getProvince(this.CityData, {
+          parent: item.value
+        }).then(res => {
+          if (res.code == '0') {
+            this.city = res.result.map(item => {
+              return {
+                label: item.name,
+                value: item.regionId
+              }
+            })
+            if (this.checkMatched.indexOf(item.value) != -1) {
+              this.checkAllCity = true
+              this.checkMatchedCity = this.city.map(item => {
+                return item.value
+              })
+            } else {
+              this.checkMatchedCity = this.checkData.map(item => {
+                return item.value
+              })
+            }
+            //   this.city.push(...res.result.records)
+            this.showCityData = true
+          }
+        })
+      },
+      checkAllBox() {
+        this.checkMatched = []
+        this.checkData = []
+        if (this.checkAll) {
+          this.checkMatched = this.province.map(item => {
+            return item.value
+          })
+          this.checkData.push(...this.province)
+        } else {
+          this.checkMatched = []
+          this.checkData = []
+          this.checkMatchedCity = []
+        }
+        this.$emit('update:checkData', this.checkData)
+      },
+      checkOne(item, index) {
+        if (this.checkMatched.indexOf(item.value) == -1) {
+          var index1 = this.checkData.findIndex(v => v.value === item.value)
+          this.checkData.splice(index1, 1)
+          if (this.nowProvince) {
+            if (this.nowProvince.value == item.value) {
+              this.checkMatchedCity = []
+            }
+          }
+        } else {
+          this.checkData.push(item)
+          var data = []
+          getProvince(this.CityData, {
+            parent: item.value
+          }).then(res => {
+            if (res.code == '0') {
+              data = res.result.map(item => {
+                return {
+                  label: item.name,
+                  value: item.regionId
+                }
+              })
+              for (var i = 0; i < this.checkData.length; i++) {
+                for (let j = 0; j < data.length; j++) {
+                  if (this.checkData[i].value == data[j].value) {
+                    this.checkData.splice(i, 1)
+                  }
+                }
+              }
+            }
+          })
+
+          if (this.nowProvince) {
+            if (item.value == this.nowProvince.value) {
+              this.checkMatchedCity = this.city.map(item => {
+                return item.value
+              })
+            }
+          }
+        }
+        if (this.checkMatched.length == this.province.length) {
+          this.checkAll = true
+        } else {
+          this.checkAll = false
+        }
+        this.$emit('update:checkData', this.checkData)
+      },
+      checkAllBoxCity() {
+        this.checkMatchedCity = []
+        if (this.checkAllCity) {
+          this.checkMatchedCity = this.city.map(item => {
+            return item.value
+          })
+          this.checkMatched.push(this.nowProvince.value)
+          this.checkData.push(this.nowProvince)
+        } else {
+          this.checkMatchedCity = []
+          var index = this.checkData.findIndex(v => v.value === this.nowProvince.value)
+          var index1 = this.checkMatched.findIndex(v => v === this.nowProvince.value)
+          this.checkData.splice(index, 1)
+          this.checkMatched.splice(index1, 1)
+        }
+        this.$emit('update:checkData', this.checkData)
+      },
+      checkOneCity(item, index) {
+        var allCity = this.checkMatchedCity.filter(v => {
+          return v.toString().slice(0, 2) == this.nowProvince.value
+        })
+
+        if (allCity.length == this.city.length) {
+          this.checkMatched.push(this.nowProvince.value)
+          this.checkData.push(this.nowProvince)
+          for (var i = 0; i < allCity.length; i++) {
+            for (var j = 0; j < this.checkData.length; j++) {
+              if (allCity[i] == this.checkData[j].value) {
+                this.checkData.splice(j, 1)
+                j--
+              }
+            }
+          }
+        }
+        if (this.checkMatchedCity.indexOf(item.value) != -1) {
+          if (allCity.length != this.city.length) {
+            this.checkData.push(item)
+          }
+          if (this.checkMatched.length == this.province.length) {
+            this.checkAll = true
+          } else {
+            this.checkAll = false
+          }
+        } else {
+          if (this.checkMatched.indexOf(this.nowProvince.value) != -1) {
+            var index1 = this.checkData.findIndex(v => v.value === this.nowProvince.value)
+            var index2 = this.checkMatched.findIndex(v => v === this.nowProvince.value)
+            this.checkData.splice(index1, 1)
+            this.checkMatched.splice(index2, 1)
+            this.checkAll = false
+            var data = this.city.filter(v => {
+              return v.value != item.value
+            })
+            this.checkData.push(...data)
+          } else {
+            var index1 = this.checkData.findIndex(v => v.value === item.value)
+            this.checkData.splice(index1, 1)
+          }
+        }
+        this.$emit('update:checkData', this.checkData)
+      },
+      clear() {
+        this.checkData = []
+        this.checkMatched = []
+        this.checkMatchedCity = []
+        this.checkAll = false
+        this.$emit('update:checkData', this.checkData)
+      },
+      detele(item, index) {
+        //   if (this.checkMatched.indexOf(this.nowProvince.value) != -1) {
+        var index1 = this.checkMatched.findIndex(v => v === item.value)
+        var index2 = this.checkData.findIndex(v => v.value === item.value)
+        this.checkData.splice(index2, 1)
+        this.checkMatched.splice(index1, 1)
+        this.checkAll = false
+        //   } else {
+        //   }
+
+        this.$emit('update:checkData', this.checkData)
+      }
+    }
+  }
+</script>

File diff suppressed because it is too large
+ 1414 - 0
src/views/modules/autoLaunch/material-all/components/targetedPopulation.vue


+ 262 - 0
src/views/modules/autoLaunch/material-all/components/templateModal.vue

@@ -0,0 +1,262 @@
+<style>
+#table_time_selected1 tr {
+  border: 1px solid rgb(102, 162, 243);
+}
+
+.plug-timer-grid th {
+  line-height: 25px;
+}
+
+.group-creat .ant-form-item-required::before {
+  display: inline-block;
+  margin-right: 4px;
+  color: #f5222d;
+  font-size: 14px;
+  font-family: SimSun, sans-serif;
+  line-height: 1;
+  content: '';
+}
+
+.else-label .ant-form-item-label label::after {
+  content: '';
+  position: relative;
+  top: -0.5px;
+  margin: 0 8px 0 2px;
+}
+.ant-form-item-required::before {
+  display: inline-block;
+  margin-right: 4px;
+  color: #f5222d;
+  font-size: 14px;
+  font-family: SimSun, sans-serif;
+  line-height: 1;
+  content: '*';
+}
+</style>
+<style lang="scss" scoped>
+.require-check {
+  /deep/ .ant-form-item-label {
+    label::before {
+      display: inline-block;
+      margin-right: 4px;
+      color: #f5222d;
+      font-size: 14px;
+      font-family: SimSun, sans-serif;
+      line-height: 1;
+      content: '*';
+    }
+  }
+}
+</style>
+<template>
+  <a-modal v-model="visible" :title="type === 'add' ? '编辑素材指定定向包' : '编辑素材指定定向包'" :width="1100" v-if="visible">
+    <a-spin :spinning="spinning">
+      <a-form @submit="handleSubmit" :form="form">
+
+        <targeted-population ref="population" :populationData.sync="populationData" />
+      </a-form>
+    </a-spin>
+    <template slot="footer">
+      <!-- <a-button type="primary" @click="handleSubmit" :loading="loading"> 确定 </a-button> -->
+      <a-button
+        type="default"
+        @click="
+          () => {
+            this.visible = false
+          }
+        "
+      >
+        取消
+      </a-button>
+      <a-button type="primary" @click="handleSubmit" :loading="loading">
+        {{ type == 'add' ? '确定' : '修改' }}
+      </a-button>
+    </template>
+  </a-modal>
+</template>
+
+<script>
+import { getAction, postAction, deleteAction, putAction } from '@/api/manage'
+import moment from 'moment'
+import { mapGetters } from 'vuex'
+import jq from 'jquery'
+import selectTable from '@/views/modules/Statistics/components/selectPagination.vue'
+import targetedPopulation from './targetedPopulation.vue'
+import pick from 'lodash.pick'
+export default {
+  name: 'new-mould',
+  components: {
+    targetedPopulation,
+    selectTable,
+  },
+  data() {
+    return {
+      visible: false,
+      spinning: false,
+      projectName: '',
+      form: this.$form.createForm(this),
+      projectId: '',
+      populationData: {},
+      accountId: '',
+      templateId: undefined,
+      type: 'add',
+      loading: false,
+      labelCol: { lg: { span: 7 }, sm: { span: 7 } },
+      disabled: false,
+      id:null
+    }
+  },
+  computed: {},
+  methods: {
+    create(accountId, type) {
+      this.disabled = false
+      this.spinning = false
+      this.visible = true
+      this.type = type
+      this.populationData = {}
+      this.accountId = accountId
+    },
+    handleOk(item, type) {
+      this.spinning = true
+      this.visible = true
+      this.type = type
+      // var params = {}
+      // params.id = item.id
+      // this.templateId = item.id
+      // this.projectName = item.projectName
+      // this.projectId = item.projectId
+      // getAction('/kuaishouDirectionalPackage/queryById', params).then((res) => {
+      //   if (res.success) {
+          this.id = item.id;
+          var dataJson = {
+            ...item,
+          }
+
+          this.populationData = dataJson
+
+          this.populationData.devicePrice = dataJson.devicePrice ? JSON.parse(dataJson.devicePrice) : null
+          this.populationData.appInterest = dataJson.appInterest ? JSON.parse(dataJson.appInterest) : null
+          this.populationData.businessInterest = dataJson.businessInterest
+            ? JSON.parse(dataJson.businessInterest)
+            : null
+          this.populationData.fansStar = dataJson.fansStar ? JSON.parse(dataJson.fansStar) : null
+          this.populationData.interestVideo = dataJson.interestVideo ? JSON.parse(dataJson.interestVideo) : null
+          this.populationData.deviceBrand = dataJson.deviceBrand ? JSON.parse(dataJson.deviceBrand) : null
+
+          this.populationData.age = dataJson.min ? [dataJson.min, dataJson.max] : []
+          this.populationData.agesRange = dataJson.agesRange ? JSON.parse(dataJson.agesRange) : []
+          this.populationData.devicePrice = dataJson.devicePrice ? dataJson.devicePrice : null
+
+          this.populationData.behavior = dataJson.label
+          this.populationData.interest = dataJson.interestLabel
+
+          this.populationData.sceneType = dataJson.sceneType ? JSON.parse(dataJson.sceneType) : []
+          this.populationData.allForm = {}
+          this.populationData.allForm.regionType =
+            dataJson.region && JSON.parse(dataJson.region).length > 0 ? 'limit' : 'noLimit'
+
+          this.populationData.allForm.region = dataJson.region
+          // postAction('/kuaishou/batch/getRegionDetail', {
+          //   regionArr: dataJson.region
+          // }).then(res => {
+          //   console.log(res, 11111)
+          //   if (res.success) {
+          //     this.populationData.allForm.region = res.result
+          //   }
+          // })
+
+          this.populationData.allForm.ageType =
+            dataJson.agesRange.length > 0 ? 'ageLimit' : dataJson.min>0 ? 'ageCustom' : 'noLimit'
+          this.populationData.allForm.device = dataJson.deviceBrand && eval(dataJson.deviceBrand).length > 0 ? '1' : '0'
+          this.populationData.allForm.price = dataJson.devicePrice && eval(dataJson.devicePrice).length > 0 ? '1' : '0'
+          this.populationData.allForm.appType =
+            dataJson.appInterest && eval(dataJson.appInterest).length > 0
+              ? '1'
+              : dataJson.appIds && eval(dataJson.appIds).length > 0
+              ? '2'
+              : '0'
+          this.populationData.allForm.fansStar =
+            dataJson.fansStar && eval(dataJson.fansStar).length > 0 ? '1' : '0'
+          this.populationData.allForm.interestVideo =
+            dataJson.interestVideo && eval(dataJson.interestVideo).length > 0 ? '1' : '0'
+          this.populationData.allForm.platform_os = dataJson.platformOs
+          this.populationData.allForm.businessInterestType = dataJson.businessInterestType
+          this.populationData.allForm.isOpen = dataJson.isOpen
+          this.populationData.allForm.noAgeBreak = dataJson.noAgeBreak + ''
+          this.populationData.allForm.noGenderBreak = dataJson.noGenderBreak + ''
+          this.populationData.allForm.noAreaBreak = dataJson.noAreaBreak + ''
+          this.populationData.allForm.behaviorInterest = dataJson.label=='[]' ? '1' : '0'
+          this.populationData.allForm.checkArr =
+            this.populationData.allForm.appType == '2' ? JSON.parse(dataJson.appIds) : []
+          this.populationData.projectId = dataJson.projectId + ''
+
+          this.disabled = true
+
+          this.$nextTick(() => {
+            this.spinning = false
+          })
+
+    },
+    handleCancel(e) {
+      this.visible = false
+    },
+    handleSubmit(e) {
+      //   this.$refs.population.handleSubmit()
+
+      var data = JSON.parse(localStorage.getItem('materialDetail'))
+      e.preventDefault()
+      this.$refs.population.handleSubmit()
+      this.$refs.population.formAll.validateFields((err, value) => {
+        if (!err) {
+          this.form.validateFieldsAndScroll((err, values) => {
+            if (!err) {
+              this.loading = true
+              // this.loading = true
+
+                var params = {
+                  ...this.populationData,
+                  videoGetId: data.id,
+                  signature: data.md5,
+                  id:this.id
+                }
+                params.label = params.behavior?JSON.stringify(params.behavior):'[]'
+                params.interestLabel = params.interest?JSON.stringify(params.interest):'[]'
+                console.log(this.populationData)
+                if (this.populationData.allForm.regionType == 'limit') {
+                  if(this.populationData.allForm.region.length === 0) {
+                    this.$message.error('请选择地域');
+                    this.loading = false
+                    return
+                  }
+                }
+                if (this.type == 'add') {
+                  postAction('/kuaishouVideoDirectionalPackage/saveOrUpdate', params).then((res) => {
+                    if (res.success) {
+                      this.visible = false
+                      this.loading = false
+                      this.$emit('getData')
+                    } else {
+                      this.loading = false
+                      this.$message.error(res.message)
+                    }
+                  })
+                } else if (this.type == 'edit') {
+                  postAction('/kuaishouVideoDirectionalPackage/saveOrUpdate', params).then((res) => {
+                    this.visible = false
+                    if (res.success) {
+                      this.loading = false
+                      this.$emit('getData')
+                    } else {
+                      this.loading = false
+                      this.$message.error(res.message)
+                    }
+                  })
+                }
+            }
+          })
+        }
+      })
+    },
+  },
+}
+</script>

+ 982 - 0
src/views/modules/autoLaunch/material-all/material-detail.vue

@@ -0,0 +1,982 @@
+<style lang="scss" scoped>
+#office-iframe {
+    height: 800px;
+}
+.directional-border {
+    border: 1px solid #f2f2f2;
+    min-height: 250px;
+    width: 100%;
+    padding: 20px;
+    /deep/.title-border {
+        width: calc(100% + 40px);
+        height:50px;
+        line-height:50px;
+        background:rgb(250,250,250);
+        display: flex;
+        align-items: center;
+        margin-left: -20px;
+        margin-top: -20px;
+        padding: 20px;
+    }
+}
+.flex-main {
+    display: flex;
+    margin-bottom: 10px;
+    p {
+        color: black;
+        font-weight: 600;
+        overflow:hidden; //超出的文本隐藏
+        text-overflow:ellipsis; //溢出用省略号显示
+        white-space:nowrap; //溢出不换行
+    }
+}
+
+</style>
+<style>
+.info-detail .ant-descriptions-item-content {
+    font-weight: bold;
+}
+.info-detail .ant-descriptions-item-label {
+    color: darkgray;
+    min-width: 80px;
+}
+.info-detail table tr td {
+    border: 0;
+}
+.show-data p {
+    color: black;
+    font-weight: 600;
+}
+.show-data p span {
+    display: inline-block;
+    width: 85px;
+    color: slategrey;
+    font-weight: 500;
+    
+}
+</style>
+<template>
+    <a-row :gutter="10">
+        <a-spin :spinning="spinning">
+            <a-col :sm="6" style="margin-bottom: 20px; z-index: 10">
+                <a-card
+                style="min-height: 100px"
+                :style="{
+                    width: (clientWidth / 24) * 6 - 10 + 'px',
+                }"
+                >
+                    <video class="video" :src="url" controls="controls" style="width: 100%" v-if="url">
+                        您的浏览器不支持 video 标签。
+                    </video>
+                    <img :src="noImg" alt="" v-else style="width: 100%" />
+                </a-card>
+            </a-col>
+            <a-col :sm="18" style="margin-bottom: 20px; z-index: 10">
+                <a-card class="info-detail" style="min-height: 200px">
+                    <a-descriptions title="视频信息" v-if="materialInfo">
+                        <a-descriptions-item label="素材标题">
+                        {{ materialInfo.photoName ? materialInfo.photoName : '-' }}
+                        </a-descriptions-item>
+                        <a-descriptions-item label="素材唯一编码">
+                        {{ materialInfo.signature ? materialInfo.signature : '-' }}
+                        </a-descriptions-item>
+                        <a-descriptions-item label="素材状态">
+                        {{ materialInfo.status == 0 ? '可用' : '删除' }}
+                        </a-descriptions-item>
+                        <a-descriptions-item label="素材渠道">
+                        {{
+                            materialInfo.channelType == 0 ? '内部' : '素造'
+                        }}
+                        </a-descriptions-item>
+                        <a-descriptions-item label="上传时间">
+                        <span v-if="materialInfo.createTime">
+                            {{ materialInfo.createTime }}
+                        </span>
+                        <span v-else>-</span>
+                        </a-descriptions-item>
+                        <a-descriptions-item label="同步时间">
+                        {{ materialInfo.statDate ? materialInfo.statDate : '-' }}
+                        </a-descriptions-item>
+                        <a-descriptions-item label="编导">
+                        {{ materialInfo.planName ? (materialInfo.planName == '' ? '无' : materialInfo.planName) : '-' }}
+                        </a-descriptions-item>
+                        <a-descriptions-item label="拍摄">
+                        {{ materialInfo.shotName ? (materialInfo.shotName == '' ? '无' : materialInfo.shotName) : '-' }}
+                        </a-descriptions-item>
+                        <a-descriptions-item label="剪辑">
+                        {{ materialInfo.clipName ? (materialInfo.clipName == '' ? '无' : materialInfo.clipName) : '-' }}
+                        </a-descriptions-item>
+                    </a-descriptions>
+                </a-card>
+                <a-card style="min-height: 300px; margin: 10px 0" class="info-detail">
+                    <a-descriptions title="素材排期">
+                        <a-descriptions-item  :span="3">
+                            <span slot="label">
+                                <a-tooltip title="当前素材仅可在设置日期内进行投放,其他时段不会投放此素材">
+                                    <a-icon type="info-circle-o" />
+                                </a-tooltip>
+                                可用日期
+                            </span>
+                            <span  v-if="materialInfo&&materialInfo.putStartTime===''">
+                                不限
+                                <a @click="selectTime(null)">请选择</a>
+                            </span>
+                            <span  v-else-if="materialInfo&&materialInfo.putStartTime!==''">
+                                {{materialInfo.putStartTime+'~'+materialInfo.putEndTime}}
+                                <a @click="selectTime(materialInfo)">修改</a>
+                            </span>
+                            
+                        </a-descriptions-item>
+                    </a-descriptions>
+                    <div
+                        style="
+                        margin-bottom: 20px;
+                        color: rgba(0, 0, 0, 0.85);
+                        font-weight: bold;
+                        font-size: 16px;
+                        line-height: 1.5;
+                        "
+                    >
+                        素材定向
+                    </div>
+
+                    <div class="directional-border">
+                        <a-row class="title-border">
+                            <a-col :span="24" class="flex-main" style="justify-content: space-between;margin-bottom:0">
+                                <div>
+                                    <span class="ant-descriptions-item-label" style="color:black;font-weight:500"> 素材可用定向</span>
+                                </div>
+                                <a @click="addNewTemplate">编辑</a>
+                            </a-col>
+                        </a-row>
+                        <a-row style="margin-top:10px">
+                            <a-col :xl="12" :md="24" class="flex-main">
+                                <span class="ant-descriptions-item-label"> 地区:</span>
+                                <div v-if="directionalInfo">
+                                    <span v-if="directionalInfo.region == '' || directionalInfo.region == null||JSON.parse(directionalInfo.region).length==0"> 不限 </span>
+                                    <div v-else>
+                                        {{ region.join(',') }}
+                                    </div>
+                                </div>
+                                <p title="-" v-else>-</p>
+                            </a-col>
+                            <a-col :xl="12" :md="24" class="flex-main">
+                                <span class="ant-descriptions-item-label"> 年龄:</span>
+                                <div v-if="directionalInfo">
+                                    <span v-if="
+                                    (directionalInfo.agesRange == '[]' || directionalInfo.agesRange == null) &&
+                                    (directionalInfo.min == -1 || directionalInfo.min == null) &&
+                                    (directionalInfo.max == -1 || directionalInfo.max == null)"> 不限 </span>
+                                    <div v-else>
+                                        <span v-if="directionalInfo.agesRange == '[]' || directionalInfo.agesRange == null">
+                                        {{ directionalInfo.min + '岁~' + directionalInfo.max + '岁' }}
+                                        </span>
+                                        <span v-else>
+                                            <span v-for="(item, index) in JSON.parse(directionalInfo.agesRange)" :key="index">
+                                                {{ item | kuaishouAge }}{{ index == JSON.parse(directionalInfo.agesRange).length - 1 ? '' : ',' }}
+                                            </span>
+                                        </span>
+                                    </div>
+                                </div>
+                                <p title="-" v-else>-</p>
+                            </a-col>
+                        </a-row>
+                         <a-row>
+                            <a-col :xl="12" :md="24" class="flex-main">
+                                <span class="ant-descriptions-item-label"> 性别:</span>
+                                <div v-if="directionalInfo">
+                                     {{ directionalInfo.gender == 1 ? '女' : directionalInfo.gender == 2 ? '男' : '不限' }}
+                                </div>
+                                <p title="-" v-else>-</p>
+                            </a-col>
+                            <a-col :xl="12" :md="24" class="flex-main">
+                                <span class="ant-descriptions-item-label"> 最低版本:</span>
+                                <div v-if="directionalInfo">
+                                    {{ directionalInfo.platformOs == 1 
+                                    ? 'Android系统('+(directionalInfo.androidOsv==3?'不限)':directionalInfo.androidOsv+'x+)') : 
+                                    directionalInfo.platformOs == 2 ? 'IOS系统('+(directionalInfo.iosOsv==6?'不限)':directionalInfo.iosOsv+'x+)') : '不限' }}
+                                </div>
+                                <p title="-" v-else>-</p>
+                            </a-col>
+                        </a-row>
+                         <a-row>
+                            <a-col :xl="12" :md="24" class="flex-main">
+                                <span class="ant-descriptions-item-label"> 设备品牌:</span>
+                                <div v-if="directionalInfo">
+                                    <span v-if="directionalInfo.deviceBrand == '' || directionalInfo.deviceBrand == null ||JSON.parse(directionalInfo.deviceBrand).length == 0">
+                                        不限
+                                    </span>
+                                    <span v-else>
+                                        <span v-for="(item, index) in JSON.parse(directionalInfo.deviceBrand)" :key="index">
+                                            {{ item | deviceBrand }}{{ index == JSON.parse(directionalInfo.deviceBrand).length - 1 ? '' : ',' }}
+                                        </span>
+                                    </span>
+                                </div>
+                                <p title="-" v-else>-</p>
+                            </a-col>
+                            <a-col :xl="12" :md="24" class="flex-main">
+                                <span class="ant-descriptions-item-label"> 设备价格:</span>
+                                <div v-if="directionalInfo">
+                                    <span v-if="directionalInfo.devicePrice == '' || directionalInfo.devicePrice == null ||JSON.parse(directionalInfo.devicePrice).length == 0">
+                                        不限
+                                    </span>
+                                    <span v-else>
+                                        <span v-for="(item, index) in JSON.parse(directionalInfo.devicePrice)" :key="index">
+                                            {{ item | kuaishouPrice }}{{ index == JSON.parse(directionalInfo.devicePrice).length - 1 ? '' : ',' }}
+                                        </span>
+                                    </span>
+                                </div>
+                                <p title="-" v-else>-</p>
+                            </a-col>
+                        </a-row>
+                         <!-- <a-row>
+                            <a-col :xl="12" :md="24" class="flex-main">
+                                <span class="ant-descriptions-item-label"> APP行为:</span>
+                                <p title="-">-</p>
+                            </a-col>
+                            <a-col :xl="12" :md="24" class="flex-main">
+                                <span class="ant-descriptions-item-label"> 商业兴趣:</span>
+                                <p title="-">-</p>
+                            </a-col>
+                        </a-row> -->
+                         <a-row>
+                            <a-col :xl="12" :md="24" class="flex-main">
+                                <span class="ant-descriptions-item-label"> 网络环境:</span>
+                                <div v-if="directionalInfo">
+                                    {{ directionalInfo.network == 1 ? 'Wi-Fi' : directionalInfo.network == 2 ? '移动网络' : '不限' }}
+                                </div>
+                                <p title="-" v-else>-</p>
+                            </a-col>
+                             <a-col :xl="12" :md="24" class="flex-main">
+                                <span class="ant-descriptions-item-label"> 过滤已转换用户:</span>
+                                <div v-if="directionalInfo">
+                                    {{ directionalInfo.filterConvertedLevel | kuaishouFilterConvertedLevel }}
+                                </div>
+                                <p title="-" v-else>-</p>
+                            </a-col>
+                        </a-row>
+                         <a-row>
+                            <!-- <a-col :xl="12" :md="24" class="flex-main">
+                                <span class="ant-descriptions-item-label"> 兴趣视频用户:</span>
+                                <p title="-">-</p>
+                            </a-col> -->
+                            <a-col :xl="12" :md="24" class="flex-main">
+                                <span class="ant-descriptions-item-label"> 智能扩量:</span>
+                                <div v-if="directionalInfo">
+                                    {{ directionalInfo.isOpen == 0 ? '关闭' : '开启' }}
+                                </div>
+                                <p title="-" v-else>-</p>
+                            </a-col>
+                        </a-row>
+                         <!-- <a-row>
+                             <a-col :xl="12" :md="24" class="flex-main">
+                                <span class="ant-descriptions-item-label"> 网红类别:</span>
+                                <p title="-">-</p>
+                            </a-col>
+                        </a-row> -->
+                    </div>
+                </a-card>
+                <a-card style="min-height: 300px; margin: 10px 0">
+                    <div
+                        style="
+                        margin-bottom: 20px;
+                        color: rgba(0, 0, 0, 0.85);
+                        font-weight: bold;
+                        font-size: 16px;
+                        line-height: 1.5;
+                        "
+                    >
+                        素材已关联账户  
+                        <a-button type="primary" @click="lowerMaterial" :disabled="selectedRowKeysValue.length==0">下架素材</a-button>
+                    </div> 
+                    <a-table
+                        size="middle"
+                        :loading="loadingList"
+                        :columns="columns"
+                        :dataSource="dataList"
+                        bordered
+                        :scroll="{ x: 2000 }"
+                        :pagination="ipagination"
+                        :rowSelection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
+                    >
+
+                    </a-table>
+                </a-card>
+                <a-card style="min-height: 300px; margin: 10px 0">
+                    <div
+                        style="
+                        margin-bottom: 20px;
+                        color: rgba(0, 0, 0, 0.85);
+                        font-weight: bold;
+                        font-size: 16px;
+                        line-height: 1.5;
+                        "
+                    >
+                        素材关联被拒创意 
+                        <a-button type="primary" @click="visibleAgain = true;type = 'all'" :disabled="selectedRowKeysCreative.length==0||accountId==''||accountId==null||accountId==undefined">批量重提</a-button>
+                        <a-select
+                            show-search
+                            placeholder="请选择账户"
+                            option-filter-prop="children"
+                            style="width: 200px;margin-left:20px"
+                            :filter-option="filterOption"
+                            v-model="accountId"
+                            @change="handleChange"
+                            allowClear
+                        >
+                            <a-select-option v-for="(item,index) in accountList" :key="index"
+                            :value="item.accountId">
+                            {{item.authName}}
+                            </a-select-option>
+                        </a-select>
+                    </div> 
+
+                    <a-table
+                        size="middle"
+                        :loading="loadingCreative"
+                        :columns="columnsCreative"
+                        :dataSource="creativeList"
+                        bordered
+                        :pagination="ipaginationCreative"
+                        :rowSelection="{ selectedRowKeys: selectedRowKeysCreative, onChange: onSelectChangeCreative }"
+                    >
+                        <span slot="action"  slot-scope="text, record">
+                            <a  @click="again(record)">重提</a>
+                        </span>
+                        <span slot="coverUrl" slot-scope="text, record">
+                            <img :src="text" alt="" style="width:100px">
+                        </span>
+                    </a-table>
+                </a-card>
+            </a-col>
+        </a-spin>
+        <a-modal 
+            title="素材可用日期" 
+            v-model="timeVisible" 
+            :width="400" 
+            @ok="handleOk"
+            @cancel="timeVisible=false"
+            :confirmLoading="editTimeLoading"
+        >
+            <a-form layout="inline">
+                <a-form-item label="选择日期">
+                    <a-radio-group v-model="timeSelsetData" button-style="solid">
+                        <a-radio-button value="a">
+                            不限
+                        </a-radio-button>
+                        <a-radio-button value="b">
+                            指定日期
+                        </a-radio-button>
+                    </a-radio-group>
+                    
+                   
+                </a-form-item>
+                 <a-range-picker style="margin-top:15px" v-if="timeSelsetData === 'b'" format="YYYY-MM-DD" :disabled-date="disabledDate" v-model="dateRange">
+                    </a-range-picker>
+            </a-form>
+        </a-modal>
+        <a-modal title="一键重提" @cancel="handleClose" :visible="visibleAgain" @ok="handleOkAgain"
+            :confirmLoading="againLoading"
+            :width="650">
+            <a-form :form="form">
+                <a-form-item label="是否修改" :labelCol="{ lg: { span: 4 }, sm: { span: 6 } }"
+                :wrapperCol="{ lg: { span: 18 }, sm: { span: 18 } }">
+                <a-radio-group buttonStyle="solid" v-decorator="[
+                'type',
+                { initialValue: 0} ]">
+                    <a-radio-button :value="0">否</a-radio-button>
+                    <a-radio-button :value="1">是</a-radio-button>
+                </a-radio-group>
+                </a-form-item>
+                <a-form-item label="广告语" :labelCol="{ lg: { span: 4 }, sm: { span: 6 } }"
+                :wrapperCol="{ lg: { span: 18 }, sm: { span: 18 } }" v-if="getData('type')==1">
+                <a-input v-model="updateDescription" :max="10" :min="1" style="width:100%" @change="DescriptionChange">
+                </a-input>
+                </a-form-item>
+            </a-form>
+        </a-modal>
+        <templateModal ref="templateModal" @getData="getDirectionalInfo" />
+    </a-row>
+</template>
+
+<script>
+import { getAction, postAction } from '@/api/manage'
+import moment from 'moment'
+import $ from 'jquery'
+import qs from 'qs'
+import UploadToAli from '@femessage/upload-to-ali'
+import uploadFile from '@/components/uploadFile.vue'
+import { mapActions, mapGetters, mapState } from 'vuex'
+import templateModal from './components/templateModal';
+var echarts = require('echarts')
+export default {
+    name: 'online-training-list',
+    data() {
+        return {
+            accountId: undefined,
+            accountList: [],
+            type: 'one',
+            form: this.$form.createForm(this),
+            visibleAgain: false,
+            updateDescription: '',
+            noImg: require('@/assets/noImg.png'),
+            materialInfo: null,
+            dataView: null,
+            clientWidth: 1920,
+            spinning: false,
+            scrollTopAll: 0,
+            scrollTop: 124,
+            mediaId: 0,
+            url: JSON.parse(localStorage.getItem('materialDetail')).url,
+            timeVisible: false,
+            timeSelsetData: 'a',
+            dateRange: [],
+            editTimeLoading: false,
+            useDirectional: 'noUse',
+            directionalInfo: null,
+            region: [],
+            loadingList: false,
+            columns: [
+                {
+                    title: '账户名称',
+                    align: 'center',
+                    dataIndex: 'authName',
+                    fixed: 'left',
+                    width: 150,
+                    scopedSlots: {
+                        customRender: 'authName',
+                    },
+                },
+                {
+                    title: '账户id',
+                    align: 'center',
+                    dataIndex: 'accountId',
+                    fixed: 'left',
+                    width: 150,
+                    scopedSlots: {
+                        customRender: 'accountId',
+                    },
+                },
+                {
+                    title: '被拒创意',
+                    align: 'center',
+                    dataIndex: 'rejectCount',
+                    scopedSlots: {
+                        customRender: 'rejectCount',
+                    },
+                },
+                {
+                    title: '同步时间',
+                    align: 'center',
+                    dataIndex: 'statDate',
+                    scopedSlots: {
+                        customRender: 'statDate',
+                    },
+                },
+                {
+                    title: '关联创意数',
+                    align: 'center',
+                    dataIndex: 'creativeCount',
+                    scopedSlots: {
+                        customRender: 'creativeCount',
+                    },
+                },
+                {
+                    title: '消耗',
+                    align: 'center',
+                    dataIndex: 'charge',
+                    scopedSlots: {
+                        customRender: 'charge',
+                    },
+                },
+                {
+                    title: '封面曝光数',
+                    align: 'center',
+                    dataIndex: 'photoShow',
+                    scopedSlots: {
+                        customRender: 'photoShow',
+                    },
+                },
+                {
+                    title: '封面点击数',
+                    align: 'center',
+                    dataIndex: 'photoClick',
+                    scopedSlots: {
+                        customRender: 'photoClick',
+                    },
+                },
+                {
+                    title: '素材曝光数',
+                    align: 'center',
+                    dataIndex: 'aclick',
+                    scopedSlots: {
+                        customRender: 'aclick',
+                    },
+                },
+                {
+                    title: '行为数',
+                    align: 'center',
+                    dataIndex: 'bclick',
+                    scopedSlots: {
+                        customRender: 'bclick',
+                    },
+                },
+                {
+                    title: '封面点击率',
+                    align: 'center',
+                    dataIndex: 'photoClickRatio',
+                    scopedSlots: {
+                        customRender: 'photoClickRatio',
+                    },
+                },
+                {
+                    title: '行为率',
+                    align: 'center',
+                    dataIndex: 'actionRatio',
+                    scopedSlots: {
+                        customRender: 'actionRatio',
+                    },
+                },
+                {
+                    title: '平均千次封面曝光花费(元)',
+                    align: 'center',
+                    dataIndex: 'impression1kCost',
+                    scopedSlots: {
+                        customRender: 'impression1kCost',
+                    },
+                },
+                {
+                    title: '平均封面点击单价(元)',
+                    align: 'center',
+                    dataIndex: 'photoClickCost',
+                    scopedSlots: {
+                        customRender: 'photoClickCost',
+                    },
+                },
+                {
+                    title: '平均行为单价(元)',
+                    align: 'center',
+                    dataIndex: 'actionCost',
+                    scopedSlots: {
+                        customRender: 'actionCost',
+                    },
+                }
+
+            ],
+            dataList: [],
+            selectedRowKeys: [],
+            selectedRowKeysValue: [],
+            ipagination: {
+                current: 1,
+                pageSize: 10,
+                //   pageSizeOptions: ['10', '20', '30'],
+                showTotal: (total, range) => {
+                return range[0] + '-' + range[1] + ' 共' + total + '条'
+                },
+                showQuickJumper: true,
+                // showSizeChanger: true,
+                // pageSizeOptions: ['10', '30', '50'],
+                total: 0,
+                onChange: (current, pageSize) => {
+                    // 切换分页时的回调,
+                    // 当在页面定义change事件时,切记要把此处的事件清除,因为这两个事件重叠了,可能到时候会导致一些莫名的bug
+                    this.ipagination.current = current
+                    this.ipagination.pageSize = pageSize
+                    this.getAccountVideo();
+                },
+                total: 0,
+            },
+
+            creativeList: [],
+            loadingCreative: false,
+            columnsCreative: [
+                {
+                    title: '账户名称',
+                    align: 'center',
+                    dataIndex: 'authName',
+                    scopedSlots: {
+                        customRender: 'authName',
+                    },
+                },
+                {
+                    title: '账户ID',
+                    align: 'center',
+                    dataIndex: 'accountId',
+                    width:100,
+                    scopedSlots: {
+                        customRender: 'accountId',
+                    },
+                },
+                {
+                    title: '关联创意ID',
+                    align: 'center',
+                    dataIndex: 'creativeId',
+                    scopedSlots: {
+                        customRender: 'creativeId',
+                    },
+                },
+                {
+                    title: '创意名称',
+                    align: 'center',
+                    dataIndex: 'creativeName',
+                    scopedSlots: {
+                        customRender: 'creativeName',
+                    },
+                },
+                {
+                    title: '素材封面',
+                    align: 'center',
+                    dataIndex: 'coverUrl',
+                    scopedSlots: {
+                        customRender: 'coverUrl',
+                    },
+                },
+                {
+                    title: '广告语',
+                    align: 'center',
+                    dataIndex: 'description',
+                    scopedSlots: {
+                        customRender: 'description',
+                    },
+                },
+                {
+                    title: '被拒理由',
+                    align: 'center',
+                    dataIndex: 'reviewDetail',
+                    width:120,
+                    scopedSlots: {
+                        customRender: 'reviewDetail',
+                    },
+                },
+                {
+                    title: '操作',
+                    align: 'center',
+                    dataIndex: 'action',
+                    width: 50,
+                    scopedSlots: {
+                        customRender: 'action',
+                    },
+                },
+            ],
+            selectedRowKeysCreative: [],
+            selectedRowKeysValueCreative: [],
+            selectedOneKeysValueCreative: [],
+            againLoading: false,
+            ipaginationCreative: {
+                current: 1,
+                pageSize: 10,
+                //   pageSizeOptions: ['10', '20', '30'],
+                showTotal: (total, range) => {
+                return range[0] + '-' + range[1] + ' 共' + total + '条'
+                },
+                showQuickJumper: true,
+                // showSizeChanger: true,
+                // pageSizeOptions: ['10', '30', '50'],
+                total: 0,
+                onChange: (current, pageSize) => {
+                    // 切换分页时的回调,
+                    // 当在页面定义change事件时,切记要把此处的事件清除,因为这两个事件重叠了,可能到时候会导致一些莫名的bug
+                    this.ipaginationCreative.current = current
+                    this.ipaginationCreative.pageSize = pageSize
+                    this.getCreativeByVideo({})
+                },
+                total: 0,
+            },
+
+        }
+    },
+    components: {
+        UploadToAli,
+        uploadFile,
+        templateModal
+    },
+    watch: {
+    },
+    methods: {
+        filterOption(input, option) {
+            return (
+                option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
+            );
+        },
+        getData(className) {
+            return this.form.getFieldValue(className)
+        },
+        onSelectChange(selectedRowKeys, selectionRows) {
+            this.selectedRowKeys = selectedRowKeys
+            this.selectedRowKeysValue = selectionRows.map((item) => {
+                return item.accountId
+            })
+            //    this.selectedRowKeysValue.length > 0 ? this.selectedRowKeysValue :
+        },
+        onSelectChangeCreative(selectedRowKeys, selectionRows) {
+            this.selectedRowKeysCreative = selectedRowKeys
+            this.selectedRowKeysValueCreative = selectionRows.map((item) => {
+                return {
+                    description: item.description,
+                    creativeId: item.creativeId
+                }
+            })
+            //    this.selectedRowKeysValue.length > 0 ? this.selectedRowKeysValue :
+        },
+        getAccountVideo() {
+            this.loadingList = true;
+            var data = JSON.parse(localStorage.getItem('materialDetail'))
+            let params = {};
+            params.signature = data.md5;
+            params.projectId = data.projectId;
+            params.pageNo = this.ipagination.current;
+            params.pageSize = this.ipagination.pageSize;
+            this.getAction('/kuaishouProjectVideoGet/getAccountVideos', params).then(res => {
+                this.loadingList = false;
+                if(res.success) {
+                    this.dataList = res.result.list;
+                    this.ipagination.total = res.result.total;
+                }
+                else {
+                    this.dataList = [];
+                }
+            })
+        },
+        getCreativeByVideo() {
+            this.loadingCreative = true;
+            var data = JSON.parse(localStorage.getItem('materialDetail'))
+            let params = {};
+            params.signature = data.md5;
+            params.projectId = data.projectId;
+            params.pageNo = this.ipaginationCreative.current;
+            params.pageSize = this.ipaginationCreative.pageSize;
+            params.accountId = this.accountId;
+            this.getAction('/kuaishouProjectVideoGet/queryCreativeByVideo', params).then(res => {
+                this.loadingCreative = false;
+                if(res.success) {
+                    this.creativeList = res.result.list;
+                    this.ipaginationCreative.total = res.result.total;
+                }
+                else {
+                    this.creativeList = [];
+                }
+            })
+        },
+        addNewTemplate() {
+            if(this.directionalInfo) {
+                this.$refs.templateModal.handleOk(this.directionalInfo, 'edit')
+            }
+            else {
+                this.$refs.templateModal.create(null, 'add')
+            }
+           
+        },
+        disabledDate(current) {
+            // Can not select days before today and today
+            return current && current < moment().subtract(1, 'days')
+        },
+        getMaterialInfo() {
+            var data = JSON.parse(localStorage.getItem('materialDetail'))
+            this.spinning = true
+            var params = {
+                signature: data.md5,
+                id: data.id
+            }
+            this.getAction('/kuaishouProjectVideoGet/getVideoDetails', params).then((res) => {
+                if (res.success) {
+                    if (res.result) {
+                        this.materialInfo = res.result;
+                        this.spinning = false;
+                    } 
+                    else {
+                        this.$message.error(res.message);
+                    }
+                }
+            })
+        },
+        getDirectionalInfo() {
+            var data = JSON.parse(localStorage.getItem('materialDetail'))
+            var params = {
+                signature: data.md5,
+                id: data.id
+            }
+            this.getAction('/kuaishouVideoDirectionalPackage/queryDirctional', params).then((res) => {
+                if (res.success&&res.result) {
+                    this.directionalInfo = res.result;
+                    if (res.result&&(res.result.region == '' || res.result.region == null||JSON.parse(res.result.region).length==0)) {
+                    } else {
+                        this.showRegion(res.result.region)
+                    }
+                }
+                 else {
+                    this.$message.error(res.message);
+                }
+            })
+        },
+        showRegion(data) {
+            return new Promise((resolve, reject) => {
+                this.postDataAction('/kuaishou/batch/getRegionDetail', {
+                    regionArr: data,
+                }).then((res) => {
+                    if (res.success) {
+                        //   this.populationData.allForm.region = res.result
+                        this.region = res.result.map((item) => {
+                            return item.label
+                        })
+                    }
+                })
+            })
+        },
+        handleScroll() {
+            var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
+            this.scrollTop = scrollTop
+        },
+        handleChange() {
+            this.ipaginationCreative.current = 1;
+            this.selectedOneKeysValueCreative = [];
+            this.selectedRowKeysValueCreative = [];
+            this.selectedRowKeysCreative = [];
+            this.getCreativeByVideo();
+        },
+        selectTime(item) {
+            if(item) {
+                if(item.putStartTime!='') {
+                    this.timeSelsetData = 'b';
+                    this.dateRange = [moment(item.putStartTime), moment(item.putEndTime)];
+                } 
+                else {
+                    this.timeSelsetData = 'a';
+                    this.dateRange = [];
+                }
+            }
+            else {
+                this.timeSelsetData = 'a';
+                this.dateRange = [];
+            } 
+            this.timeVisible = true;
+            
+        },
+        handleOk() {
+            let data = JSON.parse(localStorage.getItem('materialDetail'))
+            this.editTimeLoading = true;
+            let params = {};
+            params.id = data.id
+            if(this.timeSelsetData === 'a') {
+                params.putStartTime = '';
+                params.putEndTime = '';
+            }
+            else {
+                if(this.dateRange.length === 0) {
+                    this.$message.error('请选择指定日期');
+                    this.editTimeLoading = false;
+                    return
+                }
+                params.putStartTime = moment(this.dateRange[0]).format('YYYY-MM-DD');
+                params.putEndTime = moment(this.dateRange[1]).format('YYYY-MM-DD');;
+            }
+            this.postDataAction('/kuaishouProjectVideoGet/edit', params).then(res => {
+                if(res.success) {
+                    this.editTimeLoading = false;
+                    this.$message.success('修改成功');
+                    this.timeVisible = false;
+                    this.getMaterialInfo();
+                }
+                else {
+                    this.editTimeLoading = false;
+                    this.$message.error(res.message);
+                }
+            })
+        },
+        lowerMaterial() {
+            let data = JSON.parse(localStorage.getItem('materialDetail'))
+            let params = {};
+            params.projectId = data.projectId;
+            params.accountId = this.selectedRowKeysValue;
+            params.signature = data.md5;
+            this.postDataAction('/kuaishouProjectVideoGet/offShelfVideos', params).then(res => {
+                if(res.success) {
+                    this.getAccountVideo();
+                    this.selectedRowKeysValue = [];
+                    this.selectedRowKeys = []
+                }
+            })
+            // /kuaishouProjectVideoGet/offShelfVideos
+        },
+        again(item) {
+            this.visibleAgain = true;
+            this.type = "one"
+            this.selectedOneKeysValueCreative = [{
+                description: item.description,
+                creativeId: item.creativeId,
+                accountId: item.accountId
+            }]
+        },
+        DescriptionChange(e) {
+            if (e.target.value.length > 30) {
+                this.$message.error('广告语最多30字!')
+            }
+        },
+        handleClose(e) {
+            this.visibleAgain = false;
+            this.updateDescription = '';
+            this.form.resetFields();
+        },
+        getAccountList() {
+            let data = JSON.parse(localStorage.getItem('materialDetail'))
+            let params = {};
+            params.projectId = data.projectId;
+            this.getAction('/ctop/userAllocation/queryAccountIdsByProjectId', params).then(res => {
+                if(res.success) {
+                    this.accountList = res.result;
+                }
+            })
+        },
+        handleOkAgain() {
+            if (this.updateDescription.length > 30 && this.getData('type') == 1) {
+                this.$message.error('广告语最多30个字,请修正后再次提交!')
+            } else {
+                this.againLoading = true
+                this.form.validateFields((err, values) => {
+                    if (!err) {
+                    values.updateDescription = this.updateDescription;
+                    var params = {
+                        ...values,
+                        accountId: this.type=='one'?this.selectedOneKeysValueCreative[0].accountId:this.accountId,
+                        creativeArr: this.type=='one'?this.selectedOneKeysValueCreative:this.selectedRowKeysValueCreative
+                    }
+                    this.postDataAction('/MaterialRefuse/batchUpdateCreative', params).then(res => {
+                        if (res.success) {
+                            // this.visibleFail = true
+                            this.visibleAgain = false;
+                            this.updateDescription = '';
+                            this.handleClose();
+                            this.selectedOneKeysValueCreative = [];
+                            this.selectedRowKeysValueCreative = [];
+                            this.selectedRowKeysCreative = [];
+                            this.ipaginationCreative.current = 1;
+                            this.getCreativeByVideo();
+                            this.againLoading = false;
+                            this.$message.success(res.message);
+                        } else {
+                            this.againLoading = false
+                            this.$message.error(res.message)
+                        }
+                    })
+                    }
+                })
+            }
+        }
+    },
+    mounted() {
+        this.$nextTick(() => {
+            //   this.mediaId = JSON.parse(localStorage.getItem('videoInfo')).mediaId
+            window.addEventListener('scroll', this.handleScroll);
+            this.clientWidth = document.documentElement.clientWidth - 224;
+            //   this.$route.query.mediaId
+            //   this.$route.query.md5
+            this.getMaterialInfo();
+            this.getDirectionalInfo();
+            this.getAccountVideo();
+            this.getCreativeByVideo();
+            this.getAccountList()
+
+        })
+    },
+    created() {},
+}
+</script>

+ 213 - 0
src/views/modules/autoLaunch/material-all/material-service.js

@@ -0,0 +1,213 @@
+/**
+ * @file 人群包管理基础服务
+ * @author jiayufei(jiayufei@c-top.com.cn)
+ */
+
+ class AppMarketService {
+    constructor() {}
+
+    // 相关账户的table列表
+    setAcountColumns() {
+        return [
+            {
+                title: '账户名称',
+                dataIndex: 'authName',
+                width: '50%',
+                align: 'center'
+            },
+            {
+                title: '编辑',
+                dataIndex: 'action',
+                scopedSlots: {customRender: 'action'},
+                width: '50%',
+                align: 'center'
+            }
+        ]
+    }
+
+    // 原因的table列表
+    setCauseColumns() {
+        return [
+            {
+                title: '账户名称',
+                dataIndex: 'authName',
+                width: '25%',
+                align: 'center'
+            },
+            {
+                title: '推送结果',
+                dataIndex: 'result',
+                width: '25%',
+                align: 'center'
+            },
+            {
+                title: '失败原因',
+                dataIndex: 'message',
+                width: '25%',
+                align: 'center',
+                customRender(t) {
+                    if(t === 'OK') {
+                        return '-';
+                    }
+                    else {
+                        return t;
+                    }
+                }
+            },
+            {
+                title: '操作',
+                dataIndex: 'action',
+                scopedSlots: {customRender: 'action'},
+                width: '25%',
+                align: 'center'
+            }
+        ]
+    }
+
+    // 相关项目的table列表
+    setDepColumns() {
+        return [
+            {
+                title: '广告组名称',
+                dataIndex: 'unitName',
+                width: '50%',
+                align: 'center'
+            },
+            {
+                title: '所属账户',
+                dataIndex: 'authName',
+                width: '50%',
+                align: 'center'
+            }
+        ]
+    }
+
+    // 状态枚举
+    setPlatform() {
+        return [
+            {
+                label: 0,
+                value: '不限'
+            },
+            {
+                label: 1,
+                value: 'Android'
+            },
+            {
+                label: 2,
+                value: 'IOS'
+            }
+        ]
+    }
+
+    // 上传人去报的校验规则
+    setPersonRules() {
+        return {
+            name: [
+                {required: true, message: '人群包名称不能为空', trigger: 'blur'},
+                {min: 1, max: 20, message: '人群包名称不能超过20个字符', trigger: 'blur'}
+            ],
+            resource: [
+                {required: true, message: '请选择匹配类型', trigger: 'change'}
+            ]
+        }
+    }
+
+    // 人群包类型枚举值
+    setPopulationTypeTasks() {
+        return [
+            {
+                label: 1,
+                value: '上传人群'
+            }, {
+                label: 2,
+                value: '广告人群'
+            }, {
+                label: 3,
+                value: '主题专区'
+            }, {
+                label: 4,
+                value: '逻辑规则'
+            }, {
+                label: 5,
+                value: '人群扩展'
+            }, {
+                label: 6,
+                value: '平台制定'
+            }, {
+                label: 7,
+                value: '定制付费'
+            }, {
+                label: 8,
+                value: '网红粉丝类别'
+            }, {
+                label: 9,
+                value: '内容付费行为'
+            }, {
+                label: 10,
+                value: '移动应用安装'
+            }, {
+                label: 11,
+                value: '快手使用活跃度'
+            }, {
+                label: 12,
+                value: '行业分类'
+            }, {
+                label: 13,
+                value: '商业兴趣'
+            }, {
+                label: 14,
+                value: '固话标签'
+            }, {
+                label: 15,
+                value: '行业偏好'
+            }, {
+                label: 16,
+                value: '第三方标签'
+            }, {
+                label: 17,
+                value: '产品关键词'
+            }, {
+                label: 19,
+                value: '应用渗透率'
+            }, {
+                label: 22,
+                value: '指定网红'
+            }, {
+                label: 23,
+                value: '行业分类'
+            }
+        ]
+    }
+
+    // 匹配类型枚举值
+    setMateTypeTasks() {
+        return [
+            {
+                label: 1,
+                value: 'IMEI'
+            }, {
+                label: 2,
+                value: 'IDFA'
+            }, {
+                label: 3,
+                value: 'IMEI_MD5'
+            }, {
+                label: 4,
+                value: 'IDFA_MD5'
+            }, {
+                label: 5,
+                value: '手机号-MD5'
+            }, {
+                label: 7,
+                value: 'OAID'
+            }, {
+                label: 8,
+                value: 'OAID_MD5'
+            }
+        ]
+    }
+
+}
+
+export default new AppMarketService();

+ 225 - 0
src/views/modules/autoLaunch/material-all/material.less

@@ -0,0 +1,225 @@
+.directional-content {
+    // background: #fff;
+    // height: calc(100vh - 137px);
+    // padding: 20px;
+    overflow: hidden;
+    /deep/.chart-card-content {
+        height: 0;
+    }
+    .middle-button {
+        margin: 0 8px;
+    }
+    .control-con-header {
+        margin-bottom: 20px;
+        position: relative;
+        /deep/ .ant-form-inline .ant-form-item > .ant-form-item-control-wrapper, .ant-form-inline .ant-form-item > .ant-form-item-label {
+            width: 200px !important;
+        }
+        .reset-class {
+            margin-right: 10px !important;
+        }
+        .upload-person {
+            position: absolute;
+            right: 10px;
+            top: 0;
+        }
+    }
+    .cause-text-class {
+        cursor: pointer;
+    }
+    .pagin-table-class {
+        display: flex;
+        justify-content: flex-end;
+        margin-top: 20px;
+    }
+    .acount-search-class {
+        width: 200% !important;
+    }
+    .grid-form-type {
+        margin-left: 210px;
+    }
+}
+/deep/ .push-modal {
+    width: 600px !important;
+    .acount-title {
+        display: flex;
+        font-size: 14px;
+        height: 40px;
+        line-height: 40px;
+        .acount-title-left {
+            margin-right: 20px;
+            width: 100px;
+        }
+    }
+    .push-plate {
+        margin-bottom: 20px;
+    }
+}
+.person-modal {
+    width: 500px;
+    /deep/ .ant-form-item {
+        display: flex;
+    }
+    /deep/ .ant-form-item-label {
+        width: 20%;
+    }
+    /deep/ .ant-form-item-control-wrapper {
+        width: 80%;
+    }
+    .acount-search-class {
+        width: 100% !important;
+    }
+    .upload-txt-rules {
+        margin-top: 10px;
+        margin-bottom: 10px;
+        line-height: 1.5;
+    }
+    /deep/ .ant-radio-group {
+        line-height: 30px;
+    }
+}
+/deep/ .cause-modal {
+    width: 600px !important;
+    .cause-modal-table-class {
+        height: 500px;
+        overflow-y: auto;
+    }
+    .pagin-table-class {
+        display: flex;
+        justify-content: flex-end;
+        margin-top: 20px;
+    }
+}
+/deep/ .relax-modal {
+    width: 600px !important;
+    .acount-title {
+        display: flex;
+        font-size: 14px;
+        height: 40px;
+        line-height: 40px;
+        .acount-title-left {
+            margin-right: 20px;
+            width: 100px;
+        }
+    }
+    .push-plate {
+        margin-bottom: 20px;
+    }
+}
+
+.grid-form-item-account {
+    /deep/ .ant-form-item-control {
+        line-height: inherit;
+    }
+}
+.material-total {
+    width: 100%;
+    min-height:100px;
+    margin-top:15px;
+    /deep/ .ant-card-body {
+        padding: 0;
+    }
+}
+.material-main {
+    width: 100%;
+    min-height:300px;
+    margin-top:15px;
+    .home-card {
+        width: 100%;
+        overflow: hidden;
+        padding: 10px 0px;
+        display: flex;
+        flex-wrap: wrap;
+        margin-left: 25px;
+        min-height: 300px;
+        .home-right {
+            width: 100%;
+        }
+      
+        .bg:after {
+            content: '';
+            width: 110%;
+            height: 110%;
+            position: absolute;
+            left: -5%;
+            top: -5%;
+            background: inherit;
+            filter: blur(10px);
+            z-index: 2;
+        }
+    }
+    .home-item {
+        overflow: hidden;
+        position: relative;
+        img {
+            width: 100%;
+            height: auto;
+        }
+        .bottom-details {
+            width: 100%;
+            height: 37%;
+            background: rgba(0, 0, 0, .7);
+            position: absolute;
+            bottom: 0;
+            left: 0;
+            z-index: 10;
+            padding: 10px;
+            .bottom-title {
+                display: flex;
+                justify-content: space-between;
+            }
+            h3 {
+                color: whitesmoke;
+                line-height: 25px;
+                width: 60%;
+                overflow: hidden; //超出的文本隐藏
+                text-overflow: ellipsis; //溢出用省略号显示
+                white-space: nowrap; //溢出不换行  
+            }
+            p {
+                color: whitesmoke;
+                line-height: 1;
+                width: 100%;
+                overflow: hidden; //超出的文本隐藏
+                text-overflow: ellipsis; //溢出用省略号显示
+                white-space: nowrap; //溢出不换行
+            }
+        }
+    }
+      
+    @media only screen and (min-width: 1200px) {
+        .home-item {
+            border-style: solid;
+            border-width: 1px;
+            border-color: #e4e4e4;
+            width: calc(25% - 50px);
+            padding: 10px;
+            margin-right: 50px;
+            margin-bottom: 10px;
+            display: flex;
+            align-items: center;
+            background: #fff;
+            position: relative;
+            z-index: 99;
+        }
+    }
+      
+    @media only screen and (min-width: 1530px) {
+        .home-item {
+            border-style: solid;
+            border-width: 1px;
+            border-color: #e4e4e4;
+            width: calc(20% - 50px);
+            padding: 10px;
+            margin-right: 50px;
+            margin-bottom: 10px;
+            display: flex;
+            align-items: center;
+            background: #fff;
+            position: relative;
+            z-index: 99;
+        }
+    }
+}
+
+

+ 310 - 0
src/views/modules/autoLaunch/material-all/material.vue

@@ -0,0 +1,310 @@
+<template>
+  <div class="directional-content">
+    <a-card style="width: 100%"> 
+        <div class="table-page-search-wrapper">
+            <a-form layout="inline"  :form="form"
+                hide-required-mark :selfUpdate="true" 
+                @submit="handleQueryList">
+                <a-row :gutter="24">
+                     <a-col :md="8" :sm="8" :xxl="6">
+                        <!-- <a-form-item label="项目名称"> -->
+                        <selectTable :projectId.sync="projectId" ref="selectTable" :requireCheck="false"></selectTable>
+                    </a-col>
+                    <a-col :md="8" :sm="8" :xxl="6">
+                        <a-form-item label="唯一编码">
+                            <a-input
+                                v-decorator="['signature']" type="text"
+                                placeholder="请输入想要搜索的素材md5"
+                            />
+                        </a-form-item>
+                    </a-col>
+                    <!--  -->
+                    <a-col :md="8" :sm="8" :xxl="6">
+                        <a-form-item label="素材状态">
+                            <a-select
+                                v-decorator="['status',{initialValue:''}]"
+                                placeholder="请选择"
+                                allow-clear
+                            >
+                                <a-select-option :value="''">不限</a-select-option>
+                                <a-select-option :value="0">可用</a-select-option>
+                                <a-select-option :value="1">删除</a-select-option>
+                            </a-select>
+                        </a-form-item>
+                    </a-col>
+                     <!--  -->
+                    <a-col :md="8" :sm="8" :xxl="6">
+                        <a-form-item label="素材渠道">
+                            <a-select
+                                v-decorator="['channelType',{initialValue:''}]"
+                                placeholder="请选择"
+                                allow-clear
+                            >
+                                <a-select-option :value="''">不限</a-select-option>
+                                <a-select-option :value="0">内部</a-select-option>
+                                <a-select-option :value="1">素造</a-select-option>
+                            </a-select>
+                        </a-form-item>
+                    </a-col>
+                    <a-col :md="8" :sm="8" :xxl="6">
+                        <span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
+                            <a-button type="primary" icon="search" @click="handleQueryList">查询</a-button>
+                            <a-button type="primary" @click="handleResetForm" icon="reload" class="middle-button">重置</a-button>
+                        </span>
+                        
+                    </a-col>
+                </a-row>
+            </a-form>
+        </div>
+    </a-card>
+    <a-row :gutter="24" class="material-total" v-if="totalData">
+        <a-col :sm="24" :md="12" :xl="6">
+            <chart-card title="素材总数" :total="totalData.total + ''">
+                <a-tooltip title="此项目可用的素材总数" slot="action">
+                    <a-icon type="info-circle-o" />
+                </a-tooltip>
+                <!-- <div slot="percentage">
+                    <trend :flag="costLink > 0 ? 'up' : 'down'">
+                        <span slot="term">环比</span>
+                        {{ (costLink * 100).toFixed(2) }}%
+                    </trend>
+                </div> -->
+            </chart-card>
+        </a-col>
+        <a-col :sm="24" :md="12" :xl="6">
+            <chart-card title="在投素材数" :total="totalData.yesterdayValidCount + ''">
+                <a-tooltip title="此项目昨日在投素材总数" slot="action">
+                    <a-icon type="info-circle-o" />
+                </a-tooltip>
+            </chart-card>
+        </a-col>
+        <a-col :sm="24" :md="12" :xl="6">
+            <chart-card title="今日同步素材数" :total="totalData.todayUpCount + ''">
+                <a-tooltip title="此项目今日同步素材数" slot="action">
+                    <a-icon type="info-circle-o" />
+                </a-tooltip>
+
+                <!-- <div slot="percentage">
+                    <trend :flag="totalData.todayUpCount >= totalData.yesterdayUpCount > 0 ? 'up' : 'down'">
+                        {{ totalData.todayUpCount - totalData.yesterdayUpCount === 0 ? '0' : ((totalData.todayUpCount - totalData.yesterdayUpCount)/totalData.yesterdayUpCount).toFixed(2) }}%
+                    </trend>
+                </div> -->
+            </chart-card>
+        </a-col>
+        <a-col :sm="24" :md="12" :xl="6">
+            <chart-card title="近一周同步素材数" :total="totalData.thisWeekCount + ''">
+                <a-tooltip title="此项目近一周同步素材数" slot="action">
+                    <a-icon type="info-circle-o" />
+                </a-tooltip>
+                <div slot="percentage">
+                    <trend :flag="totalData.thisWeekCount >= totalData.lastWeekCount > 0 ? 'up' : 'down'">
+                        <!-- <span slot="term">环比</span> -->
+                        {{ totalData.thisWeekCount - totalData.lastWeekCount === 0 ? '0' : (((totalData.thisWeekCount - totalData.lastWeekCount)/totalData.lastWeekCount)*100).toFixed(2) }}%
+                    </trend>
+                </div>
+            </chart-card>
+        </a-col>
+    </a-row>
+    <a-card  class="material-main">
+        <a-spin :spinning="spinning">
+            <div v-if="dataSource.length > 0">
+                <div  class="home-card">
+                    <div class="home-item" v-for="(items, index) in dataSource" :key="index" @click="lookView(items)">
+                        <img :src="items.coverUrl" alt="">
+                        <div class="bottom-details">
+                            <div class="bottom-title">
+                                <h3 :title="items.photoName">{{ items.photoName ? items.photoName : '-' }}</h3>
+                                <a @click.stop="lowerMaterial(items)" :disabled="items.status === 1">下架素材</a>
+                            </div>
+                            <p>素材来源:{{ items.channelType === 0 ? '内部' : '素造' }}</p>
+                            <p :title="items.statDate">上传日期:{{ items.statDate }}</p>
+                            <p>素材状态:{{ items.status === 0 ? '可用' : '删除' }}</p>
+                            <p></p>
+                        </div>
+                    </div>
+                </div>
+           
+                <a-pagination
+                size="small"
+                :showTotal="ipagination.showTotal"
+                style="float: right"
+                v-if="dataSource.length > 0"
+                showQuickJumper
+                :pageSize.sync="ipagination.pageSize"
+                :total="ipagination.total"
+                v-model="ipagination.current"
+                @change="getDataSource"
+                />
+            </div>
+            <div v-else class="home-card" style="justify-content: center;align-items: center;">
+                <a-empty />
+            </div>
+        </a-spin>
+    </a-card>
+    <a-modal title="查看视频" v-model="visibleVideo" :width="400" :footer="null">
+        <video class="video" :src="videoUrlShow" controls="controls" style="width: 100%">
+            您的浏览器不支持 video 标签。
+        </video>
+    </a-modal>
+  </div>
+</template>
+
+<script>
+import moment from 'moment';
+import selectTable from '@/views/modules/Statistics/components/selectPagination.vue';
+import ChartCard from '@/components/ChartCard';
+import Trend from '@/components/Trend';
+import { stopOtherVideo, closeAllVideoFun } from '@/utils/videoControl'; // 停止除当前外的其他视频播放,及停止所有视频播放的方法
+export default {
+    components: {
+        selectTable,
+        ChartCard,
+        Trend
+    },
+    data() {
+        return {
+            visibleVideo: false,
+            videoUrlShow: null,
+            spinning: false,
+            form: this.$form.createForm(this),
+            projectId: '',
+            dataSource: [],
+            dataLoading: false,
+            ipagination: {
+                current: 1,
+                pageSize: 10,
+                //   pageSizeOptions: ['10', '20', '30'],
+                showTotal: (total, range) => {
+                    return range[0] + "-" + range[1] + " 共" + total + "条"
+                },
+                showQuickJumper: true,
+                showSizeChanger:false,
+                pageSizeOptions: ['10', '30', '50'],
+                total: 0,
+                onChange: (current, pageSize) => {
+                    // 切换分页时的回调,
+                    // 当在页面定义change事件时,切记要把此处的事件清除,因为这两个事件重叠了,可能到时候会导致一些莫名的bug
+                    this.ipagination.current = current;
+                    this.ipagination.pageSize= pageSize;
+                    this.handleGetTableList({})
+                }
+            },
+            totalData: null
+        }
+    },
+    watch: {
+        visibleVideo(n, o) {
+            if (!n) {
+                closeAllVideoFun()
+            }
+        },
+    },
+    methods: {
+        lowerMaterial(item) {
+            let params = {};
+            params.id = item.id;
+            let that = this
+            this.$confirm({
+                title: '下架提示',
+                content: '是否下架此素材?',
+                onOk() {
+                    that.postDataAction('/kuaishouProjectVideoGet/offShelfVideo', params).then(result => {
+                        if(result.success) {
+                            that.$message.success('下架成功')
+                            that.handleGetTableList({})
+                        }
+                        else {
+                            that.$message.error(result.message)
+                        }
+                    }).catch(error => {
+                        console.log(error, 'eeee');
+                    });
+                }
+            });
+        },
+        lookView(item) {
+            // this.visibleVideo = true
+            // this.videoUrlShow = item.url
+            var params = { md5: item.signature, url:item.url, id:item.id, photoId:item.photoId, projectId:item.projectId }
+            localStorage.setItem('materialDetail', JSON.stringify(params))
+            this.$router.push({
+                path: '/autoLaunch/material-all/material-detail',
+            })
+        },
+        getDataSource(current, pageSize) {
+            // 切换分页时的回调,
+            // 当在页面定义change事件时,切记要把此处的事件清除,因为这两个事件重叠了,可能到时候会导致一些莫名的bug
+            this.ipagination.current = current;
+            this.ipagination.pageSize= pageSize;
+            const paramsData = this.form.getFieldsValue();
+            this.handleGetTableList(paramsData);
+        },
+        handleQueryList() {
+            this.ipagination.current = 1;
+            event.preventDefault();
+            const paramsData = this.form.getFieldsValue();
+            this.handleGetTableList(paramsData);
+            this.getVideoTotalNumber();
+        },
+        handleResetForm() {
+            this.totalData = null;
+            this.ipagination.current = 1;
+            this.form.resetFields();
+            this.projectId = undefined;
+            this.handleGetTableList({});
+            this.$refs.selectTable.keyValue = "";
+            this.$refs.selectTable.getData()
+        },
+        handleGetTableList(data) {
+            this.spinning = true;
+            const paramsData = {
+                signature: data.signature,
+                projectId: this.projectId,
+                status: data.status,
+                channelType: data.channelType,
+
+                pageNo:  this.ipagination.current,
+                pageSize: this.ipagination.pageSize
+            };
+            this.dataSource = []
+            this.dataLoading = true;
+            this.getAction('/kuaishouProjectVideoGet/list', paramsData).then(result => {
+                this.dataLoading = false;
+                this.spinning = false;
+                if (result.code === 200) {
+                    this.dataSource = result.result.list || [];
+                    this.ipagination.total = result.result.total || 0;
+                }
+                else {
+                    this.$message.error(result.message);
+                }
+            }).catch(error => {
+                this.spinning = false;
+                this.dataLoading = false;
+                console.log(error, 'eeee');
+            });
+        },
+        getVideoTotalNumber() {
+            if(this.projectId !== '') {
+                let params = {};
+                params.projectId = this.projectId;
+                this.getAction('/kuaishouProjectVideoGet/getVideoTotalNumber', params).then(res => {
+                    if(res.success) {
+                        this.totalData = res.result;
+                    }
+                    else {
+                        this.totalData = null;
+                    }
+                })
+            }
+            
+        }
+    },
+    mounted() {
+        this.handleGetTableList({});
+    },
+}
+</script>
+<style lang="less" scoped>
+    @import "material";
+</style>

+ 4 - 4
src/views/modules/autoLaunch/material-pool/material.vue

@@ -37,10 +37,10 @@ export default {
                     key: 'url',
                     tab: '落地页管理',
                 },
-                // {
-                //     key: 'application',
-                //     tab: '应用包管理',
-                // },
+                {
+                    key: 'application',
+                    tab: '应用包管理',
+                },
             ], 
         }
     },

+ 1 - 0
src/views/modules/autoLaunch/url/components/tree-select.vue

@@ -142,6 +142,7 @@ export default {
             }
             defaultCheckKey.splice(value, 1);
             this.checkedKeys = defaultCheckKey;
+            this.$emit('applyType', this.applyTypeOption);
         },
         onChange(e) {
             const value = e.target.value;

+ 3 - 3
src/views/modules/copy-library/copy-library-server.js

@@ -3,8 +3,8 @@
  * @author jiayufei
  */
 
-// export const urlAcount = 'http://118.24.244.213:8080'; // 线上
+export const urlAcount = 'http://118.24.244.213:8808'; // 线上
 // export const urlAcount = 'http://apipre.tjyourong.com.cn'; // 预生产
 // export const urlAcount = 'http://192.168.1.43:8080'; // 子安
-// export const urlAcount = 'http://139.186.165.84:8080'; // 测试
-export const urlAcount = 'http://192.168.1.8:8080'; // 学超
+// export const urlAcount = 'http://139.186.165.84:8808'; // 测试
+// export const urlAcount = 'http://192.168.1.8:8080'; // 学超

+ 7 - 3
src/views/modules/copy-library/copy-library.less

@@ -6,11 +6,15 @@
     .control-con-header {
         margin-bottom: 20px;
         position: relative;
-        .common-input-long {
-            width: 320px;
+        .grid-form-options {
+            margin-top: 15px;
         }
+        .common-input-long,
         .acount-search-class {
-            width: 450px;
+            width: 625px;
+        }
+        .common-input-long {
+            margin-left: 10px;
         }
         .reset-class {
             margin-right: 10px !important;

+ 492 - 117
src/views/modules/copy-library/copy-library.vue

@@ -7,23 +7,29 @@
                 :form="form"
                 hide-required-mark
             >
-                <a-row class="grid-form-options">
+                <a-row>
                     <a-form-item
                         v-if="controlTypeModel === '1'"
                         class="grid-form-item"
                         label="账户:"
                         :colon="false"
                     >
-                        <acount-search class="acount-search-class" :appId.sync="configForm.acountId" :multiple="false" request="1,3"></acount-search>
+                        <acount-search
+                            class="acount-search-class"
+                            :appId.sync="configForm.acountId"
+                            :multiple="false"
+                            request="1,3"
+                        >
+                        </acount-search>
                     </a-form-item>
                     <a-form-model-item v-if="controlTypeModel === '2'" label="项目:">
                         <a-select
                             class="common-input-long"
                             show-search
                             v-model="configForm.adConvertId"
-                            placeholder="请选择"
                             :filter-option="filterOption"
                             allowClear
+                            placeholder="请选择项目"
                         >
                             <a-select-option
                                 v-for="(item, index) in optimizationOption"
@@ -34,6 +40,8 @@
                             </a-select-option>
                         </a-select>
                     </a-form-model-item>
+                </a-row>
+                <a-row class="grid-form-options">
                     <a-form-item
                         class="grid-form-item"
                         label="关键词:"
@@ -49,18 +57,26 @@
                         <a-range-picker
                             v-model="configForm.launchDateRange"
                             format="YYYY-MM-DD"
+                            :disabled-date="disabledDate"
                             @change="handleLaunchData"
                         />
                     </a-form-item>
+                    <a-form-item v-show="configForm.acountId || configForm.adConvertId" label="状态">
+                        <a-select v-model="configForm.searchStatus" style="width: 100px">
+                            <a-select-option :value="2">不限</a-select-option>
+                            <a-select-option :value="0">已删除</a-select-option>
+                            <a-select-option :value="1">可投放</a-select-option>
+                        </a-select>
+                    </a-form-item>
                     <a-form-item class="form-handle-btn">
                         <a-button type="default" class="reset-class" @click="handleResetList">重置</a-button>
                         <a-button type="primary" @click="handleQueryList">查询</a-button>
                     </a-form-item>
                 </a-row>
             </a-form>
-            <a-button type="primary" class="upload-person" @click="handleAddAccountConfig">新增文案</a-button>
         </div>
         <div class="control-con-table">
+            <a-button type="primary" class="upload-person" @click="handleAddAccountConfig">新增文案</a-button>
             <a-tabs v-model="controlTypeModel" @change="handleTabsChange">
                 <a-tab-pane key="1" tab="通用">
                     <a-table
@@ -72,6 +88,11 @@
                         :pagination="false"
                         :scroll="{x: 1500}"
                     >
+                        <span slot="currencyAction" slot-scope="text, record">
+                            <a :disabled="record.status === '已删除'" @click="handleCurrencyEdit(record)">编辑</a>
+                            <a-divider type="vertical"/>
+                            <a :disabled="record.status === '已删除'" @click="handleCurrencyDelete(record)">删除</a>
+                        </span>
                     </a-table>
                     <a-pagination
                         class="pagin-table-class"
@@ -96,6 +117,11 @@
                         :pagination="false"
                         :scroll="{x: 1500}"
                     >
+                        <span slot="appointAction" slot-scope="text, record">
+                            <a :disabled="record.status === '已删除'" @click="handleCurrencyEdit(record)">编辑</a>
+                            <a-divider type="vertical"/>
+                            <a :disabled="record.status === '已删除'" @click="handleAppointDelete(record)">删除</a>
+                        </span>
                     </a-table>
                     <a-pagination
                         class="pagin-table-class"
@@ -114,7 +140,7 @@
         </div>
         <a-modal
             v-if="causeVisible"
-            title="新建文案"
+            :title="copywritingType === 'add' ? '新建文案' : '编辑文案'"
             dialog-class="copywrit-modal"
             :visible="causeVisible"
             @ok="handleCauseSure"
@@ -126,12 +152,8 @@
                     <div class="acount-title-right">
                         <div class="only-title-mater">
                             <a-radio-group v-model="copywrittypeName" button-style="solid" @change="handleFormLayoutChange">
-                                <a-radio-button value="horizontal">
-                                    通用
-                                </a-radio-button>
-                                <a-radio-button value="vertical">
-                                    指定素材
-                                </a-radio-button>
+                                <a-radio-button value="horizontal" :disabled="copywritingEditList.controlTypeModel === '2'">通用</a-radio-button>
+                                <a-radio-button value="vertical" :disabled="copywritingEditList.controlTypeModel === '1'">指定素材</a-radio-button>
                             </a-radio-group>
                         </div>
                     </div>
@@ -140,19 +162,19 @@
                     <div class="acount-title-left">广告账户</div>
                     <div class="acount-title-right">
                         <div class="only-title-mater">
-                            <acount-search :appId.sync="advertisingAccount" request="1,3"></acount-search>
+                            <acount-search :appId.sync="advertisingAccount" request="1,3" :disabled="copywritingType === 'edit'"></acount-search>
                         </div>
                     </div>
                 </div>
-                <div v-if="copywrittypeName === 'horizontal'" class="acount-title">
+                <div v-if="copywrittypeName === 'horizontal' && copywritingType === 'add'" class="acount-title">
                     <div class="acount-title-left">文件上传</div>
                     <div class="acount-title-right">
                         <div class="only-title-mater">
                             <a-upload
                                 name="file"
-                                action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
                                 :file-list="fileList"
-                                @change="handleChange"
+                                :customRequest="handleCustomRequest"
+                                :remove="handleRemoveUpload"
                             >
                                 <a-button><a-icon type="upload"/>文件上传</a-button>
                             </a-upload>
@@ -163,7 +185,7 @@
                     <div class="acount-title-left">选择素材</div>
                     <div class="acount-title-right">
                         <div class="only-title-mater">
-                            <div><a @click="handleSelectMaterial">选择素材</a></div>
+                            <div v-if="copywritingType === 'add'"><a @click="handleSelectMaterial">选择素材</a></div>
                             <div class="title-mater-list">
                                 <p
                                     class="mater-list-name"
@@ -171,20 +193,21 @@
                                     :key="item.id"
                                 >
                                     <span class="mater-list-show">{{ item.materialName }}</span>
-                                    <span class="mater-list-icon" @click="handleDelAlone(item)"><a-icon type="close"/></span>
+                                    <span class="mater-list-show">123</span>
+                                    <span v-if="copywritingType === 'add'" class="mater-list-icon" @click="handleDelAlone(item)"><a-icon type="close"/></span>
                                 </p>
                             </div>
                         </div>
                     </div>
                 </div>
-                <div v-if="copywrittypeName === 'vertical'" class="acount-title push-plate">
+                <div v-if="copywrittypeName === 'vertical' && copywritingType === 'add'" class="acount-title push-plate">
                     <div class="acount-title-left">创意标题</div>
                     <div class="acount-title-right">
                         <a-button type="primary" @click="handleAddOrigin"><a-icon type="plus" />创意标题</a-button>
                         <span style="margin-left: 20px;">已填:{{ titleFiledResult.length || 0 }}</span>
                     </div>
                 </div>
-                <div v-if="copywrittypeName === 'vertical'" class="acount-title">
+                <div v-if="copywrittypeName === 'vertical' && copywritingType === 'add'" class="acount-title">
                     <div class="acount-title-left"></div>
                     <div class="acount-title-right">
                         <a-form :form="examinForm">
@@ -231,8 +254,69 @@
                                             + {{ val.name }}
                                         </a-tag>
                                     </div>
-                                    <div v-if="item.tabStatus === 'alone'"><a @click="handleMoreTagsShow(item.id, 'more')">更多</a></div>
-                                    <div v-if="item.tabStatus === 'all'"><a @click="handleMoreTagsShow(item.id, 'little')">收起</a></div>
+                                    <div v-if="item.tabStatus === 'alone'">
+                                        <a @click="handleMoreTagsShow(item.id, 'more')">更多</a>
+                                    </div>
+                                    <div v-if="item.tabStatus === 'all'">
+                                        <a @click="handleMoreTagsShow(item.id, 'little')">收起</a>
+                                    </div>
+                                </div>
+                            </a-form-item>
+                        </a-form>
+                    </div>
+                </div>
+                <div v-if="copywritingType === 'edit'" class="acount-title push-plate">
+                    <div class="acount-title-left">创意标题</div>
+                    <div class="acount-title-right">
+                        <a-form :form="examinForm">
+                            <a-form-item
+                                v-for="item in defaultFormList"
+                                :key="item.id"
+                                class="examin-form-model"
+                                :label-col="labelCol"
+                                :wrapper-col="wrapperCol"
+                                label=""
+                            >
+                                <a-input
+                                    v-decorator="[
+                                        item.name,
+                                        {rules: [
+                                            {validator: validatePass, trigger: 'blur'}
+                                        ]}
+                                    ]"
+                                    class="examin-form-input"
+                                    :id="item.name"
+                                    placeholder="请输入"
+                                    @change="handleFormInputChang($event, item.name, item.id)"
+                                />
+                                <span class="examin-form-num">{{ item.lenSize }}/30</span>
+                                <div class="ad-name-tags-class">
+                                    <div v-if="item.tabStatus === 'alone'" class="name-tags-left">
+                                        <a-tag
+                                            v-for="val in item.updateTagsList"
+                                            :key="val.id"
+                                            color="#1890ff"
+                                            @click="handleGetChangeAll(val.name, item.name, item.id)"
+                                        >
+                                            + {{ val.name }}
+                                        </a-tag>
+                                    </div>
+                                    <div v-if="item.tabStatus === 'all'" class="name-tags-left">
+                                        <a-tag
+                                            v-for="val in item.defaultTagsList"
+                                            :key="val.id"
+                                            color="#1890ff"
+                                            @click="handleGetChangeAll(val.name, item.name, item.id)"
+                                        >
+                                            + {{ val.name }}
+                                        </a-tag>
+                                    </div>
+                                    <div v-if="item.tabStatus === 'alone'">
+                                        <a @click="handleMoreTagsShow(item.id, 'more')">更多</a>
+                                    </div>
+                                    <div v-if="item.tabStatus === 'all'">
+                                        <a @click="handleMoreTagsShow(item.id, 'little')">收起</a>
+                                    </div>
                                 </div>
                             </a-form-item>
                         </a-form>
@@ -301,7 +385,6 @@
                             </a-checkbox>
                             <img :src="item.coverUrl"/>
                             <div class="checkbox-select-time">时间:{{ item.createTime }}</div>
-                            <!-- <div class="checkbox-select-show"><a>查看视频</a></div> -->
                         </li>
                     </a-checkbox-group>
                     <a-pagination
@@ -324,17 +407,11 @@
 <script>
 import AcountSearch from '@/views/modules/Statistics/components/Treeselect.vue';
 
-import {getAction, postFileAction, postAction} from '@/api/manage';
-import {fileCheck, fileEdit, fileEditAll, fileInsertV2, fileEditUpdate, fileEditUpdateBatch} from '@/api/actor';
+import moment from 'moment';
+import {getAction, postFileAction, postAction, deleteAction} from '@/api/manage';
 import {mapGetters} from 'vuex';
 import {urlAcount} from './copy-library-server.js';
 
-let COS = require('cos-js-sdk-v5');
-let cos = new COS({
-    SecretId: 'AKIDE6IpMi8fJQRCg1iuWzFajjRs43kbbets',
-    SecretKey: 'tXzuwMfplTTK3c9GFUyETilasvQfePu9'
-});
-
 export default {
     name: 'copy-library',
     components: {
@@ -342,6 +419,9 @@ export default {
     },
     data() {
         return {
+            moment,
+            copywritingEditList: {},
+            copywritingType: 'add',
             projectModelValue: '',
             optimizationOption: [], // 账户option
             controlTypeModel: '1',
@@ -349,43 +429,7 @@ export default {
             modalSelectMaterial: [],
             materTotalAll: 0,
             viedoCheckValue: [],
-            viedoDefaultList: [
-                {
-                    name: '北京市',
-                    id: 1,
-                    statDate: '2019-08-08'
-                },
-                {
-                    name: '上海市',
-                    id: 2,
-                    statDate: '2019-08-08'
-                },
-                {
-                    name: '天津市',
-                    id: 3,
-                    statDate: '2019-08-08'
-                },
-                {
-                    name: '武汉市',
-                    id: 4,
-                    statDate: '2019-08-08'
-                },
-                {
-                    name: '贵州市',
-                    id: 5,
-                    statDate: '2019-08-08'
-                },
-                {
-                    name: '太原市',
-                    id: 6,
-                    statDate: '2019-08-08'
-                },
-                {
-                    name: '大同市',
-                    id: 7,
-                    statDate: '2019-08-08'
-                }
-            ],
+            viedoDefaultList: [],
             visibleMatemal: false,
             advertisingAccount: [],
             copywrittypeName: 'horizontal',
@@ -408,8 +452,9 @@ export default {
             configForm: {
                 acountId: '',
                 num: '',
-                adConvertId: '',
-                launchDateRange: []
+                adConvertId: undefined,
+                launchDateRange: [],
+                searchStatus: 2
             },
             currencyPag: {
                 page: 1,
@@ -424,6 +469,12 @@ export default {
                     width: 200,
                     dataIndex: 'textCopywriter'
                 },
+                // {
+                //     title: '状态',
+                //     align: 'center',
+                //     width: 150,
+                //     dataIndex: 'status'
+                // },
                 {
                     title: '相关创意',
                     align: 'center',
@@ -501,6 +552,12 @@ export default {
                     width: 200,
                     dataIndex: 'slogan'
                 },
+                // {
+                //     title: '状态',
+                //     align: 'center',
+                //     width: 150,
+                //     dataIndex: 'status'
+                // },
                 {
                     title: '相关创意',
                     align: 'center',
@@ -580,10 +637,11 @@ export default {
             masterPag: {
                 page: 1,
                 size: 10
-            },
+            }, 
             defaultFormList: [],
             titleFiledResult: 0,
             examinForm: this.$form.createForm(this),
+            changeShowmasterData: [],
             masterTimes: [] // 选择素材的时间选择
         };
     },
@@ -615,6 +673,135 @@ export default {
     },
     methods: {
         ...mapGetters(['nickname', 'avatar', 'userInfo']),
+        handleGetEditProjectList(data) {
+            const paramsData = {
+                slogan: data.slogan,
+                projectId: data.projectId
+            };
+            getAction(urlAcount + '/bytedance-api/ctop/bytedanceVideoSlogenInfo/queryBySlogenAndProjectId', paramsData).then(result => {
+                if (result.code === 0) {
+                    const defaultData = result.result.materialNameArray;
+                    const updateData = [];
+                    defaultData.forEach((item, index) => {
+                        updateData.push({
+                            id: index + 1,
+                            materialName: item
+                        });
+                    });
+                    this.modalSelectMaterial = [...updateData];
+                }
+                else {
+                    that.$message.error(result.message);
+                }
+            }).catch(error => {
+                console.log(error, 'eeee');
+            });
+        },
+        handleCurrencyEdit(data) {
+            const defaultData = data;
+            defaultData.controlTypeModel = this.controlTypeModel;
+            if (this.controlTypeModel === '1') {
+                this.advertisingAccount[0] = defaultData.accountId;
+            }
+            if (this.controlTypeModel === '2') {
+                this.$nextTick(() => {
+                    this.handleGetEditProjectList(defaultData);
+                });
+            }
+            this.causeVisible = true;
+            this.copywritingType = 'edit';
+            this.copywrittypeName = this.controlTypeModel === '1' ? 'horizontal' : 'vertical';
+            this.copywritingEditList = defaultData;
+            this.$nextTick(() => {
+                let changeValue = this.controlTypeModel === '1' ? data.textCopywriter : data.slogan;
+                let finallyLenList = this.handleJudgeExec(changeValue);
+                let newOptionList = [];
+                finallyLenList.forEach(item => {
+                    this.adNameTags.forEach(val => {
+                        if (item === val.name) {
+                            newOptionList.push(val);
+                        }
+                    });
+                });
+                let resultSelectSize = 0;
+                if (newOptionList.length) {
+                    const inputDefaultLen = this.handleExportRules(changeValue);
+                    let tagsLen = newOptionList.length * 2;
+                    let tagsSureLen = 0;
+                    newOptionList.forEach(item => {
+                        this.adNameTags.forEach(val => {
+                            if (item.name === val.name) {
+                                tagsSureLen += val.maxWordLen;
+                            }
+                        });
+                    });
+                    finallyLenList.forEach(item => {
+                        tagsLen += item.length;
+                    });
+                    resultSelectSize = inputDefaultLen - tagsLen + tagsSureLen + newOptionList.length;
+                }
+                else {
+                    resultSelectSize = this.handleExportRules(changeValue);
+                }
+                const defaultList = this.adNameTags;
+                const randomNum = new Date().getTime() + Math.ceil(Math.random() * 1000);
+                this.defaultFormList.push({
+                    id: randomNum,
+                    name: 'username' + randomNum,
+                    value: changeValue,
+                    lenSize: resultSelectSize,
+                    tabStatus: 'alone',
+                    defaultTagsList: defaultList,
+                    updateTagsList: defaultList.slice(0, 4)
+                });
+            });
+        },
+        handleCurrencyDelete(data) {
+            let that = this;
+            this.$confirm({
+                content: '确定是否删除该条文案',
+                iconType: 'exclamation-circle',
+                onOk() {
+                    deleteAction(urlAcount + '/bytedance-api/advertiser/bytedanceGeneralCopywriter/delete', {id: data.id}).then(result => {
+                        if (result.code === 0) {
+                            that.handleGetCurrencyList();
+                            that.$message.success('删除成功');
+                        }
+                        else {
+                            that.$message.error(result.message);
+                        }
+                    }).catch(error => {
+                        console.log(error, 'eeee');
+                    });
+                }
+            });
+        },
+        handleAppointDelete(data) {
+            let that = this;
+            this.$confirm({
+                content: '确定是否删除该条文案',
+                iconType: 'exclamation-circle',
+                onOk() {
+                    deleteAction(urlAcount + '/bytedance-api/ctop/bytedanceVideoSlogenInfo/deleteBySlogenAndProjectId', {
+                        slogan: data.slogan,
+                        projectId: data.projectId
+                    }).then(result => {
+                        if (result.code === 0) {
+                            that.handleGetAppointList();
+                            that.$message.success('删除成功');
+                        }
+                        else {
+                            that.$message.error(result.message);
+                        }
+                    }).catch(error => {
+                        console.log(error, 'eeee');
+                    });
+                }
+            });
+        },
+        disabledDate(current) {
+            return current > moment().subtract(1, 'day');
+        },
         handleRefreshMaster() {
             this.projectModelValue = '';
             this.masterTimes = [];
@@ -646,6 +833,7 @@ export default {
                 projectId: this.projectModelValue,
                 startDate: this.masterTimes[0],
                 endDate: this.masterTimes[1],
+                offlineFlag: 0,
                 pageNo: this.masterPag.page,
                 pageSize: this.masterPag.size
             };
@@ -671,9 +859,18 @@ export default {
             this.configForm = {
                 acountId: '',
                 num: '',
-                adConvertId: '',
-                launchDateRange: []
+                adConvertId: undefined,
+                launchDateRange: [],
+                searchStatus: 2
             };
+            if (this.currencyColumns[this.currencyColumns.length - 1].title === '操作') {
+                this.currencyColumns.pop();
+                this.currencyColumns.splice(1, 1);
+            }
+            if (this.appointColumns[this.appointColumns.length - 1].title === '操作') {
+                this.appointColumns.pop();
+                this.appointColumns.splice(1, 1);
+            }
             if (e === '1') {
                 this.handleGetCurrencyList();
             }
@@ -688,13 +885,17 @@ export default {
                 userId: this.userInfo().id,
                 startTime: this.configForm.launchDateRange[0],
                 endTime: this.configForm.launchDateRange[0],
+                status: this.configForm.searchStatus === 2 ? '' : this.configForm.searchStatus,
                 pageNo: this.currencyPag.page,
                 pageSize: this.currencyPag.size
             };
             getAction(urlAcount + '/bytedance-api/advertiser/bytedanceGeneralCopywriter/queryPageListByText', paramsData).then(result => {
                 if (result.code === 0) {
-                    this.currencyData = result.result.list;
-                    this.currencyTotalAll = result.result.total;
+                    this.currencyData = result.result.list ? result.result.list.map(item => {
+                        item.status = item.status === 0 ? '已删除' : '可投放';
+                        return item;
+                    }) : [];
+                    this.currencyTotalAll = result.result.total || 0;
                 }
                 else {
                     this.currencyData = [];
@@ -712,30 +913,43 @@ export default {
                 keyWord: this.configForm.num,
                 startTime: this.configForm.launchDateRange[0],
                 endTime: this.configForm.launchDateRange[0],
+                status: this.configForm.searchStatus === 2 ? '' : this.configForm.searchStatus,
                 pageNo: this.appointPag.page,
                 pageSize: this.appointPag.size
             };
             getAction(urlAcount + '/bytedance-api/ctop/bytedanceVideoSlogenInfo/queryPageListByText', paramsData).then(result => {
                 if (result.code === 0) {
-                    this.appointData = result.result.list;
-                    this.appointTotalAll = result.result.total;
+                    this.appointData = result.result.list ? result.result.list.map(item => {
+                        item.status = item.status === 0 ? '已删除' : '可投放';
+                        return item;
+                    }) : [];
+                    this.appointTotalAll = result.result.total || 0;
                 }
                 else {
                     this.appointData = [];
-                    this.appointTotalAll = [];
+                    this.appointTotalAll = 0;
                     this.$message.error(result.message);
                 }
             }).catch(error => {
                 console.log(error, 'eeee');
             });
         },
-        handleChange(info) {
+        handleCustomRequest(info) {
             const isZip = info.file.name.indexOf('xlsx') !== -1 || info.file.name.indexOf('xls') !== -1;
             if (!isZip) {
                 this.$message.error('上传模板只能是 xls、xlsx格式!');
                 return;
             }
-            this.fileList = info.fileList;
+            this.fileList = [];
+            this.$nextTick(() => {
+                this.fileList.push(info.file);
+            });
+        },
+        handleRemoveUpload(data) {
+            let index = this.fileList.indexOf(data);
+            let newUploadFile = this.fileList;
+            newUploadFile.splice(index, 1);
+            this.fileList = newUploadFile;
         },
         handleSearchMaster() {
             this.hendleMaterialInfo();
@@ -754,7 +968,11 @@ export default {
             this.hendleMaterialInfo();
         },
         handleSelectMaterial() {
-            this.hendleMaterialInfo();
+            this.masterPag = {
+                page: 1,
+                size: 10
+            };
+            this.handleRefreshMaster();
             this.visibleMatemal = true;
         },
         // 选择素材的取消按钮
@@ -768,18 +986,35 @@ export default {
         handleOkShow() {
             const defaultList = this.viedoDefaultList;
             const defaultCheckValue = this.viedoCheckValue;
-            let finallyIds = new Set();
             let changeSelectMaterData = defaultList.filter(item => {
                 if (defaultCheckValue.includes(item.id)) {
                     return item;
                 }
             });
-            finallyIds = this.modalSelectMaterial.concat(changeSelectMaterData).map(item => item.id);
-            this.modalSelectMaterial = defaultList.filter(item => {
-                if (finallyIds.includes(item.id)) {
-                    return item;
+            if (this.modalSelectMaterial.length) {
+                this.changeShowmasterData = [...this.modalSelectMaterial];
+                this.changeShowmasterData = this.changeShowmasterData.concat(changeSelectMaterData);
+                let temp = {}; // 用于id判断
+                let result = []; // 最后的新数组
+                this.changeShowmasterData.map(item => {
+                    if (!temp[item.id]) {
+                        result.push(item);
+                        temp[item.id] = true;
+                    }
+                });
+                if (result.length > 10) {
+                    this.$message.error('最多上传10个素材');
+                    return;
                 }
-            });
+                this.modalSelectMaterial = [...result];
+            }
+            else {
+                if (changeSelectMaterData.length > 10) {
+                    this.$message.error('最多上传10个素材');
+                    return;
+                }
+                this.modalSelectMaterial = [...changeSelectMaterData];
+            }
             this.handleCancelAll();
         },
         handleFormLayoutChange(e) {
@@ -836,16 +1071,24 @@ export default {
             this.$nextTick(() => {
                 const dynamicWordPackIds = [];
                 let finallyLenList = this.handleJudgeExec(this.examinForm.getFieldsValue()[field]);
-                let updateFinallyResult = this.adNameTags.filter(item => finallyLenList.includes(item.name)).map(val => val.name);
+                let newOptionList = [];
+                finallyLenList.forEach(item => {
+                    this.adNameTags.forEach(val => {
+                        if (item === val.name) {
+                            newOptionList.push(val);
+                        }
+                    });
+                });
+                let updateFinallyResult = newOptionList.map(val => val.name);
                 const inputDefaultLen = this.handleExportRules(this.defaultFormList.filter(item => item.id === formId)[0].value);
                 let tagsLen = updateFinallyResult.length * 2;
                 let tagsSureLen = 0;
                 let resultSelectSize = 0;
-                this.adNameTags.forEach(item => {
-                    updateFinallyResult.forEach(val => {
-                        if (item.name === val) {
-                            tagsSureLen += item.maxWordLen;
-                            dynamicWordPackIds.push(item.creativeWordId);
+                updateFinallyResult.forEach(item => {
+                    this.adNameTags.forEach(val => {
+                        if (item === val.name) {
+                            tagsSureLen += val.maxWordLen;
+                            dynamicWordPackIds.push(val.creativeWordId);
                         }
                     });
                 });
@@ -879,7 +1122,15 @@ export default {
             let txt = node.value;
             this.$nextTick(() => {
                 let finallyLenList = this.handleJudgeExec(txt);
-                let updateFinallyResult = this.adNameTags.filter(item => finallyLenList.includes(item.name)).map(val => val.name);
+                let arr = [];
+                finallyLenList.forEach(item => {
+                    this.adNameTags.forEach(val => {
+                        if (item === val.name) {
+                            arr.push(val);
+                        }
+                    });
+                });
+                let updateFinallyResult = arr.map(val => val.name);
                 if (updateFinallyResult.length >= 2) {
                     this.$message.error('最多选择两个词包');
                     return;
@@ -899,16 +1150,24 @@ export default {
             this.$nextTick(() => {
                 const dynamicWordPackIds = [];
                 let changeData = this.handleJudgeExec(this.examinForm.getFieldsValue()[field]);
-                let updateChangeData = this.adNameTags.filter(item => changeData.includes(item.name)).map(val => val.name);
+                let newOptionList = [];
+                changeData.forEach(item => {
+                    this.adNameTags.forEach(val => {
+                        if (item === val.name) {
+                            newOptionList.push(val);
+                        }
+                    });
+                });
+                let updateChangeData = newOptionList.map(val => val.name);
                 const inputDefaultLen = this.handleExportRules(this.examinForm.getFieldsValue()[field]);
                 let tagsLen = updateChangeData.length * 2;
                 let tagsSureLen = 0;
                 let resultSelectSize = 0;
-                this.adNameTags.forEach(item => {
-                    updateChangeData.forEach(val => {
-                        if (item.name === val) {
-                            tagsSureLen += item.maxWordLen;
-                            dynamicWordPackIds.push(item.creativeWordId);
+                updateChangeData.forEach(item => {
+                    this.adNameTags.forEach(val => {
+                        if (item === val.name) {
+                            tagsSureLen += val.maxWordLen;
+                            dynamicWordPackIds.push(val.creativeWordId);
                         }
                     });
                 });
@@ -928,16 +1187,24 @@ export default {
         validatePass(rule, value, callback) {
             this.$nextTick(() => {
                 let finallyLenList = this.handleJudgeExec(value);
-                let updateFinallyResult = this.adNameTags.filter(item => finallyLenList.includes(item.name)).map(val => val.name);
+                let newOptionList = [];
+                finallyLenList.forEach(item => {
+                    this.adNameTags.forEach(val => {
+                        if (item === val.name) {
+                            newOptionList.push(val);
+                        }
+                    });
+                });
+                let updateFinallyResult = newOptionList.map(val => val.name);
                 let resultSelectSize = 0;
                 if (updateFinallyResult.length) {
-                    const inputDefaultLen = this.handleExportRules(value.length);
+                    const inputDefaultLen = this.handleExportRules(value);
                     let tagsLen = updateFinallyResult.length * 2;
                     let tagsSureLen = 0;
-                    this.adNameTags.forEach(item => {
-                        updateFinallyResult.forEach(val => {
-                            if (item.name === val) {
-                                tagsSureLen += item.maxWordLen;
+                    updateFinallyResult.forEach(item => {
+                        this.adNameTags.forEach(val => {
+                            if (item === val.name) {
+                                tagsSureLen += val.maxWordLen;
                             }
                         });
                     });
@@ -947,7 +1214,7 @@ export default {
                     resultSelectSize = inputDefaultLen - tagsLen + tagsSureLen + updateFinallyResult.length;
                 }
                 else {
-                    resultSelectSize = this.handleExportRules(value.length);
+                    resultSelectSize = this.handleExportRules(value);
                 }
                 if (resultSelectSize === 0) {
                     callback(new Error('请输入'));
@@ -979,7 +1246,7 @@ export default {
                 });
             }
         },
-        handleUploadWxecl() {
+        handleUploadWxeclAdd() {
             if (!this.advertisingAccount.length) {
                 this.$message.error('请选择账户');
                 return;
@@ -988,9 +1255,9 @@ export default {
                 this.$message.error('请上传文件');
                 return;
             }
-            let paramsData = new FormData()
+            let paramsData = new FormData();
             paramsData.append('accountId', this.advertisingAccount);
-            paramsData.append('excelFile', this.fileList[0].originFileObj);
+            paramsData.append('excelFile', this.fileList[0]);
             postFileAction(urlAcount + '/bytedance-api/advertiser/bytedanceGeneralCopywriter/loadExcel', paramsData, {
                 headers: {
                     'Content-Type': 'multipart/form-data'
@@ -1033,9 +1300,10 @@ export default {
                     postAction(urlAcount + '/bytedance-api/ctop/bytedanceVideoSlogenInfo/addList', paramsData).then(result => {
                         if (result.code === 0) {
                             this.$message.success(result.message);
-                            this.controlTypeModel = '1';
+                            this.controlTypeModel = '2';
+                            this.modalSelectMaterial = [];
                             this.handleCauseCancel();
-                            this.handleGetCurrencyList();
+                            this.handleGetAppointList();
                         }
                         else {
                             this.$message.error(result.message);
@@ -1046,12 +1314,71 @@ export default {
                 }
             });
         },
+        handleUploadWxeclEdit() {
+            if (!this.defaultFormList[0].value) {
+                this.$message.error('文案标题不能为空');
+                return;
+            }
+            const paramsData = {
+                id: this.copywritingEditList.id,
+                textCopywriter: this.defaultFormList[0].value
+            };
+            postAction(urlAcount + '/bytedance-api/advertiser/bytedanceGeneralCopywriter/edit', paramsData).then(result => {
+                if (result.code === 0) {
+                    this.$message.success(result.message);
+                    this.causeVisible = false;
+                    this.controlTypeModel = '1';
+                    this.handleCauseCancel();
+                    this.handleGetCurrencyList();
+                }
+                else {
+                    this.$message.success(result.message);
+                }
+            }).catch(error => {
+                console.log(error, 'eeee');
+            });
+        },
+        handleVerticalEdit() {
+            if (!this.defaultFormList[0].value) {
+                this.$message.error('文案标题不能为空');
+                return;
+            }
+            const paramsData = {
+                slogan: this.copywritingEditList.slogan,
+                projectId: this.copywritingEditList.projectId,
+                newSlogan: this.defaultFormList[0].value
+            };
+            postAction(urlAcount + '/bytedance-api/ctop/bytedanceVideoSlogenInfo/edit', paramsData).then(result => {
+                if (result.code === 0) {
+                    this.$message.success(result.message);
+                    this.causeVisible = false;
+                    this.controlTypeModel = '2';
+                    this.handleCauseCancel();
+                    this.handleGetAppointList();
+                }
+                else {
+                    this.$message.success(result.message);
+                }
+            }).catch(error => {
+                console.log(error, 'eeee');
+            });
+        },
         handleCauseSure() {
-            if (this.copywrittypeName === 'horizontal') {
-                this.handleUploadWxecl();
+            if (this.copywritingType === 'add') {
+                if (this.copywrittypeName === 'horizontal') {
+                    this.handleUploadWxeclAdd();
+                }
+                else if (this.copywrittypeName === 'vertical') {
+                    this.handleVerticalAdd();
+                }
             }
-            else if (this.copywrittypeName === 'vertical') {
-                this.handleVerticalAdd();
+            else if (this.copywritingType === 'edit') {
+                if (this.copywrittypeName === 'horizontal') {
+                    this.handleUploadWxeclEdit();
+                }
+                else if (this.copywrittypeName === 'vertical') {
+                    this.handleVerticalEdit();
+                }
             }
         },
         handleCauseCancel() {
@@ -1061,6 +1388,7 @@ export default {
             this.causeVisible = false;
             this.defaultFormList = [];
             this.modalSelectMaterial = [];
+            this.copywritingType = '';
         },
         handleGetCreativeWord() {
             getAction('/ctop/ByteDanceCreativeWordPackage/list').then(result => {
@@ -1092,6 +1420,8 @@ export default {
         },
         handleAddAccountConfig() {
             this.causeVisible = true;
+            this.copywritingType = 'add';
+            this.copywritingEditList = {};
         },
         handleLaunchData(date, dateString) {
             this.configForm.launchDateRange = dateString;
@@ -1103,6 +1433,42 @@ export default {
             };
             this.currencyPag = page;
             this.appointPag = page;
+            if (this.configForm.acountId) {
+                if (this.currencyColumns[this.currencyColumns.length - 1].title !== '操作') {
+                    this.currencyColumns.splice(1, 0, {
+                        title: '状态',
+                        align: 'center',
+                        width: 150,
+                        dataIndex: 'status'
+                    });
+                    this.currencyColumns.push({
+                        title: '操作',
+                        dataIndex: 'currencyAction',
+                        align: 'center',
+                        width: 150,
+                        fixed: 'right',
+                        scopedSlots: {customRender: 'currencyAction'}
+                    });
+                }
+            }
+            if (this.configForm.adConvertId) {
+                if (this.appointColumns[this.appointColumns.length - 1].title !== '操作') {
+                    this.appointColumns.splice(1, 0, {
+                        title: '状态',
+                        align: 'center',
+                        width: 150,
+                        dataIndex: 'status'
+                    });
+                    this.appointColumns.push({
+                        title: '操作',
+                        dataIndex: 'appointAction',
+                        align: 'center',
+                        width: 150,
+                        fixed: 'right',
+                        scopedSlots: {customRender: 'appointAction'}
+                    });
+                }
+            }
             if (this.controlTypeModel === '1') {
                 this.handleGetCurrencyList();
             }
@@ -1114,8 +1480,9 @@ export default {
             this.configForm = {
                 acountId: '',
                 num: '',
-                adConvertId: '',
-                launchDateRange: []
+                adConvertId: undefined,
+                launchDateRange: [],
+                searchStatus: 2
             };
             const page = {
                 page: 1,
@@ -1123,6 +1490,14 @@ export default {
             };
             this.currencyPag = page;
             this.appointPag = page;
+            if (this.currencyColumns[this.currencyColumns.length - 1].title === '操作') {
+                this.currencyColumns.pop();
+                this.currencyColumns.splice(1, 1);
+            }
+            if (this.appointColumns[this.appointColumns.length - 1].title === '操作') {
+                this.appointColumns.pop();
+                this.appointColumns.splice(1, 1);
+            }
             if (this.controlTypeModel === '1') {
                 this.handleGetCurrencyList();
             }

+ 16 - 3
src/views/modules/creative-copywrit/creative-copywrit.less

@@ -21,7 +21,11 @@
             width: 100px;
         }
         .only-title-mater {
+            width: 500px;
             height: 35px;
+            overflow: hidden;
+            white-space: nowrap;
+            text-overflow: ellipsis;
         }
         .examin-form-model {
             width: 500px;
@@ -76,8 +80,6 @@
 
 .solgan-whole-content {
     display: flex;
-    height: 300px;
-    overflow-y: auto;
     .solgan-title-header {
         padding-top: 10px;
         margin-right: 20px;
@@ -85,7 +87,7 @@
     }
     .solgan-form-class {
         .examin-form-input {
-            width: 380px;
+            width: 320px;
         }
         /deep/ .ant-form-item-children {
             display: inline-flex;
@@ -99,6 +101,17 @@
             text-overflow: ellipsis;
         }
         .solgan-form-model {
+            /deep/ .ant-form-item-children {
+                display: contents !important;
+            }
+            .solgan-tags-change {
+                width: 430px;
+                display: flex;
+                justify-content: space-between;
+            }
+            .solgan-icon-type {
+                width: 100px;
+            }
             .examin-form-num {
                 margin-left: 10px;
                 margin-right: 5px;

File diff suppressed because it is too large
+ 700 - 122
src/views/modules/creative-copywrit/creative-copywrit.vue


+ 1 - 0
src/views/modules/crowd-control/components/tree-select/tree-select.vue

@@ -143,6 +143,7 @@ export default {
             }
             defaultCheckKey.splice(value, 1);
             this.checkedKeys = defaultCheckKey;
+            this.$emit('applyType', this.applyTypeOption);
         },
         onChange(e) {
             const value = e.target.value;

+ 70 - 10
src/views/modules/crowd-control/crowd-control.vue

@@ -25,9 +25,12 @@
                         <span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
                             <a-button type="primary" icon="search" @click="handleQueryList">查询</a-button>
                             <a-button type="primary" @click="handleResetForm" icon="reload" class="middle-button">重置</a-button>
-                             <a-button type="primary" @click="handleUploadPerson">
+                             <a-button type="primary" @click="handleUploadPerson" class="middle-button">
                                 上传人群包
                             </a-button>
+                             <a-button type="primary" @click="handleUpdatePerson" v-if="realShow" :loading="realLoading">
+                                更新人群
+                            </a-button>
                            
                         </span>
                         
@@ -243,7 +246,7 @@ import AcountSearch from '@/views/modules/Statistics/components/Treeselect.vue';
 import selectTable from '@/views/modules/Statistics/components/selectPagination.vue';
 import AppMarketService from './crowd-control-service';
 import BMF from 'browser-md5-file';
-
+import { mapGetters } from 'vuex';
 let COS = require('cos-js-sdk-v5');
 let cos = new COS({
     SecretId: 'AKIDE6IpMi8fJQRCg1iuWzFajjRs43kbbets',
@@ -394,6 +397,8 @@ export default {
                     this.handleAcountRelax(this.relaxStatus  ,this.acountRelaxDetail)
                 }
             },
+            realShow: false,
+            realLoading: false
         };
     },
     watch: {
@@ -407,18 +412,42 @@ export default {
         this.form = this.$form.createForm(this);
     },
     mounted() {
+        this.realShow = this.userInfo().realname === '管理员' ? true : false
+        if(!this.realShow) {
+            getAction('/kuaishou/batch/syncUserPopulationList',{ userId:this.userInfo().id, type:1}).then(res => {
+                if(res.success) {
+
+                }
+            })
+        }
         this.handleGetTableList({});
     },
     methods: {
+        ...mapGetters(['nickname', 'avatar', 'userInfo']),
         handleAgian(val) {
             let params = {};
             params.id = val.id;
             params.accountIds = [val.accountId];
             postAction('/kuaishouPopulationPackage/push' ,params).then(res => {
                 if(res.success) {
-                    this.$message.success(res.message);
-                    this.historyVisible = false;
-                    this.handleGetTableList({});
+                   
+                    if(!this.realShow) {
+                        getAction('/kuaishou/batch/syncUserPopulationList',{ userId:this.userInfo().id, type:1}).then(res => {
+                            if(res.success) {
+                                this.$message.success(res.message);
+                                this.historyVisible = false;
+                                this.handleGetTableList({});
+                            }
+                            else {
+                                this.$message.error(res.message);
+                            }
+                        })
+                    }
+                    else {
+                        this.$message.success(res.message);
+                        this.historyVisible = false;
+                        this.handleGetTableList({});
+                    }
                 }
                 else {
                     this.$message.error(res.message);
@@ -497,7 +526,7 @@ export default {
             let that = this;
             this.$confirm({
                 title: '删除提示',
-                content: '确定要删除这一条吗?',
+                content: '是否删除该人群包?',
                 onOk() {
                     getAction('/kuaishouPopulationPackage/delete', {id: data.id}).then(result => {
                         if (result.code === 200) {
@@ -596,13 +625,28 @@ export default {
                     id: this.tableSelectList.id
                 };
                 postAction('/kuaishouPopulationPackage/push', paramsData).then(result => {
-                    this.pushConfirmLoading = false;
+                    
                     if (result.code === 200) {
-                        this.pushVisible = false;
-                        this.handleGetTableList({});
-                        this.$message.success('推送成功')
+                        
+                        if(!this.realShow) {
+                            getAction('/kuaishou/batch/syncUserPopulationList',{ userId:this.userInfo().id, type:1}).then(res => {
+                                if(res.success) {
+                                    this.pushConfirmLoading = false;
+                                    this.pushVisible = false;
+                                    this.handleGetTableList({});
+                                    this.$message.success('推送成功')
+                                }
+                            })
+                        }
+                        else {
+                            this.pushConfirmLoading = false;
+                            this.pushVisible = false;
+                            this.handleGetTableList({});
+                            this.$message.success('推送成功')
+                        }
                     }
                     else {
+                        this.pushConfirmLoading = false;
                         this.$message.error(result.message);
                     }
                 }).catch(error => {
@@ -726,6 +770,22 @@ export default {
         handleUploadPerson() {
             this.personVisible = true;
         },
+        handleUpdatePerson() {
+            if(this.realShow) {
+                this.realLoading = true;
+                getAction('/kuaishou/batch/syncUserPopulationList',{ userId:this.userInfo().id, type:0}).then(res => {
+                    if(res.success) {
+                        this.realLoading = false;
+                        this.$message.success('更新成功');
+                        this.handleResetForm();
+                    }
+                    else {
+                        this.realLoading = false;
+                        this.$message.error('更新失败');
+                    }
+                })
+            }
+        },
         handleOk() {
             this.$refs.ruleForm.validate(valid => {
                 if (valid) {

+ 2 - 2
src/views/modules/headline-view/headline-view-server.js

@@ -3,8 +3,8 @@
  * @author jiayufei
  */
 
-export const urlAcount = 'http://118.24.244.213:8080'; // 线上
+export const urlAcount = 'http://118.24.244.213:8808'; // 线上
 // export const urlAcount = 'http://apipre.tjyourong.com.cn'; // 预生产
 // export const urlAcount = 'http://192.168.1.43:8080'; // 子安
-// export const urlAcount = 'http://139.186.165.84:8080'; // 测试
+// export const urlAcount = 'http://139.186.165.84:8808'; // 测试
 // export const urlAcount = 'http://192.168.1.8:8080'; // 学超

File diff suppressed because it is too large
+ 398 - 216
src/views/modules/headline-view/headline-view.vue


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

@@ -345,7 +345,6 @@
         <checkBoxGroup
           :options="[
             { label: '优选广告位', value: 1 },
-            { label: '信息流广告', value: 7 },
             { label: '上下滑大屏广告', value: 6 },
             { label: '视频播放页广告', value: 3 },
           ]"
@@ -533,8 +532,28 @@
             'unitName',
             {
               rules: [{ required: true, message: '广告组必填' }, {validator: handleConfirmValue}],
-            },]" @change="checkGroup($event, index)"></a-input>
+            },]" @change="checkGroup($event, index)" id="unitName"></a-input>
           <span style="color: red" v-if="item.unitNameCheck">广告组名称重复</span>
+          <a-tag color="#2db7f5" @click="getChangeAll('序号', 'form', 'unitName')">+序号</a-tag>
+        </a-form-item>
+        <a-form-item
+          v-if="showNumber"
+          label="序号开始值"
+          :labelCol="{ lg: { span: 7 }, sm: { span: 7 } }"
+          :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }"
+        >
+          <a-input-number
+            :min="0"
+            v-decorator="[
+              'startNumber',
+              {
+                rules: [{ required: true, message: '序号开始值必填' }],
+                initialValue: 0,
+              },
+            ]"
+            style="width: 150px"
+          >
+          </a-input-number>
         </a-form-item>
       </div>
       <div style="text-align: center; font-size: 16px">创意素材</div>
@@ -584,6 +603,27 @@
         </a-radio-group>
       </a-form-item>
       <a-form-item
+        v-if="getData('createType')=='0'"
+        label="封面数"
+        :labelCol="{ lg: { span: 7 }, sm: { span: 7 } }"
+        :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }"
+      >
+         <a-input-number
+          :max="15"
+          :min="1"
+          v-decorator="[
+            'imageCount',
+            {
+              rules: [{ required: true, message: '封面数必填' }],
+              initialValue: 5,
+            },
+          ]"
+          style="width: 150px"
+        >
+        </a-input-number>
+      </a-form-item>
+      
+      <a-form-item
         label="选择视频"
         :labelCol="{ lg: { span: 7 }, sm: { span: 7 } }"
         :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }"
@@ -1143,6 +1183,7 @@ export default {
 
   data() {
     return {
+      showNumber:false,
       md5Str:'',
       uriCheck: false,
       templateLoading: false,
@@ -2413,6 +2454,53 @@ export default {
         }
       })
     },
+    getChangeAll(type, form, field) {
+      this.showNumber = false
+      this.showNumber = true
+      var node = document.getElementById(field)
+      var v = '{{' + type + '}}'
+      if (document.selection) {
+          //IE
+          node.focus()
+          var sel = document.selection.createRange()
+          sel.text = v
+          sel.select()
+          if (field == 'campaignName') {
+            this[form].setFieldsValue({ campaignName: sel.text })
+          } else if (field == 'unitName') {
+            this[form].setFieldsValue({ unitName: sel.text })
+          }
+      } else if (node.selectionStart || node.selectionStart == '0') {
+          //MOZILLA/GOOGLE
+          var startPos = node.selectionStart
+          var endPos = node.selectionEnd
+          var restoreTop = node.scrollTop
+          node.value = node.value.substring(0, startPos) + v + node.value.substring(endPos, node.value.length)
+          if (restoreTop > 0) {
+          node.scrollTop = restoreTop
+          }
+          if (field == 'campaignName') {
+          this[form].setFieldsValue({ campaignName: node.value })
+          } else if (field == 'unitName') {
+          this[form].setFieldsValue({ unitName: node.value })
+          }
+          node.focus()
+          node.selectionStart = startPos + v.length
+          node.selectionEnd = startPos + v.length
+          // this.campaignName = node.value
+      } else {
+          //OTHER
+          node.value += v
+          // console.log(node.value)
+          if (field == 'campaignName') {
+          this[form].setFieldsValue({ campaignName: node.value })
+          } else if (field == 'unitName') {
+          this[form].setFieldsValue({ unitName: node.value })
+          }
+          node.focus()
+          // this.campaignName = node.value
+      }
+    },
   },
   watch: {
     timeSeries(val) {

+ 51 - 7
src/views/modules/material/accountCheck.vue

@@ -13,9 +13,19 @@
 <template>
   <div>
     <a-modal title="账户选择" v-model="showEdit" @ok="handleOk" @cancel="close" width="80%">
-      <a-checkbox :indeterminate="indeterminate" @change="onCheckAllChange" :checked="checkAll">全选</a-checkbox>
+      <!-- <a-checkbox :indeterminate="indeterminate" @change="onCheckAllChange" :checked="checkAll">全选</a-checkbox>
       <br />
-      <a-checkbox-group :options="showList" v-model="dataValue" class="checked-account" @change="onChange"/>
+      <a-checkbox-group :options="showList" v-model="dataValue" class="checked-account" @change="onChange" /> -->
+      <a-tree
+        v-model="checkedKeys"
+        checkable
+        :expanded-keys="expandedKeys"
+        :auto-expand-parent="autoExpandParent"
+        :selected-keys="selectedKeys"
+        :tree-data="treeData"
+        @expand="onExpand"
+        @select="onSelect"
+      />
     </a-modal>
   </div>
 </template>
@@ -30,19 +40,44 @@ export default {
 
   data: function () {
     return {
+      checkedKeys: [],
       showEdit: false,
       dataList: [],
       showList: null,
       dataValue: [],
       indeterminate: false,
       checkAll: false,
+      expandedKeys: [],
+      autoExpandParent: true,
+      selectedKeys: [],
+      treeData:[],
     }
   },
+  watch: {
+    checkedKeys(val) {
+      console.log('onCheck', val)
+    },
+  },
   methods: {
+    onExpand(expandedKeys) {
+      console.log('onExpand', expandedKeys)
+      // if not set autoExpandParent to false, if children expanded, parent can not collapse.
+      // or, you can remove all expanded children keys.
+      this.expandedKeys = expandedKeys
+      this.autoExpandParent = false
+    },
+    onCheck(checkedKeys) {
+      console.log('onCheck', checkedKeys)
+      this.checkedKeys = checkedKeys
+    },
+    onSelect(selectedKeys, info) {
+      console.log('onSelect', info)
+      this.selectedKeys = selectedKeys
+    },
     handleOk(e) {
       console.log(e)
       this.showEdit = false
-      this.$emit('synchro', this.dataValue)
+      this.$emit('synchro', this.checkedKeys)
     },
     close() {
       this.showEdit = false
@@ -72,17 +107,26 @@ export default {
       this.dataList = []
       this.showList = null
       this.dataValue = []
+      this.checkedKeys = []
       this.indeterminate = false
       this.checkAll = false
       console.log(url, item)
       getAction(url, item).then((res) => {
-        if (res.code == 0) {
-          this.showList = res.result.map((item) => {
+        if (res.success) {
+          let arrList = []
+          this.treeData = res.result.map(item=>{
             return {
-              label: item.authName,
-              value: item.accountId,
+              title: item.projectName,
+              key: item.projectId,
+              children:item.userAllocationList.map(i=>{
+                  return {
+                    title: i.authName+'\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0'+(i.userName?i.userName:'管理员'), 
+                    key: i.accountId
+                  }
+              })
             }
           })
+         
         }
         console.log(res)
       })

+ 3 - 3
src/views/modules/material/accountCheckBytedance.vue

@@ -289,12 +289,12 @@ export default {
         resolve(data)
       }
     },
-    getParticipateList(projectId) {
+    getParticipateList(productId) {
       //我参与的
       //   toutiaoParticipateList
       this.showEdit = true
-      getAction('/ctop/userAllocation/getUserIdListByProjectId', {
-        projectId: projectId,
+      getAction('/ctop/userAllocation/getUserIdListByProductId', {
+        productId: productId,
       }).then((res) => {
         if (res.code == 0) {
           console.log(res)

+ 423 - 0
src/views/modules/material/comment/selectTable.vue

@@ -0,0 +1,423 @@
+<style>
+.select-table .ant-table-thead > tr > th,
+.select-table .ant-table-tbody > tr > td {
+  padding: 0 !important;
+}
+.select-table .ant-table {
+  font-size: 12px;
+}
+.demo-infinite-container {
+  border: 1px solid #e8e8e8;
+  border-radius: 4px;
+  overflow: auto;
+  padding: 8px 24px;
+  height: 300px;
+}
+.demo-loading-container {
+  position: absolute;
+  bottom: 40px;
+  width: 100%;
+  text-align: center;
+}
+</style>
+<style lang="scss" scoped>
+.require-check {
+  /deep/ .ant-form-item-label {
+    label::before {
+      display: inline-block;
+      margin-right: 4px;
+      color: #f5222d;
+      font-size: 14px;
+      font-family: SimSun, sans-serif;
+      line-height: 1;
+      content: '*';
+    }
+  }
+}
+</style>
+<template>
+  <a-form-item
+    label="产品名称"
+    :label-col="labelCol"
+    :wrapper-col="wrapperCol"
+    v-clickoutside="handleClose"
+    style="width: 100%"
+    class="select-table"
+    :class="{'require-check':requireCheck} "
+  >
+    <a-input
+      placeholder="请选择产品名称"
+      @focus="topMiddle = true"
+      v-model="keyValue"
+      @change="getData"
+      :disabled="disabled"
+    />
+    <div
+      v-show="topMiddle"
+      v-infinite-scroll="handleInfiniteOnLoad"
+      style="
+        background: white;
+        padding: 10px;
+        box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.15);
+        position: absolute;
+        z-index: 1000;
+        width: 100%;
+      "
+      class="demo-infinite-container"
+      :infinite-scroll-disabled="busy"
+      :infinite-scroll-distance="80"
+    >
+      <a-list :data-source="data">
+        <a-list-item slot="renderItem" slot-scope="item" @click="showProject(item)">
+          <a-list-item-meta :description="'广告主名称:' + item.advertiserName">
+            <a slot="title">产品名称:{{ item.productName }}</a>
+          </a-list-item-meta>
+          <!-- <div>
+            {{
+              item.mediaId == '1'
+                ? '头条'
+                : item.mediaId == '2'
+                ? '快手'
+                : item.mediaId == '3'
+                ? '头条内广'
+                : '快手内广'
+            }}
+          </div> -->
+        </a-list-item>
+        <div v-if="loading && !busy" class="demo-loading-container">
+          <a-spin />
+        </div>
+      </a-list>
+    </div>
+  </a-form-item>
+</template>
+
+<script>
+import { getAction, postAction } from '@/api/manage'
+import moment from 'moment'
+import { mapGetters } from 'vuex'
+import jq from 'jquery'
+import infiniteScroll from 'vue-infinite-scroll'
+const clickoutside = {
+  // 初始化指令
+  bind(el, binding, vnode) {
+    function documentHandler(e) {
+      // 这里判断点击的元素是否是本身,是本身,则返回
+      if (el.contains(e.target)) {
+        return false
+      }
+      // 判断指令中是否绑定了函数
+      if (binding.expression) {
+        // 如果绑定了函数 则调用那个函数,此处binding.value就是handleClose方法
+        binding.value(e)
+      }
+    }
+    // 给当前元素绑定个私有变量,方便在unbind中可以解除事件监听
+    el.__vueClickOutside__ = documentHandler
+    document.addEventListener('click', documentHandler)
+  },
+  update() {},
+  unbind(el, binding) {
+    // 解除事件监听
+    document.removeEventListener('click', el.__vueClickOutside__)
+    delete el.__vueClickOutside__
+  },
+}
+export default {
+  name: 'select-pagination',
+  components: {},
+  directives: { clickoutside, infiniteScroll },
+  props: {
+    projectId: {
+      type: [String, Number],
+      default() {
+        return ''
+      },
+    },
+    type: {
+      type: String,
+      default() {
+        return ''
+      },
+    },
+    labelCol: {
+      type: Object,
+      default() {
+        return {
+          xs: { span: 24 },
+          sm: { span: 5 },
+        }
+      },
+    },
+    disabled: {
+      type: Boolean,
+      default() {
+        return false
+      },
+    },
+    requireCheck: {
+      type: Boolean,
+      default() {
+        return false
+      },
+    }
+  },
+
+  data() {
+    return {
+      taobaoSpecialOfferList: {
+        advertiserId: "fd41614705a047dd65ab0e34e9150cfe",
+        advertiserName: " 淘宝(中国)软件有限公司",
+        createTime: "2021-03-03 10:15:30",
+        designResponsibleName: "辛巴特",
+        id: 3660879,
+        maxBid: 30000,
+        mediaId: "1",
+        productId: 1410280,
+        productName: "头条-淘宝特价版",
+        projectId: 1530887,
+        projectName: "头条-淘宝特价版",
+        responsibleName: "董琪",
+        roleCode: "operator",
+        saleId: null,
+        saleName: null,
+        updateTime: "2021-03-03 21:23:04",
+        userId: "a0d58df3392c4583b55ce3b041792aa7",
+        userName: "王晓娟"
+      },
+      loading: false,
+      busy: false,
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 12 },
+      },
+      selectedRowKeys: [],
+      selectedRowKeysValue: [],
+      topMiddle: false,
+      keyValue: '',
+      data: [],
+      dataElse: [],
+      ipagination: {
+        current: 0,
+        pageSize: 20,
+      },
+      rowClick: (record, index) => ({
+        // 事件
+        on: {
+          click: () => {
+            // var str =
+            //   record.mediaId == '1'
+            //     ? '头条'
+            //     : record.mediaId == '2'
+            //     ? '快手'
+            //     : record.mediaId == '3'
+            //     ? '头条内广'
+            //     : '快手内广'
+            this.keyValue = record.productName
+            this.topMiddle = false
+            this.data = this.dataElse
+            this.$emit('update:projectId', record.id)
+          },
+        },
+      }),
+    }
+  },
+  computed: {},
+  filters: {},
+  methods: {
+    showProject(record) {
+      var str =
+        record.mediaId == '1'
+          ? '头条'
+          : record.mediaId == '2'
+          ? '快手'
+          : record.mediaId == '3'
+          ? '头条内广'
+          : '快手内广'
+      this.keyValue = record.productName
+      this.topMiddle = false
+      this.$emit('update:projectId', record.id)
+    },
+    ...mapGetters(['nickname', 'avatar', 'userInfo']),
+    onSelectChange(selectedRowKeys, selectionRows) {
+      this.selectedRowKeys = selectedRowKeys
+      this.selectedRowKeysValue = selectionRows.map((item) => {
+        return { orientationId: item.orientationId, orientationName: item.orientationName }
+      })
+    },
+    getData() {
+      if (this.keyValue == '') {
+        this.$emit('update:projectId', '')
+      }
+      this.ipagination.current = 1
+      getAction('/ctop/product/getUserProductList', {
+        userId: this.userInfo().id,
+        pageNo: this.ipagination.current,
+        productName: this.keyValue,
+      }).then((res) => {
+        if (res.code == 0) {
+          let defaultList = res.result.records.map((item, index) => {
+            return {
+              ...item,
+              productId: item.id + '',
+              key: index,
+            };
+          })
+          if (this.type === 'taobao') {
+            this.data = defaultList.filter(item => item.productId === 1410280);
+          }
+          else {
+            this.data = defaultList;
+          }
+          // this.dataElse = res.result.records.map((item, index) => {
+          //   return {
+          //     ...item,
+          //     projectId: item.projectId + '',
+          //     key: index,
+          //   }
+          // })
+        }
+      })
+    },
+    handleClose() {
+      this.topMiddle = false
+    },
+    // allData() {
+    //   getAction('/ctop/product/getUserProductList', {
+    //     userId: this.userInfo().id,
+    //     pageSize: this.ipagination.pageSize,
+    //     pageNo: this.ipagination.current,
+    //   }).then((res) => {
+    //     if (res.code == 0) {
+    //       this.data = res.result.records.map((item, index) => {
+    //         return {
+    //           ...item,
+    //           projectId: item.projectId + '',
+    //           key: index,
+    //         }
+    //       })
+    //       this.dataElse = res.result.records.map((item, index) => {
+    //         return {
+    //           ...item,
+    //           projectId: item.projectId + '',
+    //           key: index,
+    //         }
+    //       })
+    //     }
+    //   })
+    // },
+    handleInfiniteOnLoad() {
+      const data = this.data
+      this.loading = true
+      this.ipagination.current++
+      // this.fetchData((res) => {
+      //   this.data = data.concat(res.results)
+      //   this.loading = false
+      // })
+      getAction('/ctop/product/getUserProductList', {
+        userId: this.userInfo().id,
+        pageSize: this.ipagination.pageSize,
+        pageNo: this.ipagination.current,
+        productName: this.keyValue,
+      }).then((res) => {
+        if (res.code == 0) {
+          this.busy = true
+          let defaultList = res.result.records.map((item, index) => {
+              return {
+                ...item,
+                projectId: item.projectId + '',
+              }
+            })
+          this.data = data.concat(
+            
+          )
+          if (this.type === 'taobao') {
+            this.data = defaultList.filter(item => item.productId === 1410280);
+          }
+          else {
+            this.data = data.concat(defaultList);
+          }
+          // this.data = res.result.records.map((item, index) => {
+          //   return {
+          //     ...item,
+          //     projectId: item.projectId + '',
+          //     key: index,
+          //   }
+          // })
+          // this.dataElse = res.result.records.map((item, index) => {
+          //   return {
+          //     ...item,
+          //     projectId: item.projectId + '',
+          //     key: index,
+          //   }
+          // })
+        }
+      })
+    },
+  },
+  watch: {
+    projectId(n, o) {
+      if (n == '') {
+        this.keyValue = ''
+      } else {
+      }
+    },
+  },
+  mounted: function () {
+    // this.handleInfiniteOnLoad()
+  },
+}
+</script>
+
+<style type="text/css">
+.plug-timer-grid {
+  width: 100%;
+}
+
+.plug-timer-grid td,
+.plug-timer-grid th {
+  border: 1px solid #97b4d1;
+  text-align: center; /*cursor:pointer;*/
+  font-size: 10px;
+  line-height: 10px;
+}
+
+.Selected {
+  background-color: rgb(102, 162, 243);
+  opacity: 0.5;
+}
+
+.plug-timer-grid {
+  border-collapse: collapse;
+  z-index: 4;
+}
+
+.plug-timer-grid thead tr {
+  display: table-row;
+  vertical-align: inherit;
+  border-color: inherit;
+}
+
+.group-creat table td {
+  height: 20px;
+  max-width: 5px;
+  font-size: 12px;
+  text-align: center;
+  vertical-align: middle;
+  overflow: hidden;
+  transition: background 0.5s;
+  -webkit-transition: background 0.5s;
+}
+
+.plug-timer-grid tbody th {
+  width: 4%;
+}
+
+.plug-timer-grid tbody tr td {
+  width: 2%;
+}
+
+/*.clear{*/
+/*  margin:20px 0px 20px 0px;*/
+/*}*/
+</style>

+ 157 - 49
src/views/modules/material/videoMaterial.vue

@@ -356,10 +356,13 @@ a {
         <a-row :gutter="24">
           <a-col :md="8" :sm="8">
             <!-- <a-form-item label="项目名称"> -->
-            <selectTable :projectId.sync="queryParam.projectId"></selectTable>
+            <selectTable :projectId.sync="queryParam.productId" ref="selectTable"></selectTable>
           </a-col>
 
           <a-col :md="8" :sm="8">
+            <selectTableProject :projectId.sync="queryParam.projectId" :productId="queryParam.productId" ref="selectTableProject"></selectTableProject>
+          </a-col>
+          <a-col :md="8" :sm="8">
             <a-form-item label="素材名称">
               <a-input placeholder="请输入素材名称" v-model="queryParam.materialName"></a-input>
             </a-form-item>
@@ -390,6 +393,34 @@ a {
             </a-form-item>
           </a-col>
           <a-col :md="8" :sm="8">
+            <a-form-item label="剪辑">
+              <a-select v-model="queryParam.clipId" allowClear show-search :filter-option="filterOption">
+                <a-select-option v-for="item in designList" :key="item.userId" :value="item.userId">
+                  {{ item.companyName + '_' + item.userName }}
+                </a-select-option>
+              </a-select>
+            </a-form-item>
+          </a-col>
+          <a-col :md="8" :sm="8">
+            <a-form-item label="拍摄">
+              <a-select v-model="queryParam.shotId" allowClear show-search :filter-option="filterOption">
+                <a-select-option v-for="item in designList" :key="item.userId" :value="item.userId">
+                  {{ item.companyName + '_' + item.userName }}
+                </a-select-option>
+              </a-select>
+            </a-form-item>
+          </a-col>
+          <a-col :md="8" :sm="8">
+            <a-form-item label="编导">
+              <a-select v-model="queryParam.planId" allowClear show-search :filter-option="filterOption">
+                <a-select-option v-for="item in designList" :key="item.userId" :value="item.userId">
+                  {{ item.companyName + '_' + item.userName }}
+                </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">
               <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
               <a-button type="primary" @click="searchRe" icon="reload" style="margin-left: 8px">重置</a-button>
@@ -418,7 +449,7 @@ a {
       <a-button
         @click="onCheckAllChange"
         v-if="
-          queryParam.projectId &&
+          queryParam.productId &&
           active == '1' &&
           (role.roleCode == 'operator' ||
             role.roleCode == 'kuaishouOperationManager' ||
@@ -430,7 +461,7 @@ a {
       >
       <a-button
         v-if="
-          queryParam.projectId &&
+          queryParam.productId &&
           active == '1' &&
           (role.roleCode == 'operator' ||
             role.roleCode == 'kuaishouOperationManager' ||
@@ -439,8 +470,50 @@ a {
             role.roleCode == 'touTiaoOperationManager')
         "
         :disabled="checkArr.length == 0"
-        @click="tongbu"
-        >一键同步</a-button
+        @click="tongbu('1')"
+        >一键同步头条</a-button
+      >
+      <a-button
+        v-if="
+          queryParam.productId &&
+          active == '1' &&
+          (role.roleCode == 'operator' ||
+            role.roleCode == 'kuaishouOperationManager' ||
+            role.roleCode == 'admin' ||
+            role.roleCode == 'operationAssistant' ||
+            role.roleCode == 'touTiaoOperationManager')
+        "
+        :disabled="checkArr.length == 0"
+        @click="tongbu('3')"
+        >一键同步头条内广</a-button
+      >
+      <a-button
+        v-if="
+          queryParam.productId &&
+          active == '1' &&
+          (role.roleCode == 'operator' ||
+            role.roleCode == 'kuaishouOperationManager' ||
+            role.roleCode == 'admin' ||
+            role.roleCode == 'operationAssistant' ||
+            role.roleCode == 'touTiaoOperationManager')
+        "
+        :disabled="checkArr.length == 0"
+        @click="tongbu('2')"
+        >一键同步快手</a-button
+      >
+      <a-button
+        v-if="
+          queryParam.productId &&
+          active == '1' &&
+          (role.roleCode == 'operator' ||
+            role.roleCode == 'kuaishouOperationManager' ||
+            role.roleCode == 'admin' ||
+            role.roleCode == 'operationAssistant' ||
+            role.roleCode == 'touTiaoOperationManager')
+        "
+        :disabled="checkArr.length == 0"
+        @click="tongbu('4')"
+        >一键同步快手内广</a-button
       >
     </div>
 
@@ -475,7 +548,7 @@ a {
                         text-overflow: ellipsis;
                       "
                       :title="items.projectName"
-                      >{{ items.projectName }}</span
+                      >{{ (items.mediaId == "1" ? '头条' :items.mediaId == "2"? '快手':items.mediaId == "3"?'内广':'内广') +(items.projectName?'_'+items.projectName:'') }}</span
                     >
                     <span
                       style="
@@ -580,6 +653,7 @@ a {
                     <div class="show-data">
                       <span>抖音</span>
                       <span>消耗:{{ items.bytedanceCost || 0 }}</span>
+                      <span style="display: inline-block;text-align: left;width: 400px;">审核通过时间:{{ items.confirmTime || '-' }}</span>
                       <!-- <span>封面点击:{{ items.byteDance.click }}</span> -->
                       <!-- <span>封面展示:{{ items.byteDance.showNum }}</span> -->
                     </div>
@@ -721,7 +795,7 @@ a {
                     <a-checkbox :value="items.id" style="float: right" v-show="active == '1'"></a-checkbox>
 
                     <br />
-                    {{ items.createTime | getDate }}
+                    {{ items.createTime }}
                   </span>
                 </div>
               </div>
@@ -1260,7 +1334,15 @@ a {
           </a-carousel>
         </a-modal>
         <div style="flex: 3; padding: 10px; box-sizing: border-box">
-          <a-form v-if="detail" class="detail ant-advanced-search-form" layout="inline">
+          <a-form v-if="detail&&allDetailData" class="detail ant-advanced-search-form" layout="inline">
+            <div>
+              <a-form-item label="视频名称">{{allDetailData.materialName}}</a-form-item>
+            </div>
+            <div>
+              <a-form-item label="唯一编码">{{allDetailData.code}}</a-form-item>
+            </div>
+            
+            <a-form-item label="视频链接"><a-input v-model="allDetailData.url" type="text" read-only /></a-form-item>
             <div v-if="detail.parameter" style="display: flex">
               <a-form-item label="视频时长" v-if="detail.parameter.second" style="flex: 1"
                 >{{ detail.parameter.second }}秒</a-form-item
@@ -1667,8 +1749,8 @@ import qs from 'qs'
 import { mapGetters } from 'vuex'
 import moment from 'moment'
 
-import selectTable from '@/views/modules/Statistics/components/selectPagination.vue'
-
+import selectTable from './comment/selectTable.vue'
+import selectTableProject from '@/views/modules/Statistics/components/selectPagination.vue'
 import BMF from 'browser-md5-file'
 import uploadFile from '@/components/uploadFile.vue'
 import { closeAllVideoFun, stopOtherVideo } from '@/utils/videoControl'
@@ -1685,10 +1767,12 @@ export default {
     uploadFile,
     PermissionModal,
     accountCheckBytedance,
+    selectTableProject,
   },
 
   data() {
     return {
+      designList: [],
       // 标签的数据
       labelValue: [],
       options: [],
@@ -1862,6 +1946,7 @@ export default {
       waterLoading: false,
       videoTag: [],
       videoVisibleChange: '',
+      allDetailData: null,
     }
   },
   filters: {
@@ -1929,7 +2014,7 @@ export default {
         }
       })
     }, 1000)
-
+    this.getDesignList()
     getAction('/ctop/tagInfo/treeList', {
       pageSize: 10000,
     }).then((res) => {
@@ -1950,9 +2035,12 @@ export default {
         this.loadData()
       }
     },
-    'queryParam.projectId': function (n, o) {
+    'queryParam.productId': function (n, o) {
       if (n != '') {
         this.getList(n)
+        this.checkArr = []
+        this.$refs.selectTableProject.keyValue = ''
+        this.$refs.selectTableProject.getData(n)
       }
     },
     visibleDetail: function (n, o) {
@@ -1976,6 +2064,14 @@ export default {
     },
   },
   methods: {
+    // 获取设计人员
+    getDesignList() {
+      postAction('/ctop/kuaishou/videoReport/getDesignList').then((res) => {
+        if (res.success) {
+          this.designList = res.result
+        }
+      })
+    },
     changeTag(visible) {
       if (this.videoVisibleChange != visible) {
         this.videoVisibleChange = visible
@@ -2189,33 +2285,40 @@ export default {
       return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
     },
     moment,
-    tongbu() {
-      getAction('/ctop/project/queryById', { id: this.queryParam.projectId }).then((res) => {
-        console.log(res)
-        if (res.success) {
-          if (res.result.mediaId == '1' || res.result.mediaId == '3') {
-            this.$refs.check.getData('/ctop/userAllocation/getAccountListByProjectId', {
-              userId: this.userInfo().id,
-              projectId: this.queryParam.projectId,
-            })
-          } else if (res.result.mediaId == '2' || res.result.mediaId == '4') {
-            this.$refs.accountCheckBytedance.getParticipateList(this.queryParam.projectId)
-          }
-        } else {
-          this.$message.error('网络波动,请稍后再试')
-        }
-      })
+    tongbu(value) {
+      this.mediaId = value
+      // getAction('/ctop/project/queryById', { id: this.queryParam.projectId }).then((res) => {
+      //   console.log(res)
+      //   if (res.success) {
+      if (value == '1' || value == '3') {
+        this.$refs.check.getData('/ctop/userAllocation/getAccountListByUserIdAndProductId', {
+          userId: this.userInfo().id,
+          productId: this.queryParam.productId,
+          mediaId: value,
+        })
+      } else if (value == '2' || value == '4') {
+        this.$refs.accountCheckBytedance.getParticipateList(this.queryParam.productId)
+        // this.$refs.check.getData('/ctop/userAllocation/getAccountListByUserIdAndProductId', {
+        //   userId: this.userInfo().id,
+        //   productId: this.queryParam.productId,
+        //   mediaId: value,
+        // })
+      }
+      //   } else {
+      //     this.$message.error('网络波动,请稍后再试')
+      //   }
+      // })
     },
     implement(data) {
       // {treeData:data,shieldBackwardSwitch:this.shieldBackwardSwitch}
       var params = {}
       params.mediaId = this.mediaId
       params.materialArray = JSON.stringify(this.checkArr)
-      params.accountArray = data.treeData?JSON.stringify(data.treeData):JSON.stringify(data)
-      if(this.mediaId == '2'){
+      params.accountArray = data.treeData ? JSON.stringify(data.treeData) : JSON.stringify(data)
+      if (this.mediaId == '2') {
         params.shieldBackwardSwitch = data.shieldBackwardSwitch
       }
-      
+
       postAction('/ctop/materialUpload/uploadAccount', params).then((res) => {
         if (res.code == 0) {
           this.checkArr = []
@@ -2294,27 +2397,33 @@ export default {
         type: 'VIDEO',
         userId: this.userInfo().id,
         status: this.active,
+        productId: '',
       }
+      this.$refs.selectTable.keyValue = ''
+      this.$refs.selectTable.getData()
+      this.$refs.selectTableProject.keyValue = ''
+      this.$refs.selectTableProject.getData()
+      
       this.labelValue = []
 
       this.loadData(1)
     },
     getList(value) {
-      if (value) {
-        // this.mediaId = this.dataElse.filter(item => {
-        //   if (value == item.projectId) {
-        //     return item
-        //   }
-        // })[0].mediaId
-        getAction('/ctop/projectMember/participateListV2', {
-          userId: this.userInfo().id,
-          projectId: value,
-        }).then((res) => {
-          if (res.code == 0) {
-            this.mediaId = res.result.records[0].mediaId
-          }
-        })
-      }
+      // if (value) {
+      //   // this.mediaId = this.dataElse.filter(item => {
+      //   //   if (value == item.projectId) {
+      //   //     return item
+      //   //   }
+      //   // })[0].mediaId
+      //   getAction('/ctop/product/getUserProductList', {
+      //     userId: this.userInfo().id,
+      //     productId: value,
+      //   }).then((res) => {
+      //     if (res.code == 0) {
+      //       this.mediaId = res.result.records[0].mediaId
+      //     }
+      //   })
+      // }
       this.loadData()
     },
     onChangeCheckImage(checkedList) {
@@ -2382,6 +2491,7 @@ export default {
       this.id = item.id
       this.code = item.code
       this.excellent = item.excellent
+      this.allDetailData = item
       if (this.active == '2') {
         this.refuseReason = item.refuseReason
         this.refuseFile = item.refuseFile ? JSON.parse(item.refuseFile) : null
@@ -2808,10 +2918,8 @@ export default {
         this.url.list = '/ctop/materialInfo/listV2'
 
         this.queryParam = {
-          type: 'VIDEO',
-          userId: this.userInfo().id,
+          ...this.queryParam,
           status: key,
-          projectId: this.queryParam.projectId,
         }
         if (this.labelValue.length >= 1) {
           this.queryParam.tagCode = this.labelValue[this.labelValue.length - 1]

+ 10 - 0
src/views/modules/user-manage-operation/user-manage-operation-server.js

@@ -0,0 +1,10 @@
+/**
+ * @file 账户配置API
+ * @author jiayufei
+ */
+
+ export const urlAcount = 'http://118.24.244.213:8808'; // 线上
+ // export const urlAcount = 'http://apipre.tjyourong.com.cn'; // 预生产
+//  export const urlAcount = 'http://192.168.1.43:8080'; // 子安
+//  export const urlAcount = 'http://139.186.165.84:8808'; // 测试
+//  export const urlAcount = 'http://192.168.1.8:8080'; // 学超

+ 289 - 0
src/views/modules/user-manage-operation/user-manage-operation.vue

@@ -0,0 +1,289 @@
+<template>
+  <a-card class="user-manage-operation" :bordered="false">
+    <div class="table-page-search-wrapper">
+		<a-form layout="inline">
+			<a-row :gutter="24">
+				<a-col :md="6" :sm="12">
+					<a-form-item label="账号">
+						<a-input placeholder="请输入账号查询" v-model="queryParam.username"></a-input>
+					</a-form-item>
+				</a-col>
+				<a-col :md="6" :sm="12">
+					<a-form-item label="姓名">
+						<a-input placeholder="请输入姓名查询" v-model="queryParam.realname"></a-input>
+					</a-form-item>
+				</a-col>
+				<a-col :md="6" :sm="12">
+					<a-form-item label="汇报上级">
+						<a-input placeholder="请输入姓名查询" v-model="queryParam.leaderName"></a-input>
+					</a-form-item>
+				</a-col>
+				<a-col :md="6" :sm="12">
+					<a-form-item label="用户角色">
+						<a-input placeholder="请输入用户角色" v-model="queryParam.roleName"></a-input>
+					</a-form-item>
+				</a-col>
+				<a-col :md="6" :sm="12">
+					<a-form-item label="部门分配">
+						<a-tree-select
+							style="width: 100%"
+							:dropdownStyle="{ maxHeight: '200px', overflow: 'auto' }"
+							:treeData="treeData"
+							v-model="queryParam.departId"
+							placeholder="无"
+						>
+						</a-tree-select>
+					</a-form-item>
+				</a-col>
+				<a-col :md="6" :sm="8">
+					<a-form-item label="邮箱">
+						<a-input placeholder="请输入邮箱查询" v-model="queryParam.email"></a-input>
+					</a-form-item>
+				</a-col>
+				<a-col :md="6" :sm="8">
+					<a-form-item label="状态">
+						<a-select v-model="queryParam.status" placeholder="请选择用户状态查询">
+							<a-select-option value="1">正常</a-select-option>
+							<a-select-option value="2">冻结</a-select-option>
+						</a-select>
+					</a-form-item>
+				</a-col>
+				<a-col :md="6" :sm="8">
+					<span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
+						<a-button type="primary" @click="handleSearchQuery" icon="search">查询</a-button>
+						<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
+					</span>
+				</a-col>
+			</a-row>
+		</a-form>
+    </div>
+    <div>
+		<a-table
+			ref="table"
+			bordered
+			size="middle"
+			:columns="columns"
+			:dataSource="dataSource"
+			:pagination="false"
+			:loading="controlLoading"
+		>
+			<template slot="avatarslot" slot-scope="text, record">
+				<div class="anty-img-wrap">
+					<a-avatar shape="square" :src="getAvatarView(record.avatar)" icon="user"/>
+				</div>
+			</template>
+			<template slot="leaderName" slot-scope="text, record">
+				<span>{{ text ? text : '-' }}</span>
+			</template>
+			<template slot="sex" slot-scope="text, record">
+				<span>{{ text ? (text == 1 ? '男' : '女') : '未填写' }}</span>
+			</template>
+			<template slot="status" slot-scope="text, record">
+				<span>{{ text ? (text == 1 ? '正常' : '冻结') : '未填写' }}</span>
+			</template>
+			<template slot="departName" slot-scope="text, record">
+				<span>{{ text ? text : '-' }}</span>
+			</template>
+				<span slot="action" slot-scope="text, record">
+				<a @click="handleEdit(record)">编辑</a>
+			</span>
+		</a-table>
+		<a-pagination
+			class="pagin-table-class"
+			:total="totalAll"
+			:show-total="total => `共 ${totalAll} 条`"
+			size="small"
+			show-size-changer
+			show-quick-jumper
+			@change="onShowSizeChange"
+			@showSizeChange="onShowSizeChange"
+		/>
+    </div>
+    <user-modal ref="modalForm" @ok="handleModalFormOk"></user-modal>
+  </a-card>
+</template>
+<script>
+import UserModal from '@/views/system/modules/UserModal';
+
+import {mapGetters} from 'vuex';
+import {queryIdTree} from '@/api/api';
+import {getAction} from '@/api/manage';
+import {urlAcount} from './user-manage-operation-server.js';
+export default {
+    name: 'user-manage-operation',
+    components: {
+      	UserModal
+    },
+    data() {
+		return {
+			controlLoading: false,
+			dataSource: [],
+			totalAll: 0,
+			tablePag: {
+				page: 1, 
+				size: 10
+			},
+			description: '这是用户管理页面',
+			treeData: [],
+			queryParam: {},
+			columns: [
+				{
+					title: '用户账号',
+					align: 'center',
+					dataIndex: 'username',
+					width: 120
+				},
+				{
+					title: '真实姓名',
+					align: 'center',
+					width: 100,
+					dataIndex: 'realname'
+				},
+				{
+					title: '头像',
+					align: 'center',
+					width: 120,
+					dataIndex: 'avatar',
+					scopedSlots: { customRender: 'avatarslot' }
+				},
+				{
+					title: '性别',
+					align: 'center',
+					width: 80,
+					dataIndex: 'sex',
+					scopedSlots: { customRender: 'sex' },
+					sorter: true
+				},
+				{
+					title: '手机号码',
+					align: 'center',
+					width: 100,
+					dataIndex: 'phone'
+				},
+				{
+					title: '邮箱',
+					align: 'center',
+					dataIndex: 'email'
+				},
+				{
+					title: '汇报上级',
+					align: 'center',
+					dataIndex: 'leaderName',
+					scopedSlots: {customRender: 'leaderName'}
+				},
+				{
+					title: '所属部门',
+					align: 'center',
+					dataIndex: 'departName',
+					scopedSlots: {customRender: 'departName'}
+				},
+				{
+					title: '用户角色',
+					align: 'center',
+					dataIndex: 'roleName',
+					scopedSlots: {customRender: 'roleName'}
+				},
+				{
+					title: '状态',
+					align: 'center',
+					width: 80,
+					dataIndex: 'status',
+					scopedSlots: {customRender: 'status'}
+				},
+				{
+					title: '操作',
+					dataIndex: 'action',
+					scopedSlots: {customRender: 'action'},
+					align: 'center',
+					width: 170
+				}
+			]
+		}
+    },
+    created() {
+		this.$nextTick(() => {
+			this.loadTreeData();
+		});
+    },
+	mounted() {
+		this.handleGetDataInit();
+	},
+    methods: {
+		...mapGetters(['userInfo']),
+		searchReset() {
+			this.queryParam = {};
+			this.handleGetDataInit();
+		},
+		handleEdit(record, sign) {
+			this.$refs.modalForm.edit(record, sign);
+			this.$refs.modalForm.title = "编辑";
+			this.$refs.modalForm.disableSubmit = false;
+		},
+		handleSearchQuery() {
+			this.tablePag = {
+                page: 1,
+                size: 10
+            };
+			this.handleGetDataInit();
+		},
+		handleModalFormOk() {
+			this.tablePag = {
+                page: 1,
+                size: 10
+            };
+			this.handleGetDataInit();
+		},
+		handleGetDataInit() {
+			this.controlLoading = true;
+			const paramsData = this.queryParam;
+			paramsData.id = this.userInfo().id;
+			paramsData.pageNo = this.tablePag.page;
+      		paramsData.pageSize = this.tablePag.size;
+            getAction(urlAcount + '/bytedance-api/sys/user/listV2', paramsData).then(result => {
+                if (result.code === 200) {
+					this.controlLoading = false;
+					this.dataSource = result.result.list;
+					this.totalAll =  result.result.total;
+                }
+                else {
+                    this.$message.error(result.message);
+                }
+            }).catch(error => {
+                console.log(error, 'eeee');
+            });
+        },
+		onShowSizeChange(current, pageSize) {
+			console.log(current, pageSize, 'current, pageSize');
+            this.tablePag = {
+                page: current,
+                size: pageSize
+            };
+            this.handleGetDataInit();
+        },
+		loadTreeData() {
+			queryIdTree().then(res => {
+				if (res.success) {
+					this.treeData = [];
+					for (let i = 0; i < res.result.length; i++) {
+						let temp = res.result[i];
+						this.treeData.push(temp);
+					}
+				}
+			});
+		},
+		getAvatarView(avatar) {
+			return window._CONFIG['domianURL'] + '/sys/common/view' + '/' + avatar;
+		}
+    }
+};
+</script>
+<style lang="less" scoped>
+	@import '~@assets/less/common.less';
+	.user-manage-operation {
+		.pagin-table-class {
+			display: flex;
+			justify-content: flex-end;
+			margin-top: 20px;
+		}
+	}
+</style>

File diff suppressed because it is too large
+ 575 - 587
src/views/system/modules/UserModal.vue


File diff suppressed because it is too large
+ 487 - 415
src/views/user/Login.vue


+ 8 - 4
src/views/user/transferLocal.vue

@@ -137,11 +137,15 @@ export default {
   },
   mounted() {
     this.$nextTick(() => {
-      console.log(window.location.search)
-      var data = window.location.search.split('?')[1]
-      var arr = data.split('=')
+      console.log(window.location.search,this.$route.query)
+      var data = this.$route.query.corpId
+      var arr =  data.split('?')
       var json = {}
-      json[arr[0]] = arr[1]
+      json.corpId = arr[0]
+      json[arr[1].split('=')[0]] = arr[1].split('=')[1]
+      // var arr = data.split('=')
+      // var json = {}
+      // json[arr[0]] = arr[1]
       var params = qs.stringify(json)
       postAction('/sys/wxlogin', params).then(res => {
         console.log(res)

+ 45 - 45
vue.config.js

@@ -61,53 +61,53 @@ module.exports = {
     }
   },
 
-  devServer: {
-    hot:true,
-    // inline: true,
-    port: 3000,
-    open : true,
-    proxy: {
-      '/jeecg-boot': {
-          // target: 'http://192.168.1.8:8080', //请求本地 需要jeecg-boot后台项目  蒙蒙
-          // target: 'http://192.168.1.3:8080', //请求本地 需要jeecg-boot后台项目  蒙蒙
-        // target: 'http://192.168.0.59:8088', //请求本地 需要jeecg-boot后台项目  英豪
-        // target: 'http://192.168.1.62:8088', //请求本地 需要jeecg-boot后台项目  英豪
-        // target: 'http://192.168.6.162:8806', //请求本地 需要jeecg-boot后台项目  祚云
-        // target: 'http://192.168.1.43:8098', //请求本地 需要jeecg-boot后台项目  毕洁泉
-        // target: 'http://192.168.1.43:8088', //请求本地 需要jeecg-boot后台项目  毕洁泉
-        // target: 'http://192.168.1.43:8806', //请求本地 需要jeecg-boot后台项目  毕洁泉
-        // target: 'http://192.168.0.252:8098', //请求本地 需要jeecg-boot后台项目  毕洁泉
-        // target: 'http://192.168.1.219:8081', //请求本地 需要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: '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://192.168.1.43:8080', // 子安
-        // target: 'http://192.168.1.8:8806', // 学超
-       target:'http://139.186.165.84:8806', //测试
-        // target:'http://apipre.tjyourong.com.cn', //预生产
+	devServer: {
+		hot:true,
+		// inline: true,
+		port: 3000,
+		open : true,
+		proxy: {
+			'/jeecg-boot': {
+				// target: 'http://192.168.1.8:8080', //请求本地 需要jeecg-boot后台项目  蒙蒙
+				// target: 'http://192.168.1.3:8080', //请求本地 需要jeecg-boot后台项目  蒙蒙
+				// target: 'http://192.168.0.59:8088', //请求本地 需要jeecg-boot后台项目  英豪
+				// target: 'http://192.168.1.62:7001', //请求本地 需要jeecg-boot后台项目  英豪
+				// target: 'http://192.168.6.162:9806', //请求本地 需要jeecg-boot后台项目  祚云
+				// target: 'http://192.168.1.43:8098', //请求本地 需要jeecg-boot后台项目  毕洁泉
+				// target: 'http://192.168.1.43:8088', //请求本地 需要jeecg-boot后台项目  毕洁泉
+				// target: 'http://192.168.1.43:8806', //请求本地 需要jeecg-boot后台项目  毕洁泉
+				// target: 'http://192.168.0.252:8098', //请求本地 需要jeecg-boot后台项目  毕洁泉
+				// target: 'http://192.168.1.219:8081', //请求本地 需要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: '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://192.168.1.43:9090', // 子安
+				// target: 'http://192.168.1.8:8806', // 学超
+				// target:'http://139.186.165.84:8806', //测试
+				// target:'http://apipre.tjyourong.com.cn', //预生产
 
-        ws: false,
+				ws: false,
 
-        // changeOrigin: true,
-        // pathRewrite: {
-        //     '/jeecg-boot': ''  //默认所有请求都加了jeecg-boot前缀,需要去掉
-        // }
-      },
-    },
-    // before(app) {
-    //     app.get('/seller', (req, res) => {
-    //         res.json({
-    //           errno: 0,
-    //           data: appData
-    //         })//接口返回json数据,上面配置的数据seller就赋值给data请求后调用
-    //     })
-    // }
-  },
+				// changeOrigin: true,
+				// pathRewrite: {
+				//     '/jeecg-boot': ''  //默认所有请求都加了jeecg-boot前缀,需要去掉
+				// }
+			},
+		},
+		// before(app) {
+		//     app.get('/seller', (req, res) => {
+		//         res.json({
+		//           errno: 0,
+		//           data: appData
+		//         })//接口返回json数据,上面配置的数据seller就赋值给data请求后调用
+		//     })
+		// }
+	},
 
   lintOnSave: undefined,
 //   publicPath:'./',