ソースを参照

Merge branch 'master' of http://git.tjyourong.com.cn/ctop/adsp-vue

朱鑫波 4 年 前
コミット
c3e02898ed
31 ファイル変更8268 行追加150 行削除
  1. 3 1
      public/color.less
  2. 5 0
      src/App.vue
  3. BIN
      src/assets/logoNew.png
  4. BIN
      src/assets/logoNew1.png
  5. 58 26
      src/components/menu/SideMenu.vue
  6. 12 6
      src/components/page/GlobalHeader.vue
  7. 11 2
      src/components/page/GlobalLayout.vue
  8. 27 4
      src/components/tools/Logo.vue
  9. 18 6
      src/mixins/JeecgListMixin.js
  10. 2 2
      src/utils/request.js
  11. 14 0
      src/views/dashboard/Analysis.vue
  12. 2 8
      src/views/modules/BatchCreate/TouTiaoBatch.vue
  13. 8 1
      src/views/modules/BatchCreate/components/material.vue
  14. 1 1
      src/views/modules/BatchCreate/linkMultiSelect.vue
  15. 703 0
      src/views/modules/LaunchHousekeeper/LaunchHousekeeperList.vue
  16. 1029 0
      src/views/modules/LaunchHousekeeper/material.vue
  17. 666 0
      src/views/modules/LaunchHousekeeper/newProject.vue
  18. 237 0
      src/views/modules/LaunchHousekeeper/radioCheck.vue
  19. 658 0
      src/views/modules/LaunchHousekeeper/setProjectBudget.vue
  20. 716 0
      src/views/modules/LaunchHousekeeper/setProjectConvert.vue
  21. 1819 0
      src/views/modules/LaunchHousekeeper/setProjectCreate.vue
  22. 1068 0
      src/views/modules/LaunchHousekeeper/setProjectDirectional.vue
  23. 127 13
      src/views/modules/Statistics/Statistics.vue
  24. 1 5
      src/views/modules/Statistics/accountReport.vue
  25. 209 0
      src/views/modules/Statistics/components/datePick.vue
  26. 4 1
      src/views/modules/Statistics/components/lifting.vue
  27. 769 0
      src/views/modules/Statistics/imageStatics/imageCostReport.vue
  28. 57 30
      src/views/modules/Statistics/newHome.vue
  29. 38 38
      src/views/modules/material/labelMaterial.vue
  30. 3 4
      src/views/modules/material/videoMaterial.vue
  31. 3 2
      vue.config.js

+ 3 - 1
public/color.less

@@ -2216,7 +2216,9 @@ this.tinycolor = tinycolor;
 }
 
 .layout .header {
-  background-color: @primary-color !important;
+  // background-color:#0B2040  !important;
+  background:#0B2040  !important;
+  
 }
 
 i.trigger:hover {

+ 5 - 0
src/App.vue

@@ -60,4 +60,9 @@
     height: 39px !important;
     border-bottom:1px solid #1890ff !important;
   }
+  .layout .header {
+ background-color:#0B2040  !important;
+  background:#0B2040  !important;
+  
+}
 </style>

BIN
src/assets/logoNew.png


BIN
src/assets/logoNew1.png


+ 58 - 26
src/components/menu/SideMenu.vue

@@ -146,32 +146,64 @@
 
 <!-- update_begin author:sunjianlei date:20190530 for: 选中首页的时候不显示背景颜色 -->
 <style lang="less">
-  .ant-menu.ant-menu-root {
-    & > .ant-menu-item:first-child {
-      background-color: transparent;
-
-    //   & > a, & > a:hover {
-    //     color: rgba(0, 0, 0, 0.65);
-    //   }
-
-    //   &.ant-menu-item-selected {
-    //     & > a, & > a:hover {
-    //       color: @primary-color;
-    //     }
-    //   }
-    }
+  // .ant-menu.ant-menu-root {
+  //   & > .ant-menu-item:first-child {
+  //     background-color: transparent;
+
+  //   //   & > a, & > a:hover {
+  //   //     color: rgba(0, 0, 0, 0.65);
+  //   //   }
+
+  //   //   &.ant-menu-item-selected {
+  //   //     & > a, & > a:hover {
+  //   //       color: @primary-color;
+  //   //     }
+  //   //   }
+  //   }
+
+  //   &.ant-menu-dark > .ant-menu-item:first-child {
+  //     & > a, & > a:hover {
+  //       color: rgba(255, 255, 255, 0.65);
+  //     }
+
+  //     &.ant-menu-item-selected {
+  //       & > a, & > a:hover {
+  //         color: rgba(255, 255, 255, 1);
+  //       }
+  //     }
+  //   }
+  // }
+</style>
+<!-- update_end author:sunjianlei date:20190530 for: 选中首页的时候不显示背景颜色 -->
 
-    &.ant-menu-dark > .ant-menu-item:first-child {
-      & > a, & > a:hover {
-        color: rgba(255, 255, 255, 0.65);
-      }
+<!--侧边栏的选中after显示在左侧 -->
 
-      &.ant-menu-item-selected {
-        & > a, & > a:hover {
-          color: rgba(255, 255, 255, 1);
-        }
-      }
-    }
+<style lang="less">
+  ul.ant-menu-inline li.ant-menu-selected::after, ul.ant-menu-vertical li.ant-menu-selected::after,ul.ant-menu-vertical li.ant-menu-item-selected::after,ul.ant-menu-inline li.ant-menu-item-selected::after {
+      -webkit-transform: scaleY(1);
+      transform: scaleY(1);
+      opacity: 1;
+      -webkit-transition: opacity 0.15s cubic-bezier(0.645, 0.045, 0.355, 1), -webkit-transform 0.15s cubic-bezier(0.645, 0.045, 0.355, 1);
+      transition: opacity 0.15s cubic-bezier(0.645, 0.045, 0.355, 1), -webkit-transform 0.15s cubic-bezier(0.645, 0.045, 0.355, 1);
+      transition: transform 0.15s cubic-bezier(0.645, 0.045, 0.355, 1), opacity 0.15s cubic-bezier(0.645, 0.045, 0.355, 1);
+      transition: transform 0.15s cubic-bezier(0.645, 0.045, 0.355, 1), opacity 0.15s cubic-bezier(0.645, 0.045, 0.355, 1), -webkit-transform 0.15s cubic-bezier(0.645, 0.045, 0.355, 1);
   }
-</style>
-<!-- update_end author:sunjianlei date:20190530 for: 选中首页的时候不显示背景颜色 -->
+  .ant-menu-inline li.ant-menu-item::after ,.ant-menu-vertical li.ant-menu-item::after ,.ant-menu-vertical li.ant-menu-item::after{
+    display: block;
+    position: absolute;
+    top: 0;
+    left: 0px;
+    right: 0;
+    bottom: 0;
+    border-left: 3px solid #1890ff;
+    border-right: 0px ;
+    -webkit-transform: scaleY(0.0001);
+    transform: scaleY(0.0001);
+    opacity: 0;
+    -webkit-transition: opacity 0.15s cubic-bezier(0.215, 0.61, 0.355, 1), -webkit-transform 0.15s cubic-bezier(0.215, 0.61, 0.355, 1);
+    transition: opacity 0.15s cubic-bezier(0.215, 0.61, 0.355, 1), -webkit-transform 0.15s cubic-bezier(0.215, 0.61, 0.355, 1);
+    transition: transform 0.15s cubic-bezier(0.215, 0.61, 0.355, 1), opacity 0.15s cubic-bezier(0.215, 0.61, 0.355, 1);
+    transition: transform 0.15s cubic-bezier(0.215, 0.61, 0.355, 1), opacity 0.15s cubic-bezier(0.215, 0.61, 0.355, 1), -webkit-transform 0.15s cubic-bezier(0.215, 0.61, 0.355, 1);
+    content: '';
+}
+</style>

+ 12 - 6
src/components/page/GlobalHeader.vue

@@ -17,8 +17,8 @@
         :type="collapsed ? 'menu-unfold' : 'menu-fold'"
         @click.native="toggle"/>
 
-      <span v-if="device === 'desktop'">欢迎使用汇创投放助手</span>
-      <span v-else>汇创投放助手</span>
+      <!-- <span v-if="device === 'desktop'">欢迎使用汇创投放助手</span> -->
+      <!-- <span v-else>汇创投放助手</span> -->
 
 
       <user-menu :theme="theme"/>
@@ -166,7 +166,12 @@
   /* update_begin author:scott date:20190220 for: 缩小首页布局顶部的高度*/
 
   $height: 59px;
-
+    .layout .header .user-wrapper .action .anticon, .layout .top-nav-header-index .user-wrapper .action .anticon {
+        color: #999;
+    }
+    .layout .header .user-wrapper .action .anticon, .layout .top-nav-header-index .user-wrapper .action .anticon {
+        color: #999;
+    }
   .layout {
 
     .top-nav-header-index {
@@ -181,8 +186,8 @@
       }
 
       .trigger {
-        line-height: 64px;
-
+        line-height: 48px;
+        font-size: 17px;
         &:hover {
           background: rgba(0, 0, 0, 0.05);
         }
@@ -191,7 +196,7 @@
 
     .header {
       z-index: 2;
-      color: white;
+      color: #999;
       height: $height;
       background-color: #1890ff;
       transition: background 300ms;
@@ -202,6 +207,7 @@
         box-shadow: 0 0 4px rgba(0, 0, 0, 0.2);
         background-color: white !important;
       }
+
     }
 
     .header, .top-nav-header-index {

+ 11 - 2
src/components/page/GlobalLayout.vue

@@ -181,7 +181,15 @@
       filter: invert(80%);
     }
   }
-
+  .layout .header .user-wrapper .action i.anticon, .layout .top-nav-header-index .user-wrapper .action i.anticon {
+        color: #999;
+  }
+  .layout .header .user-wrapper .action:hover i.anticon, .layout .top-nav-header-index .user-wrapper .action:hover i.anticon {
+        color: #fff;
+  }
+  .layout .header .user-wrapper .action:hover, .layout .top-nav-header-index .user-wrapper .action:hover {
+        color: #fff;
+  }
   .layout {
     min-height: 100vh !important;
     overflow-x: hidden;
@@ -239,7 +247,7 @@
     }
 
     .trigger {
-      font-size: 22px;
+      font-size: 17px;
       line-height: 42px;
       padding: 0 18px;
       cursor: pointer;
@@ -247,6 +255,7 @@
 
       &:hover {
         background: rgba(255, 255, 255, 0.3);
+        color:#fff
       }
     }
 

+ 27 - 4
src/components/tools/Logo.vue

@@ -1,8 +1,9 @@
 <template>
   <div class="logo">
     <router-link :to="{name:'dashboard'}">
-      <img src="~@/assets/logo.png" alt="logo">
-      <h1 v-if="showTitle">{{ title }}</h1>
+      <img src="~@/assets/logoNew1.png" alt="logo">
+      <span class="name">有腾投放管家</span>
+      <!-- <h1 v-if="showTitle">{{ 有腾管家 }}</h1> -->
     </router-link>
   </div>
 </template>
@@ -49,7 +50,29 @@
     }
 
     &.light .logo {
-      background-color: #1890ff;
+      background-color: #0B2040;
     }
   }
-</style>
+.logo{
+  .name{
+    font-size: 14px;
+    font-family: PingFangSC-Medium, PingFang SC;
+    font-weight: 500;
+    color: #CED2D9;
+    // line-height: 22px;
+    margin-left: 20px;
+    padding-left: 21px;
+    position: relative;
+  }
+  .name::before{
+    content: '';
+    width: 1px;
+    height: 18px;
+    background: rgba(255, 255, 255, 0.31);
+    position: absolute;
+    left: 0;
+    top: 50%;
+    margin-top: -9px;
+  }
+}
+</style>

+ 18 - 6
src/mixins/JeecgListMixin.js

