|
@@ -125,7 +125,7 @@
|
|
:header-cell-style="headerCellStyle"
|
|
:header-cell-style="headerCellStyle"
|
|
@selection-change="handleSelectionChange">
|
|
@selection-change="handleSelectionChange">
|
|
<el-table-column type="selection" width="50" />
|
|
<el-table-column type="selection" width="50" />
|
|
- <el-table-column prop="asin" label="ASIN" width="538">
|
|
|
|
|
|
+ <el-table-column prop="asin" label="商品" width="538">
|
|
<template #default="scope">
|
|
<template #default="scope">
|
|
<div style="display: flex; align-items: center">
|
|
<div style="display: flex; align-items: center">
|
|
<div style="margin-right: 8px; line-height: normal">
|
|
<div style="margin-right: 8px; line-height: normal">
|
|
@@ -203,7 +203,7 @@
|
|
<template #header>
|
|
<template #header>
|
|
<div class="card-header">
|
|
<div class="card-header">
|
|
<span style="font-weight: 550; font-size: 15px; color: #1f2128">已添加: {{ addedData.length }}</span>
|
|
<span style="font-weight: 550; font-size: 15px; color: #1f2128">已添加: {{ addedData.length }}</span>
|
|
- <el-button class="button" text @click="delAll">全部删除</el-button>
|
|
|
|
|
|
+ <el-button class="button" text bg @click="delAll">全部删除</el-button>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
<!-- <div v-for="o in 4" :key="o" class="text item">{{ 'List item ' + o }}</div> -->
|
|
<!-- <div v-for="o in 4" :key="o" class="text item">{{ 'List item ' + o }}</div> -->
|
|
@@ -260,7 +260,7 @@
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
|
|
|
<div class="column-item">
|
|
<div class="column-item">
|
|
- <p style="color: #606266; font-weight: 450">自动定向</p>
|
|
|
|
|
|
+ <p style="color: #606266; font-weight: 450"><span style="color: #e47470">*</span> 自动定向</p>
|
|
<el-radio-group v-model="ruleForm.autoRedirect" @change="changeBid">
|
|
<el-radio-group v-model="ruleForm.autoRedirect" @change="changeBid">
|
|
<div style="display: flex">
|
|
<div style="display: flex">
|
|
<el-radio label="defaultBid">设置默认出价</el-radio>
|
|
<el-radio label="defaultBid">设置默认出价</el-radio>
|
|
@@ -275,7 +275,6 @@
|
|
</div>
|
|
</div>
|
|
</el-radio-group>
|
|
</el-radio-group>
|
|
</div>
|
|
</div>
|
|
-
|
|
|
|
<el-card v-if="showCard" class="box-card">
|
|
<el-card v-if="showCard" class="box-card">
|
|
<div>
|
|
<div>
|
|
<div style="color: #8e9095">
|
|
<div style="color: #8e9095">
|
|
@@ -340,9 +339,160 @@
|
|
<el-card>1233</el-card>
|
|
<el-card>1233</el-card>
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
|
|
|
|
|
+ <div style="font-size: 20px; font-weight: bold; margin-top: 30px">否定词</div>
|
|
|
|
+ <hr />
|
|
|
|
+ <el-form-item prop="matchType" style="width: 100%; margin-top: 20px">
|
|
|
|
+ <div style="width: 100%; height: 520px; display: flex; border: 1px solid #c2c7cf; border-radius: 6px">
|
|
|
|
+ <div style="width: 50%; border-right: 1px solid #c2c7cf">
|
|
|
|
+ <div style="margin: 10px 0">
|
|
|
|
+ <span style="margin-left: 25px; color: #e47470">*</span>
|
|
|
|
+ <span style="color: #666666; margin-right: 10px">匹配类型: </span>
|
|
|
|
+ <el-checkbox v-model="ruleForm.phraseNegation" label="词组否定" />
|
|
|
|
+ <el-checkbox v-model="ruleForm.preciseNegation" label="精确否定" />
|
|
|
|
+ </div>
|
|
|
|
+ <el-input
|
|
|
|
+ v-model="ruleForm.negativeTextarea"
|
|
|
|
+ :rows="17"
|
|
|
|
+ type="textarea"
|
|
|
|
+ placeholder="请输入关键词,多个关键词使用逗号或者换行符分隔。(最多添加1000个关键词)"
|
|
|
|
+ maxlength="11000"
|
|
|
|
+ style="padding: 0 20px" />
|
|
|
|
+ <div style="display: flex; flex-direction: row-reverse; margin-top: 10px">
|
|
|
|
+ <el-button style="margin-right: 18px" type="primary" text bg @click="addNegative">添加</el-button>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div style="width: 50%">
|
|
|
|
+ <el-card class="box-card" shadow="never">
|
|
|
|
+ <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="delAllNegative">全部删除</el-button>
|
|
|
|
+ </div>
|
|
|
|
+ </template>
|
|
|
|
+ <div class="card-body">
|
|
|
|
+ <el-table :data="tableData" style="width: 100%" :header-row-style="changeNegTableHeader">
|
|
|
|
+ <el-table-column prop="negativeWords" label="否定词" width="628" />
|
|
|
|
+ <el-table-column prop="operate" label="操作" width="60" align="right">
|
|
|
|
+ <template #default="scope">
|
|
|
|
+ <el-button type="primary" size="small" @click="delSingleNegative(scope)" text>删除</el-button>
|
|
|
|
+ </template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ </el-table>
|
|
|
|
+ </div>
|
|
|
|
+ </el-card>
|
|
|
|
+ <div style="padding: 0 10px 0 10px; margin-top: -12px"></div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </el-form-item>
|
|
|
|
+
|
|
|
|
+ <div style="font-size: 20px; font-weight: bold; margin-top: 30px">否定商品</div>
|
|
|
|
+ <hr />
|
|
|
|
+ <el-form-item prop="matchType" style="width: 100%; margin-top: 20px">
|
|
|
|
+ <div style="width: 100%; height: 520px; display: flex; border: 1px solid #c2c7cf; border-radius: 6px">
|
|
|
|
+ <div style="width: 50%; border-right: 1px solid #c2c7cf">
|
|
|
|
+ <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
|
|
|
|
+ <el-tab-pane label="搜索" name="first">
|
|
|
|
+ <div style="margin-bottom: 10px">
|
|
|
|
+ <el-input placeholder="按ASIN搜索" v-model="negativeInput" @change="searchNegative" clearable />
|
|
|
|
+ </div>
|
|
|
|
+ <el-table
|
|
|
|
+ height="415"
|
|
|
|
+ style="width: 100%"
|
|
|
|
+ v-loading="loading"
|
|
|
|
+ :data="negativeTableData"
|
|
|
|
+ :header-cell-style="headerCellStyle"
|
|
|
|
+ @selection-change="handleSelectionChange"
|
|
|
|
+ :show-header="false">
|
|
|
|
+ <el-table-column prop="asin" label="商品" width="588">
|
|
|
|
+ <template #default="scope">
|
|
|
|
+ <div style="display: flex; align-items: center">
|
|
|
|
+ <div style="margin-right: 8px; line-height: normal">
|
|
|
|
+ <el-image class="img-box" :src="scope.row.image_link" />
|
|
|
|
+ </div>
|
|
|
|
+ <div>
|
|
|
|
+ <el-tooltip class="box-item" effect="dark" :content="scope.row.title" placement="top">
|
|
|
|
+ <div class="single-line">{{ scope.row.title ? scope.row.title : '--' }}</div>
|
|
|
|
+ </el-tooltip>
|
|
|
|
+ <span>
|
|
|
|
+ ASIN: <span class="data-color" style="margin-right: 8px">{{ scope.row.asin ? scope.row.asin : '--' }}</span>
|
|
|
|
+ </span>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ <el-table-column prop="name" label="Name" width="120" align="right">
|
|
|
|
+ <template #header>
|
|
|
|
+
|
|
|
|
+ </template>
|
|
|
|
+ <template #default="scope">
|
|
|
|
+ <el-button type="primary" size="small" @click="addSingleNegative(scope)" text>添加</el-button>
|
|
|
|
+ </template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ </el-table>
|
|
|
|
+ </el-tab-pane>
|
|
|
|
+ <el-tab-pane label="输入" name="second">
|
|
|
|
+ <el-input
|
|
|
|
+ v-model="ruleForm.negativeGoodsTextarea"
|
|
|
|
+ :rows="17"
|
|
|
|
+ type="textarea"
|
|
|
|
+ placeholder="请输入关键词,多个关键词使用逗号或者换行符分隔。(最多添加1000个关键词)"
|
|
|
|
+ maxlength="11000"
|
|
|
|
+ style="padding: 0 20px" />
|
|
|
|
+ <div style="display: flex; flex-direction: row-reverse; margin-top: 10px">
|
|
|
|
+ <el-button style="margin-right: 18px" type="primary" text bg @click="addNegativeGoods">添加</el-button>
|
|
|
|
+ </div>
|
|
|
|
+ </el-tab-pane>
|
|
|
|
+ </el-tabs>
|
|
|
|
+ </div>
|
|
|
|
+ <div style="width: 50%">
|
|
|
|
+ <el-card class="box-card" shadow="never">
|
|
|
|
+ <template #header>
|
|
|
|
+ <div class="card-header">
|
|
|
|
+ <span style="font-weight: 550; font-size: 15px; color: #1f2128">已添加: {{ addedNegetiveTableData.length }}</span>
|
|
|
|
+ <el-button class="button" text bg @click="delAllNegativeGoods">全部删除</el-button>
|
|
|
|
+ </div>
|
|
|
|
+ </template>
|
|
|
|
+ <div class="card-body"></div>
|
|
|
|
+ </el-card>
|
|
|
|
+ <div style="padding: 0 10px 0 10px; margin-top: -12px">
|
|
|
|
+ <el-table
|
|
|
|
+ :data="addedNegetiveTableData"
|
|
|
|
+ height="415"
|
|
|
|
+ style="width: 100%"
|
|
|
|
+ :header-cell-style="headerCellStyle"
|
|
|
|
+ @selection-change="handleAddedChange">
|
|
|
|
+ <el-table-column prop="asin" label="商品" width="588">
|
|
|
|
+ <template #default="scope">
|
|
|
|
+ <div style="display: flex; align-items: center">
|
|
|
|
+ <div style="margin-right: 8px; line-height: normal">
|
|
|
|
+ <el-image class="img-box" :src="scope.row.image_link" />
|
|
|
|
+ </div>
|
|
|
|
+ <div>
|
|
|
|
+ <el-tooltip class="box-item" effect="dark" :content="scope.row.title" placement="top">
|
|
|
|
+ <div class="single-line">{{ scope.row.title ? scope.row.title : '--' }}</div>
|
|
|
|
+ </el-tooltip>
|
|
|
|
+ <span
|
|
|
|
+ >ASIN:
|
|
|
|
+ <span class="data-color" style="margin-right: 8px">{{ scope.row.asin ? scope.row.asin : '--' }}</span>
|
|
|
|
+ </span>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ <el-table-column label="操作" width="120" align="right">
|
|
|
|
+ <template #default="scope">
|
|
|
|
+ <el-button type="primary" size="small" @click="delSingleNegativeGoods(scope)" text>删除</el-button>
|
|
|
|
+ </template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ </el-table>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </el-form-item>
|
|
|
|
+
|
|
<br />
|
|
<br />
|
|
<el-form-item>
|
|
<el-form-item>
|
|
- <el-button type="primary" @click="submitForm(ruleFormRef)">Create</el-button>
|
|
|
|
|
|
+ <el-button type="negativeGoods" @click="submitForm(ruleFormRef)">Create</el-button>
|
|
<el-button @click="resetForm(ruleFormRef)">Reset</el-button>
|
|
<el-button @click="resetForm(ruleFormRef)">Reset</el-button>
|
|
</el-form-item>
|
|
</el-form-item>
|
|
</el-form>
|
|
</el-form>
|
|
@@ -352,526 +502,594 @@
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
<script lang="ts" setup>
|
|
- import { onMounted, reactive, ref, computed, watch } from 'vue'
|
|
|
|
- import { useRoute } from 'vue-router'
|
|
|
|
- import type { FormInstance, FormRules, TabsPaneContext } from 'element-plus'
|
|
|
|
- import { Search } from '@element-plus/icons-vue'
|
|
|
|
- import { useShopInfo } from '/@/stores/shopInfo'
|
|
|
|
- import { usePublicData } from '/@/stores/publicData'
|
|
|
|
- import { storeToRefs } from 'pinia'
|
|
|
|
- import { useRouter } from 'vue-router'
|
|
|
|
- import axios from 'axios'
|
|
|
|
- import { request } from '/@/utils/service'
|
|
|
|
-
|
|
|
|
- const router = useRouter()
|
|
|
|
- const route = useRoute()
|
|
|
|
- const shopInfo = useShopInfo()
|
|
|
|
- const { profile } = storeToRefs(shopInfo)
|
|
|
|
- const loading = ref(true)
|
|
|
|
- const fullTableData = ref([]) // 表格数据
|
|
|
|
- let addedData = ref([]) // 已添加的商品数据
|
|
|
|
- let selections = [] // 添加选中的项
|
|
|
|
- let addedSels = [] // 删除选中的项
|
|
|
|
- const currentPage = ref() // 当前页
|
|
|
|
- const pageSize = ref(20) // 每页显示条目数
|
|
|
|
- const totalItems = ref() // 数据总量
|
|
|
|
- const showCard = ref(false)
|
|
|
|
-
|
|
|
|
- // 当单选按钮变化时更新showCard状态
|
|
|
|
- function changeBid() {
|
|
|
|
- console.log(ruleForm.autoRedirect)
|
|
|
|
- showCard.value = ruleForm.autoRedirect === 'targetBid'
|
|
|
|
- }
|
|
|
|
- // 切换投放类型
|
|
|
|
- function changeType() {}
|
|
|
|
-
|
|
|
|
- function setTableData(asin = '', sku = '') {
|
|
|
|
- return request({
|
|
|
|
- url: '/api/sellers/listings/',
|
|
|
|
- method: 'GET',
|
|
|
|
- params: {
|
|
|
|
- page: currentPage.value,
|
|
|
|
- limit: pageSize.value,
|
|
|
|
- profile_id: profile.value.profile_id,
|
|
|
|
- asin,
|
|
|
|
- sku,
|
|
|
|
- },
|
|
|
|
|
|
+import { onMounted, reactive, ref, computed, watch } from 'vue'
|
|
|
|
+import { useRoute } from 'vue-router'
|
|
|
|
+import type { FormInstance, FormRules, TabsPaneContext } from 'element-plus'
|
|
|
|
+import { useShopInfo } from '/@/stores/shopInfo'
|
|
|
|
+import { usePublicData } from '/@/stores/publicData'
|
|
|
|
+import { storeToRefs } from 'pinia'
|
|
|
|
+import { useRouter } from 'vue-router'
|
|
|
|
+import { request } from '/@/utils/service'
|
|
|
|
+
|
|
|
|
+const negativeTableData = ref([])
|
|
|
|
+const addedNegetiveTableData = ref([])
|
|
|
|
+const router = useRouter()
|
|
|
|
+const route = useRoute()
|
|
|
|
+const shopInfo = useShopInfo()
|
|
|
|
+const { profile } = storeToRefs(shopInfo)
|
|
|
|
+const loading = ref(true)
|
|
|
|
+const fullTableData = ref([]) // 表格数据
|
|
|
|
+let addedData = ref([]) // 已添加的商品数据
|
|
|
|
+let selections = [] // 添加选中的项
|
|
|
|
+let addedSels = [] // 删除选中的项
|
|
|
|
+const currentPage = ref() // 当前页
|
|
|
|
+const pageSize = ref(20) // 每页显示条目数
|
|
|
|
+const totalItems = ref() // 数据总量
|
|
|
|
+const showCard = ref(false)
|
|
|
|
+const activeName = ref('first')
|
|
|
|
+const searchInp = ref('')
|
|
|
|
+const select = ref('name')
|
|
|
|
+const select2 = ref('latest')
|
|
|
|
+const textarea = ref('')
|
|
|
|
+const buttons = [{ type: 'primary', text: '添加' }] as const
|
|
|
|
+const negativeInput = ref('')
|
|
|
|
+
|
|
|
|
+// 表单相关数据
|
|
|
|
+const formSize = ref('default')
|
|
|
|
+const labelPosition = ref('top')
|
|
|
|
+const ruleFormRef = ref<FormInstance>()
|
|
|
|
+interface RuleForm {
|
|
|
|
+ name: string
|
|
|
|
+ adMix: string
|
|
|
|
+ count: string
|
|
|
|
+ date1: string
|
|
|
|
+ date2: string
|
|
|
|
+ budget: string
|
|
|
|
+ delivery: boolean
|
|
|
|
+ type: string
|
|
|
|
+ bidStrategy: string
|
|
|
|
+ placeBid: string
|
|
|
|
+ firstPage: string
|
|
|
|
+ other: string
|
|
|
|
+ adGroupName: string
|
|
|
|
+ autoRedirect: string
|
|
|
|
+ defaultBidInp: string
|
|
|
|
+ closeMatch: boolean
|
|
|
|
+ broadMatch: boolean
|
|
|
|
+ similarProducts: boolean
|
|
|
|
+ relatedProducts: boolean
|
|
|
|
+ closeMatchInp: string
|
|
|
|
+ broadMatchInp: string
|
|
|
|
+ similarProductsInp: string
|
|
|
|
+ relatedProductsInp: string
|
|
|
|
+ phraseNegation: boolean
|
|
|
|
+ preciseNegation: boolean
|
|
|
|
+ negativeTextarea: string
|
|
|
|
+ negativeGoodsTextarea: string
|
|
|
|
+}
|
|
|
|
+const ruleForm = reactive<RuleForm>({
|
|
|
|
+ name: 'Hello',
|
|
|
|
+ adMix: '',
|
|
|
|
+ count: '',
|
|
|
|
+ date1: '',
|
|
|
|
+ date2: '',
|
|
|
|
+ budget: '',
|
|
|
|
+ delivery: false,
|
|
|
|
+ type: 'auto',
|
|
|
|
+ bidStrategy: 'dynamicBid_Low',
|
|
|
|
+ placeBid: '',
|
|
|
|
+ firstPage: '',
|
|
|
|
+ other: '',
|
|
|
|
+ adGroupName: '',
|
|
|
|
+ autoRedirect: 'defaultBid',
|
|
|
|
+ defaultBidInp: '',
|
|
|
|
+ closeMatch: true,
|
|
|
|
+ broadMatch: true,
|
|
|
|
+ similarProducts: true,
|
|
|
|
+ relatedProducts: true,
|
|
|
|
+ closeMatchInp: '666',
|
|
|
|
+ broadMatchInp: '666',
|
|
|
|
+ similarProductsInp: '666',
|
|
|
|
+ relatedProductsInp: '666',
|
|
|
|
+ phraseNegation: true,
|
|
|
|
+ preciseNegation: true,
|
|
|
|
+ negativeTextarea: '',
|
|
|
|
+ negativeGoodsTextarea: '',
|
|
|
|
+})
|
|
|
|
+const rules = computed(() => ({
|
|
|
|
+ name: [{ required: true, message: 'Please input Activity name', trigger: 'blur' }],
|
|
|
|
+ adMix: [{ required: false, message: 'Please select Activity zone', trigger: 'change' }],
|
|
|
|
+ count: [{ required: true, message: 'Please select Activity count', trigger: 'change' }],
|
|
|
|
+ date1: [{ required: true, type: 'date', message: 'Please pick a date', trigger: 'change' }],
|
|
|
|
+ date2: [{ required: false, type: 'date', message: 'Please pick a time', trigger: 'change' }],
|
|
|
|
+ budget: [
|
|
|
|
+ { required: true, message: '请输入预算', trigger: 'blur' },
|
|
|
|
+ { pattern: /^(?:[1-9]\d{0,5}|1000000)(?:\.\d{1,2})?$/, message: '预算必须是1到1000000之间的数字,小数点后最多两位', trigger: 'blur' },
|
|
|
|
+ ],
|
|
|
|
+ type: [{ required: false, trigger: 'change' }],
|
|
|
|
+ bidStrategy: [{ required: true, message: 'Please select activity resource', trigger: 'change' }],
|
|
|
|
+ placeBid: [{ required: false, pattern: /^[0-9]{1,3}$/, message: '必须是0~900之间的整数百分比', trigger: 'change' }],
|
|
|
|
+ firstPage: [{ required: false, pattern: /^[0-9]{1,3}$/, message: '必须是0~900之间的整数百分比', trigger: 'change' }],
|
|
|
|
+ other: [{ required: false, pattern: /^[0-9]{1,3}$/, message: '必须是0~900之间的整数百分比', trigger: 'change' }],
|
|
|
|
+ adGroupName: [{ required: true, message: 'Please input Activity name', trigger: 'blur' }],
|
|
|
|
+ autoRedirect: [{ required: true, trigger: 'change' }],
|
|
|
|
+ defaultBidInp: getValidationRules('defaultBidInp'),
|
|
|
|
+ relatedProductsInp: getValidationRules('relatedProductsInp'),
|
|
|
|
+ similarProductsInp: getValidationRules('similarProductsInp'),
|
|
|
|
+ broadMatchInp: getValidationRules('broadMatchInp'),
|
|
|
|
+ closeMatchInp: getValidationRules('closeMatchInp'),
|
|
|
|
+}))
|
|
|
|
+
|
|
|
|
+//------------------------------------------------------------------------------方法------------------------------------------------------------------------------
|
|
|
|
+
|
|
|
|
+// 当单选按钮变化时更新showCard状态
|
|
|
|
+function changeBid() {
|
|
|
|
+ console.log(ruleForm.autoRedirect)
|
|
|
|
+ showCard.value = ruleForm.autoRedirect === 'targetBid'
|
|
|
|
+}
|
|
|
|
+// 切换投放类型
|
|
|
|
+function changeType() {}
|
|
|
|
+
|
|
|
|
+function setTableData(asin = '', sku = '') {
|
|
|
|
+ return request({
|
|
|
|
+ url: '/api/sellers/listings/',
|
|
|
|
+ method: 'GET',
|
|
|
|
+ params: {
|
|
|
|
+ page: currentPage.value,
|
|
|
|
+ limit: pageSize.value,
|
|
|
|
+ profile_id: profile.value.profile_id,
|
|
|
|
+ asin,
|
|
|
|
+ sku,
|
|
|
|
+ },
|
|
|
|
+ })
|
|
|
|
+ .then((resp) => {
|
|
|
|
+ fullTableData.value = resp.data
|
|
|
|
+ totalItems.value = resp.total
|
|
|
|
+ currentPage.value = resp.page
|
|
|
|
+ loading.value = false
|
|
})
|
|
})
|
|
- .then((resp) => {
|
|
|
|
- fullTableData.value = resp.data
|
|
|
|
- totalItems.value = resp.total
|
|
|
|
- currentPage.value = resp.page
|
|
|
|
- loading.value = false
|
|
|
|
- })
|
|
|
|
- .catch((error) => {
|
|
|
|
- console.error('Error fetching data:', error)
|
|
|
|
- loading.value = false
|
|
|
|
- })
|
|
|
|
- }
|
|
|
|
|
|
+ .catch((error) => {
|
|
|
|
+ console.error('Error fetching data:', error)
|
|
|
|
+ loading.value = false
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
|
|
- // 处理分页器当前页变化
|
|
|
|
- function handleCurrentChange(newPage) {
|
|
|
|
- currentPage.value = newPage
|
|
|
|
- loading.value = true
|
|
|
|
- setTableData()
|
|
|
|
|
|
+// 处理分页器当前页变化
|
|
|
|
+function handleCurrentChange(newPage) {
|
|
|
|
+ currentPage.value = newPage
|
|
|
|
+ loading.value = true
|
|
|
|
+ setTableData()
|
|
|
|
+}
|
|
|
|
+// 处理分页器每页显示条目数变化
|
|
|
|
+function handleSizeChange(newSize) {
|
|
|
|
+ pageSize.value = newSize
|
|
|
|
+ currentPage.value = 1 // 重置到第一页
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 点击表格选项触发事件
|
|
|
|
+function handleSelectionChange(selection) {
|
|
|
|
+ selections = selection
|
|
|
|
+}
|
|
|
|
+// 添加已选中的项
|
|
|
|
+function handleAdd() {
|
|
|
|
+ // 过滤掉已经存在于addedData.value中的项
|
|
|
|
+ const newSelections = selections.filter(
|
|
|
|
+ (sel) => !addedData.value.some((added) => added.sku === sel.sku) // 假设使用sku作为唯一标识
|
|
|
|
+ )
|
|
|
|
+ // 如果有新的不重复项,加入到addedData.value中
|
|
|
|
+ if (newSelections.length > 0) {
|
|
|
|
+ addedData.value.push(...newSelections)
|
|
}
|
|
}
|
|
- // 处理分页器每页显示条目数变化
|
|
|
|
- function handleSizeChange(newSize) {
|
|
|
|
- pageSize.value = newSize
|
|
|
|
- currentPage.value = 1 // 重置到第一页
|
|
|
|
|
|
+ // console.log('addedData', addedData.value)
|
|
|
|
+}
|
|
|
|
+// 获取addedTable中已选中的项
|
|
|
|
+function handleAddedChange(selection) {
|
|
|
|
+ addedSels = selection
|
|
|
|
+}
|
|
|
|
+// 删除第二个table中已经选中的项
|
|
|
|
+function handleDel() {
|
|
|
|
+ addedData.value = addedData.value.filter((item) => !addedSels.includes(item))
|
|
|
|
+ addedSels = []
|
|
|
|
+}
|
|
|
|
+function addSingle(scope) {
|
|
|
|
+ console.log('scope', scope.row)
|
|
|
|
+
|
|
|
|
+ const isAlreadyAdded = addedData.value.some((item) => item.sku === scope.row.sku)
|
|
|
|
+ if (!isAlreadyAdded) {
|
|
|
|
+ addedData.value.push(scope.row)
|
|
|
|
+ } else {
|
|
|
|
+ console.log('Item is already added.')
|
|
}
|
|
}
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
|
|
- // 点击表格选项触发事件
|
|
|
|
- function handleSelectionChange(selection) {
|
|
|
|
- selections = selection
|
|
|
|
|
|
+function addSingleNegative(scope) {
|
|
|
|
+ console.log('scope', scope.row)
|
|
|
|
+
|
|
|
|
+ const isAlreadyAdded = addedNegetiveTableData.value.some((item) => item.sku === scope.row.sku)
|
|
|
|
+ if (!isAlreadyAdded) {
|
|
|
|
+ addedNegetiveTableData.value.push(scope.row)
|
|
|
|
+ } else {
|
|
|
|
+ console.log('Item is already added.')
|
|
}
|
|
}
|
|
- // 添加已选中的项
|
|
|
|
- function handleAdd() {
|
|
|
|
- // 过滤掉已经存在于addedData.value中的项
|
|
|
|
- const newSelections = selections.filter(
|
|
|
|
- (sel) => !addedData.value.some((added) => added.sku === sel.sku) // 假设使用sku作为唯一标识
|
|
|
|
- )
|
|
|
|
- // 如果有新的不重复项,加入到addedData.value中
|
|
|
|
- if (newSelections.length > 0) {
|
|
|
|
- addedData.value.push(...newSelections)
|
|
|
|
- }
|
|
|
|
- // console.log('addedData', addedData.value)
|
|
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function delSingle(scope) {
|
|
|
|
+ const index = addedData.value.findIndex((item) => item.sku === scope.row.sku)
|
|
|
|
+
|
|
|
|
+ if (index !== -1) {
|
|
|
|
+ addedData.value.splice(index, 1)
|
|
|
|
+ console.log('Item removed successfully.')
|
|
|
|
+ } else {
|
|
|
|
+ console.log('Item not found.')
|
|
}
|
|
}
|
|
- // 获取addedTable中已选中的项
|
|
|
|
- function handleAddedChange(selection) {
|
|
|
|
- addedSels = selection
|
|
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function delSingleNegativeGoods(scope) {
|
|
|
|
+ const index = addedNegetiveTableData.value.findIndex((item) => item.sku === scope.row.sku)
|
|
|
|
+
|
|
|
|
+ if (index !== -1) {
|
|
|
|
+ addedNegetiveTableData.value.splice(index, 1)
|
|
|
|
+ console.log('Item removed successfully.')
|
|
|
|
+ } else {
|
|
|
|
+ console.log('Item not found.')
|
|
}
|
|
}
|
|
- // 删除第二个table中已经选中的项
|
|
|
|
- function handleDel() {
|
|
|
|
- addedData.value = addedData.value.filter((item) => !addedSels.includes(item))
|
|
|
|
- addedSels = []
|
|
|
|
|
|
+}
|
|
|
|
+// 全部删除已添加商品列表
|
|
|
|
+function delAll() {
|
|
|
|
+ addedData.value = []
|
|
|
|
+ // addedData.value.splice(0, addedData.value.length)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function delAllNegativeGoods() {
|
|
|
|
+ addedNegetiveTableData.value = []
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function inpChange(e) {
|
|
|
|
+ const value = e
|
|
|
|
+ if (select.value === 'asin') {
|
|
|
|
+ loading.value = true
|
|
|
|
+ setTableData(value)
|
|
|
|
+ } else if (select.value === 'sku') {
|
|
|
|
+ loading.value = true
|
|
|
|
+ setTableData('', value)
|
|
}
|
|
}
|
|
- function addSingle(scope) {
|
|
|
|
- console.log('scope', scope.row)
|
|
|
|
|
|
+}
|
|
|
|
|
|
- const isAlreadyAdded = addedData.value.some((item) => item.sku === scope.row.sku)
|
|
|
|
- if (!isAlreadyAdded) {
|
|
|
|
- addedData.value.push(scope.row)
|
|
|
|
- } else {
|
|
|
|
- console.log('Item is already added.')
|
|
|
|
- }
|
|
|
|
|
|
+function selChange(e) {
|
|
|
|
+ console.log('e', e)
|
|
|
|
+ const value = e
|
|
|
|
+ if (select.value === 'asin' && searchInp.value) {
|
|
|
|
+ loading.value = true
|
|
|
|
+ setTableData(value)
|
|
|
|
+ } else if (select.value === 'sku' && searchInp.value) {
|
|
|
|
+ loading.value = true
|
|
|
|
+ setTableData('', value)
|
|
}
|
|
}
|
|
- function delSingle(scope) {
|
|
|
|
- const index = addedData.value.findIndex((item) => item.sku === scope.row.sku)
|
|
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+let negativeList = reactive([])
|
|
|
|
+const tableData = negativeList
|
|
|
|
|
|
- if (index !== -1) {
|
|
|
|
- addedData.value.splice(index, 1)
|
|
|
|
- console.log('Item removed successfully.')
|
|
|
|
|
|
+function addNegative() {
|
|
|
|
+ // 删除 negativeTextarea 前后的空格
|
|
|
|
+ const trimmedText = ruleForm.negativeTextarea.trim()
|
|
|
|
+ // 使用逗号和换行符分割文本
|
|
|
|
+ const items = trimmedText.split(/,|\n/)
|
|
|
|
+
|
|
|
|
+ // 遍历分割后的每个项目
|
|
|
|
+ items.forEach((item) => {
|
|
|
|
+ const trimmedItem = item.trim() // 删除每个项目前后的空格
|
|
|
|
+ if (trimmedItem) {
|
|
|
|
+ // 如果两者都是 true,则为每个创建两个条目
|
|
|
|
+ if (ruleForm.phraseNegation && ruleForm.preciseNegation) {
|
|
|
|
+ negativeList.push({ negativeWords: '词组: ' + trimmedItem })
|
|
|
|
+ negativeList.push({ negativeWords: '精确: ' + trimmedItem })
|
|
|
|
+ } else if (ruleForm.phraseNegation) {
|
|
|
|
+ negativeList.push({ negativeWords: '词组: ' + trimmedItem })
|
|
|
|
+ } else if (ruleForm.preciseNegation) {
|
|
|
|
+ negativeList.push({ negativeWords: '精确: ' + trimmedItem })
|
|
|
|
+ }
|
|
} else {
|
|
} else {
|
|
- console.log('Item not found.')
|
|
|
|
|
|
+ console.log('有空项目,未被添加到列表中')
|
|
}
|
|
}
|
|
- }
|
|
|
|
- // 全部删除
|
|
|
|
- function delAll() {
|
|
|
|
- addedData.value = []
|
|
|
|
- }
|
|
|
|
|
|
+ })
|
|
|
|
|
|
- function inpChange(e) {
|
|
|
|
- const value = e
|
|
|
|
- if (select.value === 'asin') {
|
|
|
|
- loading.value = true
|
|
|
|
- setTableData(value)
|
|
|
|
- } else if (select.value === 'sku') {
|
|
|
|
- loading.value = true
|
|
|
|
- setTableData('', value)
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ // 清空输入框
|
|
|
|
+ ruleForm.negativeTextarea = ''
|
|
|
|
+ console.log(negativeList)
|
|
|
|
+}
|
|
|
|
|
|
- function selChange(e) {
|
|
|
|
- console.log('e', e)
|
|
|
|
- const value = e
|
|
|
|
- if (select.value === 'asin' && searchInp.value) {
|
|
|
|
- loading.value = true
|
|
|
|
- setTableData(value)
|
|
|
|
- } else if (select.value === 'sku' && searchInp.value) {
|
|
|
|
- loading.value = true
|
|
|
|
- setTableData('', value)
|
|
|
|
- }
|
|
|
|
|
|
+function delSingleNegative(scope) {
|
|
|
|
+ const index = negativeList.findIndex((item) => item.negativeWords === scope.row.negativeWords)
|
|
|
|
+ if (negativeList.length) {
|
|
|
|
+ negativeList.splice(index, 1)
|
|
|
|
+ console.log(`已删除索引为 ${index} 的条目`)
|
|
|
|
+ } else {
|
|
|
|
+ console.log('无效的索引,无法删除条目')
|
|
}
|
|
}
|
|
|
|
+}
|
|
|
|
+function delAllNegative() {
|
|
|
|
+ // negativeList.splice(0, negativeList.length)
|
|
|
|
+ negativeList.length = 0
|
|
|
|
+}
|
|
|
|
+function setNegativeTableData(asin = '',) {
|
|
|
|
+ return request({
|
|
|
|
+ url: '/api/sellers/listings/',
|
|
|
|
+ method: 'GET',
|
|
|
|
+ params: {
|
|
|
|
+ page: currentPage.value,
|
|
|
|
+ limit: pageSize.value,
|
|
|
|
+ profile_id: profile.value.profile_id,
|
|
|
|
+ asin,
|
|
|
|
+ },
|
|
|
|
+ })
|
|
|
|
+ .then((resp) => {
|
|
|
|
+ negativeTableData.value = resp.data
|
|
|
|
+ loading.value = false
|
|
|
|
+ })
|
|
|
|
+ .catch((error) => {
|
|
|
|
+ console.error('Error fetching data:', error)
|
|
|
|
+ loading.value = false
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
|
|
- // const size = ref('default')
|
|
|
|
- // const labelPosition = ref('top')
|
|
|
|
- interface RuleForm {
|
|
|
|
- name: string
|
|
|
|
- adMix: string
|
|
|
|
- count: string
|
|
|
|
- date1: string
|
|
|
|
- date2: string
|
|
|
|
- budget: string
|
|
|
|
- delivery: boolean
|
|
|
|
- type: string
|
|
|
|
- bidStrategy: string
|
|
|
|
- placeBid: string
|
|
|
|
- firstPage: string
|
|
|
|
- other: string
|
|
|
|
- adGroupName: string
|
|
|
|
- autoRedirect: string
|
|
|
|
- defaultBidInp: string
|
|
|
|
- closeMatch: boolean
|
|
|
|
- broadMatch: boolean
|
|
|
|
- similarProducts: boolean
|
|
|
|
- relatedProducts: boolean
|
|
|
|
- closeMatchInp: string
|
|
|
|
- broadMatchInp: string
|
|
|
|
- similarProductsInp: string
|
|
|
|
- relatedProductsInp: string
|
|
|
|
|
|
+function searchNegative(e) {
|
|
|
|
+ if (e === '') {
|
|
|
|
+ negativeTableData.value = []
|
|
|
|
+ } else {
|
|
|
|
+ setNegativeTableData(e)
|
|
}
|
|
}
|
|
|
|
+}
|
|
|
|
|
|
- const formSize = ref('default')
|
|
|
|
- const labelPosition = ref('top')
|
|
|
|
- const ruleFormRef = ref<FormInstance>()
|
|
|
|
- const ruleForm = reactive<RuleForm>({
|
|
|
|
- name: 'Hello',
|
|
|
|
- adMix: '',
|
|
|
|
- count: '',
|
|
|
|
- date1: '',
|
|
|
|
- date2: '',
|
|
|
|
- budget: '',
|
|
|
|
- delivery: false,
|
|
|
|
- type: 'auto',
|
|
|
|
- bidStrategy: 'dynamicBid_Low',
|
|
|
|
- placeBid: '',
|
|
|
|
- firstPage: '',
|
|
|
|
- other: '',
|
|
|
|
- adGroupName: '',
|
|
|
|
- autoRedirect: 'defaultBid',
|
|
|
|
- defaultBidInp: '',
|
|
|
|
- closeMatch: true,
|
|
|
|
- broadMatch: true,
|
|
|
|
- similarProducts: true,
|
|
|
|
- relatedProducts: true,
|
|
|
|
- closeMatchInp: '',
|
|
|
|
- broadMatchInp: '',
|
|
|
|
- similarProductsInp: '',
|
|
|
|
- relatedProductsInp: '',
|
|
|
|
- })
|
|
|
|
- const rules = computed(() => ({
|
|
|
|
- name: [{ required: true, message: 'Please input Activity name', trigger: 'blur' }],
|
|
|
|
- adMix: [{ required: false, message: 'Please select Activity zone', trigger: 'change' }],
|
|
|
|
- count: [{ required: true, message: 'Please select Activity count', trigger: 'change' }],
|
|
|
|
- date1: [{ required: true, type: 'date', message: 'Please pick a date', trigger: 'change' }],
|
|
|
|
- date2: [{ required: false, type: 'date', message: 'Please pick a time', trigger: 'change' }],
|
|
|
|
- budget: [
|
|
|
|
- { required: true, message: '请输入预算', trigger: 'blur' },
|
|
|
|
- { pattern: /^(?:[1-9]\d{0,5}|1000000)(?:\.\d{1,2})?$/, message: '预算必须是1到1000000之间的数字,小数点后最多两位', trigger: 'blur' },
|
|
|
|
- ],
|
|
|
|
- type: [{ required: false, trigger: 'change' }],
|
|
|
|
- bidStrategy: [{ required: true, message: 'Please select activity resource', trigger: 'change' }],
|
|
|
|
- placeBid: [{ required: false, pattern: /^[0-9]{1,3}$/, message: '必须是0~900之间的整数百分比', trigger: 'change' }],
|
|
|
|
- firstPage: [{ required: false, pattern: /^[0-9]{1,3}$/, message: '必须是0~900之间的整数百分比', trigger: 'change' }],
|
|
|
|
- other: [{ required: false, pattern: /^[0-9]{1,3}$/, message: '必须是0~900之间的整数百分比', trigger: 'change' }],
|
|
|
|
- adGroupName: [{ required: true, message: 'Please input Activity name', trigger: 'blur' }],
|
|
|
|
- autoRedirect: [{ required: true, trigger: 'change' },],
|
|
|
|
- defaultBidInp: getValidationRules('defaultBidInp'),
|
|
|
|
- relatedProductsInp: getValidationRules('relatedProductsInp'),
|
|
|
|
- similarProductsInp: getValidationRules('similarProductsInp'),
|
|
|
|
- broadMatchInp: getValidationRules('broadMatchInp'),
|
|
|
|
- closeMatchInp: getValidationRules('closeMatchInp'),
|
|
|
|
- }))
|
|
|
|
-
|
|
|
|
- function checkBid(value, callback, bidField) {
|
|
|
|
- const bid = parseFloat(value)
|
|
|
|
- const budget = parseFloat(ruleForm.budget)
|
|
|
|
- // 检查值是否为最多两位小数的普通数字格式
|
|
|
|
- const isNormalNumberWithTwoDecimals = /^-?\d+(\.\d{1,2})?$/.test(value)
|
|
|
|
-
|
|
|
|
- if (!isNormalNumberWithTwoDecimals) {
|
|
|
|
- callback(new Error('请输入数字值(最多两位小数)'))
|
|
|
|
- } else if (isNaN(bid)) {
|
|
|
|
- callback(new Error('请输入有效的数字'))
|
|
|
|
- } else if (bid < 0.02 || bid > 1000) {
|
|
|
|
- callback(new Error('值必须在0.02到1000之间'))
|
|
|
|
- } else if (bid >= budget) {
|
|
|
|
- callback(new Error('出价必须小于预算'))
|
|
|
|
- } else {
|
|
|
|
- callback()
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+function addNegativeGoods(e) {
|
|
|
|
+ setNegativeTableData(e)
|
|
|
|
+}
|
|
|
|
|
|
- // const validateDefaultBidInp = (rule: any, value: any, callback: any) => {
|
|
|
|
- // if (ruleForm.autoRedirect === 'defaultBid') {
|
|
|
|
- // checkBid(value, callback, 'defaultBidInp')
|
|
|
|
- // } else {
|
|
|
|
- // ruleFormRef.value?.clearValidate('defaultBidInp')
|
|
|
|
- // callback()
|
|
|
|
- // }
|
|
|
|
- // }
|
|
|
|
-
|
|
|
|
- // 校验defaultBidInp
|
|
|
|
- // const validateDefaultBidInp = (rule, value, callback) => {
|
|
|
|
- // if (ruleForm.autoRedirect === 'defaultBid') {
|
|
|
|
- // checkBid(value, callback, 'defaultBidInp');
|
|
|
|
- // } else {
|
|
|
|
- // callback();
|
|
|
|
- // }
|
|
|
|
- // };
|
|
|
|
-
|
|
|
|
- // 校验其他相关字段
|
|
|
|
- // const validateRelatedFields = (rule, value, callback, fieldName) => {
|
|
|
|
- // if (ruleForm.autoRedirect === 'targetBid') {
|
|
|
|
- // checkBid(value, callback, fieldName);
|
|
|
|
- // } else {
|
|
|
|
- // callback();
|
|
|
|
- // }
|
|
|
|
- // };
|
|
|
|
-
|
|
|
|
- // 动态生成校验规则的函数
|
|
|
|
- function getValidationRules(fieldName) {
|
|
|
|
- // 默认校验规则
|
|
|
|
- const commonRules = [
|
|
|
|
- { required: true, message: '此项为必填项', trigger: 'blur' },
|
|
|
|
- { validator: (rule, value, callback) => checkBid(value, callback, fieldName), trigger: 'blur' },
|
|
|
|
- ]
|
|
|
|
-
|
|
|
|
- // 根据不同字段和状态返回特定的校验规则
|
|
|
|
- switch (fieldName) {
|
|
|
|
- case 'defaultBidInp':
|
|
|
|
- if (ruleForm.autoRedirect === 'defaultBid') {
|
|
|
|
- return commonRules
|
|
|
|
- }
|
|
|
|
- break
|
|
|
|
- case 'similarProductsInp':
|
|
|
|
- if (ruleForm.autoRedirect === 'targetBid' && ruleForm.similarProducts) {
|
|
|
|
- return commonRules
|
|
|
|
- } else if (ruleForm.similarProducts == false) {
|
|
|
|
- ruleFormRef.value?.clearValidate(fieldName)
|
|
|
|
- }
|
|
|
|
- break
|
|
|
|
- case 'relatedProductsInp':
|
|
|
|
- if (ruleForm.autoRedirect === 'targetBid' && ruleForm.relatedProducts) {
|
|
|
|
- return commonRules
|
|
|
|
- } else if (ruleForm.relatedProducts == false) {
|
|
|
|
- ruleFormRef.value?.clearValidate(fieldName)
|
|
|
|
- }
|
|
|
|
- break
|
|
|
|
- case 'broadMatchInp':
|
|
|
|
- if (ruleForm.autoRedirect === 'targetBid' && ruleForm.broadMatch) {
|
|
|
|
- return commonRules
|
|
|
|
- } else if (ruleForm.broadMatch == false) {
|
|
|
|
- ruleFormRef.value?.clearValidate(fieldName)
|
|
|
|
- }
|
|
|
|
- break
|
|
|
|
- case 'closeMatchInp':
|
|
|
|
- // 仅当autoRedirect为'targetBid'且closeMatch开启时校验closeMatchInp
|
|
|
|
- if (ruleForm.autoRedirect === 'targetBid' && ruleForm.closeMatch) {
|
|
|
|
- return commonRules
|
|
|
|
- } else if (ruleForm.closeMatch == false) {
|
|
|
|
- ruleFormRef.value?.clearValidate(fieldName)
|
|
|
|
- }
|
|
|
|
- break
|
|
|
|
- default:
|
|
|
|
- return []
|
|
|
|
- }
|
|
|
|
- // 如果不满足上述条件,则无需校验
|
|
|
|
- return []
|
|
|
|
|
|
+function checkBid(value, callback, bidField) {
|
|
|
|
+ const bid = parseFloat(value)
|
|
|
|
+ const budget = parseFloat(ruleForm.budget)
|
|
|
|
+ // 检查值是否为最多两位小数的普通数字格式
|
|
|
|
+ const isNormalNumberWithTwoDecimals = /^-?\d+(\.\d{1,2})?$/.test(value)
|
|
|
|
+
|
|
|
|
+ if (!isNormalNumberWithTwoDecimals) {
|
|
|
|
+ callback(new Error('请输入数字值(最多两位小数)'))
|
|
|
|
+ } else if (isNaN(bid)) {
|
|
|
|
+ callback(new Error('请输入有效的数字'))
|
|
|
|
+ } else if (bid < 0.02 || bid > 1000) {
|
|
|
|
+ callback(new Error('值必须在0.02到1000之间'))
|
|
|
|
+ } else if (bid >= budget) {
|
|
|
|
+ callback(new Error('出价必须小于预算'))
|
|
|
|
+ } else {
|
|
|
|
+ callback()
|
|
}
|
|
}
|
|
|
|
+}
|
|
|
|
|
|
- watch(
|
|
|
|
- [
|
|
|
|
- () => ruleForm.autoRedirect,
|
|
|
|
- () => ruleForm.closeMatch,
|
|
|
|
- () => ruleForm.broadMatch,
|
|
|
|
- () => ruleForm.similarProducts,
|
|
|
|
- () => ruleForm.relatedProducts,
|
|
|
|
- ],
|
|
|
|
- () => {
|
|
|
|
- // 更新每个受影响字段的校验规则
|
|
|
|
- rules.value.defaultBidInp = getValidationRules('defaultBidInp')
|
|
|
|
- rules.value.closeMatchInp = getValidationRules('closeMatchInp')
|
|
|
|
- rules.value.broadMatchInp = getValidationRules('broadMatchInp')
|
|
|
|
- rules.value.similarProductsInp = getValidationRules('similarProductsInp')
|
|
|
|
- rules.value.relatedProductsInp = getValidationRules('relatedProductsInp')
|
|
|
|
- }
|
|
|
|
- )
|
|
|
|
|
|
+// 动态生成校验规则的函数
|
|
|
|
+function getValidationRules(fieldName) {
|
|
|
|
+ // 默认校验规则
|
|
|
|
+ const commonRules = [
|
|
|
|
+ { required: true, message: '此项为必填项', trigger: 'blur' },
|
|
|
|
+ { validator: (rule, value, callback) => checkBid(value, callback, fieldName), trigger: 'blur' },
|
|
|
|
+ ]
|
|
|
|
|
|
- // watch(() => ruleForm.autoRedirect, (newVal) => {
|
|
|
|
- // if (newVal === 'defaultBid') {
|
|
|
|
- // // 当autoRedirect变为'defaultBid'时,清除其他字段的校验状态,并校验defaultBidInp
|
|
|
|
- // ['relatedProductsInp', 'similarProductsInp', 'broadMatchInp', 'closeMatchInp'].forEach(field => {
|
|
|
|
- // ruleFormRef.value?.clearValidate(field);
|
|
|
|
- // });
|
|
|
|
- // ruleFormRef.value?.validateField('defaultBidInp');
|
|
|
|
- // } else if (newVal === 'targetBid') {
|
|
|
|
- // // 当autoRedirect变为'targetBid'时,清除defaultBidInp的校验状态,并校验其他相关字段
|
|
|
|
- // ruleFormRef.value?.clearValidate('defaultBidInp');
|
|
|
|
- // ['relatedProductsInp', 'similarProductsInp', 'broadMatchInp', 'closeMatchInp'].forEach(field => {
|
|
|
|
- // ruleFormRef.value?.validateField(field);
|
|
|
|
- // });
|
|
|
|
- // }
|
|
|
|
- // });
|
|
|
|
-
|
|
|
|
- async function submitForm(formEl: FormInstance | undefined) {
|
|
|
|
- if (!formEl) return
|
|
|
|
- await formEl.validate((valid, fields) => {
|
|
|
|
- if (valid) {
|
|
|
|
- console.log('submit!')
|
|
|
|
- } else {
|
|
|
|
- console.log('error submit!', fields)
|
|
|
|
|
|
+ // 根据不同字段和状态返回特定的校验规则
|
|
|
|
+ switch (fieldName) {
|
|
|
|
+ case 'defaultBidInp':
|
|
|
|
+ if (ruleForm.autoRedirect === 'defaultBid') {
|
|
|
|
+ return commonRules
|
|
}
|
|
}
|
|
- })
|
|
|
|
|
|
+ break
|
|
|
|
+ case 'similarProductsInp':
|
|
|
|
+ if (ruleForm.autoRedirect === 'targetBid' && ruleForm.similarProducts) {
|
|
|
|
+ return commonRules
|
|
|
|
+ } else if (ruleForm.similarProducts == false) {
|
|
|
|
+ ruleFormRef.value?.clearValidate(fieldName)
|
|
|
|
+ }
|
|
|
|
+ break
|
|
|
|
+ case 'relatedProductsInp':
|
|
|
|
+ if (ruleForm.autoRedirect === 'targetBid' && ruleForm.relatedProducts) {
|
|
|
|
+ return commonRules
|
|
|
|
+ } else if (ruleForm.relatedProducts == false) {
|
|
|
|
+ ruleFormRef.value?.clearValidate(fieldName)
|
|
|
|
+ }
|
|
|
|
+ break
|
|
|
|
+ case 'broadMatchInp':
|
|
|
|
+ if (ruleForm.autoRedirect === 'targetBid' && ruleForm.broadMatch) {
|
|
|
|
+ return commonRules
|
|
|
|
+ } else if (ruleForm.broadMatch == false) {
|
|
|
|
+ ruleFormRef.value?.clearValidate(fieldName)
|
|
|
|
+ }
|
|
|
|
+ break
|
|
|
|
+ case 'closeMatchInp':
|
|
|
|
+ // 仅当autoRedirect为'targetBid'且closeMatch开启时校验closeMatchInp
|
|
|
|
+ if (ruleForm.autoRedirect === 'targetBid' && ruleForm.closeMatch) {
|
|
|
|
+ return commonRules
|
|
|
|
+ } else if (ruleForm.closeMatch == false) {
|
|
|
|
+ ruleFormRef.value?.clearValidate(fieldName)
|
|
|
|
+ }
|
|
|
|
+ break
|
|
|
|
+ default:
|
|
|
|
+ return []
|
|
}
|
|
}
|
|
|
|
+ // 如果不满足上述条件,则无需校验
|
|
|
|
+ return []
|
|
|
|
+}
|
|
|
|
|
|
- function resetForm(formEl: FormInstance | undefined) {
|
|
|
|
- if (!formEl) return
|
|
|
|
- formEl.resetFields()
|
|
|
|
|
|
+watch(
|
|
|
|
+ [() => ruleForm.autoRedirect, () => ruleForm.closeMatch, () => ruleForm.broadMatch, () => ruleForm.similarProducts, () => ruleForm.relatedProducts],
|
|
|
|
+ () => {
|
|
|
|
+ // 定义需要更新校验规则的字段
|
|
|
|
+ const fields = ['defaultBidInp', 'closeMatchInp', 'broadMatchInp', 'similarProductsInp', 'relatedProductsInp']
|
|
|
|
+ fields.forEach((field) => {
|
|
|
|
+ rules.value[field] = getValidationRules(field)
|
|
|
|
+ })
|
|
}
|
|
}
|
|
|
|
+)
|
|
|
|
+
|
|
|
|
+async function submitForm(formEl: FormInstance | undefined) {
|
|
|
|
+ if (!formEl) return
|
|
|
|
+ await formEl.validate((valid, fields) => {
|
|
|
|
+ if (valid) {
|
|
|
|
+ console.log('submit!')
|
|
|
|
+ } else {
|
|
|
|
+ console.log('error submit!', fields)
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function resetForm(formEl: FormInstance | undefined) {
|
|
|
|
+ if (!formEl) return
|
|
|
|
+ formEl.resetFields()
|
|
|
|
+}
|
|
|
|
|
|
- // const options = Array.from({ length: 10000 }).map((_, idx) => ({
|
|
|
|
- // value: `${idx + 1}`,
|
|
|
|
- // label: `${idx + 1}`,
|
|
|
|
- // }))
|
|
|
|
|
|
|
|
- // 商品模块
|
|
|
|
- const activeName = ref('first')
|
|
|
|
|
|
+const handleClick = (tab: TabsPaneContext, event: Event) => {
|
|
|
|
+ console.log(tab, event)
|
|
|
|
+}
|
|
|
|
|
|
- const handleClick = (tab: TabsPaneContext, event: Event) => {
|
|
|
|
- console.log(tab, event)
|
|
|
|
|
|
+// 修改表头样式
|
|
|
|
+const headerCellStyle = (args) => {
|
|
|
|
+ // console.log('args', args)
|
|
|
|
+ if (args.rowIndex === 0) {
|
|
|
|
+ return {
|
|
|
|
+ backgroundColor: 'rgba(245, 245, 245, 0.9)',
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+}
|
|
|
|
|
|
- const searchInp = ref('')
|
|
|
|
- const select = ref('name')
|
|
|
|
- const select2 = ref('latest')
|
|
|
|
- const textarea = ref('')
|
|
|
|
- const buttons = [{ type: 'primary', text: '添加' }] as const
|
|
|
|
-
|
|
|
|
- // 修改表头样式
|
|
|
|
- const headerCellStyle = (args) => {
|
|
|
|
- // console.log('args', args)
|
|
|
|
- if (args.rowIndex === 0) {
|
|
|
|
- return {
|
|
|
|
- backgroundColor: 'rgba(245, 245, 245, 0.9)',
|
|
|
|
- }
|
|
|
|
|
|
+function changeNegTableHeader(args) {
|
|
|
|
+ console.log('args', args)
|
|
|
|
+ if (args.rowIndex === 0) {
|
|
|
|
+ return {
|
|
|
|
+ color: '#505968',
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+}
|
|
|
|
|
|
- onMounted(() => {
|
|
|
|
- setTableData()
|
|
|
|
- // const myTest = route.query
|
|
|
|
- // console.log('myTest', myTest)
|
|
|
|
- })
|
|
|
|
|
|
+onMounted(() => {
|
|
|
|
+ setTableData()
|
|
|
|
+ // const myTest = route.query
|
|
|
|
+ // console.log('myTest', myTest)
|
|
|
|
+})
|
|
|
|
|
|
- defineOptions({
|
|
|
|
- name: 'SpCreateCampaigns',
|
|
|
|
- })
|
|
|
|
|
|
+defineOptions({
|
|
|
|
+ name: 'SpCreateCampaigns',
|
|
|
|
+})
|
|
</script>
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
<style lang="scss" scoped>
|
|
- ::v-deep(.el-form--default.el-form--label-top .el-form-item .el-form-item__label) {
|
|
|
|
- font-weight: 500;
|
|
|
|
- }
|
|
|
|
- .column-item .el-radio-group {
|
|
|
|
- display: inline-flex;
|
|
|
|
- font-size: 0;
|
|
|
|
- flex-direction: column;
|
|
|
|
- align-items: flex-start;
|
|
|
|
- }
|
|
|
|
- .radio-description {
|
|
|
|
- font-size: 12px;
|
|
|
|
- color: #666;
|
|
|
|
- margin-top: -18px;
|
|
|
|
- margin-left: 22px;
|
|
|
|
- }
|
|
|
|
- .radio-description-2 {
|
|
|
|
- font-size: 12px;
|
|
|
|
- color: #666;
|
|
|
|
- margin-top: -10px;
|
|
|
|
- }
|
|
|
|
- .column-margin-bottom label.el-radio.is-bordered {
|
|
|
|
- margin-bottom: 10px;
|
|
|
|
- padding: 35px;
|
|
|
|
- }
|
|
|
|
- ::v-deep(.column-margin-bottom label.el-radio.is-bordered span.el-radio__inner) {
|
|
|
|
- margin-top: -18px;
|
|
|
|
- margin-left: -15px;
|
|
|
|
- }
|
|
|
|
- .gap-items {
|
|
|
|
- display: flex;
|
|
|
|
- justify-content: flex-start;
|
|
|
|
- width: 100%;
|
|
|
|
- margin-bottom: 20px;
|
|
|
|
- }
|
|
|
|
- .gap-item {
|
|
|
|
- width: 200px;
|
|
|
|
- margin-left: 30px;
|
|
|
|
- color: #0b0d0d;
|
|
|
|
- }
|
|
|
|
|
|
+::v-deep(.el-form--default.el-form--label-top .el-form-item .el-form-item__label) {
|
|
|
|
+ font-weight: 500;
|
|
|
|
+}
|
|
|
|
+.column-item .el-radio-group {
|
|
|
|
+ display: inline-flex;
|
|
|
|
+ font-size: 0;
|
|
|
|
+ flex-direction: column;
|
|
|
|
+ align-items: flex-start;
|
|
|
|
+}
|
|
|
|
+.radio-description {
|
|
|
|
+ font-size: 12px;
|
|
|
|
+ color: #666;
|
|
|
|
+ margin-top: -18px;
|
|
|
|
+ margin-left: 22px;
|
|
|
|
+}
|
|
|
|
+.radio-description-2 {
|
|
|
|
+ font-size: 12px;
|
|
|
|
+ color: #666;
|
|
|
|
+ margin-top: -10px;
|
|
|
|
+}
|
|
|
|
+.column-margin-bottom label.el-radio.is-bordered {
|
|
|
|
+ margin-bottom: 10px;
|
|
|
|
+ padding: 35px;
|
|
|
|
+}
|
|
|
|
+::v-deep(.column-margin-bottom label.el-radio.is-bordered span.el-radio__inner) {
|
|
|
|
+ margin-top: -18px;
|
|
|
|
+ margin-left: -15px;
|
|
|
|
+}
|
|
|
|
+.gap-items {
|
|
|
|
+ display: flex;
|
|
|
|
+ justify-content: flex-start;
|
|
|
|
+ width: 100%;
|
|
|
|
+ margin-bottom: 20px;
|
|
|
|
+}
|
|
|
|
+.gap-item {
|
|
|
|
+ width: 200px;
|
|
|
|
+ margin-left: 30px;
|
|
|
|
+ color: #0b0d0d;
|
|
|
|
+}
|
|
|
|
|
|
- .demo-tabs > .el-tabs__content {
|
|
|
|
- padding: 52px;
|
|
|
|
- color: #6b778c;
|
|
|
|
- font-size: 32px;
|
|
|
|
- font-weight: 600;
|
|
|
|
- }
|
|
|
|
- /* 广告组商品Tab栏 */
|
|
|
|
- ::v-deep(.el-tabs__nav-scroll) {
|
|
|
|
- overflow: hidden;
|
|
|
|
- margin-left: 20px;
|
|
|
|
- }
|
|
|
|
- ::v-deep(.el-tabs__nav-wrap::after) {
|
|
|
|
- height: 2px !important;
|
|
|
|
- }
|
|
|
|
- ::v-deep(.el-table__inner-wrapper::before) {
|
|
|
|
- background-color: white;
|
|
|
|
- }
|
|
|
|
- // 表格内容边距
|
|
|
|
- div {
|
|
|
|
- & #pane-first,
|
|
|
|
- & #pane-second {
|
|
|
|
- margin: 10px;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- // 输入底部样式
|
|
|
|
- ::v-deep(.card-box .el-card__body) {
|
|
|
|
- display: flex;
|
|
|
|
- align-items: center;
|
|
|
|
- justify-content: space-between;
|
|
|
|
- padding: 12px;
|
|
|
|
- }
|
|
|
|
- .card-header {
|
|
|
|
- display: flex;
|
|
|
|
- justify-content: space-between;
|
|
|
|
- align-items: center;
|
|
|
|
- }
|
|
|
|
- .box-card {
|
|
|
|
- width: 100%;
|
|
|
|
- // margin: 10px 0 10px 10px;
|
|
|
|
- margin-right: 10px;
|
|
|
|
- border: none;
|
|
|
|
|
|
+.demo-tabs > .el-tabs__content {
|
|
|
|
+ padding: 52px;
|
|
|
|
+ color: #6b778c;
|
|
|
|
+ font-size: 32px;
|
|
|
|
+ font-weight: 600;
|
|
|
|
+}
|
|
|
|
+/* 广告组商品Tab栏 */
|
|
|
|
+::v-deep(.el-tabs__nav-scroll) {
|
|
|
|
+ overflow: hidden;
|
|
|
|
+ margin-left: 20px;
|
|
|
|
+}
|
|
|
|
+::v-deep(.el-tabs__nav-wrap::after) {
|
|
|
|
+ height: 2px !important;
|
|
|
|
+}
|
|
|
|
+::v-deep(.el-table__inner-wrapper::before) {
|
|
|
|
+ background-color: white;
|
|
|
|
+}
|
|
|
|
+// 表格内容边距
|
|
|
|
+div {
|
|
|
|
+ & #pane-first,
|
|
|
|
+ & #pane-second {
|
|
|
|
+ margin: 10px;
|
|
}
|
|
}
|
|
|
|
+}
|
|
|
|
+// 输入底部样式
|
|
|
|
+::v-deep(.card-box .el-card__body) {
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ justify-content: space-between;
|
|
|
|
+ padding: 12px;
|
|
|
|
+}
|
|
|
|
+.card-header {
|
|
|
|
+ display: flex;
|
|
|
|
+ justify-content: space-between;
|
|
|
|
+ align-items: center;
|
|
|
|
+}
|
|
|
|
+.box-card {
|
|
|
|
+ width: 100%;
|
|
|
|
+ // margin: 10px 0 10px 10px;
|
|
|
|
+ margin-right: 10px;
|
|
|
|
+ border: none;
|
|
|
|
+}
|
|
|
|
|
|
- .single-line {
|
|
|
|
- color: rgb(30, 33, 41);
|
|
|
|
- overflow: hidden;
|
|
|
|
- display: -webkit-box;
|
|
|
|
- -webkit-box-orient: vertical;
|
|
|
|
- -webkit-line-clamp: 1;
|
|
|
|
- white-space: pre-wrap;
|
|
|
|
- word-break: break-word;
|
|
|
|
- }
|
|
|
|
- .data-color {
|
|
|
|
- color: rgb(30, 33, 41);
|
|
|
|
- }
|
|
|
|
- .img-box {
|
|
|
|
- width: 60px;
|
|
|
|
- height: 60px;
|
|
|
|
- margin-top: 5px;
|
|
|
|
- border: 1px solid rgb(194, 199, 207);
|
|
|
|
- border-radius: 4px;
|
|
|
|
- }
|
|
|
|
- .target-group-item {
|
|
|
|
- margin-top: 15px;
|
|
|
|
- }
|
|
|
|
- .suggested-bid-item {
|
|
|
|
- margin-left: 230px;
|
|
|
|
- margin-right: 60px;
|
|
|
|
- }
|
|
|
|
- .bid-input {
|
|
|
|
- width: 200px;
|
|
|
|
- margin-left: 15px;
|
|
|
|
- }
|
|
|
|
|
|
+.single-line {
|
|
|
|
+ color: rgb(30, 33, 41);
|
|
|
|
+ overflow: hidden;
|
|
|
|
+ display: -webkit-box;
|
|
|
|
+ -webkit-box-orient: vertical;
|
|
|
|
+ -webkit-line-clamp: 1;
|
|
|
|
+ white-space: pre-wrap;
|
|
|
|
+ word-break: break-word;
|
|
|
|
+}
|
|
|
|
+.data-color {
|
|
|
|
+ color: rgb(30, 33, 41);
|
|
|
|
+}
|
|
|
|
+.img-box {
|
|
|
|
+ width: 60px;
|
|
|
|
+ height: 60px;
|
|
|
|
+ margin-top: 5px;
|
|
|
|
+ border: 1px solid rgb(194, 199, 207);
|
|
|
|
+ border-radius: 4px;
|
|
|
|
+}
|
|
|
|
+.target-group-item {
|
|
|
|
+ margin-top: 15px;
|
|
|
|
+}
|
|
|
|
+.suggested-bid-item {
|
|
|
|
+ margin-left: 230px;
|
|
|
|
+ margin-right: 60px;
|
|
|
|
+}
|
|
|
|
+.bid-input {
|
|
|
|
+ width: 200px;
|
|
|
|
+ margin-left: 15px;
|
|
|
|
+}
|
|
</style>
|
|
</style>
|