初始化
This commit is contained in:
258
src/views/Home/Index.vue
Normal file
258
src/views/Home/Index.vue
Normal file
@@ -0,0 +1,258 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-card shadow="never">
|
||||
<el-skeleton :loading="loading" animated>
|
||||
<el-row :gutter="20" justify="space-between">
|
||||
<el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">
|
||||
<div class="flex items-center">
|
||||
<img :src="avatar" alt="" class="w-40px h-40px rounded-[50%] mr-20px" />
|
||||
<div class="text-20px text-700">
|
||||
{{ t('workplace.welcome') }} {{ username }} {{ t('workplace.happyDay') }}
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">
|
||||
<div class="flex h-40px items-center justify-end <sm:mt-10px">
|
||||
<div class="px-8px text-right">
|
||||
<div class="text-14px text-gray-400 mb-20px">今日待跟进</div>
|
||||
<CountTo
|
||||
class="text-20px number-font"
|
||||
:start-val="0"
|
||||
:end-val="10"
|
||||
:duration="2600"
|
||||
/>
|
||||
</div>
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
<div class="px-8px text-right">
|
||||
<div class="text-14px text-gray-400 mb-20px">今日已跟进</div>
|
||||
<CountTo
|
||||
class="text-20px number-font"
|
||||
:start-val="0"
|
||||
:end-val="25"
|
||||
:duration="2600"
|
||||
/>
|
||||
</div>
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
<div class="px-8px text-right">
|
||||
<div class="text-14px text-gray-400 mb-20px">今日已成交</div>
|
||||
<CountTo
|
||||
class="text-20px number-font"
|
||||
:start-val="0"
|
||||
:end-val="2"
|
||||
:duration="2600"
|
||||
/>
|
||||
</div>
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
<div class="px-8px text-right">
|
||||
<div class="text-14px text-gray-400 mb-20px">剩余过期数</div>
|
||||
<CountTo
|
||||
class="text-20px number-font"
|
||||
:start-val="0"
|
||||
:end-val="235"
|
||||
:duration="2600"
|
||||
/>
|
||||
</div>
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
<div class="px-8px text-right">
|
||||
<div class="text-14px text-red-600 mb-20px">未知意向数</div>
|
||||
<CountTo
|
||||
class="text-20px number-font"
|
||||
:start-val="0"
|
||||
:end-val="0"
|
||||
:duration="2600"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-skeleton>
|
||||
</el-card>
|
||||
<el-row class="mt-10px" :gutter="10" justify="space-between">
|
||||
<el-col :xl="6" :lg="6" :md="12" :sm="12" :xs="24" class="mb-10px">
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<div class="flex justify-between h-3">
|
||||
<span>本月成交来源</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-skeleton :loading="loading" animated>
|
||||
<Echart :options="pieOptionsData" :height="280" />
|
||||
</el-skeleton>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :xl="6" :lg="6" :md="12" :sm="12" :xs="24" class="mb-10px">
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<div class="flex justify-between h-3">
|
||||
<span>成交率</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-skeleton :loading="loading" animated>
|
||||
<el-skeleton :loading="loading" animated>
|
||||
<Echart :options="lineOptionsData" :height="280" />
|
||||
</el-skeleton>
|
||||
</el-skeleton>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :xl="6" :lg="6" :md="12" :sm="12" :xs="24" class="mb-10px">
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<div class="flex justify-between h-3">
|
||||
<span>跟进榜Top10</span>
|
||||
<el-radio-group v-model="followDate" size="small">
|
||||
<el-radio label="day">本日</el-radio>
|
||||
<el-radio label="month">本月</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</template>
|
||||
<el-skeleton :loading="loading" animated>
|
||||
<ul class="follow-wrap">
|
||||
<!-- <TransitionGroup name="flip"> -->
|
||||
<li
|
||||
class="follow-item number-font mb-18px text-14px"
|
||||
v-for="(item, index) in followList"
|
||||
:key="index"
|
||||
>
|
||||
<span class="mr-10px">NO.{{ index + 1 }}</span>
|
||||
<span class="mr-10px">{{ item.name }}</span>
|
||||
<span>已跟进{{ item.count }}条线索</span>
|
||||
</li>
|
||||
<br />
|
||||
<!-- </TransitionGroup> -->
|
||||
</ul>
|
||||
</el-skeleton>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :xl="6" :lg="6" :md="12" :sm="12" :xs="24" class="mb-10px">
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<div class="flex justify-between h-3">
|
||||
<span>本月成交榜Top10</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-skeleton :loading="loading" animated>
|
||||
<el-table :data="followList" size="small">
|
||||
<el-table-column prop="sort" label="排名" width="50" />
|
||||
<el-table-column prop="name" label="姓名" width="70" />
|
||||
<el-table-column prop="count" label="跟进数量" width="70" />
|
||||
<el-table-column prop="orgName" label="所属组织" />
|
||||
</el-table>
|
||||
</el-skeleton>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts" name="Home">
|
||||
import { set } from 'lodash-es'
|
||||
import { EChartsOption } from 'echarts'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
import avatarImg from '@/assets/imgs/avatar.gif'
|
||||
import { pieOptions, lineOptions } from './echarts-data'
|
||||
|
||||
const { t } = useI18n()
|
||||
const userStore = useUserStore()
|
||||
const loading = ref(false)
|
||||
const avatar = userStore.getUser.avatar ? userStore.getUser.avatar : avatarImg
|
||||
const username = userStore.getUser.nickname
|
||||
|
||||
const followDate = ref('day')
|
||||
|
||||
// 成交线索来源
|
||||
const pieOptionsData = reactive<EChartsOption>(pieOptions) as EChartsOption
|
||||
const getSaleClueSource = async () => {
|
||||
const data = [
|
||||
{ value: 335, name: '宝典' },
|
||||
{ value: 310, name: '一点通' },
|
||||
{ value: 234, name: '抖音' },
|
||||
{ value: 135, name: '小红书' },
|
||||
{ value: 1548, name: '转介绍' }
|
||||
]
|
||||
set(
|
||||
pieOptionsData,
|
||||
'legend.data',
|
||||
data.map((v) => t(v.name))
|
||||
)
|
||||
pieOptionsData!.series![0].data = data.map((v) => {
|
||||
return {
|
||||
name: t(v.name),
|
||||
value: v.value
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 成交率
|
||||
const lineOptionsData = reactive<EChartsOption>(lineOptions) as EChartsOption
|
||||
const getMonthlySaleRate = async () => {
|
||||
const data = [
|
||||
{ estimate: 100, actual: 120, name: 'analysis.january' },
|
||||
{ estimate: 120, actual: 82, name: 'analysis.february' },
|
||||
{ estimate: 161, actual: 91, name: 'analysis.march' },
|
||||
{ estimate: 134, actual: 154, name: 'analysis.april' },
|
||||
{ estimate: 105, actual: 162, name: 'analysis.may' },
|
||||
{ estimate: 160, actual: 140, name: 'analysis.june' },
|
||||
{ estimate: 165, actual: 145, name: 'analysis.july' },
|
||||
{ estimate: 114, actual: 250, name: 'analysis.august' },
|
||||
{ estimate: 163, actual: 134, name: 'analysis.september' },
|
||||
{ estimate: 185, actual: 56, name: 'analysis.october' },
|
||||
{ estimate: 118, actual: 99, name: 'analysis.november' },
|
||||
{ estimate: 123, actual: 123, name: 'analysis.december' }
|
||||
]
|
||||
set(
|
||||
lineOptionsData,
|
||||
'xAxis.data',
|
||||
data.map((v) => t(v.name))
|
||||
)
|
||||
set(lineOptionsData, 'series', [
|
||||
{
|
||||
name: t('analysis.estimate'),
|
||||
smooth: true,
|
||||
type: 'line',
|
||||
data: data.map((v) => v.estimate),
|
||||
animationDuration: 2800,
|
||||
animationEasing: 'cubicInOut'
|
||||
},
|
||||
{
|
||||
name: t('analysis.actual'),
|
||||
smooth: true,
|
||||
type: 'line',
|
||||
itemStyle: {},
|
||||
data: data.map((v) => v.actual),
|
||||
animationDuration: 2800,
|
||||
animationEasing: 'quadraticOut'
|
||||
}
|
||||
])
|
||||
}
|
||||
|
||||
const followList = ref([
|
||||
{ sort: 1, name: '张三', count: 12, orgName: '销售1组' },
|
||||
{ sort: 2, name: '张三', count: 11, orgName: '销售3组' },
|
||||
{ sort: 3, name: '张三', count: 11, orgName: '销售1组' },
|
||||
{ sort: 4, name: '张三', count: 10, orgName: '销售1组' },
|
||||
{ sort: 5, name: '张三', count: 2, orgName: '销售2组' },
|
||||
{ sort: 6, name: '张三', count: 1, orgName: '销售1组' },
|
||||
{ sort: 2, name: '张三', count: 11, orgName: '销售3组' },
|
||||
{ sort: 3, name: '张三', count: 11, orgName: '销售1组' },
|
||||
{ sort: 4, name: '张三', count: 10, orgName: '销售1组' },
|
||||
{ sort: 5, name: '张三', count: 2, orgName: '销售2组' },
|
||||
{ sort: 6, name: '张三', count: 1, orgName: '销售1组' }
|
||||
])
|
||||
|
||||
const getAllApi = async () => {
|
||||
await Promise.all([getSaleClueSource(), getMonthlySaleRate()])
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
getAllApi()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@font-face {
|
||||
font-family: numberFont;
|
||||
src: url('@/assets/fonts/DISPLAY FREE TFB.ttf');
|
||||
}
|
||||
|
||||
.number-font {
|
||||
font-family: numberFont !important;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user