@@ -121,15 +121,27 @@ export const JeecgListMixin = {
       this.loading = true;
       await getAction(this.url.list, params).then((res) => {
         if (res.success) {
+          if(res.result.records){
             this.dataSource = res.result.records.map(item=>{
-                return {
-                    ...item,
-                    innerData:[],
-                    showVideo:false
-                }
+              return {
+                  ...item,
+                  innerData:[],
+                  showVideo:false
+              }
             })
             this.ipagination.total = res.result.total;
-            this.spinning= false
+          }else{
+            this.dataSource = res.result.map(item=>{
+              return {
+                  ...item,
+                  innerData:[],
+                  showVideo:false
+              }
+            })
+            // this.ipagination = null;
+            this.ipagination.pageSize=res.result.length
+          }
+            
         }
         if (res.code === 510) {
           this.$message.warning(res.message)

+ 2 - 2
src/utils/request.js

@@ -13,8 +13,8 @@ if (process.env.NODE_ENV == 'development') {
 else if (process.env.NODE_ENV == 'debug') { 
 } 
 else if (process.env.NODE_ENV == 'production') { 
-    // axios.defaults.baseURL = 'http://192.168.1.251/jeecg-boot';
-axios.defaults.baseURL = 'http://api.tjyourong.com.cn/jeecg-boot';
+    axios.defaults.baseURL = 'http://192.168.1.251/jeecg-boot';
+// axios.defaults.baseURL = 'http://api.tjyourong.com.cn/jeecg-boot';
 }
 const service = axios.create({
 //   baseURL: '/jeecg-boot', // api base_url

+ 14 - 0
src/views/dashboard/Analysis.vue

@@ -1,6 +1,10 @@
 <style lang='scss'>
     .only-there .ant-tabs-bar{
         background: white;
+        padding: 0 24px;
+    }
+    .ant-card-head .ant-tabs-bar{
+      padding: 0;
     }
     #updateInfo .ant-modal-content,#updateInfo .ant-modal-body {
       
@@ -516,4 +520,14 @@
       }
     }
   }
+</style>
+<style lang="less">
+  .ant-tabs-bar {
+    margin: 0 0 12px 0;
+    /* height: 55px; */
+    border-bottom: 1px solid #e8e8e8;
+    outline: none;
+    -webkit-transition: padding 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
+    transition: padding 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
+}
 </style>

+ 2 - 8
src/views/modules/BatchCreate/TouTiaoBatch.vue

@@ -607,7 +607,7 @@ export default {
 
             spinning:false,
             moment,
-            loading:false,
+           
             accountID:undefined,
             openID:undefined,
             treeData:[],
@@ -631,7 +631,7 @@ export default {
             columns,
             selectedRowKeys:[],
             selectedRows:[],
-
+            loading:false,
             editID:0,
             //批量修改里的表格
             typeValue,
@@ -945,12 +945,6 @@ export default {
                 this.$message.error('请选择账户后重试')
             }
 
-
-            // postAction('',{
-
-            // }).then((res)=>{
-            //     console.log(res)
-            // })
         },
         //点击分页
         sort(pagination, filters, sorter, { currentDataSource }){

+ 8 - 1
src/views/modules/BatchCreate/components/material.vue

@@ -733,8 +733,15 @@
       getTags() {
         let accountInfo = localStorage.getItem('accountInfo')
         // console.log(groupInfo)
+        let LHKaccountInfo=sessionStorage.getItem('LHKaccountInfo');
+        
+        if(accountInfo){
+          this.accountInfo=JSON.parse(accountInfo)
+        }else if(LHKaccountInfo){
+          this.accountInfo=JSON.parse(LHKaccountInfo)[1]
+        }
 
-        this.accountInfo=JSON.parse(accountInfo)
+        
 
         getAction('/bytedance/batch/creative/words/get', {
           accountId: this.accountInfo.value

+ 1 - 1
src/views/modules/BatchCreate/linkMultiSelect.vue

@@ -569,7 +569,7 @@
                 parentCode:0,
                 level:this.maxLayers
             }).then((res)=>{
-                // console.log(res);
+                console.log(res);
                 if(res.success){
                     res.data.forEach((item,index)=>{
                         item.value=item.code

+ 703 - 0
src/views/modules/LaunchHousekeeper/LaunchHousekeeperList.vue

@@ -0,0 +1,703 @@
+<template>
+    <div class="housekeeper">
+         <div class="topOptions">
+            <span class="OptinItem topOpt">
+                <!-- <Treeselect :appId.sync="accountID" :multiple="false" request="2,4" reqUrl='/ctop/projectMember/getProjectAccountByUserId' ref="treeSelect" style="margin-bottom:8px " /> -->
+
+                <a-tree-select
+                    v-model="accountIds"
+                    show-search
+                    style="width: 600px;height:30px"
+                    :dropdownMatchSelectWidth='true'
+                    :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"              
+                    tree-checkable
+                    searchPlaceholder='请输入账户关键字搜索'
+                    :show-checked-strategy="SHOW_PARENT"
+                    placeholder="请选择项目和账户或搜索账户关键字"
+                    treeNodeFilterProp="title"
+                    :allowClear="true"
+                    @change="treeChange"
+                                       
+                    :maxTagCount='1'    
+                    :tree-data="treeData"
+                    :filterOption='filterOption'
+                >
+              
+                </a-tree-select>
+            </span>
+            <span class="OptinItem">
+                <a-select  style="width: 120px" v-model="statusValue" @change="statusChange" placeholder="请选择状态">
+                    <a-select-option :value="0" >
+                        不限
+                    </a-select-option>
+                    <a-select-option :value="1" >
+                        启用
+                    </a-select-option>
+                    <a-select-option :value="2" >
+                        暂停
+                    </a-select-option>
+                </a-select>
+            </span>
+
+            <span class="OptinItem">
+                <!-- <a-date-picker @change="dateChange" /> -->
+                 <a-range-picker v-model="dateValue" :disabled-date="disabledDate"  style="width: 250px;" format="YYYY-MM-DD" @change="dateChange" />
+            </span>
+            <span class="OptinItem">
+                <a-input-search placeholder="请输入投放项目的名称" v-model="optionId" style="width: 200px"  />
+            </span>
+            <span class="optionBtn">
+                <a-button type='primary' @click="search" class="searchBtn">查询</a-button>
+                <!-- <a-button type='default' @click="reset">重置</a-button> -->
+            </span>
+        </div>
+        <div class="tableArea">
+            <div class="tableOption">
+                <span class="OptinItem" style="margin-right:20px">
+                    <a-button type='primary' @click="addNewProject">
+                        <a-icon type="plus" />
+                        新增投放项目
+                    </a-button>
+                </span>
+                <span class="OptinItem">
+                    <a-tooltip>
+                        <template slot="title" >
+                            这里可以批量启动、暂停、删除你的选择哦~
+                        </template>
+                        <!-- <a-button type="link" @click="changeSelectStatus">批量操作</a-button> -->
+                        <span >批量操作:</span>
+                    </a-tooltip>
+                </span>
+                <span class="OptinItem">
+                    <a-select  style="width: 120px" @change="optChange" v-model="optValue" placeholder="请选择状态" :disabled='selectedRowKeys.length<=0'>
+                        <a-select-option value="open" >
+                            启动
+                        </a-select-option>
+                        <a-select-option value="pause">
+                            暂停
+                        </a-select-option>
+                        <a-select-option value="delete">
+                            删除
+                        </a-select-option>
+                    </a-select>
+                </span>
+                 <span class="OptinItem">
+                    <a-popconfirm
+                        title="确定要删除选择的内容吗?"
+                        ok-text="删除"
+                        cancel-text="取消"
+                        @confirm="confirm"
+                        @cancel="cancel"
+                        v-if="optValue=='delete'"
+                    >
+                        <a-button type='primary' @click="isOkHandle" class="ok">确定</a-button>
+                    </a-popconfirm>
+                    <a-button type='primary' @click="isOkHandle" class="ok" v-else>确定</a-button>
+
+                 </span>
+                <!-- <span class="optionBtn">
+                    <a-button type='primary' @click="reset">自定义列</a-button>
+                </span> -->
+            </div>
+            <div class="table">
+                <a-table
+                    :columns="columns"
+                    :data-source="data"
+                    :rowSelection="{selectedRowKeys: selectedRowKeys,...rowSelection}"
+                    bordered
+                    :pagination="ipagination"
+                    :loading="loading"
+                    @change="sort"
+                    
+                >
+                   
+
+                    <span slot="checkedStatus" slot-scope="text,record">
+                        <a-spin :spinning="record.spin" size="small" >
+                            <div class="spin-content">
+                                <a-switch size="default" :checked=text  @change="switchChange(text,record)"/>
+                            </div>
+                        </a-spin>    
+                        <!-- <a-switch size="default" :checked=text  @change="switchChange(text,record)"/>                     -->
+                    </span>
+
+                    <span slot="budgetMode" slot-scope="text">
+                        <span v-if="text=='DAILY'">日预算</span>
+                        <span v-if="text=='TOTAL'">总预算</span>
+                    </span>
+                    
+                  
+                    <span slot="parentGroup" slot-scope="text">
+                        <a href="javascript:;" >{{text}}</a>
+                    </span>
+                    <span slot="parentPlan" slot-scope="text">
+                        <a href="javascript:;" >{{text}}</a>
+                    </span>
+                    <span slot="time" slot-scope="text,record">
+                        {{record.startTime}}至{{record.endTime}}
+                    </span>
+                    <span slot="flowControlMode" slot-scope="text">
+                        <span v-if="text=='FLOW_CONTROL_MODE_FAST'">优先跑量</span>
+                        <span v-if="text=='FLOW_CONTROL_MODE_SMOOTH'">优先低成本</span>
+                        <span v-if="text=='FLOW_CONTROL_MODE_BALANCE'">均衡投放</span>
+                    </span>
+
+                    <span slot="options" slot-scope="text,record">
+                        <a href="javascript:;" @click="editProject(record)">编辑</a>
+                        <a-divider type="vertical" />
+                        <a href="javascript:;" @click="planAnalysis(record)">计划分析</a>
+                        <a-divider type="vertical" />
+                        <a-popconfirm
+                            title="确定删除该投放项目吗?"
+                            @confirm="deleteProject(record)"                            
+                        >
+                            <a href="javascript:;" >删除</a>
+                        </a-popconfirm>
+                        
+                    </span>
+                </a-table>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+import moment from 'moment';
+import { getAction, postAction, downFile, downFilePost } from '@/api/manage';
+const SHOW_PARENT = TreeSelect.SHOW_PARENT;
+import { TreeSelect } from 'ant-design-vue';
+import qs from 'qs'
+const columns = [
+  {
+    title: '开关',
+    dataIndex: 'checkedStatus',
+    key: 'checkedStatus',
+    align: 'center',
+    scopedSlots: { customRender: 'checkedStatus' }
+  },
+  {
+    title: '投放项目名称',
+    dataIndex: 'name',
+    key: 'name',
+    align: 'center',
+    scopedSlots: { customRender: 'name' }
+  },
+  {
+    title: '投放项目状态',
+    dataIndex: 'statusName',
+    key: 'statusName',
+    align: 'center',
+  },
+    //   {
+    //     title: '建议',
+    //     dataIndex: 'landingType_dictText',
+    //     key: 'landingType_text',
+    //     align: 'center',
+    //   },
+  {
+    title: '投放项目预算类型',
+    dataIndex: 'budgetMode',
+    key: 'budgetMode',
+    align: 'center',
+    width:250,
+    scopedSlots: { customRender: 'budgetMode' }
+  },
+  {
+    title: '投放项目预算(元)',
+    dataIndex: 'budget',
+    key: 'budget',
+    align: 'center',
+    scopedSlots: { customRender: 'budget' }
+  },
+  {
+    title: '投放时间',
+    dataIndex: 'time',
+    key: 'time',
+    align: 'center',
+    scopedSlots: { customRender: 'time' }
+  },
+  {
+    title: '投放项目ID',
+    dataIndex: 'id',
+    key: 'id',
+    align: 'center',
+    scopedSlots: { customRender: 'id' }
+  },
+  {
+    title: '所属账户ID',
+    dataIndex: 'accountId',
+    key: 'accountId',
+    align: 'center',
+    scopedSlots: { customRender: 'accountId' }
+  },
+  {
+    title: '操作',
+    dataIndex: 'options',
+    key: 'options',
+    align: 'center',
+    width:200,
+    scopedSlots: { customRender: 'options' }
+  },
+];
+
+export default {
+    data() {
+        return {
+            treeData: [],
+            SHOW_PARENT,
+            accountIds:[],
+            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;
+                }
+            },
+
+            accountID:undefined,
+            treeData:[],
+            dateValue:[],//日期选择框选择
+            dateString:[],//--我赋值的是dateString
+
+
+            statusValue:undefined,
+            optionId:'',//input输入的id或关键词
+            optValue:undefined,
+
+            data:[],
+            columns,
+            selectedRowKeys:[],
+            selectedRows:[],
+            loading:false,
+            userInfo:{},
+        }
+    },
+    computed: {
+        rowSelection(){
+            return {
+                onChange: (selectedRowKeys, selectedRows) => {
+                    // console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
+                    this.selectedRowKeys=selectedRowKeys;
+                    this.selectedRows=selectedRows;
+                },
+                onSelect: (record, selected, selectedRows) => {
+                    // console.log(record, selected, selectedRows);
+                    this.modifyTableData=selectedRows;
+
+                    this.selectedRows=selectedRows;
+                },
+                onSelectAll: (selected, selectedRows, changeRows) => {
+                    // console.log(selected, selectedRows, changeRows);
+                    this.modifyTableData=selectedRows
+                    this.selectedRows=selectedRows;
+                },
+            }
+
+        },
+    },
+    methods:{
+         // //项目改变后的事件
+        treeChange(val) {
+        // console.log(this.treeData)
+        console.log(val)
+        this.accountIds = [];
+        //选择一个后禁用其他
+        if(val.length==1){
+            if(val[0]*1){
+                let selectindex=0
+                this.treeData.forEach((ele,index)=>{                   
+                    if(ele.children){
+                        ele.children.map((item,ind)=>{
+                                if(item.value==val[0]){
+                                    selectindex=index;
+                                }
+                        })
+                    }                   
+                });
+                // console.log(selectindex)
+                if(selectindex ||selectindex==0){
+                    this.treeData.forEach((ele,index)=>{
+                        if(index!=selectindex){
+                            ele.disableCheckbox = true;
+                            if(ele.children){
+                                ele.children.map((item,ind)=>{
+                                    item.disableCheckbox = true;
+                                })
+                            }
+                        }
+                    })
+                }
+                
+            }else{
+                //  console.log(1)
+                this.treeData.forEach((ele,index)=>{
+                        if(ele.value!=val[0]){
+                            ele.disableCheckbox = true;
+                            
+                            if(ele.children){
+                                ele.children.forEach((item,ind)=>{
+                                    item.disableCheckbox = true;
+                                })
+                            }
+                        }
+                        
+                })
+            }
+            // console.log(this.mediaId)
+            
+        }
+
+            if(val.length==0){
+                this.treeData.forEach((ele,index)=>{              
+                        ele.disableCheckbox = false;
+                        
+                        if(ele.children){
+                            ele.children.forEach((item,ind)=>{
+                                item.disableCheckbox = false;
+                            })
+                        }
+                    
+                });
+                
+            }
+        if(val){
+            val.forEach((ele,index)=>{
+            if(ele*1){
+                this.accountIds.push(ele)
+            }else{              
+                let projectArr=this.treeData.filter((item)=>{
+                    return item.value==ele
+                });
+                // console.log(projectArr)
+                projectArr[0].children.forEach((element)=>{
+                    this.accountIds.push(element.value)
+                })
+            }
+
+
+            })       
+        }
+        
+        console.log(this.accountIds);
+        let LHKaccountInfo=[]
+        this.accountIds.forEach(item=>{
+            this.treeData.forEach(element=>{
+                element.children.forEach(ele=>{
+                if(item==ele.value){
+                    LHKaccountInfo.push(ele)
+                }
+                })
+            })
+        })
+
+        
+        },
+        
+        
+        filterOption(input, option){
+        console.log(input, option)
+        return (
+            option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
+            );
+        },
+    
+        //请求项目和账户内容
+        accountHttp(){
+            this.treeData=[];
+            this.accountIds=[];
+            getAction('/ctop/projectMember/getProjectAccountByUserId?mediaType=1', {}).then(res => {
+            if(res.success){
+                    // console.log(res);
+                    if(res.result){
+                        res.result.forEach((element,index) => {
+                        if(element){                  
+                            this.treeData.push({});                    
+                            this.treeData[index].title=element.project.projectName +'_('+ element.project.advertiserName +')';
+                            this.treeData[index].value='project'+element.project.projectId;
+                            this.treeData[index].key=element.project.projectId;
+                            this.treeData[index].mediaId=element.project.mediaId;
+                            this.treeData[index].children=[];
+                                                
+                            if(element.account.length){
+                            element.account.forEach((ele,i)=>{
+                                this.treeData[index].children.push({});
+                                this.treeData[index].children[i].title=ele.userName+'_'+ele.authName;
+                                this.treeData[index].children[i].value=ele.accountId;
+                                this.treeData[index].children[i].key=ele.accountId;
+                            })
+                                
+                            }                           
+                        }      
+                        });
+                        // console.log(this.treeData)
+                        
+                    }
+            }
+            })
+        },
+
+        //状态改变
+        statusChange(value){
+            console.log(value);
+
+        },
+
+        disabledDate(current) {
+            // console.log(current)
+            return current && current > moment().subtract(1, 'day')
+        },
+
+        dateChange(date, dateString) {
+            console.log(date, dateString);
+            this.dateString=dateString;
+        },
+
+        search(){
+            // console.log(this.accountID,this.dateString,this.statusValue,this.optionId);
+
+            if(this.accountIds.length>0){
+                this.loading=true
+                
+                this.tableListHttp()
+                
+            }else{
+                this.$message.error('请选择账户后重试')
+            }
+
+        },
+
+           //批量操作下的启动 删除 暂停
+        optChange(value){
+            // console.log(value)
+            this.optValue=value;
+        },
+
+         //确定删除
+        confirm(e) {
+            // console.log(e);
+            this.loading=true;
+            if(this.optValue=='delete'){
+                
+                let params=[];
+                params=this.selectedRows.map(item=>{
+                    return {
+                        accountId:item.accountId,
+                        groupId:item.id,    
+                        userId:this.userInfo.value.id,
+                        optStatus:'DELETED',                   
+                    }
+                })
+                this.batchEditStatus(params)
+            }
+        },
+
+         //批量操作的确定按钮
+        isOkHandle(){
+            console.log(this.optValue,this.selectedRows)
+            if(this.optValue&&this.selectedRowKeys.length>0){
+                let params=[];
+                params=this.selectedRows.map(item=>{
+                    return {
+                        accountId:item.accountId,
+                        groupId:item.id,
+                        userId:this.userInfo.value.id,
+                        optStatus:'DELETED',
+                    }
+                })
+            
+                if(this.optValue=='pause'){   
+                    this.loading=true;
+                    params.forEach(item=>{
+                        item.optStatus='DISABLED';
+                    })
+                    // this.batchEditStatus(params)
+                }else if(this.optValue=='open'){
+                   params.forEach(item=>{
+                        item.optStatus='ENABLED';
+                    })
+                    // this.batchEditStatus(params)
+                }
+              
+                this.batchEditStatus(params)
+                
+            }
+            
+
+        },
+
+        sort(pagination, filters, sorter, { currentDataSource }){
+            
+            this.ipagination.current=pagination.current;
+
+            this.ipagination.pageSize=pagination.pageSize;
+            this.search()
+        },
+
+        batchEditStatus(params){
+            this.loading=true;
+            postAction('/adlab/ctopAdlabProjectDetail/edit',params).then(res=>{
+                console.log(res)
+                if(res.success){
+                    this.$message.success('修改成功');
+                    this.tableListHttp();
+                }else{
+                    this.$message.success('修改失败');
+                    this.loading=false;
+
+                }
+                this.selectedRows=[];
+                this.selectedRowKeys=[];
+            })
+        },
+         //状态改变
+        switchChange(text,record){
+            // this.spinning=true;
+            console.log(text,record);
+            let recordData=JSON.parse(JSON.stringify(record))
+            record.spin=true;
+
+            let params=[];
+            params.push({
+                userId:this.userInfo.value.id,
+                accountId:record.accountId,
+                groupId:record.id,
+                optStatus:record.optStatus=="DISABLED"?'ENABLED':'DISABLED'
+            })
+            
+            postAction('/adlab/ctopAdlabProjectDetail/edit',params).then(res=>{
+                console.log(res)
+                record.spin=false;
+                if(res.success){
+                    this.$message.success('修改成功');
+                    record.checkedStatus=!record.checkedStatus
+                }else{
+                    this.$message.success('修改失败')
+                }
+            })
+
+        },
+
+        // 新增投放项目
+        addNewProject(){
+            this.$router.push({path:'/LaunchHousekeeper/newProject'})
+        },
+
+        editProject(records){
+            console.log(records);
+            sessionStorage.setItem('editLHKProjectInfo',JSON.stringify(records));
+            this.$router.push({path:'/LaunchHousekeeper/setProjectBudget'})
+        },
+        planAnalysis(records){
+            console.log(records)
+        },
+        deleteProject(records){
+            console.log(records);
+          
+            let params=[];
+             params.push({
+                userId:this.userInfo.value.id,
+                accountId:records.accountId,
+                groupId:records.id,
+                optStatus:'DELETED'
+            })
+            
+            this.batchEditStatus(params)
+
+            
+        },
+
+        // 请求账户的列表
+        tableListHttp(){
+            // let accountIds=JSON.stringify(this.accountIds)     
+            // let createTime=JSON.stringify(this.dateString)      
+            postAction('/adlab/ctopAdlabProjectDetail/list',{
+                accountIds:this.accountIds,
+                userId:this.userInfo.value.id,
+                createTime:this.dateString,
+                optStatus:this.statusValue==undefined?0:this.statusValue,
+                name:this.name==undefined?'':this.name,
+                pageNo:this.ipagination.current,
+                pageSize:this.ipagination.pageSize
+            }).then(res=>{
+                console.log(res);
+                this.loading=false;
+                if(res.success){
+                    this.data=res.result.records.map(item=>{
+                        return {
+                            ...item,
+                            spin:false,
+                            checkedStatus:item.optStatus=='DISABLED'?false:true,
+                        }
+                    });
+                    this.ipagination.total=res.result.total;
+
+                    console.log(this.data)
+                }
+            })
+        },
+    },
+    activated(){
+        this.tableListHttp();
+    },
+    mounted() {
+        this.accountHttp()
+        let userInfo=localStorage.getItem('pro__Login_Userinfo')
+        if(userInfo){
+            this.userInfo=JSON.parse(userInfo)        
+        }
+        this.tableListHttp();
+    },
+}
+</script>
+
+<style lang="scss" scoped>
+.housekeeper{
+    .OptinItem{
+        display: inline-block;
+        margin-right: 15px;
+        .ok{
+            margin-right: 15px;
+        }
+    }
+    .OptinItem:first-child{
+        margin-right: 10px;
+    }
+    .topOptions{
+        padding: 15px 20px;
+        background: white;
+        border-radius: 2px;;
+        .topOpt{
+            width: 100%;
+            margin-bottom: 10px;
+        }
+    }
+    .optionBtn{
+        // display: inline-block;
+        
+        float: right;
+        .searchBtn{
+            margin-right: 10px;
+        }
+    }
+    .tableArea{
+        margin-top: 12px;
+        border-radius: 2px;
+        padding: 0px 20px;
+        background: white;
+        .tableOption{
+            padding: 20px 0;
+        }
+    }
+}
+</style>

ファイルの差分が大きいため隠しています
+ 1029 - 0
src/views/modules/LaunchHousekeeper/material.vue


+ 666 - 0
src/views/modules/LaunchHousekeeper/newProject.vue

@@ -0,0 +1,666 @@
+<template>
+  <div class="newPlan">
+    <a-form :form="form">
+      <div class="moduler">
+        <div class="moduler-title">选择账户</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-tree-select
+                    v-model="accountIds"
+                    show-search
+                    style="width: 600px;height:30px"
+                    :dropdownMatchSelectWidth='true'
+                    :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"              
+                    tree-checkable
+                    searchPlaceholder='请输入账户关键字搜索'
+                    :show-checked-strategy="SHOW_PARENT"
+                    placeholder="请选择项目和账户或搜索账户关键字"
+                    treeNodeFilterProp="title"
+                    :allowClear="true"
+                    @change="treeChange"
+                    @search="treeSearch"
+                    @select="treeSelect"                        
+                    :maxTagCount='1'    
+                    :tree-data="treeData"
+                    :filterOption='filterOption'
+                >
+              
+                </a-tree-select>
+            </div>
+          </div>
+        </div>
+      </div>
+      <!-- 投放范围 -->
+      <div class="moduler">
+        <div class="moduler-title">请选择投放媒体</div>
+        <div class="ad-range">
+          <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="['deliveryRange', { initialValue:'DEFAULT' }]">
+                  <a-radio-button value="DEFAULT">默认</a-radio-button>
+                  <a-radio-button value="UNION">
+                    穿山甲
+                    <a-tooltip>
+                      <template slot="title">基于4亿日活跃用户大数据积累,顶尖AI智能推荐技术,今日头条与最广泛的合作伙伴携手打造全新移动生态联盟</template>
+                      <a-icon type="question-circle" />
+                    </a-tooltip>
+                  </a-radio-button>
+                </a-radio-group>
+              </a-form-item>
+            </div>
+          </div>        
+        </div>
+      </div>
+        <!-- 推广目的 -->
+        <div class="moduler">
+            <div class="moduler-title">请选择推广目的</div>
+            
+            <div class="row-item">
+                <div class="hint-item">
+                    <a-tooltip>
+                    <template slot="title">
+                        <span>应用推广:提升应用的下载、安装、激活、付费</span>
+                        <span>销售线索收集:提升销售线索的获取量</span>
+                    </template>
+                    <a-icon type="question-circle" />
+                </a-tooltip>
+                </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="['landingType',{initialValue:'APP' }]" @change="landingTypeChange">
+                        <a-radio-button value="APP">应用推广</a-radio-button>
+                        <a-radio-button value="LINK">销售线索收集</a-radio-button>                                   
+                    </a-radio-group>
+                    </a-form-item>
+                </div>
+            </div>        
+           
+        </div>
+        <!-- 投放方式 -->
+        <div class="moduler">
+            <div class="moduler-title">请选择投放方式</div>
+            
+            <div class="row-item">
+            <div class="hint-item">
+                <a-tooltip>
+                    <template slot="title">
+                        <span>根据您的投放方式,为您提供包括计划启停、预算分配、出价调整、素材优选等一站式解决方案</span>
+                    </template>
+                    <a-icon type="question-circle" />
+                </a-tooltip>
+            </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="['adTarget', { initialValue:'CPA' }]">
+                  <a-radio-button value="CPA" >优先成本</a-radio-button>
+                  <a-radio-button value="COST">优先跑量</a-radio-button>
+                  <a-radio-button value="PUSH">激进抢量</a-radio-button>
+                 </a-radio-group> 
+              </a-form-item>
+            </div>
+          </div>  
+            
+        </div>
+        <!-- 基础信息 -->
+        <div class="moduler">
+            <div class="moduler-title">请设置基本信息</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-input v-model="name"  allow-clear />
+               </a-form-item>
+            </div>
+          </div>  
+            
+        </div>
+    
+      <!-- 操作 -->
+      <div class="moduler">
+        <!-- <div class="moduler-title">计划名称</div> -->
+        <div class="opt">
+          <a-button type="default" style="margin-right:15px" @click="goBack">取消</a-button>
+         
+          <a-button type="primary" @click="goNext"  :loading="goNextloading">下一步</a-button>
+        </div>
+      </div>
+    </a-form>
+    <div class="infoModal">
+         <a-modal v-model="visible" title="提示"  @ok="handleOk" :keyboard='false' :maskClosable='false'>
+            <ul>
+              <li v-for="(item,index) in errorInfo" :key="index">
+                  <span>账户{{LHKaccountInfo[index].title}}:</span>{{item.message || '投放项目创建成功,下一步去设置转化信息'}}
+              </li>
+            </ul>
+            <template slot="footer">
+              <a-button key="back" @click="handleCancel">
+                返回本页
+              </a-button>
+              <a-button key="submit" type="primary"  @click="handleOk">
+                下一步
+              </a-button>
+            </template>
+          </a-modal>
+    </div>
+  </div>
+</template>
+
+<script>
+import moment from 'moment'
+import { getAction, postAction, downFile, downFilePost } from '@/api/manage'
+
+import { TreeSelect } from 'ant-design-vue';
+import qs from 'qs'
+const SHOW_PARENT = TreeSelect.SHOW_PARENT;
+// import selectCheckAll from './toutiaoTime'
+
+var str = ""
+for (let i = 0; i < 7*48; i++) {
+ str+='0'
+  
+}
+export default {
+  components: {
+    // selectCheckAll,
+    // newDirectedPackage,
+  },
+  data() {
+    return {
+        LHKaccountInfo:{},
+        treeValue: [],
+        treeData: [],
+        SHOW_PARENT,
+        accountIds:[],
+        name: '',
+        form: this.$form.createForm(this),
+
+        goNextloading:false,
+        goPlanShowloading:false,
+        
+        
+        dateRange: [moment(), moment()],
+
+        visible:false,
+        errorInfo:[],
+       
+        validationRules: {
+            url: [   
+            {          
+                required: true,
+                validator: this.validateURL,
+            },
+            ],
+            name:[{
+            required: true,
+            validator: this.validateName,
+            }],
+            bid:[{
+            required: true,
+            message:'出价信息必须填写',
+            // validator: this.validateBid,
+            }],
+            roi:[{
+            required: true,
+            message:'ROI系数必须填写',
+            // validator: this.validateBid,
+            }],
+        },
+        
+    }
+  },
+  watch: {
+    
+  },
+  methods: {
+    // //项目改变后的事件
+    treeChange(val) {
+      // console.log(this.treeData)
+      console.log(val)
+      this.accountIds = [];
+      //选择一个后禁用其他
+      if(val.length==1){
+          if(val[0]*1){
+            let selectindex=0
+              this.treeData.forEach((ele,index)=>{                   
+                  if(ele.children){
+                     ele.children.map((item,ind)=>{
+                            if(item.value==val[0]){
+                                selectindex=index;
+                            }
+                      })
+                  }                   
+              });
+              // console.log(selectindex)
+              if(selectindex ||selectindex==0){
+                this.treeData.forEach((ele,index)=>{
+                    if(index!=selectindex){
+                         ele.disableCheckbox = true;
+                         if(ele.children){
+                              ele.children.map((item,ind)=>{
+                                   item.disableCheckbox = true;
+                              })
+                         }
+                    }
+                })
+              }
+              
+          }else{
+            //  console.log(1)
+              this.treeData.forEach((ele,index)=>{
+                    if(ele.value!=val[0]){
+                         ele.disableCheckbox = true;
+                         
+                         if(ele.children){
+                              ele.children.forEach((item,ind)=>{
+                                   item.disableCheckbox = true;
+                              })
+                         }
+                    }
+                    
+              })
+          }
+          // console.log(this.mediaId)
+          
+      }
+
+        if(val.length==0){
+            this.treeData.forEach((ele,index)=>{              
+                    ele.disableCheckbox = false;
+                    
+                    if(ele.children){
+                        ele.children.forEach((item,ind)=>{
+                            item.disableCheckbox = false;
+                        })
+                    }
+                
+            });
+            
+        }
+      if(val){
+        val.forEach((ele,index)=>{
+          if(ele*1){
+              this.accountIds.push(ele)
+          }else{              
+              let projectArr=this.treeData.filter((item)=>{
+                  return item.value==ele
+              });
+              // console.log(projectArr)
+              projectArr[0].children.forEach((element)=>{
+                 this.accountIds.push(element.value)
+              })
+          }
+
+
+        })       
+      }
+      
+     console.log(this.accountIds);
+      let LHKaccountInfo=[]
+      this.accountIds.forEach(item=>{
+          this.treeData.forEach(element=>{
+            element.children.forEach(ele=>{
+              if(item==ele.value){
+                LHKaccountInfo.push(ele)
+              }
+            })
+          })
+      })
+
+      sessionStorage.setItem('LHKaccountInfo',JSON.stringify(LHKaccountInfo))
+    },
+    treeSearch(){
+    },
+    treeSelect(){
+    },
+    
+    filterOption(input, option){
+      console.log(input, option)
+      return (
+          option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
+        );
+    },
+ 
+
+    //请求项目和账户内容
+    accountHttp(){
+        this.treeData=[];
+        this.accountIds=[];
+        getAction('/ctop/projectMember/getProjectAccountByUserId?mediaType=1', {}).then(res => {
+        if(res.success){
+                // console.log(res);
+                if(res.result){
+                    res.result.forEach((element,index) => {
+                    if(element){                  
+                        this.treeData.push({});                    
+                        this.treeData[index].title=element.project.projectName +'_('+ element.project.advertiserName +')';
+                        this.treeData[index].value='project'+element.project.projectId;
+                        this.treeData[index].key=element.project.projectId;
+                        this.treeData[index].mediaId=element.project.mediaId;
+                        this.treeData[index].children=[];
+                                            
+                        if(element.account.length){
+                        element.account.forEach((ele,i)=>{
+                            this.treeData[index].children.push({});
+                            this.treeData[index].children[i].title=ele.userName+'_'+ele.authName;
+                            this.treeData[index].children[i].value=ele.accountId;
+                            this.treeData[index].children[i].key=ele.accountId;
+                        })
+                            
+                        }                           
+                    }      
+                    });
+                    // console.log(this.treeData)
+                    
+                }
+        }
+        })
+    },
+
+    
+    handleOk(e) {
+        this.visible=false;
+        this.$router.replace({path:'/LaunchHousekeeper/setProjectConvert'})
+        
+        
+    },
+    handleCancel(e) {
+        this.visible = false;
+    },
+    
+   
+    //获取表单的某一个属性值
+    getFormData(className) {
+      return this.form.getFieldValue(className)
+    },
+    dateChange(date, dateString) {
+      // console.log(date,dateString)
+      this.form.getFieldDecorator('startTime')
+      this.form.getFieldDecorator('endTime')
+      this.form.setFieldsValue({
+        startTime: date[0].format('YYYY-MM-DD HH:mm'),
+        endTime:  date[1].format('YYYY-MM-DD HH:mm'),
+      })
+    },
+    
+    //推广目的改变
+    landingTypeChange(e){
+        console.log(e.target)
+        if(e.target.value=='APP'){            
+            this.name=`应用推广_${moment().format('MM_DD_HH:SS')}`           
+        }else if(e.target.value=='LINK'){            
+            this.name=`销售线索收集_${moment().format('MM_DD_HH:SS')}`           
+        }
+    },
+    
+    // 验证网址
+    IsURL(res) {
+      //   var strRegex = /^([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/|www\.)(([A-Za-z0-9-~]+)\.)+([A-Za-z0-9-~\/])+$/
+      var strRegex = /^([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/)(([A-Za-z0-9-~]+)\.)+([A-Za-z0-9-~\/])+(.+[A-Za-z0-9-~\/])+$/
+      var re = new RegExp(strRegex)
+      // console.log(re.test(res))
+      if (re.test(res)) {
+        return true
+      } else {
+        return false
+      }
+    },
+    validateURL(rule, value, callback) {
+      // console.log(rule, value, callback);
+
+      if (this.IsURL(value)) {
+        callback()
+      } else if (value && !this.IsURL(value)) {
+        callback('链接地址无法访问,请正确输入')
+      } else {
+          callback('链接必须填写')
+      }
+    },
+    validateName(rule, value, callback){
+      // console.log(rule, value, callback);
+
+        if (value) {
+          callback()
+        } else {
+              callback('应用包名称必须填写')
+        }
+    },
+    validateBid(rule, value, callback){
+      // console.log(rule, value, callback);
+        if (value) {
+          callback()
+        } else {
+            callback('出价必须填写')
+        }
+    },
+
+   
+    
+    goBack() {
+      this.$router.replace('/modules/LaunchHousekeeper/LaunchHousekeeperList')
+      this.$bus.$emit('remove', '/LaunchHousekeeper/newProject')
+    },
+    
+    // 保存并新建创意
+    goNext() {
+      this.$nextTick(()=>{
+        if (this.name) {
+           let LHKaccountInfo=sessionStorage.getItem('LHKaccountInfo');
+            if(LHKaccountInfo){
+                this.LHKaccountInfo=JSON.parse(LHKaccountInfo)
+            }
+          this.form.validateFields((err, values) => {
+            if (!err) {
+
+              console.log('Received values of form: ', values)
+              // console.log(this.names)
+              this.goNextloading=true;
+              values.accountIds = this.accountIds
+              values.name=this.name
+              postAction('/adlab/Project/create', {                
+                ...values,
+              }).then((res) => {
+                console.log(res)
+                if (res.success) {
+                  this.goNextloading=false;
+                
+                    if(res.result){
+                        this.errorInfo=res.result;
+                        this.visible=true;
+
+                        let projectInfo=[]
+                        res.result.forEach(item=>{
+                            if(item.code==0){
+                              projectInfo.push(item)
+                            }
+                        })
+
+                        sessionStorage.setItem('projectInfo',JSON.stringify(projectInfo))
+                    }
+                 
+                } else {
+                   this.goNextloading=false;
+                  this.$message.error('网络开小差了,等会再试试')
+                }
+              })
+            }else{
+              this.$message.error('请正确填写必填项目')
+            }
+          })
+        }else{
+            this.$message.error('请输入投放项目名称')
+        }
+      })
+      
+    },
+    
+
+    
+  },
+  
+  mounted() {
+    this.accountHttp()
+    // this.$bus.$emit('remove', '/modules/BatchCreate/newGroup')
+    let namepart='';
+    if(this.getFormData('landingType')=='APP'){
+        namepart='应用推广'
+    }else{
+        namepart='销售线索收集'
+    }
+    
+    this.name ='[项目]'+ namepart + moment().format('MM_DD_hh:mm') ;
+
+    
+  },
+}
+</script>
+<style lang="scss">
+.newPlan{
+  .ant-btn-danger {
+    background-color: #ff4d4f !important; 
+  }
+}
+
+
+.ant-tooltip-inner,
+.ant-tooltip,
+.ant-tooltip-arrow::before {
+  background-color: #fff;
+  color: #333;
+}
+.ant-tooltip-inner {
+  span {
+    display: block;
+  }
+}
+.ant-tooltip {
+  max-width: 450px;
+}
+.newPlan {
+  .ant-radio-button-wrapper {
+    min-width: 80px;
+    text-align: center;
+  }
+  .ant-form-item {
+    -webkit-box-sizing: border-box;
+    box-sizing: border-box;
+    margin: 0;
+    padding: 0;
+    color: rgba(0, 0, 0, 0.65);
+    font-size: 14px;
+    font-variant: tabular-nums;
+    line-height: 1.5;
+    list-style: none;
+    -webkit-font-feature-settings: 'tnum';
+    font-feature-settings: 'tnum';
+    vertical-align: top;
+  }
+  .directedBody {
+    .ant-form-item {
+      margin-bottom: 20px;
+    }
+  }
+}
+</style>
+<style lang="scss" scoped>
+.newPlan {
+  font-family: PingFangSC-Regular, tahoma, arial, 'Hiragino Sans GB', 'Microsoft yahei', sans-serif;
+  color: #333;
+  ul,
+  li {
+    margin: 0;
+    padding: 0;
+  }
+  .moduler {
+    background: #fff;
+    margin-bottom: 16px;
+    position: relative;
+    padding: 32px 24px 48px 32px;
+    border-radius: 4px;
+    box-shadow: 0px 1px 6px 0px rgba(0, 0, 0, 0.05);
+    .moduler-title {
+      display: flex;
+      align-items: center;
+      font-size: 22px;
+      margin-bottom: 20px;
+    }
+    .row-item {
+      display: flex;
+      justify-content: flex-start;
+      align-items: center;
+      margin-bottom: 32px;
+    }
+    .row-item:last-of-type {
+      margin-bottom: 0;
+    }
+    .row-item .hint-item {
+      width: 24px;
+      min-width: 24px;
+      align-self: flex-start;
+      line-height: 20px;
+      height: 20px;
+      margin-top: 5px;
+    }
+    .row-item .label-item {
+      position: relative;
+      align-items: flex-start;
+      align-self: flex-start;
+      line-height: 20px;
+      height: 20px;
+      margin-top: 7px;
+      width: 80px;
+      min-width: 80px;
+      .text-item {
+        font-size: 14px;
+        width: 60px;
+      }
+    }
+    .row-item .required-item {
+      width: 4px;
+      height: 4px;
+      border-radius: 2px;
+      background: #f45858;
+      position: absolute;
+      right: 10px;
+      top: 50%;
+      transform: translateY(-50%);
+    }
+    .row-item .input-item {
+      min-width: 480px;
+      position: relative;
+      // height: 35px;
+      .tip {
+        font-size: 12px;
+        color: tomato;
+      }
+    }
+  }
+  .opt {
+    text-align: right;
+  }
+}
+</style>

+ 237 - 0
src/views/modules/LaunchHousekeeper/radioCheck.vue

@@ -0,0 +1,237 @@
+<template>
+    <div class="radioCheck" >
+        
+            <label :class="{'item':true,'selection': selectValue.indexOf(item.value)>-1,'bgcolor':item.disabled}" v-for="(item,index) in checkArr" :key="index">
+                
+                <span>
+                    <input type="checkbox" :value="item.value"  class="checkbox-button-input" @click="radioCheckChange($event,item)">
+                </span>
+                <span>{{item.title}}</span>
+                
+            </label>
+            <!-- <label :class="{'item':true,'selection': selectValue.indexOf(item.value)>-1}" v-for="(item,index) in checkArr" :key="index" :disabled='item.disabled'>               
+                <span>
+                    <input type="checkbox" :value="item.value"  class="checkbox-button-input" @click="radioCheckChange">
+                </span>
+                <span>{{item.title}}</span>               
+            </label>        -->
+    </div>
+</template>
+
+<script>
+export default {
+    data() {
+        return {
+            selectValue:[''],
+            currentSelect:'',
+        }
+    },
+   
+    props:['checkArr','selectArr'],
+    watch:{
+        checkArr:{
+            handler(n,o){
+                // console.log(n,o)
+                this.selectValue=[];
+                let i=0;
+                this.checkArr.forEach((item,index)=>{
+                    // console.log(item)
+                    if(item.disabled==false){
+                        i++;
+                        this.selectValue[0]=item.value;
+                        // console.log(this.selectValue)
+                    }else if(item.disabled==undefined){
+                        if(item.checked){
+                            this.selectValue.push(item.value)
+                        }
+                        
+                    }
+                })
+                if(this.selectValue.length==0){
+                    this.selectValue=[''];
+                }
+                if(i==3){
+                    this.selectValue[0]='';
+                }
+                // console.log(this.selectValue)
+                this.$emit('getSonValue',this.selectValue)
+            },
+            deep:true,
+            // immediate: true
+
+        },
+        
+    },
+    methods: {
+        //单选多选的事件
+        radioCheckChange(e,item){
+            console.log(e.target,item,!item.disabled);
+            
+            this.currentSelect=e.target.value;
+            if(!item.disabled){
+
+                if(e.target.value=='' || this.selectValue.length==0 ){
+                    this.selectValue=[''];
+                }else{
+                    if(this.selectValue.indexOf('')>-1){
+                        let i=this.selectValue.indexOf('');
+                        this.selectValue.splice(0,1)
+                    }
+                    
+                    if(this.selectValue.indexOf(e.target.value)==-1){
+                        this.selectValue.push(e.target.value)
+                    }else if(this.selectValue.indexOf(e.target.value)>-1){
+                        this.selectValue=this.selectValue.filter((item)=>{
+                            return item!=e.target.value
+                        })  
+                    }
+
+                    if(this.selectValue.length==0){
+                        this.selectValue=[''];
+                    }
+                    
+                }
+            // console.log(this.currentSelect,this.selectValue);
+            }
+            this.$emit('getSonValue',this.selectValue)
+        },
+    },
+    mounted() {
+        // this.selectValue=[]
+        // console.log(this.checkArr)
+        this.checkArr.forEach((item,index)=>{
+            
+            if(item.disabled&&item.disabled!=undefined){
+                this.selectValue[0]=item.value
+            }else{
+                this.selectValue=['']
+            }
+        })
+        this.$emit('getSonValue',this.selectValue)
+    },
+}
+</script>
+
+<style lang="scss" scoped>
+.radioCheck{        
+    border-radius: 5px;
+    height: 32px;
+    padding: 0;
+    margin: 0;
+    border: none;
+    background: transparent;
+    .btn{
+        background: transparent;
+        padding: 0;
+        margin: 0;
+        border: none;
+    }
+    .item{
+        min-width: 80px;
+        padding: 0px 15px;
+        text-align: center;
+        display: inline-block;
+        border: 1px solid #ccc;
+        border-left: 0;
+        height: 32px;
+        line-height: 32px;
+        cursor: pointer;
+        .checkbox-button-input{
+            width: 0;
+            height: 0;
+            opacity: 0;
+        }
+
+    }
+    .bgcolor{
+        color:rgba(0, 0, 0, 0.25);
+        background-color: #f5f5f5;
+        border-color: #d9d9d9;
+        cursor: not-allowed;
+    }
+    .item::after{
+        content: "";
+        position: absolute;
+        right: 1px;
+        top: -2px;
+        width: 0;
+        height: 0;
+        border-top: 6px solid transparent;
+        border-bottom: 6px solid transparent;
+        border-left: 6px solid;
+        border-left-color: #e0e0e0;
+        -webkit-transform: rotate(-45deg);
+        -ms-transform: rotate(-45deg);
+        transform: rotate(-45deg);
+        border-radius: 2px;
+    }
+    .item:hover{
+        color: #1890ff;
+    }
+    .selection{
+        color: #1890ff;
+        background: #fff;
+        border-color: #1890ff;
+    }
+    .item.selection:hover{
+        // color: #1890ff;
+        color: #40a9ff;
+        background: #fff;
+        border-color: #40a9ff;
+    }
+    .item.selection:after{
+        border-left: 6px solid #1890ff;
+    }
+    .item:hover::after{
+        // border-color: #40a9ff;
+        border-left: 6px solid #40a9ff;
+    }
+    .bgcolor:hover{
+        color:rgba(0, 0, 0, 0.25);
+        background-color: #f5f5f5;
+        border-color: #d9d9d9;
+        cursor: not-allowed;
+    }
+    .bgcolor:hover::after{
+        // border-color: #40a9ff;
+        border-left: 6px solid #e0e0e0;
+    }
+    .bgcolor.selection:after{
+        border-left: 6px solid #e0e0e0;
+    }
+    .bgcolor.selection{
+        color:rgba(0, 0, 0, 0.25);
+        background-color: #f5f5f5;
+        border-color: #d9d9d9;
+        cursor: not-allowed;
+    }
+    .bgcolor.selection:hover{
+        // color: #1890ff;
+        color:rgba(0, 0, 0, 0.25);
+        background-color: #f5f5f5;
+        border-color: #d9d9d9;
+        cursor: not-allowed;
+    }
+    .bgcolor.selection:after{
+        border-left: 6px solid #e0e0e0;
+    }
+}
+.radioCheck .item:first-child {
+    border-radius: 5px 0 0 5px;
+    border-left: 1px solid #ccc;
+}
+.radioCheck .item.selection:first-child {
+    border-radius: 5px 0 0 5px;
+    border-left: 1px solid #1890ff;
+}
+.radioCheck .item.selection:nth-child(2) {
+    
+    border-left: 1px solid #1890ff;
+}
+.radioCheck .item:first-child:after{
+    border-left: 0;
+}
+.radioCheck .item:last-child {
+    border-radius: 0px 5px 5px 0px;
+}
+</style>

+ 658 - 0
src/views/modules/LaunchHousekeeper/setProjectBudget.vue

@@ -0,0 +1,658 @@
+<template>
+  <div class="newPlan">
+    
+    <div class="moduler">
+        <div v-if="projectInfo.length>0">
+         <span style="margin-right:8px"> 项目:<strong>{{projectInfo[0].name||''}}</strong></span>
+         <span style="margin-right:8px"> 推广目的:<strong>{{projectInfo[0].landingType=='APP'?'应用推广':'销售线索收集'||''}}</strong></span>
+         <span style="margin-right:8px"> 投放媒体:<strong>{{projectInfo[0].deliveryRange=="DEFAULT"?'默认':'穿山甲'||''}}</strong></span>
+         <span style="margin-right:8px"> 投放方式:
+             <strong v-if="projectInfo[0].adTarget=='CPA'">优先成本</strong>
+             <strong v-if="projectInfo[0].adTarget=='COST'">优先跑量</strong>
+             <strong v-if="projectInfo[0].adTarget=='PUSH'">激进抢量</strong>
+        </span>
+          
+        </div>
+    </div>
+   
+        
+        <div class="moduler">
+            
+            <a-form :form="form">
+                <div class="moduler-title">预算与出价</div>
+                <div class="ad-range">
+                    <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="['scheduleType', { initialValue:'SCHEDULE_FROM_NOW' }]" @change="scheduleTypeChange">
+                            <a-radio-button value="SCHEDULE_FROM_NOW">从今天起长期投放</a-radio-button>
+                            <a-radio-button value="SCHEDULE_START_END">设置开始和结束时间</a-radio-button>
+                            </a-radio-group>
+                            <p style="margin-top:15px">
+                            <a-range-picker
+                                @change="dateChange"
+                                v-model="dateRange"
+                                :disabled-date="disabledDate" 
+                                v-if="getFormData('scheduleType')=='SCHEDULE_START_END'"
+                            />
+                            </p>
+                        </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="['scheduleTime', { initialValue:'' }]" >
+                              <a-radio-button value=''>不限</a-radio-button>
+                              <a-radio-button value="SpecifiedTImePeriod">指定时间段</a-radio-button>
+                            </a-radio-group>
+                            <div
+                            v-show="getFormData('scheduleTime')=='SpecifiedTImePeriod'"
+                            style="margin-top:15px"
+                            >
+                            <selectCheckAll
+                                style="width:100%"
+                                :scheduleTime.sync="scheduleTimeData"
+                                ref="selectCheck"
+                            />
+                            </div>
+                        </a-form-item>
+                        </div>
+                    </div>
+                    <div class="row-item">
+                      <div class="hint-item">
+                        <a-tooltip>
+                          <template slot="title">
+                            <span>单次预算修改幅度不小于100元,日修改预算不超过20次。如果是总预算广告,且设了起始日期,将要求您预算设置需要大于或等于[投放天数 * 100],即满足每日最低预算300的要求</span>
+                          </template>
+                          <a-icon type="question-circle" />
+                        </a-tooltip>
+                      </div>
+                      <div class="label-item">
+                        <div class="text-item">预算</div>
+                        <div class="required-item"></div>
+                      </div>
+                      <div class="input-item">
+                        <a-form-item>
+                          <a-input-group compact>
+                            <a-select :disabled="true" v-decorator="['budgetMode', { initialValue:'DAILY' }]">
+                              <a-select-option value="DAILY" >日预算</a-select-option>
+                              <!-- <a-select-option
+                                value="TOTAL"
+                                v-if="getFormData('smartBidType')=='SMART_BID_CUSTOM'"
+                              >总预算</a-select-option> -->
+                            </a-select>
+                            <a-input style="width: 25%" v-decorator="['budget', { initialValue:300 }]" />
+                          </a-input-group>
+                          <span class="tip" v-if="getFormData('budget')<300">请输入预算,不少于300元,不超过9999999.99元</span>
+                        </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="['pricing', { initialValue:'PRICING_OCPM' }]">
+                              <a-radio-button value="PRICING_OCPM" >按展示付费(oCPM)</a-radio-button>
+                              <!-- <a-radio-button value="PRICING_CPC" >按点击付费(CPC)</a-radio-button>
+                              <a-radio-button value="PRICING_CPM" >按展示付费(CPM)</a-radio-button>
+                              <a-radio-button value="PRICING_CPA">按转化付费(CPA)</a-radio-button>
+                              <a-radio-button  value="PRICING_OCPC">按点击付费(oCPC)</a-radio-button> -->
+                            </a-radio-group>
+                        </a-form-item>
+                        </div>
+                    </div>
+                    <div class="row-item" >
+                      <div class="hint-item">
+                        <a-tooltip>
+                          <template slot="title">
+                            <span>请填入您当前预算下,每个转化事件的真实预期成本,预期成本过低可能影响模型的优化能力。此成本仅作为投放参考,实际扣费仍以后台展示为准。</span>
+                          </template>
+                          <a-icon type="question-circle" />
+                        </a-tooltip>
+                      </div>
+                      <div class="label-item">
+                        <div class="text-item">预期成本</div>
+                        <div class="required-item"></div>
+                      </div>
+                      <div class="input-item">
+                        <a-form-item>
+                          <a-input-number
+                            style="width:200px"
+                            :max="10000"
+                            :step="0.1"
+                            v-decorator="['bid', {rules:validationRules.bid} ]"
+                          />
+                          <span style="margin-left:5px">元</span>
+                          <!-- <span style="margin-left:20px">请填入必填字段,获取建议出价</span> -->
+                        </a-form-item>
+                        <span
+                          class="tip"
+                          v-if="getFormData('bid')<0.1"
+                        >请输入预期成本,不少于0.1元,不超过10000元</span>
+                      </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-button type='primary' @click="isSetDeepConvert" > 是否设置深度转化 </a-button>
+                        </div>
+                    </div>
+
+                    <div class="row-item" v-if="isDeepConvert">
+                      <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="['deepBidType', { initialValue:'DEEP_BID_MIN' }]"
+                          >                            
+                            <a-radio-button value="DEEP_BID_MIN" >自定义双出价</a-radio-button>
+                          </a-radio-group>
+                        </a-form-item>
+                      </div>
+                    </div>
+                    <div class="row-item" v-if="isDeepConvert">
+                      <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-input-number
+                            style="width:200px"
+                            :max="10000"
+                            :step="0.1"
+                            :min='0.1'
+                            v-decorator="['deepBid', {rules:validationRules.bid} ]"                 
+                          />
+          
+                          <span style="margin-left:5px">元</span>
+                        </a-form-item>
+                        <span
+                          class="tip"
+                          v-if="getFormData('pricing')!='PRICING_CPA'&&getFormData('deepCpabid')<0.1"
+                        >请输入深度转化出价,不少于0.1元,不超过10000元</span>
+                      </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="['autoStop', { initialValue:0 }]">
+                              <a-radio-button :value="1">开启</a-radio-button>
+                              <a-radio-button :value="0">关闭</a-radio-button>
+                            </a-radio-group>
+                        </a-form-item>
+                        </div>
+                    </div>
+                </div>
+            </a-form>  
+        </div>
+            
+            <!-- 当前账户 -->
+            <div class="moduler">
+                <div class="adName">
+                    <span>当前账户:</span> 
+                    <div class="nameList">
+                        <strong v-for="item in LHKaccountInfo" :key="item.value" class="item">{{item.title+'('+item.value+')'}}</strong>
+                    </div>
+                </div>
+            </div>
+            <!-- 操作 -->
+            <div class="moduler">
+                <!-- <div class="moduler-title">计划名称</div> -->
+                <div class="opt">
+                <a-button type="default" style="margin-right:15px" @click="goBack">取消</a-button>
+                
+                <a-button type="primary" @click="goNext"  :loading="goNextloading">开始投放</a-button>
+                </div>
+            </div>
+        
+      <!-- 投放链接 -->
+    
+    <div class="infoModal">
+         <a-modal v-model="visible" title="提示"  @ok="handleOk" :keyboard='false' :maskClosable='false'>
+            <ul>
+              <li v-for="(item,index) in errorInfo" :key="index">
+                  <span>账户{{LHKaccountInfo[index].title}}:</span>{{item.message || '设置预算与出价信息成功'}}
+              </li>
+            </ul>
+            <template slot="footer">
+              <a-button key="back" @click="handleCancel">
+                返回本页
+              </a-button>
+              <a-button key="submit" type="primary"  @click="handleOk">
+                返回投放管家页面
+              </a-button>
+            </template>
+          </a-modal>
+    </div>
+  </div>
+</template>
+
+<script>
+import moment from 'moment'
+import { getAction, postAction, downFile, downFilePost } from '@/api/manage'
+import selectCheckAll from '../BatchCreate/toutiaoTime'
+import qs from 'qs'
+var str = ""
+for (let i = 0; i < 7*48; i++) {
+ str+='0'
+  
+}
+export default {
+  components: {
+    selectCheckAll,
+    // newDirectedPackage,
+  },
+  data() {
+    return {
+        userInfo:{},
+        isDeepConvert:false,
+        projectInfo:[],
+        LHKaccountInfo:[],
+        
+        form: this.$form.createForm(this),
+
+        showIndex:0,
+
+        goNextloading:false,
+        goPlanShowloading:false,
+        
+        
+        dateRange: [moment(), moment()],
+        scheduleTime: '',
+        scheduleTimeData:str,
+
+        visible:false,
+        errorInfo:[],
+       
+        validationRules: {
+            url: [   
+            {          
+                required: true,
+                validator: this.validateURL,
+            },
+            ],
+            name:[{
+            required: true,
+            validator: this.validateName,
+            }],
+            bid:[{
+            required: true,
+            message:'出价信息必须填写',
+            // validator: this.validateBid,
+            }],
+            roi:[{
+            required: true,
+            message:'ROI系数必须填写',
+            // validator: this.validateBid,
+            }],
+        },
+
+        currentConvertTypes:[],
+        convertIds:[],
+    }
+  },
+  watch: {
+    
+  },
+  methods: {
+    // 投放日期改变
+    scheduleTypeChange(val){
+      console.log(val)
+      if(val=='SCHEDULE_FROM_NOW'){
+        this.dateRange=[moment(),moment().add(10,'years')]
+        
+      }else{
+        this.dateRange=[moment(),moment().add(10,'days')]
+      }
+    },
+    callback(val) {
+      console.log(val);
+    },
+
+    isSetDeepConvert(){
+      this.isDeepConvert=!this.isDeepConvert
+    },
+    
+    handleOk(e) {
+        this.visible=false;
+      // this.$router.push('/LaunchHousekeeper/setProjectDirectional')
+        this.$router.push({path:'/modules/LaunchHousekeeper/LaunchHousekeeperList'})
+        this.$bus.$emit('remove', '/LaunchHousekeeper/setProjectConvert')
+        
+    },
+    handleCancel(e) {
+        this.visible = false;
+    },
+   
+   
+    
+   
+    //获取表单的某一个属性值
+    getFormData(className) {
+      return this.form.getFieldValue(className)
+    },
+    dateChange(date, dateString) {
+      // console.log(date,dateString)
+      this.form.getFieldDecorator('startTime')
+      this.form.getFieldDecorator('endTime')
+      this.form.setFieldsValue({
+        startTime: date[0].format('YYYY-MM-DD'),
+        endTime:  date[1].format('YYYY-MM-DD'),
+      })
+    },
+    
+    
+    
+    
+    // 验证网址
+    IsURL(res) {
+      //   var strRegex = /^([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/|www\.)(([A-Za-z0-9-~]+)\.)+([A-Za-z0-9-~\/])+$/
+      var strRegex = /^([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/)(([A-Za-z0-9-~]+)\.)+([A-Za-z0-9-~\/])+(.+[A-Za-z0-9-~\/])+$/
+      var re = new RegExp(strRegex)
+      // console.log(re.test(res))
+      if (re.test(res)) {
+        return true
+      } else {
+        return false
+      }
+    },
+    validateURL(rule, value, callback) {
+      // console.log(rule, value, callback);
+
+      if (this.IsURL(value)) {
+        callback()
+      } else if (value && !this.IsURL(value)) {
+        callback('链接地址无法访问,请正确输入')
+      } else {
+          callback('链接必须填写')
+      }
+    },
+    validateName(rule, value, callback){
+      // console.log(rule, value, callback);
+
+        if (value) {
+          callback()
+        } else {
+              callback('应用包名称必须填写')
+        }
+    },
+    validateBid(rule, value, callback){
+      // console.log(rule, value, callback);
+        if (value) {
+          callback()
+        } else {
+            callback('出价必须填写')
+        }
+    },
+
+    disabledDate(current) {
+            // console.log(current)
+            return current && current < moment()
+      },
+    
+    goBack() {
+      this.$router.replace('/modules/LaunchHousekeeper/LaunchHousekeeperList')
+      this.$bus.$emit('remove', '/LaunchHousekeeper/setProjectBudget')
+    },
+    
+    // 保存并新建创意
+    goNext() {
+      this.$nextTick(()=>{
+        
+          this.form.validateFields((err, values) => {
+            if(this.getFormData('bid')<this.getFormData('budget')){
+
+              if (!err) {
+
+                console.log('Received values of form: ', values)
+                
+                this.goNextloading=true;
+                if(this.getFormData('scheduleTime')!=''){
+                    values.weekTime=this.scheduleTimeData
+                }else{
+                    values.weekTime=''
+                }
+                if(this.getFormData('scheduleType')=='SCHEDULE_FROM_NOW'){
+                  values.startTime=this.dateRange[0].format('YYYY-MM-DD');
+                  values.endTime= this.dateRange[1].add(10,"years").format('YYYY-MM-DD');
+                  
+                }else{
+                    values.startTime=this.dateRange[0].format('YYYY-MM-DD');
+                    values.endTime= this.dateRange[1].format('YYYY-MM-DD');
+                }
+                
+
+                let params=[];
+                params=this.projectInfo.map((item,index)=>{
+                  return {
+                    ...item,
+                    ...values,
+                    userId:this.userInfo.value.id
+                  }
+                })
+                console.log(values)
+                postAction('/adlab/Project/setBudget', params).then((res) => {
+                  console.log(res)
+                  if (res.success) {
+                    this.goNextloading=false;
+                  
+                      if(res.result){
+                          this.errorInfo=res.result;
+                          this.visible=true;
+ 
+                      }
+                  
+                  } else {
+                    this.goNextloading=false;
+                    this.$message.error(res.message)
+                  }
+                })
+              }else{
+                this.$message.error('请正确填写必填项目')
+              }
+                          
+            }else{
+              this.$message.error('出价不得高于组预算')
+            }
+          })
+        
+      })
+      
+    },
+    
+    EchoPageInfo(){
+
+    },
+    
+  },
+  
+  mounted() {
+      this.$bus.$emit('remove', '/LaunchHousekeeper/setProjectCreate')
+        let projectInfo=sessionStorage.getItem('projectInfo');
+        if(projectInfo){
+            this.projectInfo=JSON.parse(projectInfo)
+        }
+        let LHKaccountInfo=sessionStorage.getItem('LHKaccountInfo');
+        if(LHKaccountInfo){
+            this.LHKaccountInfo=JSON.parse(LHKaccountInfo)
+        }
+        let editLHKProjectInfo=sessionStorage.getItem('editLHKProjectInfo');
+        if(editLHKProjectInfo){
+          this.LHKaccountInfo.push(editLHKProjectInfo);
+        }
+        let userInfo=localStorage.getItem('pro__Login_Userinfo')
+        if(userInfo){
+            this.userInfo=JSON.parse(userInfo)        
+        }
+        
+  },
+}
+</script>
+<style lang="scss">
+.newPlan{
+  .ant-btn-danger {
+    background-color: #ff4d4f !important; 
+  }
+}
+
+
+.ant-tooltip-inner,
+.ant-tooltip,
+.ant-tooltip-arrow::before {
+  background-color: #fff;
+  color: #333;
+}
+.ant-tooltip-inner {
+  span {
+    display: block;
+  }
+}
+.ant-tooltip {
+  max-width: 450px;
+}
+.newPlan {
+  .ant-radio-button-wrapper {
+    min-width: 80px;
+    text-align: center;
+  }
+  .ant-form-item {
+    -webkit-box-sizing: border-box;
+    box-sizing: border-box;
+    margin: 0;
+    padding: 0;
+    color: rgba(0, 0, 0, 0.65);
+    font-size: 14px;
+    font-variant: tabular-nums;
+    line-height: 1.5;
+    list-style: none;
+    -webkit-font-feature-settings: 'tnum';
+    font-feature-settings: 'tnum';
+    vertical-align: top;
+  }
+  .directedBody {
+    .ant-form-item {
+      margin-bottom: 20px;
+    }
+  }
+}
+</style>
+<style lang="scss" scoped>
+.newPlan {
+  font-family: PingFangSC-Regular, tahoma, arial, 'Hiragino Sans GB', 'Microsoft yahei', sans-serif;
+  color: #333;
+  ul,
+  li {
+    margin: 0;
+    padding: 0;
+  }
+  .moduler {
+    background: #fff;
+    margin-bottom: 16px;
+    position: relative;
+    padding: 32px 24px 48px 32px;
+    border-radius: 4px;
+    box-shadow: 0px 1px 6px 0px rgba(0, 0, 0, 0.05);
+    .moduler-title {
+      display: flex;
+      align-items: center;
+      font-size: 22px;
+      margin-bottom: 20px;
+    }
+    .row-item {
+      display: flex;
+      justify-content: flex-start;
+      align-items: center;
+      margin-bottom: 32px;
+    }
+    .row-item:last-of-type {
+      margin-bottom: 0;
+    }
+    .row-item .hint-item {
+      width: 24px;
+      min-width: 24px;
+      align-self: flex-start;
+      line-height: 20px;
+      height: 20px;
+      margin-top: 5px;
+    }
+    .row-item .label-item {
+      position: relative;
+      align-items: flex-start;
+      align-self: flex-start;
+      line-height: 20px;
+      height: 20px;
+      margin-top: 7px;
+      width: 80px;
+      min-width: 80px;
+      .text-item {
+        font-size: 14px;
+        width: 60px;
+      }
+    }
+    .row-item .required-item {
+      width: 4px;
+      height: 4px;
+      border-radius: 2px;
+      background: #f45858;
+      position: absolute;
+      right: 10px;
+      top: 50%;
+      transform: translateY(-50%);
+    }
+    .row-item .input-item {
+      min-width: 480px;
+      position: relative;
+      // height: 35px;
+      .tip {
+        font-size: 12px;
+        color: tomato;
+      }
+    }
+    .adName{
+      display: flex;
+      .nameList{
+        width: 90%;
+      }
+      .item{
+        display: inline-block;
+        width: 30%;
+        margin-left: 15px;
+        margin-bottom: 10px;
+      }
+    }
+  }
+  .opt {
+    text-align: right;
+  }
+}
+</style>

+ 716 - 0
src/views/modules/LaunchHousekeeper/setProjectConvert.vue

@@ -0,0 +1,716 @@
+<template>
+  <div class="newPlan">
+    
+    <div class="moduler">
+        <div v-if="projectInfo.length>0">
+         <span style="margin-right:8px"> 项目:<strong>{{projectInfo[0].name||''}}</strong></span>
+         <span style="margin-right:8px"> 推广目的:<strong>{{projectInfo[0].landingType=='APP'?'应用推广':'销售线索收集'||''}}</strong></span>
+         <span style="margin-right:8px"> 投放媒体:<strong>{{projectInfo[0].deliveryRange=="DEFAULT"?'默认':'穿山甲'||''}}</strong></span>
+         <span style="margin-right:8px"> 投放方式:
+             <strong v-if="projectInfo[0].adTarget=='CPA'">优先成本</strong>
+             <strong v-if="projectInfo[0].adTarget=='COST'">优先跑量</strong>
+             <strong v-if="projectInfo[0].adTarget=='PUSH'">激进抢量</strong>
+        </span>
+          
+        </div>
+    </div>
+   
+        
+        <div class="moduler">
+            
+            <a-form :form="form">
+                <div class="moduler-title">投放链接</div>
+                <div class="ad-range">
+                    <div class="row-item" v-if="projectInfo.length>0&&projectInfo[0].landingType=='APP'" >
+                        <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="['downloadType',{ initialValue:'DOWNLOAD_URL' }]"
+                                 @change="downloadTypeChange">
+                                    <a-radio-button value="DOWNLOAD_URL">下载链接</a-radio-button>
+                                    <a-radio-button value="EXTERNAL_URL">落地页</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>
+                        <div class="input-item">
+                            <a-form-item>
+                                <a-radio-group v-decorator="['appType', { initialValue:'APP_IOS' }]" @change="appTypeChange">
+                                <a-radio-button value="" v-if="getFormData('downloadType')=='EXTERNAL_URL' || (projectInfo.length>0&&projectInfo[0].landingType=='LINK')">不限</a-radio-button>
+                                <a-radio-button value="APP_IOS">IOS</a-radio-button>
+                                <a-radio-button value="APP_ANDROID">安卓</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>
+                        <div class="input-item">
+                            <a-form-item>
+                                <a-input v-decorator="['url', {rules:validationRules.url}]" @change="UrlChange" />
+                            </a-form-item>
+                        </div>
+                    </div>    
+                    <div class="row-item" v-if="getFormData('downloadType')=='DOWNLOAD_URL'&&getFormData('appType')=='APP_ANDROID'">
+                        <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-input v-decorator="['adlabPackage', {rules:validationRules.name}]" :disabled="true" />
+                        </a-form-item>
+                        </div>
+                    </div>
+                    <div class="row-item" v-if="getFormData('downloadType')=='DOWNLOAD_URL'&&getFormData('appType')=='APP_ANDROID'">
+                        <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-input v-decorator="['webUrl', {rules:validationRules.url}]" />
+                        </a-form-item>
+                        </div>
+                    </div>
+                    <div class="row-item" v-show="getFormData('downloadType')=='EXTERNAL_URL'">
+                        <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="['useOpenUrl', { initialValue:'NO' }]" @change="useOpenUrlChange">
+                            <a-radio-button value="NO">不启用</a-radio-button>
+                            <a-radio-button value="YES">启用</a-radio-button>
+                            </a-radio-group>
+                        </a-form-item>
+                        </div>
+                    </div>
+                    <div class="row-item" v-show="getFormData('downloadType')=='EXTERNAL_URL'&&getFormData('useOpenUrl')=='YES'">
+                        <div class="hint-item"></div>
+                        <div class="label-item">
+                        <div class="text-item">跳转APP链接</div>
+                        <div class="required-item"></div>
+                        </div>
+                        <div class="input-item">
+                        <a-form-item>
+                            <a-input v-decorator="['openUrl']" />
+                        </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 style="margin-bottom:15px" v-for="(item,index) in LHKaccountInfo" :key="index">
+                                <a-radio-button
+                                    value="SelectConversionTarget"
+                                    @click="SelectConversionTarget(item,index)"
+                                    :disabled="!IsURL(getFormData('url'))"
+                                    v-show="showIndex<=index"
+                                >选择转化目标</a-radio-button>
+                                <a-select  style="width: 335px"     v-show="showIndex>index"  @change="APIChange($event,index)">
+                                    <a-select-option v-for="item in currentConvertTypes[index]" :key="item.convertId" :value='item.convertId'>
+                                        {{item.external_name}}
+                                    </a-select-option>
+                                </a-select>
+                                <span style="margin-left:20px">账户:{{item.title}} </span>
+                            </a-form-item>
+                        </div>
+                    </div>    
+                </div>
+            </a-form>  
+        </div>
+            
+            <!-- 当前账户 -->
+            <div class="moduler">
+                <div class="adName">
+                    <span>当前账户:</span> 
+                    <div class="nameList">
+                        <strong v-for="item in LHKaccountInfo" :key="item.value" class="item">{{item.title+'('+item.value+')'}}</strong>
+                    </div>
+                </div>
+            </div>
+            <!-- 操作 -->
+            <div class="moduler">
+                <!-- <div class="moduler-title">计划名称</div> -->
+                <div class="opt">
+                <a-button type="default" style="margin-right:15px" @click="goBack">取消</a-button>
+                
+                <a-button type="primary" @click="goNext"  :loading="goNextloading">下一步</a-button>
+                </div>
+            </div>
+        
+      <!-- 投放链接 -->
+    
+    <div class="infoModal">
+         <a-modal v-model="visible" title="提示"  @ok="handleOk" :keyboard='false' :maskClosable='false'>
+            <ul>
+              <li v-for="(item,index) in errorInfo" :key="index">
+                  <span>账户{{LHKaccountInfo[index].title}}:</span>{{item.message || '设置转化信息成功'}}
+              </li>
+            </ul>
+            <template slot="footer">
+              <a-button key="back" @click="handleCancel">
+                返回本页
+              </a-button>
+              <a-button key="submit" type="primary"  @click="handleOk">
+                下一步
+              </a-button>
+            </template>
+          </a-modal>
+    </div>
+  </div>
+</template>
+
+<script>
+import moment from 'moment'
+import { getAction, postAction, downFile, downFilePost } from '@/api/manage'
+import qs from 'qs'
+var str = ""
+for (let i = 0; i < 7*48; i++) {
+ str+='0'
+  
+}
+export default {
+  components: {
+    // selectCheckAll,
+    // newDirectedPackage,
+  },
+  data() {
+    return {
+        projectInfo:[],
+        LHKaccountInfo:[],
+        
+        form: this.$form.createForm(this),
+
+        showIndex:0,
+
+        goNextloading:false,
+        goPlanShowloading:false,
+        
+        
+        dateRange: [moment(), moment()],
+
+        visible:false,
+        errorInfo:[],
+       
+        validationRules: {
+            url: [   
+            {          
+                required: true,
+                validator: this.validateURL,
+            },
+            ],
+            name:[{
+            required: true,
+            validator: this.validateName,
+            }],
+            bid:[{
+            required: true,
+            message:'出价信息必须填写',
+            // validator: this.validateBid,
+            }],
+            roi:[{
+            required: true,
+            message:'ROI系数必须填写',
+            // validator: this.validateBid,
+            }],
+        },
+
+        currentConvertTypes:[],
+        convertIds:[],
+        convertInfo:[],
+    }
+  },
+  watch: {
+    
+  },
+  methods: {
+    
+    callback(val) {
+      console.log(val);
+    },
+
+    // 链接地址改变
+    UrlChange(e){
+      console.log(e.target.value);
+      if(this.IsURL(e.target.value)&&this.getFormData('appType')=='APP_ANDROID'&&this.projectInfo[0].landingType=='APP'){
+        postAction('/ctop/queryTool/parseInstallPackage',qs.stringify({
+          installUrl:e.target.value,
+          appType:this.getFormData('appType')
+        })).then(res=>{
+          console.log(res)
+          if(res.success){
+            this.form.setFieldsValue({
+              adlabPackage:res.result.package
+            })
+          }else{
+            this.$message.error(res.message)
+          }
+        })
+      }
+    },
+    
+    handleOk(e) {
+        this.visible=false;
+      // this.$router.push('/LaunchHousekeeper/setProjectDirectional')
+        this.$router.push({path:'/LaunchHousekeeper/setProjectDirectional'})
+       
+        
+    },
+    handleCancel(e) {
+        this.visible = false;
+    },
+    // 直达链接是否启用
+    useOpenUrlChange(){
+      this.form.setFieldsValue({
+        openUrl:''
+      })
+    },
+    // 下载方式改变
+    downloadTypeChange(val){
+        console.log(val)
+        this.showIndex=0;
+        if(val.target.value=="EXTERNAL_URL"){
+            this.form.setFieldsValue({
+                appType:'',
+                url:'',
+                adlabPackage:'',
+                webUrl:'',
+            })
+        }else{
+           this.form.setFieldsValue({
+                appType:'APP_IOS',
+                url:'',
+                adlabPackage:'',
+                useOpenUrl:'NO',
+                openUrl:'',
+            }) 
+        }
+    },
+    // 投放平台改变
+    appTypeChange(val){
+        this.showIndex=0;
+        if(val.target.value=="APP_IOS"){
+            this.form.setFieldsValue({
+                url:'',
+                adlabPackage:'',
+                webUrl:'',
+            })
+        }else{
+           this.form.setFieldsValue({               
+                url:'',
+                     
+            }) 
+        }
+    },
+    //  转化目标显示
+    SelectConversionTarget(item,index) {
+        
+        
+        let downloadType=this.getFormData('downloadType');
+       
+        let adlabPackage=this.getFormData('adlabPackage');
+        let appType=this.getFormData('appType');
+
+        let downloadUrl='';
+        let externalUrl='';
+        if(downloadType=='DOWNLOAD_URL'){
+            downloadUrl=this.getFormData('url');
+            externalUrl='';
+        }else{
+            externalUrl=this.getFormData('url');
+            downloadUrl='';
+        }
+        if(downloadType=='DOWNLOAD_URL'&&appType=='APP_ANDROID'){
+            if(adlabPackage){
+            postAction('/ctop/queryTool/queryConvert',qs.stringify({
+                accountId:this.LHKaccountInfo[index].value,
+                landingType:this.projectInfo[index].landingType,
+                downloadType,
+                downloadUrl,
+                externalUrl,
+                toutiaoPackage:adlabPackage,
+                appType,
+                
+            })).then(res=>{
+                console.log(res)
+                if(res.success){
+                  this.showIndex=index+1
+                  this.currentConvertTypes[index]=[];
+                  res.result.data.forEach(ele=>{
+                    if(ele.external_actions.length>0){
+                      ele.external_actions.forEach(element=>{
+                        if(element.deep_external_action){
+                          element.deep_external_action.forEach(i=>{
+                            this.currentConvertTypes[index].push(i)
+                          })
+                        }else{
+                          this.currentConvertTypes[index].push(element)
+                        }
+                      })
+                    }
+                      
+                  })
+                
+                }else{
+                  this.$message.error('网络异常,数据获取失败')
+                }
+            })
+            }else{
+                this.$message.error('请先输入应用包名称!')
+            }
+        }else{
+            postAction('/ctop/queryTool/queryConvert',qs.stringify({
+                accountId:this.LHKaccountInfo[index].value,
+                landingType:this.projectInfo[index].landingType,
+                downloadType,
+                downloadUrl,
+                externalUrl,
+                toutiaoPackage:adlabPackage,
+                appType,
+                
+            })).then(res=>{
+                console.log(res);
+                if(res.success){
+                  this.showIndex=index+1;
+                  this.currentConvertTypes[index]=[];
+                  res.result.data.forEach(ele=>{
+                    if(ele.external_actions.length>0){
+                      ele.external_actions.forEach(element=>{
+                        if(element.deep_external_action){
+                          element.deep_external_action.forEach(i=>{
+                            this.currentConvertTypes[index].push(i)
+                          })
+                        }else{
+                          this.currentConvertTypes[index].push(element)
+                        }
+                      })
+                    }
+                      
+                  })
+                
+                }else{
+                  this.$message.error('网络异常,数据获取失败')
+                }
+            })
+        }
+
+        
+    },
+
+    // 转化目标改变
+    APIChange(val,index,item){
+      console.log(val,index,item);
+      this.convertIds[index]={
+        accountId:this.LHKaccountInfo[index].value,
+        convertId:val,
+
+      }
+      
+      // this.convertInfo[index]={
+      //   accountId:this.LHKaccountInfo[index].value,
+      //   ...item
+      // }
+    },
+   
+    //获取表单的某一个属性值
+    getFormData(className) {
+      return this.form.getFieldValue(className)
+    },
+    dateChange(date, dateString) {
+      // console.log(date,dateString)
+      this.form.getFieldDecorator('startTime')
+      this.form.getFieldDecorator('endTime')
+      this.form.setFieldsValue({
+        startTime: date[0].format('YYYY-MM-DD HH:mm'),
+        endTime:  date[1].format('YYYY-MM-DD HH:mm'),
+      })
+    },
+    
+    
+    
+    
+    // 验证网址
+    IsURL(res) {
+      //   var strRegex = /^([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/|www\.)(([A-Za-z0-9-~]+)\.)+([A-Za-z0-9-~\/])+$/
+      var strRegex = /^([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/)(([A-Za-z0-9-~]+)\.)+([A-Za-z0-9-~\/])+(.+[A-Za-z0-9-~\/])+$/
+      var re = new RegExp(strRegex)
+      // console.log(re.test(res))
+      if (re.test(res)) {
+        return true
+      } else {
+        return false
+      }
+    },
+    validateURL(rule, value, callback) {
+      // console.log(rule, value, callback);
+
+      if (this.IsURL(value)) {
+        callback()
+      } else if (value && !this.IsURL(value)) {
+        callback('链接地址无法访问,请正确输入')
+      } else {
+          callback('链接必须填写')
+      }
+    },
+    validateName(rule, value, callback){
+      // console.log(rule, value, callback);
+
+        if (value) {
+          callback()
+        } else {
+              callback('应用包名称必须填写')
+        }
+    },
+    validateBid(rule, value, callback){
+      // console.log(rule, value, callback);
+        if (value) {
+          callback()
+        } else {
+            callback('出价必须填写')
+        }
+    },
+
+   
+    
+    goBack() {
+      this.$router.replace('/modules/LaunchHousekeeper/LaunchHousekeeperList')
+      this.$bus.$emit('remove', '/LaunchHousekeeper/setProjectConvert')
+    },
+    
+    // 保存并新建创意
+    goNext() {
+      this.$nextTick(()=>{
+        
+          this.form.validateFields((err, values) => {
+            if (!err) {
+
+              console.log('Received values of form: ', values)
+              
+              this.goNextloading=true;
+              let params=[];
+              params=this.convertIds.map((item,index)=>{
+                return {
+                  ...item,
+                  ...values,
+                  ...this.projectInfo[index]
+                }
+              })
+              console.log(params)
+              postAction('/adlab/Project/setConvert', params).then((res) => {
+                console.log(res)
+                if (res.success) {
+                  this.goNextloading=false;
+                
+                    if(res.result){
+                        this.errorInfo=res.result;
+                        this.visible=true;
+
+                        let projectInfo=[]
+                        res.result.forEach(item=>{
+                            if(item.code==0){
+                              projectInfo.push(item)
+                            }
+                        })
+
+                         sessionStorage.setItem('projectInfo',JSON.stringify(projectInfo))
+                    }
+                 
+                } else {
+                   this.goNextloading=false;
+                  this.$message.error(res.message)
+                }
+              })
+            }else{
+              this.$message.error('请正确填写必填项目')
+            }
+          })
+        
+      })
+      
+    },
+    
+
+    
+  },
+  destroyed() {
+     sessionStorage.setItem('convertInfo',JSON.stringify(this.convertInfo))
+  },
+  mounted() {
+    this.$bus.$emit('remove', '/LaunchHousekeeper/newProject')
+        let projectInfo=sessionStorage.getItem('projectInfo');
+        if(projectInfo){
+            this.projectInfo=JSON.parse(projectInfo)
+        }
+        let LHKaccountInfo=sessionStorage.getItem('LHKaccountInfo');
+        if(LHKaccountInfo){
+            this.LHKaccountInfo=JSON.parse(LHKaccountInfo)
+        }
+    
+  },
+}
+</script>
+<style lang="scss">
+.newPlan{
+  .ant-btn-danger {
+    background-color: #ff4d4f !important; 
+  }
+}
+
+
+.ant-tooltip-inner,
+.ant-tooltip,
+.ant-tooltip-arrow::before {
+  background-color: #fff;
+  color: #333;
+}
+.ant-tooltip-inner {
+  span {
+    display: block;
+  }
+}
+.ant-tooltip {
+  max-width: 450px;
+}
+.newPlan {
+  .ant-radio-button-wrapper {
+    min-width: 80px;
+    text-align: center;
+  }
+  .ant-form-item {
+    -webkit-box-sizing: border-box;
+    box-sizing: border-box;
+    margin: 0;
+    padding: 0;
+    color: rgba(0, 0, 0, 0.65);
+    font-size: 14px;
+    font-variant: tabular-nums;
+    line-height: 1.5;
+    list-style: none;
+    -webkit-font-feature-settings: 'tnum';
+    font-feature-settings: 'tnum';
+    vertical-align: top;
+  }
+  .directedBody {
+    .ant-form-item {
+      margin-bottom: 20px;
+    }
+  }
+}
+</style>
+<style lang="scss" scoped>
+.newPlan {
+  font-family: PingFangSC-Regular, tahoma, arial, 'Hiragino Sans GB', 'Microsoft yahei', sans-serif;
+  color: #333;
+  ul,
+  li {
+    margin: 0;
+    padding: 0;
+  }
+  .moduler {
+    background: #fff;
+    margin-bottom: 16px;
+    position: relative;
+    padding: 32px 24px 48px 32px;
+    border-radius: 4px;
+    box-shadow: 0px 1px 6px 0px rgba(0, 0, 0, 0.05);
+    .moduler-title {
+      display: flex;
+      align-items: center;
+      font-size: 22px;
+      margin-bottom: 20px;
+    }
+    .row-item {
+      display: flex;
+      justify-content: flex-start;
+      align-items: center;
+      margin-bottom: 32px;
+    }
+    .row-item:last-of-type {
+      margin-bottom: 0;
+    }
+    .row-item .hint-item {
+      width: 24px;
+      min-width: 24px;
+      align-self: flex-start;
+      line-height: 20px;
+      height: 20px;
+      margin-top: 5px;
+    }
+    .row-item .label-item {
+      position: relative;
+      align-items: flex-start;
+      align-self: flex-start;
+      line-height: 20px;
+      height: 20px;
+      margin-top: 7px;
+      width: 80px;
+      min-width: 80px;
+      .text-item {
+        font-size: 14px;
+        width: 60px;
+      }
+    }
+    .row-item .required-item {
+      width: 4px;
+      height: 4px;
+      border-radius: 2px;
+      background: #f45858;
+      position: absolute;
+      right: 10px;
+      top: 50%;
+      transform: translateY(-50%);
+    }
+    .row-item .input-item {
+      min-width: 480px;
+      position: relative;
+      // height: 35px;
+      .tip {
+        font-size: 12px;
+        color: tomato;
+      }
+    }
+    .adName{
+      display: flex;
+      .nameList{
+        width: 90%;
+      }
+      .item{
+        display: inline-block;
+        width: 30%;
+        margin-left: 15px;
+        margin-bottom: 10px;
+      }
+    }
+  }
+  .opt {
+    text-align: right;
+  }
+}
+</style>

ファイルの差分が大きいため隠しています
+ 1819 - 0
src/views/modules/LaunchHousekeeper/setProjectCreate.vue


ファイルの差分が大きいため隠しています
+ 1068 - 0
src/views/modules/LaunchHousekeeper/setProjectDirectional.vue


+ 127 - 13
src/views/modules/Statistics/Statistics.vue

@@ -1,6 +1,13 @@
-<style>
+<style lang='less'>
+.ant-card-head .ant-tabs-bar{
+  padding: 0;
+}
 .search-box .ant-card-body {
   padding: 5px 15px;
+
+}
+.search-box{
+  padding: 15px 10px;
 }
 .search-box p {
   display: inline-block;
@@ -34,6 +41,26 @@
   top: 65px;
   right: 10px;
 }
+.statistics{
+  .ant-card-bordered {
+     border: none; 
+  }
+  .ant-card-head .ant-tabs {
+    clear: both;
+    margin-bottom: -13px;
+    color: rgba(0, 0, 0, 0.65);
+    font-weight: normal;
+    font-size: 14px;
+}
+.duibi{
+  position: absolute;
+  right: 24px;
+  top: 15px;
+}
+p{
+  margin-bottom: 0;
+}
+}
 </style>
 <template>
   <div class="statistics">
@@ -41,7 +68,7 @@
       <a-col :span="24">
         <a-card :bordered="false" class="search-box">
           <time-check @getAdd="getAdd" :startValue.sync="startValue"></time-check>
-          <p @click="visible = true">对比</p>
+          <!-- <p>对比</p> -->
         </a-card>
       </a-col>
     </a-row>
@@ -86,12 +113,13 @@
     <a-row :gutter="10">
       <a-col :span="24">
         <a-card
-          style="width:100%"
+          style="width:100%;position:relative"
           :tabList="tabListNoTitle"
           :activeTabKey="noTitleKey"
           @tabChange="key => onTabChange(key, 'noTitleKey')"
         >
           <div id="chart" style="width:100%;height:500px"></div>
+          <a-button class="duibi" type='primary'  @click="visible = true">数据对比</a-button>
         </a-card>
       </a-col>
     </a-row>
@@ -275,14 +303,22 @@
         </a-col>
       </a-row>
     </a-modal>
-    <a-row style="margin-bottom:15px;margin-top:15px">
+    <a-row style="margin-bottom:15px;margin-top:12px">
       <a-col :span="24">
         <a-card
           :tabList="tableNowCard"
+
           :activeTabKey="noTitleKeyTable"
           @tabChange="key => onTabChange(key, 'noTitleKeyTable')"
+           style="word-break: break-all;font-size:16px;font-weight:600"
         >
-          <a-table :columns="columns" :dataSource="dataTable" :pagination="false" :loading="loading" bordered></a-table>
+          <a-table :columns="columns" :dataSource="dataTable" :pagination="false" :loading="loading" bordered>
+            <!-- <span slot="cost" slot-scope="cost">{{ cost | decimalsHandle }}</span> -->
+            <span slot="cost" slot-scope="cost">{{ cost | decimalsHandle }}</span>
+            <span slot="photoClick" slot-scope="photoClick">{{ photoClick | formatCurrency }}</span>
+            <span slot="photoShow" slot-scope="photoShow">{{ photoShow | formatCurrency }}</span>
+            <span slot="aclick" slot-scope="aclick">{{ aclick | formatCurrency }}</span>
+          </a-table>
         </a-card>
       </a-col>
     </a-row>
@@ -335,35 +371,35 @@ export default {
           scopedSlots: { customRender: 'yesCost' },
           align: 'center'
         },
-        { title: '总消耗', dataIndex: 'cost', align: 'center' },
+        { title: '总消耗', dataIndex: 'cost', align: 'center' , scopedSlots: { customRender: 'cost' },},
         {
           title: '封面点击数环比',
           dataIndex: 'yesPhotoClick',
           scopedSlots: { customRender: 'photoClickProportion' },
           align: 'center'
         },
-        { title: '封面点击数', dataIndex: 'photoClick', align: 'center' },
+        { title: '封面点击数', dataIndex: 'photoClick', align: 'center', scopedSlots: { customRender: 'photoClick' }, },
         {
           title: '封面曝光数环比',
           dataIndex: 'yesPhotoShow',
           scopedSlots: { customRender: 'photoShowProportion' },
           align: 'center'
         },
-        { title: '封面曝光数', dataIndex: 'photoShow', align: 'center' },
+        { title: '封面曝光数', dataIndex: 'photoShow', align: 'center' , scopedSlots: { customRender: 'photoShow' },},
         {
           title: '素材曝光数环比',
           dataIndex: 'yesAclick',
           scopedSlots: { customRender: 'aclickProportion' },
           align: 'center'
         },
-        { title: '素材曝光数', dataIndex: 'aclick', align: 'center' }
+        { title: '素材曝光数', dataIndex: 'aclick', align: 'center', scopedSlots: { customRender: 'aclick' }, }
       ],
       columnsDb: [
         { title: '时间', dataIndex: 'statDate', align: 'center' },
-        { title: '总消耗', dataIndex: 'cost', align: 'center' },
-        { title: '封面点击数', dataIndex: 'photoClick', align: 'center' },
-        { title: '封面曝光数', dataIndex: 'photoShow', align: 'center' },
-        { title: '素材曝光数', dataIndex: 'aclick', align: 'center' }
+        { title: '总消耗', dataIndex: 'cost', align: 'center' , scopedSlots: { customRender: 'cost' },},
+        { title: '封面点击数', dataIndex: 'photoClick', align: 'center', scopedSlots: { customRender: 'photoClick' }, },
+        { title: '封面曝光数', dataIndex: 'photoShow', align: 'center', scopedSlots: { customRender: 'photoShow' }, },
+        { title: '素材曝光数', dataIndex: 'aclick', align: 'center', scopedSlots: { customRender: 'aclick' }, }
       ],
       dataTable: [],
       dataTableTwo: [],
@@ -1492,6 +1528,84 @@ export default {
   },
   deactivated() {
     window.clearTimeout(upDate)
+  },
+  filters: {
+    toPercentage(val) {
+      if(typeof val != 'string'){
+          return (val * 100).toFixed(2) + '%'
+      }else{
+        return val
+      }
+      
+    },
+    //保留两位小数并且变成货币格式
+    decimalsHandle(val){
+        
+        if(val && typeof val !='string'){
+            if(val>=0){
+                val=parseFloat(val).toFixed(2);
+                let numberStr = val.toString()
+                let str = numberStr.split('.')
+                
+                let str0=str[0].split('').reverse();
+                for (let i = 0; i < str0.length; i++) {
+                    if ((i + 1) % 4 === 0) {
+                        str0.splice(i, 0, ',')
+                    }
+                }
+                str0.reverse()
+                let handleResult = ''
+                for (let j = 0; j < str0.length; j++) {
+                    handleResult += str0[j]
+                }
+                
+                return handleResult+'.'+str[1]
+            }else{
+                val=parseFloat(val).toFixed(2);
+                let numberStr = val.toString()
+                let str = numberStr.split('.')
+                
+                let str0=str[0].substr(1).split('').reverse();
+                for (let i = 0; i < str0.length; i++) {
+                    if ((i + 1) % 4 === 0) {
+                        str0.splice(i, 0, ',')
+                    }
+                }
+                str0.reverse()
+                let handleResult = ''
+                for (let j = 0; j < str0.length; j++) {
+                    handleResult += str0[j]
+                }
+                
+                return '-'+handleResult+'.'+str[1]
+            }
+            
+        }else if(typeof val =='string'){
+            return val
+        }
+        else{
+            return 0
+        }           
+    },
+    //变成货币格式
+    formatCurrency(val){
+      if(val){
+          let numberStr = val.toString()
+        let str = numberStr.split('').reverse()
+        for (let i = 0; i < str.length; i++) {
+            if ((i + 1) % 4 === 0) {
+            str.splice(i, 0, ',')
+            }
+        }
+        str.reverse()
+        let handleResult = ''
+        for (let j = 0; j < str.length; j++) {
+            handleResult += str[j]
+        }
+        return handleResult
+      }
+        
+    }
   }
 }
 </script>

+ 1 - 5
src/views/modules/Statistics/accountReport.vue

@@ -19,7 +19,7 @@
             @change="treeChange"
             @search="treeSearch"
             @select="treeSelect"                        
-             :maxTagCount='1'    
+            :maxTagCount='1'    
             :tree-data="treeData"
             :filterOption='filterOption'
           >
@@ -105,11 +105,7 @@
                   </span>
                 </a-tooltip>
             </div>
-            <div class="infoNum">
-                <span class="red">{{showNumLink.showNum | formatCurrency }}</span> 
-                <span class="green" v-if="dateValue[0].format('YYYY-MM-DD')==dateValue[1].format('YYYY-MM-DD')"><span class="huanbi">环比: </span> {{ showNumLink.showNumLink|toPercentage  }}</span> 
             </div>
-        </div>
         <div class="showBox">
             <div class="title">
                 <div class="infotitle">转化数</div>

+ 209 - 0
src/views/modules/Statistics/components/datePick.vue

@@ -0,0 +1,209 @@
+<template>
+  
+  <div class="datePicker" >
+      <p
+      :style="active == item.value ? 'color:cornflowerblue;background:#f2f2f2' : ''"
+      v-for="(item, index) of pickOptions"
+      :key="index"
+      @click="changeDate(item)"
+    >
+      {{ item.title }}
+    </p>
+   
+    <a-range-picker v-clickoutside="handleClose"
+      v-model="mydateValue"
+      style="width:250px;"
+      :allowClear=false      
+      :disabled-date="disabledDate"
+      :openChange="openChange"
+      @change="onChange"
+    />
+    
+  </div>
+</template>
+
+
+<script>
+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__
+  }
+}
+import moment from 'moment'
+let pickOptions = [
+  {
+    title: '今天',
+    key: '1',
+    value: 1,
+    dateValue: [moment(), moment()]
+  },
+  {
+    title: '昨天',
+    key: '2',
+    value: 2,
+    dateValue: [moment().subtract(1, 'days'), moment().subtract(1, 'days')]
+  },
+  {
+    title: '一周',
+    key: '3',
+    value: 3,
+    dateValue: [moment().subtract(7, 'days'), moment().subtract(1, 'days')]
+  },
+  {
+    title: '一个月',
+    key: '5',
+    value: 5,
+    dateValue: [
+      moment()
+        .subtract(1, 'days')
+        .subtract(1, 'months'),
+      moment().subtract(1, 'days')
+    ]
+  },
+  {
+    title: '三个月',
+    key: '6',
+    value: 6,
+    dateValue: [
+      moment()
+        .subtract(1, 'days')
+        .subtract(3, 'months'),
+      moment().subtract(1, 'days')
+    ]
+  },
+  {
+    title: '六个月',
+    key: '7',
+    value: 7,
+    dateValue: [
+      moment()
+        .subtract(1, 'days')
+        .subtract(6, 'months'),
+      moment().subtract(1, 'days')
+    ]
+  },
+  {
+    title: '一年',
+    key: '8',
+    value: 8,
+    dateValue: [
+      moment().subtract(1, 'days').subtract(1, 'years'),
+      moment().subtract(1, 'days')
+    ]
+  }
+]
+
+export default {
+  props: ['dateValue','type'],
+  data() {
+    return {
+      moment,
+      mydateValue: [moment(),moment()],
+      pickOptions,
+      active:1
+      // pickOptions:JSON.parse(JSON.stringify(pickOptions))
+    }
+  },
+  directives: { clickoutside },
+  watch: {
+    parentDate(n,o){
+        if(n[0].format('YYYY-MM-DD')!=this.mydateValue[0].format('YYYY-MM-DD')){
+              this.mydateValue=n
+        } 
+    }
+  },
+  methods: {
+    //日期改变事件
+    onChange(date, dateString) {
+      this.mydateValue = date
+      this.active=9;
+      console.log(this.mydateValue)
+      if (dateString.length == 2) {   
+        this.$emit('update:dateValue', this.mydateValue)
+        this.$emit('update:type', 9)
+      }
+    },
+    //侧边的按钮点击事件
+    changeDate(val) {
+        console.log(val);
+        this.active=val.value;
+        this.mydateValue = val.dateValue
+      
+        this.$emit('update:dateValue', this.mydateValue)
+        this.$emit('update:type', val.value)
+    },
+    handleClose(e) {
+        // console.log(e)
+        if(e.target.className){
+            if(e.target.className.indexOf('ant-calendar')==-1){
+                // this.$parent.opendateClose()
+            }
+        }
+            
+      
+    },
+    disabledDate(current) {
+      // console.log(current)
+
+      return current && current > moment().subtract(1, 'day')
+    },
+    openChange(open) {
+      // console.log(open)
+    }
+  },
+  mounted() {
+    this.mydateValue = [moment(), moment()]    
+    // console.log(this.$refs.pickOptions.style.left)
+  }
+
+}
+</script>
+
+<style lang="scss" scoped>
+.datePicker {
+  position: relative;
+  p{
+      margin-bottom: 0;
+  }
+  .pickOptions {
+    width: 100px;
+    background-color: #fff;
+    height: 302px;
+    position: absolute;
+    top: -2px;
+    left: -402px;
+    border-right: 1px solid #999;
+    box-shadow: 0 0 15px rgba(0, 0, 0, 0.1);
+    cursor: pointer;
+    z-index: 3;
+    div {
+      height: 43px;
+      padding: 10px 15px;
+      box-sizing: border-box;
+    }
+    .btn:hover{
+        color: #1890ff;
+    }
+  }
+}
+</style>

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

@@ -11,10 +11,13 @@
   padding: 5px 10px;
   cursor: pointer;
 }
+p{
+  margin-bottom: 0px;
+}
 </style>
 <style>
 .data-display-statistics{
-  margin: 10px 0;
+  margin: 12px 0;
 }
 .data-display-statistics .ant-card-body {
   display: flex;

+ 769 - 0
src/views/modules/Statistics/imageStatics/imageCostReport.vue

@@ -0,0 +1,769 @@
+<template>
+  <div class="vsummary">
+      <div class="tabspane">
+        <a-tabs v-model="tabKeys" @change="tabChange">
+            <a-tab-pane :key="1" tab="头条">           
+            </a-tab-pane>
+            <a-tab-pane :key="2" tab="快手" >               
+            </a-tab-pane>
+        </a-tabs>
+      </div>
+    <div class="xiangmuxuanze">
+      <span>项目选择:</span>
+       
+        <a-tree-select
+            v-model="accountIds"
+            show-search
+            style="width: 600px;height:30px"
+            :dropdownMatchSelectWidth='true'
+            :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"              
+            tree-checkable
+            searchPlaceholder='请输入账户关键字搜索'
+            :show-checked-strategy="SHOW_PARENT"
+            placeholder="请选择项目和账户或搜索账户关键字"
+            treeNodeFilterProp="title"
+            :allowClear="true"
+            @change="treeChange"                               
+            :maxTagCount='1'    
+            :tree-data="treeData"
+            :filterOption='filterOption'
+        >
+        
+        </a-tree-select>
+        
+    </div>
+    <div class="timeDiv">
+      <div>
+        <span>时间范围:</span>
+
+        <a-range-picker
+          :disabled-date="disabledDate"
+          format="YYYY-MM-DD"
+          style="width: 250px;"
+          @change="dateChange"
+          v-model="dateRange"
+        />
+        
+      </div>
+      <div>
+        <span>图片ID:</span>
+        <a-input class="myinput" v-model="videoID" style="width:250px" />
+      </div>
+
+      <a-button type="primary" @click="searchRes">查询</a-button>
+    </div>
+
+    <div style="display:flex;margin:15px 0" class="btndiv">
+      <a-button type="primary" @click="exportExcel" id="mybtn" v-show="exportExcelIsOk">导出报表</a-button>
+    </div>
+
+   
+    <div class="tableBody">
+
+        <a-table
+        size="middle"
+        :columns="columns"
+        :dataSource="data"
+        bordered
+        id="outTable"
+        :pagination="ipagination"
+        :scroll="{ x: scrollX }"
+        :loading="loading"
+        @change="sort"
+        style="word-break: break-all;padding:0 15px"
+        >
+        <div slot="imageUrl" slot-scope="text,records">
+            <img
+            :src="text"
+            alt
+            style="width:80px"
+            @click="openVideo(records.imageUrl)"
+            @load="loadShow"
+            />
+        </div>
+        <span slot="ctr" slot-scope="ctr">{{ ctr | toPercentage }}</span>
+        
+
+        </a-table>
+    
+    </div>
+    <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%">
+      <img
+        @click.stop
+        class="video"
+        :src="videoUrl"
+        controls="controls"
+        style="height:600px;width:100%"
+      />
+    </a-modal>
+  </div>
+</template>
+
+<script>
+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 selectComponent from './selectComponent'
+// import Treeselect from '../components/Treeselect'
+const TTcolumns = [
+  {
+    title: '图片',
+    dataIndex: 'imageUrl',
+    align: 'center',
+    width: 100,
+    fixed: 'left',
+    key: 'imageUrl',
+    scopedSlots: { customRender: 'imageUrl' }
+  },
+  {
+    title: '图片ID',
+    dataIndex: 'signature',
+    align: 'center',
+    width: 150,
+    fixed: 'left'
+  },
+  {
+    title: '项目名称',
+    dataIndex: 'projectName',
+    align: 'center',
+    width: 200,
+    fixed: 'left'
+  },
+    {
+    title:'相关人员',
+    dataIndex:'operation',
+    key:'operation',
+    scopedSlots: { customRender: 'operation' },
+    align: 'center',
+    width:100,
+    fixed: 'left'
+  },
+  
+  {
+    title: '消耗',
+    dataIndex: 'cost',
+
+    scopedSlots: { customRender: 'cost' },
+    align: 'center',
+    sorter: () => {}
+  },
+  {
+    title: '点击数',
+    dataIndex: 'click',
+    align: 'center',
+
+    scopedSlots: { customRender: 'click' },
+    sorter: () => {}
+    // (a, b) => a.clickMaterial - b.clickMaterial
+  },
+  {
+    title: '展示数',
+    dataIndex: 'showNum',
+    align: 'center',
+
+    scopedSlots: { customRender: 'showNum' },
+    sorter: () => {}
+  },   
+  {
+    title: '转化数',
+    dataIndex: 'convert',
+    align: 'center',
+
+    scopedSlots: { customRender: 'convert' },
+    sorter: () => {}
+  },
+  {
+    title: '上传时间',
+    dataIndex: 'statDate',
+    scopedSlots: { customRender: 'statDate' },
+    align: 'center',
+    sorter: () => {}
+  },
+]
+const KScolumns = [
+  {
+    title: '图片',
+    dataIndex: 'videoU',
+    align: 'center',
+    width: 100,
+    fixed: 'left',
+    key: 'videoU',
+    scopedSlots: { customRender: 'videoU' }
+  },
+  {
+    title: '图片ID',
+    dataIndex: 'signature',
+    align: 'center',
+    width: 150,
+    fixed: 'left'
+  },
+  {
+    title: '项目名称',
+    dataIndex: 'projectName',
+    align: 'center',
+    width: 200,
+    fixed: 'left'
+  },
+    {
+    title:'相关人员',
+    dataIndex:'operation',
+    key:'operation',
+    scopedSlots: { customRender: 'operation' },
+    align: 'center',
+    width:100,
+    fixed: 'left'
+  },
+  
+  {
+    title: '消耗',
+    dataIndex: 'cost',
+
+    scopedSlots: { customRender: 'cost' },
+    align: 'center',
+    sorter: () => {}
+  },
+  {
+    title: '点击数',
+    dataIndex: 'clickMaterial',
+    align: 'center',
+
+    scopedSlots: { customRender: 'clickMaterial' },
+    sorter: () => {}
+    // (a, b) => a.clickMaterial - b.clickMaterial
+  },
+  {
+    title: '展示数',
+    dataIndex: 'showMaterial',
+    align: 'center',
+
+    scopedSlots: { customRender: 'showMaterial' },
+    sorter: () => {}
+  },   
+  {
+    title: '转化数',
+    dataIndex: 'convertMaterial',
+    align: 'center',
+
+    scopedSlots: { customRender: 'convertMaterial' },
+    sorter: () => {}
+  },
+  {
+    title: '上传时间',
+    dataIndex: 'materialUploadTime',
+    scopedSlots: { customRender: 'materialUploadTime' },
+    align: 'center',
+    sorter: () => {}
+  },
+]
+
+
+let show = 0
+
+export default {
+  data() {
+    return {
+        tabKeys:1,
+        
+        accountIds:[],
+        treeData:[],
+        SHOW_PARENT,
+        KSaccountList:[],
+        TTaccountList:[],
+        accountID:undefined,
+        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;
+            }
+        },
+
+
+
+        relevantPeopleVisible:false,
+      relevantPeopleData:{},
+      roleCode: localStorage.getItem('roleCode'),
+       //下拉选择框的数据
+      projectArr:[],
+      selectValue:'',
+      appId:[],
+      //设置表格的列宽
+      tableWidth: '',
+
+      //gudinglie
+  
+
+      //是否打开视频
+      Videovisible: false,
+      videoUrl: '',
+
+      //是否显示导出按钮
+      exportExcelIsOk: true,
+      consumeValue: 0,
+
+      columns: [...TTcolumns],
+      TTcolumns,
+      KScolumns,
+      data: [],
+      totalSelect: 0,
+      daysFlag: false,
+      dateRange: [],
+      dataElse: [],
+      loading: false,
+      visible: false,
+      //自定义列的搜索框
+      searchInput: '',
+      //弹出框中现实的选中列数
+      scrollX: 0,
+      listNum: [],
+      //
+      form: [],
+      videoID: '',
+      timedata: []
+    }
+  },
+  // mixins: [JeecgListMixin],
+  components: {
+    // selectComponent,
+    // Treeselect
+  },
+    methods: {
+        tabChange(val){
+          this.accountIds=[];
+            if(this.tabKeys==1){
+                this.treeData=this.TTaccountList;
+                this.columns=this.TTcolumns;
+                
+            }else if (this.tabKeys==2){
+                this.treeData=this.KSaccountList;
+                this.columns=this.KScolumns
+            }
+        },
+        treeChange(val) {
+        // console.log(this.treeData)
+            console.log(val)
+            this.accountIds = [];
+            
+            if(val){
+                val.forEach((ele,index)=>{
+                if(ele*1){
+                    this.accountIds.push(ele)
+                }else{              
+                    let projectArr=this.treeData.filter((item)=>{
+                        return item.value==ele
+                    });
+                    // console.log(projectArr)
+                    projectArr[0].children.forEach((element)=>{
+                        this.accountIds.push(element.value)
+                    })
+                }
+
+
+                })       
+            }
+            
+            console.log(this.accountIds);
+            
+
+        
+        },
+        
+        
+        filterOption(input, option){
+            console.log(input, option)
+            return (
+                option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
+                );
+        },
+
+        // 查看相关人员
+        showRelevantPeople(record){
+        this.relevantPeopleVisible=true;
+        console.log(record)
+        getAction('/ctop/materialAscription/getDetail',{
+            code:record.signature
+        }).then(res=>{
+            console.log(res);
+            if(res.result&&res.success){
+            this.relevantPeopleData=res.result
+            }
+            
+        })
+        },
+        sort(pagination, filters, sorter, { currentDataSource }){
+            console.log(pagination, filters, sorter)
+            if(sorter.order == 'ascend'){
+                this.HttpPost(sorter.columnKey+'+')
+                return 
+            }else if(sorter.order == 'descend'){
+                this.HttpPost(sorter.columnKey+'-')
+                return 
+            }
+            this.ipagination.current=pagination.current
+            this.HttpPost()
+        },
+        moment,
+        //select切换---项目
+        selectChange(key){
+            this.selectValue=key;
+        },
+        //打开视频
+        openVideo(val) {
+          this.Videovisible = true
+          this.videoUrl = val
+        },
+        videoOk() {
+          this.Videovisible = false
+        },
+
+        disabledDate(current) {
+        // console.log(current)
+          return current && current > moment().subtract(1, 'day')
+        },
+
+        consumeOnChange() {},
+        //查询按钮
+        searchRes() {
+            this.date = []
+            this.HttpPost()       
+        },
+        loadShow(){
+            show++
+            if(this.data.length>0){
+                if(show == (this.data.length*2)){
+                    this.data = [...this.data]
+                }
+            }
+        },
+        //网络请求table数据函数
+        HttpPost(sort){
+          this.loading=true;
+          show = 0
+          postAction('/image/bytedance/cost', {
+              startDate: this.timedata[0],
+              endDate: this.timedata[1],        
+              code: this.videoID,
+              pageNumber:this.ipagination.current,
+              pageSize:this.ipagination.pageSize,
+              accountList:this.accountIds,
+              // sort:sort?sort:''
+          }).then(res => {
+              let resArr = []
+              this.loading=false;
+              if (res.success) {
+              //   let result = res.result
+              //   this.data.push({ ...result, key: 1 })
+              //   result.map((item, index) => {
+              //     item.key = index
+              //   })
+              this.data = res.data.list.map((item,index)=>{
+                  return {
+                      ...item,
+                      key:index
+                  }
+              })
+              this.ipagination.total = res.data.total
+              this.loading = false
+              
+              }else{
+                  this.loading = false
+              }
+          })
+        },
+        //导出报表
+        exportExcel() {
+        // var params = {}
+        // params.projectId = this.projectId
+        // params.disCount = this.discount
+        // params.statDate = this.statDate.format('YYYY-MM-DD')
+        // var name = this.dataElse.filter(item => {
+        //   return item.projectId == this.projectId
+        // })[0].projectName
+        // downFilePost('/ctop/yiche/report/exportDailyReport', params).then(res => {
+        //   let blob = new Blob([res], {
+        //     type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
+        let column = this.columns.map((item, index) => {
+            return item.dataIndex
+        })
+            let columns=['url',...column]
+            
+        downFilePost('/toutiao/videoReportDaily/bytedanceVideoInfoListTotalExportExcel', {
+            columns,
+            signature: this.videoID,
+            startDate: this.timedata[0],
+            endDate: this.timedata[1],
+            cost: this.consumeValue,
+            accountIds:this.appId,
+        }).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 = this.statDate.format('YYYY-MM-DD') + '视频汇总.xlsx' //下载后文件名
+            document.body.appendChild(downloadElement)
+            downloadElement.click() //点击下载
+            document.body.removeChild(downloadElement) //下载完成移除元素
+            window.URL.revokeObjectURL(href) //释放掉blob对象
+        })
+        },
+
+        //日期选择回调
+        dateChange(data, dataString) {
+        if (data.length) {
+            this.timedata = dataString
+            this.dateRange[0] = data[0]
+            this.totalSelect = (data[1]._d - data[0]._d) / (24 * 60 * 60 * 1000) + 1
+            this.daysFlag = true
+            if (this.totalSelect > 92) {
+            this.$message.error('时间跨度太长啦,选小一点好嘛?')
+            this.daysFlag = false
+            this.dateRange = []
+            }
+        } else {
+            this.daysFlag = false
+            this.dateRange = []
+        }
+        },
+
+        //请求项目和账户内容
+        accountHttp(type){
+            this.accountID=undefined;
+            getAction(`/ctop/projectMember/getProjectAccountByUserId?mediaType=${type}`, {}).then(res => {
+                if(res.success){                   
+                    if(res.result){
+                        res.result.forEach((element,index) => {
+                        if(element){
+                            if(type==1){
+                                this.TTaccountList.push({});
+                                this.TTaccountList[index].title=element.project.projectName +'_('+ element.project.advertiserName +')';
+                                this.TTaccountList[index].value='project'+element.project.projectId;
+                                this.TTaccountList[index].key=element.project.projectId;
+                                this.TTaccountList[index].mediaId=element.project.mediaId;
+                                this.TTaccountList[index].children=[];
+
+                                if(element.account.length){
+                                    element.account.forEach((ele,i)=>{
+                                        this.TTaccountList[index].children.push({});
+                                        this.TTaccountList[index].children[i].title=ele.userName+'_'+ele.authName;
+                                        this.TTaccountList[index].children[i].value=ele.accountId;
+                                        this.TTaccountList[index].children[i].key=ele.accountId;
+                                    })
+
+                                }
+                                this.treeData=this.TTaccountList
+                            }else if(type==2){
+                                this.KSaccountList.push({});
+                                this.KSaccountList[index].title=element.project.projectName +'_('+ element.project.advertiserName +')';
+                                this.KSaccountList[index].value='project'+element.project.projectId;
+                                this.KSaccountList[index].key=element.project.projectId;
+                                this.KSaccountList[index].mediaId=element.project.mediaId;
+                                this.KSaccountList[index].children=[];
+
+                                if(element.account.length){
+                                    element.account.forEach((ele,i)=>{
+                                        this.KSaccountList[index].children.push({});
+                                        this.KSaccountList[index].children[i].title=ele.userName+'_'+ele.authName;
+                                        this.KSaccountList[index].children[i].value=ele.accountId;
+                                        this.KSaccountList[index].children[i].key=ele.accountId;
+                                    })
+
+                                }
+                                this.treeData=this.KSaccountList
+                            }
+                            
+                        }
+                        });
+                        // console.log(this.treeData)
+
+                    }
+                }
+            })
+        },
+  },
+  // watch:{
+  //     'ipagination.current':function(n,o){
+  //         console.log(n,o)
+  //         this.HttpPost()
+  //     }
+  // },
+ 
+  filters: {
+    toPercentage(val) {
+      return (val * 100).toFixed(2) + '%'
+      // return val
+    },
+    toshowTime(val) {
+      // console.log(val, this.timedata)
+      // return this.timedata[0] + '~' + this.timedata[1]
+      return val
+    },
+    tofixed(val) {
+      return Number(val).toFixed(2)
+    }
+  },
+
+  mounted() {
+    
+    //进入页面默认展示昨天到今天的数据
+    this.dateRange=[moment().subtract(1,'days'),moment()]
+    this.timedata=[moment().subtract(1
+    ,'days').format('YYYY-MM-DD'),moment().format('YYYY-MM-DD')]
+    // this.loading=true;
+   
+    this.HttpPost()
+    this.accountHttp(1);
+    this.accountHttp(2);
+    
+    
+  }
+}
+</script>
+<style lang="less">
+// .ant-table .ant-table-fixed-left .ant-table-thead {
+//   height: 108px !important ;
+// }
+.vsummary{
+  .ant-table .ant-table-thead .ant-table-header-column .ant-table-column-title {
+    // display:block;
+    white-space: normal;
+    word-break: break-all;
+  }
+}
+
+</style>
+
+<style lang="scss" scoped>
+.vsummary {
+  width: 100%;
+  height: 100%;
+  background:  #fff;
+  padding: 20px;
+  box-sizing: border-box;
+}
+.tableBody{
+   margin-top: 20px;
+}
+.xiangmuxuanze{
+  margin-bottom: 20px;;
+}
+.timeDiv {
+  display: flex;
+  justify-content: space-between;
+}
+span {
+  margin-left: 5px;
+}
+.myinput {
+  width: 40%;
+}
+
+.addlist {
+  float: left;
+  width: 70%;
+  border: 1px solid #eee;
+  .selectionList {
+    padding: 10px 15px;
+    height: 450px;
+    overflow: auto;
+    .leibie {
+      .leiName {
+        font-size: 26px;
+        text-align: left;
+      }
+    }
+    .jutixiang {
+      display: inline-block;
+      width: 32%;
+      box-sizing: border-box;
+      padding: 10px 3px;
+    }
+  }
+}
+.listNum {
+  float: right;
+  width: 28%;
+  border: 1px solid #eee;
+  position: relative;
+}
+.zhuti {
+  margin-top: 15px;
+  overflow: hidden;
+
+  p {
+    height: 40px;
+    line-height: 20px;
+    padding: 10px 15px;
+
+    background: rgb(249, 250, 253);
+    border-bottom: 1px solid #eee;
+  }
+  #btn {
+    position: absolute;
+    right: 0;
+    top: 5px;
+  }
+  .selectlist {
+    width: 100%;
+    list-style: none;
+    margin: 0;
+    height: 450px;
+    padding: 0 15px 10px;
+    overflow: auto;
+
+    li {
+      width: 100%;
+      padding: 5px 8px;
+      margin: 6px 0;
+      border-radius: 10px;
+      background: rgb(248, 248, 248);
+      height: 32px;
+      position: relative;
+      span {
+        width: 80%;
+        height: 100%;
+        display: inline-block;
+        margin: 0 10px;
+        // overflow:hidden;
+        // text-overflow:ellipsis;
+        // white-space: nowrap;
+      }
+      .listText {
+        position: absolute;
+        top: 2;
+        left: 10;
+        width: 40%;
+        overflow: hidden;
+        white-space: nowrap;
+        text-overflow: ellipsis;
+      }
+      #closeStyle {
+        position: absolute;
+        top: 9px;
+        right: 7px;
+      }
+    }
+  }
+}
+</style>

+ 57 - 30
src/views/modules/Statistics/newHome.vue

@@ -2,7 +2,13 @@
   <div class="homePage">
     <div>
       <a-row :gutter="16">
-       
+       <a-col :span="24">
+        <a-card :bordered="false" class="search-box">
+          <div class="time"  @click="opendate" >
+            <datePick  :dateValue.sync='dateValue'   :type.sync='type'   />
+          </div>
+        </a-card>
+      </a-col>
         <a-col :sm="24" :md="12" :xl="6" :xxl="6" class="topBox">
           <div class="showBox">
             <div class="title">
@@ -105,6 +111,9 @@
     </div>
     <!-- 折线图模块 -->
     <div class="section">
+      <a-spin :spinning="spinning">
+     
+    
         <a-tabs default-active-key="cost" @change="callback" >
             <a-tab-pane key="cost" tab="总消耗"> 
             </a-tab-pane>
@@ -114,10 +123,8 @@
             </a-tab-pane>
         </a-tabs>
         <div id="sectionChart" style='width:100%;height:300px' ref="sectionChart"></div>
-        <a-button class="duibi" @click="comparehandle" type='default' >对比</a-button>
-        <div class="time"  @click="opendate" >
-            <DatePicker :openOptions='openOptions' :left='0' :parentDate='dateValue' />
-        </div>
+        <a-button class="duibi" @click="comparehandle" type='primary' >数据对比</a-button>
+      </a-spin>
     </div>
 
 
@@ -151,8 +158,9 @@
 <script>
 import moment from 'moment'
 import DatePicker from '@/components/DatePicker.vue'
+import datePick from './components/datePick'
 import CompareData from './CompareData.vue'
-
+import timeCheck from './components/timeCheck'
 import { getAction, postAction, downFile, downFilePost } from '@/api/manage'
 // import vueEchart from './components/vueEchart'
 // 引入基本模板
@@ -378,7 +386,9 @@ export default {
   
     components:{
         DatePicker,
-        CompareData
+        CompareData,
+        timeCheck,
+        datePick
     },
   data() {
     return {
@@ -407,16 +417,16 @@ export default {
       //子元素的数据存储
     
         type:1,
-        dateValue:[moment(),moment()],
+        dateValue:[moment(), moment()],
         
       //日期矿打开
       openOptions:false,
-
+      spinning:false,
     }
   },
   watch:{
     type(n,o){
-      // console.log(n,o)
+      console.log(n,o)
         // console.log(this.type)
         if(this.type<9){
             this.sectionHttp({type:this.type})
@@ -430,17 +440,20 @@ export default {
         }
     },
     dateValue: {
-    handler(newName, oldName) {
-      // console.log(newName,oldName)
-        this.sectionHttp({
-            type:this.type,
-            startDate:this.dateValue[0].format('YYYY-MM-DD'),
-            endDate:this.dateValue[1].format('YYYY-MM-DD')
-            })
-    },
-    immediate: true,
-    deep: true
-  }
+      handler(newName, oldName) {
+        console.log(newName,oldName)
+        if(newName.length>1){
+          this.sectionHttp({
+              type:this.type,
+              startDate:this.dateValue[0].format('YYYY-MM-DD'),
+              endDate:this.dateValue[1].format('YYYY-MM-DD')
+          })
+        }
+          
+      },
+      immediate: true,
+      deep: true
+    }
   },
   methods: {
     //获取echart的值
@@ -499,13 +512,15 @@ export default {
     },
     //处理echart
     sectionHttp(params) {
-      this.loading = true
+      this.loading = true;
+      this.spinning=true;
       this.sectionOption=JSON.parse(JSON.stringify(sectionOption));
       return new Promise((resolve, reject) => {
         postAction('/ctop/byteDance/homePage/report/chart', params).then(res => {
           // console.log(res)
           if (res.success) {
             this.loading = false
+            this.spinning=false;
             //处理今天
             if(res.result){
 
@@ -867,16 +882,21 @@ export default {
 
 <style lang="scss" scoped>
 .homePage {
+    p {
+     margin-bottom: 0;
+    }
     .topBox{
-        margin-bottom: 20px;
+        margin-bottom: 12px;
+        margin-top: 12px;
+        border-radius: 2px;
     }
   .showBox {
-    width: 98%;
+    width: 100%;
     box-sizing: border-box;
     margin-right: 20px;
     padding: 25px 25px 0;
     background-color: #fff;
-    
+    border-radius: 2px;
     .title {
       color: #999;
       font-size: 16px;
@@ -903,7 +923,9 @@ export default {
       margin-bottom: 0;
     }
   }
-
+  .topBox:last-child{
+    margin-right: 0;
+  }
   .footerInfo {
     margin-top: 10px;
     border-top: 1px solid #eee;
@@ -945,19 +967,23 @@ export default {
   }
 
   .section{
+    #sectionChart{
+      padding: 0px  30px;
+    }
       width: 100%;
       background-color: #fff;
-      padding: 10px 15px 20px;
+      padding: 10px 0 20px;
       position: relative;
-      margin-bottom: 20px;;
+      margin-bottom: 12px;;
+       border-radius: 2px;
       .duibi{
           position: absolute;
           
           height: 30px;
           line-height: 30px;
           padding: 0 15px;
-          top: 15px;
-          right: 300px;
+          top: 8px;
+          right: 20px;
           // border: 1px solid #666;
           cursor: pointer;
       }
@@ -976,6 +1002,7 @@ export default {
     width: 100%;
     padding: 20px 15px;
     background-color: #fff;
+     border-radius: 2px;
     p{
       width: 100%;
       border-bottom: 1px solid #ccc;

+ 38 - 38
src/views/modules/material/labelMaterial.vue

@@ -52,10 +52,9 @@
 
     <!-- table区域-begin -->
     <div>
-      <a-table
-        ref="table"
+      <a-table       
         size="middle"
-        bordered
+        
         rowKey="id"
         :columns="columns"
         :dataSource="dataSource"
@@ -123,17 +122,12 @@ import { JeecgListMixin } from '@/mixins/JeecgListMixin'
 //   import PermissionDataRuleList from './PermissionDataRuleList'
 import JEllipsis from '@/components/jeecg/JEllipsis'
 const columns = [
-  {
-    title: '标签分类',
-    dataIndex: 'tagCategoryId_dictText',
-    key: 'tagCategoryId_dictText',
-    align: 'center',
-  },
+  
   {
     title: '标签名称',
     dataIndex: 'tagName',
     key: 'tagName',
-    align: 'center',
+    align: 'left',
     scopedSlots: {
       customRender: 'tagName',
     },
@@ -167,33 +161,39 @@ const columns = [
         return '三级标签'
       }
     },
-    align: 'center',
-  },
-  {
-    title: '所属一级标签',
-    dataIndex: 'firstTagId_dictText',
-    key: 'firstTagId_dictText',
-    customRender: function (text) {
-      if (text == null) {
-        return '-'
-      } else {
-        return text
-      }
-    },
-    align: 'center',
+    align: 'left',
   },
+  // {
+  //   title: '所属一级标签',
+  //   dataIndex: 'firstTagId_dictText',
+  //   key: 'firstTagId_dictText',
+  //   customRender: function (text) {
+  //     if (text == null) {
+  //       return '-'
+  //     } else {
+  //       return text
+  //     }
+  //   },
+  //   align: 'center',
+  // },
+  // {
+  //   title: '所属二级标签',
+  //   dataIndex: 'secendTagId_dictText',
+  //   key: 'secendTagId_dictText',
+  //   customRender: function (text) {
+  //     if (text == null) {
+  //       return '-'
+  //     } else {
+  //       return text
+  //     }
+  //   },
+  //   align: 'center',
+  // },
   {
-    title: '所属二级标签',
-    dataIndex: 'secendTagId_dictText',
-    key: 'secendTagId_dictText',
-    customRender: function (text) {
-      if (text == null) {
-        return '-'
-      } else {
-        return text
-      }
-    },
-    align: 'center',
+    title: '标签分类',
+    dataIndex: 'tagCategoryName',
+    key: 'tagCategoryName',
+    align: 'left',
   },
   {
     title: '描述',
@@ -206,7 +206,7 @@ const columns = [
         return text
       }
     },
-    align: 'center',
+    align: 'left',
     width: 400,
   },
   // {
@@ -232,7 +232,7 @@ const columns = [
     scopedSlots: {
       customRender: 'action',
     },
-    align: 'center',
+    align: 'left',
     width: 250,
   },
 ]
@@ -252,7 +252,7 @@ export default {
       // 展开的行,受控属性
       expandedRowKeys: [],
       url: {
-        list: '/ctop/tagInfo/list',
+        list: '/ctop/tagInfo/treeList',
         delete: '/ctop/tagInfo/edit',
         deleteBatch: '/sys/permission/deleteBatch',
       },

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

@@ -1005,6 +1005,7 @@ a {
           v-if="add&&visible"
         >
           <el-cascader
+
             placeholder="搜索你想要的内容标签"
             :options="departTreeContent"
             class="only-video-material-disable-modal"
@@ -1012,7 +1013,7 @@ a {
               'contentTagList', // 给表单赋值或拉取表单时,该input对应的key
               { rules: [{ required: true, message: '请选择内容标签!' }] }
             ]"
-            :props="{ multiple: true,value:'id',label:'tagName',emitPath:false,checkStrictly: true}"
+            :props="{ multiple: true,value:'id',label:'tagName',emitPath:false,checkStrictly: true, expandTrigger: 'hover'}"
             filterable
             style="width:100%"
           ></el-cascader>
@@ -1962,10 +1963,8 @@ export default {
         categoryId: type,
       }).then((res) => {
         if (res.success) {
-          if (arr == 'departTreeContent') {
+          if (res.result) {
             this[arr] = this.getTreeData(res.result)
-          } else {
-            this[arr].push(...res.result)
           }
         }
       })

+ 3 - 2
vue.config.js

@@ -58,7 +58,7 @@ module.exports = {
     open : true,
     proxy: {
       '/jeecg-boot': {
-        //  target: 'http://192.168.1.8:8080', //请求本地 需要jeecg-boot后台项目  蒙蒙
+        //  target: 'http://192.168.1.90:8080', //请求本地 需要jeecg-boot后台项目  蒙蒙
         // target: 'http://192.168.0.59:8088', //请求本地 需要jeecg-boot后台项目  英豪
         target: 'http://192.168.1.72:8088', //请求本地 需要jeecg-boot后台项目  英豪
         // target: 'http://192.168.2.115:8080', //请求本地 需要jeecg-boot后台项目  祚云
@@ -66,7 +66,7 @@ module.exports = {
         // target: 'http://192.168.0.230:8088', //请求本地 需要jeecg-boot后台项目  孙震
         // target: 'http://192.168.1.51:8080', //请求本地 需要jeecg-boot后台项目  毕洁泉
 
-        // target: 'http://192.168.1.51:8098', //请求本地 需要jeecg-boot后台项目  毕洁泉
+        target: 'http://192.168.1.74:8098', //请求本地 需要jeecg-boot后台项目  毕洁泉
         // target: 'http://192.168.0.252:8098', //请求本地 需要jeecg-boot后台项目  毕洁泉
         // target: 'http://192.168.0.170:8088', //请求本地 需要jeecg-boot后台项目  毕洁泉
         //  target: 'http://api.tjyourong.com.cn', //请求本地 需要jeecg-boot后台项目
@@ -78,6 +78,7 @@ module.exports = {
 
 
         ws: false,
+
         changeOrigin: true,
         // pathRewrite: {
         //     '/jeecg-boot': ''  //默认所有请求都加了jeecg-boot前缀,需要去掉