feat(property-marketing): 新增投放指南详情页功能
refactor(property-marketing): 优化评分图标映射逻辑 feat(property-marketing): 实现投放指南历史记录操作功能 perf(property-marketing): 优化图表数据更新逻辑 feat(property-marketing): 添加时间筛选功能 实现保存投放指南功能 - 优化页面样式和布局
This commit is contained in:
@ -25,23 +25,12 @@
|
||||
<div class="overall-strategy">
|
||||
<span class="placement-optimization-title">人群分析</span>
|
||||
<a-space direction="vertical">
|
||||
<a-space class="placement-optimization-str">
|
||||
<span>
|
||||
<img :src="getStarIcon(1)" style="width: 25px; height: 17px" />
|
||||
18-24岁女性,兴趣为“美妆/穿搭”,一线城市,抖音平台 ROI 3.2</span
|
||||
>
|
||||
</a-space>
|
||||
<a-space>
|
||||
<span>
|
||||
<img :src="getStarIcon(2)" style="width: 25px; height: 17px" />
|
||||
25-34岁男性,兴趣为“数码产品”,二线城市,巨量引擎 ROI 2.8</span
|
||||
>
|
||||
</a-space>
|
||||
<a-space>
|
||||
<span>
|
||||
<img :src="getStarIcon(3)" style="width: 25px; height: 17px" />
|
||||
18-24岁男性,兴趣为“运动/健身”,三线城市,抖音 ROI 2.3</span
|
||||
>
|
||||
<a-space
|
||||
v-if="getSubmoduleContent(MODEL_PERFORMANCE_ANALYSIS, '人群分析').length > 0"
|
||||
v-for="(item, index) in getSubmoduleContent(MODEL_PERFORMANCE_ANALYSIS, '人群分析')"
|
||||
:key="index"
|
||||
>
|
||||
<span><img :src="getStarIcon(index)" style="width: 25px; height: 17px" />{{ item }}</span>
|
||||
</a-space>
|
||||
</a-space>
|
||||
</div>
|
||||
@ -50,23 +39,12 @@
|
||||
<div class="overall-strategy">
|
||||
<span class="placement-optimization-title">投放素材</span>
|
||||
<a-space direction="vertical">
|
||||
<a-space class="placement-optimization-str">
|
||||
<span>
|
||||
<img :src="getStarIcon(1)" style="width: 25px; height: 17px" />
|
||||
图文风格 + 明确福利点,CTR 3.2%、CVR 8.5%</span
|
||||
>
|
||||
</a-space>
|
||||
<a-space>
|
||||
<span>
|
||||
<img :src="getStarIcon(1)" style="width: 25px; height: 17px" />
|
||||
场景短视频 + 明确人设定位,CTR 2.7%、CVR 7.1%</span
|
||||
>
|
||||
</a-space>
|
||||
<a-space>
|
||||
<span>
|
||||
<img :src="getStarIcon(1)" style="width: 25px; height: 17px" />
|
||||
口播讲解类 + 产品对比,CTR 2.1%、CVR 6.0%</span
|
||||
>
|
||||
<a-space
|
||||
v-if="getSubmoduleContent(MODEL_PERFORMANCE_ANALYSIS, '投放素材').length > 0"
|
||||
v-for="(item, index) in getSubmoduleContent(MODEL_PERFORMANCE_ANALYSIS, '投放素材')"
|
||||
:key="index"
|
||||
>
|
||||
<span><img :src="getStarIcon(index)" style="width: 25px; height: 17px" />{{ item }}</span>
|
||||
</a-space>
|
||||
</a-space>
|
||||
</div>
|
||||
@ -77,23 +55,12 @@
|
||||
<div class="overall-strategy">
|
||||
<span class="placement-optimization-title">投放时段</span>
|
||||
<a-space direction="vertical">
|
||||
<a-space class="placement-optimization-str">
|
||||
<span>
|
||||
<img :src="getStarIcon(1)" style="width: 25px; height: 17px" />
|
||||
晚高峰时段(19:00–21:00),ROI 3.1</span
|
||||
>
|
||||
</a-space>
|
||||
<a-space>
|
||||
<span>
|
||||
<img :src="getStarIcon(1)" style="width: 25px; height: 17px" />
|
||||
中午时段(11:30–13:00),ROI 2.5</span
|
||||
>
|
||||
</a-space>
|
||||
<a-space>
|
||||
<span>
|
||||
<img :src="getStarIcon(1)" style="width: 25px; height: 17px" />
|
||||
下午茶时段(15:00–17:00),ROI 2.3</span
|
||||
>
|
||||
<a-space
|
||||
v-if="getSubmoduleContent(MODEL_PERFORMANCE_ANALYSIS, '投放时段').length > 0"
|
||||
v-for="(item, index) in getSubmoduleContent(MODEL_PERFORMANCE_ANALYSIS, '投放时段')"
|
||||
:key="index"
|
||||
>
|
||||
<span><img :src="getStarIcon(index)" style="width: 25px; height: 17px" />{{ item }}</span>
|
||||
</a-space>
|
||||
</a-space>
|
||||
</div>
|
||||
@ -103,23 +70,12 @@
|
||||
<div class="overall-strategy">
|
||||
<span class="placement-optimization-title">平台表现</span>
|
||||
<a-space direction="vertical">
|
||||
<a-space class="placement-optimization-str">
|
||||
<span>
|
||||
<img :src="getStarIcon(1)" style="width: 25px; height: 17px" />
|
||||
抖音 - ROI 3.2,CVR 8.5%</span
|
||||
>
|
||||
</a-space>
|
||||
<a-space>
|
||||
<span>
|
||||
<img :src="getStarIcon(2)" style="width: 25px; height: 17px" />
|
||||
聚光平台 - ROI 2.7,CVR 7.3%</span
|
||||
>
|
||||
</a-space>
|
||||
<a-space>
|
||||
<span>
|
||||
<img :src="getStarIcon(3)" style="width: 25px; height: 17px" />
|
||||
B站 - ROI 2.4,CVR 6.8%</span
|
||||
>
|
||||
<a-space
|
||||
v-if="getSubmoduleContent(MODEL_PERFORMANCE_ANALYSIS, '平台表现').length > 0"
|
||||
v-for="(item, index) in getSubmoduleContent(MODEL_PERFORMANCE_ANALYSIS, '平台表现')"
|
||||
:key="index"
|
||||
>
|
||||
<span><img :src="getStarIcon(index)" style="width: 25px; height: 17px" />{{ item }}</span>
|
||||
</a-space>
|
||||
</a-space>
|
||||
</div>
|
||||
@ -140,23 +96,12 @@
|
||||
<div class="overall-strategy">
|
||||
<span class="placement-optimization-title">人群建议</span>
|
||||
<a-space direction="vertical">
|
||||
<a-space class="placement-optimization-str">
|
||||
<span>
|
||||
<img :src="getStarIcon(1)" style="width: 25px; height: 17px" />
|
||||
集中在 18–24 岁女性 + 精准兴趣标签(如“护肤”、“口红”)</span
|
||||
>
|
||||
</a-space>
|
||||
<a-space>
|
||||
<span>
|
||||
<img :src="getStarIcon(2)" style="width: 25px; height: 17px" />
|
||||
24–30 岁男性 + 实用类内容受众(如“工具控”、“搞机党”)</span
|
||||
>
|
||||
</a-space>
|
||||
<a-space>
|
||||
<span>
|
||||
<img :src="getStarIcon(3)" style="width: 25px; height: 17px" />
|
||||
泛娱乐向受众 + 较大地域分布(兴趣“短剧”、“直播带货”)</span
|
||||
>
|
||||
<a-space
|
||||
v-if="getSubmoduleContent(MODEL_PLACEMENT_SUGGESTION, '人群建议').length > 0"
|
||||
v-for="(item, index) in getSubmoduleContent(MODEL_PLACEMENT_SUGGESTION, '人群建议')"
|
||||
:key="index"
|
||||
>
|
||||
<span><img :src="getStarIcon(index)" style="width: 25px; height: 17px" />{{ item }}</span>
|
||||
</a-space>
|
||||
</a-space>
|
||||
</div>
|
||||
@ -167,23 +112,12 @@
|
||||
<div class="overall-strategy">
|
||||
<span class="placement-optimization-title">素材建议</span>
|
||||
<a-space direction="vertical">
|
||||
<a-space class="placement-optimization-str">
|
||||
<span>
|
||||
<img :src="getStarIcon(1)" style="width: 25px; height: 17px" />
|
||||
福利明确+钩子强的图文短视频,建议加限时优惠提示</span
|
||||
>
|
||||
</a-space>
|
||||
<a-space>
|
||||
<span>
|
||||
<img :src="getStarIcon(2)" style="width: 25px; height: 17px" />
|
||||
场景代入型视频,突出客户痛点与产品关联</span
|
||||
>
|
||||
</a-space>
|
||||
<a-space>
|
||||
<span>
|
||||
<img :src="getStarIcon(3)" style="width: 25px; height: 17px" />
|
||||
达人口播/测评,搭配标题党封面吸引点击</span
|
||||
>
|
||||
<a-space
|
||||
v-if="getSubmoduleContent(MODEL_PLACEMENT_SUGGESTION, '素材建议').length > 0"
|
||||
v-for="(item, index) in getSubmoduleContent(MODEL_PLACEMENT_SUGGESTION, '素材建议')"
|
||||
:key="index"
|
||||
>
|
||||
<span><img :src="getStarIcon(index)" style="width: 25px; height: 17px" />{{ item }}</span>
|
||||
</a-space>
|
||||
</a-space>
|
||||
</div>
|
||||
@ -195,23 +129,12 @@
|
||||
<div class="overall-strategy">
|
||||
<span class="placement-optimization-title">投放策略建议</span>
|
||||
<a-space direction="vertical">
|
||||
<a-space class="placement-optimization-str">
|
||||
<span>
|
||||
<img :src="getStarIcon(1)" style="width: 25px; height: 17px" />
|
||||
预算前置在 ROI 最佳时段和平台,优先抢头部流量</span
|
||||
>
|
||||
</a-space>
|
||||
<a-space>
|
||||
<span>
|
||||
<img :src="getStarIcon(2)" style="width: 25px; height: 17px" />
|
||||
中等预算组合投放 + 高点击素材A/B测试</span
|
||||
>
|
||||
</a-space>
|
||||
<a-space>
|
||||
<span>
|
||||
<img :src="getStarIcon(3)" style="width: 25px; height: 17px" />
|
||||
低预算长周期测试,重点看 CVR,优胜劣汰</span
|
||||
>
|
||||
<a-space
|
||||
v-if="getSubmoduleContent(MODEL_PLACEMENT_SUGGESTION, '投放策略建议').length > 0"
|
||||
v-for="(item, index) in getSubmoduleContent(MODEL_PLACEMENT_SUGGESTION, '投放策略建议')"
|
||||
:key="index"
|
||||
>
|
||||
<span><img :src="getStarIcon(index)" style="width: 25px; height: 17px" />{{ item }}</span>
|
||||
</a-space>
|
||||
</a-space>
|
||||
</div>
|
||||
@ -223,13 +146,37 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { IconQuestionCircle } from '@arco-design/web-vue/es/icon';
|
||||
import { isEmpty } from '@/utils/tools';
|
||||
|
||||
const props = defineProps({
|
||||
action_guide: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
tmp: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
});
|
||||
|
||||
const MODEL_PERFORMANCE_ANALYSIS = '表现分析';
|
||||
const MODEL_PLACEMENT_SUGGESTION = '新投放建议生成';
|
||||
|
||||
// 封装通用方法来获取 submodules 的内容
|
||||
const getSubmoduleContent = (moduleName: string, submoduleName: string) => {
|
||||
console.log(props.action_guide, 'getSubmoduleContent');
|
||||
const module = props.action_guide
|
||||
.find((item) => item.title === moduleName)
|
||||
?.submodules.find((mod) => mod.subtitle === submoduleName);
|
||||
const content = [];
|
||||
if (module) {
|
||||
const content = Object.values(module.content);
|
||||
console.log(content, 'content');
|
||||
return content;
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
import { getStarIcon } from '../../constants';
|
||||
import { defineProps } from 'vue';
|
||||
</script>
|
||||
|
||||
@ -1,36 +1,55 @@
|
||||
<template>
|
||||
<view>
|
||||
<div class="part-div">
|
||||
<div class="part-div-header">
|
||||
<span class="part-div-header-title">本月摘要</span>
|
||||
<a-popover position="tl">
|
||||
<icon-question-circle />
|
||||
<template #content>
|
||||
<p style="margin: 0">本月摘要。</p>
|
||||
</template>
|
||||
</a-popover>
|
||||
</div>
|
||||
<div class="month-data-div">
|
||||
<div style="align-self: stretch">
|
||||
<span class="month-text-black">总消耗:</span>
|
||||
<span class="month-text-blue">¥52,382.16</span>
|
||||
<span class="month-normal-span">,较上周期</span><span class="month-text-red">↑12.6%</span>
|
||||
<span class="month-normal-span">;<br />整体ROI:</span><span class="month-text-blue">2.84</span>
|
||||
<span class="month-normal-span">,属于</span><span class="month-text-red">中等偏高水平</span>
|
||||
<span class="month-text-black">,较上周期 </span><span class="month-text-red">+0.45</span>
|
||||
<span class="month-normal-span">;<br />主要转化来源:</span><span class="month-text-blue">抖音 46.3%</span>
|
||||
<span class="month-normal-span">,CTR 2.91%;<br />优质素材表现:</span>
|
||||
<span class="month-text-blue">美团酒店爆款横版1号</span>
|
||||
<span class="month-normal-spanw">。CTR 3.47%,CVR 5.92%。</span>
|
||||
</div>
|
||||
<div class="part-div">
|
||||
<div class="part-div-header">
|
||||
<span class="part-div-header-title">本月摘要</span>
|
||||
<a-popover position="tl">
|
||||
<icon-question-circle />
|
||||
<template #content>
|
||||
<p style="margin: 0">本月摘要。</p>
|
||||
</template>
|
||||
</a-popover>
|
||||
</div>
|
||||
<div class="month-data-div">
|
||||
<div style="align-self: stretch">
|
||||
<a-space direction="vertical" v-for="(item, index) in overview">
|
||||
<span :style="{ color: getColor(item?.highlight) }">{{ item.text }}</span>
|
||||
<br />
|
||||
</a-space>
|
||||
<!-- <span class="month-text-black">总消耗:</span>-->
|
||||
<!-- <span class="month-text-blue">¥52,382.16</span>-->
|
||||
<!-- <span class="month-normal-span">,较上周期</span><span class="month-text-red">↑12.6%</span>-->
|
||||
<!-- <span class="month-normal-span">;<br />整体ROI:</span><span class="month-text-blue">2.84</span>-->
|
||||
<!-- <span class="month-normal-span">,属于</span><span class="month-text-red">中等偏高水平</span>-->
|
||||
<!-- <span class="month-text-black">,较上周期 </span><span class="month-text-red">+0.45</span>-->
|
||||
<!-- <span class="month-normal-span">;<br />主要转化来源:</span><span class="month-text-blue">抖音 46.3%</span>-->
|
||||
<!-- <span class="month-normal-span">,CTR 2.91%;<br />优质素材表现:</span>-->
|
||||
<!-- <span class="month-text-blue">美团酒店爆款横版1号</span>-->
|
||||
<!-- <span class="month-normal-spanw">。CTR 3.47%,CVR 5.92%。</span>-->
|
||||
</div>
|
||||
</div>
|
||||
</view>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { IconQuestionCircle } from '@arco-design/web-vue/es/icon';
|
||||
import { defineProps } from 'vue';
|
||||
|
||||
const colorMap = {
|
||||
purple: 'purple',
|
||||
orange: 'orange',
|
||||
};
|
||||
const props = defineProps({
|
||||
overview: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
});
|
||||
|
||||
const getColor = (highlight?: string) => {
|
||||
return highlight ? colorMap[highlight] : undefined;
|
||||
};
|
||||
console.log(props.overview, 'overvie333');
|
||||
</script>
|
||||
<style lang="scss">
|
||||
<style lang="scss">
|
||||
@import './style.scss';
|
||||
</style>
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
//本月摘要数据-div
|
||||
.month-data-div {
|
||||
align-self: stretch;
|
||||
padding: 16px 30px 16px 16px;
|
||||
@ -15,7 +14,6 @@
|
||||
display: flex;
|
||||
}
|
||||
|
||||
//本月摘要-蓝色字体
|
||||
.month-text-blue {
|
||||
color: var(--Brand-Brand-6, #6D4CFE);
|
||||
font-size: 16px;
|
||||
@ -25,7 +23,6 @@
|
||||
word-wrap: break-word
|
||||
}
|
||||
|
||||
//红色字体
|
||||
.month-text-red {
|
||||
color: var(--Functional-Danger-6, #F64B31);
|
||||
font-size: 16px;
|
||||
@ -35,7 +32,6 @@
|
||||
word-wrap: break-word
|
||||
}
|
||||
|
||||
//黑色字体
|
||||
.month-text-black {
|
||||
color: var(--Text-1, #211F24);
|
||||
font-size: 16px;
|
||||
|
||||
@ -38,13 +38,13 @@
|
||||
<a-col :span="12">
|
||||
<div class="overall-strategy">
|
||||
<span class="placement-optimization-title">人群包优化</span>
|
||||
<span class="placement-optimization-str">{{props.optimization?.[3]?.['content']}}</span>
|
||||
<span class="placement-optimization-str">{{props?.optimization?.[3]?.['content']}}</span>
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<div class="overall-strategy">
|
||||
<span class="placement-optimization-title">素材优化</span>
|
||||
<span class="placement-optimization-str">{{props.optimization?.[4]['content']}}</span>
|
||||
<span class="placement-optimization-str">{{props?.optimization?.[4]?.['content']}}</span>
|
||||
|
||||
</div>
|
||||
</a-col>
|
||||
@ -65,6 +65,8 @@ const props = defineProps({
|
||||
default: () => [],
|
||||
},
|
||||
});
|
||||
|
||||
console.log(props.optimization,'optimization')
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<view>
|
||||
<a-table
|
||||
class="account-table"
|
||||
:columns="columns"
|
||||
:data="listResult.data"
|
||||
:filter-icon-align-left="alignLeft"
|
||||
:pagination="false"
|
||||
>
|
||||
<a-table class="account-table" :columns="columns" :data="listData" :pagination="false">
|
||||
<template #platform="{ record }">
|
||||
<span class="mr-5px" v-if="record.platform.length > 0" v-for="(item, index) in record.platform">
|
||||
<img :src="PLATFORM_LIST[item].icon" width="19" class="mr-4px" />
|
||||
<span>{{ PLATFORM_LIST[item].label }}</span>
|
||||
</span>
|
||||
</template>
|
||||
<template #operation="{ record }">
|
||||
<a-space size="medium">
|
||||
<a-space>
|
||||
@ -15,14 +15,14 @@
|
||||
type="warning"
|
||||
ok-text="确认删除"
|
||||
cancel-text="取消"
|
||||
@ok="deleteBrand(record.id)"
|
||||
@ok="deleteData(record.id)"
|
||||
>
|
||||
<icon-delete></icon-delete>
|
||||
</a-popconfirm>
|
||||
</a-space>
|
||||
<a-space>
|
||||
<a-button type="outline" class="operation-btn">下载</a-button>
|
||||
<a-button type="outline" class="operation-btn">详情</a-button>
|
||||
<a-button type="outline" @click="downloadDetailAsImage(record.id)" class="operation-btn">下载</a-button>
|
||||
<a-button type="outline" @click="goDetail(record.id)" class="operation-btn">详情</a-button>
|
||||
</a-space>
|
||||
</a-space>
|
||||
</template>
|
||||
@ -30,23 +30,15 @@
|
||||
</view>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import top1 from '@/assets/img/captcha/top1.svg';
|
||||
import top2 from '@/assets/img/captcha/top2.svg';
|
||||
import top3 from '@/assets/img/captcha/top3.svg';
|
||||
import { IconDelete } from '@arco-design/web-vue/es/icon';
|
||||
import { PLATFORM_LIST } from '@/views/property-marketing/put-account/common_constants';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import html2canvas from 'html2canvas';
|
||||
|
||||
const listQuery = reactive({
|
||||
project_id: ref(''),
|
||||
platform: ref(''),
|
||||
page: ref(1),
|
||||
name: ref(''),
|
||||
page_size: ref('10'),
|
||||
});
|
||||
const columns = [
|
||||
{
|
||||
title: '生成日期',
|
||||
dataIndex: 'date',
|
||||
slotName: 'account_name',
|
||||
dataIndex: 'created_at',
|
||||
width: 60,
|
||||
minWidth: 60,
|
||||
},
|
||||
@ -57,18 +49,16 @@ const columns = [
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
titleSlotName: 'project_name',
|
||||
width: 180,
|
||||
minWidth: 180,
|
||||
title: '项目',
|
||||
dataIndex: 'project_name',
|
||||
title: '计划',
|
||||
dataIndex: 'plan',
|
||||
},
|
||||
{
|
||||
title: '平台',
|
||||
titleSlotName: 'week_consumption',
|
||||
dataIndex: 'platform',
|
||||
width: 120,
|
||||
minWidth: 120,
|
||||
slotName: 'platform',
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
@ -78,40 +68,54 @@ const columns = [
|
||||
minWidth: 60,
|
||||
},
|
||||
];
|
||||
const listResult = reactive({
|
||||
data: [
|
||||
{
|
||||
date: '日期',
|
||||
account: '账号',
|
||||
project_name: '项目名称',
|
||||
week_consumption: '本周总消耗',
|
||||
week_consumption_rate: 0.1,
|
||||
roi: '2.6',
|
||||
ctr: '3.1%',
|
||||
},
|
||||
{
|
||||
account_name: '全球旅行',
|
||||
platform_name: '平台',
|
||||
project_name: '项目名称',
|
||||
week_consumption: '本周总消耗',
|
||||
week_consumption_rate: -0.1,
|
||||
roi: '2.6',
|
||||
ctr: '3.1%',
|
||||
},
|
||||
{
|
||||
account_name: '全球旅行',
|
||||
platform_name: '平台',
|
||||
project_name: '项目名称',
|
||||
week_consumption: '本周总消耗',
|
||||
week_consumption_rate: -0.1,
|
||||
roi: '2.6',
|
||||
ctr: '3.1%',
|
||||
},
|
||||
],
|
||||
total: ref(0),
|
||||
});
|
||||
// hotTranslation.vue
|
||||
import { useRouter } from 'vue-router';
|
||||
import { deleteHistorylog } from '@/api/all/propertyMarketing'; // 引入 useRouter
|
||||
|
||||
const topImages = [top1, top2, top3];
|
||||
const router = useRouter(); // 创建 router 实例
|
||||
|
||||
// 详情
|
||||
const goDetail = async (id) => {
|
||||
// 使用 router.push 进行编程式导航,并传递话题 ID
|
||||
router.push(`/put-account/detail/${id}`);
|
||||
};
|
||||
|
||||
const downloadDetailAsImage = (id) => {
|
||||
const url = `/put-account/detail/${id}`;
|
||||
const win = window.open(url, '_blank');
|
||||
|
||||
win.onload = () => {
|
||||
setTimeout(() => {
|
||||
html2canvas(win.document.body, {
|
||||
useCORS: true,
|
||||
scale: 2,
|
||||
}).then((canvas) => {
|
||||
const imgData = canvas.toDataURL('image/png');
|
||||
const link = document.createElement('a');
|
||||
link.href = imgData;
|
||||
link.download = `详情页面_${Date.now()}.png`;
|
||||
link.click();
|
||||
win.close(); // 关闭新窗口
|
||||
});
|
||||
}, 2000); // 等待页面加载
|
||||
};
|
||||
};
|
||||
const deleteData = async (id) => {
|
||||
const { code, data } = await deleteHistorylog(id);
|
||||
|
||||
if (code === 200) {
|
||||
Message.success('删除成功');
|
||||
}
|
||||
};
|
||||
|
||||
const props = defineProps({
|
||||
listData: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
data: [];
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
||||
@ -1,95 +1,77 @@
|
||||
<!--表单搜索组件-->
|
||||
<template>
|
||||
<view>
|
||||
<a-space size="large" direction="vertical" class="search-form">
|
||||
<a-row class="grid-demo" :gutter="{ md: 8, lg: 24, xl: 32 }">
|
||||
<a-col :span="8">
|
||||
<a-space>
|
||||
<span>账户</span>
|
||||
<a-input
|
||||
class="w-310px"
|
||||
:style="{ width: '320px' }"
|
||||
v-model="query.account_name"
|
||||
placeholder="请搜索..."
|
||||
size="medium"
|
||||
allow-clear
|
||||
>
|
||||
<template #prefix>
|
||||
<icon-search />
|
||||
</template>
|
||||
</a-input>
|
||||
</a-space>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-space>
|
||||
<span>计划</span>
|
||||
<a-input
|
||||
class="w-310px"
|
||||
:style="{ width: '320px' }"
|
||||
v-model="query.plan"
|
||||
placeholder="请搜索..."
|
||||
size="medium"
|
||||
allow-clear
|
||||
>
|
||||
<template #prefix>
|
||||
<icon-search />
|
||||
</template>
|
||||
</a-input>
|
||||
</a-space>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-space>
|
||||
<span>平台</span>
|
||||
<div class="container px-24px">
|
||||
<div class="filter-row flex mb-20px">
|
||||
<div class="filter-row-item flex items-center">
|
||||
<span class="label">账户名称</span>
|
||||
<a-space size="medium" class="w-240px">
|
||||
<a-input v-model="query.account_name" placeholder="请搜索..." size="medium" allow-clear>
|
||||
<template #prefix>
|
||||
<icon-search />
|
||||
</template>
|
||||
</a-input>
|
||||
</a-space>
|
||||
</div>
|
||||
|
||||
<a-select
|
||||
v-model="query.platform"
|
||||
class="w-320"
|
||||
size="medium"
|
||||
placeholder="全部"
|
||||
allow-clear
|
||||
@change="handleSearch"
|
||||
>
|
||||
<a-option v-for="(item, index) in PLATFORM_LIST" :key="index" :value="item.value" :label="item.label"
|
||||
>{{ item.label }}
|
||||
</a-option>
|
||||
</a-select>
|
||||
</a-space>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<div class="filter-row-item flex items-center">
|
||||
<span class="label">计划</span>
|
||||
<a-space size="medium" class="w-240px">
|
||||
<a-input
|
||||
class="w-310px"
|
||||
:style="{ width: '320px' }"
|
||||
v-model="query.plan"
|
||||
placeholder="请搜索..."
|
||||
size="medium"
|
||||
allow-clear
|
||||
>
|
||||
<template #prefix>
|
||||
<icon-search />
|
||||
</template>
|
||||
</a-input>
|
||||
</a-space>
|
||||
</div>
|
||||
|
||||
<a-row class="grid-demo" :gutter="{ md: 8, lg: 24, xl: 32 }">
|
||||
<a-col :span="10">
|
||||
<a-space>
|
||||
<span>时间筛选</span>
|
||||
<a-range-picker
|
||||
showTime
|
||||
:time-picker-props="{
|
||||
defaultValue: ['00:00:00', '00:00:00'],
|
||||
}"
|
||||
@select="onSelect"
|
||||
style="width: 380px"
|
||||
/>
|
||||
</a-space>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-space>
|
||||
<a-button type="outline" class="search-btn" @click="handleSearch">
|
||||
<template #icon>
|
||||
<icon-search />
|
||||
</template>
|
||||
<template #default>搜索</template>
|
||||
</a-button>
|
||||
<a-button type="outline" class="reset-btn" @click="handleSearch">
|
||||
<template #icon>
|
||||
<icon-refresh />
|
||||
</template>
|
||||
<template #default>重置</template>
|
||||
</a-button>
|
||||
</a-space>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-space>
|
||||
</view>
|
||||
<div class="filter-row-item flex items-center">
|
||||
<span class="label">平台</span>
|
||||
<a-select
|
||||
v-model="query.platform"
|
||||
class="w-150"
|
||||
size="medium"
|
||||
placeholder="全部"
|
||||
allow-clear
|
||||
@change="handleSearch"
|
||||
>
|
||||
<a-option v-for="(item, index) in PLATFORM_LIST" :key="index" :value="item.value" :label="item.label"
|
||||
>{{ item.label }}
|
||||
</a-option>
|
||||
</a-select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="filter-row flex mb-20px">
|
||||
<div class="filter-row-item flex items-center">
|
||||
<span class="label">时间筛选</span>
|
||||
<a-space size="medium" class="w-240px">
|
||||
<a-range-picker v-model="query.data_time" size="medium" allow-clear format="YYYY-MM-DD" class="w-310" />
|
||||
</a-space>
|
||||
</div>
|
||||
|
||||
<div class="filter-row-item flex items-center">
|
||||
<a-button class="w-84px search-btn mr-12px" size="medium" @click="handleSearch">
|
||||
<template #icon>
|
||||
<icon-search />
|
||||
</template>
|
||||
<template #default>搜索</template>
|
||||
</a-button>
|
||||
<a-button class="w-84px reset-btn" size="medium" @click="handleReset">
|
||||
<template #icon>
|
||||
<icon-refresh />
|
||||
</template>
|
||||
<template #default>重置</template>
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -103,52 +85,77 @@ const props = defineProps({
|
||||
},
|
||||
});
|
||||
const emits = defineEmits('onSearch', 'onReset', 'update:query');
|
||||
|
||||
// 获取最近7天的日期
|
||||
const getLast7Days = () => {
|
||||
const today = new Date();
|
||||
const last7Days = new Date(today);
|
||||
last7Days.setDate(today.getDate() - 7);
|
||||
return [last7Days.toISOString().split('T')[0], today.toISOString().split('T')[0]];
|
||||
};
|
||||
const handleSearch = () => {
|
||||
emits('onSearch', props.query);
|
||||
};
|
||||
// 使用 computed 实现 v-model
|
||||
const localQuery = computed({
|
||||
get: () => props.query,
|
||||
set: (value) => emits('update:query', value),
|
||||
});
|
||||
onMounted(() => {
|
||||
localQuery.value.data_time = getLast7Days();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
:deep(.arco-select-view-single),
|
||||
:deep(.arco-select-view-multiple),
|
||||
:deep(.arco-picker),
|
||||
:deep(.arco-input-wrapper) {
|
||||
border-radius: 4px;
|
||||
border-color: #d7d7d9;
|
||||
background-color: #fff;
|
||||
width: 224px;
|
||||
height: 32px;
|
||||
.container {
|
||||
:deep(.arco-input-wrapper),
|
||||
:deep(.arco-select-view-single),
|
||||
:deep(.arco-select-view-multiple),
|
||||
:deep(.arco-picker) {
|
||||
border-radius: 4px;
|
||||
border-color: #d7d7d9;
|
||||
background-color: #fff;
|
||||
|
||||
&:focus-within,
|
||||
&.arco-input-focus {
|
||||
background-color: var(--color-bg-2);
|
||||
border-color: rgb(var(--primary-6));
|
||||
box-shadow: 0 0 0 0 var(--color-primary-light-2);
|
||||
&:focus-within,
|
||||
&.arco-input-focus {
|
||||
background-color: var(--color-bg-2);
|
||||
border-color: rgb(var(--primary-6));
|
||||
box-shadow: 0 0 0 0 var(--color-primary-light-2);
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.search-btn) {
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--Brand-Brand-6, #6d4cfe);
|
||||
color: #6d4cfe;
|
||||
}
|
||||
|
||||
:deep(.reset-btn) {
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--BG-500, #b1b2b5);
|
||||
background: var(--BG-white, #fff);
|
||||
}
|
||||
|
||||
.filter-row {
|
||||
.filter-row-item {
|
||||
&:not(:last-child) {
|
||||
margin-right: 24px;
|
||||
}
|
||||
|
||||
.label {
|
||||
margin-right: 8px;
|
||||
color: #211f24;
|
||||
font-family: 'PuHuiTi-Regular';
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
flex-shrink: 0;
|
||||
line-height: 22px; /* 157.143% */
|
||||
}
|
||||
|
||||
:deep(.arco-space-item) {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.search-btn {
|
||||
// 搜索
|
||||
color: var(--Brand-6, #6d4cfe);
|
||||
font-size: 14px;
|
||||
font-family: PuHuiTi-Medium;
|
||||
font-weight: 400;
|
||||
line-height: 22px;
|
||||
height: 32px;
|
||||
border-radius: 3px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.reset-btn {
|
||||
// 重置
|
||||
color: var(--Text-2, #3c4043);
|
||||
font-size: 14px;
|
||||
font-family: PuHuiTi-Medium;
|
||||
font-weight: 400;
|
||||
line-height: 22px;
|
||||
height: 32px;
|
||||
border-radius: 3px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -3,9 +3,9 @@
|
||||
<a-table
|
||||
class="account-table"
|
||||
:columns="columns"
|
||||
:data="listResult.data"
|
||||
:filter-icon-align-left="alignLeft"
|
||||
:data="listData"
|
||||
:pagination="false"
|
||||
@sorter-change="handleSorterChange"
|
||||
>
|
||||
<template #week_consumption>
|
||||
<a-space>
|
||||
@ -53,8 +53,10 @@
|
||||
</template>
|
||||
|
||||
<template #platform="{ record }">
|
||||
<img :src="PLATFORM_LIST[record.platform].icon" width="19" class="mr-4px" />
|
||||
<span>{{ PLATFORM_LIST[record.platform].label }}</span>
|
||||
<a-space size="medium" v-if="record.platform">
|
||||
<img :src="PLATFORM_LIST[record.platform]?.icon" width="19" class="mr-4px" />
|
||||
<span>{{ PLATFORM_LIST[record.platform].label }}</span>
|
||||
</a-space>
|
||||
</template>
|
||||
|
||||
<template #weekConsumptionRate="{ record }">
|
||||
@ -73,22 +75,30 @@
|
||||
<template #suffix>%</template>
|
||||
</a-statistic>
|
||||
</template>
|
||||
</a-table>
|
||||
|
||||
<template #clickRate="{ record }">
|
||||
<span>{{ `${record.click_rate}%` }}</span>
|
||||
</template>
|
||||
</a-table>
|
||||
</view>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { PLATFORM_LIST } from '../../../common_constants';
|
||||
|
||||
defineProps({
|
||||
listResult: {
|
||||
type: Object,
|
||||
const props = defineProps({
|
||||
listData: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
total: 0;
|
||||
data: [];
|
||||
},
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['updateQuery']);
|
||||
|
||||
const handleSorterChange = (column, order) => {
|
||||
emit('updateQuery', { column, order });
|
||||
};
|
||||
const listQuery = reactive({
|
||||
project_id: ref(''),
|
||||
platform: ref(''),
|
||||
@ -122,6 +132,9 @@ const columns = [
|
||||
dataIndex: 'total_use_amount',
|
||||
width: 120,
|
||||
minWidth: 120,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '本周总消耗环比',
|
||||
@ -130,25 +143,34 @@ const columns = [
|
||||
width: 120,
|
||||
minWidth: 120,
|
||||
slotName: 'weekConsumptionRate',
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
},
|
||||
},
|
||||
{
|
||||
titleSlotName: 'roi',
|
||||
dataIndex: 'roi',
|
||||
width: 120,
|
||||
minWidth: 120,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
},
|
||||
},
|
||||
{
|
||||
titleSlotName: 'ctr',
|
||||
dataIndex: 'click_rate',
|
||||
width: 120,
|
||||
minWidth: 120,
|
||||
slotName: 'clickRate',
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
},
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.table-data {
|
||||
//账户列表-分页
|
||||
.account-page {
|
||||
padding: 10px 24px 20px 24px;
|
||||
background-color: #fff;
|
||||
|
||||
Reference in New Issue
Block a user