|
@@ -1,9 +1,282 @@
|
|
<template>
|
|
<template>
|
|
- <p>新建广告页面</p>
|
|
|
|
|
|
+ <div>
|
|
|
|
+ <el-card>
|
|
|
|
+ <div style="padding-left: 5px">
|
|
|
|
+ <div style="font-size: 20px; font-weight: bold">广告活动</div>
|
|
|
|
+ <hr />
|
|
|
|
+ <br />
|
|
|
|
+ <el-form
|
|
|
|
+ :label-position="labelPosition"
|
|
|
|
+ ref="ruleFormRef"
|
|
|
|
+ :model="ruleForm"
|
|
|
|
+ :rules="rules"
|
|
|
|
+ label-width="120px"
|
|
|
|
+ class="demo-ruleForm"
|
|
|
|
+ :size="formSize"
|
|
|
|
+ status-icon
|
|
|
|
+ >
|
|
|
|
+ <el-form-item label="广告活动名称" prop="name" style="width: 350px">
|
|
|
|
+ <el-input v-model="ruleForm.name" />
|
|
|
|
+ </el-form-item>
|
|
|
|
+ <el-form-item label="广告组合" prop="adMix">
|
|
|
|
+ <el-select v-model="ruleForm.adMix" placeholder="Activity zone">
|
|
|
|
+ <el-option label="Zone one" value="shanghai" />
|
|
|
|
+ <el-option label="Zone two" value="beijing" />
|
|
|
|
+ </el-select>
|
|
|
|
+ </el-form-item>
|
|
|
|
+
|
|
|
|
+ <el-form-item prop="date1" label="开始日期" style="width: 350px">
|
|
|
|
+ <el-date-picker v-model="ruleForm.date1" type="date" label="开始日期" placeholder="开始日期" style="width: 100%" />
|
|
|
|
+ </el-form-item>
|
|
|
|
+ <el-form-item prop="date2" label="结束日期" style="width: 350px">
|
|
|
|
+ <el-date-picker v-model="ruleForm.date2" label="结束日期" placeholder="结束日期" style="width: 100%" />
|
|
|
|
+ </el-form-item>
|
|
|
|
+ <el-form-item prop="budget" label="每日预算" style="width: 350px">
|
|
|
|
+ <el-input v-model="ruleForm.budget" />
|
|
|
|
+ </el-form-item>
|
|
|
|
+ <!-- <el-form-item label="Instant delivery" prop="delivery">
|
|
|
|
+ <el-switch v-model="ruleForm.delivery" />
|
|
|
|
+ </el-form-item> -->
|
|
|
|
+ <el-form-item label="投放类型" prop="type" class="column-item">
|
|
|
|
+ <el-radio-group v-model="ruleForm.type" @click="changeType">
|
|
|
|
+ <div>
|
|
|
|
+ <el-radio label="auto">自动</el-radio>
|
|
|
|
+ <div class="radio-description">定向与您推广商品相似的关键词和商品</div>
|
|
|
|
+ </div>
|
|
|
|
+ <div>
|
|
|
|
+ <el-radio label="manual">手动</el-radio>
|
|
|
|
+ <div class="radio-description">选择关键词或商品以定向购物者搜索并设置自定义出价</div>
|
|
|
|
+ </div>
|
|
|
|
+ </el-radio-group>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ <el-form-item label="竞价策略" prop="bidStrategy" class="column-item column-margin-bottom">
|
|
|
|
+ <el-radio-group v-model="ruleForm.bidStrategy">
|
|
|
|
+ <div>
|
|
|
|
+ <el-radio label="dynamicBid_Low" border>动态竞价-仅降低
|
|
|
|
+ <div class="radio-description-2">当您的广告不太可能带来销售时,我们将实时降低您的竞价</div>
|
|
|
|
+ </el-radio>
|
|
|
|
+ </div>
|
|
|
|
+ <div>
|
|
|
|
+ <el-radio label="dynamicBid_HighAndLow" border>动态竞价-提高和降低
|
|
|
|
+ <div class="radio-description-2">
|
|
|
|
+ 当您的广告很有可能带来销售时,我们将实时提高您的竞价(最高可达 100%),并在您的广告不太可能带来销售时降低您的竞价
|
|
|
|
+ </div>
|
|
|
|
+ </el-radio>
|
|
|
|
+ </div>
|
|
|
|
+ <el-radio label="staticBid" border>固定竞价
|
|
|
|
+ <div class="radio-description-2">我们将使用您的确切竞价和您设置的任何手动调整,而不会根据售出可能性对您的竞价进行更改</div>
|
|
|
|
+ </el-radio>
|
|
|
|
+ </el-radio-group>
|
|
|
|
+ </el-form-item>
|
|
|
|
+
|
|
|
|
+ <el-form
|
|
|
|
+ :label-position="labelPosition"
|
|
|
|
+ ref="ruleFormRef2"
|
|
|
|
+ :model="ruleForm2"
|
|
|
|
+ :rules="rules2"
|
|
|
|
+ label-width="120px"
|
|
|
|
+ class="demo-ruleForm"
|
|
|
|
+ :size="formSize"
|
|
|
|
+ status-icon
|
|
|
|
+ >
|
|
|
|
+ <el-form-item label="按展示位置调整出价" prop="placeBid">
|
|
|
|
+ <p style="color: #8e9196">除了出价策略外,您还可以将出价提高多达900%</p>
|
|
|
|
+ <div class="gap-items">
|
|
|
|
+ <div class="gap-item">搜索结果顶部(首页)</div>
|
|
|
|
+ <el-input v-model="ruleForm2.placeBid" class="gap-item">
|
|
|
|
+ <template #append>%</template>
|
|
|
|
+ </el-input>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="gap-items">
|
|
|
|
+ <div class="gap-item">商品首页</div>
|
|
|
|
+ <el-input v-model="ruleForm2.firstPage" class="gap-item">
|
|
|
|
+ <template #append>%</template>
|
|
|
|
+ </el-input>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="gap-items">
|
|
|
|
+ <div class="gap-item">搜索结果的其余位置</div>
|
|
|
|
+ <el-input v-model="ruleForm2.other" class="gap-item">
|
|
|
|
+ <template #append>%</template>
|
|
|
|
+ </el-input>
|
|
|
|
+ </div>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ </el-form>
|
|
|
|
+
|
|
|
|
+ <el-form-item>
|
|
|
|
+ <el-button type="primary" @click="submitForm">Create</el-button>
|
|
|
|
+ <el-button @click="resetForm(ruleFormRef)">Reset</el-button>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ </el-form>
|
|
|
|
+ </div>
|
|
|
|
+ </el-card>
|
|
|
|
+ </div>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
<script lang="ts" setup>
|
|
|
|
+import { onMounted, reactive, ref } from 'vue'
|
|
|
|
+import { useRoute } from 'vue-router'
|
|
|
|
+import type { FormInstance, FormRules } from 'element-plus'
|
|
|
|
+
|
|
|
|
+const route = useRoute()
|
|
|
|
+
|
|
|
|
+// 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
|
|
|
|
+}
|
|
|
|
+interface RuleForm2 {
|
|
|
|
+ placeBid: string
|
|
|
|
+ firstPage: string
|
|
|
|
+ other: string
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+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',
|
|
|
|
+})
|
|
|
|
+const rules = reactive<FormRules<RuleForm>>({
|
|
|
|
+ name: [
|
|
|
|
+ {required: true, message: 'Please input Activity name', trigger: 'blur' },
|
|
|
|
+ {min: 3, max: 5, message: 'Length should be 3 to 5', 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'} ],
|
|
|
|
+ type: [ {required: false, message: 'Please select at least one activity type', trigger: 'change'} ],
|
|
|
|
+ bidStrategy: [ {required: true, message: 'Please select activity resource', trigger: 'change'} ],
|
|
|
|
+})
|
|
|
|
+
|
|
|
|
+const ruleFormRef2 = ref<FormInstance>()
|
|
|
|
+const ruleForm2 = reactive<RuleForm2>({
|
|
|
|
+ placeBid: '',
|
|
|
|
+ firstPage: '',
|
|
|
|
+ other: '',
|
|
|
|
+})
|
|
|
|
+const rules2 = reactive<FormRules<RuleForm2>>({
|
|
|
|
+ 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' }],
|
|
|
|
+})
|
|
|
|
+
|
|
|
|
+async function submitForm() {
|
|
|
|
+ let isValid = true
|
|
|
|
+
|
|
|
|
+ // 校验第一个表单
|
|
|
|
+ if (ruleFormRef.value) {
|
|
|
|
+ await ruleFormRef.value.validate((valid) => {
|
|
|
|
+ if (!valid) {
|
|
|
|
+ console.log('Error in form 1')
|
|
|
|
+ isValid = false
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ // 校验第二个表单
|
|
|
|
+ if (isValid && ruleFormRef2.value) {
|
|
|
|
+ await ruleFormRef2.value.validate((valid) => {
|
|
|
|
+ if (!valid) {
|
|
|
|
+ console.log('Error in form 2')
|
|
|
|
+ isValid = false
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ // 如果两个表单都通过校验,则继续后续操作
|
|
|
|
+ if (isValid) {
|
|
|
|
+ console.log('Both forms are valid. Proceed with the submission.')
|
|
|
|
+ // 这里可以放置提交表单的逻辑
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function resetForm(formEl: FormInstance | undefined) {
|
|
|
|
+ if (!formEl) return
|
|
|
|
+ formEl.resetFields()
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const options = Array.from({ length: 10000 }).map((_, idx) => ({
|
|
|
|
+ value: `${idx + 1}`,
|
|
|
|
+ label: `${idx + 1}`,
|
|
|
|
+}))
|
|
|
|
+
|
|
|
|
+function changeType() {
|
|
|
|
+ console.log(ruleForm.type)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+onMounted(() => {
|
|
|
|
+ const myTest = route.query
|
|
|
|
+ console.log(222, myTest)
|
|
|
|
+})
|
|
|
|
+
|
|
|
|
+defineOptions({
|
|
|
|
+ name: 'SpCreateCampaigns',
|
|
|
|
+})
|
|
|
|
+
|
|
|
|
+// ::v-deep(.column-margin-bottom span.el-radio__input.is-checked) {
|
|
|
|
+// margin-top: -20px;
|
|
|
|
+// margin-left: -15px;
|
|
|
|
+// }
|
|
</script>
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
<style 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;
|
|
|
|
+}
|
|
</style>
|
|
</style>
|