dev-report
parent
a8ea0e4b26
commit
41c20623d4
@ -0,0 +1,4 @@ |
|||||||
|
import request from '@/config/axios' |
||||||
|
export const getList = async (data) => { |
||||||
|
return await request.post({ url: '/admin-api/crm/sch-clue/clueQuality/report', data }) |
||||||
|
} |
@ -1,5 +1,4 @@ |
|||||||
import request from '@/config/axios' |
import request from '@/config/axios' |
||||||
// 线索情况
|
|
||||||
export const getList = async (data) => { |
export const getList = async (data) => { |
||||||
return await request.post({ url: '/admin-api/crm/sch-clue/signRate/report', data }) |
return await request.post({ url: '/admin-api/crm/sch-clue/signRate/report', data }) |
||||||
} |
} |
||||||
|
@ -0,0 +1,140 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<ContentWrap> |
||||||
|
<el-form :model="searchForm" label-width="0" inline> |
||||||
|
<el-form-item> |
||||||
|
<el-date-picker |
||||||
|
v-model="searchForm.period" |
||||||
|
type="month" |
||||||
|
format="YYYY-MM" |
||||||
|
value-format="YYYY-MM" |
||||||
|
placeholder="选择年月" |
||||||
|
:clearable="false" |
||||||
|
/> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item> |
||||||
|
<el-tree-select |
||||||
|
v-model="searchForm.sourceId" |
||||||
|
:data="sourceOptions" |
||||||
|
:props="defaultProps" |
||||||
|
check-strictly |
||||||
|
node-key="sourceId" |
||||||
|
placeholder="请选择渠道" |
||||||
|
/> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item> |
||||||
|
<el-button @click="handleSearch">查询</el-button> |
||||||
|
<el-button @click="handleReset">重置</el-button> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
|
||||||
|
<el-table |
||||||
|
v-loading="loading" |
||||||
|
:data="tableList" |
||||||
|
border |
||||||
|
stripe |
||||||
|
:summary-method="getSummaries" |
||||||
|
show-summary |
||||||
|
> |
||||||
|
<el-table-column prop="sourceName" label="渠道名称" /> |
||||||
|
<el-table-column prop="newClueSignNum" label="新线索成交数" sortable /> |
||||||
|
<el-table-column prop="newClueNum" label="新线索总数" sortable /> |
||||||
|
<el-table-column prop="rate" label="新线索成交率" sortable :formatter="parseRate" /> |
||||||
|
<el-table-column prop="reallyClueSignNum" sortable> |
||||||
|
<template #header> <Tooltip message="新线索+老线索" /> <span>实际成交数</span> </template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
</ContentWrap> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script setup name="ChannelReport"> |
||||||
|
import * as reportApi from '@/api/home/reportChannel' |
||||||
|
import { getSimpleSourceList } from '@/api/clue/source' |
||||||
|
import { removeNullField } from '@/utils' |
||||||
|
import { formatDate } from '@/utils/formatTime' |
||||||
|
import { handleTree } from '@/utils/tree' |
||||||
|
|
||||||
|
const defaultProps = { |
||||||
|
children: 'children', |
||||||
|
label: 'sourceName', |
||||||
|
value: 'sourceId', |
||||||
|
isLeaf: 'leaf' |
||||||
|
} |
||||||
|
|
||||||
|
onMounted(() => { |
||||||
|
getOptions() |
||||||
|
handleReset() |
||||||
|
handleSearch() |
||||||
|
}) |
||||||
|
|
||||||
|
const searchForm = ref({}) |
||||||
|
|
||||||
|
function handleReset() { |
||||||
|
searchForm.value = { |
||||||
|
sourceName: undefined, |
||||||
|
period: formatDate(new Date(), 'YYYY-MM') |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const sourceOptions = ref([]) |
||||||
|
|
||||||
|
function getOptions() { |
||||||
|
getSimpleSourceList().then((data) => { |
||||||
|
sourceOptions.value = handleTree(data, 'sourceId') |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const loading = ref(false) |
||||||
|
const tableList = ref([]) |
||||||
|
async function handleSearch() { |
||||||
|
loading.value = true |
||||||
|
try { |
||||||
|
const data = await reportApi.getList(removeNullField(searchForm.value)) |
||||||
|
tableList.value = data |
||||||
|
} finally { |
||||||
|
loading.value = false |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function parseRate(row) { |
||||||
|
return Number(row.rate * 100).toFixed(2) + '%' |
||||||
|
} |
||||||
|
|
||||||
|
function getSummaries({ columns, data }) { |
||||||
|
let sums = [] |
||||||
|
columns.forEach((column, index) => { |
||||||
|
if (index == 0) { |
||||||
|
sums[index] = '合计' |
||||||
|
return |
||||||
|
} |
||||||
|
const values = data.map((item) => Number(item[column.property])) |
||||||
|
if (!values.every((value) => Number.isNaN(value))) { |
||||||
|
if (column.property == 'rate') { |
||||||
|
const sum = data.reduce( |
||||||
|
(pre, cur) => ({ |
||||||
|
clueNum: pre.clueNum + cur.newClueNum, |
||||||
|
signNum: pre.signNum + cur.newClueSignNum |
||||||
|
}), |
||||||
|
{ clueNum: 0, signNum: 0 } |
||||||
|
) |
||||||
|
sums[index] = sum.clueNum > 0 ? ((sum.signNum * 100) / sum.clueNum).toFixed(2) + '%' : 0 |
||||||
|
} else { |
||||||
|
sums[index] = values.reduce((prev, curr) => { |
||||||
|
const value = Number(curr) |
||||||
|
if (!Number.isNaN(value)) { |
||||||
|
return prev + curr |
||||||
|
} else { |
||||||
|
return prev |
||||||
|
} |
||||||
|
}, 0) |
||||||
|
} |
||||||
|
} else { |
||||||
|
sums[index] = '' |
||||||
|
} |
||||||
|
}) |
||||||
|
return sums |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped></style> |
@ -1,5 +1,5 @@ |
|||||||
<template> |
<template> |
||||||
<div> </div> |
<div>成交报表</div> |
||||||
</template> |
</template> |
||||||
|
|
||||||
<script setup></script> |
<script setup></script> |
Loading…
Reference in new issue