wjx 4 veckor sedan
förälder
incheckning
7fedf55b4f

+ 11 - 0
src/pages/weComTask/API/home/index.ts

@@ -23,6 +23,17 @@ export function getExternalUserRepeatCorpUserApi() {
     })
 }
 
+/**
+ * 单主体内粉丝前20总用户数,主体内重粉数
+ * @returns 
+ */
+export function getExternalUserRepeatByCorpAtlasApi() {
+    return request({
+        url: api + `/corpOperation/ads/corp/externalUserRepeatByCorp/atlas`,
+        method: 'GET'
+    })
+}
+
 /**
  * 用户重粉次数统计 主体维度
  * @returns 

+ 76 - 52
src/pages/weComTask/page/home/index.tsx

@@ -1,6 +1,6 @@
 import { useAjax } from '@/Hook/useAjax';
 import React, { useEffect, useState } from 'react';
-import { getCorpExternalUserRepeatListApi, getExternalUserRepeatByCorpListApi, getExternalUserRepeatCorpApi, getExternalUserRepeatCorpUserApi } from '../../API/home';
+import { getCorpExternalUserRepeatListApi, getExternalUserRepeatByCorpAtlasApi, getExternalUserRepeatByCorpListApi, getExternalUserRepeatCorpApi, getExternalUserRepeatCorpUserApi } from '../../API/home';
 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';
@@ -11,7 +11,7 @@ import { CorpExternalUserColumns, ExternalUserColumns } from './tableConfig';
 const Home: React.FC = () => {
 
     /*******************************************/
-    const { Bar, Pie } = useEcharts()
+    const { Bar } = useEcharts()
     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 }>({})
@@ -19,25 +19,18 @@ const Home: React.FC = () => {
     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 [userData, setUserData] = useState<Record<string, any>[]>([])
     const [overflowData, setOverflowData] = useState<{ avgCorpRepeatUserRate: number, repeatUserRate: number, userCount: number }>({ avgCorpRepeatUserRate: 0, repeatUserRate: 0, userCount: 0 })
 
     const getExternalUserRepeatCorp = useAjax(() => getExternalUserRepeatCorpApi())
     const getExternalUserRepeatCorpUser = useAjax(() => getExternalUserRepeatCorpUserApi())
+    const getExternalUserRepeatByCorpAtlas = useAjax(() => getExternalUserRepeatByCorpAtlasApi())
     const getExternalUserRepeatByCorpList = useAjax((params) => getExternalUserRepeatByCorpListApi(params))
     const getCorpExternalUserRepeatList = useAjax((params) => getCorpExternalUserRepeatListApi(params))
     /*******************************************/
 
     useEffect(() => {
-        getExternalUserRepeatByCorpList.run(queryParmas).then(res => {
-            if (res?.data?.records?.length) {
-                setPieData(res?.data?.records?.map(item => {
-                    return { name: item.corpName, value: item.externalUserRepeatCount }
-                }))
-            } else {
-                setPieData([])
-            }
-        })
+        getExternalUserRepeatByCorpList.run(queryParmas)
     }, [queryParmas])
 
     useEffect(() => {
@@ -83,6 +76,15 @@ const Home: React.FC = () => {
             }
 
         })
+        getExternalUserRepeatByCorpAtlas.run().then(res => {
+            if (res?.data) {
+                setUserData(res?.data?.map(item => {
+                    return { name: item.corpName, '主体粉丝总数': item.corpExternalUserCount, '主体内重粉数': item.corpExternalUserRepeatCount }
+                }))
+            } else {
+                setUserData([])
+            }
+        })
     }, [])
 
     return <div>
