浏览代码

计划创建部分

Szx 3 年之前
父节点
当前提交
418202267b

二进制
dist.rar


+ 56 - 2
src/api/index.ts

@@ -30,6 +30,7 @@ import {
   IPBookItem,
   
 } from "#/api";
+import { any } from "vue-types";
 
 /**
  * 登录
@@ -1074,6 +1075,28 @@ export const getPackage = (
 ): any => {
   return axios("/ad/package/get", { params: query });
 };
+/**
+ * 新建定向包
+ * @param
+ */
+ export const createPackage = (
+  data:any
+): any => {
+  return axios.post("/ad/package/create", data);
+};
+
+// 获取优化目标
+export const getBestTargetApi = (
+  query: {
+    advertiser_id: string | number,
+    landing_type: string | number,
+    marketing_purpose: string | number,
+  }
+): any => {
+  return axios("/tools/adConvert/optimizedTarget", { params: query });
+};
+
+
 
 /* 创建计划
 * @param null
@@ -1099,11 +1122,41 @@ export const getPlanList = (
     advertiser_name?: string | number,
     campaign_name?: string | number,
     status?: string | number,
-    page: string | number,
+    page?: string | number,
   }
 ): any => {
   return axios("/ad/create/logs", { params: query });
 };
+/**
+ * 删除摸版
+ * @param
+ */
+
+export const delModelItem=(query:{
+id:string
+}):any=>{
+  return axios("/ad/create/deleteTemplates",{params:query})
+}
+
+
+/**
+ * 删除管理计划
+ * @param
+ */
+export const delPlanList =(query:{log_id:string}):any=>{
+  return axios("/ad/create/log/delete",{params:query})
+}
+
+
+/**
+ * 编辑管理计划
+ * @param
+ */
+export const editPlanLst =(query:any)=>{
+  return axios("/ad/create/log/edit")
+}
+
+
 
 /**
  * 获取计划模板
@@ -1111,7 +1164,8 @@ export const getPlanList = (
  */
 export const getPlanTemplate = (
   query: {
-    page: string | number,
+    page?: string | number,
+    name?:string
   }
 ): any => {
   return axios("/ad/create/templates", { params: query });

+ 0 - 1
src/components/Tinymce/src/Editor.vue

@@ -168,7 +168,6 @@ export default defineComponent({
           immediate: true,
         }
       );
-
       editor.on(
         normalizedEvents ? normalizedEvents : "change keyup undo redo",
         () => {

+ 39 - 1
src/router/async.ts

@@ -243,6 +243,44 @@ export const PlanCreate: RouteConfig = {
   component: () => import("@/views/put/plan-create-index.vue")
 };
 
+const EditPlan1: RouteConfig = {
+  name: "EditPlan1",
+  path: "/put/edit-plan/plan-edit",
+  meta: {
+    title: "编辑计划",
+    activeMenu: "/put/plan-management",
+  },
+  component: () => import("@/views/put/plan-edit/planedit.vue")
+};
+const CreativityAdd1: RouteConfig = {
+  name: "CreativityAdd1",
+  path: "/put/edit-plan/add-creative",
+  meta: {
+    title: "编辑计划",
+    activeMenu: "/put/plan-management",
+  },
+  component: () => import("@/views/put/plan-edit/creativeAdd.vue")
+};
+
+
+export const PlanEdit: RouteConfig = {
+  name: "PlanEdit",
+  path: "/put/edit-plan",
+  meta: {
+    title: "编辑计划",
+    activeMenu: "/put/plan-management",
+    noMenu: true
+  },
+  hidden: true,
+  children: [EditPlan1,CreativityAdd1],
+  component: () => import("@/views/put/plan-edit-index.vue")
+};
+
+
+
+
+
+
 export const PutManager: RouteConfig = {
   name: "PutManager",
   path: "/put",
@@ -357,7 +395,7 @@ export const ForgetPwd: RouteConfig = {
 
 
 const asyncRoutes: RouteConfig[] = [BackManager, DataAnalysis, PutManager,
-  PlanCreate, Financial, PerformanceDetial, ForgetPwd, MaterialCenter];
+  PlanCreate, Financial, PerformanceDetial, ForgetPwd, MaterialCenter,PlanEdit];
 // const asyncRoutes: RouteConfig[] = [AccountManager, DataAnalysis, PutManager,
 //   Financial, QuickApp, PerformanceDetial, ForgetPwd, MaterialCenter];
 

+ 9 - 9
src/views/_pageOptions/table-put.ts

@@ -1136,38 +1136,38 @@ export const landingCloumn: Array<colunm> = [
 export const PlanCloumn: Array<colunm> = [
   {
     title: "计划名称",
-    dataIndex: "id",
+    dataIndex: "ad_name",
     width: 200,
   },
 
   {
     title: "所属账户",
-    dataIndex: "title",
+    dataIndex: "advertiser_name",
     width: 200,
   },
   {
     title: "所属广告组",
-    dataIndex: "name",
+    dataIndex: "campaign_name",
     width: 200,
     ellipsis: true,
   },
   {
     title: "状态",
-    dataIndex: "gzh_name",
+    dataIndex: "status",
     width: 100,
     slots: {
-      customRender: "gzh",
+      customRender: "status",
     },
   },
   {
     title: "状态原因",
-    dataIndex: "name",
+    dataIndex: "request_result.message",
     width: 200,
     ellipsis: true,
   },
   {
     title: "创建时间",
-    dataIndex: "name",
+    dataIndex: "created_at",
     width: 200,
   },
   {
@@ -1189,7 +1189,7 @@ export const PlanTemplateCloumn: Array<colunm> = [
   },
   {
     title: "创建时间",
-    dataIndex: "name",
+    dataIndex: "created_at",
     width: 200,
   },
   {
@@ -1197,7 +1197,7 @@ export const PlanTemplateCloumn: Array<colunm> = [
     dataIndex: "",
     width: 160,
     slots: {
-      customRender: "setting",
+      customRender: "action",
     },
   },
 ]

+ 1 - 2
src/views/account/orange.vue

@@ -41,8 +41,7 @@
       >
         <a-form-item label=" 公众号名称" :name="[ 'appName']">
           <a-input
-            v-model:value="wxEditList.appName"
-            
+            v-model:value="wxEditList.appName" 
           >
           </a-input>
         </a-form-item>

+ 2 - 4
src/views/put/component/location-auto-release.vue

@@ -260,11 +260,9 @@
           >
         </div>
         <div class="selectedItem">
-          <p v-for="county in checkedCounties" :key="county.value">
-            {{ county.label
-            }}<i
+          <p v-for="item in checkedCounties" :key="index">{{ item.label}}<i
               class="deleteCity el-icon-close"
-              @click="deleteCounty(county)"
+              @click="deleteCounty(item)"
               style="margin-top: 3px"
             ></i>
           </p>

+ 3 - 0
src/views/put/plan-create/account-select.vue

@@ -118,6 +118,7 @@ const AccountSelect = defineComponent({
   methods: {
     // 跳转前校验页面
     check() {
+      //选择当前投放的账号
       if (!this.selectedAccount.advertiser_id) {
         this.warningFlag = true;
         message.warning("请选择要投放的广告主账号");
@@ -131,6 +132,7 @@ const AccountSelect = defineComponent({
       }
     },
     onSearch() {
+      //搜索广告主账号
       this.adAccountList = this.adAccountListOrigin.filter((item: any) => {
         return item.advertiser_name.indexOf(this.adAccountSearch) > -1;
       });
@@ -142,6 +144,7 @@ const AccountSelect = defineComponent({
     },
     // 选择头条账户获取广告主账户
     getAdAccountList(item: any) {
+      console.log(item)
       this.adAccountList = item.target.value.advertises;
       this.adAccountListOrigin = JSON.parse(
         JSON.stringify(item.target.value.advertises)

+ 2 - 1
src/views/put/plan-create/creativity-add.vue

@@ -188,7 +188,7 @@ const CreativityAdd = defineComponent({
     this.getClassify();
     Bus.$on("stepFourCheck", (val?: any) => {
       console.log("Step4Check");
-      // Bus.$emit("stepFourBack");
+      Bus.$emit("stepFourBack");
       this.beforeCommit();
     });
   },
@@ -205,6 +205,7 @@ const CreativityAdd = defineComponent({
         // 自定义创意
         data.creative_list = this.materialCom.backData();
       }
+      data.task_id=1
       // 二、数据处理
       // 1.创意方式,当值为"STATIC_ASSEMBLE"表示程序化创意,其他情况不传字段
       // if (data.creative_material_mode === "CUSTOM")

+ 51 - 34
src/views/put/plan-create/group-select.vue

@@ -8,31 +8,25 @@
       ref="formCheck"
     >
       <a-form-item label="创建方式">
-        <a-radio-group v-model:value="form.build_mode">
+        <a-radio-group v-model:value="form.build_mode" @change="getAdviseList">
           <a-radio value="1">新建广告组</a-radio>
           <a-radio value="2">已有广告组</a-radio>
         </a-radio-group>
       </a-form-item>
       <div v-if="form.build_mode === '1'">
         <a-form-item label="营销链路" name="marketing_purpose">
-          <a-radio-group
-            v-model:value="form.marketing_purpose"
-            @change="makeGroupName"
-          >
+          <a-radio-group v-model:value="form.marketing_purpose" @change="makeGroupName">
             <a-radio-button value="CONVERSION">行动转化</a-radio-button>
-            <a-radio-button value="INTENTION">用户意向</a-radio-button>
-            <a-radio-button value="ACKNOWLEDGE">品牌认知</a-radio-button>
+            <!-- <a-radio-button value="INTENTION">用户意向</a-radio-button>
+            <a-radio-button value="ACKNOWLEDGE">品牌认知</a-radio-button> -->
           </a-radio-group>
         </a-form-item>
         <a-form-item name="landing_type" style="margin-left: 100px">
-          <a-radio-group
-            v-model:value="form.landing_type"
-            @change="makeGroupName"
-          >
+          <a-radio-group v-model:value="form.landing_type" @change="makeGroupName">
             <a-radio-button value="LINK">销售线索收集</a-radio-button>
-            <a-radio-button value="APP">应用推广</a-radio-button>
-          </a-radio-group></a-form-item
-        >
+            <!-- <a-radio-button value="APP">应用推广</a-radio-button> -->
+          </a-radio-group>
+        </a-form-item>
         <a-form-item label="广告类型" name="campaign_type">
           <a-select v-model:value="form.campaign_type" placeholder="请选择">
             <a-select-option value="FEED">所有广告</a-select-option>
@@ -45,11 +39,7 @@
             <a-radio value="BUDGET_MODE_DAY">指定预算</a-radio>
           </a-radio-group>
         </a-form-item>
-        <a-form-item
-          label="日预算"
-          name="budget"
-          v-if="form.budget_mode === 'BUDGET_MODE_DAY'"
-        >
+        <a-form-item label="日预算" name="budget" v-if="form.budget_mode === 'BUDGET_MODE_DAY'">
           <a-input addon-after="元" type="number" v-model:value="form.budget" />
         </a-form-item>
         <a-form-item label="广告组名称" name="campaign_name">
@@ -57,7 +47,9 @@
         </a-form-item>
       </div>
       <div v-else class="ad-group-box">
-        <div class="title-box"><h3>选择广告组</h3></div>
+        <div class="title-box">
+          <h3>选择广告组</h3>
+        </div>
         <div class="main-box">
           <div class="search-box">
             <a-input-search
@@ -67,25 +59,27 @@
               @search="onSearch"
             />
           </div>
-          <div class="table-title"><h3>广告组名称</h3></div>
+          <div class="table-title">
+            <h3>广告组名称</h3>
+          </div>
           <div class="list-box">
             <a-radio-group v-model:value="form.campaign_id">
               <!-- <a-radio :style="radioStyle" :value="1"
                 >广告组1 <span class="desc">测试广告组</span></a-radio
-              > -->
+              >-->
               <a-radio
                 :style="radioStyle"
                 v-for="item in groupList"
                 :key="item.campaign_id"
                 :value="item.campaign_id"
-                >{{ item.campaign_name }}
-                <span class="desc" v-show="item.landing_type === 'LINK'"
-                  >销售线索搜集</span
-                >
-                <span class="desc" v-show="item.landing_type === 'APP'"
-                  >应用推广</span
-                ></a-radio
               >
+                {{ item.campaign_name }}
+                <span
+                  class="desc"
+                  v-show="item.landing_type === 'LINK'"
+                >销售线索搜集</span>
+                <span class="desc" v-show="item.landing_type === 'APP'">应用推广</span>
+              </a-radio>
             </a-radio-group>
             <a-empty v-show="groupList.length === 0"></a-empty>
           </div>
@@ -116,7 +110,7 @@ const GroupSelect = defineComponent({
         marketing_purpose: "", // 营销目的
         campaign_type: undefined, // 广告类型
         budget_mode: "BUDGET_MODE_INFINITE", // 广告组预算
-        budget: "", // 日预算
+        budget: 0, // 日预算
         campaign_name: "", // 广告组名称
         campaign_id: 0, // 选择的已有广告组
       },
@@ -242,11 +236,13 @@ const GroupSelect = defineComponent({
     });
   },
   methods: {
-    // 搜索广告组名称
-    onSearch() {
-      console.log("搜索广告组", this.groupNameSearch);
-      this.getGroups();
+
+    //更新广告组列表
+    getAdviseList() {
+      this.getGroups()
     },
+    // 搜索广告组名称
+
     // step2创建广告组页面校验
     check() {
       if (window.localStorage.getItem("plan-create-campaign")) {
@@ -270,6 +266,7 @@ const GroupSelect = defineComponent({
             // 请求创建广告主接口
             let param: any = {
               ...this.form,
+              budget:Number(this.form.budget),
               advertiser_id: Number(this.$route.query.advertiser_id),
             };
             delete param.build_mode;
@@ -324,6 +321,9 @@ const GroupSelect = defineComponent({
     },
     // 生成广告组名称
     makeGroupName() {
+      console.log(this.form.landing_type)
+      console.log(1)
+      localStorage.setItem('langding_type',this.form.landing_type)
       if (!this.form.landing_type || !this.form.marketing_purpose) return;
       let langdingTypeName = "",
         marketingPurposeName = "";
@@ -342,6 +342,23 @@ const GroupSelect = defineComponent({
       let time = this.getNowFormatDate();
       this.form.campaign_name = `${marketingPurposeName}_${langdingTypeName}_${time}`;
     },
+    //搜索广告组名字
+    onSearch() {
+      console.log(this.groupNameSearch)
+      console.log(this.groupList)
+      this.groupList = this.groupList.filter((item: any) => {
+        let arr = []
+        if (this.groupNameSearch == '') {
+          this.getGroups()
+        }
+        if (item.campaign_name.indexOf(this.groupNameSearch) > -1) {
+          arr.push(item)
+          return arr
+        } 
+      }
+
+      )
+    },
     // 工具函数 获取当前时间
     getNowFormatDate() {
       var date = new Date();

+ 186 - 149
src/views/put/plan-create/plan-edit.vue

@@ -5,25 +5,25 @@
       <h1>优化目标</h1>
       <a-form :label-col="labelCol" :wrapper-col="wrapperCol">
         <a-form-item label="转化跟踪方式">
-          <a-select placeholder="请选择">
+          <a-select placeholder="请选择" @change="valueChange(value)">
             <a-select-option value="XIANSUOTONG">线索通</a-select-option>
             <a-select-option value="XIANSUOTONG_API">线索API</a-select-option>
           </a-select>
         </a-form-item>
         <a-form-item label="优化目标">
           <a-select placeholder="请选择">
-            <a-select-option
-              v-for="(item, index) in []"
-              :key="index"
-            ></a-select-option>
+            <a-select-option v-for="(item, index) in []" :key="index"></a-select-option>
+          </a-select>
+        </a-form-item>
+        <a-form-item label="深度优化目标">
+          <a-select placeholder="选填">
+            <a-select-option v-for="(item, index) in []" :key="index"></a-select-option>
           </a-select>
         </a-form-item>
+
         <a-form-item label="落地页">
           <a-select placeholder="请选择" v-model:value="plan.external_url">
-            <a-select-option
-              v-for="(item, index) in []"
-              :key="index"
-            ></a-select-option>
+            <a-select-option v-for="(item, index) in []" :key="index"></a-select-option>
           </a-select>
         </a-form-item>
         <a-form-item label="直达链接内容">
@@ -31,7 +31,6 @@
         </a-form-item>
       </a-form>
     </div>
-
     <!-- part2------设置投放位置 -->
     <div class="part-box">
       <h1>设置投放位置</h1>
@@ -43,10 +42,7 @@
             <a-radio value="SCENE">首选场景</a-radio>
           </a-radio-group>
         </a-form-item>
-        <a-form-item
-          label="投放媒体"
-          v-show="plan.inventory_catalog === 'MANUAL'"
-        >
+        <a-form-item label="投放媒体" v-show="plan.inventory_catalog === 'MANUAL'">
           <a-select
             mode="multiple"
             size="default"
@@ -57,15 +53,10 @@
             <a-select-option
               v-for="item in optionsList.mediaList"
               :key="item.value"
-            >
-              {{ item.label }}
-            </a-select-option>
+            >{{ item.label }}</a-select-option>
           </a-select>
         </a-form-item>
-        <a-form-item
-          label="投放场景"
-          v-show="plan.inventory_catalog === 'SCENE'"
-        >
+        <a-form-item label="投放场景" v-show="plan.inventory_catalog === 'SCENE'">
           <a-select
             size="default"
             placeholder="请选择"
@@ -75,9 +66,7 @@
             <a-select-option
               v-for="item in optionsList.sceneList"
               :key="item.value"
-            >
-              {{ item.label }}
-            </a-select-option>
+            >{{ item.label }}</a-select-option>
           </a-select>
         </a-form-item>
         <a-form-item label="搜索快投关键词">
@@ -85,35 +74,25 @@
         </a-form-item>
       </a-form>
     </div>
-
+    <button @click="show">展示数据</button>
     <!-- part3------用户定向 -->
     <div class="part-box">
       <h1>用户定向</h1>
-      <a-form
-        :label-col="labelCol"
-        :wrapper-col="wrapperCol"
-        style="margin-bottom: 20px"
-      >
+      <a-form :label-col="labelCol" :wrapper-col="wrapperCol" style="margin-bottom: 20px">
         <a-form-item label="定向方式">
-          <a-radio-group
-            v-model:value="userTarget.directType"
-            @change="getPackageList"
-          >
+          <a-radio-group v-model:value="userTarget.directType" @change="getPackageList">
             <a-radio value="BUILD">新建定向</a-radio>
             <a-radio value="SELECT">选择已有定向包</a-radio>
           </a-radio-group>
         </a-form-item>
-        <a-form-item
-          label="选择已有定向包"
-          v-if="userTarget.directType === 'SELECT'"
-        >
+        <a-form-item label="选择已有定向包" v-if="userTarget.directType === 'SELECT'">
           <a-select placeholder="请选择">
             <a-select-option
               v-for="(item, index) in directList"
-              :key="index"
+              :key="item.audience_package_id"
               :value="item.audience_package_id"
-              >{{ item.name }}</a-select-option
-            >
+              v-model:value="plan.audience_package_id"
+            >{{ item.name }}</a-select-option>
           </a-select>
         </a-form-item>
       </a-form>
@@ -203,10 +182,7 @@
           </a-checkbox-group>
         </a-form-item>
         <a-form-item label="网络">
-          <a-checkbox-group
-            v-model:value="plan.ac"
-            @change="checkboxChange($event, 'ac')"
-          >
+          <a-checkbox-group v-model:value="plan.ac" @change="checkboxChange($event, 'ac')">
             <a-checkbox value="unknown">不限</a-checkbox>
             <a-checkbox value="WIFI">Wi-Fi</a-checkbox>
             <a-checkbox value="2G">2G</a-checkbox>
@@ -230,10 +206,7 @@
             <a-radio-button value="CUSTOMER">公司账户</a-radio-button>
           </a-radio-group>
         </a-form-item>
-        <a-form-item
-          label="过滤时间"
-          v-if="plan.hide_if_converted === 'CUSTOMER'"
-        >
+        <a-form-item label="过滤时间" v-if="plan.hide_if_converted === 'CUSTOMER'">
           <!-- 当过滤已转化用户类型选择"公司账户"/“APP”时可填写 -->
           <a-radio-group v-model:value="plan.converted_time_duration">
             <a-radio-button value="CUSTOMER">当天</a-radio-button>
@@ -277,9 +250,7 @@
           >
             <a-checkbox value="NONE">不限</a-checkbox>
             <a-checkbox value="WITH_IN_A_MONTH">一个月以内</a-checkbox>
-            <a-checkbox value="ONE_MONTH_2_THREE_MONTH"
-              >一个月到三个月</a-checkbox
-            >
+            <a-checkbox value="ONE_MONTH_2_THREE_MONTH">一个月到三个月</a-checkbox>
             <a-checkbox value="THREE_MONTH_EAILIER">三个月以上</a-checkbox>
           </a-checkbox-group>
         </a-form-item>
@@ -315,8 +286,7 @@
             <span
               style="position: relative; top: -54px; left: 450px"
               v-if="plan.launch_price[0] > 0 && plan.launch_price[1] < 11000"
-              >{{ plan.launch_price[0] }}元~{{ plan.launch_price[1] }}元</span
-            >
+            >{{ plan.launch_price[0] }}元~{{ plan.launch_price[1] }}元</span>
             <span
               style="position: relative; top: -54px; left: 450px"
               v-if="
@@ -324,8 +294,7 @@
                   plan.launch_price[1] === 11000) ||
                 plan.launch_price[0] == plan.launch_price[1]
               "
-              >不限</span
-            >
+            >不限</span>
             <span
               style="position: relative; top: -54px; left: 450px"
               v-if="
@@ -333,8 +302,7 @@
                 plan.launch_price[1] < 11000 &&
                 plan.launch_price[1] !== 0
               "
-              >{{ plan.launch_price[1] }}元以内</span
-            >
+            >{{ plan.launch_price[1] }}元以内</span>
             <span
               style="position: relative; top: -54px; left: 450px"
               v-if="
@@ -342,8 +310,7 @@
                 plan.launch_price[1] === 11000 &&
                 plan.launch_price[0] !== 11000
               "
-              >{{ plan.launch_price[0] }}元以上</span
-            >
+            >{{ plan.launch_price[0] }}元以上</span>
           </div>
         </a-form-item>
         <!-- 职业状态 -->
@@ -367,15 +334,25 @@
             checked-children="开"
             un-checked-children="关"
           />
-          <check-box
-            ref="extendCom"
-            :compType="4"
-            :showList="[]"
-            v-if="plan.auto_extend_enabled"
-          ></check-box>
+          <check-box ref="extendCom" :compType="4" :showList="[]" v-if="plan.auto_extend_enabled"></check-box>
         </a-form-item>
         <p style="line-height: 40px; width: 700px; text-align: right">
-          <a-button @click="saveDirectPackage">保存为定向包</a-button>
+          <a-modal
+            @ok="saveDirectPackage"
+            v-model:visible="packDescript.isShow"
+            centered="true"
+            width="40%"
+          >
+            <a-form :rules="packageRules" :model="packDescript">
+              <a-form-item label="定向包名">
+                <a-input v-model:value="packDescript.name" style="width: 140px" />
+              </a-form-item>
+              <a-form-item label="定向包描述">
+                <a-input v-model:value="packDescript.descript" style="width: 140px" />
+              </a-form-item>.
+            </a-form>
+          </a-modal>
+          <a-button @click="handleShowPack">保存为定向包</a-button>
         </p>
       </a-form>
     </div>
@@ -385,66 +362,37 @@
       <h1>预算与出价</h1>
       <a-form :label-col="labelCol" :wrapper-col="wrapperCol">
         <a-form-item label="投放场景">
-          <a-radio-group
-            v-model:value="plan.smart_bid_type"
-            @change="itemChange('smart_bid_type')"
-          >
+          <a-radio-group v-model:value="plan.smart_bid_type" @change="itemChange('smart_bid_type')">
             <a-radio value="SMART_BID_CUSTOM">常规投放</a-radio>
             <a-radio value="SMART_BID_CONSERVATIVE">放量投放</a-radio>
           </a-radio-group>
           <span
             style="font-size: 13px; color: gray"
             v-show="plan.smart_bid_type === 'SMART_BID_CUSTOM'"
-            >控制成本,尽量消耗完预算</span
-          >
+          >控制成本,尽量消耗完预算</span>
           <span
             style="font-size: 13px; color: gray"
             v-show="plan.smart_bid_type === 'SMART_BID_CONSERVATIVE'"
-            >接受成本上浮,尽量消耗更多预算</span
-          >
+          >接受成本上浮,尽量消耗更多预算</span>
           <a-checkbox
             v-if="plan.smart_bid_type === 'SMART_BID_CONSERVATIVE'"
             v-model:checked="plan.adjust_cpa"
-            >通过学习期后,尝试优化转化成本</a-checkbox
-          >
+          >通过学习期后,尝试优化转化成本</a-checkbox>
         </a-form-item>
-        <a-form-item
-          label="日预算"
-          v-if="plan.smart_bid_type === 'SMART_BID_CONSERVATIVE'"
-        >
-          <a-input
-            addon-after="元"
-            v-model:value="plan.budget"
-            style="width: 140px"
-            type="number"
-          />
+        <a-form-item label="日预算" v-if="plan.smart_bid_type === 'SMART_BID_CONSERVATIVE'">
+          <a-input addon-after="元" v-model:value="plan.budget" style="width: 140px" type="number" />
         </a-form-item>
-        <a-form-item
-          label="预算"
-          v-if="plan.smart_bid_type === 'SMART_BID_CUSTOM'"
-        >
-          <a-input
-            addon-after="元"
-            v-model:value="plan.budget"
-            style="width: 220px"
-            type="number"
-          >
+        <a-form-item label="预算" v-if="plan.smart_bid_type === 'SMART_BID_CUSTOM'">
+          <a-input addon-after="元" v-model:value="plan.budget" style="width: 220px" type="number">
             <template #addonBefore>
               <a-select v-model:value="plan.budget_mode" style="width: 90px">
-                <a-select-option value="BUDGET_MODE_DAY"
-                  >日预算</a-select-option
-                >
-                <a-select-option value="BUDGET_MODE_TOTAL"
-                  >总预算</a-select-option
-                >
+                <a-select-option value="BUDGET_MODE_DAY">日预算</a-select-option>
+                <a-select-option value="BUDGET_MODE_TOTAL">总预算</a-select-option>
               </a-select>
-            </template></a-input
-          >
+            </template>
+          </a-input>
         </a-form-item>
-        <a-form-item
-          label="竞价策略"
-          v-if="plan.smart_bid_type === 'SMART_BID_CUSTOM'"
-        >
+        <a-form-item label="竞价策略" v-if="plan.smart_bid_type === 'SMART_BID_CUSTOM'">
           <a-radio-group v-model:value="plan.flow_control_mode">
             <a-radio value="FLOW_CONTROL_MODE_FAST">优先跑量</a-radio>
             <a-radio value="FLOW_CONTROL_MODE_SMOOTH">均衡投放</a-radio>
@@ -468,25 +416,25 @@
             <a-radio value="NONE">不限</a-radio>
             <a-radio value="CUSTOM">指定时间段</a-radio>
           </a-radio-group>
-          <time-schedule
-            ref="timeCom"
-            style="width: 800px; margin-top: 10px"
-            v-if="userTarget.timeDuration === 'CUSTOM'"
-          ></time-schedule>
+
+          <div v-if="userTarget.timeDuration === 'CUSTOM'">
+            <div>
+              <time-schedule
+                ref="timeCom"
+                style="width: 800px; margin-top: 10px"
+                v-if="userTarget.timeDuration === 'CUSTOM'"
+              ></time-schedule>
+            </div>
+          </div>
         </a-form-item>
         <!-- 投放时段 -->
         <a-form-item label="付费方式">
           <a-radio-group v-model:value="plan.pricing">
-            <a-radio value="PRICING_CPM">按展示付费(oCPM)</a-radio>
+            <a-radio value="PRICING_OCPM">按展示付费(oCPM)</a-radio>
           </a-radio-group>
         </a-form-item>
         <a-form-item label="目标转化出价">
-          <a-input
-            style="width: 100px"
-            type="number"
-            suffix="元"
-            v-model:value="plan.cpa_bid"
-          />
+          <a-input style="width: 100px" type="number" suffix="元" v-model:value="plan.cpa_bid" />
           <span style="font-size: 13px; color: gray">出价不能大于预算</span>
         </a-form-item>
       </a-form>
@@ -494,34 +442,22 @@
 
     <!-- part5------第三方检测链 -->
     <div class="part-box">
-      <h1>第三方检测链</h1>
+      <h1>第三方检测链</h1>
       <a-form :label-col="labelCol" :wrapper-col="wrapperCol">
         <a-form-item label="展示">
           <a-input placeholder="选填" v-model:value="plan.track_url[0]" />
         </a-form-item>
         <a-form-item label="有效触点">
-          <a-input
-            placeholder="选填"
-            v-model:value="plan.action_track_url[0]"
-          />
+          <a-input placeholder="选填" v-model:value="plan.action_track_url[0]" />
         </a-form-item>
         <a-form-item label="视频播放">
-          <a-input
-            placeholder="选填"
-            v-model:value="plan.video_play_track_url[0]"
-          />
+          <a-input placeholder="选填" v-model:value="plan.video_play_track_url[0]" />
         </a-form-item>
         <a-form-item label="视频播完">
-          <a-input
-            placeholder="选填"
-            v-model:value="plan.video_play_done_track_url[0]"
-          />
+          <a-input placeholder="选填" v-model:value="plan.video_play_done_track_url[0]" />
         </a-form-item>
         <a-form-item label="视频有效播放">
-          <a-input
-            placeholder="选填"
-            v-model:value="plan.video_play_effective_track_url[0]"
-          />
+          <a-input placeholder="选填" v-model:value="plan.video_play_effective_track_url[0]" />
         </a-form-item>
       </a-form>
     </div>
@@ -543,7 +479,7 @@
 
 <script lang="ts">
 import { defineComponent, reactive, toRefs, ref } from "vue";
-import { createPlan, getPackage } from "@/api";
+import { createPlan, getPackage, createPackage, getBestTargetApi } from "@/api";
 import Bus from "@/utils/bus";
 import { Moment } from "moment";
 import moment from "moment";
@@ -571,6 +507,12 @@ const PlanEdit = defineComponent({
     const brandCom: any = ref(null); // 手机品牌组件
     const extendCom: any = ref(null); // 智能放量组件
     const state = reactive({
+      packDescript: {
+        name: '',
+        descript: '',
+        isShow: false
+      },
+
       // 页面变量
       userTarget: {
         // 用户定向相关页面变量
@@ -594,6 +536,7 @@ const PlanEdit = defineComponent({
         scene_inventory: "", // 投放场景-广告位置时首选场景时必填 否则删除
         feed_delivery_search: true, // 搜索快投关键词
         // part3 用户定向----------------------------------------------------
+        // audience_package_id:0,
         district: "", // 地域类型
         city: ref<any[]>([]), // 选中的城市或区县
         gender: "NONE", // 性别
@@ -608,7 +551,7 @@ const PlanEdit = defineComponent({
         device_type: ref<any[]>(["NONE"]), // 设备类型 不限不传
         ac: ref<any[]>(["unknown"]), // 网络
         hide_if_exists: 0, // 已安装用户 0-不限 1-过滤 2-定向
-        hide_if_converted: "AD", // 过滤已转化用户 默认AD广告计划
+        // hide_if_converted: "AD", // 过滤已转化用户 默认AD广告计划
         converted_time_duration: "CUSTOMER", // 过滤时间
         article_category: ref<any[]>([]), // 文章分类
         carrier: ref<any[]>(["NONE"]), // 运营商
@@ -628,8 +571,9 @@ const PlanEdit = defineComponent({
         start_time: "", // 投放开始时间
         end_time: "", // 投放结束时间
         schedule_time: "", // 投放时段
-        pricing: "PRICING_CPM", // 付费方式
-        cpa_bid: "", // 目标转化出价
+        pricing: "PRICING_OCPM", // 付费方式
+        cpa_bid: 0, // 目标转化出价
+        // convert_id:1,//可用转换目标
         // part5 第三方检测---------------------------------------
         track_url: ref<any[]>([]), // 展示
         action_track_url: ref<any[]>([]), // 有效触点
@@ -649,6 +593,14 @@ const PlanEdit = defineComponent({
       advertiser_id: 0,
       directList: ref<any[]>([]),
     });
+    const packageRules = {
+      name: [
+        { required: true, message: 'Please input Activity name', trigger: 'blur' },
+      ],
+      descript: [{
+        required: true, message: "1111"
+      }]
+    }
     return {
       ...toRefs(state),
       labelCol: { span: 3 },
@@ -661,23 +613,43 @@ const PlanEdit = defineComponent({
       workCom,
       brandCom,
       extendCom,
+      packageRules
     };
   },
   mounted() {
+
+    //获取优化目标
+    this.getBestTarget()
+
+    //从路由中获取广告id
     this.advertiser_id = Number(this.$route.query.advertiser_id);
     let time = this.getNowFormatDate();
+    this.getPackageList()
     this.plan.name = `${this.plan.pricing}_${time}`;
+    //跳转
     Bus.$on("stepThreeCheck", (val?: any) => {
       console.log("Step3Check");
       Bus.$emit("stepThreeBack");
-      // this.beforeCommit();
+      this.beforeCommit();
     });
   },
   methods: {
+    //获取优化目标
+    async getBestTarget() {
+      let data = {
+        advertiser_id: Number(this.$route.query.advertiser_id),
+        landing_type: 'LINK',
+        marketing_purpose: 'CONVERSION'
+      }
+      const res = await getBestTargetApi(data)
+    },
+
     // 提交前处理数据
     beforeCommit() {
+      console.log('beforeCommit')
       let data: any = {};
       data = JSON.parse(JSON.stringify(this.plan));
+      console.log(data, 'dta')
       //  一、组件数据收集
       // 1.地域组件
       data.district = this.cityCom.backData().type;
@@ -707,7 +679,7 @@ const PlanEdit = defineComponent({
         ? this.extendCom.backData()
         : [];
       // 8.投放时段
-      data.schedule_time = this.timeCom ? this.timeCom.backData() : [];
+      data.schedule_time = this.timeCom ? this.timeCom.backData() : '';
 
       // 二、数据处理
       // 1.搜索快投关键词 feed_delivery_search--true=>HAS_OPEN, false=>DISABLED
@@ -759,8 +731,9 @@ const PlanEdit = defineComponent({
       }
       // 14.当投放时间为指定时间时 range=>start_time\end_time 否则删除
       if (data.schedule_type === "SCHEDULE_START_END") {
-        data.start_time = moment(this.range[0]).format("YYYY-MM-DD");
-        data.end_time = moment(this.range[1]).format("YYYY-MM-DD");
+        console.log(this.range)
+        data.start_time = moment(this.range[0]).format("YYYY-MM-DD") + ' 00:00';
+        data.end_time = moment(this.range[1]).format("YYYY-MM-DD") + ' 00:00';
       } else {
         delete data.start_time;
         delete data.end_time;
@@ -777,6 +750,24 @@ const PlanEdit = defineComponent({
       } else {
         delete data.superior_popularity_type;
       }
+      //链转为空数组处理
+      if (+data.track_url[0] + 0 == 0) {
+        data.track_url = [];
+      }
+
+      if (+data.action_track_url[0] + 0 == 0) {
+        data.action_track_url = [];
+      }
+      if (+data.video_play_track_url[0] + 0 == 0) {
+        data.video_play_track_url = [];
+      }
+      if (+data.video_play_done_track_url[0] + 0 == 0) {
+        data.video_play_done_track_url = [];
+      }
+      if (+data.video_play_effective_track_url[0] + 0 == 0) {
+        data.video_play_effective_track_url = [];
+      }
+      data.cpa_bid = +data.cpa_bid
       // 调用接口
       console.log("data", data);
       // return;
@@ -794,13 +785,22 @@ const PlanEdit = defineComponent({
         name: this.plan.name,
         ad_data: { ...plan_data },
       };
+      console.log(12312312)
       console.log("新建计划数据", param);
       try {
         let { data } = await createPlan(param);
-        console.log("请求成功");
+        console.log(data.code, 'step3code')
         Bus.$emit("stepThreeBack");
       } catch (err) {
-        console.log("请求失败", err.msg);
+        // console.log("请求失败", err.msg);
+      }
+
+    },
+    //转换跟踪方式变换
+
+    valueChange(value: string) {
+      if (value) {
+
       }
     },
     // 回显之前处理数据
@@ -953,6 +953,10 @@ const PlanEdit = defineComponent({
         });
       }
     },
+    show() {
+      console.log(this.plan)
+      this.beforeCommit();
+    },
     // 选项改变时联动
     itemChange(type: any) {
       // 投放场景为放量投放 预算类型固定为日预算 清空预算
@@ -964,8 +968,41 @@ const PlanEdit = defineComponent({
         this.plan.budget = 0;
       }
     },
+    handleShowPack() {
+      this.packDescript.isShow = true
+    },
     // 用户定向保存为定向包
-    saveDirectPackage() {
+    async saveDirectPackage() {
+      let packconfig = {
+        gender: this.plan.gender,
+        age: this.plan.age,
+        interest_action_mode: this.plan.interest_action_mode,
+        superior_popularity_type: this.plan.superior_popularity_type,
+        platform: this.plan.platform,
+        auto_extend_enabled: this.plan.auto_extend_enabled == false ? 0 : 1,
+        device_type: this.plan.device_brand,
+        ac: this.plan.ac,
+        hide_if_exists: this.plan.hide_if_exists,
+        // hide_if_converted: this.plan.hide_if_converted,
+        article_category: this.plan.article_category,
+        carrier: this.plan.carrier,
+        device_brand: this.plan.device_brand,
+        launch_price: this.plan.launch_price,
+      }
+      let data = {
+        advertiser_id: Number(this.$route.query.advertiser_id),
+        landing_type: "EXTERNAL",
+        description: this.packDescript.descript,
+        name: this.packDescript.name,
+        ...packconfig
+      }
+      const res = await createPackage(data)
+
+      if (res.code == 0) {
+        message.success('定向包创建成功')
+      }
+      this.packDescript.isShow = false
+      console.log(res)
       console.log("保存定向包");
     },
     // 工具函数 0=>false 1=>true false=>0 true=>1

+ 66 - 0
src/views/put/plan-edit-index.vue

@@ -0,0 +1,66 @@
+<template>
+    <div class="edit-plan">
+        <div class="title-box-common title-box">
+            <a-breadcrumb>
+                <a-breadcrumb-item>
+                    <a href="javascript:;" @click="goBack">计划管理</a>
+                </a-breadcrumb-item>
+                <a-breadcrumb-item>编辑</a-breadcrumb-item>
+            </a-breadcrumb>
+            <h3>计划编辑</h3>
+        </div>
+        <div class="padding-box-common">
+            <div class="main-box">
+                <div class="step-box">
+                    <router-view v-slot="{ Component }">
+                        <keep-alive>
+                            <component :is="Component" />
+                        </keep-alive>
+                    </router-view>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+<script lang="ts">
+import useApp from "@/hooks/useApp";
+import { defineComponent, reactive, toRefs } from "vue";
+export default defineComponent({
+    setup() {
+        const { route, router } = useApp();
+        const goBack = () => {
+            router.push('/put/plan-management')
+        };
+        return {
+            goBack
+        }
+    }
+})
+
+</script>
+<style lang="scss" scoped>
+@import "@/assets/common-style/frame.scss";
+.edit-plan {
+    .title-box {
+        display: block;
+        padding-top: 4px;
+        h3 {
+            margin-top: 10px;
+        }
+    }
+    .main-box {
+        background: white;
+        padding: 20px;
+    }
+    .step-box {
+        margin-bottom: 30px;
+    }
+    .steps-action {
+        margin-top: 30px;
+        border-top: 1px solid rgb(231, 230, 230);
+        .ant-btn {
+            margin: 10px 10px 0 0;
+        }
+    }
+}
+</style>

+ 323 - 0
src/views/put/plan-edit/creativeAdd.vue

@@ -0,0 +1,323 @@
+<template>
+    <div class="creativity-add">
+        <div class="part-box" style="padding-bottom: 20px">
+            <h3 class="title">添加创意</h3>
+            <a-form :label-col="labelCol" :wrapper-col="wrapperCol">
+                <a-form-item label="创意方式">
+                    <a-radio-group v-model:value="creativityAdd.creative_material_mode">
+                        <a-radio value="STATIC_ASSEMBLE">程序化创意</a-radio>
+                        <a-radio value="CUSTOM">自定义创意</a-radio>
+                    </a-radio-group>
+                </a-form-item>
+                <a-form-item label="创意内容">
+                    <creativity-content :type="creativityAdd" ref="materialCom"></creativity-content>
+                </a-form-item>
+                <a-form-item
+                    label="创意标题"
+                    v-show="creativityAdd.creative_material_mode === 'STATIC_ASSEMBLE'"
+                >
+                    <p
+                        v-for="(item, index) in creativityAdd.title_list"
+                        :key="index"
+                        style="width: 700px"
+                    >
+                        <a-input
+                            placeholder="请输入"
+                            :maxlength="30"
+                            v-model:value="item.title"
+                            style="width: 300px; margin-right: 10px"
+                        ></a-input>
+                        <span v-show="index === 0">
+                            <a-button
+                                :disabled="creativityAdd.title_list.length === 10"
+                                style="margin-right: 10px"
+                                type="primary"
+                                @click="addTitle"
+                            >添加创意标题</a-button>
+                            <span
+                                style="color: gray"
+                            >创意标题个数:{{ creativityAdd.title_list.length }}/10</span>
+                        </span>
+                        <i
+                            v-show="index !== 0"
+                            class="iconfont icon-shanchu"
+                            style="color: gray; cursor: pointer"
+                            @click="deleteTitle(index)"
+                        ></i>
+                    </p>
+                </a-form-item>
+                <a-form-item label="推广卡片">
+                    <push-card ref="cardCom"></push-card>
+                </a-form-item>
+                <a-form-item label="来源">
+                    <a-input
+                        v-model:value="creativityAdd.source"
+                        :maxlength="10"
+                        placeholder="请输入"
+                        style="width: 300px"
+                    ></a-input>
+                </a-form-item>
+                <a-form-item label="自动生成视频素材">
+                    <a-switch
+                        checked-children="开"
+                        un-checked-children="关"
+                        v-model:checked="creativityAdd.creative_auto_generate_switch"
+                    />
+                </a-form-item>
+                <a-form-item label="广告评论">
+                    <a-switch
+                        checked-children="开"
+                        un-checked-children="关"
+                        :disabled="true"
+                        v-model:checked="creativityAdd.is_comment_disable"
+                    />
+                </a-form-item>
+                <a-form-item label="客户端视频下载">
+                    <a-switch
+                        checked-children="开"
+                        un-checked-children="关"
+                        v-model:checked="creativityAdd.ad_download_status"
+                    />
+                </a-form-item>
+                <a-form-item label="创意展现">
+                    <a-radio-group v-model:value="creativityAdd.creative_display_mode">
+                        <a-radio value="CREATIVE_DISPLAY_MODE_CTR">优选模式</a-radio>
+                        <a-radio value="CREATIVE_DISPLAY_MODE_RANDOM">轮播模式</a-radio>
+                    </a-radio-group>
+                </a-form-item>
+            </a-form>
+        </div>
+        <div class="part-box">
+            <h3 class="title">创意分类</h3>
+            <a-form :label-col="labelCol" :wrapper-col="wrapperCol">
+                <a-form-item label="创意分类">
+                    <a-cascader
+                        v-model:value="kind"
+                        :options="[]"
+                        placeholder="请选择"
+                        style="width: 500px"
+                    />
+                </a-form-item>
+                <a-form-item label="创意标签">
+                    <a-input
+                        addon-after="添加(回车)"
+                        v-model:value="label"
+                        style="width: 500px"
+                        @keyup.enter="addKeyWords"
+                        :maxlength="10"
+                        :disabled="creativityAdd.ad_keywords.length === 20"
+                    />
+                    <div class="label-box">
+                        <div class="title-box">
+                            <h3>
+                                已添加
+                                <span>({{ creativityAdd.ad_keywords.length }}/20)</span>
+                            </h3>
+                            <a-button type="link" @click="creativityAdd.ad_keywords = []">全部清空</a-button>
+                        </div>
+                        <div class="label-container">
+                            <p
+                                class="label-item"
+                                v-for="(item, index) in creativityAdd.ad_keywords"
+                                :key="index"
+                            >
+                                <span :title="item">{{ item }}</span>
+                                <i
+                                    class="iconfont icon-guanbi"
+                                    @click="creativityAdd.ad_keywords.splice(index, 1)"
+                                ></i>
+                            </p>
+                        </div>
+                    </div>
+                </a-form-item>
+            </a-form>
+        </div>
+        <a-button @click="goToPlanEdit">上一步</a-button>
+        <a-button type="primary" @click="saveCreative">保存</a-button>
+    </div>
+</template>
+
+<script lang="ts">
+import { defineComponent, reactive, toRefs, ref } from "vue";
+import { createCustomCreative } from "@/api";
+import Bus from "@/utils/bus";
+import { message } from "ant-design-vue";
+import creativityContent from "../component/creativity-content.vue";
+import PushCard from "../component/push-card.vue";
+
+const CreativityAdd = defineComponent({
+    components: { creativityContent, PushCard },
+    setup() {
+        const materialCom: any = ref(null);
+        const cardCom: any = ref(null);
+        const state = reactive({
+            label: "", // 创意标签输入框
+            kind: ref<any[]>([]), // 创意分类
+            creativityAdd: {
+                creative_material_mode: "STATIC_ASSEMBLE", // 创意方式,当值为"STATIC_ASSEMBLE"表示程序化创意,其他情况不传字段
+                creatives: ref<any[]>([]), //自定义素材信息, 最多支持10个创意。首选投放位置和创意类型决定素材规格。当为程序化创意时,该字段不填数据,值为[]
+                title_list: [
+                    {
+                        title: "", // 标题
+                    },
+                ], // 程序化创意时传 自定义不传
+                // 卡片以下
+                source: "",
+                creative_display_mode: "CREATIVE_DISPLAY_MODE_CTR", // 创意展现方式
+                creative_auto_generate_switch: false, // 自动生成素材0-关闭 1-开启
+                is_comment_disable: true, // 广告评论0-关闭 1-开启
+                ad_download_status: true, // 客户端下载视频0-关闭 1-开启
+                // 创意分类
+                third_industry_id: 0, // 创意分类 三级级联选择器
+                ad_keywords: ref<any[]>([]), // 创意标签string[]
+            },
+            creativityClassify: {},
+        });
+        return {
+            ...toRefs(state),
+            labelCol: { span: 3 },
+            wrapperCol: { span: 8 },
+            materialCom,
+            cardCom,
+        };
+    },
+    mounted() {
+        this.getClassify();
+        //初始化拿到编辑列表
+    },
+    methods: {
+        //返回上一页
+        goToPlanEdit(){
+
+            
+        this.$router.push("/put/edit-plan/plan-edit?"+`advertiser_id=${this.$route.query.advertiser_id}`)
+        },
+        //保存配置
+        saveCreative() {
+            this.beforeCommit();
+        },
+        // 获取创意分类
+        getClassify() {
+            console.log("获取分类");
+        },
+        // 提交前数据处理
+        beforeCommit() {
+            let data: any = {};
+            // 一、从素材组件和卡片组件获取数据
+            if (this.creativityAdd.creative_material_mode === "CUSTOM") {
+                // 自定义创意
+                data.creative_list = this.materialCom.backData();
+            }
+            data.task_id = 1
+            // 二、数据处理
+            // 1.创意方式,当值为"STATIC_ASSEMBLE"表示程序化创意,其他情况不传字段
+            // if (data.creative_material_mode === "CUSTOM")
+            //   delete data.creative_material_mode;
+            // 2.添加ad_data
+            data.ad_data = {
+                third_industry_id: this.creativityAdd.third_industry_id,
+                ad_keywords: this.creativityAdd.ad_keywords,
+                source: this.creativityAdd.source,
+                creative_auto_generate_switch: this.creativityAdd
+                    .creative_auto_generate_switch
+                    ? 1
+                    : 0,
+                is_comment_disable: this.creativityAdd.is_comment_disable ? 0 : 1,
+                ad_download_status: this.creativityAdd.ad_download_status ? 0 : 1,
+                creative_display_mode: this.creativityAdd.creative_display_mode,
+            };
+            data.advertiser_id = 0;
+            data.ad_id = 0;
+            this.creatCreativity(data);
+        },
+        // 走创建接口
+        async creatCreativity(val: any) {
+            // this.creativityAdd.creative_material_mode === "CUSTOM"
+            let { data } = await createCustomCreative(val);
+        },
+        // 渲染前数据处理
+        beforeBackshow(creativityOrigin: any) {
+            // 1.创意方式页面
+            if (!creativityOrigin.creative_material_mode)
+                creativityOrigin.creative_material_mode = "CUSTOM";
+        },
+        // 程序化-新增标题
+        addTitle() {
+            this.creativityAdd.title_list.push({ title: "" });
+        },
+        // 程序化-删除标题
+        deleteTitle(index: any) {
+            this.creativityAdd.title_list.splice(index, 1);
+        },
+        // 添加创意标签
+        addKeyWords() {
+            if (!this.label) return message.error("标签内容不能为空");
+            if (this.label.length > 10)
+                return message.error("标签长度不能超过10个字符");
+            if (this.creativityAdd.ad_keywords.includes(this.label))
+                return message.error("标签已存在");
+            this.creativityAdd.ad_keywords.push(this.label);
+            this.label = "";
+        },
+    },
+    beforeUnmount() {
+        Bus.$off("stepFourCheck");
+    },
+});
+
+export default CreativityAdd;
+</script>
+<style lang="scss" scoped>
+.creativity-add {
+    .title {
+        line-height: 30px;
+        font-weight: bold;
+        padding-left: 10px;
+    }
+    .label-box {
+        width: 500px;
+        height: 200px;
+        border: 1px solid rgb(230, 230, 230);
+        margin-top: 10px;
+        .title-box {
+            width: 100%;
+            height: 36px;
+            line-height: 36px;
+            display: flex;
+            justify-content: space-between;
+            padding: 0 0 0 10px;
+            border-bottom: 1px solid rgb(230, 230, 230);
+        }
+        .label-container {
+            height: 163px;
+            width: 100%;
+            padding: 10px;
+            overflow: auto;
+            .label-item {
+                width: 220px;
+                height: 24px;
+                padding: 0 4px;
+                line-height: 24px;
+                background: rgb(241, 241, 241);
+                border: 1px solid rgb(223, 220, 220);
+                float: left;
+                margin-right: 10px;
+                margin-bottom: 10px;
+                span {
+                    display: inline-block;
+                    width: 180px;
+                    white-space: nowrap;
+                    text-overflow: ellipsis;
+                    overflow: hidden;
+                    word-break: break-all;
+                }
+                i {
+                    float: right;
+                    font-size: 13px;
+                    cursor: pointer;
+                }
+            }
+        }
+    }
+}
+</style>

+ 968 - 0
src/views/put/plan-edit/planedit.vue

@@ -0,0 +1,968 @@
+<template>
+  <div class="plan-edit">
+    <!-- part1------优化目标 -->
+    <div class="part-box">
+      <h1>优化目标</h1>
+      <a-form :label-col="labelCol" :wrapper-col="wrapperCol">
+        <!-- <a-form-item label="转化跟踪方式">
+          <a-select placeholder="请选择">
+            <a-select-option value="XIANSUOTONG">线索通</a-select-option>
+            <a-select-option value="XIANSUOTONG_API">线索API</a-select-option>
+          </a-select>
+        </a-form-item>-->
+        <a-form-item label="优化目标">
+          <a-select placeholder="请选择" :disabled="true">
+            <a-select-option v-for="(item, index) in []" :key="index"></a-select-option>
+          </a-select>
+        </a-form-item>
+        <a-form-item label="落地页">
+          <a-select placeholder="请选择" v-model:value="plan.external_url" :disabled="true">
+            <a-select-option v-for="(item, index) in []" :key="index"></a-select-option>
+          </a-select>
+        </a-form-item>
+        <a-form-item label="直达链接内容">
+          <a-input placeholder="选填" v-model:value="plan.open_url" />
+        </a-form-item>
+      </a-form>
+    </div>
+
+    <!-- part2------设置投放位置 -->
+    <div class="part-box">
+      <h1>设置投放位置</h1>
+      <a-form :label-col="labelCol" :wrapper-col="wrapperCol">
+        <a-form-item label="广告位置">
+          <a-radio-group v-model:value="plan.inventory_catalog" :disabled="true">
+            <a-radio value="SMART">系统优选广告位</a-radio>
+            <a-radio value="MANUAL">首选媒体</a-radio>
+            <a-radio value="SCENE">首选场景</a-radio>
+          </a-radio-group>
+        </a-form-item>
+        <a-form-item label="投放媒体" v-show="plan.inventory_catalog === 'MANUAL'">
+          <a-select
+            mode="multiple"
+            size="default"
+            placeholder="请选择"
+            v-model:value="plan.inventory_type"
+            style="width: 400px"
+          >
+            <a-select-option
+              v-for="item in optionsList.mediaList"
+              :key="item.value"
+            >{{ item.label }}</a-select-option>
+          </a-select>
+        </a-form-item>
+        <a-form-item label="投放场景" v-show="plan.inventory_catalog === 'SCENE'">
+          <a-select
+            size="default"
+            placeholder="请选择"
+            v-model:value="plan.scene_inventory"
+            style="width: 400px"
+          >
+            <a-select-option
+              v-for="item in optionsList.sceneList"
+              :key="item.value"
+            >{{ item.label }}</a-select-option>
+          </a-select>
+        </a-form-item>
+        <a-form-item label="搜索快投关键词">
+          <a-switch v-model:checked="plan.feed_delivery_search" />
+        </a-form-item>
+      </a-form>
+    </div>
+
+    <!-- part3------用户定向 -->
+    <div class="part-box">
+      <h1>用户定向</h1>
+      <a-form :label-col="labelCol" :wrapper-col="wrapperCol" style="margin-bottom: 20px">
+        <a-form-item label="定向方式">
+          <a-radio-group v-model:value="userTarget.directType" @change="getPackageList">
+            <a-radio value="BUILD">新建定向</a-radio>
+            <a-radio value="SELECT">选择已有定向包</a-radio>
+          </a-radio-group>
+        </a-form-item>
+        <a-form-item label="选择已有定向包" v-if="userTarget.directType === 'SELECT'">
+          <a-select placeholder="请选择">
+            <a-select-option
+              v-for="(item, index) in directList"
+              :key="index"
+              :value="item.audience_package_id"
+            >{{ item.name }}</a-select-option>
+          </a-select>
+        </a-form-item>
+      </a-form>
+      <a-form
+        :label-col="labelCol"
+        :wrapper-col="wrapperCol"
+        v-if="userTarget.directType === 'BUILD'"
+      >
+        <!-- 地域组件 -->
+        <a-form-item label="地域">
+          <!-- 组件数据接入DDD -->
+          <location :checkedCity="'[]'" ref="cityCom"></location>
+        </a-form-item>
+        <a-form-item label="性别">
+          <a-radio-group v-model:value="plan.gender">
+            <a-radio-button value="NONE">不限</a-radio-button>
+            <a-radio-button value="GENDER_MALE">男</a-radio-button>
+            <a-radio-button value="GENDER_FEMALE">女</a-radio-button>
+          </a-radio-group>
+        </a-form-item>
+        <a-form-item label="年龄">
+          <a-checkbox-group
+            v-model:value="plan.age"
+            style="width: 700px"
+            @change="checkboxChange($event, 'age')"
+          >
+            <a-checkbox value="NONE">不限</a-checkbox>
+            <a-checkbox value="AGE_BETWEEN_18_23">18-23</a-checkbox>
+            <a-checkbox value="AGE_BETWEEN_24_30">24-30</a-checkbox>
+            <a-checkbox value="AGE_BETWEEN_31_40">31-40</a-checkbox>
+            <a-checkbox value="AGE_BETWEEN_41_49">41-49</a-checkbox>
+            <a-checkbox value="AGE_ABOVE_50">50+</a-checkbox>
+          </a-checkbox-group>
+        </a-form-item>
+        <!-- 自定义人群 -->
+        <a-form-item label="自定义人群">
+          <a-radio-group v-model:value="userTarget.crowdType">
+            <a-radio-button value="NONE">不限</a-radio-button>
+            <a-radio-button value="CUSTOM">自定义人群</a-radio-button>
+          </a-radio-group>
+          <!-- 组件数据待接入DDD -->
+          <direction-exclusion
+            ref="crowdCom"
+            :compType="'crowd'"
+            v-if="userTarget.crowdType === 'CUSTOM'"
+          ></direction-exclusion>
+        </a-form-item>
+        <a-form-item label="行为兴趣">
+          <a-radio-group v-model:value="plan.interest_action_mode">
+            <a-radio-button value="UNLIMITED">不限</a-radio-button>
+            <a-radio-button value="RECOMMEND">系统推荐</a-radio-button>
+          </a-radio-group>
+        </a-form-item>
+        <!-- 媒体定向 -->
+        <a-form-item label="媒体定向">
+          <a-radio-group v-model:value="plan.superior_popularity_type">
+            <a-radio-button value="NONE">不限</a-radio-button>
+            <a-radio-button value="1" disabled>游戏优质媒体</a-radio-button>
+            <a-radio-button value="CUSTOM">自定义</a-radio-button>
+          </a-radio-group>
+          <!-- 组件数据接入DDD -->
+          <direction-exclusion
+            ref="mediaCom"
+            :compType="'media'"
+            v-if="plan.superior_popularity_type === 'CUSTOM'"
+          ></direction-exclusion>
+        </a-form-item>
+        <a-form-item label="平台">
+          <a-checkbox-group
+            v-model:value="plan.platform"
+            @change="checkboxChange($event, 'platform')"
+          >
+            <a-checkbox value="NONE">不限</a-checkbox>
+            <a-checkbox value="IOS">ios</a-checkbox>
+            <a-checkbox value="ANDROID">Android</a-checkbox>
+            <a-checkbox value="PC">pc</a-checkbox>
+          </a-checkbox-group>
+        </a-form-item>
+        <a-form-item label="设备类型">
+          <a-checkbox-group
+            v-model:value="plan.device_type"
+            @change="checkboxChange($event, 'device_type')"
+          >
+            <a-checkbox value="NONE">不限</a-checkbox>
+            <a-checkbox value="MOBILE">智能手机</a-checkbox>
+            <a-checkbox value="PAD">平板</a-checkbox>
+          </a-checkbox-group>
+        </a-form-item>
+        <a-form-item label="网络">
+          <a-checkbox-group v-model:value="plan.ac" @change="checkboxChange($event, 'ac')">
+            <a-checkbox value="unknown">不限</a-checkbox>
+            <a-checkbox value="WIFI">Wi-Fi</a-checkbox>
+            <a-checkbox value="2G">2G</a-checkbox>
+            <a-checkbox value="3G">3G</a-checkbox>
+            <a-checkbox value="4G">4G</a-checkbox>
+          </a-checkbox-group>
+        </a-form-item>
+        <a-form-item label="已安装用户">
+          <a-radio-group v-model:value="plan.hide_if_exists">
+            <a-radio-button :value="0">不限</a-radio-button>
+            <a-radio-button :value="1">过滤</a-radio-button>
+            <a-radio-button :value="2">定向</a-radio-button>
+          </a-radio-group>
+        </a-form-item>
+        <a-form-item label="过滤已转化用户">
+          <a-radio-group v-model:value="plan.hide_if_converted">
+            <a-radio-button value="NO_EXCLUDE">不限</a-radio-button>
+            <a-radio-button value="AD">广告计划</a-radio-button>
+            <a-radio-button value="CAMPAIGN">广告组</a-radio-button>
+            <a-radio-button value="ADVERTISER">广告账户</a-radio-button>
+            <a-radio-button value="CUSTOMER">公司账户</a-radio-button>
+          </a-radio-group>
+        </a-form-item>
+        <a-form-item label="过滤时间" v-if="plan.hide_if_converted === 'CUSTOMER'">
+          <!-- 当过滤已转化用户类型选择"公司账户"/“APP”时可填写 -->
+          <a-radio-group v-model:value="plan.converted_time_duration">
+            <a-radio-button value="CUSTOMER">当天</a-radio-button>
+            <a-radio-button value="SEVEN_DAY">7天</a-radio-button>
+            <a-radio-button value="ONE_MONTH">1个月</a-radio-button>
+            <a-radio-button value="THREE_MONTH">3个月</a-radio-button>
+            <a-radio-button value="SIX_MONTH">6个月</a-radio-button>
+            <a-radio-button value="TWELVE_MONTH">12个月</a-radio-button>
+          </a-radio-group>
+        </a-form-item>
+        <!-- 文章分类 -->
+        <a-form-item label="文章分类">
+          <a-radio-group v-model:value="userTarget.articleType">
+            <a-radio-button value="NONE">不限</a-radio-button>
+            <a-radio-button value="CLASSIFY">文章分类</a-radio-button>
+          </a-radio-group>
+          <!-- 组件数据接入DDD -->
+          <check-box
+            ref="articleCom"
+            :compType="1"
+            :showList="[]"
+            v-if="userTarget.articleType === 'CLASSIFY'"
+          ></check-box>
+        </a-form-item>
+        <a-form-item label="运营商">
+          <a-checkbox-group
+            v-model:value="plan.carrier"
+            @change="checkboxChange($event, 'carrier')"
+          >
+            <a-checkbox value="NONE">不限</a-checkbox>
+            <a-checkbox value="MOBILE">移动</a-checkbox>
+            <a-checkbox value="UNICOM">联通</a-checkbox>
+            <a-checkbox value="TELCOM">电信</a-checkbox>
+          </a-checkbox-group>
+        </a-form-item>
+        <a-form-item label="新用户">
+          <a-checkbox-group
+            v-model:value="plan.activate_type"
+            style="width: 600px"
+            @change="checkboxChange($event, 'activate_type')"
+          >
+            <a-checkbox value="NONE">不限</a-checkbox>
+            <a-checkbox value="WITH_IN_A_MONTH">一个月以内</a-checkbox>
+            <a-checkbox value="ONE_MONTH_2_THREE_MONTH">一个月到三个月</a-checkbox>
+            <a-checkbox value="THREE_MONTH_EAILIER">三个月以上</a-checkbox>
+          </a-checkbox-group>
+        </a-form-item>
+        <!-- 手机品牌 -->
+        <a-form-item label="手机品牌">
+          <a-radio-group v-model:value="userTarget.deviceBrand">
+            <a-radio-button value="NONE">不限</a-radio-button>
+            <a-radio-button value="BRAND">手机品牌</a-radio-button>
+          </a-radio-group>
+          <!-- 组件数据接入DDD -->
+          <check-box
+            ref="brandCom"
+            :compType="2"
+            :showList="[]"
+            v-if="userTarget.deviceBrand === 'BRAND'"
+          ></check-box>
+        </a-form-item>
+        <a-form-item label="手机价格">
+          <a-radio-group v-model:value="userTarget.phonePrice">
+            <a-radio-button value="NONE">不限</a-radio-button>
+            <a-radio-button value="CUSTOM">自定义</a-radio-button>
+          </a-radio-group>
+          <div v-if="userTarget.phonePrice === 'CUSTOM'">
+            <a-slider
+              range
+              :marks="phonePriceMarks"
+              :max="11000"
+              :min="0"
+              :step="null"
+              v-model:value="plan.launch_price"
+              style="width: 410px"
+            />
+            <span
+              style="position: relative; top: -54px; left: 450px"
+              v-if="plan.launch_price[0] > 0 && plan.launch_price[1] < 11000"
+            >{{ plan.launch_price[0] }}元~{{ plan.launch_price[1] }}元</span>
+            <span
+              style="position: relative; top: -54px; left: 450px"
+              v-if="
+                (plan.launch_price[0] === 0 &&
+                  plan.launch_price[1] === 11000) ||
+                plan.launch_price[0] == plan.launch_price[1]
+              "
+            >不限</span>
+            <span
+              style="position: relative; top: -54px; left: 450px"
+              v-if="
+                plan.launch_price[0] === 0 &&
+                plan.launch_price[1] < 11000 &&
+                plan.launch_price[1] !== 0
+              "
+            >{{ plan.launch_price[1] }}元以内</span>
+            <span
+              style="position: relative; top: -54px; left: 450px"
+              v-if="
+                plan.launch_price[0] > 0 &&
+                plan.launch_price[1] === 11000 &&
+                plan.launch_price[0] !== 11000
+              "
+            >{{ plan.launch_price[0] }}元以上</span>
+          </div>
+        </a-form-item>
+        <!-- 职业状态 -->
+        <a-form-item label="职业状态">
+          <a-radio-group v-model:value="userTarget.workStatus">
+            <a-radio-button value="NONE">不限</a-radio-button>
+            <a-radio-button value="STATUS">职业状态</a-radio-button>
+          </a-radio-group>
+          <!-- 组件数据待接入DDD -->
+          <check-box
+            ref="workCom"
+            :compType="3"
+            :showList="[]"
+            v-if="userTarget.workStatus === 'STATUS'"
+          ></check-box>
+        </a-form-item>
+        <!-- 智能放量 -->
+        <a-form-item label="智能放量">
+          <a-switch
+            v-model:checked="plan.auto_extend_enabled"
+            checked-children="开"
+            un-checked-children="关"
+          />
+          <check-box ref="extendCom" :compType="4" :showList="[]" v-if="plan.auto_extend_enabled"></check-box>
+        </a-form-item>
+        <p style="line-height: 40px; width: 700px; text-align: right">
+          <a-button @click="saveDirectPackage">保存为定向包</a-button>
+        </p>
+      </a-form>
+    </div>
+
+    <!-- part4------预算与出价 -->
+    <div class="part-box">
+      <h1>预算与出价</h1>
+      <a-form :label-col="labelCol" :wrapper-col="wrapperCol">
+        <a-form-item label="投放场景">
+          <a-radio-group
+            v-model:value="plan.smart_bid_type"
+            @change="itemChange('smart_bid_type')"
+            :disabled="true"
+          >
+            <a-radio value="SMART_BID_CUSTOM">常规投放</a-radio>
+            <a-radio value="SMART_BID_CONSERVATIVE">放量投放</a-radio>
+          </a-radio-group>
+          <span
+            style="font-size: 13px; color: gray"
+            v-show="plan.smart_bid_type === 'SMART_BID_CUSTOM'"
+          >控制成本,尽量消耗完预算</span>
+          <span
+            style="font-size: 13px; color: gray"
+            v-show="plan.smart_bid_type === 'SMART_BID_CONSERVATIVE'"
+          >接受成本上浮,尽量消耗更多预算</span>
+          <a-checkbox
+            v-if="plan.smart_bid_type === 'SMART_BID_CONSERVATIVE'"
+            v-model:checked="plan.adjust_cpa"
+          >通过学习期后,尝试优化转化成本</a-checkbox>
+        </a-form-item>
+        <a-form-item label="日预算" v-if="plan.smart_bid_type === 'SMART_BID_CONSERVATIVE'">
+          <a-input addon-after="元" v-model:value="plan.budget" style="width: 140px" type="number" />
+        </a-form-item>
+        <a-form-item label="预算" v-if="plan.smart_bid_type === 'SMART_BID_CUSTOM'">
+          <a-input addon-after="元" v-model:value="plan.budget" style="width: 220px" type="number">
+            <template #addonBefore>
+              <a-select v-model:value="plan.budget_mode" style="width: 90px">
+                <a-select-option value="BUDGET_MODE_DAY">日预算</a-select-option>
+                <a-select-option value="BUDGET_MODE_TOTAL">总预算</a-select-option>
+              </a-select>
+            </template>
+          </a-input>
+        </a-form-item>
+        <a-form-item label="竞价策略" v-if="plan.smart_bid_type === 'SMART_BID_CUSTOM'">
+          <a-radio-group v-model:value="plan.flow_control_mode">
+            <a-radio value="FLOW_CONTROL_MODE_FAST">优先跑量</a-radio>
+            <a-radio value="FLOW_CONTROL_MODE_SMOOTH">均衡投放</a-radio>
+            <a-radio value="FLOW_CONTROL_MODE_BALANCE">控制成本上限</a-radio>
+          </a-radio-group>
+        </a-form-item>
+        <!-- 预算 -->
+        <a-form-item label="投放时间">
+          <a-radio-group v-model:value="plan.schedule_type">
+            <a-radio value="SCHEDULE_FROM_NOW">从今天起长期投放</a-radio>
+            <a-radio value="SCHEDULE_START_END">设置开始和结束时间</a-radio>
+          </a-radio-group>
+          <a-range-picker
+            v-if="plan.schedule_type === 'SCHEDULE_START_END'"
+            v-model:value="range"
+            :allowClear="false"
+          />
+        </a-form-item>
+        <a-form-item label="投放时段">
+          <a-radio-group v-model:value="userTarget.timeDuration">
+            <a-radio value="NONE">不限</a-radio>
+            <a-radio value="CUSTOM">指定时间段</a-radio>
+          </a-radio-group>
+          <time-schedule
+            ref="timeCom"
+            style="width: 800px; margin-top: 10px"
+            v-if="userTarget.timeDuration === 'CUSTOM'"
+          ></time-schedule>
+        </a-form-item>
+        <!-- 投放时段 -->
+        <a-form-item label="付费方式">
+          <a-radio-group v-model:value="plan.pricing">
+            <a-radio value="PRICING_CPM">按展示付费(oCPM)</a-radio>
+          </a-radio-group>
+        </a-form-item>
+        <a-form-item label="目标转化出价">
+          <a-input style="width: 100px" type="number" suffix="元" v-model:value="plan.cpa_bid" />
+          <span style="font-size: 13px; color: gray">出价不能大于预算</span>
+        </a-form-item>
+      </a-form>
+    </div>
+
+    <!-- part5------第三方检测链 -->
+    <div class="part-box">
+      <h1>第三方检测链</h1>
+      <a-form :label-col="labelCol" :wrapper-col="wrapperCol">
+        <a-form-item label="展示">
+          <a-input placeholder="选填" v-model:value="plan.track_url[0]" />
+        </a-form-item>
+        <a-form-item label="有效触点">
+          <a-input placeholder="选填" v-model:value="plan.action_track_url[0]" />
+        </a-form-item>
+        <a-form-item label="视频播放">
+          <a-input placeholder="选填" v-model:value="plan.video_play_track_url[0]" />
+        </a-form-item>
+        <a-form-item label="视频播完">
+          <a-input placeholder="选填" v-model:value="plan.video_play_done_track_url[0]" />
+        </a-form-item>
+        <a-form-item label="视频有效播放">
+          <a-input placeholder="选填" v-model:value="plan.video_play_effective_track_url[0]" />
+        </a-form-item>
+      </a-form>
+    </div>
+
+    <!-- part6------计划名称 -->
+    <div class="part-box">
+      <h1>计划名称</h1>
+      <a-form :label-col="labelCol" :wrapper-col="wrapperCol">
+        <a-form-item label="计划名称">
+          <a-input placeholder="选填" v-model:value="plan.name" />
+        </a-form-item>
+        <a-form-item label="创建数量">
+          <a-input placeholder="选填" v-model:value="plan.number" />
+        </a-form-item>
+      </a-form>
+    </div>
+  </div>
+  <a-button @click="cancel">取消</a-button>
+  <a-button  type="primary"  @click="nextStep">下一步</a-button>
+</template>
+
+<script lang="ts">
+import { defineComponent, reactive, toRefs, ref } from "vue";
+import { createPlan, getPackage } from "@/api";
+import Bus from "@/utils/bus";
+import { Moment } from "moment";
+import moment from "moment";
+import TimeSchedule from "../component/time-schedule.vue";
+import Location from "../component/location-auto-release.vue";
+import DirectionExclusion from "../component/direction-exclusion.vue";
+import CheckBox from "../component/check-box.vue";
+import { message } from "ant-design-vue";
+import { PriceSlider, LaunchMedia, LaunchScene } from "../component/plan-data";
+
+const PlanEdit = defineComponent({
+  components: {
+    TimeSchedule,
+    Location,
+    DirectionExclusion,
+    CheckBox,
+  },
+  setup() {
+    const cityCom: any = ref(null); // 地域组件
+    const crowdCom: any = ref(null); // 人群组件
+    const mediaCom: any = ref(null); // 媒体组件
+    const timeCom: any = ref(null); // 时段组件
+    const articleCom: any = ref(null); // 文章分类组件
+    const workCom: any = ref(null); // 工作状态组件
+    const brandCom: any = ref(null); // 手机品牌组件
+    const extendCom: any = ref(null); // 智能放量组件
+    const state = reactive({
+      // 页面变量
+      userTarget: {
+        // 用户定向相关页面变量
+        directType: "BUILD", // 新建定向包-BUILD 选择已有定向包-SELECT
+        crowdType: "NONE", // 人群定向 不限-NONE 自定义-CUSTOM
+        mediaTarget: "NONE", // 媒体定向 不限-NONE 自定义-CUSTOM
+        articleType: "NONE", // 文章分类 不限-NONE 分类-CLASSIFY
+        deviceBrand: "NONE", // 手机品牌 不限-NONE 品牌-BRAND
+        workStatus: "NONE", // 职业状态 不限-NONE 状态-STATUS
+        phonePrice: "NONE", // 手机价格 不限-NONE 自定义-CUNSTOM
+        timeDuration: "NONE", // 投放时段 不限-NONE 指定时段-CUSTOM
+      },
+      plan: {
+        // part1 优化目标----------------------------------------------------
+        convert_type: "", // 转化跟踪方式
+        external_url: undefined, // 落地页
+        open_url: "", // 直达链接内容
+        // part2 投放位置----------------------------------------------------
+        inventory_catalog: "SMART", // 广告位置
+        inventory_type: ref<any[]>([]), // 投放媒体-广告位置是首选媒体时必填 否则删除
+        scene_inventory: "", // 投放场景-广告位置时首选场景时必填 否则删除
+        feed_delivery_search: true, // 搜索快投关键词
+        // part3 用户定向----------------------------------------------------
+        district: "", // 地域类型
+        city: ref<any[]>([]), // 选中的城市或区县
+        gender: "NONE", // 性别
+        age: ref<any[]>(["NONE"]), // 年龄
+        retargeting_tags_include: ref<any[]>([]), // 定向人群
+        retargeting_tags_exclude: ref<any[]>([]), //排除人群
+        interest_action_mode: "UNLIMITED", // 行为兴趣
+        superior_popularity_type: "NONE", // 媒体定向类型 、、 选择自定义媒体包时本字段不传
+        flow_package: ref<any[]>([]), // 定向流量包
+        exclude_flow_package: ref<any[]>([]), // 排除流量包
+        platform: ref<any[]>(["NONE"]), // 平台-字符串数组
+        device_type: ref<any[]>(["NONE"]), // 设备类型 不限不传
+        ac: ref<any[]>(["unknown"]), // 网络
+        hide_if_exists: 0, // 已安装用户 0-不限 1-过滤 2-定向
+        hide_if_converted: "AD", // 过滤已转化用户 默认AD广告计划
+        converted_time_duration: "CUSTOMER", // 过滤时间
+        article_category: ref<any[]>([]), // 文章分类
+        carrier: ref<any[]>(["NONE"]), // 运营商
+        activate_type: ref<any[]>(["NONE"]), // 新用户
+        device_brand: ref<any[]>([]), // 手机品牌
+        launch_price: ref<any[]>([0, 11000]), // 手机价格-number[]
+        career: ref<any[]>([]), // 职业状态-string[]
+        auto_extend_enabled: false, // 智能放量
+        auto_extend_targets: ref<any[]>([]), // 可开放定向
+        // part4 预算与出价---------------------------------------
+        smart_bid_type: "SMART_BID_CUSTOM", // 投放场景
+        adjust_cpa: false, // 优化转化成本 0-false 1-true // 投放场景为常规投放时不传
+        flow_control_mode: "FLOW_CONTROL_MODE_FAST", // 竞价策略
+        budget_mode: "BUDGET_MODE_DAY", // 预算类型 日预算-BUDGET_MODE_DAY 总预算-BUDGET_MODE_TOTAL // 投放场景为放量投放时 固定为日预算
+        budget: 0, // 预算
+        schedule_type: "SCHEDULE_FROM_NOW", // 投放时间类型
+        start_time: "", // 投放开始时间
+        end_time: "", // 投放结束时间
+        schedule_time: "", // 投放时段
+        pricing: "PRICING_CPM", // 付费方式
+        cpa_bid: "", // 目标转化出价
+        // part5 第三方检测---------------------------------------
+        track_url: ref<any[]>([]), // 展示
+        action_track_url: ref<any[]>([]), // 有效触点
+        video_play_track_url: ref<any[]>([]), // 视频播放
+        video_play_done_track_url: ref<any[]>([]), // 视频播完
+        video_play_effective_track_url: ref<any[]>([]), // 有效播放
+        // part6 计划名称---------------------------------------
+        name: "", // 计划名称
+        number: 1, // 创建数量
+      },
+      range: ref<Moment[]>([]), // 投放时间选择
+      phonePriceMarks: PriceSlider, //手机价格区间
+      optionsList: {
+        mediaList: LaunchMedia, // 投放媒体
+        sceneList: LaunchScene, // 投放场景
+      },
+      advertiser_id: 0,
+      directList: ref<any[]>([]),
+    });
+    return {
+      ...toRefs(state),
+      labelCol: { span: 3 },
+      wrapperCol: { span: 8 },
+      cityCom,
+      crowdCom,
+      mediaCom,
+      timeCom,
+      articleCom,
+      workCom,
+      brandCom,
+      extendCom,
+    };
+  },
+  mounted() {
+    this.advertiser_id = Number(this.$route.query.advertiser_id);
+    let time = this.getNowFormatDate();
+    this.plan.name = `${this.plan.pricing}_${time}`;
+    Bus.$on("stepThreeCheck", (val?: any) => {
+      console.log("Step3Check");
+      Bus.$emit("stepThreeBack");
+      // this.beforeCommit();
+    });
+  },
+  methods: {
+    //取消
+    cancel(){
+      this.$router.push('/put/plan-management')
+    },
+    //下一步
+    nextStep(){
+        
+      this.$router.push('/put/edit-plan/add-creative?'+`advertiser_id=${this.$route.query.advertiser_id}`)
+        this.beforeCommit()
+    },
+    // 提交前处理数据
+    beforeCommit() {
+      let data: any = {};
+      data = JSON.parse(JSON.stringify(this.plan));
+      //  一、组件数据收集
+      // 1.地域组件
+      data.district = this.cityCom.backData().type;
+      data.city = this.cityCom.backData().list;
+      // 2.定向排除-人群组件
+      data.retargeting_tags_include = this.crowdCom
+        ? this.crowdCom.backData().direction
+        : []; // 定向
+      data.retargeting_tags_exclude = this.crowdCom
+        ? this.crowdCom.backData().exclusion
+        : []; // 排除
+      // 3.定向排除-媒体组件
+      data.flow_package = this.mediaCom
+        ? this.mediaCom.backData().direction
+        : []; // 定向
+      data.exclude_flow_package = this.mediaCom
+        ? this.mediaCom.backData().exclusion
+        : []; // 排除
+      // 4.checkbox-文章分类
+      data.article_category = this.articleCom ? this.articleCom.backData() : [];
+      // 5.checkbox-手机品牌
+      data.device_brand = this.brandCom ? this.brandCom.backData() : [];
+      // 6.checkbox-职业状态
+      data.career = this.workCom ? this.workCom.backData() : [];
+      // 7.checkbox-智能放量
+      data.auto_extend_targets = this.extendCom
+        ? this.extendCom.backData()
+        : [];
+      // 8.投放时段
+      data.schedule_time = this.timeCom ? this.timeCom.backData() : [];
+
+      // 二、数据处理
+      // 1.搜索快投关键词 feed_delivery_search--true=>HAS_OPEN, false=>DISABLED
+      data.feed_delivery_search = data.feed_delivery_search
+        ? "HAS_OPEN"
+        : "DISABLED";
+      // 2.用户定向选择已有定向包时处理
+      // 3.缺省代表不限的字段 ['NONE'] => [], 平台、设备类型、运营商carrier、新用户activate_type、(年龄age)、ac(unknown)
+      //   3.1平台
+      if (data.platform[0] === "NONE") delete data.platform;
+      //   3.2设备类型device_type
+      if (data.device_type[0] === "NONE") delete data.device_type;
+      //   3.3运营商carrier
+      if (data.carrier[0] === "NONE") delete data.carrier;
+      //   3.4新用户activate_type
+      if (data.activate_type[0] === "NONE") delete data.activate_type;
+      //   3.5年龄 age
+      if (data.age[0] === "NONE") delete data.age;
+      //   3.6 ac
+      if (data.ac[0] === "unknown") delete data.ac;
+      // 4.当过滤已转化用户不是CUSTOMER 时 删除过滤时间
+      if (data.hide_if_converted !== "CUSTOMER")
+        delete data.converted_time_duration;
+      // 5.用户分类为不限时 删除字段
+      if (this.userTarget.articleType === "NONE") delete data.article_category;
+      // 6.手机品牌为不限时 删除字段device_brand
+      if (this.userTarget.deviceBrand === "NONE") delete data.device_brand;
+      // 7.职位状态为不限时 删除字段career
+      if (this.userTarget.workStatus === "NONE") delete data.career;
+      // 8.广告位置不是首选媒体时 删除投放媒体字段 不是首选场景-删除投放场景字段
+      if (data.inventory_catalog !== "MANUAL") delete data.inventory_type;
+      if (data.inventory_catalog !== "SCENE") delete data.scene_inventory;
+      // 9.手机价格为不限时 删除字段launch_price
+      if (this.userTarget.phonePrice === "NONE") delete data.launch_price;
+      // 10.智能放量开关auto_extend_enabled false=> 0 true=>1 关闭智能放量 删除开放定向字段
+      data.auto_extend_enabled = this.numAndBool(data.auto_extend_enabled);
+      if (!data.auto_extend_enabled) delete data.auto_extend_targets;
+      // 11.投放时段-timeDuration-NONE时 删除schedule_time
+      if (this.userTarget.timeDuration === "NONE") delete data.schedule_time;
+      // 12.删除plan.name plan.number
+      delete data.name;
+      delete data.number;
+      // 13.投放场景为常规投放时 删除优化转化成本 adjust_cpa 否则删除竞价策略
+      if (data.smart_bid_type === "SMART_BID_CUSTOM") {
+        delete data.adjust_cpa;
+      } else {
+        data.adjust_cpa = this.numAndBool(data.adjust_cpa);
+        delete data.flow_control_mode;
+      }
+      // 14.当投放时间为指定时间时 range=>start_time\end_time 否则删除
+      if (data.schedule_type === "SCHEDULE_START_END") {
+        data.start_time = moment(this.range[0]).format("YYYY-MM-DD");
+        data.end_time = moment(this.range[1]).format("YYYY-MM-DD");
+      } else {
+        delete data.start_time;
+        delete data.end_time;
+      }
+      // 15.投放人群为不限时 删除 retargeting_tags_include 、 retargeting_tags_exclude
+      if (this.userTarget.crowdType === "NONE") {
+        delete data.retargeting_tags_include;
+        delete data.retargeting_tags_exclude;
+      }
+      // 15.媒体定向为不限时 删除 flow_package 、 exclude_flow_package
+      if (this.plan.superior_popularity_type === "NONE") {
+        delete data.flow_package;
+        delete data.exclude_flow_package;
+      } else {
+        delete data.superior_popularity_type;
+      }
+      // 调用接口
+      console.log("data", data);
+      // return;
+      this.savePlan(data);
+    },
+    // 保存数据
+    async savePlan(plan_data: any) {
+      let advertiser_id = this.$route.query.advertiser_id;
+      let campaign_id = this.$route.query.campaign_id;
+      let param = {
+        advertiser_id,
+        campaign_id,
+        ad_num: this.plan.number,
+        is_template: 1,
+        name: this.plan.name,
+        ad_data: { ...plan_data },
+      };
+      console.log("新建计划数据", param);
+      try {
+        let { data } = await createPlan(param);
+        console.log("请求成功");
+        Bus.$emit("stepThreeBack");
+      } catch (err) {
+        console.log("请求失败", err.msg);
+      }
+    },
+    // 回显之前处理数据
+    beforeBackShow(planOrigin: any) {
+      // 1.搜索快投关键词 feed_delivery_search--HAS_OPEN=>true, DISABLED=>false
+      planOrigin.feed_delivery_search =
+        planOrigin.feed_delivery_search === "HAS_OPEN" ? true : false;
+      // 2.判断数据里是否有定向包id 决定userTarget.directType用户定向方式页面变量
+      // 3.判断数据里是否有定向、排除人群包 决定userTarget.crowdType人群定向方式页面变量
+
+      // 4.空数组转换成不限 [] => ['NONE'], 平台、设备类型、运营商carrier、新用户activate_type
+      //   4.1平台
+      planOrigin.platform = planOrigin.platform
+        ? planOrigin.platform
+        : ["NONE"];
+      //   4.2设备类型
+      planOrigin.device_type = planOrigin.device_type
+        ? planOrigin.device_type
+        : ["NONE"];
+      //   4.3运营商
+      planOrigin.carrier = planOrigin.carrier ? planOrigin.carrier : ["NONE"];
+      //   4.4新用户activate_type
+      planOrigin.activate_type = planOrigin.activate_type
+        ? planOrigin.activate_type
+        : ["NONE"];
+      // 5.根据是否有article_category  字段判断页面变量文章分类
+      // planOrigin.article_category= ['SOCIETY', 'ENTERTAINMENT', 'CARS']
+      this.userTarget.articleType = planOrigin.article_category
+        ? "CLASSIFY"
+        : "NONE";
+      // 6.根据否有device_brand字段判断页面变量手机品牌
+      this.userTarget.deviceBrand = planOrigin.device_brand ? "BRAND" : "NONE";
+      // 7.根据否有career字段判断页面变量职业状态
+      this.userTarget.workStatus = planOrigin.career ? "STATUS" : "NONE";
+      // 8.根据否有launch_price字段判断页面变量手机价格
+      this.userTarget.phonePrice = planOrigin.launch_price ? "CUSTOM" : "NONE";
+      // 9.根据auto_extend_enabled字段转化trur/false渲染
+      planOrigin.auto_extend_enabled = this.numAndBool(
+        planOrigin.auto_extend_enabled
+      );
+      // 10.根据否有schedule_time字段判断页面变量投放时段
+      this.userTarget.timeDuration = planOrigin.schedule_time
+        ? "CUSTOM"
+        : "NONE";
+      // 11.投放场景不是常规投放时 优化成本bool转num
+      if (planOrigin.smart_bid_type !== "SMART_BID_CUSTOM")
+        planOrigin.adjust_cpa = this.numAndBool(planOrigin.adjust_cpa);
+      // 12.如果返回数据里有start_time/end_time 将这两个值赋值给range
+      if (planOrigin.hasOwnProperty("")) {
+        this.range = [
+          moment(planOrigin.start_time, "YYYY-MM-DD"),
+          moment(planOrigin.end_time, "YYYY-MM-DD"),
+        ];
+      }
+    },
+    // 获取已有定向包
+    async getPackageList() {
+      let param = {
+        advertiser_id: this.advertiser_id,
+        page: 1,
+        page_size: 100,
+      };
+      let { data } = await getPackage(param);
+      console.log("定向包数据", data);
+      this.directList = data.audience_packages;
+    },
+    // 多选框互斥
+    checkboxChange(val: any, type: any) {
+      // 年龄互斥
+      if (type === "age") {
+        this.$nextTick(() => {
+          if (this.plan.age.indexOf("NONE") == 0 && this.plan.age.length > 1) {
+            this.plan.age.splice(this.plan.age.indexOf("NONE"), 1);
+          } else if (this.plan.age.indexOf("NONE") > 0) {
+            this.plan.age = ["NONE"];
+          }
+          if (this.plan.age.length === 0) this.plan.age = ["NONE"];
+        });
+      }
+      // 平台互斥
+      if (type === "platform") {
+        this.$nextTick(() => {
+          if (
+            this.plan.platform.indexOf("NONE") == 0 &&
+            this.plan.platform.length > 1
+          ) {
+            this.plan.platform.splice(this.plan.platform.indexOf("NONE"), 1);
+          } else if (this.plan.platform.indexOf("NONE") > 0) {
+            this.plan.platform = ["NONE"];
+          }
+          if (this.plan.platform.length === 0) this.plan.platform = ["NONE"];
+        });
+      }
+      // 设备类型互斥
+      if (type === "device_type") {
+        if (
+          this.plan.device_type.indexOf("NONE") == 0 &&
+          this.plan.device_type.length > 1
+        ) {
+          this.plan.device_type.splice(
+            this.plan.device_type.indexOf("NONE"),
+            1
+          );
+        } else if (this.plan.device_type.indexOf("NONE") > 0) {
+          this.plan.device_type = ["NONE"];
+        }
+        if (this.plan.device_type.length === 0)
+          this.plan.device_type = ["NONE"];
+      }
+      // 网络互斥
+      if (type === "ac") {
+        console.log("acccc");
+        if (this.plan.ac.indexOf("unknown") == 0 && this.plan.ac.length > 1) {
+          this.plan.ac.splice(this.plan.ac.indexOf("unknown"), 1);
+        } else if (this.plan.ac.indexOf("unknown") > 0) {
+          this.plan.ac = ["unknown"];
+        }
+        if (this.plan.ac.length === 0) this.plan.ac = ["unknown"];
+      }
+      // 运营商互斥
+      if (type === "carrier") {
+        this.$nextTick(() => {
+          if (
+            this.plan.carrier.indexOf("NONE") == 0 &&
+            this.plan.carrier.length > 1
+          ) {
+            this.plan.carrier.splice(this.plan.carrier.indexOf("NONE"), 1);
+          } else if (this.plan.carrier.indexOf("NONE") > 0) {
+            this.plan.carrier = ["NONE"];
+          }
+          if (this.plan.carrier.length === 0) this.plan.carrier = ["NONE"];
+        });
+      }
+      // 新用户互斥
+      if (type === "activate_type") {
+        this.$nextTick(() => {
+          if (
+            this.plan.activate_type.indexOf("NONE") == 0 &&
+            this.plan.activate_type.length > 1
+          ) {
+            this.plan.activate_type.splice(
+              this.plan.activate_type.indexOf("NONE"),
+              1
+            );
+          } else if (this.plan.activate_type.indexOf("NONE") > 0) {
+            this.plan.activate_type = ["NONE"];
+          }
+          if (this.plan.activate_type.length === 0)
+            this.plan.activate_type = ["NONE"];
+        });
+      }
+    },
+    // 选项改变时联动
+    itemChange(type: any) {
+      // 投放场景为放量投放 预算类型固定为日预算 清空预算
+      if (
+        type === "smart_bid_type" &&
+        this.plan.smart_bid_type === "SMART_BID_CONSERVATIVE"
+      ) {
+        this.plan.budget_mode = "BUDGET_MODE_DAY";
+        this.plan.budget = 0;
+      }
+    },
+    // 用户定向保存为定向包
+    saveDirectPackage() {
+      console.log("保存定向包");
+    },
+    // 工具函数 0=>false 1=>true false=>0 true=>1
+    numAndBool(val: any) {
+      if (val === 0) return false;
+      if (val === 1) return true;
+      if (val === true) return 1;
+      if (val === false) return 0;
+    },
+    // 工具函数 获取当前时间
+    getNowFormatDate() {
+      var date = new Date();
+      var seperator1 = "-";
+      var seperator2 = ":";
+      var month: any = date.getMonth() + 1;
+      var strDate: any = date.getDate();
+      var strHours: any = date.getHours();
+      var strMinutes: any = date.getMinutes();
+      var strSeconds: any = date.getSeconds();
+      if (month >= 1 && month <= 9) {
+        month = "0" + month;
+      }
+      if (strDate >= 0 && strDate <= 9) {
+        strDate = "0" + strDate;
+      }
+      if (strHours >= 0 && strHours <= 9) {
+        strHours = "0" + strHours;
+      }
+      if (strMinutes >= 0 && strMinutes <= 9) {
+        strMinutes = "0" + strMinutes;
+      }
+      if (strSeconds >= 0 && strSeconds <= 9) {
+        strSeconds = "0" + strSeconds;
+      }
+      var currentdate =
+        date.getFullYear() +
+        seperator1 +
+        month +
+        seperator1 +
+        strDate +
+        " " +
+        strHours +
+        seperator2 +
+        strMinutes +
+        seperator2 +
+        strSeconds;
+      currentdate = currentdate.replace(/-/g, "_").replace(/ /g, "_");
+      currentdate = currentdate.slice(5, 19);
+      return currentdate;
+    },
+    // 互斥项切换-工具函数
+
+  },
+  // beforeUnmount() {
+  //   Bus.$off("stepThreeCheck");
+  // },
+});
+
+export default PlanEdit;
+</script>
+<style lang="scss" scoped>
+.plan-edit {
+  .part-box {
+    min-height: 100px;
+    border-bottom: 1px solid rgb(230, 230, 230);
+    padding-bottom: 30px;
+    h1 {
+      font-weight: bold;
+      height: 40px;
+      line-height: 40px;
+    }
+  }
+}
+</style>

+ 153 - 51
src/views/put/plan-management.vue

@@ -2,49 +2,35 @@
   <div class="plan-management">
     <div class="title-box-common">
       <h3>计划管理</h3>
-      <a-button type="primary" @click="visible = true">新建</a-button>
+      <a-button type="primary" @click="newAdd">新建</a-button>
     </div>
     <div class="padding-box-common">
       <div class="search-box">
         <div class="search-item">
           <span class="label">计划名称:</span>
-          <a-input
-            v-model:value="search.plan_name"
-            placeholder="请输入计划名称或ID"
-          ></a-input>
+          <a-input v-model:value="search.ad_name" placeholder="请输入计划名称或ID"></a-input>
         </div>
         <div class="search-item">
           <span class="label">所属账户:</span>
-          <a-input
-            v-model:value="search.account"
-            placeholder="请输入账户名称或ID"
-          >
-          </a-input>
+          <a-input v-model:value="search.advertiser_name" placeholder="请输入账户名称或ID"></a-input>
         </div>
         <div class="search-item">
           <span class="label">所属广告组:</span>
-          <a-input
-            v-model:value="search.group"
-            placeholder="请输入广告组名称或ID"
-          >
-          </a-input>
+          <a-input v-model:value="search.campaign_name" placeholder="请输入广告组名称或ID"></a-input>
         </div>
         <div class="search-item">
           <span class="label">状态:</span>
-          <a-select
-            placeholder="请选择"
-            style="width: 200px"
-            v-model:value="search.status"
-          >
-            <a-select-option value="">全部</a-select-option>
-            <a-select-option value="a">下发中</a-select-option>
-            <a-select-option value="x">下发失败</a-select-option>
-            <a-select-option value="s">下发成功</a-select-option>
+          <a-select placeholder="请选择" style="width: 200px" v-model:value="search.status">
+            <a-select-option value>全部</a-select-option>
+            <a-select-option value="DOING">下发中</a-select-option>
+            <a-select-option value="FAIL">下发失败</a-select-option>
+            <a-select-option value="SUCCESS">下发成功</a-select-option>
           </a-select>
         </div>
         <div class="search-item">
-          <span class="label"></span><a-button type="primary"> 搜索 </a-button>
-          <a-button @click="resetSearch"> 重置 </a-button>
+          <span class="label"></span>
+          <a-button type="primary" @click="searchList">搜索</a-button>
+          <a-button @click="resetSearch">重置</a-button>
         </div>
       </div>
       <div class="table-box">
@@ -53,30 +39,83 @@
           :data-source="list"
           :columns="columns"
           rowKey="id"
-          :loading="loading"
+          :loading="palnloading"
           :pagination="tablePageOptions"
-        ></a-table>
+        >
+          <template #status="{ text, record }">
+            <p v-if="record.status == 'SUCCESS'">下发成功</p>
+            <p v-if="record.status == 'DOING'">下发中</p>
+            <p v-if="record.status == 'FAIL'">下发失败</p>
+          </template>
+
+          <template #setting="{ text, record }">
+            <template v-if="record.status == 'SUCCESS'">
+              <a-button @click="editMatch(record)">数据</a-button>
+              <a-button @click="editItem(record)">编辑</a-button>
+              <a-popconfirm
+                placement="top"
+                ok-text="删除"
+                cancel-text="取消"
+                @confirm="delItem(record)"
+                :title="`确认删除广告计划${record.ad_name}?`"
+              >
+                <a-button>删除</a-button>
+              </a-popconfirm>
+            </template>
+            <template v-if="record.status == 'FAIL'">
+              <a-popconfirm
+                placement="top"
+                ok-text="删除"
+                cancel-text="取消"
+                @confirm="delItem(record)"
+                :title="`确认删除广告计划${record.ad_name}?`"
+              >
+                <a-button>删除</a-button>
+              </a-popconfirm>
+              <a-button @click="editItem(record)">编辑</a-button>
+            </template>
+            <template v-if="record.status == 'DOING'">
+              <a-popconfirm
+                placement="top"
+                ok-text="删除"
+                cancel-text="取消"
+                @confirm="delItem(record)"
+                :title="`确认删除广告计划${record.ad_name}?`"
+              >
+                <a-button>删除</a-button>
+              </a-popconfirm>
+            </template>
+          </template>
+        </a-table>
       </div>
     </div>
-    <a-modal
-      v-model:visible="visible"
-      title="选择模板"
-      @ok="handleOk"
-      okText="直接创建"
-      width="1000px"
-    >
+    <a-modal v-model:visible="visible" title="选择模板" @ok="handleOk" okText="直接创建" width="1000px">
       <a-input-search
         style="width: 200px; margin-bottom: 10px"
         placeholder="请输入模板名称"
+        @search="onSearch"
       ></a-input-search>
       <a-table
         bordered
-        :data-source="list"
+        :data-source="templatelist"
         :columns="templateColumns"
         rowKey="id"
         :loading="loading"
         :pagination="tablePageOptions"
-      ></a-table>
+      >
+        <template #action="{ text, record }">
+          <a-button @click="useModel(record)">使用</a-button>
+          <a-popconfirm
+            placement="top"
+            ok-text="删除"
+            cancel-text="取消"
+            @confirm="delModelItem(record)"
+            :title="`确认删除摸版名为${record.name}?`"
+          >
+            <a-button>删除</a-button>
+          </a-popconfirm>
+        </template>
+      </a-table>
     </a-modal>
   </div>
 </template>
@@ -84,24 +123,27 @@
 <script lang="ts">
 import { defineComponent, reactive, toRefs } from "vue";
 import usePagination from "@/hooks/usePagination";
-import { getPlanList, getPlanTemplate } from "@/api";
+import { getPlanList, getPlanTemplate, delPlanList, delModelItem } from "@/api";
 import { PlanCloumn, PlanTemplateCloumn } from "../_pageOptions/table-put";
-import { message } from "ant-design-vue";
-
+import { message } from 'ant-design-vue';
 const PlanManagement = defineComponent({
   setup() {
     let { meta, tablePageOptions, loading } = usePagination();
     const state = reactive({
       search: {
-        plan_name: "",
-        account: "",
-        group: "",
+        ad_name: "",
+        advertiser_name: "",
+        campaign_name: "",
         status: "",
+
       },
       visible: false,
       list: [],
+      templatelist: [],
       columns: PlanCloumn,
       templateColumns: PlanTemplateCloumn,
+      palnloading: false,
+      deltext: '确认删除吗'
     });
     return { ...toRefs(state), meta, tablePageOptions, loading };
   },
@@ -110,26 +152,86 @@ const PlanManagement = defineComponent({
     this.getTemplate();
   },
   methods: {
+    //新建
+    newAdd() {
+      this.visible = true;
+      this.getTemplate()
+    },
     // 重置
     resetSearch() {
-      this.search.plan_name = "";
-      this.search.account = "";
-      this.search.group = "";
+      this.search.ad_name = "";
+      this.search.advertiser_name = "";
+      this.search.campaign_name = "";
       this.search.status = "";
+      this.getList()
+    },
+    //删除摸版列表
+    delModelItem(item: any) {
+      console.log(item)
+      delModelItem({id:item.id}).then(() => {
+            message.info('删除摸版成功')
+            this.getTemplate()
+      })
+    },
+
+    //删除计划item
+    delItem(item: any) {
+      console.log(item)
+      delPlanList({ log_id: item.id }).then(() => {
+        message.info('删除计划成功');
+        this.getList()
+      })
+
+    },
+    //搜索列表
+    async searchList() {
+      this.palnloading = true
+      let { data, code } = await getPlanList(this.search as any);
+      code == 0 ? this.palnloading = false : this.palnloading = true
+      this.list = data.list
     },
-    // 获取计划列表
+    // 获取计划列表 初始化
     async getList() {
-      let { data } = await getPlanList({ page: 1 });
-      console.log("计划列表", data);
+      this.palnloading = true
+      let { data, code } = await getPlanList({});
+      code == 0 ? this.palnloading = false : this.palnloading = true
+      this.list = data.list
     },
     async getTemplate() {
-      let { data } = await getPlanTemplate({ page: 1 });
-      console.log("计划模板", data);
+      let { data, code } = await getPlanTemplate({ page: 1 });
+      code == 0 ? this.palnloading = false : this.palnloading = true
+      this.templatelist = data.list
+    },
+    //搜索摸版列表
+    onSearch(vaule: string) {
+      getPlanTemplate({ name: vaule }).then((res: any) => {
+        let { data, code } = res
+        code == 0 ? this.palnloading = false : this.palnloading = true
+        this.templatelist = data.list
+      })
+    },
+    //使用按钮跳转到新新建计划
+    useModel(item: any) {
+      console.log(item)
+      this.$router.push({ path: "/put/plan-create/account-select", params: item })
     },
+
+
+
     // 直接创建
     handleOk() {
       this.$router.push("/put/plan-create");
     },
+    //编辑
+    editItem(item: any) {
+      console.log(item)
+      //跳转到编辑页面
+      this.$router.push("/put/edit-plan/plan-edit?"+`advertiser_id=${item.advertiser_id}`);
+    },
+    //
+    editMatch(item: any) {
+      this.$router.push( "/put/datas/ad-plan?"+item)
+    }
   },
 });