소스 검색

✨ feat: 新增sp新建广告活动-关键词定向

WanGxC 1 년 전
부모
커밋
061c1424fe
1개의 변경된 파일119개의 추가작업 그리고 35개의 파일을 삭제
  1. 119 35
      src/views/adManage/sp/campaigns/CreateCampaigns/index.vue

+ 119 - 35
src/views/adManage/sp/campaigns/CreateCampaigns/index.vue

@@ -394,7 +394,6 @@
             </el-radio-group>
           </div>
           <!-- 关键词定向 -->
-          <!-- TODO: 未完成 不知道有什么用 -->
           <div
             style="font-size: 20px; font-weight: bold; margin-top: 30px"
             v-if="ruleForm.targetType == 'keyWords' && campaignRuleForm.type == 'MANUAL'">
@@ -411,13 +410,13 @@
                       <el-select v-model="bidType" class="m-2" placeholder="Select" style="width: 450px">
                         <el-option v-for="item in bidTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
                       </el-select>
-                      <el-input v-model="bidInput" placeholder="Please input">
+                      <el-input v-model="bidInput" :disabled="!(bidType == 'customBid')" placeholder="Please input">
                         <template #prepend>$</template>
                       </el-input>
                     </div>
                     <div style="display: flex">
                       <span style="margin: 0 10px 0 8px; font-weight: 500; color: #616266">匹配类型: </span>
-                      <el-checkbox v-model="widelyType" label="广泛" />
+                      <el-checkbox v-model="broadType" label="广泛" />
                       <el-checkbox v-model="phraseType" label="词组" />
                       <el-checkbox v-model="exactType" label="精确" />
                     </div>
@@ -436,8 +435,10 @@
                     </el-table>
                   </el-tab-pane>
                   <el-tab-pane label="输入" name="second">
-                    <el-input v-model="keyWordsTextarea" :rows="10" type="textarea" placeholder="未完成" style="padding-left: 5px" />
-                    <el-button type="primary" size="small" text bg @click="addKeyWords">添加</el-button>
+                    <el-input v-model="keyWordsTextarea" :rows="10" type="textarea" style="padding-left: 5px" />
+                    <div style="display: flex; flex-direction: row-reverse; margin-top: 10px">
+                      <el-button type="primary" text bg @click="addKeyWords">添加</el-button>
+                    </div>
                   </el-tab-pane>
                 </el-tabs>
               </div>
@@ -445,8 +446,10 @@
                 <el-card class="box-card" shadow="never" style="border: none">
                   <template #header>
                     <div class="card-header">
-                      <span style="font-weight: 550; font-size: 15px; color: #1f2128">已添加: {{ addedData.length }}</span>
-                      <el-button class="button" text bg @click="delAllKeyWords">全部删除</el-button>
+                      <span style="font-weight: 550; font-size: 15px; color: #1f2128">已添加: {{ addedKeyWordsTableData.length }}</span>
+                      <span style="color: #529b2e">成功: {{ successCount }}</span>
+                      <span style="color: #c45656">失败: {{ errorCount }}</span>
+                      <el-button class="button" type="danger" text bg @click="delAllKeyWords">全部删除</el-button>
                     </div>
                   </template>
                   <div class="card-body" body-style="padding-bottom: -20px;">
@@ -456,9 +459,18 @@
                       :header-row-style="changeKeyWordsTableHeader"
                       :header-cell-style="headerCellStyle">
                       <el-table-column prop="keyword" label="关键词" width="auto" />
-                      <el-table-column prop="bid" label="出价" />
+                      <el-table-column prop="matchType" label="匹配类型" />
+                      <el-table-column prop="bid" label="出价">
+                        <template #default="scope">
+                          <el-input v-model="scope.row.bid" placeholder="Please input bid" />
+                        </template>
+                      </el-table-column>
                       <el-table-column prop="suggestBid" label="建议出价" />
