|
@@ -351,7 +351,7 @@
|
|
|
<div>
|
|
|
<el-radio label="Goods" style="align-items: flex-start; margin-top: 20px">
|
|
|
<div style="margin-top: -4px">商品投放</div>
|
|
|
- <div>选择关键词以帮助您的商品出现在购物者搜索中</div>
|
|
|
+ <div>选择特定的商品, 分类, 品牌或者其他商品功能来定向您的广告</div>
|
|
|
</el-radio>
|
|
|
</div>
|
|
|
</el-radio-group>
|
|
@@ -483,10 +483,12 @@
|
|
|
<div style="font-size: 20px; font-weight: bold; margin-top: 30px" v-if="ruleForm.targetType == 'Goods'">商品定向</div>
|
|
|
<hr v-if="ruleForm.targetType == 'Goods'" />
|
|
|
<el-form-item style="width: 100%; margin-top: 20px" v-if="ruleForm.targetType == 'Goods'">
|
|
|
- <div style="width: 100%; height: 520px; display: flex; border: 1px solid #c2c7cf; border-radius: 6px" v-loading="productOrientationLoading">
|
|
|
+ <div
|
|
|
+ style="width: 100%; height: 520px; display: flex; border: 1px solid #c2c7cf; border-radius: 6px"
|
|
|
+ v-loading="productOrientationLoading">
|
|
|
<div style="width: 50%; border-right: 1px solid #c2c7cf">
|
|
|
- <el-tabs type="border-card" stretch class="goods-orientation-tabs" style="border-bottom-left-radius: 6px;">
|
|
|
- <el-tab-pane label="品类" style="border-top-left-radius: 6px;">
|
|
|
+ <el-tabs type="border-card" stretch class="goods-orientation-tabs" style="border-bottom-left-radius: 6px">
|
|
|
+ <el-tab-pane label="品类" style="border-top-left-radius: 6px">
|
|
|
<div style="display: flex; align-items: center">
|
|
|
<span style="width: 40px">竞价:</span>
|
|
|
<el-select v-model="categoryBiddingType" class="m-2" placeholder="Select">
|
|
@@ -500,9 +502,7 @@
|
|
|
<el-tab-pane label="建议" name="first">
|
|
|
<el-table :data="proposalTableData" style="width: 100%" height="342">
|
|
|
<el-table-column prop="proposal" label="建议" width="520">
|
|
|
- <template #header>
|
|
|
- 0建议
|
|
|
- </template>
|
|
|
+ <template #header> 0建议 </template>
|
|
|
</el-table-column>
|
|
|
<el-table-column prop="address" label="Address">
|
|
|
<template #header>
|
|
@@ -515,13 +515,63 @@
|
|
|
</el-table>
|
|
|
</el-tab-pane>
|
|
|
<el-tab-pane label="搜索" name="second">
|
|
|
- <el-input placeholder="请输入关键词过滤" />
|
|
|
- <el-table :data="searchClassifyTableData" style="width: 100%" height="309">
|
|
|
- <el-table-column prop="categorie_name" label="亚马逊分类">
|
|
|
-
|
|
|
- </el-table-column>
|
|
|
-
|
|
|
- </el-table>
|
|
|
+ <el-input placeholder="请输入关键词过滤" />
|
|
|
+ <el-scrollbar height="309px">
|
|
|
+ <el-tree :data="searchClassifyTableData" :props="defaultProps">
|
|
|
+ <template #default="{ node, data }">
|
|
|
+ <span class="custom-tree-node">
|
|
|
+ <span style="width: 75%">{{ node.label }}</span>
|
|
|
+ <span style="color: rgb(50, 108, 216)" v-if="data.ta == true">
|
|
|
+ <a @click="refine(data)"> 细化 </a>
|
|
|
+ <a style="margin-left: 8px" @click="orientate(node, data)"> 定向 </a>
|
|
|
+ </span>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-tree>
|
|
|
+ </el-scrollbar>
|
|
|
+ <el-dialog v-model="visible" :title="`细化分类: ${dialogTitle}`" >
|
|
|
+ <div style="display: flex; justify-content: space-between;">
|
|
|
+ <span>根据特定品牌、价格范围、星级和Prime配送资格,细化分类</span>
|
|
|
+ <span>
|
|
|
+ <el-checkbox v-model="dialogForm.isCount" label="显示商品数量" />
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ <el-form :model="dialogForm" :rules="dialogRules" ref="dialogFormRef" style="margin-top:20px">
|
|
|
+ <el-form-item style="padding-left: 140px;">
|
|
|
+ <span style="margin-right: 10px; color:#616266; font-weight: 500;">品牌</span>
|
|
|
+ <el-select v-model="dialogForm.dialogselectValue" placeholder="请选择">
|
|
|
+ <el-option v-for="item in dialogForm.dialogOptions" :key="item.value" :label="item.label" :value="item.value" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item prop="prices" style="padding-left: 112px; margin-top: 10px;">
|
|
|
+ <span style="margin-right: 10px; color:#616266; font-weight: 500;">价格范围</span>
|
|
|
+ <el-input-number v-model="dialogForm.prices.lowest" :min="1" :controls="false" placeholder="无最低商品价格" />
|
|
|
+ --
|
|
|
+ <el-input-number v-model="dialogForm.prices.highest" :min="1" :controls="false" placeholder="无最高商品价格" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item prop="starRating" style="padding-left: 85px; margin-top: 10px;">
|
|
|
+ <span style="margin-right: 15px; color:#616266; font-weight: 500;">查看星级评定</span>
|
|
|
+ <el-slider v-model="dialogForm.starRating" range show-stops :max="5" :marks="marks" style="width: 70%;"/>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item prop="delivery" style="padding-left: 140px; margin-top: 30px;">
|
|
|
+ <span style="margin-right: 10px; color:#616266; font-weight: 500;">配送</span>
|
|
|
+ <el-radio-group v-model="dialogForm.delivery">
|
|
|
+ <el-radio label="all" style="font-weight: 400;">具备</el-radio>
|
|
|
+ <el-radio label="eligible" style="font-weight: 400;">具备Prime资格</el-radio>
|
|
|
+ <el-radio label="diseligible" style="font-weight: 400;">不具备Prime资格</el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <template #footer>
|
|
|
+ <div style="display: flex; justify-content: space-between;">
|
|
|
+ <span v-loading="countLoadig">定位到的商品数量: {{ commodityCount[0]?.min }} - {{ commodityCount[0]?.max }}</span>
|
|
|
+ <span class="dialog-footer">
|
|
|
+ <el-button @click="visible = false">取消</el-button>
|
|
|
+ <el-button type="primary" @click="dialogFormSubmit">确定</el-button>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
</el-tab-pane>
|
|
|
</el-tabs>
|
|
|
</el-tab-pane>
|
|
@@ -711,6 +761,7 @@
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
import { onMounted, reactive, ref, computed, watch } from 'vue'
|
|
|
+import type { CSSProperties } from 'vue'
|
|
|
import { useRoute } from 'vue-router'
|
|
|
import type { FormInstance, FormRules, TabsPaneContext } from 'element-plus'
|
|
|
import { useShopInfo } from '/@/stores/shopInfo'
|
|
@@ -861,9 +912,9 @@ function handleSizeChange(newSize) {
|
|
|
|
|
|
// ------------------------------------------投放类型模块------------------------------------------
|
|
|
async function changeTargetType() {
|
|
|
- console.log(ruleForm.targetType)
|
|
|
+ // console.log(ruleForm.targetType)
|
|
|
showCard.value = ruleForm.targetType === 'keyWords'
|
|
|
- if(ruleForm.targetType === 'Goods') {
|
|
|
+ if (ruleForm.targetType === 'Goods') {
|
|
|
productOrientationLoading.value = true
|
|
|
await setProductOrientationData()
|
|
|
}
|
|
@@ -887,6 +938,67 @@ const accurate = ref(false)
|
|
|
const proposalTableData = ref([])
|
|
|
const searchClassifyTableData = ref([])
|
|
|
const productOrientationLoading = ref(false)
|
|
|
+const defaultProps = {
|
|
|
+ children: 'ch',
|
|
|
+ label: 'cna',
|
|
|
+}
|
|
|
+const countLoadig = ref(false)
|
|
|
+const visible = ref(false)
|
|
|
+let dialogTitle = ref('')
|
|
|
+let categoryId = ref('')
|
|
|
+const dialogselectValue = ref('')
|
|
|
+let dialogOptions: any = ref([])
|
|
|
+const dialogForm: any = reactive({
|
|
|
+ prices: {
|
|
|
+ lowest: undefined,
|
|
|
+ highest: undefined
|
|
|
+ },
|
|
|
+ starRating: [0,5],
|
|
|
+ dialogselectValue: [],
|
|
|
+ delivery: 'all',
|
|
|
+ isCount: false,
|
|
|
+})
|
|
|
+const dialogFormRef = ref()
|
|
|
+const dialogRules = reactive({
|
|
|
+ prices: [
|
|
|
+ { validator: validatePrices, trigger: 'blur' }
|
|
|
+ ]
|
|
|
+})
|
|
|
+
|
|
|
+interface Mark {
|
|
|
+ style: CSSProperties
|
|
|
+ label: string
|
|
|
+}
|
|
|
+type Marks = Record<number, Mark | string>
|
|
|
+const marks = reactive<Marks>({
|
|
|
+ 0: '0',
|
|
|
+ 1: '1',
|
|
|
+ 2: '2',
|
|
|
+ 3: '3',
|
|
|
+ 4: '4',
|
|
|
+ 5: '5',
|
|
|
+})
|
|
|
+let commodityCount = ref([])
|
|
|
+
|
|
|
+
|
|
|
+async function validatePrices(rule, value) {
|
|
|
+ if (value.highest !== '' && value.lowest !== '' && value.highest <= value.lowest) {
|
|
|
+ return Promise.reject('最高价格必须大于最低价格')
|
|
|
+ }
|
|
|
+ return Promise.resolve()
|
|
|
+}
|
|
|
+
|
|
|
+function dialogFormSubmit() {
|
|
|
+ dialogFormRef.value.validate((valid) => {
|
|
|
+ if (valid) {
|
|
|
+ console.log('表单提交')
|
|
|
+ visible.value = false
|
|
|
+ } else {
|
|
|
+ console.log('验证失败')
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
async function setProductOrientationData() {
|
|
|
try {
|
|
@@ -898,15 +1010,72 @@ async function setProductOrientationData() {
|
|
|
},
|
|
|
})
|
|
|
searchClassifyTableData.value = resp.data
|
|
|
- console.log('searchClassifyTableData', searchClassifyTableData.value)
|
|
|
productOrientationLoading.value = false
|
|
|
+ } catch (error) {
|
|
|
+ console.error('请求失败:', error)
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
+async function setDialogOption() {
|
|
|
+ try {
|
|
|
+ const resp = await request({
|
|
|
+ url: '/api/ad_manage/categories/brands/',
|
|
|
+ method: 'GET',
|
|
|
+ params: {
|
|
|
+ profile_id: profile.value.profile_id,
|
|
|
+ category_id: categoryId.value,
|
|
|
+ },
|
|
|
+ })
|
|
|
+ const options = resp.data
|
|
|
+ dialogForm.dialogOptions = options.brands.map(brand => {
|
|
|
+ return {
|
|
|
+ label: brand.name,
|
|
|
+ value: brand.id
|
|
|
+ }
|
|
|
+ })
|
|
|
+ console.log('🚀 ~ setDialogOption ~ dialogOptions-->>', dialogOptions)
|
|
|
} catch (error) {
|
|
|
- console.error("请求失败:", error)
|
|
|
+ console.error('请求失败:', error)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
+async function getCount() {
|
|
|
+ try {
|
|
|
+ const resp = await request({
|
|
|
+ url: '/api/ad_manage/products/count/',
|
|
|
+ method: 'POST',
|
|
|
+ data: {
|
|
|
+ profile_id: profile.value.profile_id,
|
|
|
+ category_id: categoryId.value,
|
|
|
+ },
|
|
|
+ })
|
|
|
+ commodityCount.value = resp.data.AsinCounts
|
|
|
+ countLoadig.value = false
|
|
|
+ } catch(error) {
|
|
|
+ console.error('请求失败:', error)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function refine(data) {
|
|
|
+ console.log('🚀 ~ refine ~ data-->>', data)
|
|
|
+ dialogTitle.value = data.cna
|
|
|
+ categoryId.value = data.cid
|
|
|
+ visible.value = true
|
|
|
+ setDialogOption()
|
|
|
+}
|
|
|
+
|
|
|
+function orientate(node, data) {
|
|
|
+}
|
|
|
+
|
|
|
+watch(() => dialogForm.isCount, (newValue, oldValue) => {
|
|
|
+ if (newValue === true) {
|
|
|
+ countLoadig.value = true
|
|
|
+ getCount()
|
|
|
+ } else {
|
|
|
+ commodityCount.value = []
|
|
|
+ }
|
|
|
+ })
|
|
|
|
|
|
// ------------------------------------------关键词定向模块------------------------------------------
|
|
|
const bidType = ref('customBid')
|
|
@@ -1455,4 +1624,19 @@ div {
|
|
|
::v-deep(.category-tabs .el-tabs__nav) {
|
|
|
margin-left: 20px;
|
|
|
}
|
|
|
+// el-tree自定义样式
|
|
|
+.custom-tree-node {
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ font-size: 14px;
|
|
|
+ padding-right: 8px;
|
|
|
+}
|
|
|
+/* 弹窗样式 */
|
|
|
+.dialog-head {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ justify-content: space-between;
|
|
|
+}
|
|
|
</style>
|