ringcode преди 3 години
родител
ревизия
a6e0193e2b

+ 1 - 1
public/index.html

@@ -10,7 +10,7 @@
   <% for (var i in htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.css) { %>
     <link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="stylesheet" />
     <% } %>
-      <link rel="stylesheet" type="text/css" href="//at.alicdn.com/t/font_2651824_8qs04u9ywnn.css">
+      <link rel="stylesheet" type="text/css" href="//at.alicdn.com/t/font_2651824_jy66ibe48qh.css">
       <!-- 使用CDN加速的JS文件,配置在vue.config.js下 -->
       <% for (var i in htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.js) { %>
         <script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>

+ 482 - 0
src/views/put/component/creativity-content.vue

@@ -0,0 +1,482 @@
+<template>
+  <div class="creativity-content">
+    <div class="program-type common-type">
+      <p style="color: gray">
+        图片创意个数:{{
+          count.imageType1 + count.imageType2 + count.imageType2
+        }}/12 视频创意个数: {{ count.videoType1 + count.videoType2 }}/10
+      </p>
+      <div class="type-box">
+        <div
+          :class="{
+            'type-item': true,
+            'current-type': currentType === item.value,
+          }"
+          v-for="(item, index) in typeList"
+          :key="index"
+          @click="currentType = item.value"
+        >
+          <i class="iconfont icon-tupian"></i>
+          <span>{{ item.label }}</span>
+          <p class="count-num" v-show="count[item.value] > 0">
+            {{ count[item.value] }}
+          </p>
+        </div>
+      </div>
+      <div class="material-box">
+        <div
+          class="material-container"
+          v-for="(item, index) in image_list"
+          :key="index"
+        >
+          <div
+            :class="{
+              'type-item': true,
+              'video-type':
+                item.image_mode === 'CREATIVE_IMAGE_MODE_VIDEO_VERTICAL' ||
+                item.image_mode === 'CREATIVE_IMAGE_MODE_VIDEO',
+              'video-type1':
+                item.image_mode === 'CREATIVE_IMAGE_MODE_VIDEO_VERTICAL',
+              'video-type2': item.image_mode === 'CREATIVE_IMAGE_MODE_VIDEO',
+              'image-type':
+                item.image_mode === 'CREATIVE_IMAGE_MODE_LARGE_VERTICAL' ||
+                item.image_mode === 'CREATIVE_IMAGE_MODE_LARGE' ||
+                item.image_mode === 'CREATIVE_IMAGE_MODE_SMALL',
+              'image-type1':
+                item.image_mode === 'CREATIVE_IMAGE_MODE_LARGE_VERTICAL',
+              'image-type2': item.image_mode === 'CREATIVE_IMAGE_MODE_LARGE',
+              'image-type3': item.image_mode === 'CREATIVE_IMAGE_MODE_SMALL',
+            }"
+            @mouseenter="item.delete_cover = true"
+            @mouseleave="item.delete_cover = false"
+          >
+            <i
+              class="iconfont icon-guanbi1"
+              @click="deleteImageListItem(item, index)"
+              v-show="item.delete_cover"
+            ></i>
+            <div
+              @mouseenter="item.video_cover = true"
+              @mouseleave="item.video_cover = false"
+              class="video-box"
+              v-if="
+                item.image_mode === 'CREATIVE_IMAGE_MODE_VIDEO_VERTICAL' ||
+                item.image_mode === 'CREATIVE_IMAGE_MODE_VIDEO'
+              "
+            >
+              <div class="cover" v-show="item.video_cover">
+                <a-button size="small">视频库</a-button>
+              </div>
+            </div>
+            <div
+              class="image-box"
+              @mouseenter="item.image_cover = true"
+              @mouseleave="item.image_cover = false"
+            >
+              <div class="cover" v-show="item.image_cover">
+                <p
+                  style="text-align: center"
+                  v-if="
+                    item.image_mode === 'CREATIVE_IMAGE_MODE_VIDEO_VERTICAL' ||
+                    item.image_mode === 'CREATIVE_IMAGE_MODE_VIDEO'
+                  "
+                >
+                  <a-button size="small">生成封面</a-button>
+                  <a-button size="small">图片库</a-button>
+                </p>
+                <a-button size="small" v-else>图片库</a-button>
+              </div>
+            </div>
+          </div>
+        </div>
+
+        <!-- <div class="material-container">
+          <div class="type-item video-type video-type1">
+            <i class="iconfont icon-guanbi1"></i>
+            <div class="video-box">
+              <div class="cover">
+                <a-button size="small">视频库</a-button>
+              </div>
+            </div>
+            <div class="image-box">
+              <div class="cover">
+                <p style="text-align: center">
+                  <a-button size="small">生成封面</a-button>
+                  <a-button size="small">图片库</a-button>
+                </p>
+              </div>
+            </div>
+          </div>
+        </div>
+        <div class="material-container">
+          <div class="type-item video-type video-type2">
+            <i class="iconfont icon-guanbi1"></i>
+            <div class="video-box">
+              <div class="cover">
+                <a-button size="small">视频库</a-button>
+              </div>
+            </div>
+            <div class="image-box">
+              <div class="cover">
+                <p style="text-align: center">
+                  <a-button size="small">生成封面</a-button>
+                  <a-button size="small">图片库</a-button>
+                </p>
+              </div>
+            </div>
+          </div>
+        </div>
+        <div class="material-container">
+          <div class="type-item image-type image-type1">
+            <i class="iconfont icon-guanbi1"></i>
+            <div class="image-box">
+              <div class="cover">
+                <a-button size="small">图片库</a-button>
+              </div>
+            </div>
+          </div>
+        </div>
+        <div class="material-container">
+          <div class="type-item image-type image-type2">
+            <i class="iconfont icon-guanbi1"></i>
+            <div class="image-box">
+              <div class="cover">
+                <a-button size="small">图片库</a-button>
+              </div>
+            </div>
+          </div>
+        </div>
+        <div class="material-container">
+          <div class="type-item image-type image-type3">
+            <i class="iconfont icon-guanbi1"></i>
+            <div class="image-box">
+              <div class="cover">
+                <a-button size="small">图片库</a-button>
+              </div>
+            </div>
+          </div>
+        </div> -->
+        <div class="add-btn" @click="addMaterial">
+          <i class="iconfont icon-jia1"></i>
+          <span>添加</span>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import { defineComponent, reactive, toRefs, ref } from "vue";
+import {} from "@/api";
+import { message } from "ant-design-vue";
+
+const creativityContent = defineComponent({
+  setup() {
+    const state = reactive({
+      contentType: "PROGRAM", // 创意方式 PROGRAM-程序化创意 CUSTOM-自定义创意
+      creatives: ref<any[]>([]), // 自定义创意渲染数组
+      image_list: ref<any[]>([]), // 程序化创意渲染数组
+      currentType: "videoType1", // 当前素材类型 默认竖版视频
+      typeList: [
+        {
+          label: "竖版视频",
+          value: "videoType1",
+          mode: "CREATIVE_IMAGE_MODE_VIDEO_VERTICAL",
+        },
+        {
+          label: "横板视频",
+          value: "videoType2",
+          mode: "CREATIVE_IMAGE_MODE_VIDEO",
+        },
+        {
+          label: "大图竖图",
+          value: "imageType1",
+          mode: "CREATIVE_IMAGE_MODE_LARGE_VERTICAL",
+        },
+        {
+          label: "大图横图",
+          value: "imageType2",
+          mode: "CREATIVE_IMAGE_MODE_LARGE",
+        },
+        {
+          label: "小图",
+          value: "imageType3",
+          mode: "CREATIVE_IMAGE_MODE_SMALL",
+        },
+      ],
+      count: {
+        videoType1: 0, // 竖版视频
+        videoType2: 0, // 横板视频
+        imageType1: 0, // 大图竖图
+        imageType2: 0, // 大图横图
+        imageType3: 0, // 小图
+      }, // 素材类型计数
+    });
+    return { ...toRefs(state) };
+  },
+  mounted() {},
+  methods: {
+    // 程序化-添加创意
+    addMaterial() {
+      console.log("添加创意");
+      if (this.contentType === "PROGRAM") {
+        let mode = "";
+        this.typeList.forEach((item) => {
+          if (item.value === this.currentType) mode = item.mode;
+        });
+        switch (mode) {
+          case "CREATIVE_IMAGE_MODE_VIDEO_VERTICAL":
+            this.count.videoType1++;
+            break;
+          case "CREATIVE_IMAGE_MODE_VIDEO":
+            this.count.videoType2++;
+            break;
+          case "CREATIVE_IMAGE_MODE_LARGE_VERTICAL":
+            this.count.imageType1++;
+            break;
+          case "CREATIVE_IMAGE_MODE_LARGE":
+            this.count.imageType2++;
+            break;
+          case "CREATIVE_IMAGE_MODE_SMALL":
+            this.count.imageType3++;
+            break;
+        }
+        console.log(this.count.videoType1);
+        this.image_list.push({
+          image_mode: mode,
+          image_id: 0,
+          video_id: 0,
+          image_url: "",
+          video_url: "",
+          image_cover: false,
+          video_cover: false,
+          delete_cover: false,
+        });
+      }
+    },
+    // 程序化-删除创意
+    deleteImageListItem(item: any, index: any) {
+      this.image_list.splice(index, 1);
+      switch (item.image_mode) {
+        case "CREATIVE_IMAGE_MODE_VIDEO_VERTICAL":
+          this.count.videoType1--;
+          break;
+        case "CREATIVE_IMAGE_MODE_VIDEO":
+          this.count.videoType2--;
+          break;
+        case "CREATIVE_IMAGE_MODE_LARGE_VERTICAL":
+          this.count.imageType1--;
+          break;
+        case "CREATIVE_IMAGE_MODE_LARGE":
+          this.count.imageType2--;
+          break;
+        case "CREATIVE_IMAGE_MODE_SMALL":
+          this.count.imageType3--;
+          break;
+      }
+    },
+  },
+});
+// 要传的
+// 自定义创意:creatives: [{
+//   image_mode: '', // 素材类型
+//   title: '', // 创意标题
+//   image_id: 0, // 图片id(视频封面id)
+//   video_id: 0, // 视频id
+// }]
+// 程序化创意:image_list:[{
+//   image_mode:'', // 素材类型
+//   image_id: 0, // 图片id(视频封面id)
+//   video_id: 0, // 视频id
+// }]
+// 小图 CREATIVE_IMAGE_MODE_SMALL 横板大图 CREATIVE_IMAGE_MODE_LARGE 竖版大图 CREATIVE_IMAGE_MODE_LARGE_VERTICAL
+// 竖版视频 CREATIVE_IMAGE_MODE_VIDEO_VERTICAL 横板视频 CREATIVE_IMAGE_MODE_VIDEO
+// 传之前遍历删除imagr_url\video_url\video_cover\image_cover\delete_cover
+
+export default creativityContent;
+</script>
+<style lang="scss" scoped>
+.creativity-content {
+  .common-type {
+    width: 800px;
+    min-height: 300px;
+    padding: 0 10px;
+  }
+  .program-type {
+    border: 2px solid rgb(230, 230, 230);
+    border-radius: 4px;
+  }
+  .type-box {
+    width: 100%;
+    height: 80px;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    .type-item {
+      width: 146px;
+      height: 80px;
+      border: 2px solid rgb(200, 200, 200);
+      border-radius: 4px;
+      display: flex;
+      align-items: center;
+      justify-content: space-around;
+      cursor: pointer;
+      position: relative;
+      i {
+        font-size: 40px;
+        color: rgb(189, 187, 187);
+      }
+      .count-num {
+        color: white;
+        position: absolute;
+        top: 0;
+        right: 0;
+        width: 18px;
+        height: 18px;
+        line-height: 18px;
+        text-align: center;
+        background: rgb(105, 105, 255);
+      }
+    }
+    .current-type {
+      border: 2px solid rgb(83, 115, 255);
+    }
+  }
+  .material-box {
+    overflow: hidden;
+    margin-top: 20px;
+    padding-bottom: 10px;
+    .add-btn {
+      width: 100px;
+      height: 100px;
+      background: rgb(243, 243, 243);
+      border: 2px dashed rgb(200, 200, 200);
+      border-radius: 4px;
+      text-align: center;
+      float: left;
+      cursor: pointer;
+      i {
+        font-size: 20px;
+        color: gray;
+        display: block;
+        line-height: 20px;
+        margin-top: 36px;
+      }
+      span {
+        display: block;
+      }
+    }
+    .material-container {
+      width: 244px;
+      height: 160px;
+      // background: rgb(211, 211, 211);
+      float: left;
+      margin: 0 20px 20px 0;
+      border: 1px dashed rgb(214, 214, 214);
+      .type-item {
+        cursor: pointer;
+        position: relative;
+        .icon-guanbi1 {
+          position: absolute;
+          top: -12px;
+          right: 0;
+          opacity: 0.7;
+          z-index: 1000;
+          &:hover {
+            color: red;
+          }
+        }
+        .video-box,
+        .image-box {
+          position: relative;
+          display: flex;
+          align-items: center;
+          justify-content: center;
+        }
+        .cover {
+          width: 100%;
+          height: 100%;
+          position: absolute;
+          top: 0;
+          left: 0;
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          background: rgba(0, 0, 0, 0.301);
+          p {
+            line-height: 28px;
+          }
+          .ant-btn {
+            width: 80px;
+            font-size: 13px;
+          }
+        }
+      }
+      .video-type {
+        padding: 0 4px;
+        background: rgb(219, 219, 219);
+        display: flex;
+        justify-content: space-around;
+        align-items: center;
+        div {
+          background: rgb(241, 241, 241);
+        }
+      }
+      .video-type1 {
+        height: 100%;
+        div {
+          width: 110px;
+          height: 140px;
+        }
+      }
+      .video-type2 {
+        margin-top: 25px;
+        height: 100px;
+        div {
+          width: 110px;
+          height: 80px;
+        }
+      }
+      .image-type {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        background: rgb(219, 219, 219);
+        .image-box {
+          background: rgb(241, 241, 241);
+        }
+      }
+      .image-type1 {
+        width: 120px;
+        height: 100%;
+        margin: 0 auto;
+        .image-box {
+          width: 100px;
+          height: 140px;
+        }
+      }
+      .image-type2 {
+        width: 100%;
+        height: 100%;
+        margin: 0 auto;
+        .image-box {
+          width: 224px;
+          height: 140px;
+        }
+      }
+      .image-type3 {
+        width: 140px;
+        height: 100px;
+        margin: 30px auto;
+        .image-box {
+          width: 120px;
+          height: 80px;
+        }
+      }
+    }
+    .material-container:nth-child(3n) {
+      margin-right: 0;
+    }
+  }
+}
+</style>