@@ -143,45 +145,57 @@ const Home: React.FC = () => {
             </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>
-                <Input.Search
-                    placeholder="请输入企业名称"
-                    onSearch={(e) => { setQueryParmas({ ...queryParmas, corpName: e, pageNum: 1 }); }}
-                    style={{ width: 200 }}
-                    allowClear
-                />
-            </Flex>
-            <Row gutter={16}>
-                <Col span={12}>
-                    <Card style={{ height: '100%' }}>
-                        {/* <Pie data={pieData} title="主体重粉占比" /> */}
-                        <Pie data={[]} title="主体重粉占比" />
-                    </Card>
-                </Col>
-                <Col span={12}>
+
+        <Flex justify='space-between' style={{ margin: '20px 0 10px' }}>
+            <Title level={3} style={{ margin: 0 }}><RetweetOutlined style={{ color: '#1890ff' }} /> 单主体内重粉分布</Title>
+            <Input.Search
+                placeholder="请输入企业名称"
+                onSearch={(e) => { setQueryParmas({ ...queryParmas, corpName: e, pageNum: 1 }); }}
+                style={{ width: 200 }}
+                allowClear
+            />
+        </Flex>
+        <Row gutter={16}>
+            <Col span={12}>
+                <Spin spinning={getExternalUserRepeatByCorpAtlas.loading}>
                     <Card style={{ height: '100%' }}>
-                        <Table
-                            columns={ExternalUserColumns()}
-                            scroll={{ y: 300, x: 900 }}
-                            bordered
-                            dataSource={getExternalUserRepeatByCorpList.data?.data?.records}
-                            loading={getExternalUserRepeatByCorpList.loading}
-                            rowKey="corpId"
-                            pagination={{
-                                total: getExternalUserRepeatByCorpList.data?.data?.total,
-                                current: getExternalUserRepeatByCorpList?.data?.data?.current || 1,
-                                pageSize: getExternalUserRepeatByCorpList?.data?.data?.size || 10,
-                                onChange: (page: number, pageSize: number) => {
-                                    setQueryParmas({ ...queryParmas, pageNum: page, pageSize })
-                                }
-                            }}
-                        />
+                        <Bar data={userData} title="粉丝前20单主体总用户数, 主体内重粉数" />
                     </Card>
-                </Col>
-            </Row>
-        </Spin>
+                </Spin>
+            </Col>
+            <Col span={12}>
+                <Card style={{ height: '100%' }}>
+                    <Table
+                        columns={ExternalUserColumns()}
+                        scroll={{ y: 300, x: 900 }}
+                        bordered
+                        dataSource={getExternalUserRepeatByCorpList.data?.data?.records}
+                        loading={getExternalUserRepeatByCorpList.loading}
+                        rowKey="corpId"
+                        pagination={{
+                            total: getExternalUserRepeatByCorpList.data?.data?.total,
+                            current: getExternalUserRepeatByCorpList?.data?.data?.current || 1,
+                            pageSize: getExternalUserRepeatByCorpList?.data?.data?.size || 10
+                        }}
+                        onChange={(pagination: any, _: any, sortData: any) => {
+                            let { current, pageSize } = pagination
+                            let newQueryForm = JSON.parse(JSON.stringify(queryParmas))
+                            if (sortData && sortData?.order) {
+                                newQueryForm['sortType'] = sortData?.order === 'ascend' ? 'ASC' : 'DESC'
+                                newQueryForm['orderByField'] = sortData?.field
+                            } else {
+                                delete newQueryForm['sortType']
+                                delete newQueryForm['orderByField']
+                            }
+                            newQueryForm.pageNum = current || newQueryForm.pageNum
+                            newQueryForm.pageSize = pageSize || newQueryForm.pageSize
+                            setQueryParmas({ ...newQueryForm })
+                        }}
+                    />
+                </Card>
+            </Col>
+        </Row>
+
 
         <Spin spinning={getExternalUserRepeatCorp.loading || getExternalUserRepeatCorpUser.loading || getCorpExternalUserRepeatList.loading}>
             <Title level={3}><BarChartOutlined style={{ color: '#22c55e' }} /> 用户在集团内重粉分布</Title>
@@ -229,13 +243,18 @@ const Home: React.FC = () => {
                                     <Title level={3} style={{ marginTop: 0, textAlign: 'center', fontSize: 18, color: '#313131' }}>用户添加主体分布重粉详细数据</Title>
                                     <Flex vertical gap={7}>
                                         <div className={style.item}>
-                                            <span>粉丝总数</span>
+                                            <Space>
+                                                <span>粉丝总数</span>
+                                                <Tooltip title="未识别+添加1个+添加多个(>1)">
+                                                    <QuestionCircleOutlined />
+                                                </Tooltip>
+                                            </Space>
                                             <div className={style.num}>
                                                 <Statistic value={corpRepeat?.userCount || 0} valueStyle={{ fontSize: 16 }} />
                                             </div>
                                         </div>
                                         <div className={style.item}>
-                                            <span>未失败人数</span>
+                                            <span>未识别人数</span>
                                             <div className={style.num}>
                                                 <Statistic value={corpRepeat?.wsbrsCount || 0} valueStyle={{ fontSize: 16 }} />
                                             </div>
@@ -352,7 +371,12 @@ const DetailsTemplate: React.FC<{ data: { [x: string]: any }, title: string }> =
         <Title level={3} style={{ marginTop: 0, textAlign: 'center', fontSize: 18, color: '#313131' }}>{title || '详细数据'}</Title>
         <Flex vertical gap={7}>
             <div className={style.item}>
-                <span>粉丝总数</span>
+                <Space>
+                    <span>粉丝总数</span>
+                    <Tooltip title="未识别+添加2名+添加多名(>1)">
+                        <QuestionCircleOutlined />
+                    </Tooltip>
+                </Space>
                 <div className={style.num}>
                     <Statistic value={data?.userCount || 0} valueStyle={{ fontSize: 16 }} />
                 </div>

+ 50 - 7
src/pages/weComTask/page/home/tableConfig.tsx

@@ -1,6 +1,7 @@
-import { Statistic } from "antd";
+import { Space, Statistic, Tooltip } from "antd";
 import { AnyObject } from "antd/es/_util/type"
 import { ColumnsType } from "antd/es/table"
+import { QuestionCircleOutlined } from "@ant-design/icons"
 
 
 export const CorpExternalUserColumns = (): ColumnsType<AnyObject> => {
@@ -14,7 +15,12 @@ export const CorpExternalUserColumns = (): ColumnsType<AnyObject> => {
             width: 150,
         },
         {
-            title: '粉丝总数',
+            title: <Space>
+                <span>粉丝总数</span>
+                <Tooltip title="非重复人数+重复人数+未识别人数">
+                    <QuestionCircleOutlined />
+                </Tooltip>
+            </Space>,
             dataIndex: 'userCount',
             key: 'userCount',
             align: 'center',
@@ -28,7 +34,12 @@ export const CorpExternalUserColumns = (): ColumnsType<AnyObject> => {
             render: (text: any) => <Statistic value={text || 0} valueStyle={{ fontSize: 12 }} />
         },
         {
-            title: '重复总人数',
+            title: <Space>
+                <span>重复总人数</span>
+                <Tooltip title="重复(2,3,4,5,5+)">
+                    <QuestionCircleOutlined />
+                </Tooltip>
+            </Space>,
             dataIndex: 'cfCount',
             key: 'cfCount',
             align: 'center',
@@ -168,27 +179,57 @@ export const ExternalUserColumns = (): ColumnsType<AnyObject> => {
             dataIndex: 'corpExternalUserCount',
             key: 'corpExternalUserCount',
             align: 'center',
+            sorter: true,
             render: (text: any) => <Statistic value={text || 0} valueStyle={{ fontSize: 12 }} />
         },
         {
             title: '已识别用户数',
-            dataIndex: 'ysbCount',
-            key: 'ysbCount',
+            dataIndex: 'qcUuidCount',
+            key: 'qcUuidCount',
             align: 'center',
+            sorter: true,
             render: (text: any) => <Statistic value={text || 0} valueStyle={{ fontSize: 12 }} />
         },
+        {
+            title: '已识别用户数占比',
+            dataIndex: 'qcUuidCountRate',
+            key: 'qcUuidCountRate',
+            align: 'center',
+            sorter: true,
+            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: '未识别用户数',
-            dataIndex: 'nsbCount',
-            key: 'nsbCount',
+            dataIndex: 'qcUuidNullCount',
+            key: 'qcUuidNullCount',
             align: 'center',
+            sorter: true,
             render: (text: any) => <Statistic value={text || 0} valueStyle={{ fontSize: 12 }} />
         },
+        {
+            title: '未识别粉用户占比',
+            dataIndex: 'qcUuidNullCountRate',
+            key: 'qcUuidNullCountRate',
+            align: 'center',
+            sorter: true,
+            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: 'corpExternalUserRate',
             key: 'corpExternalUserRate',
             align: 'center',
+            sorter: true,
             render: (text: any) => <Statistic
                 value={text ? text * 100 : 0}
                 valueStyle={text > 0.2 ? { color: '#cf1322', fontSize: 12 } : { color: '#3f8600', fontSize: 12 }}
@@ -208,6 +249,7 @@ export const ExternalUserColumns = (): ColumnsType<AnyObject> => {
             dataIndex: 'corpExternalUserRepeatCount',
             key: 'corpExternalUserRepeatCount',
             align: 'center',
+            sorter: true,
             render: (text: any) => <Statistic value={text || 0} valueStyle={{ fontSize: 12 }} />
         },
         {
@@ -215,6 +257,7 @@ export const ExternalUserColumns = (): ColumnsType<AnyObject> => {
             dataIndex: 'corpExternalUserRepeatRate',
             key: 'corpExternalUserRepeatRate',
             align: 'center',
+            sorter: true,
             render: (text: any) => <Statistic
                 value={text ? text * 100 : 0}
                 valueStyle={text > 0.2 ? { color: '#cf1322', fontSize: 12 } : { color: '#3f8600', fontSize: 12 }}