Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mengchangaigc
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
姚珂
mengchangaigc
Commits
fd59473d
Commit
fd59473d
authored
Aug 21, 2026
by
黄同智
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
视频数据分析页面的布局
parent
6f5ecf40
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
735 additions
and
3 deletions
+735
-3
AdPlatformTags.vue
.../web-vue/src/views/analysis/components/AdPlatformTags.vue
+265
-0
DeliveryReport.vue
.../web-vue/src/views/analysis/components/DeliveryReport.vue
+132
-0
TagAnalysis.vue
apps/web-vue/src/views/analysis/components/TagAnalysis.vue
+216
-0
TencentDeliveryReport.vue
...e/src/views/analysis/components/TencentDeliveryReport.vue
+88
-0
video.vue
apps/web-vue/src/views/analysis/video.vue
+34
-3
No files found.
apps/web-vue/src/views/analysis/components/AdPlatformTags.vue
0 → 100644
View file @
fd59473d
<
template
>
<div
class=
"p-6"
>
<el-card
class=
"bg-fff round-12"
shadow=
"hover"
>
<div
class=
"flex-items-center gap-34 filter-header"
>
<div
v-for=
"item in platformTabs"
:key=
"item.value"
class=
"pb-18 flex-items-center gap-10 pointer platform-tab"
:class=
"
{ active: platform === item.value }" @click="platform = item.value">
<span
class=
"w-24 h-24 round-6 flex-center platform-icon"
>
{{
item
.
icon
}}
</span>
<span
class=
"fs-16 font-bold"
>
{{
item
.
label
}}
</span>
</div>
</div>
<div
class=
"py-20"
>
<div
class=
"flex-items-center mb-18"
>
<el-button
v-for=
"item in scopes"
:key=
"item"
:type=
"scope === item ? 'primary' : ''"
class=
"round-6"
@
click=
"scope = item"
>
{{
item
}}
</el-button>
</div>
<div
class=
"flex-items-center"
>
<el-select
v-model=
"category"
class=
"w-140"
placeholder=
"请选择分类"
>
<el-option
label=
"全部分类"
value=
"all"
/>
<el-option
label=
"服饰鞋包"
value=
"clothes"
/>
</el-select>
<div
class=
"w-240 mx-10"
>
<el-date-picker
v-model=
"dateRange"
type=
"daterange"
range-separator=
"至"
start-placeholder=
"开始日期"
end-placeholder=
"结束日期"
style=
"width: 100% !important;"
/>
</div>
<el-button
type=
"primary"
class=
"round-6"
@
click=
"query"
>
查询
</el-button>
<el-button
class=
" round-6"
@
click=
"reset"
>
重置
</el-button>
</div>
</div>
</el-card>
<el-card
class=
"bg-fff round-12 mt-16"
shadow=
"hover"
>
<div
class=
"pb-16 flex-between ratio-title"
>
<span
class=
"fs-16 font-bold color-000"
>
占比分析
</span>
<el-button
type=
"primary"
link
@
click=
"collapsed = !collapsed"
>
{{
collapsed
?
'展开'
:
'收起'
}}
</el-button>
</div>
<div
v-show=
"!collapsed"
class=
"p-20 flex gap-26"
>
<div
class=
"flex-1 gap-14 card-grid"
>
<div
v-for=
"item in ratioList"
:key=
"item.name"
class=
"p-18 round-6 flex-between metric-card"
>
<div
class=
"flex-items-center"
>
<span
class=
"w-42 h-42 round-8 flex-center fs-20"
:style=
"
{ color: item.color, backgroundColor: item.bg }">
{{
item
.
icon
}}
</span>
<div
class=
"ml-16"
>
<div
class=
"font-bold color-000"
>
{{
item
.
name
}}
</div>
<div
class=
"mt-8"
>
数量:
<span
class=
"font-bold"
>
{{
item
.
count
.
toLocaleString
()
}}
</span>
</div>
<div
class=
"mt-6"
>
消耗:
<span
class=
"font-bold"
>
¥
{{
item
.
cost
.
toLocaleString
()
}}
</span>
</div>
</div>
</div>
<div
class=
"lh-24"
>
<div>
数量占比:
<span
class=
"font-bold"
>
{{
item
.
countRate
}}
%
</span></div>
<div>
消耗占比:
<span
class=
"font-bold"
>
{{
item
.
costRate
}}
%
</span></div>
</div>
</div>
</div>
<div
class=
"flex-1 minw-400 flex-items-center justify-center chart-panel"
>
<div
class=
"w-240 h-240"
>
<v-chart
class=
"w-full h-full"
:option=
"pieOption"
autoresize
/>
</div>
<div
class=
"ml-40 flex-1"
>
<div
v-for=
"item in ratioList"
:key=
"item.name"
class=
"flex-between mb-18"
>
<div
class=
"flex-items-center gap-10"
>
<span
class=
"w-10 h-10 round-2"
:style=
"
{ backgroundColor: item.color }">
</span>
<span>
{{
item
.
name
}}
</span>
</div>
<span
class=
"fs-12 color-666"
>
{{
item
.
count
}}
(
{{
item
.
countRate
}}
%)
</span>
</div>
</div>
</div>
</div>
</el-card>
<el-card
class=
"bg-fff round-12 mt-16"
shadow=
"hover"
>
<div
class=
"pb-16 flex-between table-title"
>
<div
class=
"flex-items-center gap-8"
>
<span
class=
"fs-16 font-bold color-000"
>
详细数据
</span>
<span
class=
"color-888"
>
⊙
</span>
</div>
<el-button
class=
"round-6"
@
click=
"query"
>
⇩ 导出表格
</el-button>
</div>
<el-table
:data=
"pagedTableData"
class=
"analysis-table"
>
<el-table-column
prop=
"account"
label=
"广告账户"
min-width=
"210"
/>
<el-table-column
prop=
"subject"
label=
"主体"
min-width=
"180"
/>
<el-table-column
prop=
"department"
label=
"部门"
width=
"130"
/>
<el-table-column
prop=
"group"
label=
"分组"
width=
"120"
/>
<el-table-column
prop=
"user"
label=
"用户"
width=
"100"
/>
<el-table-column
prop=
"category1"
label=
"一级分类"
width=
"110"
/>
<el-table-column
prop=
"category2"
label=
"二级分类"
width=
"110"
/>
<el-table-column
prop=
"total"
label=
"总素材数"
width=
"110"
align=
"center"
/>
<el-table-column
prop=
"first"
label=
"首发素材"
width=
"120"
align=
"center"
>
<template
#
default=
"
{ row }">
<MetricText
:value=
"row.first"
sub=
"28.5%"
/>
</
template
>
</el-table-column>
<el-table-column
prop=
"firstCost"
label=
"首发素材消耗"
width=
"140"
align=
"center"
/>
<el-table-column
prop=
"good"
label=
"优质素材"
width=
"110"
align=
"center"
>
<
template
#
default=
"{ row }"
><span
class=
"font-bold color-green"
>
{{
row
.
good
}}
</span></
template
>
</el-table-column>
<el-table-column
prop=
"goodCost"
label=
"优质素材消耗"
width=
"140"
align=
"center"
>
<
template
#
default=
"{ row }"
><span
class=
"font-bold color-green"
>
{{
row
.
goodCost
}}
</span></
template
>
</el-table-column>
<el-table-column
prop=
"low"
label=
"低效素材"
width=
"110"
align=
"center"
>
<
template
#
default=
"{ row }"
><span
class=
"font-bold color-main"
>
{{
row
.
low
}}
</span></
template
>
</el-table-column>
<el-table-column
prop=
"bad"
label=
"低质素材"
width=
"110"
align=
"center"
>
<
template
#
default=
"{ row }"
><span
class=
"font-bold color-orange"
>
{{
row
.
bad
}}
</span></
template
>
</el-table-column>
<el-table-column
prop=
"same"
label=
"同质化挤压严重素材"
width=
"160"
align=
"center"
>
<
template
#
default=
"{ row }"
><span
class=
"font-bold color-pink"
>
{{
row
.
same
}}
</span></
template
>
</el-table-column>
<el-table-column
prop=
"risk"
label=
"同质化素材风险-排队投放素材"
width=
"210"
align=
"center"
>
<
template
#
default=
"{ row }"
><span
class=
"font-bold color-green"
>
{{
row
.
risk
}}
</span></
template
>
</el-table-column>
</el-table>
<div
class=
"py-12 flex justify-end table-footer"
>
<el-pagination
v-model:current-page=
"pageData.currentPage"
v-model:page-size=
"pageData.pageSize"
background
layout=
"total, sizes, prev, pager, next, jumper"
:total=
"tableData.length"
:page-sizes=
"pageData.pageSizes"
@
size-change=
"handleSizeChange"
/>
</div>
</el-card>
</div>
</template>
<
script
setup
lang=
"ts"
>
import
{
computed
,
defineComponent
,
h
,
reactive
,
ref
}
from
'vue'
;
import
VChart
from
'vue-echarts'
;
import
{
use
}
from
'echarts/core'
;
import
{
CanvasRenderer
}
from
'echarts/renderers'
;
import
{
PieChart
}
from
'echarts/charts'
;
import
{
GraphicComponent
,
LegendComponent
,
TooltipComponent
}
from
'echarts/components'
;
import
{
ElMessage
}
from
'element-plus'
;
use
([
CanvasRenderer
,
PieChart
,
TooltipComponent
,
LegendComponent
,
GraphicComponent
]);
const
MetricText
=
defineComponent
({
props
:
{
value
:
[
Number
,
String
],
sub
:
String
},
setup
(
props
)
{
return
()
=>
h
(
'div'
,
[
h
(
'div'
,
{
class
:
'font-bold color-000'
},
String
(
props
.
value
)),
h
(
'div'
,
{
class
:
'fs-12 color-888'
},
props
.
sub
)]);
},
});
const
platform
=
ref
(
'qianchuan'
);
const
scope
=
ref
(
'汇总'
);
const
category
=
ref
(
''
);
const
dateRange
=
ref
(
''
);
const
collapsed
=
ref
(
false
);
const
pageData
=
reactive
({
currentPage
:
1
,
pageSize
:
10
,
pageSizes
:
[
10
,
20
,
50
,
100
],
});
const
platformTabs
=
[
{
label
:
'巨量千川'
,
value
:
'qianchuan'
,
icon
:
'Ⅲ'
},
{
label
:
'巨量广告'
,
value
:
'ad'
,
icon
:
'⊘'
},
];
const
scopes
=
[
'汇总'
,
'部门'
,
'分组'
,
'个人'
,
'广告账户'
];
const
ratioList
=
[
{
name
:
'首发素材'
,
count
:
1280
,
cost
:
342800
,
countRate
:
28.5
,
costRate
:
32.4
,
color
:
'#5046e5'
,
bg
:
'#f0efff'
,
icon
:
'⌘'
},
{
name
:
'优质素材'
,
count
:
860
,
cost
:
415200
,
countRate
:
19.1
,
costRate
:
39.2
,
color
:
'#ef3d3d'
,
bg
:
'#fff0f0'
,
icon
:
'♙'
},
{
name
:
'低效素材'
,
count
:
940
,
cost
:
182500
,
countRate
:
20.9
,
costRate
:
17.2
,
color
:
'#8656ee'
,
bg
:
'#f5efff'
,
icon
:
'!'
},
{
name
:
'低质素材'
,
count
:
520
,
cost
:
68100
,
countRate
:
11.6
,
costRate
:
6.4
,
color
:
'#f59e0b'
,
bg
:
'#fff7e8'
,
icon
:
'△'
},
{
name
:
'同质化挤压严重素材'
,
count
:
480
,
cost
:
32400
,
countRate
:
10.7
,
costRate
:
3.1
,
color
:
'#ec4899'
,
bg
:
'#fff0f8'
,
icon
:
'▱'
},
{
name
:
'同质化素材风险-排队投放素材'
,
count
:
410
,
cost
:
17900
,
countRate
:
9.2
,
costRate
:
1.7
,
color
:
'#10b981'
,
bg
:
'#ecfdf5'
,
icon
:
'♢'
},
];
const
tableData
=
[
{
account
:
'总计'
,
subject
:
'--'
,
department
:
'--'
,
group
:
'--'
,
user
:
'--'
,
category1
:
'--'
,
category2
:
'--'
,
total
:
'4,490'
,
first
:
'1,280'
,
firstCost
:
'¥342,800'
,
good
:
860
,
goodCost
:
'¥415,200'
,
low
:
940
,
bad
:
520
,
same
:
480
,
risk
:
410
},
{
account
:
'广州千川官方号-01 (8821941)'
,
subject
:
'广州某某网络科技有限公司'
,
department
:
'华南电商一队'
,
group
:
'直播二组'
,
user
:
'张伟'
,
category1
:
'服饰鞋包'
,
category2
:
'女装短袖'
,
total
:
1250
,
first
:
380
,
firstCost
:
'¥112,000'
,
good
:
240
,
goodCost
:
'¥145,000'
,
low
:
280
,
bad
:
150
,
same
:
120
,
risk
:
80
},
{
account
:
'杭州巨量千川-旗舰02 (9120482)'
,
subject
:
'杭州电商服务有限公司'
,
department
:
'华东数码二队'
,
group
:
'信息流一组'
,
user
:
'李娜'
,
category1
:
'3C数码'
,
category2
:
'智能耳机'
,
total
:
980
,
first
:
290
,
firstCost
:
'¥89,500'
,
good
:
195
,
goodCost
:
'¥118,200'
,
low
:
210
,
bad
:
115
,
same
:
95
,
risk
:
75
},
{
account
:
'上海巨量广告-品牌01 (7739102)'
,
subject
:
'上海传媒网络科技公司'
,
department
:
'华东美妆一队'
,
group
:
'品牌推广组'
,
user
:
'王强'
,
category1
:
'美妆护肤'
,
category2
:
'精华面霜'
,
total
:
1120
,
first
:
310
,
firstCost
:
'¥95,000'
,
good
:
220
,
goodCost
:
'¥102,000'
,
low
:
245
,
bad
:
135
,
same
:
110
,
risk
:
100
},
{
account
:
'北京千川测试户-05 (6652011)'
,
subject
:
'北京互联网有限公司'
,
department
:
'华北综合队'
,
group
:
'效果提升组'
,
user
:
'刘洋'
,
category1
:
'食品饮料'
,
category2
:
'休闲零食'
,
total
:
640
,
first
:
180
,
firstCost
:
'¥32,300'
,
good
:
125
,
goodCost
:
'¥38,000'
,
low
:
135
,
bad
:
80
,
same
:
75
,
risk
:
45
},
];
const
pagedTableData
=
computed
(()
=>
{
const
start
=
(
pageData
.
currentPage
-
1
)
*
pageData
.
pageSize
;
return
tableData
.
slice
(
start
,
start
+
pageData
.
pageSize
);
});
const
pieOption
=
computed
(()
=>
({
tooltip
:
{
trigger
:
'item'
},
legend
:
{
show
:
false
},
series
:
[{
type
:
'pie'
,
radius
:
[
'42%'
,
'78%'
],
label
:
{
show
:
false
},
data
:
ratioList
.
map
((
item
)
=>
({
name
:
item
.
name
,
value
:
item
.
count
,
itemStyle
:
{
color
:
item
.
color
}
})),
}],
graphic
:
[
{
type
:
'text'
,
left
:
'center'
,
top
:
'42%'
,
style
:
{
text
:
'总素材数'
,
textAlign
:
'center'
,
fill
:
'#6b7c93'
,
fontSize
:
12
}
},
{
type
:
'text'
,
left
:
'center'
,
top
:
'51%'
,
style
:
{
text
:
'4,490'
,
textAlign
:
'center'
,
fill
:
'#0f172a'
,
fontSize
:
20
,
fontWeight
:
700
}
},
{
type
:
'text'
,
left
:
'center'
,
top
:
'63%'
,
style
:
{
text
:
'六维类型'
,
textAlign
:
'center'
,
fill
:
'#6b7c93'
,
fontSize
:
12
}
},
],
}));
const
query
=
()
=>
ElMessage
.
success
(
'查询完成'
);
const
reset
=
()
=>
{
category
.
value
=
''
;
dateRange
.
value
=
''
;
};
const
handleSizeChange
=
()
=>
{
pageData
.
currentPage
=
1
;
};
</
script
>
<
style
scoped
lang=
"scss"
>
.filter-header
,
.ratio-title
,
.table-title
,
.table-footer
{
border-bottom
:
1px
solid
#edf0f5
;
}
.table-footer
{
border-top
:
1px
solid
#edf0f5
;
border-bottom
:
none
;
}
.platform-tab
{
color
:
#607086
;
&
.active
{
color
:
rgba
(
var
(
--
main-color
)
,
1
);
border-bottom
:
2px
solid
rgba
(
var
(
--
main-color
)
,
1
);
}
}
.platform-icon
,
.work-tag
{
background-color
:
rgba
(
var
(
--
main-color
)
,
.08
);
}
.card-grid
{
display
:
grid
;
grid-template-columns
:
repeat
(
2
,
minmax
(
280px
,
1fr
));
}
.analysis-table
{
:deep
(
.el-table__header
th
)
{
background
:
#f8fbff
;
color
:
#48607f
;
font-weight
:
bold
;
}
}
.color-green
{
color
:
#00a86b
;
}
.color-orange
{
color
:
#f59e0b
;
}
.color-pink
{
color
:
#ec4899
;
}
</
style
>
apps/web-vue/src/views/analysis/components/DeliveryReport.vue
0 → 100644
View file @
fd59473d
<
template
>
<div
class=
"p-6"
>
<el-card
class=
"round-12 mt-10 filter-card"
shadow=
"hover"
>
<div
class=
"flex-items-center gap-34 header-tabs"
>
<div
v-for=
"item in platforms"
:key=
"item"
class=
"pb-16 font-bold pointer"
:class=
"
{ active: platform === item }" @click="platform = item">
{{
item
}}
</div>
</div>
<div
class=
"py-14 sub-tabs"
>
<div
class=
"flex-items-center gap-24"
>
<span
v-for=
"item in scopes"
:key=
"item"
class=
"font-bold pointer"
:class=
"
{ 'color-main': scope === item }" @click="scope = item">
{{
item
}}
</span>
<div
class=
"flex-items-center gap-10"
>
<div
class=
"w-300 flex-items-center mr-10"
>
<div
class=
"w-90"
>
上传时间:
</div>
<el-date-picker
v-model=
"uploadRange"
type=
"daterange"
range-separator=
"至"
start-placeholder=
"开始日期"
end-placeholder=
"结束日期"
style=
"width: 100% !important;"
/>
</div>
<div
class=
"w-300 flex-items-center mr-10"
>
<div
class=
"w-90"
>
投放时间:
</div>
<el-date-picker
v-model=
"deliveryRange"
type=
"daterange"
range-separator=
"至"
start-placeholder=
"开始日期"
end-placeholder=
"结束日期"
style=
"width: 100% !important;"
/>
</div>
</div>
</div>
<div
class=
"mt-16"
>
<el-button
type=
"primary"
class=
"round-6"
>
视频作者
</el-button>
<el-button
class=
"round-6 mr-10"
>
下单运营
</el-button>
<el-select
v-model=
"department"
class=
"w-180 mr-10"
placeholder=
"请选择部门"
/>
<el-select
v-model=
"category"
class=
"w-180 mr-10"
placeholder=
"请选择分类"
/>
<el-button
type=
"primary"
class=
"w-66 round-6"
>
查询
</el-button>
<el-button
class=
"round-6"
>
导出数据
</el-button>
<el-button
class=
"w-34 h-34 round-6"
>
☷
</el-button>
</div>
</div>
</el-card>
<el-card
class=
"round-12 mt-16"
shadow=
"hover"
>
<el-table
:data=
"pagedTableData"
class=
"analysis-table"
>
<el-table-column
prop=
"department"
label=
"部门"
min-width=
"160"
/>
<el-table-column
prop=
"cost"
label=
"消耗"
width=
"120"
align=
"center"
/>
<el-table-column
prop=
"roi"
label=
"roi"
width=
"90"
align=
"center"
/>
<el-table-column
prop=
"totalAmount"
label=
"总成交金额"
width=
"130"
align=
"center"
/>
<el-table-column
prop=
"amount"
label=
"成交金额"
width=
"130"
align=
"center"
/>
<el-table-column
prop=
"coupon"
label=
"智能优惠券"
width=
"130"
align=
"center"
/>
<el-table-column
prop=
"conversions"
label=
"转化数"
width=
"110"
align=
"center"
/>
<el-table-column
prop=
"rate"
label=
"转化率"
width=
"110"
align=
"center"
/>
<el-table-column
prop=
"costRate"
label=
"转化成本"
width=
"110"
align=
"center"
/>
<el-table-column
prop=
"show"
label=
"展示数"
width=
"130"
align=
"center"
/>
<el-table-column
prop=
"avgCost"
label=
"平均千次展现费用"
width=
"160"
align=
"center"
/>
<el-table-column
prop=
"click"
label=
"点击数"
width=
"120"
align=
"center"
/>
<el-table-column
prop=
"clickRate"
label=
"点击率"
width=
"110"
align=
"center"
/>
<el-table-column
prop=
"avgPrice"
label=
"平均点击单价"
width=
"140"
align=
"center"
/>
<el-table-column
prop=
"play"
label=
"播放量"
width=
"130"
align=
"center"
/>
</el-table>
<div
class=
"py-12 flex justify-end table-footer"
>
<el-pagination
v-model:current-page=
"pageData.currentPage"
v-model:page-size=
"pageData.pageSize"
background
layout=
"total, sizes, prev, pager, next, jumper"
:total=
"tableData.length"
:page-sizes=
"pageData.pageSizes"
@
size-change=
"handleSizeChange"
/>
</div>
</el-card>
</div>
</
template
>
<
script
setup
lang=
"ts"
>
import
{
computed
,
reactive
,
ref
}
from
'vue'
;
const
platform
=
ref
(
'巨量广告'
);
const
scope
=
ref
(
'部门'
);
const
department
=
ref
(
''
);
const
category
=
ref
(
''
);
const
uploadRange
=
ref
(
''
);
const
deliveryRange
=
ref
(
''
);
const
pageData
=
reactive
({
currentPage
:
1
,
pageSize
:
10
,
pageSizes
:
[
10
,
20
,
50
,
100
],
});
const
platforms
=
[
'巨量广告'
,
'巨量千川'
,
'磁力智投'
,
'磁力金牛'
,
'百度营销'
,
'小红书'
];
const
scopes
=
[
'部门'
,
'分组'
,
'个人'
,
'明细'
,
'分日'
,
'分月'
];
const
tableData
=
[
{
department
:
'总计'
,
cost
:
'1375201.50'
,
roi
:
'3.69'
,
totalAmount
:
'¥5,074,860'
,
amount
:
'¥4,740,000'
,
coupon
:
'¥334,860'
,
conversions
:
'44,240'
,
rate
:
'4.54%'
,
costRate
:
'¥31.09'
,
show
:
'26,040,000'
,
avgCost
:
'¥52.81'
,
click
:
'974,510'
,
clickRate
:
'3.74%'
,
avgPrice
:
'¥1.41'
,
play
:
'22,300,000'
},
{
department
:
'项目1-爆款电商'
,
cost
:
'342100.80'
,
roi
:
'4.12'
,
totalAmount
:
'¥1,409,450'
,
amount
:
'¥1,320,000'
,
coupon
:
'¥89,450'
,
conversions
:
'11,400'
,
rate
:
'5.10%'
,
costRate
:
'¥30.01'
,
show
:
'6,450,000'
,
avgCost
:
'¥53.03'
,
click
:
'223,500'
,
clickRate
:
'3.46%'
,
avgPrice
:
'¥1.53'
,
play
:
'5,600,000'
},
{
department
:
'达人测试部门'
,
cost
:
'285400.00'
,
roi
:
'3.85'
,
totalAmount
:
'¥1,098,790'
,
amount
:
'¥1,020,000'
,
coupon
:
'¥78,790'
,
conversions
:
'9,240'
,
rate
:
'4.82%'
,
costRate
:
'¥30.88'
,
show
:
'5,120,000'
,
avgCost
:
'¥55.74'
,
click
:
'191,980'
,
clickRate
:
'3.75%'
,
avgPrice
:
'¥1.48'
,
play
:
'4,320,000'
},
{
department
:
'xx素颜霜项目'
,
cost
:
'220500.00'
,
roi
:
'3.68'
,
totalAmount
:
'¥811,440'
,
amount
:
'¥760,000'
,
coupon
:
'¥51,440'
,
conversions
:
'7,350'
,
rate
:
'4.50%'
,
costRate
:
'¥30.00'
,
show
:
'4,100,000'
,
avgCost
:
'¥53.78'
,
click
:
'163,330'
,
clickRate
:
'3.98%'
,
avgPrice
:
'¥1.35'
,
play
:
'3,680,000'
},
{
department
:
'小真测试部门'
,
cost
:
'196200.50'
,
roi
:
'3.42'
,
totalAmount
:
'¥671,000'
,
amount
:
'¥630,000'
,
coupon
:
'¥41,000'
,
conversions
:
'6,150'
,
rate
:
'4.25%'
,
costRate
:
'¥31.90'
,
show
:
'3,820,000'
,
avgCost
:
'¥51.36'
,
click
:
'144,700'
,
clickRate
:
'3.78%'
,
avgPrice
:
'¥1.35'
,
play
:
'3,100,000'
},
{
department
:
'抖音投放一组'
,
cost
:
'189000.20'
,
roi
:
'3.52'
,
totalAmount
:
'¥665,280'
,
amount
:
'¥620,000'
,
coupon
:
'¥45,280'
,
conversions
:
'5,980'
,
rate
:
'4.15%'
,
costRate
:
'¥31.60'
,
show
:
'3,600,000'
,
avgCost
:
'¥52.50'
,
click
:
'144,000'
,
clickRate
:
'4.00%'
,
avgPrice
:
'¥1.31'
,
play
:
'3,150,000'
},
];
const
pagedTableData
=
computed
(()
=>
{
const
start
=
(
pageData
.
currentPage
-
1
)
*
pageData
.
pageSize
;
return
tableData
.
slice
(
start
,
start
+
pageData
.
pageSize
);
});
const
handleSizeChange
=
()
=>
{
pageData
.
currentPage
=
1
;
};
</
script
>
<
style
scoped
lang=
"scss"
>
.filter-card
,
.table-card
{
border
:
1px
solid
#dfe7f2
;
}
.header-tabs
,
.sub-tabs
,
.table-footer
{
border-bottom
:
1px
solid
#edf0f5
;
}
.table-footer
{
border-top
:
1px
solid
#edf0f5
;
border-bottom
:
none
;
}
.header-tabs
.active
{
color
:
rgba
(
var
(
--
main-color
)
,
1
);
border-bottom
:
2px
solid
rgba
(
var
(
--
main-color
)
,
1
);
}
.analysis-table
{
:deep
(
.el-table__header
th
)
{
background
:
#f8fbff
;
color
:
#48607f
;
font-weight
:
bold
;
}
}
</
style
>
apps/web-vue/src/views/analysis/components/TagAnalysis.vue
0 → 100644
View file @
fd59473d
<
template
>
<div
class=
"p-6"
>
<el-card
class=
"bg-fff round-12"
shadow=
"hover"
>
<div
class=
"flex-items-center gap-34 header-tabs"
>
<div
v-for=
"item in topTabs"
:key=
"item"
class=
"pb-16 font-bold pointer"
:class=
"
{ active: topTab === item }" @click="topTab = item">
{{
item
}}
</div>
</div>
<div
class=
"py-20"
>
<div
class=
"flex mb-18 round-6 platform-box"
>
<div
v-for=
"item in platforms"
:key=
"item"
class=
"px-22 py-8 round-6 font-bold pointer"
:class=
"
{ active: platform === item }" @click="platform = item">
{{
item
}}
</div>
</div>
<div
class=
"flex-items-center"
>
<el-select
v-model=
"category"
class=
"w-240 mr-10"
placeholder=
"请选择分类"
>
<el-option
label=
"全部分类"
value=
"all"
/>
<el-option
label=
"美妆护肤"
value=
"beauty"
/>
</el-select>
<el-select
v-model=
"tag"
class=
"w-220 mr-10"
placeholder=
"请选择标签"
>
<el-option
label=
"全部标签"
value=
"all"
/>
<el-option
label=
"主打模特"
value=
"model"
/>
</el-select>
<div
class=
"w-300 flex-items-center mr-10"
>
<div
class=
"w-90"
>
上传时间:
</div>
<el-date-picker
v-model=
"uploadRange"
type=
"daterange"
range-separator=
"至"
start-placeholder=
"开始日期"
end-placeholder=
"结束日期"
style=
"width: 100% !important;"
/>
</div>
<div
class=
"w-300 flex-items-center mr-10"
>
<div
class=
"w-90"
>
消耗时间:
</div>
<el-date-picker
v-model=
"costRange"
type=
"daterange"
range-separator=
"至"
start-placeholder=
"开始日期"
end-placeholder=
"结束日期"
style=
"width: 100% !important;"
/>
</div>
<el-button
type=
"primary"
class=
"w-66 round-6"
>
查询
</el-button>
<el-button
class=
"w-76 round-6"
>
重置
</el-button>
</div>
</div>
</el-card>
<el-card
class=
"bg-fff round-12 mt-16"
shadow=
"hover"
>
<div
class=
"flex-between pb-16 section-title"
>
<div
class=
"flex-items-center gap-10"
>
<span
class=
"fs-24 color-main"
>
◔
</span>
<span
class=
"font-bold fs-16"
>
占比分析
</span>
</div>
<span
class=
"color-888"
>
数据汇总范围: 2025-10-06 ~ 2025-10-21
</span>
</div>
<div
class=
"flex minh-400 chart-area"
>
<div
class=
"w-400 h-400"
>
<v-chart
class=
"w-full h-full"
:option=
"pieOption"
autoresize
/>
</div>
<div
class=
"flex-1 legend-grid gap-10 ml-60 pt-20"
>
<div
v-for=
"item in chartData"
:key=
"item.name"
class=
"px-14 py-12 round-6 flex-between border-eee"
>
<div
class=
"flex-items-center gap-10"
>
<span
class=
"w-12 h-12 round-2"
:style=
"
{ backgroundColor: item.color }">
</span>
<span
class=
"font-bold"
>
{{
item
.
name
}}
</span>
</div>
<div
class=
"text-right"
>
<div
class=
"font-bold"
>
¥
{{
item
.
value
.
toLocaleString
()
}}
</div>
<div
class=
"fs-12 color-888"
>
{{
item
.
rate
}}
%
</div>
</div>
</div>
</div>
</div>
</el-card>
<el-card
class=
"bg-fff round-12 mt-16"
shadow=
"hover"
>
<div
class=
"pb-16 flex-between table-title"
>
<span
class=
"fs-16 font-bold"
>
详细数据
</span>
<div
class=
"flex-items-center gap-8"
>
<el-button
class=
"round-6"
>
导出
</el-button>
<el-button
class=
"w-34 h-34 round-6"
>
⌯
</el-button>
</div>
</div>
<el-table
:data=
"pagedTableData"
class=
"analysis-table"
>
<el-table-column
prop=
"name"
label=
"模特姓名 / 标签"
width=
"130"
/>
<el-table-column
prop=
"videos"
label=
"视频数量"
width=
"100"
align=
"center"
/>
<el-table-column
prop=
"cost"
label=
"消耗"
width=
"130"
align=
"center"
/>
<el-table-column
prop=
"roi"
label=
"roi"
width=
"90"
align=
"center"
/>
<el-table-column
prop=
"amount"
label=
"成交金额"
width=
"130"
align=
"center"
/>
<el-table-column
prop=
"coupon"
label=
"智能优惠券"
width=
"120"
align=
"center"
/>
<el-table-column
prop=
"subsidy"
label=
"电商平台补贴金额"
width=
"150"
align=
"center"
/>
<el-table-column
prop=
"conversions"
label=
"转化数"
width=
"100"
align=
"center"
/>
<el-table-column
prop=
"rate"
label=
"转化率"
width=
"100"
align=
"center"
/>
<el-table-column
prop=
"costRate"
label=
"转化成本"
width=
"110"
align=
"center"
/>
<el-table-column
prop=
"show"
label=
"展示数"
width=
"120"
align=
"center"
/>
<el-table-column
prop=
"avgCost"
label=
"平均千次展现费用"
width=
"150"
align=
"center"
/>
<el-table-column
prop=
"click"
label=
"点击数"
width=
"110"
align=
"center"
/>
<el-table-column
prop=
"clickRate"
label=
"点击率"
width=
"100"
align=
"center"
/>
<el-table-column
prop=
"price"
label=
"平均点击单价"
width=
"130"
align=
"center"
/>
<el-table-column
prop=
"play"
label=
"播放量"
width=
"130"
align=
"center"
/>
<el-table-column
prop=
"complete"
label=
"3S完播率"
width=
"110"
align=
"center"
/>
<el-table-column
prop=
"deal"
label=
"净成交金额"
width=
"140"
align=
"center"
/>
<el-table-column
prop=
"orders"
label=
"净成交订单数"
width=
"130"
align=
"center"
/>
<el-table-column
prop=
"netRoi"
label=
"净成交ROI"
width=
"110"
align=
"center"
/>
<el-table-column
prop=
"unit"
label=
"净成交订单成本"
width=
"140"
align=
"center"
/>
</el-table>
<div
class=
"py-12 flex justify-end table-footer"
>
<el-pagination
v-model:current-page=
"pageData.currentPage"
v-model:page-size=
"pageData.pageSize"
background
layout=
"total, sizes, prev, pager, next, jumper"
:total=
"tableData.length"
:page-sizes=
"pageData.pageSizes"
@
size-change=
"handleSizeChange"
/>
</div>
</el-card>
</div>
</
template
>
<
script
setup
lang=
"ts"
>
import
{
computed
,
reactive
,
ref
}
from
'vue'
;
import
VChart
from
'vue-echarts'
;
import
{
use
}
from
'echarts/core'
;
import
{
CanvasRenderer
}
from
'echarts/renderers'
;
import
{
PieChart
}
from
'echarts/charts'
;
import
{
GraphicComponent
,
TooltipComponent
}
from
'echarts/components'
;
use
([
CanvasRenderer
,
PieChart
,
TooltipComponent
,
GraphicComponent
]);
const
topTab
=
ref
(
'标签分析'
);
const
platform
=
ref
(
'抖音'
);
const
category
=
ref
(
''
);
const
tag
=
ref
(
''
);
const
uploadRange
=
ref
(
''
);
const
costRange
=
ref
(
''
);
const
pageData
=
reactive
({
currentPage
:
1
,
pageSize
:
10
,
pageSizes
:
[
10
,
20
,
50
,
100
],
});
const
topTabs
=
[
'标签分析'
,
'潜力 / 当月爆款'
,
'使用数据'
];
const
platforms
=
[
'抖音'
,
'腾讯'
,
'TikTok'
];
const
chartData
=
[
{
name
:
'谭明珠(主打模特)'
,
value
:
128450.5
,
rate
:
25.3
,
color
:
'#5572f6'
},
{
name
:
'林启珊(高ROI)'
,
value
:
86200.2
,
rate
:
17.0
,
color
:
'#8cc97d'
},
{
name
:
'吴雪妮(痛点对撞)'
,
value
:
68300
,
rate
:
13.5
,
color
:
'#f6b827'
},
{
name
:
'李银凤(口播种草)'
,
value
:
52140.1
,
rate
:
10.3
,
color
:
'#f87171'
},
{
name
:
'阮丽琼(情景短剧)'
,
value
:
43200
,
rate
:
8.5
,
color
:
'#4bb9e9'
},
{
name
:
'马依卓(测评体验)'
,
value
:
38100
,
rate
:
7.5
,
color
:
'#4bd0a0'
},
{
name
:
'无模特(纯产品)'
,
value
:
32000
,
rate
:
6.3
,
color
:
'#ff823b'
},
{
name
:
'绿款二创标签'
,
value
:
24500
,
rate
:
4.8
,
color
:
'#a78bfa'
},
{
name
:
'沉浸拆箱标签'
,
value
:
18400
,
rate
:
3.6
,
color
:
'#f472b6'
},
{
name
:
'高反差对比'
,
value
:
16150.57
,
rate
:
3.2
,
color
:
'#60a5fa'
},
];
const
pieOption
=
computed
(()
=>
({
tooltip
:
{
trigger
:
'item'
},
series
:
[{
type
:
'pie'
,
radius
:
[
'48%'
,
'82%'
],
label
:
{
show
:
false
},
data
:
chartData
.
map
((
item
)
=>
({
value
:
item
.
value
,
name
:
item
.
name
,
itemStyle
:
{
color
:
item
.
color
}
}))
}],
graphic
:
[
{
type
:
'text'
,
left
:
'center'
,
top
:
'42%'
,
style
:
{
text
:
'总消耗金额(元)'
,
fill
:
'#8492a6'
,
textAlign
:
'center'
,
fontSize
:
12
}
},
{
type
:
'text'
,
left
:
'center'
,
top
:
'50%'
,
style
:
{
text
:
'507441.37'
,
fill
:
'#0f172a'
,
textAlign
:
'center'
,
fontSize
:
28
,
fontWeight
:
700
}
},
{
type
:
'text'
,
left
:
'center'
,
top
:
'61%'
,
style
:
{
text
:
'多维对比看板'
,
fill
:
'#7c3aed'
,
textAlign
:
'center'
,
fontSize
:
12
,
fontWeight
:
700
}
},
],
}));
const
tableData
=
[
{
name
:
'总计'
,
videos
:
768
,
cost
:
'¥507,441.37'
,
roi
:
'2.85'
,
amount
:
'¥1,446,202.00'
,
coupon
:
'¥12,300.00'
,
subsidy
:
'¥8,200.00'
,
conversions
:
'16,200'
,
rate
:
'3.65%'
,
costRate
:
'¥31.32'
,
show
:
'9,740,000'
,
avgCost
:
'¥52.10'
,
click
:
'355,501'
,
clickRate
:
'3.65%'
,
price
:
'¥1.43'
,
play
:
'8,200,000'
,
complete
:
'19.2%'
,
deal
:
'¥1,380,500.00'
,
orders
:
'15,350'
,
netRoi
:
'2.72'
,
unit
:
'¥33.05'
},
{
name
:
'谭明珠'
,
videos
:
185
,
cost
:
'¥128,450.50'
,
roi
:
'3.25'
,
amount
:
'¥417,464.00'
,
coupon
:
'¥3,850.00'
,
subsidy
:
'¥2,400.00'
,
conversions
:
'4,210'
,
rate
:
'4.12%'
,
costRate
:
'¥30.50'
,
show
:
'2,450,000'
,
avgCost
:
'¥52.42'
,
click
:
'98,200'
,
clickRate
:
'4.01%'
,
price
:
'¥1.31'
,
play
:
'2,100,000'
,
complete
:
'22.5%'
,
deal
:
'¥398,500.00'
,
orders
:
'4,010'
,
netRoi
:
'3.10'
,
unit
:
'¥32.03'
},
{
name
:
'林启珊'
,
videos
:
142
,
cost
:
'¥86,200.20'
,
roi
:
'2.98'
,
amount
:
'¥256,876.00'
,
coupon
:
'¥2,100.00'
,
subsidy
:
'¥1,800.00'
,
conversions
:
'2,840'
,
rate
:
'3.85%'
,
costRate
:
'¥30.35'
,
show
:
'1,680,000'
,
avgCost
:
'¥51.30'
,
click
:
'64,680'
,
clickRate
:
'3.85%'
,
price
:
'¥1.33'
,
play
:
'1,420,000'
,
complete
:
'20.8%'
,
deal
:
'¥245,200.00'
,
orders
:
'2,710'
,
netRoi
:
'2.84'
,
unit
:
'¥31.80'
},
{
name
:
'吴雪妮'
,
videos
:
118
,
cost
:
'¥68,300.00'
,
roi
:
'2.82'
,
amount
:
'¥192,606.00'
,
coupon
:
'¥1,650.00'
,
subsidy
:
'¥1,200.00'
,
conversions
:
'2,150'
,
rate
:
'3.62%'
,
costRate
:
'¥31.76'
,
show
:
'1,320,000'
,
avgCost
:
'¥51.74'
,
click
:
'47,784'
,
clickRate
:
'3.62%'
,
price
:
'¥1.43'
,
play
:
'1,110,000'
,
complete
:
'19.5%'
,
deal
:
'¥183,900.00'
,
orders
:
'2,050'
,
netRoi
:
'2.69'
,
unit
:
'¥33.31'
},
{
name
:
'李银凤'
,
videos
:
95
,
cost
:
'¥52,140.10'
,
roi
:
'2.75'
,
amount
:
'¥143,385.00'
,
coupon
:
'¥1,200.00'
,
subsidy
:
'¥950.00'
,
conversions
:
'1,620'
,
rate
:
'3.45%'
,
costRate
:
'¥32.18'
,
show
:
'1,050,000'
,
avgCost
:
'¥49.65'
,
click
:
'36,225'
,
clickRate
:
'3.45%'
,
price
:
'¥1.44'
,
play
:
'890,000'
,
complete
:
'18.2%'
,
deal
:
'¥136,800.00'
,
orders
:
'1,540'
,
netRoi
:
'2.62'
,
unit
:
'¥33.85'
},
];
const
pagedTableData
=
computed
(()
=>
{
const
start
=
(
pageData
.
currentPage
-
1
)
*
pageData
.
pageSize
;
return
tableData
.
slice
(
start
,
start
+
pageData
.
pageSize
);
});
const
handleSizeChange
=
()
=>
{
pageData
.
currentPage
=
1
;
};
</
script
>
<
style
scoped
lang=
"scss"
>
.header-tabs
,
.section-title
,
.table-title
,
.table-footer
{
border-bottom
:
1px
solid
#edf0f5
;
}
.table-footer
{
border-top
:
1px
solid
#edf0f5
;
border-bottom
:
none
;
}
.header-tabs
.active
{
color
:
rgba
(
var
(
--
main-color
)
,
1
);
border-bottom
:
2px
solid
rgba
(
var
(
--
main-color
)
,
1
);
}
.platform-box
{
width
:
fit-content
;
border
:
1px
solid
#dfe7f2
;
overflow
:
hidden
;
}
.platform-box
.active
{
background
:
rgba
(
var
(
--
main-color
)
,
1
);
color
:
#fff
;
}
.legend-grid
{
display
:
grid
;
grid-template-columns
:
repeat
(
2
,
300px
);
}
.analysis-table
{
:deep
(
.el-table__header
th
)
{
background
:
#f8fbff
;
color
:
#48607f
;
font-weight
:
bold
;
}
}
</
style
>
apps/web-vue/src/views/analysis/components/TencentDeliveryReport.vue
0 → 100644
View file @
fd59473d
<
template
>
<div
class=
"p-6"
>
<el-card
class=
"bg-fff round-12 mt-10"
shadow=
"hover"
>
<div
class=
"flex-items-center gap-30 header-tabs"
>
<div
v-for=
"item in dataTabs"
:key=
"item"
class=
"pb-16 font-bold pointer"
:class=
"
{ active: dataTab === item }" @click="dataTab = item">
{{
item
}}
</div>
</div>
<div
class=
"pt-16 flex-between"
>
<div
class=
"flex-items-center"
>
<el-button
type=
"primary"
class=
"round-6"
>
汇总
</el-button>
<el-button
class=
"round-6 mr-10"
>
明细
</el-button>
<el-select
v-model=
"department"
class=
"w-180 mr-10"
placeholder=
"请选择部门"
><el-option
label=
"默认部门"
value=
"默认部门"
/></el-select>
<el-select
v-model=
"group"
class=
"w-180 mr-10"
placeholder=
"请选择"
><el-option
label=
"华南电商一队"
value=
"华南电商一队"
/></el-select>
<div
class=
"w-240 mr-10"
>
<el-date-picker
v-model=
"range"
type=
"daterange"
range-separator=
"至"
start-placeholder=
"2022/04/27"
end-placeholder=
"2025/05/12"
style=
"width: 100% !important;"
/>
</div>
<el-button
type=
"primary"
class=
"w-66 round-6 mr-10"
>
查询
</el-button>
</div>
</div>
</el-card>
<el-card
class=
"bg-fff round-12 mt-16"
shadow=
"hover"
>
<div
class=
"pb-12 flex-between table-title"
>
<span
class=
"fs-16 font-bold"
>
汇总数据
</span>
<el-button
type=
"default"
plain
class=
"round-6"
>
导出数据
</el-button>
</div>
<el-table
:data=
"pagedTableData"
class=
"analysis-table"
>
<el-table-column
prop=
"department"
label=
"部门"
min-width=
"180"
/>
<el-table-column
prop=
"cost"
label=
"消耗"
align=
"center"
/>
<el-table-column
prop=
"conversions"
label=
"转化数"
align=
"center"
/>
<el-table-column
prop=
"rate"
label=
"转化率"
align=
"center"
/>
<el-table-column
prop=
"costRate"
label=
"转化成本"
align=
"center"
/>
<el-table-column
prop=
"show"
label=
"展示数"
align=
"center"
/>
<el-table-column
prop=
"click"
label=
"点击数"
align=
"center"
/>
<el-table-column
prop=
"clickRate"
label=
"点击率"
align=
"center"
/>
<el-table-column
prop=
"avgPrice"
label=
"平均点击单价"
align=
"center"
/>
<el-table-column
prop=
"play"
label=
"播放量"
align=
"center"
/>
<el-table-column
prop=
"complete"
label=
"3S完播率"
align=
"center"
/>
</el-table>
<div
class=
"px-20 py-12 flex justify-end table-footer"
>
<el-pagination
v-model:current-page=
"pageData.currentPage"
v-model:page-size=
"pageData.pageSize"
background
layout=
"total, sizes, prev, pager, next, jumper"
:total=
"tableData.length"
:page-sizes=
"pageData.pageSizes"
@
size-change=
"handleSizeChange"
/>
</div>
</el-card>
</div>
</
template
>
<
script
setup
lang=
"ts"
>
import
{
computed
,
reactive
,
ref
}
from
'vue'
;
const
dataTab
=
ref
(
'部门数据'
);
const
department
=
ref
(
''
);
const
group
=
ref
(
''
);
const
range
=
ref
(
''
);
const
pageData
=
reactive
({
currentPage
:
1
,
pageSize
:
10
,
pageSizes
:
[
10
,
20
,
50
,
100
],
});
const
dataTabs
=
[
'部门数据'
,
'分组数据'
,
'个人数据'
];
const
tableData
=
[
{
department
:
'总计'
,
cost
:
'361051.50'
,
conversions
:
'11,550'
,
rate
:
'4.27%'
,
costRate
:
'¥31.26'
,
show
:
'6,880,000'
,
click
:
'270,530'
,
clickRate
:
'3.93%'
,
avgPrice
:
'1.33'
,
play
:
'5,860,000'
,
complete
:
'20.6%'
},
{
department
:
'默认部门'
,
cost
:
'128450.50'
,
conversions
:
'4,210'
,
rate
:
'4.12%'
,
costRate
:
'¥30.50'
,
show
:
'2,450,000'
,
click
:
'98,200'
,
clickRate
:
'4.01%'
,
avgPrice
:
'1.31'
,
play
:
'2,100,000'
,
complete
:
'22.5%'
},
{
department
:
'华南电商一队'
,
cost
:
'96200.80'
,
conversions
:
'3,120'
,
rate
:
'3.95%'
,
costRate
:
'¥30.83'
,
show
:
'1,820,000'
,
click
:
'74,620'
,
clickRate
:
'4.10%'
,
avgPrice
:
'1.29'
,
play
:
'1,560,000'
,
complete
:
'21.2%'
},
{
department
:
'华东投放二队'
,
cost
:
'84300.00'
,
conversions
:
'2,680'
,
rate
:
'3.78%'
,
costRate
:
'¥31.45'
,
show
:
'1,590,000'
,
click
:
'62,010'
,
clickRate
:
'3.90%'
,
avgPrice
:
'1.36'
,
play
:
'1,320,000'
,
complete
:
'20.4%'
},
{
department
:
'海外品牌推广组'
,
cost
:
'52100.20'
,
conversions
:
'1,540'
,
rate
:
'3.45%'
,
costRate
:
'¥33.83'
,
show
:
'1,020,000'
,
click
:
'35,700'
,
clickRate
:
'3.50%'
,
avgPrice
:
'1.46'
,
play
:
'880,000'
,
complete
:
'18.5%'
},
];
const
pagedTableData
=
computed
(()
=>
{
const
start
=
(
pageData
.
currentPage
-
1
)
*
pageData
.
pageSize
;
return
tableData
.
slice
(
start
,
start
+
pageData
.
pageSize
);
});
const
handleSizeChange
=
()
=>
{
pageData
.
currentPage
=
1
;
};
</
script
>
<
style
scoped
lang=
"scss"
>
.header-tabs
,
.table-title
,
.table-footer
{
border-bottom
:
1px
solid
#edf0f5
;
}
.table-footer
{
border-top
:
1px
solid
#edf0f5
;
border-bottom
:
none
;
}
.header-tabs
.active
{
color
:
rgba
(
var
(
--
main-color
)
,
1
);
border-bottom
:
2px
solid
rgba
(
var
(
--
main-color
)
,
1
);
}
.analysis-table
{
:deep
(
.el-table__header
th
)
{
background
:
#f8fbff
;
color
:
#48607f
;
font-weight
:
bold
;
}
}
</
style
>
apps/web-vue/src/views/analysis/video.vue
View file @
fd59473d
<
template
>
<div>
<div
class=
"bgmr vh100 over-y-auto"
>
<section
class=
"bg-fff px-20 py-10 analysis-tabs"
>
<div
class=
"flex-items-center gap-16"
>
<div
v-for=
"item in tabs"
:key=
"item.value"
class=
"px-12 py-8 round-6 font-bold pointer"
:class=
"activeTab === item.value ? 'bg-main color-fff' : 'color-000'"
@
click=
"activeTab = item.value"
>
{{
item
.
label
}}
</div>
</div>
</section>
<div
class=
"p-16"
>
<component
:is=
"currentComponent"
/>
</div>
</div>
</
template
>
<
script
setup
lang=
"ts"
>
import
{
computed
,
ref
}
from
'vue'
;
import
AdPlatformTags
from
'./components/AdPlatformTags.vue'
;
import
TagAnalysis
from
'./components/TagAnalysis.vue'
;
import
TencentDeliveryReport
from
'./components/TencentDeliveryReport.vue'
;
import
DeliveryReport
from
'./components/DeliveryReport.vue'
;
const
activeTab
=
ref
(
'platform'
);
const
tabs
=
[
{
label
:
'广告平台标签'
,
value
:
'platform'
,
component
:
AdPlatformTags
},
{
label
:
'标签分析'
,
value
:
'tag'
,
component
:
TagAnalysis
},
{
label
:
'腾讯投放报表'
,
value
:
'tencent'
,
component
:
TencentDeliveryReport
},
{
label
:
'投放报表'
,
value
:
'delivery'
,
component
:
DeliveryReport
},
];
const
currentComponent
=
computed
(()
=>
tabs
.
find
((
item
)
=>
item
.
value
===
activeTab
.
value
)?.
component
);
</
script
>
<
style
scoped
lang=
"scss"
>
.analysis-tabs
{
border-bottom
:
1px
solid
#dfe7f2
;
}
</
style
>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment