莳松crm管理系统
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ss-crm-manage-web/src/views/Home/ChannelReport.vue

141 lines
3.7 KiB

9 months ago
<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>