+ 15 - 3
src/views/put/plan-create-index.vue

@@ -117,7 +117,7 @@ const PlanCreate = defineComponent({
       );
       console.log("STEP1+1");
       if (this.current === 0) this.current++;
-      window.localStorage.setItem("current-step", String(this.current));
+      this.setCurrent();
     });
     Bus.$on("stepTwoBack", (val: any) => {
       // 第一步校验完成 携带account_id跳转创建广告组页面
@@ -126,7 +126,7 @@ const PlanCreate = defineComponent({
       );
       console.log("STEP2+1");
       if (this.current === 1) this.current++;
-      window.localStorage.setItem("current-step", String(this.current));
+      this.setCurrent();
     });
     Bus.$on("stepThreeBack", (val?: any) => {
       // 第一步校验完成 携带account_id跳转创建广告组页面
@@ -135,7 +135,16 @@ const PlanCreate = defineComponent({
       );
       console.log("STEP3+1");
       if (this.current === 2) this.current++;
-      window.localStorage.setItem("current-step", String(this.current));
+      this.setCurrent();
+    });
+    Bus.$on("stepFourBack", (val?: any) => {
+      // 第一步校验完成 携带account_id跳转创建广告组页面
+      this.$router.push(
+        "/put/plan-create/" + this.routerList[4] + "?plan_id=" + val
+      );
+      console.log("STEP4+1");
+      if (this.current === 3) this.current++;
+      this.setCurrent();
     });
   },
   methods: {
@@ -161,6 +170,9 @@ const PlanCreate = defineComponent({
       window.localStorage.setItem("current-step", String(this.current));
       this.$router.push("/put/plan-create/" + this.routerList[this.current]);
     },
+    setCurrent() {
+      window.localStorage.setItem("current-step", String(this.current));
+    },
   },
   // beforeUnmount() {
   //   Bus.$off("stepOneCheck");

+ 67 - 6
src/views/put/plan-create/creativity-add.vue

@@ -1,22 +1,83 @@
 <template>
-  <div class="creativity-add">添加创意</div>
+  <div class="creativity-add">
+    <div class="part-box">
+      <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></creativity-content>
+        </a-form-item>
+      </a-form>
+    </div>
+    <div class="part-box">
+      <h3 class="title">创意分类</h3>
+    </div>
+  </div>
 </template>
 
 <script lang="ts">
-import { defineComponent, reactive, toRefs } from "vue";
+import { defineComponent, reactive, toRefs, ref } from "vue";
 import {} from "@/api";
+import Bus from "@/utils/bus";
 import { message } from "ant-design-vue";
+import creativityContent from "../component/creativity-content.vue";
 
 const CreativityAdd = defineComponent({
+  components: { creativityContent },
   setup() {
-    const state = reactive({});
-    return { ...toRefs(state) };
+    const state = reactive({
+      creativityAdd: {
+        creative_material_mode: "STATIC_ASSEMBLE", // 创意方式,当值为"STATIC_ASSEMBLE"表示程序化创意,其他情况不传字段
+        creatives: ref<any[]>([]), //自定义素材信息, 最多支持10个创意。首选投放位置和创意类型决定素材规格。当为程序化创意时,该字段不填数据,值为[]
+        title_list: [
+          {
+            title: "", // 标题
+          },
+        ], // 程序化创意时传 自定义不传
+      },
+      creativityClassify: {},
+    });
+    return { ...toRefs(state), labelCol: { span: 3 }, wrapperCol: { span: 8 } };
+  },
+  mounted() {
+    Bus.$on("stepFourCheck", (val?: any) => {
+      console.log("Step4Check");
+      Bus.$emit("stepFourBack");
+    });
+  },
+  methods: {
+    // 提交前数据处理
+    beforeCommit() {
+      let data: any = { ...this.creativityAdd };
+      // 1.创意方式,当值为"STATIC_ASSEMBLE"表示程序化创意,其他情况不传字段
+      if (data.creative_material_mode === "CUSTOM")
+        delete data.creative_material_mode;
+    },
+    // 渲染前数据处理
+    beforeBackshow(creativityOrigin: any) {
+      // 1.创意方式页面
+      if (!creativityOrigin.creative_material_mode)
+        creativityOrigin.creative_material_mode = "CUSTOM";
+    },
+  },
+  beforeUnmount() {
+    Bus.$off("stepFourCheck");
   },
-  mounted() {},
-  methods: {},
 });
 
 export default CreativityAdd;
 </script>
 <style lang="scss" scoped>
+.creativity-add {
+  .title {
+    line-height: 30px;
+    font-weight: bold;
+    padding-left: 10px;
+  }
+}
 </style>

+ 245 - 79
src/views/put/plan-create/plan-edit.vue

@@ -17,13 +17,13 @@
           </a-select>
         </a-form-item>
         <a-form-item label="落地页">
-          <a-select placeholder="请选择">
+          <a-select placeholder="请选择" v-model:value="plan.external_url">
             <a-select-option value="shanghai">Zone one</a-select-option>
             <a-select-option value="beijing">Zone two</a-select-option>
           </a-select>
         </a-form-item>
         <a-form-item label="直达链接内容">
-          <a-input placeholder="选填" />
+          <a-input placeholder="选填" v-model:value="plan.open_url" />
         </a-form-item>
       </a-form>
     </div>
@@ -40,7 +40,7 @@
           </a-radio-group>
         </a-form-item>
         <a-form-item label="搜索快投关键词">
-          <a-switch />
+          <a-switch v-model:checked="plan.feed_delivery_search" />
         </a-form-item>
       </a-form>
     </div>
@@ -50,132 +50,146 @@
       <h1>用户定向</h1>
       <a-form :label-col="labelCol" :wrapper-col="wrapperCol">
         <a-form-item label="定向方式">
-          <a-radio-group>
-            <a-radio value="1">新建定向</a-radio>
-            <a-radio value="2">选择已有定向包</a-radio>
+          <a-radio-group v-model:value="userTarget.directType">
+            <a-radio value="BUILD">新建定向</a-radio>
+            <a-radio value="SELECT">选择已有定向包</a-radio>
           </a-radio-group>
         </a-form-item>
         <!-- 地域组件 -->
         <a-form-item label="地域">
+          <!-- 组件数据接入DDD -->
           <location :checkedCity="'[]'"></location>
         </a-form-item>
         <a-form-item label="性别">
-          <a-radio-group>
-            <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 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>
-            <a-checkbox value="0">不限</a-checkbox>
-            <a-checkbox value="1">18-23</a-checkbox>
-            <a-checkbox value="2">24-30</a-checkbox>
+          <a-checkbox-group v-model:value="plan.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>
-            <a-radio-button value="0">不限</a-radio-button>
-            <a-radio-button value="1">自定义人群</a-radio-button>
+          <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 :compType="'crowd'"></direction-exclusion>
         </a-form-item>
         <a-form-item label="行为兴趣">
-          <a-radio-group>
-            <a-radio-button value="0">不限</a-radio-button>
-            <a-radio-button value="1">系统推荐</a-radio-button>
+          <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-form-item label="媒体定向" v-model:value="userTarget.mediaTarget">
           <a-radio-group>
-            <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-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 :compType="'media'"></direction-exclusion>
         </a-form-item>
         <a-form-item label="平台">
-          <a-checkbox-group>
-            <a-checkbox value="0">不限</a-checkbox>
-            <a-checkbox value="1">ios</a-checkbox>
-            <a-checkbox value="2">Android</a-checkbox>
-            <a-checkbox value="3">pc</a-checkbox>
+          <a-checkbox-group v-model:value="plan.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>
-            <a-checkbox value="0">不限</a-checkbox>
-            <a-checkbox value="1">智能手机</a-checkbox>
-            <a-checkbox value="2">平板</a-checkbox>
+          <a-checkbox-group v-model:value="plan.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>
-            <a-checkbox value="0">不限</a-checkbox>
-            <a-checkbox value="1">Wi-Fi</a-checkbox>
-            <a-checkbox value="2">2G</a-checkbox>
-            <a-checkbox value="3">3G</a-checkbox>
-            <a-checkbox value="4">4G</a-checkbox>
+          <a-checkbox-group v-model:value="plan.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>
-            <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 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>
-            <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-button value="3">广告账户</a-radio-button>
-            <a-radio-button value="4">公司账户</a-radio-button>
+          <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="过滤时间">
-          <a-radio-group>
-            <a-radio-button value="0">当天</a-radio-button>
-            <a-radio-button value="1">7天</a-radio-button>
-            <a-radio-button value="2">1个月</a-radio-button>
-            <a-radio-button value="3">3个月</a-radio-button>
-            <a-radio-button value="4">6个月</a-radio-button>
-            <a-radio-button value="5">12个月</a-radio-button>
+        <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>
-            <a-radio-button value="0">不限</a-radio-button>
-            <a-radio-button value="1">文章分类</a-radio-button>
+          <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 :compType="1"></check-box>
         </a-form-item>
         <a-form-item label="运营商">
-          <a-checkbox-group>
-            <a-checkbox value="0">不限</a-checkbox>
-            <a-checkbox value="1">移动</a-checkbox>
-            <a-checkbox value="2">联通</a-checkbox>
-            <a-checkbox value="3">电信</a-checkbox>
+          <a-checkbox-group v-model:value="plan.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>
-            <a-checkbox value="0">不限</a-checkbox>
-            <a-checkbox value="1">一个月以内</a-checkbox>
-            <a-checkbox value="2">一个月到三个月</a-checkbox>
-            <a-checkbox value="3">三个月以上</a-checkbox>
+          <a-checkbox-group v-model:value="plan.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>
-            <a-radio-button value="0">不限</a-radio-button>
-            <a-radio-button value="1">手机品牌</a-radio-button>
+          <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 :compType="2"></check-box>
         </a-form-item>
         <a-form-item label="手机价格">
@@ -189,14 +203,48 @@
             :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
+          >
         </a-form-item>
         <!-- 职业状态 -->
         <a-form-item label="职业状态">
-          <a-radio-group>
-            <a-radio-button value="0">不限</a-radio-button>
-            <a-radio-button value="1">职业状态</a-radio-button>
+          <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 :compType="3"></check-box>
         </a-form-item>
         <!-- 智能放量 -->
@@ -286,7 +334,7 @@
 </template>
 
 <script lang="ts">
-import { defineComponent, reactive, toRefs } from "vue";
+import { defineComponent, reactive, toRefs, ref } from "vue";
 import {} from "@/api";
 import Bus from "@/utils/bus";
 import TimeSchedule from "../component/time-schedule.vue";
@@ -305,7 +353,60 @@ const PlanEdit = defineComponent({
   },
   setup() {
     const state = reactive({
-      plan: {},
+      // 页面变量
+      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
+      },
+      plan: {
+        // part1 优化目标----------------------------------------------------
+        external_url: "", // 落地页
+        open_url: "", // 直达链接内容
+        // part2 投放位置----------------------------------------------------
+        feed_delivery_search: true, // 搜索快投关键词
+        // part3 用户定向----------------------------------------------------
+        district: "", // 地域类型
+        city: ref<any[]>([]), // 选中的城市或区县
+        gender: "", // 性别
+        age: ref<any[]>([]), // 年龄
+        retargeting_tags_include: ref<any[]>([]), // 定向人群
+        retargeting_tags_exclude: ref<any[]>([]), //排除人群
+        interest_action_mode: "", // 行为兴趣
+        superior_popularity_type: "", // 媒体定向类型 、、 选择自定义媒体包时本字段不传
+        flow_package: ref<any[]>([]), // 定向流量包
+        exclude_flow_package: ref<any[]>([]), // 排除流量包
+        platform: ref<any[]>([]), // 平台-字符串数组
+        device_type: ref<any[]>([]), // 设备类型 不限不传
+        ac: ref<any[]>([]), // 网络
+        hide_if_exists: 0, // 已安装用户 0-不限 1-过滤 2-定向
+        hide_if_converted: "AD", // 过滤已转化用户 默认AD广告计划
+        converted_time_duration: "", // 过滤时间
+        article_category: ref<any[]>([]), // 文章分类
+        carrier: ref<any[]>([]), // 运营商
+        activate_type: ref<any[]>([]), // 新用户
+        device_brand: ref<any[]>([]), // 手机品牌
+        launch_price: ref<any[]>([0, 11000]), // 手机价格-number[]
+        career: ref<any[]>([]), // 职业状态-string[]
+        auto_extend_enabled: 0, // 智能放量
+        // part4 预算与出价---------------------------------------
+        smart_bid_type: "", // 投放场景
+        flow_control_mode: "", // 竞价策略
+        budget_mode: "", // 预算类型
+        budget: 0, // 预算
+        schedule_type: "", // 投放时间类型
+        start_time: "", // 投放开始时间
+        end_time: "", // 投放结束时间
+        schedule_time: "", // 投放时段
+        pricing: "", // 付费方式
+        cpa_bid: "", // 目标转化出价
+        // part5 第三方检测---------------------------------------
+        // part6 计划名称---------------------------------------
+      },
       phonePriceMarks: PriceSlider, //手机价格区间
     });
     return {
@@ -320,7 +421,72 @@ const PlanEdit = defineComponent({
       Bus.$emit("stepThreeBack");
     });
   },
-  methods: {},
+  methods: {
+    // 提交前处理数据
+    beforeCommit() {
+      let data: any = {};
+      data = JSON.parse(JSON.stringify(this.plan));
+      // 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
+      //   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;
+      // 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;
+    },
+    // 回显之前处理数据
+    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  字段判断页面变量文章分类
+      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";
+    },
+  },
   beforeUnmount() {
     Bus.$off("stepThreeCheck");
   },