|
@@ -59,9 +59,12 @@
|
|
|
top: 65px;
|
|
|
right: 10px;
|
|
|
}
|
|
|
-th div {
|
|
|
- white-space: nowrap;
|
|
|
+.ant-table-thead tr th {
|
|
|
+ background: none;
|
|
|
}
|
|
|
+/* th div {
|
|
|
+ white-space: nowrap;
|
|
|
+} */
|
|
|
</style>
|
|
|
<template>
|
|
|
<div class="data-display-statistics">
|
|
@@ -88,11 +91,11 @@ th div {
|
|
|
:style="active==6?'color:cornflowerblue;background:#f2f2f2':''"
|
|
|
@click="getAdd(6)"
|
|
|
>近三月</p>
|
|
|
- <p
|
|
|
+ <!-- <p
|
|
|
:style="active==7?'color:cornflowerblue;background:#f2f2f2':''"
|
|
|
@click="getAdd(7)"
|
|
|
>近半年</p>
|
|
|
- <p :style="active==8?'color:cornflowerblue;background:#f2f2f2':''" @click="getAdd(8)">所有</p>
|
|
|
+ <p :style="active==8?'color:cornflowerblue;background:#f2f2f2':''" @click="getAdd(8)">所有</p>-->
|
|
|
<a-range-picker
|
|
|
style="width:400px"
|
|
|
:disabledDate="disabledDate"
|
|
@@ -110,10 +113,76 @@ th div {
|
|
|
<a-row :gutter="10" style="margin-top:10px">
|
|
|
<a-col :span="24">
|
|
|
<a-card style="width:100%;">
|
|
|
- <a-table :columns="columns" :dataSource="data" bordered id="outTable" :pagination="false"></a-table>
|
|
|
+ <a-table
|
|
|
+ :columns="columns"
|
|
|
+ :dataSource="data"
|
|
|
+ bordered
|
|
|
+ id="outTable"
|
|
|
+ :pagination="false"
|
|
|
+ @change="onChange"
|
|
|
+ :customRow="rowClick"
|
|
|
+ >
|
|
|
+ <div slot="url" slot-scope="url">
|
|
|
+ <video
|
|
|
+ class="video"
|
|
|
+ :src="url"
|
|
|
+ controls="controls"
|
|
|
+ style="height:200px"
|
|
|
+ >您的浏览器不支持 video 标签。</video>
|
|
|
+ </div>
|
|
|
+ <span slot="photoClickRatio" slot-scope="photoClickRatio">{{photoClickRatio|getBo}}</span>
|
|
|
+ <span slot="actionRatio" slot-scope="actionRatio">{{actionRatio|getBo}}</span>
|
|
|
+ <span
|
|
|
+ slot="impression1kCost"
|
|
|
+ slot-scope="impression1kCost"
|
|
|
+ >{{impression1kCost|toFixtwo}}</span>
|
|
|
+ <span slot="photoClickCost" slot-scope="photoClickCost">{{photoClickCost|toFixtwo}}</span>
|
|
|
+ <span slot="actionCost" slot-scope="actionCost">{{actionCost|toFixtwo}}</span>
|
|
|
+ <span slot="conversionPrice" slot-scope="conversionPrice">{{conversionPrice|toFixtwo}}</span>
|
|
|
+ </a-table>
|
|
|
</a-card>
|
|
|
</a-col>
|
|
|
</a-row>
|
|
|
+ <a-modal title="环比展示" v-model="visible" @ok="handleOk" width="90%">
|
|
|
+ <div v-if="detail">
|
|
|
+ <video
|
|
|
+ class="video"
|
|
|
+ :src="detail.url"
|
|
|
+ controls="controls"
|
|
|
+ style="height:200px;"
|
|
|
+ v-show="showVideo"
|
|
|
+ >您的浏览器不支持 video 标签。</video>
|
|
|
+ </div>
|
|
|
+ <a-button type="primary" @click="showVideo = !showVideo">{{!showVideo?"点击查看视频":"点击收起视频"}}</a-button>
|
|
|
+ <a-card style="width:100%;">
|
|
|
+ <a-table
|
|
|
+ :columns="columnsDetail"
|
|
|
+ :dataSource="dataDetail"
|
|
|
+ bordered
|
|
|
+ id="outTable"
|
|
|
+ :pagination="false"
|
|
|
+ >
|
|
|
+ <span slot="photoClickRatio" slot-scope="photoClickRatio">{{photoClickRatio|getBo}}</span>
|
|
|
+ <span slot="actionRatio" slot-scope="actionRatio">{{actionRatio|getBo}}</span>
|
|
|
+ <span slot="impression1kCost" slot-scope="impression1kCost,record">
|
|
|
+ <span v-if="record.statDate=='环比'">{{impression1kCost|getBo}}</span>
|
|
|
+ <span v-else>{{impression1kCost|toFixtwo}}</span>
|
|
|
+ </span>
|
|
|
+ <span slot="photoClickCost" slot-scope="photoClickCost,record">
|
|
|
+ <span v-if="record.statDate=='环比'">{{photoClickCost|getBo}}</span>
|
|
|
+ <span v-else>{{photoClickCost|toFixtwo}}</span>
|
|
|
+ </span>
|
|
|
+ <span slot="actionCost" slot-scope="actionCost,record">
|
|
|
+ <span v-if="record.statDate=='环比'">{{actionCost|getBo}}</span>
|
|
|
+ <span v-else>{{actionCost|toFixtwo}}</span>
|
|
|
+ </span>
|
|
|
+ <span slot="conversionPrice" slot-scope="conversionPrice,record">
|
|
|
+ <span v-if="record.statDate=='环比'">{{conversionPrice|getBo}}</span>
|
|
|
+ <span v-else>{{conversionPrice|toFixtwo}}</span>
|
|
|
+ </span>
|
|
|
+ </a-table>
|
|
|
+ </a-card>
|
|
|
+ </a-modal>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
@@ -121,172 +190,234 @@ th div {
|
|
|
import ARow from 'ant-design-vue/es/grid/Row'
|
|
|
import ACol from 'ant-design-vue/es/grid/Col'
|
|
|
import moment from 'moment'
|
|
|
-import { getAdvertiserList, getReportList, getStatistics } from '@api/statistics'
|
|
|
+import { getKuaiShouMaterialMarket, getKuaiShouChainRatio } from '@api/statistics'
|
|
|
import axios from 'axios'
|
|
|
-
|
|
|
+import { mapGetters } from 'vuex'
|
|
|
+import { stopOtherVideo, closeAllVideoFun } from '@/utils/videoControl' // 停止除当前外的其他视频播放,及停止所有视频播放的方法
|
|
|
var length = 0
|
|
|
var active = 1
|
|
|
const columns = [
|
|
|
{
|
|
|
- title: '时间',
|
|
|
- dataIndex: 'date',
|
|
|
+ title: '视频',
|
|
|
+ dataIndex: 'url',
|
|
|
+ key: 'url',
|
|
|
align: 'center',
|
|
|
- customRender: function(text, record, index) {
|
|
|
- const obj = {
|
|
|
- children: text,
|
|
|
- attrs: {}
|
|
|
- }
|
|
|
- for (let i = 0; i < length; i++) {
|
|
|
- if (index == 0 && i == 0) {
|
|
|
- obj.attrs.rowSpan = length
|
|
|
- } else {
|
|
|
- if (index == i) {
|
|
|
- obj.attrs.rowSpan = 0
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return obj
|
|
|
- }
|
|
|
+ scopedSlots: { customRender: 'url' }
|
|
|
},
|
|
|
{
|
|
|
- title: '账户Id',
|
|
|
- dataIndex: 'accountId',
|
|
|
+ title: '花费',
|
|
|
+ dataIndex: 'cost',
|
|
|
+ key: 'cost',
|
|
|
align: 'center',
|
|
|
- customRender: function(text, record, index) {
|
|
|
- const obj = {
|
|
|
- children: text,
|
|
|
- attrs: {}
|
|
|
- }
|
|
|
- if (active == 1) {
|
|
|
- for (let i = 0; i < length; i++) {
|
|
|
- if (index >= length - 3) {
|
|
|
- obj.attrs.colSpan = 2
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return obj
|
|
|
- }
|
|
|
+ sorter: (a, b) => a.cost - b.cost
|
|
|
},
|
|
|
{
|
|
|
- title: '账户昵称',
|
|
|
- dataIndex: 'accountName',
|
|
|
- scopedSlots: { customRender: 'cost' },
|
|
|
+ title: '封面曝光数',
|
|
|
+ dataIndex: 'photoShow',
|
|
|
+ key: 'photoShow',
|
|
|
align: 'center',
|
|
|
- customRender: function(text, record, index) {
|
|
|
- const obj = {
|
|
|
- children: text,
|
|
|
- attrs: {}
|
|
|
- }
|
|
|
- if (active == 1) {
|
|
|
- for (let i = 0; i < length; i++) {
|
|
|
- if (index >= length - 3) {
|
|
|
- obj.attrs.colSpan = 0
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ sorter: (a, b) => a.photoShow - b.photoShow
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '封面点击数',
|
|
|
+ dataIndex: 'photoClick',
|
|
|
+ key: 'photoClick',
|
|
|
+ align: 'center',
|
|
|
+ sorter: (a, b) => a.photoClick - b.photoClick
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '素材曝光数',
|
|
|
+ dataIndex: 'aclick',
|
|
|
+ key: 'aclick',
|
|
|
+ align: 'center',
|
|
|
+ sorter: (a, b) => a.aclick - b.aclick
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '行为数',
|
|
|
+ dataIndex: 'bclick',
|
|
|
+ key: 'bclick',
|
|
|
+ align: 'center',
|
|
|
+ sorter: (a, b) => a.bclick - b.bclick
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '封面点击率',
|
|
|
+ dataIndex: 'photoClickRatio',
|
|
|
+ key: 'photoClickRatio',
|
|
|
+ align: 'center',
|
|
|
+ scopedSlots: { customRender: 'photoClickRatio' },
|
|
|
+ sorter: (a, b) => a.photoClickRatio - b.photoClickRatio
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '行为率',
|
|
|
+ dataIndex: 'actionRatio',
|
|
|
+ key: 'actionRatio',
|
|
|
+ align: 'center',
|
|
|
+ scopedSlots: { customRender: 'actionRatio' },
|
|
|
+ sorter: (a, b) => a.actionRatio - b.actionRatio
|
|
|
+ },
|
|
|
|
|
|
- return obj
|
|
|
- }
|
|
|
+ {
|
|
|
+ title: '均千次封面曝光花费(元)',
|
|
|
+ dataIndex: 'impression1kCost',
|
|
|
+ key: 'impression1kCost',
|
|
|
+ scopedSlots: { customRender: 'impression1kCost' },
|
|
|
+ align: 'center',
|
|
|
+ sorter: (a, b) => a.impression1kCost - b.impression1kCost
|
|
|
},
|
|
|
{
|
|
|
- title: '消耗(¥)',
|
|
|
- dataIndex: 'cost',
|
|
|
- scopedSlots: { customRender: 'cost' },
|
|
|
+ title: '平均封面点击单价(元)',
|
|
|
+ dataIndex: 'photoClickCost',
|
|
|
+ key: 'photoClickCost',
|
|
|
+ scopedSlots: { customRender: 'photoClickCost' },
|
|
|
+ align: 'center',
|
|
|
+ sorter: (a, b) => a.photoClickCost - b.photoClickCost
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '平均行为单价(元)',
|
|
|
+ dataIndex: 'actionCost',
|
|
|
+ key: 'actionCost',
|
|
|
+ scopedSlots: { customRender: 'actionCost' },
|
|
|
+ align: 'center',
|
|
|
+ sorter: (a, b) => a.actionCost - b.actionCost
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '转化数',
|
|
|
+ dataIndex: 'conversions',
|
|
|
+ key: 'conversions',
|
|
|
+ align: 'center',
|
|
|
+ sorter: (a, b) => a.conversions - b.conversions
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '转化单价(元)',
|
|
|
+ dataIndex: 'conversionPrice',
|
|
|
+ key: 'conversionPrice',
|
|
|
+ scopedSlots: { customRender: 'conversionPrice' },
|
|
|
+ align: 'center',
|
|
|
+ sorter: (a, b) => a.conversionPrice - b.conversionPrice
|
|
|
+ }
|
|
|
+]
|
|
|
+const columnsDetail = [
|
|
|
+ {
|
|
|
+ title: '日期',
|
|
|
+ dataIndex: 'statDate',
|
|
|
+ key: 'statDate',
|
|
|
align: 'center'
|
|
|
},
|
|
|
{
|
|
|
- title: '折后消耗(¥)',
|
|
|
- dataIndex: 'costY',
|
|
|
+ title: '花费',
|
|
|
+ dataIndex: 'cost',
|
|
|
+ key: 'cost',
|
|
|
align: 'center'
|
|
|
},
|
|
|
{
|
|
|
- title: '封面展示',
|
|
|
+ title: '封面曝光数',
|
|
|
dataIndex: 'photoShow',
|
|
|
+ key: 'photoShow',
|
|
|
align: 'center'
|
|
|
},
|
|
|
{
|
|
|
- title: '封面点击',
|
|
|
+ title: '封面点击数',
|
|
|
dataIndex: 'photoClick',
|
|
|
+ key: 'photoClick',
|
|
|
align: 'center'
|
|
|
},
|
|
|
{
|
|
|
title: '素材曝光数',
|
|
|
dataIndex: 'aclick',
|
|
|
+ key: 'aclick',
|
|
|
align: 'center'
|
|
|
},
|
|
|
{
|
|
|
- title: '封面点击率',
|
|
|
- dataIndex: 'photoClickRatio',
|
|
|
+ title: '行为数',
|
|
|
+ dataIndex: 'bclick',
|
|
|
+ key: 'bclick',
|
|
|
align: 'center'
|
|
|
},
|
|
|
{
|
|
|
- title: 'cvr',
|
|
|
- dataIndex: 'cvr',
|
|
|
- align: 'center'
|
|
|
+ title: '封面点击率',
|
|
|
+ dataIndex: 'photoClickRatio',
|
|
|
+ key: 'photoClickRatio',
|
|
|
+ align: 'center',
|
|
|
+ scopedSlots: { customRender: 'photoClickRatio' }
|
|
|
},
|
|
|
{
|
|
|
- title: 'cpm(¥)',
|
|
|
- dataIndex: 'cpm',
|
|
|
- align: 'center'
|
|
|
+ title: '行为率',
|
|
|
+ dataIndex: 'actionRatio',
|
|
|
+ key: 'actionRatio',
|
|
|
+ align: 'center',
|
|
|
+ scopedSlots: { customRender: 'actionRatio' }
|
|
|
},
|
|
|
+
|
|
|
{
|
|
|
- title: '行为数',
|
|
|
- dataIndex: 'bClick',
|
|
|
+ title: '均千次封面曝光花费(元)',
|
|
|
+ dataIndex: 'impression1kCost',
|
|
|
+ key: 'impression1kCost',
|
|
|
+ scopedSlots: { customRender: 'impression1kCost' },
|
|
|
align: 'center'
|
|
|
},
|
|
|
{
|
|
|
- title: '转化数',
|
|
|
- dataIndex: 'formCount',
|
|
|
+ title: '平均封面点击单价(元)',
|
|
|
+ dataIndex: 'photoClickCost',
|
|
|
+ key: 'photoClickCost',
|
|
|
+ scopedSlots: { customRender: 'photoClickCost' },
|
|
|
align: 'center'
|
|
|
},
|
|
|
{
|
|
|
- title: '折前转化单价(¥)',
|
|
|
- dataIndex: 'beforeFormPrice',
|
|
|
+ title: '平均行为单价(元)',
|
|
|
+ dataIndex: 'actionCost',
|
|
|
+ key: 'actionCost',
|
|
|
+ scopedSlots: { customRender: 'actionCost' },
|
|
|
align: 'center'
|
|
|
},
|
|
|
{
|
|
|
- title: '折后转化单价(¥)',
|
|
|
- dataIndex: 'afterFormPrice',
|
|
|
+ title: '转化数',
|
|
|
+ dataIndex: 'conversions',
|
|
|
+ key: 'conversions',
|
|
|
align: 'center'
|
|
|
},
|
|
|
{
|
|
|
- title: '单价区间',
|
|
|
- dataIndex: 'price',
|
|
|
- align: 'center',
|
|
|
- customRender: function(text, record, index) {
|
|
|
- const obj = {
|
|
|
- children: text,
|
|
|
- attrs: {}
|
|
|
- }
|
|
|
- for (let i = 0; i < length; i++) {
|
|
|
- if (index == 0 && i == 0) {
|
|
|
- obj.attrs.rowSpan = length
|
|
|
- } else {
|
|
|
- if (index == i) {
|
|
|
- obj.attrs.rowSpan = 0
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return obj
|
|
|
- }
|
|
|
+ title: '转化单价(元)',
|
|
|
+ dataIndex: 'conversionPrice',
|
|
|
+ key: 'conversionPrice',
|
|
|
+ scopedSlots: { customRender: 'conversionPrice' },
|
|
|
+ align: 'center'
|
|
|
}
|
|
|
]
|
|
|
-
|
|
|
+function onChange(pagination, filters, sorter) {
|
|
|
+ // console.log('params', pagination, filters, sorter)
|
|
|
+}
|
|
|
export default {
|
|
|
name: 'data-display-statistics',
|
|
|
components: {
|
|
|
ACol,
|
|
|
- ARow,
|
|
|
+ ARow
|
|
|
},
|
|
|
|
|
|
data: function() {
|
|
|
return {
|
|
|
title: '素材大盘报表',
|
|
|
columns,
|
|
|
+ columnsDetail,
|
|
|
data: [],
|
|
|
- active:1,
|
|
|
- allValue:[],
|
|
|
- startValue:[]
|
|
|
+ active: 1,
|
|
|
+ allValue: [],
|
|
|
+ startValue: [],
|
|
|
+ visible: false,
|
|
|
+ showVideo: false,
|
|
|
+ detail: null,
|
|
|
+ dataDetail: [],
|
|
|
+ dataYestodayDetail: [],
|
|
|
+ dataChainRatio: [],
|
|
|
+ rowClick: record => ({
|
|
|
+ // 事件
|
|
|
+ on: {
|
|
|
+ click: () => {
|
|
|
+ // 点击改行时要做的事情
|
|
|
+ this.detail = record
|
|
|
+ this.getMineList(record.signature)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
}
|
|
|
},
|
|
|
filters: {
|
|
@@ -304,10 +435,32 @@ export default {
|
|
|
let s = date.getSeconds()
|
|
|
s = s < 10 ? '0' + s : s
|
|
|
return y + '-' + MM + '-' + d + ' ' + h + ':' + m + ':' + s
|
|
|
+ },
|
|
|
+ toFixtwo: function(value) {
|
|
|
+ if (value) {
|
|
|
+ return value.toFixed(2)
|
|
|
+ } else {
|
|
|
+ return 0.0
|
|
|
+ }
|
|
|
+ },
|
|
|
+ getBo: function(value) {
|
|
|
+ if (value) {
|
|
|
+ return (value * 100).toFixed(2) + '%'
|
|
|
+ } else {
|
|
|
+ return '0.00%'
|
|
|
+ }
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
+ onChange,
|
|
|
+ handleOk() {
|
|
|
+ this.visible = false
|
|
|
+ },
|
|
|
+ ...mapGetters(['nickname', 'avatar', 'userInfo']),
|
|
|
moment,
|
|
|
+ disabledDate(current) {
|
|
|
+ return current && current > moment().endOf('day')
|
|
|
+ },
|
|
|
getAdd(checked) {
|
|
|
if (checked == 9) {
|
|
|
if (this.startValue.length > 0 && this.startValue[0]) {
|
|
@@ -320,12 +473,82 @@ export default {
|
|
|
}
|
|
|
this.active = checked
|
|
|
active = checked
|
|
|
+ this.getList()
|
|
|
+ },
|
|
|
+ getList() {
|
|
|
+ var params = {}
|
|
|
+ params.userId = this.userInfo().id
|
|
|
+ params.type = this.active
|
|
|
+ if (this.active == 9) {
|
|
|
+ params.startDate = this.allValue[0]
|
|
|
+ params.endDate = this.allValue[1]
|
|
|
+ }
|
|
|
+ getKuaiShouMaterialMarket(params).then(res => {
|
|
|
+ console.log(res)
|
|
|
+ this.data = res.map((item, index) => {
|
|
|
+ return {
|
|
|
+ key: index,
|
|
|
+ ...item
|
|
|
+ }
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+ getMineList(md5) {
|
|
|
+ this.dataDetail = []
|
|
|
+ this.showVideo = false
|
|
|
+ var params = {}
|
|
|
+ params.type = this.active
|
|
|
+ params.signature = md5
|
|
|
+ getKuaiShouChainRatio(params).then(res => {
|
|
|
+ this.visible = true
|
|
|
+ console.log(res)
|
|
|
+ if (res.contrast) {
|
|
|
+ var now = {
|
|
|
+ key: 1,
|
|
|
+ ...res.contrast,
|
|
|
+ statDate:
|
|
|
+ this.active == 1 || this.active == 2 ? res.contrast.statDate : res.contrast.startDate + ' ~ ' + res.contrast.endDate
|
|
|
+ }
|
|
|
+ var yesterday = {
|
|
|
+ key: 2,
|
|
|
+ ...res.beContrast,
|
|
|
+ statDate:
|
|
|
+ this.active == 1 || this.active == 2 ? res.beContrast.statDate : res.beContrast.startDate + ' ~ ' + res.beContrast.endDate
|
|
|
+ }
|
|
|
+ var chainRatio = {
|
|
|
+ key: 3,
|
|
|
+ statDate: '环比',
|
|
|
+ photoClickRatio: res.chainRatio.photoClickRatioProportion,
|
|
|
+ conversions: (res.chainRatio.conversionsProportion * 100).toFixed(2) + '%',
|
|
|
+ cost: (res.chainRatio.costProportion * 100).toFixed(2) + '%',
|
|
|
+ impression1kCost: res.chainRatio.impression1kCostProportion,
|
|
|
+ photoClick: (res.chainRatio.photoClickProportion * 100).toFixed(2) + '%',
|
|
|
+ bclick: (res.chainRatio.bClickProportion * 100).toFixed(2) + '%',
|
|
|
+ aclick: (res.chainRatio.aClickProportion * 100).toFixed(2) + '%',
|
|
|
+ photoClickCost: res.chainRatio.photoClickCostProportion,
|
|
|
+ conversionPrice: res.chainRatio.conversionPriceProportion,
|
|
|
+ actionRatio: res.chainRatio.actionRatioProportion,
|
|
|
+ actionCost: res.chainRatio.actionCostProportion,
|
|
|
+ photoShow: (res.chainRatio.showProportion * 100).toFixed(2) + '%'
|
|
|
+ }
|
|
|
+ this.dataDetail.push(now)
|
|
|
+ this.dataDetail.push(yesterday)
|
|
|
+ this.dataDetail.push(chainRatio)
|
|
|
+ } else {
|
|
|
+ this.visible = true
|
|
|
+ }
|
|
|
+ })
|
|
|
}
|
|
|
},
|
|
|
watch: {},
|
|
|
distoryed() {},
|
|
|
+ updated() {
|
|
|
+ stopOtherVideo()
|
|
|
+ },
|
|
|
mounted: function() {
|
|
|
- this.$nextTick(() => {})
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.getList()
|
|
|
+ })
|
|
|
}
|
|
|
}
|
|
|
</script>
|