|
@@ -1,22 +1,23 @@
|
|
|
import { useAjax } from '@/Hook/useAjax';
|
|
import { useAjax } from '@/Hook/useAjax';
|
|
|
import React, { useEffect, useState } from 'react';
|
|
import React, { useEffect, useState } from 'react';
|
|
|
import { getCorpExternalUserRepeatListApi, getExternalUserRepeatByCorpListApi, getExternalUserRepeatCorpApi, getExternalUserRepeatCorpUserApi } from '../../API/home';
|
|
import { getCorpExternalUserRepeatListApi, getExternalUserRepeatByCorpListApi, getExternalUserRepeatCorpApi, getExternalUserRepeatCorpUserApi } from '../../API/home';
|
|
|
-import { Avatar, Card, Col, Flex, Input, Row, Spin, Statistic, Table, Tabs, Typography } from 'antd';
|
|
|
|
|
-import { BarChartOutlined, GlobalOutlined, RetweetOutlined, UserOutlined } from '@ant-design/icons';
|
|
|
|
|
|
|
+import { Avatar, Card, Col, Flex, Input, Row, Space, Spin, Statistic, Table, Tabs, Tooltip, Typography } from 'antd';
|
|
|
|
|
+import { BarChartOutlined, CheckOutlined, DeleteOutlined, ExclamationOutlined, GlobalOutlined, QuestionCircleOutlined, RetweetOutlined, UserOutlined } from '@ant-design/icons';
|
|
|
import useEcharts from '@/Hook/useEcharts';
|
|
import useEcharts from '@/Hook/useEcharts';
|
|
|
const { Title } = Typography;
|
|
const { Title } = Typography;
|
|
|
import style from './index.less'
|
|
import style from './index.less'
|
|
|
|
|
+import { CorpExternalUserColumns, ExternalUserColumns } from './tableConfig';
|
|
|
|
|
|
|
|
const Home: React.FC = () => {
|
|
const Home: React.FC = () => {
|
|
|
|
|
|
|
|
/*******************************************/
|
|
/*******************************************/
|
|
|
const { Bar, Pie } = useEcharts()
|
|
const { Bar, Pie } = useEcharts()
|
|
|
- const [queryParmas, setQueryParmas] = useState<{ pageNum: number, pageSize: number, corpName?: string }>({ pageNum: 1, pageSize: 20 })
|
|
|
|
|
- const [queryParmasZt, setQueryParmasZt] = useState<{ pageNum: number, pageSize: number, corpName?: string }>({ pageNum: 1, pageSize: 20 })
|
|
|
|
|
|
|
+ const [queryParmas, setQueryParmas] = useState<{ pageNum: number, pageSize: number, corpName?: string }>({ pageNum: 1, pageSize: 30 })
|
|
|
|
|
+ const [queryParmasZt, setQueryParmasZt] = useState<{ pageNum: number, pageSize: number, corpName?: string }>({ pageNum: 1, pageSize: 30 })
|
|
|
const [corpRepeat, setCorpRepeat] = useState<{ [x: string]: any }>({})
|
|
const [corpRepeat, setCorpRepeat] = useState<{ [x: string]: any }>({})
|
|
|
const [corpUserRepeat, setCorpUserRepeat] = useState<{ [x: string]: any }>({})
|
|
const [corpUserRepeat, setCorpUserRepeat] = useState<{ [x: string]: any }>({})
|
|
|
- const [barCorpData, setBarCorpData] = useState<{ name: string, value: number }[]>([])
|
|
|
|
|
- const [barCorpUserData, setBarCorpUserData] = useState<{ name: string, value: number }[]>([])
|
|
|
|
|
|
|
+ const [barCorpData, setBarCorpData] = useState<Record<string, any>[]>([])
|
|
|
|
|
+ const [barCorpUserData, setBarCorpUserData] = useState<Record<string, any>[]>([])
|
|
|
const [activeKey, setActiveKey] = useState<string>('1')
|
|
const [activeKey, setActiveKey] = useState<string>('1')
|
|
|
const [pieData, setPieData] = useState<{ name: string, value: number }[]>([])
|
|
const [pieData, setPieData] = useState<{ name: string, value: number }[]>([])
|
|
|
const [overflowData, setOverflowData] = useState<{ avgCorpRepeatUserRate: number, repeatUserRate: number, userCount: number }>({ avgCorpRepeatUserRate: 0, repeatUserRate: 0, userCount: 0 })
|
|
const [overflowData, setOverflowData] = useState<{ avgCorpRepeatUserRate: number, repeatUserRate: number, userCount: number }>({ avgCorpRepeatUserRate: 0, repeatUserRate: 0, userCount: 0 })
|
|
@@ -49,12 +50,12 @@ const Home: React.FC = () => {
|
|
|
const cr = res.data
|
|
const cr = res.data
|
|
|
setCorpRepeat(cr)
|
|
setCorpRepeat(cr)
|
|
|
setBarCorpData([
|
|
setBarCorpData([
|
|
|
- { name: '非重复添加', value: cr?.oneRepeatCount },
|
|
|
|
|
- { name: '重复添加2名', value: cr?.twoRepeatCount },
|
|
|
|
|
- { name: '重复添加3名', value: cr?.threeRepeatCount },
|
|
|
|
|
- { name: '重复添加4名', value: cr?.fourRepeatCount },
|
|
|
|
|
- { name: '重复添加5名', value: cr?.fiveRepeatCount },
|
|
|
|
|
- { name: '重复添加5名以上', value: cr?.gtFiveRepeatCount }
|
|
|
|
|
|
|
+ { name: '仅添加1个主体', '人数': cr?.oneRepeatCount },
|
|
|
|
|
+ { name: '添加2个主体', '人数': cr?.twoRepeatCount },
|
|
|
|
|
+ { name: '添加3个主体', '人数': cr?.threeRepeatCount },
|
|
|
|
|
+ { name: '添加4个主体', '人数': cr?.fourRepeatCount },
|
|
|
|
|
+ { name: '添加5个主体', '人数': cr?.fiveRepeatCount },
|
|
|
|
|
+ { name: '添加5个主体以上', '人数': cr?.gtFiveRepeatCount }
|
|
|
])
|
|
])
|
|
|
} else {
|
|
} else {
|
|
|
setCorpRepeat({})
|
|
setCorpRepeat({})
|
|
@@ -68,12 +69,12 @@ const Home: React.FC = () => {
|
|
|
setCorpUserRepeat(cur)
|
|
setCorpUserRepeat(cur)
|
|
|
setOverflowData({ avgCorpRepeatUserRate: cur?.avgCorpRepeatUserRate || 0, repeatUserRate: cur?.repeatUserRate || 0, userCount: cur?.userCount || 0 })
|
|
setOverflowData({ avgCorpRepeatUserRate: cur?.avgCorpRepeatUserRate || 0, repeatUserRate: cur?.repeatUserRate || 0, userCount: cur?.userCount || 0 })
|
|
|
setBarCorpUserData([
|
|
setBarCorpUserData([
|
|
|
- { name: '非重复添加', value: cur?.oneRepeatCount },
|
|
|
|
|
- { name: '重复添加2名', value: cur?.twoRepeatCount },
|
|
|
|
|
- { name: '重复添加3名', value: cur?.threeRepeatCount },
|
|
|
|
|
- { name: '重复添加4名', value: cur?.fourRepeatCount },
|
|
|
|
|
- { name: '重复添加5名', value: cur?.fiveRepeatCount },
|
|
|
|
|
- { name: '重复添加5名以上', value: cur?.gtFiveRepeatCount }
|
|
|
|
|
|
|
+ { name: '仅添加1名客服', '人数': cur?.oneRepeatCount },
|
|
|
|
|
+ { name: '添加2名客服', '人数': cur?.twoRepeatCount },
|
|
|
|
|
+ { name: '添加3名客服', '人数': cur?.threeRepeatCount },
|
|
|
|
|
+ { name: '添加4名客服', '人数': cur?.fourRepeatCount },
|
|
|
|
|
+ { name: '添加5名客服', '人数': cur?.fiveRepeatCount },
|
|
|
|
|
+ { name: '添加5名客服以上', '人数': cur?.gtFiveRepeatCount }
|
|
|
])
|
|
])
|
|
|
} else {
|
|
} else {
|
|
|
setCorpUserRepeat({})
|
|
setCorpUserRepeat({})
|
|
@@ -86,51 +87,65 @@ const Home: React.FC = () => {
|
|
|
|
|
|
|
|
return <div>
|
|
return <div>
|
|
|
<Spin spinning={getExternalUserRepeatCorpUser.loading}>
|
|
<Spin spinning={getExternalUserRepeatCorpUser.loading}>
|
|
|
- <Row gutter={16}>
|
|
|
|
|
- <Col span={8}>
|
|
|
|
|
- <Card variant="borderless">
|
|
|
|
|
- <Flex justify='space-between'>
|
|
|
|
|
- <Statistic
|
|
|
|
|
- title={<strong style={{ fontSize: 14 }}>集团总粉丝数</strong>}
|
|
|
|
|
- value={overflowData.userCount}
|
|
|
|
|
- />
|
|
|
|
|
- <Avatar style={{ backgroundColor: '#DBEAFE', color: '#2563eb' }} size={40}><UserOutlined /></Avatar>
|
|
|
|
|
- </Flex>
|
|
|
|
|
- </Card>
|
|
|
|
|
- </Col>
|
|
|
|
|
- <Col span={8}>
|
|
|
|
|
- <Card variant="borderless">
|
|
|
|
|
- <Flex justify='space-between'>
|
|
|
|
|
- <Statistic
|
|
|
|
|
- title={<strong style={{ fontSize: 14 }}>平均主体重粉率</strong>}
|
|
|
|
|
- value={overflowData.avgCorpRepeatUserRate ? overflowData.avgCorpRepeatUserRate * 100 : 0}
|
|
|
|
|
- precision={4}
|
|
|
|
|
- suffix="%"
|
|
|
|
|
- />
|
|
|
|
|
- <Avatar style={{ backgroundColor: '#DCFCE7', color: '#16a34a' }} size={40}><RetweetOutlined /></Avatar>
|
|
|
|
|
- </Flex>
|
|
|
|
|
- </Card>
|
|
|
|
|
- </Col>
|
|
|
|
|
- <Col span={8}>
|
|
|
|
|
- <Card variant="borderless">
|
|
|
|
|
- <Flex justify='space-between'>
|
|
|
|
|
- <Statistic
|
|
|
|
|
- title={<strong style={{ fontSize: 14 }}>集团重粉率</strong>}
|
|
|
|
|
- value={overflowData.repeatUserRate ? overflowData.repeatUserRate * 100 : 0}
|
|
|
|
|
- precision={4}
|
|
|
|
|
- suffix="%"
|
|
|
|
|
- />
|
|
|
|
|
- <Avatar style={{ backgroundColor: '#F3E8FF', color: '#9333ea' }} size={40}><GlobalOutlined /></Avatar>
|
|
|
|
|
- </Flex>
|
|
|
|
|
-
|
|
|
|
|
- </Card>
|
|
|
|
|
- </Col>
|
|
|
|
|
- </Row>
|
|
|
|
|
|
|
+ <Flex gap={16}>
|
|
|
|
|
+ <Card variant="borderless" style={{ width: '20%' }}>
|
|
|
|
|
+ <Flex justify='space-between'>
|
|
|
|
|
+ <Statistic
|
|
|
|
|
+ title={<strong style={{ fontSize: 14 }}>集团总企微用户数</strong>}
|
|
|
|
|
+ value={overflowData.userCount}
|
|
|
|
|
+ />
|
|
|
|
|
+ <Avatar style={{ backgroundColor: '#DBEAFE', color: '#2563eb' }} size={40}><UserOutlined /></Avatar>
|
|
|
|
|
+ </Flex>
|
|
|
|
|
+ </Card>
|
|
|
|
|
+ <Card variant="borderless" style={{ width: '20%' }}>
|
|
|
|
|
+ <Flex justify='space-between'>
|
|
|
|
|
+ <Statistic
|
|
|
|
|
+ title={<strong style={{ fontSize: 14 }}>已识别用户数</strong>}
|
|
|
|
|
+ value={0}
|
|
|
|
|
+ />
|
|
|
|
|
+ <Avatar style={{ backgroundColor: '#DCFCE7', color: '#16a34a' }} size={40}><CheckOutlined /></Avatar>
|
|
|
|
|
+ </Flex>
|
|
|
|
|
+ </Card>
|
|
|
|
|
+ <Card variant="borderless" style={{ width: '20%' }}>
|
|
|
|
|
+ <Flex justify='space-between'>
|
|
|
|
|
+ <Statistic
|
|
|
|
|
+ title={<strong style={{ fontSize: 14 }}>未识别用户数</strong>}
|
|
|
|
|
+ value={0}
|
|
|
|
|
+ />
|
|
|
|
|
+ <Avatar style={{ backgroundColor: 'rgba(251, 192, 163, 1)', color: '#f50' }} size={40}><ExclamationOutlined /></Avatar>
|
|
|
|
|
+ </Flex>
|
|
|
|
|
+ </Card>
|
|
|
|
|
+ <Card variant="borderless" style={{ width: '20%' }}>
|
|
|
|
|
+ <Flex justify='space-between'>
|
|
|
|
|
+ <Statistic
|
|
|
|
|
+ title={<strong style={{ fontSize: 14 }}>双删用户数</strong>}
|
|
|
|
|
+ value={0}
|
|
|
|
|
+ />
|
|
|
|
|
+ <Avatar style={{ backgroundColor: '#ffcece', color: '#ff0606' }} size={40}><DeleteOutlined /></Avatar>
|
|
|
|
|
+ </Flex>
|
|
|
|
|
+ </Card>
|
|
|
|
|
+ <Card variant="borderless" style={{ width: '20%' }}>
|
|
|
|
|
+ <Flex justify='space-between'>
|
|
|
|
|
+ <Statistic
|
|
|
|
|
+ title={<Space>
|
|
|
|
|
+ <strong style={{ fontSize: 14 }}>集团重粉率</strong>
|
|
|
|
|
+ <Tooltip title="所有主体的重复粉丝去重数量/集团粉丝数">
|
|
|
|
|
+ <QuestionCircleOutlined />
|
|
|
|
|
+ </Tooltip>
|
|
|
|
|
+ </Space>}
|
|
|
|
|
+ value={overflowData.repeatUserRate ? overflowData.repeatUserRate * 100 : 0}
|
|
|
|
|
+ precision={4}
|
|
|
|
|
+ suffix="%"
|
|
|
|
|
+ />
|
|
|
|
|
+ <Avatar style={{ backgroundColor: '#F3E8FF', color: '#9333ea' }} size={40}><GlobalOutlined /></Avatar>
|
|
|
|
|
+ </Flex>
|
|
|
|
|
+ </Card>
|
|
|
|
|
+ </Flex>
|
|
|
</Spin>
|
|
</Spin>
|
|
|
|
|
|
|
|
<Spin spinning={getExternalUserRepeatByCorpList.loading}>
|
|
<Spin spinning={getExternalUserRepeatByCorpList.loading}>
|
|
|
<Flex justify='space-between' style={{ margin: '20px 0 10px' }}>
|
|
<Flex justify='space-between' style={{ margin: '20px 0 10px' }}>
|
|
|
- <Title level={3} style={{ margin: 0 }}><RetweetOutlined style={{ color: '#1890ff' }} /> 主体重粉次数统计</Title>
|
|
|
|
|
|
|
+ <Title level={3} style={{ margin: 0 }}><RetweetOutlined style={{ color: '#1890ff' }} /> 用户在集团内重粉分布</Title>
|
|
|
<Input.Search
|
|
<Input.Search
|
|
|
placeholder="请输入企业名称"
|
|
placeholder="请输入企业名称"
|
|
|
onSearch={(e) => { setQueryParmas({ ...queryParmas, corpName: e, pageNum: 1 }); }}
|
|
onSearch={(e) => { setQueryParmas({ ...queryParmas, corpName: e, pageNum: 1 }); }}
|
|
@@ -141,92 +156,14 @@ const Home: React.FC = () => {
|
|
|
<Row gutter={16}>
|
|
<Row gutter={16}>
|
|
|
<Col span={12}>
|
|
<Col span={12}>
|
|
|
<Card style={{ height: '100%' }}>
|
|
<Card style={{ height: '100%' }}>
|
|
|
- <Pie data={pieData} title="主体重粉占比" />
|
|
|
|
|
|
|
+ {/* <Pie data={pieData} title="主体重粉占比" /> */}
|
|
|
|
|
+ <Pie data={[]} title="主体重粉占比" />
|
|
|
</Card>
|
|
</Card>
|
|
|
</Col>
|
|
</Col>
|
|
|
<Col span={12}>
|
|
<Col span={12}>
|
|
|
<Card style={{ height: '100%' }}>
|
|
<Card style={{ height: '100%' }}>
|
|
|
<Table
|
|
<Table
|
|
|
- columns={[
|
|
|
|
|
- {
|
|
|
|
|
- title: '企业名称',
|
|
|
|
|
- dataIndex: 'corpName',
|
|
|
|
|
- key: 'corpName',
|
|
|
|
|
- ellipsis: true,
|
|
|
|
|
- width: 150,
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- title: '集团粉丝总数',
|
|
|
|
|
- dataIndex: 'totalExternalUserCount',
|
|
|
|
|
- key: 'totalExternalUserCount',
|
|
|
|
|
- align: 'center',
|
|
|
|
|
- render: (text: any) => <Statistic value={text || 0} valueStyle={{ fontSize: 12 }} />
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- title: '集团内重粉数',
|
|
|
|
|
- dataIndex: 'externalUserRepeatCount',
|
|
|
|
|
- key: 'externalUserRepeatCount',
|
|
|
|
|
- align: 'center',
|
|
|
|
|
- render: (text: any) => <Statistic value={text || 0} valueStyle={{ fontSize: 12 }} />
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- title: '集团内重粉率',
|
|
|
|
|
- dataIndex: 'externalUserRepeatRate',
|
|
|
|
|
- key: 'externalUserRepeatRate',
|
|
|
|
|
- align: 'center',
|
|
|
|
|
- render: (text: any) => <Statistic
|
|
|
|
|
- value={text ? text * 100 : 0}
|
|
|
|
|
- valueStyle={text > 0.2 ? { color: '#cf1322', fontSize: 12 } : { color: '#3f8600', fontSize: 12 }}
|
|
|
|
|
- suffix="%"
|
|
|
|
|
- precision={4}
|
|
|
|
|
- />
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- title: '主体粉丝总数',
|
|
|
|
|
- dataIndex: 'corpExternalUserCount',
|
|
|
|
|
- key: 'corpExternalUserCount',
|
|
|
|
|
- align: 'center',
|
|
|
|
|
- render: (text: any) => <Statistic value={text || 0} valueStyle={{ fontSize: 12 }} />
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- title: '主体粉丝在集团占比',
|
|
|
|
|
- dataIndex: 'corpExternalUserRate',
|
|
|
|
|
- key: 'corpExternalUserRate',
|
|
|
|
|
- align: 'center',
|
|
|
|
|
- render: (text: any) => <Statistic
|
|
|
|
|
- value={text ? text * 100 : 0}
|
|
|
|
|
- valueStyle={text > 0.2 ? { color: '#cf1322', fontSize: 12 } : { color: '#3f8600', fontSize: 12 }}
|
|
|
|
|
- suffix="%"
|
|
|
|
|
- precision={4}
|
|
|
|
|
- />
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- title: '主体客服号数量',
|
|
|
|
|
- dataIndex: 'corpUserCount',
|
|
|
|
|
- key: 'corpUserCount',
|
|
|
|
|
- align: 'center',
|
|
|
|
|
- render: (text: any) => <Statistic value={text || 0} valueStyle={{ fontSize: 12 }} />
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- title: '主体内重粉数',
|
|
|
|
|
- dataIndex: 'corpExternalUserRepeatCount',
|
|
|
|
|
- key: 'corpExternalUserRepeatCount',
|
|
|
|
|
- align: 'center',
|
|
|
|
|
- render: (text: any) => <Statistic value={text || 0} valueStyle={{ fontSize: 12 }} />
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- title: '主体内重粉率',
|
|
|
|
|
- dataIndex: 'corpExternalUserRepeatRate',
|
|
|
|
|
- key: 'corpExternalUserRepeatRate',
|
|
|
|
|
- align: 'center',
|
|
|
|
|
- render: (text: any) => <Statistic
|
|
|
|
|
- value={text ? text * 100 : 0}
|
|
|
|
|
- valueStyle={text > 0.2 ? { color: '#cf1322', fontSize: 12 } : { color: '#3f8600', fontSize: 12 }}
|
|
|
|
|
- suffix="%"
|
|
|
|
|
- precision={4}
|
|
|
|
|
- />
|
|
|
|
|
- },
|
|
|
|
|
- ]}
|
|
|
|
|
|
|
+ columns={ExternalUserColumns()}
|
|
|
scroll={{ y: 300, x: 900 }}
|
|
scroll={{ y: 300, x: 900 }}
|
|
|
bordered
|
|
bordered
|
|
|
dataSource={getExternalUserRepeatByCorpList.data?.data?.records}
|
|
dataSource={getExternalUserRepeatByCorpList.data?.data?.records}
|
|
@@ -235,7 +172,7 @@ const Home: React.FC = () => {
|
|
|
pagination={{
|
|
pagination={{
|
|
|
total: getExternalUserRepeatByCorpList.data?.data?.total,
|
|
total: getExternalUserRepeatByCorpList.data?.data?.total,
|
|
|
current: getExternalUserRepeatByCorpList?.data?.data?.current || 1,
|
|
current: getExternalUserRepeatByCorpList?.data?.data?.current || 1,
|
|
|
- pageSize: getExternalUserRepeatByCorpList?.data?.data?.size || 20,
|
|
|
|
|
|
|
+ pageSize: getExternalUserRepeatByCorpList?.data?.data?.size || 10,
|
|
|
onChange: (page: number, pageSize: number) => {
|
|
onChange: (page: number, pageSize: number) => {
|
|
|
setQueryParmas({ ...queryParmas, pageNum: page, pageSize })
|
|
setQueryParmas({ ...queryParmas, pageNum: page, pageSize })
|
|
|
}
|
|
}
|
|
@@ -247,7 +184,7 @@ const Home: React.FC = () => {
|
|
|
</Spin>
|
|
</Spin>
|
|
|
|
|
|
|
|
<Spin spinning={getExternalUserRepeatCorp.loading || getExternalUserRepeatCorpUser.loading || getCorpExternalUserRepeatList.loading}>
|
|
<Spin spinning={getExternalUserRepeatCorp.loading || getExternalUserRepeatCorpUser.loading || getCorpExternalUserRepeatList.loading}>
|
|
|
- <Title level={3}><BarChartOutlined style={{ color: '#22c55e' }} /> 用户重粉次数统计</Title>
|
|
|
|
|
|
|
+ <Title level={3}><BarChartOutlined style={{ color: '#22c55e' }} /> 用户在集团内重粉分布</Title>
|
|
|
<Tabs
|
|
<Tabs
|
|
|
tabBarExtraContent={activeKey === '1' && <Input.Search
|
|
tabBarExtraContent={activeKey === '1' && <Input.Search
|
|
|
placeholder="请输入企业名称"
|
|
placeholder="请输入企业名称"
|
|
@@ -258,139 +195,10 @@ const Home: React.FC = () => {
|
|
|
items={[
|
|
items={[
|
|
|
{
|
|
{
|
|
|
key: '1',
|
|
key: '1',
|
|
|
- label: '主体维度',
|
|
|
|
|
|
|
+ label: '主体内用户分布',
|
|
|
children: <Card>
|
|
children: <Card>
|
|
|
<Table
|
|
<Table
|
|
|
- columns={[
|
|
|
|
|
- {
|
|
|
|
|
- title: '企业名称',
|
|
|
|
|
- dataIndex: 'corpName',
|
|
|
|
|
- key: 'corpName',
|
|
|
|
|
- ellipsis: true,
|
|
|
|
|
- width: 150,
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- title: '粉丝总数',
|
|
|
|
|
- dataIndex: 'userCount',
|
|
|
|
|
- key: 'userCount',
|
|
|
|
|
- align: 'center',
|
|
|
|
|
- render: (text: any) => <Statistic value={text || 0} valueStyle={{ fontSize: 12 }} />
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- title: '非重复添加人数',
|
|
|
|
|
- dataIndex: 'oneRepeatCount',
|
|
|
|
|
- key: 'oneRepeatCount',
|
|
|
|
|
- align: 'center',
|
|
|
|
|
- render: (text: any) => <Statistic value={text || 0} valueStyle={{ fontSize: 12 }} />
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- title: '非重复添加人数比例',
|
|
|
|
|
- dataIndex: 'oneRepeatCountRate',
|
|
|
|
|
- key: 'oneRepeatCountRate',
|
|
|
|
|
- align: 'center',
|
|
|
|
|
- render: (text: any) => <Statistic
|
|
|
|
|
- value={text ? text * 100 : 0}
|
|
|
|
|
- valueStyle={text > 0.5 ? { color: '#cf1322', fontSize: 12 } : { color: '#3f8600', fontSize: 12 }}
|
|
|
|
|
- suffix="%"
|
|
|
|
|
- precision={4}
|
|
|
|
|
- />
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- title: '重复添加2名人数',
|
|
|
|
|
- dataIndex: 'twoRepeatCount',
|
|
|
|
|
- key: 'twoRepeatCount',
|
|
|
|
|
- align: 'center',
|
|
|
|
|
- render: (text: any) => <Statistic value={text || 0} valueStyle={{ fontSize: 12 }} />
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- title: '重复添加2名人数比例',
|
|
|
|
|
- dataIndex: 'twoRepeatCountRate',
|
|
|
|
|
- key: 'twoRepeatCountRate',
|
|
|
|
|
- align: 'center',
|
|
|
|
|
- render: (text: any) => <Statistic
|
|
|
|
|
- value={text ? text * 100 : 0}
|
|
|
|
|
- valueStyle={text > 0.1 ? { color: '#cf1322', fontSize: 12 } : { color: '#3f8600', fontSize: 12 }}
|
|
|
|
|
- suffix="%"
|
|
|
|
|
- precision={4}
|
|
|
|
|
- />
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- title: '重复添加3名人数',
|
|
|
|
|
- dataIndex: 'threeRepeatCount',
|
|
|
|
|
- key: 'threeRepeatCount',
|
|
|
|
|
- align: 'center',
|
|
|
|
|
- render: (text: any) => <Statistic value={text || 0} valueStyle={{ fontSize: 12 }} />
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- title: '重复添加3名人数比例',
|
|
|
|
|
- dataIndex: 'threeRepeatCountRate',
|
|
|
|
|
- key: 'threeRepeatCountRate',
|
|
|
|
|
- align: 'center',
|
|
|
|
|
- render: (text: any) => <Statistic
|
|
|
|
|
- value={text ? text * 100 : 0}
|
|
|
|
|
- valueStyle={text > 0.09 ? { color: '#cf1322', fontSize: 12 } : { color: '#3f8600', fontSize: 12 }}
|
|
|
|
|
- suffix="%"
|
|
|
|
|
- precision={4}
|
|
|
|
|
- />
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- title: '重复添加4名人数',
|
|
|
|
|
- dataIndex: 'fourRepeatCount',
|
|
|
|
|
- key: 'fourRepeatCount',
|
|
|
|
|
- align: 'center',
|
|
|
|
|
- render: (text: any) => <Statistic value={text || 0} valueStyle={{ fontSize: 12 }} />
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- title: '重复添加4名人数比例',
|
|
|
|
|
- dataIndex: 'fourRepeatCountRate',
|
|
|
|
|
- key: 'fourRepeatCountRate',
|
|
|
|
|
- align: 'center',
|
|
|
|
|
- render: (text: any) => <Statistic
|
|
|
|
|
- value={text ? text * 100 : 0}
|
|
|
|
|
- valueStyle={text > 0.08 ? { color: '#cf1322', fontSize: 12 } : { color: '#3f8600', fontSize: 12 }}
|
|
|
|
|
- suffix="%"
|
|
|
|
|
- precision={4}
|
|
|
|
|
- />
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- title: '重复添加5名人数',
|
|
|
|
|
- dataIndex: 'fiveRepeatCount',
|
|
|
|
|
- key: 'fiveRepeatCount',
|
|
|
|
|
- align: 'center',
|
|
|
|
|
- render: (text: any) => <Statistic value={text || 0} valueStyle={{ fontSize: 12 }} />
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- title: '重复添加5名人数比例',
|
|
|
|
|
- dataIndex: 'fiveRepeatCountRate',
|
|
|
|
|
- key: 'fiveRepeatCountRate',
|
|
|
|
|
- align: 'center',
|
|
|
|
|
- render: (text: any) => <Statistic
|
|
|
|
|
- value={text ? text * 100 : 0}
|
|
|
|
|
- valueStyle={text > 0.07 ? { color: '#cf1322', fontSize: 12 } : { color: '#3f8600', fontSize: 12 }}
|
|
|
|
|
- suffix="%"
|
|
|
|
|
- precision={4}
|
|
|
|
|
- />
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- title: '重复添加5名以上人数',
|
|
|
|
|
- dataIndex: 'gtFiveRepeatCount',
|
|
|
|
|
- key: 'gtFiveRepeatCount',
|
|
|
|
|
- align: 'center',
|
|
|
|
|
- render: (text: any) => <Statistic value={text || 0} valueStyle={{ fontSize: 12 }} />
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- title: '重复添加5名以上人数比例',
|
|
|
|
|
- dataIndex: 'gtFiveRepeatCountRate',
|
|
|
|
|
- key: 'gtFiveRepeatCountRate',
|
|
|
|
|
- align: 'center',
|
|
|
|
|
- render: (text: any) => <Statistic
|
|
|
|
|
- value={text ? text * 100 : 0}
|
|
|
|
|
- valueStyle={text > 0.06 ? { color: '#cf1322', fontSize: 12 } : { color: '#3f8600', fontSize: 12 }}
|
|
|
|
|
- suffix="%"
|
|
|
|
|
- precision={4}
|
|
|
|
|
- />
|
|
|
|
|
- },
|
|
|
|
|
- ]}
|
|
|
|
|
|
|
+ columns={CorpExternalUserColumns()}
|
|
|
scroll={{ y: 300, x: 900 }}
|
|
scroll={{ y: 300, x: 900 }}
|
|
|
bordered
|
|
bordered
|
|
|
dataSource={getCorpExternalUserRepeatList.data?.data?.records}
|
|
dataSource={getCorpExternalUserRepeatList.data?.data?.records}
|
|
@@ -409,29 +217,123 @@ const Home: React.FC = () => {
|
|
|
},
|
|
},
|
|
|
{
|
|
{
|
|
|
key: '2',
|
|
key: '2',
|
|
|
- label: '企业维度',
|
|
|
|
|
|
|
+ label: '用户添加主体分布',
|
|
|
children: <Row gutter={16}>
|
|
children: <Row gutter={16}>
|
|
|
<Col span={12}>
|
|
<Col span={12}>
|
|
|
<Card style={{ height: '100%' }}>
|
|
<Card style={{ height: '100%' }}>
|
|
|
- <Bar data={barCorpData} title="企业维度重粉次数分布" horizontal />
|
|
|
|
|
|
|
+ <Bar data={barCorpData} title="用户添加主体分布" horizontal />
|
|
|
</Card>
|
|
</Card>
|
|
|
</Col>
|
|
</Col>
|
|
|
<Col span={12}>
|
|
<Col span={12}>
|
|
|
- <DetailsTemplate data={corpRepeat} title='企业维度重粉详细数据' />
|
|
|
|
|
|
|
+ <Card style={{ height: '100%' }}>
|
|
|
|
|
+ <Title level={3} style={{ marginTop: 0, textAlign: 'center', fontSize: 18, color: '#313131' }}>用户添加主体分布重粉详细数据</Title>
|
|
|
|
|
+ <Flex vertical gap={7}>
|
|
|
|
|
+ <div className={style.item}>
|
|
|
|
|
+ <span>粉丝总数</span>
|
|
|
|
|
+ <div className={style.num}>
|
|
|
|
|
+ <Statistic value={corpRepeat?.userCount || 0} valueStyle={{ fontSize: 16 }} />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div className={style.item}>
|
|
|
|
|
+ <span>未失败人数</span>
|
|
|
|
|
+ <div className={style.num}>
|
|
|
|
|
+ <Statistic value={corpRepeat?.wsbrsCount || 0} valueStyle={{ fontSize: 16 }} />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div className={style.item}>
|
|
|
|
|
+ <span>{`用户添加>1主体人数`}</span>
|
|
|
|
|
+ <div className={style.num}>
|
|
|
|
|
+ <Statistic value={corpRepeat?.addDy1ZtCount || 0} valueStyle={{ fontSize: 16 }} />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div className={style.item}>
|
|
|
|
|
+ <span>仅添加1个主体人数</span>
|
|
|
|
|
+ <div className={style.num}>
|
|
|
|
|
+ <Statistic value={corpRepeat?.oneRepeatCount || 0} valueStyle={{ fontSize: 16 }} />
|
|
|
|
|
+ (<Statistic
|
|
|
|
|
+ value={corpRepeat?.oneRepeatCountRate ? corpRepeat?.oneRepeatCountRate * 100 : 0}
|
|
|
|
|
+ valueStyle={corpRepeat?.oneRepeatCountRate > 0.5 ? { color: '#cf1322', fontSize: 16 } : { color: '#3f8600', fontSize: 16 }}
|
|
|
|
|
+ suffix="%"
|
|
|
|
|
+ precision={4}
|
|
|
|
|
+ />)
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div className={style.item}>
|
|
|
|
|
+ <span>添加2个主体人数</span>
|
|
|
|
|
+ <div className={style.num}>
|
|
|
|
|
+ <Statistic value={corpRepeat?.twoRepeatCount || 0} valueStyle={{ fontSize: 16 }} />
|
|
|
|
|
+ (<Statistic
|
|
|
|
|
+ value={corpRepeat?.twoRepeatCountRate ? corpRepeat?.twoRepeatCountRate * 100 : 0}
|
|
|
|
|
+ valueStyle={corpRepeat?.twoRepeatCountRate > 0.1 ? { color: '#cf1322', fontSize: 16 } : { color: '#3f8600', fontSize: 16 }}
|
|
|
|
|
+ suffix="%"
|
|
|
|
|
+ precision={4}
|
|
|
|
|
+ />)
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div className={style.item}>
|
|
|
|
|
+ <span>添加3个主体人数</span>
|
|
|
|
|
+ <div className={style.num}>
|
|
|
|
|
+ <Statistic value={corpRepeat?.threeRepeatCount || 0} valueStyle={{ fontSize: 16 }} />
|
|
|
|
|
+ (<Statistic
|
|
|
|
|
+ value={corpRepeat?.threeRepeatCountRate ? corpRepeat?.threeRepeatCountRate * 100 : 0}
|
|
|
|
|
+ valueStyle={corpRepeat?.threeRepeatCountRate > 0.09 ? { color: '#cf1322', fontSize: 16 } : { color: '#3f8600', fontSize: 16 }}
|
|
|
|
|
+ suffix="%"
|
|
|
|
|
+ precision={4}
|
|
|
|
|
+ />)
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div className={style.item}>
|
|
|
|
|
+ <span>添加4个主体人数</span>
|
|
|
|
|
+ <div className={style.num}>
|
|
|
|
|
+ <Statistic value={corpRepeat?.fourRepeatCount || 0} valueStyle={{ fontSize: 16 }} />
|
|
|
|
|
+ (<Statistic
|
|
|
|
|
+ value={corpRepeat?.fourRepeatCountRate ? corpRepeat?.fourRepeatCountRate * 100 : 0}
|
|
|
|
|
+ valueStyle={corpRepeat?.fourRepeatCountRate > 0.08 ? { color: '#cf1322', fontSize: 16 } : { color: '#3f8600', fontSize: 16 }}
|
|
|
|
|
+ suffix="%"
|
|
|
|
|
+ precision={4}
|
|
|
|
|
+ />)
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div className={style.item}>
|
|
|
|
|
+ <span>添加5个主体人数</span>
|
|
|
|
|
+ <div className={style.num}>
|
|
|
|
|
+ <Statistic value={corpRepeat?.fiveRepeatCount || 0} valueStyle={{ fontSize: 16 }} />
|
|
|
|
|
+ (<Statistic
|
|
|
|
|
+ value={corpRepeat?.fiveRepeatCountRate ? corpRepeat?.fiveRepeatCountRate * 100 : 0}
|
|
|
|
|
+ valueStyle={corpRepeat?.fiveRepeatCountRate > 0.07 ? { color: '#cf1322', fontSize: 16 } : { color: '#3f8600', fontSize: 16 }}
|
|
|
|
|
+ suffix="%"
|
|
|
|
|
+ precision={4}
|
|
|
|
|
+ />)
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div className={style.item}>
|
|
|
|
|
+ <span>添加5个主体以上人数</span>
|
|
|
|
|
+ <div className={style.num}>
|
|
|
|
|
+ <Statistic value={corpRepeat?.gtFiveRepeatCount || 0} valueStyle={{ fontSize: 16 }} />
|
|
|
|
|
+ (<Statistic
|
|
|
|
|
+ value={corpRepeat?.gtFiveRepeatCountRate ? corpRepeat?.gtFiveRepeatCountRate * 100 : 0}
|
|
|
|
|
+ valueStyle={corpRepeat?.gtFiveRepeatCountRate > 0.06 ? { color: '#cf1322', fontSize: 16 } : { color: '#3f8600', fontSize: 16 }}
|
|
|
|
|
+ suffix="%"
|
|
|
|
|
+ precision={4}
|
|
|
|
|
+ />)
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </Flex>
|
|
|
|
|
+ </Card>
|
|
|
</Col>
|
|
</Col>
|
|
|
</Row>
|
|
</Row>
|
|
|
},
|
|
},
|
|
|
{
|
|
{
|
|
|
key: '3',
|
|
key: '3',
|
|
|
- label: '客服号维度',
|
|
|
|
|
|
|
+ label: '用户添加客服号分布',
|
|
|
children: <Row gutter={16}>
|
|
children: <Row gutter={16}>
|
|
|
<Col span={12}>
|
|
<Col span={12}>
|
|
|
<Card style={{ height: '100%' }}>
|
|
<Card style={{ height: '100%' }}>
|
|
|
- <Bar data={barCorpUserData} title="客服号维度重粉次数分布" horizontal />
|
|
|
|
|
|
|
+ <Bar data={barCorpUserData} title="用户添加客服号分布" horizontal />
|
|
|
</Card>
|
|
</Card>
|
|
|
</Col>
|
|
</Col>
|
|
|
<Col span={12}>
|
|
<Col span={12}>
|
|
|
- <DetailsTemplate data={corpUserRepeat} title='客服号维度重粉详细数据' />
|
|
|
|
|
|
|
+ <DetailsTemplate data={corpUserRepeat} title='用户添加客服号详细数据' />
|
|
|
</Col>
|
|
</Col>
|
|
|
</Row>
|
|
</Row>
|
|
|
},
|
|
},
|
|
@@ -456,7 +358,37 @@ const DetailsTemplate: React.FC<{ data: { [x: string]: any }, title: string }> =
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
<div className={style.item}>
|
|
<div className={style.item}>
|
|
|
- <span>非重复添加人数</span>
|
|
|
|
|
|
|
+ <span>未识别用户数</span>
|
|
|
|
|
+ <div className={style.num}>
|
|
|
|
|
+ <Statistic value={data?.wsbkfCount || 0} valueStyle={{ fontSize: 16 }} />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div className={style.item}>
|
|
|
|
|
+ <span>已激活集团客服号数</span>
|
|
|
|
|
+ <div className={style.num}>
|
|
|
|
|
+ <Statistic value={data?.yjhkf || 0} valueStyle={{ fontSize: 16 }} />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div className={style.item}>
|
|
|
|
|
+ <span>退出集团客服号数</span>
|
|
|
|
|
+ <div className={style.num}>
|
|
|
|
|
+ <Statistic value={data?.tckf || 0} valueStyle={{ fontSize: 16 }} />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div className={style.item}>
|
|
|
|
|
+ <span>未激活集团客服号数</span>
|
|
|
|
|
+ <div className={style.num}>
|
|
|
|
|
+ <Statistic value={data?.wjhkf || 0} valueStyle={{ fontSize: 16 }} />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div className={style.item}>
|
|
|
|
|
+ <span>{`用户添加>1客服号人数`}</span>
|
|
|
|
|
+ <div className={style.num}>
|
|
|
|
|
+ <Statistic value={data?.addDy1kf || 0} valueStyle={{ fontSize: 16 }} />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div className={style.item}>
|
|
|
|
|
+ <span>仅添加1名客服人数</span>
|
|
|
<div className={style.num}>
|
|
<div className={style.num}>
|
|
|
<Statistic value={data?.oneRepeatCount || 0} valueStyle={{ fontSize: 16 }} />
|
|
<Statistic value={data?.oneRepeatCount || 0} valueStyle={{ fontSize: 16 }} />
|
|
|
(<Statistic
|
|
(<Statistic
|
|
@@ -468,7 +400,7 @@ const DetailsTemplate: React.FC<{ data: { [x: string]: any }, title: string }> =
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
<div className={style.item}>
|
|
<div className={style.item}>
|
|
|
- <span>重复添加2名人数</span>
|
|
|
|
|
|
|
+ <span>添加2名客服人数</span>
|
|
|
<div className={style.num}>
|
|
<div className={style.num}>
|
|
|
<Statistic value={data?.twoRepeatCount || 0} valueStyle={{ fontSize: 16 }} />
|
|
<Statistic value={data?.twoRepeatCount || 0} valueStyle={{ fontSize: 16 }} />
|
|
|
(<Statistic
|
|
(<Statistic
|
|
@@ -480,7 +412,7 @@ const DetailsTemplate: React.FC<{ data: { [x: string]: any }, title: string }> =
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
<div className={style.item}>
|
|
<div className={style.item}>
|
|
|
- <span>重复添加3名人数</span>
|
|
|
|
|
|
|
+ <span>添加3名客服人数</span>
|
|
|
<div className={style.num}>
|
|
<div className={style.num}>
|
|
|
<Statistic value={data?.threeRepeatCount || 0} valueStyle={{ fontSize: 16 }} />
|
|
<Statistic value={data?.threeRepeatCount || 0} valueStyle={{ fontSize: 16 }} />
|
|
|
(<Statistic
|
|
(<Statistic
|
|
@@ -492,7 +424,7 @@ const DetailsTemplate: React.FC<{ data: { [x: string]: any }, title: string }> =
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
<div className={style.item}>
|
|
<div className={style.item}>
|
|
|
- <span>重复添加4名人数</span>
|
|
|
|
|
|
|
+ <span>添加4名客服人数</span>
|
|
|
<div className={style.num}>
|
|
<div className={style.num}>
|
|
|
<Statistic value={data?.fourRepeatCount || 0} valueStyle={{ fontSize: 16 }} />
|
|
<Statistic value={data?.fourRepeatCount || 0} valueStyle={{ fontSize: 16 }} />
|
|
|
(<Statistic
|
|
(<Statistic
|
|
@@ -504,7 +436,7 @@ const DetailsTemplate: React.FC<{ data: { [x: string]: any }, title: string }> =
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
<div className={style.item}>
|
|
<div className={style.item}>
|
|
|
- <span>重复添加5名人数</span>
|
|
|
|
|
|
|
+ <span>添加5名客服人数</span>
|
|
|
<div className={style.num}>
|
|
<div className={style.num}>
|
|
|
<Statistic value={data?.fiveRepeatCount || 0} valueStyle={{ fontSize: 16 }} />
|
|
<Statistic value={data?.fiveRepeatCount || 0} valueStyle={{ fontSize: 16 }} />
|
|
|
(<Statistic
|
|
(<Statistic
|
|
@@ -516,7 +448,7 @@ const DetailsTemplate: React.FC<{ data: { [x: string]: any }, title: string }> =
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
<div className={style.item}>
|
|
<div className={style.item}>
|
|
|
- <span>重复添加5名以上人数</span>
|
|
|
|
|
|
|
+ <span>添加5名客服以上人数</span>
|
|
|
<div className={style.num}>
|
|
<div className={style.num}>
|
|
|
<Statistic value={data?.gtFiveRepeatCount || 0} valueStyle={{ fontSize: 16 }} />
|
|
<Statistic value={data?.gtFiveRepeatCount || 0} valueStyle={{ fontSize: 16 }} />
|
|
|
(<Statistic
|
|
(<Statistic
|