|
@@ -5,145 +5,39 @@
|
|
|
<span class="custom-card-icon">|</span>
|
|
|
<span class="custom-card-Text">创意</span>
|
|
|
</div>
|
|
|
- <div class="main-container">
|
|
|
+ <div style="display: flex;">
|
|
|
<div class="left-container">
|
|
|
<p class="left-part-title">请选择您想要自定义商品广告的方式</p>
|
|
|
- <el-scrollbar height="640px">
|
|
|
- <div class="demo-collapse">
|
|
|
- <el-collapse v-model="activeNames" @change="handleCollapseChange" style="border: none">
|
|
|
- <el-collapse-item title="徽标" name="logo">
|
|
|
- <div style="display: flex; margin-bottom: 5px">
|
|
|
- <p style="font-weight: 700; color: #1d2129; margin-right: 8px">品牌标识</p>
|
|
|
- <el-switch v-model="isOpenLogo" size="small" />
|
|
|
- </div>
|
|
|
- <el-upload
|
|
|
- v-model:file-list="fileList"
|
|
|
- :on-change="changeFile"
|
|
|
- v-loading="upLoading"
|
|
|
- :on-remove="handleRemove"
|
|
|
- action="#"
|
|
|
- accept=".png, .jpg"
|
|
|
- :limit="1"
|
|
|
- list-type="picture-card"
|
|
|
- :auto-upload="false">
|
|
|
- <el-icon><Plus /></el-icon>
|
|
|
- <template #file="{ file }">
|
|
|
- <div>
|
|
|
- <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
|
|
|
- <span class="el-upload-list__item-actions">
|
|
|
- <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
|
|
|
- <el-icon><zoom-in /></el-icon>
|
|
|
- </span>
|
|
|
- <span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file)">
|
|
|
- <el-icon><Delete /></el-icon>
|
|
|
- </span>
|
|
|
- </span>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- <template #tip>
|
|
|
- <div style="margin-top: 10px">
|
|
|
- <div style="display: flex; align-items: center; justify-content: space-between">
|
|
|
- <span style="line-height: 17px; font-weight: 600; color: #1e2128">徽标要求</span>
|
|
|
- <!-- <el-button type="primary" :icon="Picture" @click="openDialog">从素材库中选择</el-button> -->
|
|
|
- </div>
|
|
|
- <div class="introduce-item">1、图片大小: 至少600x100像素</div>
|
|
|
- <div class="introduce-item">2、文件大小: 小于1MB</div>
|
|
|
- <div style="display: flex; justify-content: space-between">
|
|
|
- <span class="introduce-item">3、文件格式: PNG 或 JPG</span>
|
|
|
- <span style="margin-left: 25px; position: relative">
|
|
|
- <el-icon size="14" style="position: absolute; left: -14px; top: 6px"><Link /></el-icon>
|
|
|
- <el-link
|
|
|
- type="primary"
|
|
|
- :underline="false"
|
|
|
- href="https://advertising.amazon.com/resources/ad-policy/sponsored-ads-policies#brandlogo"
|
|
|
- target="_blank"
|
|
|
- >查看要求</el-link
|
|
|
- >
|
|
|
- </span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- </el-upload>
|
|
|
- <!-- 预览弹窗 -->
|
|
|
- <el-dialog v-model="dialogVisible">
|
|
|
- <img w-full :src="dialogImageUrl" alt="Preview Image" />
|
|
|
- </el-dialog>
|
|
|
- </el-collapse-item>
|
|
|
- <el-collapse-item title="标题" name="title">
|
|
|
- <template #title style="position: relative">
|
|
|
- <span>标题</span>
|
|
|
-
|
|
|
- <el-icon size="14" style="position: absolute; right: 85px"><Link /></el-icon>
|
|
|
- <el-link
|
|
|
- type="primary"
|
|
|
- href="https://advertising.amazon.com/resources/ad-policy/creative-acceptance#editorialguidelines"
|
|
|
- target="_blank"
|
|
|
- :underline="false"
|
|
|
- style="position: absolute; right: 30px">
|
|
|
- 查看政策
|
|
|
- </el-link>
|
|
|
- </template>
|
|
|
- <div style="display: flex">
|
|
|
- <el-switch v-model="isOpenTitle" style="margin-right: 10px" />
|
|
|
- <el-input v-model="titleInp" maxlength="50" show-word-limit placeholder="Please input" type="text" />
|
|
|
- </div>
|
|
|
- </el-collapse-item>
|
|
|
- <el-collapse-item title="图片" name="image">
|
|
|
- <div style="display: flex; margin-bottom: 5px">
|
|
|
- <p style="font-weight: 700; color: #1d2129; margin-right: 8px">添加图片</p>
|
|
|
- <el-switch v-model="isOpenPicture" size="small" />
|
|
|
- </div>
|
|
|
- <el-upload
|
|
|
- v-model:file-list="pictureFile"
|
|
|
- :on-change="changePicture"
|
|
|
- v-loading="pictureLoading"
|
|
|
- :on-remove="handleRemovePicture"
|
|
|
- action="#"
|
|
|
- accept=".png, .jpeg, .gif"
|
|
|
- :limit="1"
|
|
|
- list-type="picture-card"
|
|
|
- :auto-upload="false">
|
|
|
- <el-icon><Plus /></el-icon>
|
|
|
- <template #file="{ file }">
|
|
|
- <div>
|
|
|
- <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
|
|
|
- <span class="el-upload-list__item-actions">
|
|
|
- <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
|
|
|
- <el-icon><zoom-in /></el-icon>
|
|
|
- </span>
|
|
|
- <span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file)">
|
|
|
- <el-icon><Delete /></el-icon>
|
|
|
- </span>
|
|
|
- </span>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- <template #tip>
|
|
|
- <div style="margin-top: 10px">
|
|
|
- <div style="display: flex; align-items: center; justify-content: space-between">
|
|
|
- <span style="line-height: 17px; font-weight: 600; color: #1e2128">徽标要求</span>
|
|
|
- <!-- <el-button type="primary" :icon="Picture" @click="openDialog">从素材库中选择</el-button> -->
|
|
|
- </div>
|
|
|
- <div class="introduce-item">1、图片大小: 至少 1200x628 像素</div>
|
|
|
- <div class="introduce-item">2、文件大小: 小于5MB</div>
|
|
|
- <div class="introduce-item">3、文件格式: PNG, JPEG 或GIF</div>
|
|
|
- <div class="introduce-item">4、没有在图片上添加文字, 图形或徽标</div>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- </el-upload>
|
|
|
- <!-- 预览弹窗 -->
|
|
|
- <el-dialog v-model="dialogVisible">
|
|
|
- <img w-full :src="dialogImageUrl" alt="Preview Image" />
|
|
|
- </el-dialog>
|
|
|
- </el-collapse-item>
|
|
|
- </el-collapse>
|
|
|
- </div>
|
|
|
- </el-scrollbar>
|
|
|
+ <div class="demo-collapse">
|
|
|
+ <el-collapse v-model="activeNames" @change="handleCollapseChange" style="border: none;">
|
|
|
+ <el-collapse-item title="徽标" name="logo">
|
|
|
+ <div>
|
|
|
+ Consistent with real life: in line with the process and logic of real life, and comply with languages and habits that the users are
|
|
|
+ used to;
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ Consistent within interface: all elements should be consistent, such as: design style, icons and texts, position of elements, etc.
|
|
|
+ </div>
|
|
|
+ </el-collapse-item>
|
|
|
+ <el-collapse-item title="标题" name="title">
|
|
|
+ <div>Operation feedback: enable the users to clearly perceive their operations by style updates and interactive effects;</div>
|
|
|
+ <div>Visual feedback: reflect current state by updating or rearranging elements of the page.</div>
|
|
|
+ </el-collapse-item>
|
|
|
+ <el-collapse-item title="图片" name="image">
|
|
|
+ <div>Simplify the process: keep operating process simple and intuitive;</div>
|
|
|
+ <div>Definite and clear: enunciate your intentions clearly so that the users can quickly understand and make decisions;</div>
|
|
|
+ <div>
|
|
|
+ Easy to identify: the interface should be straightforward, which helps the users to identify and frees them from memorizing and
|
|
|
+ recalling.
|
|
|
+ </div>
|
|
|
+ </el-collapse-item>
|
|
|
+ </el-collapse>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
<div class="right-container">
|
|
|
<div class="preview-title-line">
|
|
|
<p class="right-part-title">广告预览</p>
|
|
|
<el-select></el-select>
|
|
|
- <el-button style="margin-left: 10px">保存</el-button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
@@ -152,192 +46,14 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
-import { ref, inject, Ref, onMounted, watch } from 'vue'
|
|
|
-import { Delete, Picture, Plus, ZoomIn } from '@element-plus/icons-vue'
|
|
|
-import type { UploadFile } from 'element-plus'
|
|
|
-import { ElMessage } from 'element-plus'
|
|
|
-import { uploadFile, checkAsset, postCreative } from '../api/index'
|
|
|
-import { useShopInfo } from '/@/stores/shopInfo'
|
|
|
-import { storeToRefs } from 'pinia'
|
|
|
-import emitter from '/@/utils/emitter'
|
|
|
-
|
|
|
-const respAdGroupId = inject<Ref>('respAdGroupId')
|
|
|
-const shopInfo = useShopInfo()
|
|
|
-const { profile } = storeToRefs(shopInfo)
|
|
|
+import { ref } from 'vue'
|
|
|
|
|
|
// 折叠面板相关
|
|
|
const activeNames = ref([''])
|
|
|
|
|
|
function handleCollapseChange(val: string[]) {
|
|
|
- // console.log(val)
|
|
|
-}
|
|
|
-
|
|
|
-// logo相关
|
|
|
-const fileList = ref([])
|
|
|
-const upLoading = ref(false)
|
|
|
-const disabled = ref(false)
|
|
|
-const dialogVisible = ref(false)
|
|
|
-const dialogImageUrl = ref('')
|
|
|
-const centerDialogVisible = ref(false)
|
|
|
-
|
|
|
-function changeFile(file: UploadFile) {
|
|
|
- handleUpload(file)
|
|
|
-}
|
|
|
-
|
|
|
-function handleRemove(file: UploadFile) {
|
|
|
- fileList.value = []
|
|
|
+ console.log(val)
|
|
|
}
|
|
|
-
|
|
|
-function handlePictureCardPreview(file: UploadFile) {
|
|
|
- dialogImageUrl.value = file.url!
|
|
|
- dialogVisible.value = true
|
|
|
-}
|
|
|
-// 文件上传相关
|
|
|
-const brandEntityId = ref('')
|
|
|
-let brandLogoAssetID = ''
|
|
|
-let brandLogoAssetVersion = ''
|
|
|
-let brandLogoCrop = {}
|
|
|
-const isOpenLogo = ref(false)
|
|
|
-
|
|
|
-async function handleUpload(file: UploadFile) {
|
|
|
- const formData = new FormData()
|
|
|
- formData.append('file', file.raw)
|
|
|
- formData.append('profile_id', profile.value.profile_id)
|
|
|
- formData.append('brandEntityId', brandEntityId.value)
|
|
|
- formData.append('assetType', 'IMAGE')
|
|
|
- formData.append('assetSubTypeList', JSON.stringify(['LOGO']))
|
|
|
- upLoading.value = true
|
|
|
- try {
|
|
|
- const response = await uploadFile(formData)
|
|
|
- brandLogoAssetVersion = response.data.versionId
|
|
|
- const fileName = response.data.file_name
|
|
|
- const obj = {
|
|
|
- profile_id: profile.value.profile_id,
|
|
|
- file_name: fileName,
|
|
|
- }
|
|
|
- const resp = await checkAsset(obj)
|
|
|
- brandLogoAssetID = resp.data.assetId
|
|
|
-
|
|
|
- const { width, height } = resp.data.fileMetadata
|
|
|
- brandLogoCrop = {
|
|
|
- width,
|
|
|
- height,
|
|
|
- top: 0,
|
|
|
- left: 0,
|
|
|
- }
|
|
|
- if (resp.data.checkresult == 'success') {
|
|
|
- ElMessage({ message: '上传成功', type: 'success' })
|
|
|
- } else {
|
|
|
- ElMessage.error('上传失败')
|
|
|
- }
|
|
|
- } catch (error) {
|
|
|
- console.error('上传失败:', error)
|
|
|
- } finally {
|
|
|
- upLoading.value = false
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-function openDialog() {
|
|
|
- centerDialogVisible.value = true
|
|
|
- // getAssetsData()
|
|
|
-}
|
|
|
-
|
|
|
-// title相关
|
|
|
-const titleInp = ref('')
|
|
|
-const isOpenTitle = ref(false)
|
|
|
-
|
|
|
-// 图片相关
|
|
|
-const pictureFile = ref([])
|
|
|
-const pictureLoading = ref(false)
|
|
|
-const isOpenPicture = ref(false)
|
|
|
-let pictureAssetVersion = ''
|
|
|
-let pictureAssetID = ''
|
|
|
-
|
|
|
-function changePicture(file: UploadFile) {
|
|
|
- handleUploadPicture(file)
|
|
|
-}
|
|
|
-
|
|
|
-function handleRemovePicture(file: UploadFile) {
|
|
|
- fileList.value = []
|
|
|
-}
|
|
|
-
|
|
|
-async function handleUploadPicture(file: UploadFile) {
|
|
|
- const formData = new FormData()
|
|
|
- formData.append('file', file.raw)
|
|
|
- formData.append('profile_id', profile.value.profile_id)
|
|
|
- formData.append('brandEntityId', brandEntityId.value)
|
|
|
- formData.append('assetType', 'IMAGE')
|
|
|
- formData.append('assetSubTypeList', JSON.stringify(['LOGO']))
|
|
|
- upLoading.value = true
|
|
|
- try {
|
|
|
- const response = await uploadFile(formData)
|
|
|
- pictureAssetVersion = response.data.versionId
|
|
|
- const fileName = response.data.file_name
|
|
|
- const obj = {
|
|
|
- profile_id: profile.value.profile_id,
|
|
|
- file_name: fileName,
|
|
|
- }
|
|
|
- const resp = await checkAsset(obj)
|
|
|
- pictureAssetID = resp.data.assetId
|
|
|
-
|
|
|
- const { width, height } = resp.data.fileMetadata
|
|
|
- brandLogoCrop = {
|
|
|
- width,
|
|
|
- height,
|
|
|
- top: 0,
|
|
|
- left: 0,
|
|
|
- }
|
|
|
- if (resp.data.checkresult == 'success') {
|
|
|
- ElMessage({ message: '上传成功', type: 'success' })
|
|
|
- } else {
|
|
|
- ElMessage.error('上传失败')
|
|
|
- }
|
|
|
- } catch (error) {
|
|
|
- console.error('上传失败:', error)
|
|
|
- } finally {
|
|
|
- upLoading.value = false
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-const createLoading = ref(false)
|
|
|
-
|
|
|
-async function createCreativity() {
|
|
|
- createLoading.value = true
|
|
|
- const obj = {
|
|
|
- profile_id: profile.value.profile_id,
|
|
|
- adGroupId: respAdGroupId.value,
|
|
|
- properties_logo: isOpenLogo.value,
|
|
|
- properties_head: isOpenTitle.value,
|
|
|
- properties_custom: isOpenPicture.value,
|
|
|
- headline: '',
|
|
|
- brandLogo_assetId: '',
|
|
|
- brandLogo_assetVersion: '',
|
|
|
- brandLogo_croppingCoordinates: brandLogoCrop,
|
|
|
- contentType: '',
|
|
|
- rectCustomImage_assetId: '',
|
|
|
- rectCustomImage_assetVersion: '',
|
|
|
- squareCustomImage_assetId: '',
|
|
|
- squareCustomImage_assetVersion: '',
|
|
|
- }
|
|
|
- try {
|
|
|
- const response = await postCreative(obj)
|
|
|
- if (response.data.creative_state == 'success') {
|
|
|
- ElMessage({ message: '创建成功', type: 'success' })
|
|
|
- } else {
|
|
|
- ElMessage.error('上传失败')
|
|
|
- }
|
|
|
- } catch (error) {
|
|
|
- console.error('error:', error)
|
|
|
- } finally {
|
|
|
- createLoading.value = false
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-onMounted(() => {
|
|
|
- emitter.on('send-brandEntityId', (value: any) => {
|
|
|
- brandEntityId.value = value.brandEntityId[0].brandEntityId
|
|
|
- })
|
|
|
-})
|
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
@@ -356,17 +72,8 @@ onMounted(() => {
|
|
|
color: #306cd7;
|
|
|
font-size: 26px;
|
|
|
}
|
|
|
-.main-container {
|
|
|
- display: flex;
|
|
|
- border: 1px solid #e5e7eb;
|
|
|
- height: 700px;
|
|
|
- margin-bottom: 20px;
|
|
|
- border-radius: 6px;
|
|
|
-}
|
|
|
.left-container {
|
|
|
width: 50%;
|
|
|
- padding: 10px;
|
|
|
- border-right: 1px solid #e5e7eb;
|
|
|
}
|
|
|
.left-part-title {
|
|
|
color: #4e5969;
|
|
@@ -387,9 +94,4 @@ onMounted(() => {
|
|
|
font-weight: 700;
|
|
|
line-height: 32px;
|
|
|
}
|
|
|
-.introduce-item {
|
|
|
- line-height: 17px;
|
|
|
- font-size: 12px;
|
|
|
- color: #88909b;
|
|
|
-}
|
|
|
</style>
|