-                      <el-table-column prop="operate" label="操作" width="60" align="right" />
+                      <el-table-column prop="operate" label="操作" width="60" align="right">
+                        <template #default="scope">
+                          <el-button type="danger" size="small" link @click="delSingleKeyWord(scope)">删除</el-button>
+                        </template>
+                      </el-table-column>
                     </el-table>
                   </div>
                 </el-card>
@@ -914,9 +926,6 @@ const select = ref('name')
 const select2 = ref('latest')
 const buttons = [{ type: 'primary', text: '添加' }] as const
 const negativeInput = ref('')
-let widelyType = ref(true)
-let phraseType = ref(true)
-let exactType = ref(true)
 
 // 表单相关数据
 const campaignLoading = ref(false)
@@ -1274,7 +1283,7 @@ function handleGoodsAdd() {
 }
 // 点击Tab
 const handleGoodsTabs = (tab: TabsPaneContext, event: Event) => {
-  console.log(tab, event)
+  // console.log(tab, event)
 }
 
 function isItemInList(item, list) {
@@ -1925,7 +1934,6 @@ async function productTagetSave() {
 // ------------------------------------------关键词定向模块------------------------------------------
 const bidType = ref('customBid')
 const bidTypeOptions = [
-  // 竞价select下拉选项
   {
     value: 'suggestBid',
     label: '建议出价',
@@ -1944,6 +1952,31 @@ const bidInput = ref('0.75')
 const keyWordsTableData = ref([]) // 关键词定向左侧表格数据
 const addedKeyWordsTableData = ref([]) // 关键词定向右侧表格数据
 const keyWordsTextarea = ref('')
+let broadType = ref(true)
+let phraseType = ref(true)
+let exactType = ref(true)
+const MATCH_TYPE = {
+  BROAD: '广泛',
+  PHRASE: '词组',
+  EXACT: '精确',
+}
+const MATCH_TYPE_MAP = {
+  广泛: 'BROAD',
+  词组: 'PHRASE',
+  精确: 'EXACT',
+}
+const successCount = ref('')
+const errorCount = ref('')
+
+watch(bidType, () => {
+  if (bidType.value === 'defaultBid') {
+    bidInput.value = adGroupRuleForm.defaultBidInp
+  } else if (bidType.value === 'customBid') {
+    bidInput.value = ''
+  } else {
+    bidInput.value = ''
+  }
+})
 
 function addKeyWords() {
   const trimmedText = keyWordsTextarea.value.trim()
@@ -1952,26 +1985,56 @@ function addKeyWords() {
   items.forEach((item) => {
     const trimmedItem = item.trim()
     if (trimmedItem) {
-      let keyWordEntry = {
-        keyword: trimmedItem,
-        matchType: '广泛', // 或者其他匹配类型,根据你的具体需求来设置
-        bid: bidInput.value, // 使用用户输入的出价或默认出价
+      if (broadType.value) {
+        addKeyWordEntry(trimmedItem, MATCH_TYPE.BROAD)
       }
-
-      if (!addedKeyWordsTableData.value.some((n) => n.keyword === keyWordEntry.keyword)) {
-        addedKeyWordsTableData.value.push(keyWordEntry)
-      } else {
-        console.log('关键词已存在,未被添加到列表中')
+      if (phraseType.value) {
+        addKeyWordEntry(trimmedItem, MATCH_TYPE.PHRASE)
+      }
+      if (exactType.value) {
+        addKeyWordEntry(trimmedItem, MATCH_TYPE.EXACT)
       }
     } else {
-      console.log('有空项目,未被添加到列表中')
+      ElMessage({
+        message: '有空项目,未被添加到列表中',
+        type: 'warning',
+      })
     }
   })
   keyWordsTextarea.value = ''
 }
 
+function addKeyWordEntry(keyword, matchType) {
+  let bidValue
+  switch (bidType.value) {
+    case 'customBid':
+      bidValue = bidInput.value
+      break
+    case 'defaultBid':
+      bidValue = adGroupRuleForm.defaultBidInp
+      break
+    default:
+      bidValue = ''
+  }
+
+  let keyWordEntry = {
+    keyword: keyword,
+    matchType: matchType,
+    bid: bidInput.value,
+  }
+
+  if (!addedKeyWordsTableData.value.some((n) => n.keyword === keyWordEntry.keyword && n.matchType === keyWordEntry.matchType)) {
+    addedKeyWordsTableData.value.push(keyWordEntry)
+  } else {
+    ElMessage({
+      message: `关键词 ${keyword} (${matchType}) 已存在,未被添加到列表中`,
+      type: 'warning',
+    })
+  }
+}
+
 function delSingleKeyWord(scope) {
-  const index = addedKeyWordsTableData.value.findIndex((item) => item.keyword === scope.row.keyword)
+  const index = addedKeyWordsTableData.value.findIndex((item) => item.keyword === scope.row.keyword && item.matchType === scope.row.matchType)
   if (index !== -1) {
     addedKeyWordsTableData.value.splice(index, 1)
   } else {
@@ -1984,15 +2047,38 @@ function delAllKeyWords() {
 }
 
 async function keyWordsSave() {
-  // 假设你需要保存这些关键词到服务器
+  successCount.value = ''
+  errorCount.value = ''
+  const keywordList = addedKeyWordsTableData.value.map((kw) => ({
+    keywordText: kw.keyword,
+    bid: kw.bid,
+    matchType: MATCH_TYPE_MAP[kw.matchType],
+  }))
+  const requestData = {
+    profile_id: profile.value.profile_id,
+    campaignId: respCampaignId.value,
+    adGroupId: respAdGroupId.value,
+    keywordlist: keywordList,
+    state: 'PAUSED',
+  }
+  const filteredRequestData = Object.fromEntries(Object.entries(requestData).filter(([_, v]) => v != null))
   try {
-    const requestData = {
-      // ...其他需要的数据...
-      keywords: addedKeyWordsTableData.value,
+    const resp = await request({
+      url: '/api/ad_manage/sptargets/add/keywords/',
+      method: 'POST',
+      data: filteredRequestData,
+    })
+    if (resp.data.success.length !== 0) {
+      ElMessage({
+        message: '关键词创建成功',
+        type: 'success',
+      })
+      successCount.value = resp.data.success.length
+      errorCount.value = resp.data.error.length
+      delAllKeyWords()
+    } else {
+      ElMessage.error('关键词创建失败!')
     }
-    // 发送请求...
-    console.log('请求发送成功,关键词已保存', requestData)
-    delAllKeyWords()
   } catch (error) {
     console.error('请求失败:', error)
   }
@@ -2194,7 +2280,6 @@ function handleNegGoodsTabs(tab: TabsPaneContext, event: Event) {
 async function negativeGoodsSave() {
   console.log(addedNegetiveTableData.value)
   const asinList = addedNegetiveTableData.value.map((item) => item.asin)
-  console.log('🚀 ~ negativeGoodsSave ~ asinList-->>', asinList)
   negativeGoodsLoading.value = true
   console.log('addedNegetiveTableData', addedNegetiveTableData.value)
   try {
@@ -2212,7 +2297,6 @@ async function negativeGoodsSave() {
       method: 'POST',
       data: filteredRequestData,
     })
-    console.log('🚀 ~ negativeWordsSave ~ resp-->>', resp)
     negativeGoodsLoading.value = false
     if (resp.data.success.length !== 0) {
       ElMessage({
@@ -2347,7 +2431,7 @@ defineOptions({
 </script>
 
 <style lang="scss" scoped>
-::v-deep(.el-form--default.el-form--label-top .el-form-item .el-form-item__label) {
+:deep(.el-form--default.el-form--label-top .el-form-item .el-form-item__label) {
   font-weight: 500;
 }
 .column-item .el-radio-group {