Commit 7878e30d by liuchenxi

-触达效果-

parent 3a8594d6
......@@ -17,7 +17,7 @@
<span v-for="item in listTabsIndex == 1 ? touchTabs : taskTabs" :key="item.value" :class="{ active2: listTabsIndex == 1 ? item.value == tabsIndex : item.value == taskTabIndex }" @click="changeTabs(item.value)">{{ item.name }}</span>
</div>
</div>
<el-table tooltipEffect="light" :data="tableList" style="width: 100%" element-loading-text="拼命加载中" @sort-change="sortChange" :style="{ marginTop: '20px', padding: '0 20px 0 22px' }">
<el-table ref="table" tooltipEffect="light" :data="tableList" style="width: 100%" element-loading-text="拼命加载中" @sort-change="sortChange" :style="{ marginTop: '20px', padding: '0 20px 0 22px' }">
<el-table-column v-for="(v, i) in tableHeader" :key="i" :prop="v.prop" :label="v.label" :formatter="v.formatter" :sortable="v.sortable">
<template slot-scope="scope">
<span v-if="v.formatter" v-html="v.formatter(scope.row)"></span>
......@@ -32,7 +32,6 @@
<script>
import { ecmGuideCluesTable, ecmHeadCluesTaskTab, ecmHeadGuideCluesTable, ecmHeadCluesTaskTabHead, ecmGuideCluesTaskTable, ecmGuideCluesTouchEffectTotalTab, ecmGuideCluesTouchEffectTabTotalHead, ecmGuideCluesTouchEffectTab, ecmGuideCluesTouchEffectTabHead } from '@/service/api/ecmApi.js';
// import { ecmGuideCluesTable, ecmHeadCluesTaskTab, ecmHeadGuideCluesTable, ecmHeadCluesTaskTabHead, ecmGuideCluesTaskTable, ecmGuideCluesTouchEffectTotalTab } from '@/service/api/ecmApi.js';ecmGuideCluesTouchEffectTab
import marketList from '@/views/ecm/touch-components/market-list.vue';
import touchCharts from '@/views/ecm/touch-components/touch-charts.vue';
export default {
......@@ -91,7 +90,8 @@ export default {
pageSize: 20,
total: 0,
tableFirstData: {},
ordery: ''
touchOrderBy: '',
taskOrderBy: ''
};
},
mounted() {
......@@ -118,15 +118,19 @@ export default {
changeTabs(index) {
if (this.listTabsIndex == 1) {
if (this.tabsIndex == index) return;
this.touchOrderBy = '';
this.tabsIndex = index;
} else {
if (this.taskTabIndex == index) return;
this.taskOrderBy = '';
this.taskTabIndex = index;
}
this.$refs.table.clearSort();
this.getTableFirstData();
},
changeListTab(index) {
this.listTabsIndex = index;
this.$refs.table.clearSort();
this.getTableList();
},
getMarketList() {
......@@ -140,8 +144,8 @@ export default {
data.taskRate = (data.cplTaskTotalCnt / data.taskCnt) * 100;
data.flag = true;
}
data.touchRate = data ? parseFloat(((data.touchMbrNum / data.planMbrNum) * 100).toFixed(2)) : 0;
data.transformRate = data ? parseFloat(((data.convMbrNum / data.touchMbrNum) * 100).toFixed(2)) : 0;
data.touchRate = parseFloat(((data.touchMbrNum / data.planMbrNum) * 100).toFixed(2));
data.transformRate = parseFloat(((data.convMbrNum / data.touchMbrNum) * 100).toFixed(2));
this.marketListData = [{ ...data }];
});
},
......@@ -156,7 +160,6 @@ export default {
fixed: 'left',
formatter(row) {
let color = '#F0F5FF';
if (!row) return;
if (row.index == 1) {
color = '#F5222D';
} else if (row.index == 2) {
......@@ -171,11 +174,11 @@ export default {
},
{ label: '门店名称', prop: 'storeName', minWidth: '160', align: 'left', fixed: 'left' },
{ label: '触达人数', prop: 'touchMbrNum', minWidth: '160', align: 'left', fixed: 'left', sortable: 'custom' },
{ label: '触达率', prop: 'reachRate', minWidth: '160', align: 'left', fixed: 'left', sortable: 'custom' },
{ label: '触达率', prop: 'reachRate', minWidth: '160', align: 'left', fixed: 'left', sortable: 'custom', formatter: row => row.reachRate && row.reachRate.toFixed(2) + '%' },
{ label: '转化人数', prop: 'convMbrNum', minWidth: '160', align: 'left', fixed: 'left', sortable: 'custom' },
{ label: '触达转化收益', prop: 'convSalesAmt', minWidth: '160', align: 'left', fixed: 'left', sortable: 'custom' },
{ label: '客单价', prop: 'customerPrice', minWidth: '160', align: 'left', fixed: 'left', sortable: 'custom' },
{ label: '折扣率', prop: 'discountRate', minWidth: '160', align: 'left', fixed: 'left', sortable: 'custom' }
{ label: '触达转化收益', prop: 'convSalesAmt', minWidth: '160', align: 'left', fixed: 'left', sortable: 'custom', formatter: row => row.convSalesAmt && row.convSalesAmt.toFixed(2) },
{ label: '客单价', prop: 'customerPrice', minWidth: '160', align: 'left', fixed: 'left', sortable: 'custom', formatter: row => row.customerPrice && row.customerPrice.toFixed(2) },
{ label: '折扣率', prop: 'discountRate', minWidth: '160', align: 'left', fixed: 'left', sortable: 'custom', formatter: row => row.discountRate && row.discountRate.toFixed(2) }
];
}
if (this.type == 1 && this.listTabsIndex == 0) {
......@@ -187,7 +190,6 @@ export default {
align: 'left',
fixed: 'left',
formatter(row) {
if (!row) return;
let color = '#F0F5FF';
if (row.index == 1) {
color = '#F5222D';
......@@ -204,7 +206,7 @@ export default {
{ label: '门店名称', prop: 'storeName', minWidth: '160', align: 'left', fixed: 'left' },
{ label: '任务总数', prop: 'taskCnt', minWidth: '160', align: 'left', fixed: 'left', sortable: 'custom' },
{ label: '任务完成数', prop: 'cplTaskCnt', minWidth: '160', align: 'left', fixed: 'left', sortable: 'custom' },
{ label: '任务完成率', prop: 'taskCompletionRate', minWidth: '160', align: 'left', fixed: 'left', sortable: 'custom' },
{ label: '任务完成率', prop: 'taskCompletionRate', minWidth: '160', align: 'left', fixed: 'left', sortable: 'custom', formatter: row => row.taskCompletionRate && row.taskCompletionRate.toFixed(2) + '%' },
{ label: '任务放弃数', prop: 'tasksAbandonedNum', minWidth: '160', align: 'left', fixed: 'left', sortable: 'custom' },
{ label: '逾期未完成', prop: 'overdueNotCompleted', minWidth: '160', align: 'left', fixed: 'left', sortable: 'custom' },
{ label: '未完成', prop: 'notCompleted', minWidth: '160', align: 'left', fixed: 'left', sortable: 'custom' }
......@@ -213,7 +215,7 @@ export default {
},
getTableList() {
let meth;
let params = { ecmPlanId: this.$route.query.id, pageNum: this.currentPage, pageSize: this.pageSize, orderBy: this.orderBy ? this.orderBy : '' };
let params = { ecmPlanId: this.$route.query.id, pageNum: this.currentPage, pageSize: this.pageSize, orderBy: this.listTabsIndex == 1 ? this.touchOrderBy : this.taskOrderBy };
if (this.type == 2) {
// 后台线索
meth = ecmHeadCluesTaskTab;
......@@ -236,18 +238,19 @@ export default {
}
}
meth(params).then(res => {
if (!res.result.result || !res.result.result.length) return;
if (this.currentPage == 1 && this.listTabsIndex != 0) {
// 任务完成情况无表头
let resetArr = [];
resetArr[0] = this.tableFirstData;
res.result.result && (this.tableList = resetArr.concat(res.result.result));
} else {
this.tableList = res.result.result || [];
this.tableList = res.result.result;
}
this.total = res.result.totalCount;
this.loading = false;
});
this.tableList.length && this.getTableHeader();
this.getTableHeader();
},
getTableFirstData() {
let meth;
......@@ -274,11 +277,16 @@ export default {
});
},
sortChange(column) {
console.log(column);
let prop = column.prop;
let orderby = column.order;
if (orderby == 'descending') orderby = 'desc';
else orderby = 'asc';
this.orderBy = prop + ' ' + orderby;
if (this.listTabsIndex == 1) {
this.touchOrderBy = prop + ' ' + orderby;
} else {
this.taskOrderBy = prop + ' ' + orderby;
}
this.getTableList();
}
},
......
......@@ -132,7 +132,7 @@
</li>
</ul>
</el-drawer>
<el-drawer title="数据说明" :visible.sync="drawer" :direction="direction" custom-class="touch_drawer h650" v-else-if="contentTitle == '智能营销'">
<el-drawer title="数据说明" :visible.sync="drawer" :direction="direction" custom-class="touch_drawer h380" v-else-if="contentTitle == '智能营销'">
<ul class="content">
<li>更新频率:营销人次实时统计,其余指标1天更新1次;</li>
<li>
......@@ -178,6 +178,9 @@ export default {
.h670 {
height: 670px !important;
}
.h380 {
height: 380px !important;
}
.touch_drawer {
width: 395px !important;
background: #ffffff;
......
......@@ -36,7 +36,8 @@ export default {
nodeName: String,
colorArr: Array,
data: {
type: Array
type: Array,
default: () => []
}
},
mounted() {
......
......@@ -5,7 +5,7 @@
<div class="right" v-if="isRepeat">批次合计:3 / 最新批次时间:2021-03-25:12:22:33</div>
</div>
<div class="middle" v-for="(item, index) in data" :key="index">
<template v-if="item.isSales == 0">
<template v-if="item.isSales == 1">
<div class="left" v-if="isReference && !isCluePage">
<img :src="require('@/assets/img/experimentIcon.png')" class="icon" />
<span class="title">实验组</span>
......@@ -23,33 +23,33 @@
<div class="right" :class="[isCluePage ? 'cluePage' : '']">
<div v-if="!isCluePage">
<p>计划人次</p>
<p>{{ item.planMbrTime && item.planMbrTimes.toLocaleString() }}</p>
<p>{{ item.planMbrTimes ? item.planMbrTimes.toLocaleString() : 0 }}</p>
</div>
<div>
<p>{{ isCluePage ? '计划触达人数' : '计划人数' }}</p>
<p>{{ item.planMbrNum && item.planMbrNum.toLocaleString() }}</p>
<p>{{ item.planMbrNum ? item.planMbrNum.toLocaleString() : 0 }}</p>
</div>
<div v-if="isCluePage && item.flag">
<p>
任务完成率<span>(任务总数 {{ item.taskCnt && item.taskCnt.toLocaleString() }})</span>
任务完成率<span>(任务总数 {{ item.taskCnt ? item.taskCnt.toLocaleString() : 0 }})</span>
</p>
<p>{{ item.taskRate ? item.taskRate.toFixed(2) + '%' : '-' }}</p>
<p>{{ item.taskRate ? item.taskRate.toFixed(2) + '%' : 0 }}</p>
</div>
<div>
<p>
触达人数<span>(触达率 {{ item.touchRate + '%' }})</span>
触达人数<span>(触达率 {{ item.touchRate ? item.touchRate + '%' : 0 + '%' }})</span>
</p>
<p>{{ item.touchMbrNum && item.touchMbrNum.toLocaleString() }}</p>
<p>{{ item.touchMbrNum ? item.touchMbrNum.toLocaleString() : 0 }}</p>
</div>
<div>
<p>
转化人数<span :class="{ active: item.isSales == 0 && data[0].transformRate < data[1].transformRate }">(转化率 {{ item.transformRate + '%' }})</span>
转化人数<span :class="{ active: item.isSales == 1 && data[0].transformRate < data[1].transformRate }">(转化率 {{ item.transformRate ? item.transformRate + '%' : 0 + '%' }})</span>
</p>
<p>{{ item.convMbrNum && item.convMbrNum.toLocaleString() }}</p>
<p>{{ item.convMbrNum ? item.convMbrNum.toLocaleString() : 0 }}</p>
</div>
<div>
<p>转化订单数</p>
<p>{{ item.convOrderCnt && item.convOrderCnt.toLocaleString() }}</p>
<p>{{ item.convOrderCnt ? item.convOrderCnt.toLocaleString() : 0 }}</p>
</div>
<div>
<p>转化收益</p>
......@@ -87,6 +87,7 @@ export default {
},
computed: {
convSalesAmt(num) {
console.log(this.data);
return num => {
if (num) {
num = parseFloat(num).toFixed(2);
......@@ -151,6 +152,7 @@ export default {
font-weight: 400;
color: #606266;
line-height: 20px;
white-space: nowrap;
}
.title {
font-weight: 600;
......
......@@ -99,7 +99,7 @@ export default {
if (this.type == 0) meth = ecmTouchEffectColumnDiagram;
else if (this.type == 1) meth = ecmGuideCluesColumnDiagram;
else meth = ecmHeadCluesColumnDiagram;
meth({ ecmPlanId: this.$route.query.id }).then(res => {
meth({ ecmPlanId: this.$route.query.id || this.$route.params.id }).then(res => {
this.chartData = res.result.map(item => {
if (item.name == '线索转化收益') {
item.rate = item.vaule * 1;
......
......@@ -31,7 +31,7 @@
<div class="detail" @click="toClue(1)">查看详情</div>
<div class="allPlan_title">导购线索</div>
<div class="allPlan_content">
<div class="left">
<div class="allPlan_content_left">
<img :src="require('@/assets/img/funnelIcon1.png')" class="icon" />
<div>
<p>线索转化收益</p>
......@@ -47,7 +47,7 @@
<div class="detail" @click="toClue(2)">查看详情</div>
<div class="allPlan_title">后台线索</div>
<div class="allPlan_content">
<div class="left">
<div class="allPlan_content_left">
<img :src="require('@/assets/img/funnelIcon2.png')" class="icon" />
<div>
<p>线索转化收益</p>
......@@ -113,7 +113,7 @@ export default {
ecmTouchEffectFunnelChart({ ecmPlanId: this.ecmPlanId }).then(res => {
this.funnelData = this.formatFunnelData(res.result);
this.clueRate = res.result.map(item => {
if (item.线索转化收益) {
if (item.线索转化收益 && parseFloat(item.线索转化收益)) {
item = parseFloat(item.线索转化收益).toFixed(2);
let i = item.indexOf('.');
let before = parseInt(item.slice(0, i)).toLocaleString();
......@@ -133,22 +133,22 @@ export default {
if (i != '收益' && i == '触达人数' && item[i] && item.计划触达人数) {
obj.unshift({
action: i,
value: item[i] * 1,
value: parseInt(item[i]) ? item[i] * 1 : 0,
rateAction: '触达率',
rate: ((item.触达人数 / item.计划触达人数) * 100).toFixed(2) + '%'
rate: (item.触达人数 / item.计划触达人数) * 100 ? ((item.触达人数 / item.计划触达人数) * 100).toFixed(2) + '%' : 0 + '%'
});
} else if (i != '收益' && i == '转化人数' && item[i] && item.计划触达人数) {
obj.unshift({
action: i,
value: item[i] * 1,
value: parseInt(item[i]) ? item[i] * 1 : 0,
rateAction: '转化率',
rate: ((item.转化人数 / item.触达人数) * 100).toFixed(2) + '%'
rate: (item.转化人数 / item.触达人数) * 100 ? ((item.转化人数 / item.触达人数) * 100).toFixed(2) + '%' : 0 + '%'
});
} else {
if (i != '线索转化收益') {
obj.unshift({
action: i,
value: item[i] ? item[i] * 1 : 0
value: parseInt(item[i]) ? item[i] * 1 : 0
});
}
}
......@@ -204,6 +204,7 @@ export default {
justify-content: space-between;
.left {
width: 37%;
min-width: 530px;
height: 425px;
background: #edf3ff;
margin-right: 5px;
......@@ -227,7 +228,7 @@ export default {
height: 82px;
p {
&:nth-of-type(1) {
width: 164px;
text-align: center;
height: 40px;
font-size: 34px;
font-family: DINAlternate-Bold, DINAlternate;
......@@ -270,6 +271,7 @@ export default {
position: relative;
background: url('~@/assets/img/fuunelBg1.png') no-repeat;
background-size: cover;
padding-right: 10px;
.detail {
position: absolute;
width: 83px;
......@@ -300,7 +302,8 @@ export default {
}
.allPlan_content {
display: flex;
.left {
width: 100%;
.allPlan_content_left {
display: flex;
width: 36%;
height: 56px;
......@@ -311,7 +314,6 @@ export default {
font-family: PingFangSC-Regular, PingFang SC;
margin-top: 48px;
padding-left: 27px;
background: transparent;
.icon {
width: 56px;
height: 56px;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment