wjx 4 週間 前
コミット
8a8654b018

+ 25 - 20
src/Hook/useEcharts.tsx

@@ -188,7 +188,8 @@ const Pie: React.FC<PieProps> = ({
    📊 柱状图 Bar(支持横向)
 ===================================================== */
 interface BarProps {
-    data?: { name: string; value: number }[];
+    /** 多组数据格式 */
+    data?: Record<string, any>[];
     title?: string;
     color?: string[];
     horizontal?: boolean;
@@ -213,39 +214,43 @@ const Bar: React.FC<BarProps> = ({
             return;
         }
 
-        const names = data.map(d => d.name);
-        const values = data.map(d => d.value);
+        // ✅ 自动识别维度
+        const keys = Object.keys(data[0]);
+        const categoryKey = keys[0]; // 默认第一列为类目轴
+        const seriesKeys = keys.slice(1); // 其他列为系列名
+
+        const categories = data.map(d => d[categoryKey]);
+
+        const series = seriesKeys.map((key, idx) => ({
+            name: key,
+            type: 'bar',
+            data: data.map(d => d[key]),
+            barGap: 0,
+            emphasis: { focus: 'series' },
+            itemStyle: { borderRadius: 3 },
+        }));
 
         const option: echarts.EChartsOption = {
             color,
             title: { text: title, left: 'center' },
             tooltip: { trigger: 'axis' },
+            legend: { data: seriesKeys, bottom: 0 },
             grid: horizontal
-                ? { left: 80, right: 50, top: 60, bottom: 60 }
+                ? { left: 120, right: 50, top: 60, bottom: 60 }
                 : { left: 60, right: 40, top: 60, bottom: 100 },
             xAxis: horizontal
                 ? { type: 'value' }
                 : {
                     type: 'category',
-                    data: names,
-                    axisLabel: {
-                        interval: 0,
-                        rotate: 30, // 防止长文本遮挡
-                        overflow: 'truncate'
-                    }
+                    data: categories,
+                    axisLabel: { interval: 0, rotate: 30 }
                 },
             yAxis: horizontal
-                ? { type: 'category', data: names }
+                ? { type: 'category', data: categories }
                 : { type: 'value' },
-            series: [
-                {
-                    type: 'bar',
-                    data: values,
-                    barWidth: '50%',
-                    label: { show: true, position: horizontal ? 'right' : 'top' },
-                    itemStyle: { borderRadius: 4 }
-                }
-            ]
+            series: horizontal
+                ? series.map(s => ({ ...s, label: { show: true, position: 'right' } })) as any
+                : series.map(s => ({ ...s, label: { show: true, position: 'top' } })) as any
         };
 
         loading ? chartInstance.current.showLoading() : chartInstance.current.hideLoading();

+ 217 - 285
src/pages/weComTask/page/home/index.tsx

@@ -1,22 +1,23 @@
 import { useAjax } from '@/Hook/useAjax';
 import React, { useEffect, useState } from 'react';
 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';
 const { Title } = Typography;
 import style from './index.less'
+import { CorpExternalUserColumns, ExternalUserColumns } from './tableConfig';
 
 const Home: React.FC = () => {
 
     /*******************************************/
     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 [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 [pieData, setPieData] = useState<{ name: string, value: number }[]>([])
     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
                 setCorpRepeat(cr)
                 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 {
                 setCorpRepeat({})
@@ -68,12 +69,12 @@ const Home: React.FC = () => {
                 setCorpUserRepeat(cur)
                 setOverflowData({ avgCorpRepeatUserRate: cur?.avgCorpRepeatUserRate || 0, repeatUserRate: cur?.repeatUserRate || 0, userCount: cur?.userCount || 0 })
                 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 {
                 setCorpUserRepeat({})
@@ -86,51 +87,65 @@ const Home: React.FC = () => {
 
     return <div>
         <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 spinning={getExternalUserRepeatByCorpList.loading}>
             <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
                     placeholder="请输入企业名称"
                     onSearch={(e) => { setQueryParmas({ ...queryParmas, corpName: e, pageNum: 1 }); }}
@@ -141,92 +156,14 @@ const Home: React.FC = () => {
             <Row gutter={16}>
                 <Col span={12}>
                     <Card style={{ height: '100%' }}>
-                        <Pie data={pieData} title="主体重粉占比" />
+                        {/* <Pie data={pieData} title="主体重粉占比" /> */}
+                        <Pie data={[]} title="主体重粉占比" />
                     </Card>
                 </Col>
                 <Col span={12}>
                     <Card style={{ height: '100%' }}>
                         <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 }}
                             bordered
                             dataSource={getExternalUserRepeatByCorpList.data?.data?.records}
@@ -235,7 +172,7 @@ const Home: React.FC = () => {
                             pagination={{
                                 total: getExternalUserRepeatByCorpList.data?.data?.total,
                                 current: getExternalUserRepeatByCorpList?.data?.data?.current || 1,
-                                pageSize: getExternalUserRepeatByCorpList?.data?.data?.size || 20,
+                                pageSize: getExternalUserRepeatByCorpList?.data?.data?.size || 10,
                                 onChange: (page: number, pageSize: number) => {
                                     setQueryParmas({ ...queryParmas, pageNum: page, pageSize })
                                 }
@@ -247,7 +184,7 @@ const Home: React.FC = () => {
         </Spin>
 
         <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
                 tabBarExtraContent={activeKey === '1' && <Input.Search
                     placeholder="请输入企业名称"
@@ -258,139 +195,10 @@ const Home: React.FC = () => {
                 items={[
                     {
                         key: '1',
-                        label: '主体维度',
+                        label: '主体内用户分布',
                         children: <Card>
                             <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 }}
                                 bordered
                                 dataSource={getCorpExternalUserRepeatList.data?.data?.records}
@@ -409,29 +217,123 @@ const Home: React.FC = () => {
                     },
                     {
                         key: '2',
-                        label: '企业维度',
+                        label: '用户添加主体分布',
                         children: <Row gutter={16}>
                             <Col span={12}>
                                 <Card style={{ height: '100%' }}>
-                                    <Bar data={barCorpData} title="企业维度重粉次数分布" horizontal />
+                                    <Bar data={barCorpData} title="用户添加主体分布" horizontal />
                                 </Card>
                             </Col>
                             <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>
                         </Row>
                     },
                     {
                         key: '3',
-                        label: '客服号维度',
+                        label: '用户添加客服号分布',
                         children: <Row gutter={16}>
                             <Col span={12}>
                                 <Card style={{ height: '100%' }}>
-                                    <Bar data={barCorpUserData} title="客服号维度重粉次数分布" horizontal />
+                                    <Bar data={barCorpUserData} title="用户添加客服号分布" horizontal />
                                 </Card>
                             </Col>
                             <Col span={12}>
-                                <DetailsTemplate data={corpUserRepeat} title='客服号维度重粉详细数据' />
+                                <DetailsTemplate data={corpUserRepeat} title='用户添加客服号详细数据' />
                             </Col>
                         </Row>
                     },
@@ -456,7 +358,37 @@ const DetailsTemplate: React.FC<{ data: { [x: string]: any }, title: string }> =
                 </div>
             </div>
             <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}>
                     <Statistic value={data?.oneRepeatCount || 0} valueStyle={{ fontSize: 16 }} />
                     (<Statistic
@@ -468,7 +400,7 @@ const DetailsTemplate: React.FC<{ data: { [x: string]: any }, title: string }> =
                 </div>
             </div>
             <div className={style.item}>
-                <span>重复添加2名人数</span>
+                <span>添加2名客服人数</span>
                 <div className={style.num}>
                     <Statistic value={data?.twoRepeatCount || 0} valueStyle={{ fontSize: 16 }} />
                     (<Statistic
@@ -480,7 +412,7 @@ const DetailsTemplate: React.FC<{ data: { [x: string]: any }, title: string }> =
                 </div>
             </div>
             <div className={style.item}>
-                <span>重复添加3名人数</span>
+                <span>添加3名客服人数</span>
                 <div className={style.num}>
                     <Statistic value={data?.threeRepeatCount || 0} valueStyle={{ fontSize: 16 }} />
                     (<Statistic
@@ -492,7 +424,7 @@ const DetailsTemplate: React.FC<{ data: { [x: string]: any }, title: string }> =
                 </div>
             </div>
             <div className={style.item}>
-                <span>重复添加4名人数</span>
+                <span>添加4名客服人数</span>
                 <div className={style.num}>
                     <Statistic value={data?.fourRepeatCount || 0} valueStyle={{ fontSize: 16 }} />
                     (<Statistic
@@ -504,7 +436,7 @@ const DetailsTemplate: React.FC<{ data: { [x: string]: any }, title: string }> =
                 </div>
             </div>
             <div className={style.item}>
-                <span>重复添加5名人数</span>
+                <span>添加5名客服人数</span>
                 <div className={style.num}>
                     <Statistic value={data?.fiveRepeatCount || 0} valueStyle={{ fontSize: 16 }} />
                     (<Statistic
@@ -516,7 +448,7 @@ const DetailsTemplate: React.FC<{ data: { [x: string]: any }, title: string }> =
                 </div>
             </div>
             <div className={style.item}>
-                <span>重复添加5名以上人数</span>
+                <span>添加5名客服以上人数</span>
                 <div className={style.num}>
                     <Statistic value={data?.gtFiveRepeatCount || 0} valueStyle={{ fontSize: 16 }} />
                     (<Statistic

+ 226 - 0
src/pages/weComTask/page/home/tableConfig.tsx

@@ -0,0 +1,226 @@
+import { Statistic } from "antd";
+import { AnyObject } from "antd/es/_util/type"
+import { ColumnsType } from "antd/es/table"
+
+
+export const CorpExternalUserColumns = (): ColumnsType<AnyObject> => {
+
+    return [
+        {
+            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: 'wsbrsCount',
+            key: 'wsbrsCount',
+            align: 'center',
+            render: (text: any) => <Statistic value={text || 0} valueStyle={{ fontSize: 12 }} />
+        },
+        {
+            title: '重复总人数',
+            dataIndex: 'cfCount',
+            key: 'cfCount',
+            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}
+            />
+        },
+    ]
+}
+
+
+
+export const ExternalUserColumns = (): ColumnsType<AnyObject> => {
+
+    return [
+        {
+            title: '企业名称',
+            dataIndex: 'corpName',
+            key: 'corpName',
+            ellipsis: true,
+            width: 150,
+        },
+        {
+            title: '主体用户总数',
+            dataIndex: 'corpExternalUserCount',
+            key: 'corpExternalUserCount',
+            align: 'center',
+            render: (text: any) => <Statistic value={text || 0} valueStyle={{ fontSize: 12 }} />
+        },
+        {
+            title: '已识别用户数',
+            dataIndex: 'ysbCount',
+            key: 'ysbCount',
+            align: 'center',
+            render: (text: any) => <Statistic value={text || 0} valueStyle={{ fontSize: 12 }} />
+        },
+        {
+            title: '未识别用户数',
+            dataIndex: 'nsbCount',
+            key: 'nsbCount',
+            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}
+            />
+        },
+    ]
+}