wjx 9 ماه پیش
والد
کامیت
ee55bc0bae

+ 7 - 1
config/routerConfig.ts

@@ -50,7 +50,7 @@ function routeFun(items: any) {
             let arr = btnFun(route)
             return { path: route.path, name: route.meta.title, component: route.component, routes: arr, icon: route.meta.icon, key: route?.menuId }
         }
-        return { path: route.path, name: route.meta.title, component: route.component, icon: items.meta.icon, key: route?.menuId }
+        return { path: route.path, name: route.meta.title, component: route.component, icon: route.meta.icon, key: route?.menuId }
     })
 }
 /**获取线上菜单并重组路由格式和权限*/
@@ -432,6 +432,12 @@ const gsData = {
             access: 'bidREveryday',
             component: './gsData/bidREveryday',
         },
+        {
+            path: '/gsData/rolePayRetained',
+            name: 'GS角色付费留存',
+            access: 'rolePayRetained',
+            component: './gsData/rolePayRetained',
+        },
     ]
 }
 

+ 0 - 1
src/app.tsx

@@ -18,7 +18,6 @@ import { ReactComponent as MediaSvg } from '@/assets/media.svg'
 import { ReactComponent as PlayerSvg } from '@/assets/player.svg'
 import { ReactComponent as RoleManageSvg } from '@/assets/roleManage.svg'
 import versions from './utils/versions';
-import data from '@@@/mock/data';
 
 
 interface CurrentUser {

+ 1 - 0
src/pages/gameDataStatistics/extensionData/everyday/index.less

@@ -2,6 +2,7 @@
     display: flex;
     flex-flow: column;
     align-items: center;
+    font-size: 12px;
     // padding: 10px;
     >span{
         display: flex;

+ 3 - 3
src/pages/gameDataStatistics/pitcher/everyDayGame/tableConfig.tsx

@@ -43,7 +43,7 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
     let defaultStart = 18
     const zC = Array(90).fill('').map((_item: string, index: number) => {
         let field = `amountD${index + 1}Trend`
-        let data = {
+        let data: any = {
             title: `D${index + 1}`,
             dataIndex: `D${index + 1}`,
             label: "时间区间跨度",
@@ -90,7 +90,7 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
     let mDefaultStart = 108, count = 0
     const Mc = [4, 5, 6, 7, 8, 9, 10, 11, 12].map(index => {
         let field = `amountM${index}Trend`
-        let data = {
+        let data: any = {
             title: `M${index}`,
             dataIndex: `M${index}`,
             label: "时间区间跨度",
@@ -184,7 +184,7 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
                 },
                 {
                     title: '推广游戏应用类型', dataIndex: 'gameType', label: '基本信息', align: 'center', width: 95, default: 4,
-                    render: (a: string, b: any) => (<WidthEllipsis value={gameClassifyEnum[a]} />)
+                    render: (a: string, b: any) => (<WidthEllipsis value={gameClassifyEnum[a as keyof typeof gameClassifyEnum]} />)
                 },
                 {
                     title: '时间', dataIndex: 'dt', label: '基本信息', align: 'center', width: 110, default: 5, sorter: true,

+ 3 - 3
src/pages/gsData/bidREveryday/index.tsx

@@ -1,5 +1,5 @@
 import { useAjax } from "@/Hook/useAjax"
-import { getBigRApi, GetBigRProps } from "@/services/gsData/bidREveryday"
+import { getBigRApi, GetBigRProps } from "@/services/gsData"
 import React, { useEffect, useState } from "react"
 import columns12 from "./tableConfig"
 import TablePro from "@/pages/gameDataStatistics/components/TablePro"
@@ -80,8 +80,8 @@ const BidREveryday: React.FC = () => {
             config={columns12()}
             configName={'大R每日充值比'}
             fixed={{ left: 4, right: 0 }}
-            scroll={{ x: 1000, y: 500 }}
-            title='GS区服数据'
+            scroll={{ x: 1000, y: 620 }}
+            title='大R每日充值比'
             loading={getBigR.loading}
             ajax={getBigR}
             page={getBigR?.data?.current || 1}

+ 82 - 0
src/pages/gsData/rolePayRetained/index.tsx

@@ -0,0 +1,82 @@
+import { useAjax } from "@/Hook/useAjax"
+import { getRolePayRetainedApi, GetRolePayRetainedProps } from "@/services/gsData"
+import React, { useEffect, useState } from "react"
+import moment from "moment"
+import TablePro from "@/pages/gameDataStatistics/components/TablePro"
+import QueryFormGS from "@/components/QueryForm/indexGs"
+import columns12 from "./tableConfig"
+
+/**
+ * GS角色付费留存
+ * @returns 
+ */
+const RolePayRetained: React.FC = () => {
+
+    /***************************************/
+    const [queryForm, setQueryForm] = useState<GetRolePayRetainedProps>({
+        pageNum: 1,
+        pageSize: 30,
+        sourceSystem: 'ZX_ONE',
+        dtBegin: moment().format('YYYY-MM-DD'),
+        dtEnd: moment().format('YYYY-MM-DD')
+    })
+    const getRolePayRetained = useAjax((params) => getRolePayRetainedApi(params))
+    /***************************************/
+
+    useEffect(() => {
+        getRolePayRetained.run(queryForm)
+    }, [queryForm])
+
+    return <div>
+        <TablePro
+            leftChild={<QueryFormGS
+                initialValues={{ sourceSystem: 'ZX_ONE', roleSource: 2, rechargeDay: [moment(), moment()] }}
+                isSource
+                isGsId
+                rechargeDay={{ placeholder: ['指派日期开始', '指派日期结束'] }}
+                onChange={(data: any) => {
+                    console.log(data)
+                    const { rechargeDay, gsId, ...params } = data
+                    let newQueryForm = JSON.parse(JSON.stringify(queryForm))
+                    newQueryForm.pageNum = 1
+                    newQueryForm.gsIdList = gsId
+                    if (rechargeDay && rechargeDay?.length === 2) {
+                        newQueryForm['dtBegin'] = moment(rechargeDay[0]).format('YYYY-MM-DD')
+                        newQueryForm['dtEnd'] = moment(rechargeDay[1]).format('YYYY-MM-DD')
+                    } else {
+                        delete newQueryForm['dtBegin']
+                        delete newQueryForm['dtEnd']
+                    }
+                    setQueryForm({ ...newQueryForm, ...params })
+                }}
+            />}
+            config={columns12()}
+            configName={'GS角色付费留存'}
+            fixed={{ left: 4, right: 0 }}
+            scroll={{ x: 1000, y: 620 }}
+            title='GS角色付费留存'
+            loading={getRolePayRetained.loading}
+            ajax={getRolePayRetained}
+            page={getRolePayRetained?.data?.current || 1}
+            pageSize={getRolePayRetained?.data?.size || 20}
+            total={getRolePayRetained?.data?.total || 0}
+            dataSource={getRolePayRetained?.data?.records?.map((item: any, index: number) => ({ ...item, id: Number(queryForm.pageNum.toString() + (index + '')) }))}
+            onChange={(pagination: any, _: any, sortData: any) => {
+                let { current, pageSize } = pagination
+                let newQueryForm = JSON.parse(JSON.stringify(queryForm))
+                if (sortData && sortData?.order) {
+                    newQueryForm['sortAsc'] = sortData?.order === 'ascend' ? true : false
+                    newQueryForm['sortFiled'] = sortData?.field
+                } else {
+                    delete newQueryForm['sortAsc']
+                    delete newQueryForm['sortFiled']
+                }
+                newQueryForm.pageNum = current || newQueryForm.pageNum
+                newQueryForm.pageSize = pageSize || newQueryForm.pageSize
+                setQueryForm({ ...newQueryForm })
+            }}
+        />
+    </div>
+}
+
+export default RolePayRetained

+ 147 - 0
src/pages/gsData/rolePayRetained/tableConfig.tsx

@@ -0,0 +1,147 @@
+import WidthEllipsis from "@/components/widthEllipsis"
+import { Statistic } from "antd"
+import React from "react"
+import moment from "moment"
+import style from '../../gameDataStatistics/extensionData/everyday/index.less'
+
+
+function columns12(): { label: string, fieldSHow?: { label: string, saveField: string, defaultValue: any[], data: any[] }, data: any[] }[] {
+
+
+    let defaultStart = 11
+    const Dn = Array(90).fill('').map((_item: string, index: number) => {
+        let field = `da${index + 1}`
+        let data: any = {
+            title: `D${index + 1}`,
+            dataIndex: `D${index + 1}`,
+            label: "游戏区服数据",
+            width: 140,
+            render: (a: any, b: any) => {
+                let date1 = moment()
+                if (b?.gsName === '总计') {
+                    if (b?.beginDay) {
+                        date1 = moment(b.beginDay)
+                    } else {
+                        date1 = moment()
+                    }
+                } else {
+                    date1 = moment(b.dt)
+                }
+                let dt = moment()
+                let day = dt.diff(date1, 'day');
+                if (index <= day) {
+                    let [count1, count2, count3, count4, count5, count6, count7] = b?.[field]?.split('/')
+                    return <div className={style.dbox}>
+                        <span style={{ color: '#52c41a', fontWeight: 600 }}>活跃人数:<span>{count1}</span></span>
+                        <span style={{ color: '#a0d911', fontWeight: 600 }}>付费人数:<span>{count2}</span></span>
+                        <span style={{ color: '#1677ff', fontWeight: 600 }}>付费累计人数:<span>{count3}</span></span>
+                        <span style={{ color: '#0f538a', fontWeight: 600 }}>付费金额:<span><Statistic value={count4 || 0} valueStyle={{ color: '#0f538a', fontWeight: 600 }} /></span></span>
+                        <span style={{ color: 'rgb(12,130,16)', fontWeight: 600 }}>付费率:<span>{(count5 * 100)?.toFixed(2)}%</span></span>
+                        <span style={{ color: '#ff5722', fontWeight: 600 }}>活跃留存率:<span>{(count6 * 100)?.toFixed(2)}%</span></span>
+                        <span style={{ color: '#d81b60', fontWeight: 600 }}>付费留存率:<span>{(count7 * 100)?.toFixed(2)}%</span></span>
+                    </div>
+                }
+                return '--'
+            },
+        }
+        data['default'] = defaultStart + index
+        return data
+    })
+
+    let defaultStartM = 101
+    const Mn = Array(9).fill('').map((_item: string, index: number) => {
+        let field = `m${index + 4}`
+        let data: any = {
+            title: `M${index + 4}`,
+            dataIndex: `M${index + 4}`,
+            label: "游戏区服数据",
+            width: 140,
+            render: (a: any, b: any) => {
+                let date1 = moment()
+                if (b?.gsName === '总计') {
+                    if (b?.beginDay) {
+                        date1 = moment(b.beginDay)
+                    } else {
+                        date1 = moment()
+                    }
+                } else {
+                    date1 = moment(b.dt)
+                }
+                let dt = moment()
+                let day = dt.diff(date1, 'day');
+                if (index <= day) {
+                    let [count1, count2, count3, count4, count5, count6, count7] = b?.[field]?.split('/')
+                    return <div className={style.dbox}>
+                        <span style={{ color: '#52c41a', fontWeight: 600 }}>活跃人数:<span>{count1}</span></span>
+                        <span style={{ color: '#a0d911', fontWeight: 600 }}>付费人数:<span>{count2}</span></span>
+                        <span style={{ color: '#1677ff', fontWeight: 600 }}>付费累计人数:<span>{count3}</span></span>
+                        <span style={{ color: '#0f538a', fontWeight: 600 }}>付费金额:<span><Statistic value={count4 || 0} valueStyle={{ color: '#0f538a', fontWeight: 600 }} /></span></span>
+                        <span style={{ color: 'rgb(12,130,16)', fontWeight: 600 }}>付费率:<span>{(count5 * 100)?.toFixed(2)}%</span></span>
+                        <span style={{ color: '#ff5722', fontWeight: 600 }}>活跃留存率:<span>{(count6 * 100)?.toFixed(2)}%</span></span>
+                        <span style={{ color: '#d81b60', fontWeight: 600 }}>付费留存率:<span>{(count7 * 100)?.toFixed(2)}%</span></span>
+                    </div>
+                }
+                return '--'
+            },
+        }
+        data['default'] = defaultStartM + index
+        return data
+    })
+
+    return [
+        {
+            label: '基本信息',
+            data: [
+                {
+                    title: 'GS名称', dataIndex: 'gsName', label: '基本信息', align: 'center', width: 75, default: 1,
+                    render: (a: string) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '服务开始时间', dataIndex: 'dt', label: '基本信息', align: 'center', width: 90, default: 2,
+                    render: (a: string) => (<WidthEllipsis value={`${a}`} />)
+                },
+                {
+                    title: '至今服务天数', dataIndex: 'dtDiff', label: '基本信息', align: 'center', width: 45, default: 3,
+                    render: (a: string) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '指派角色数量', dataIndex: 'roleNum', label: '基本信息', align: 'center', width: 45, default: 4,
+                    render: (a: string) => (<WidthEllipsis value={a} />)
+                }
+            ]
+        },
+        {
+            label: '游戏区服数据',
+            data: [
+                {
+                    title: '付费角色数量', dataIndex: 'roleAmountNum', label: '游戏区服数据', align: 'center', width: 60, sorter: true, default: 5,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '付费次数', dataIndex: 'orderCount', label: '游戏区服数据', align: 'center', width: 60, sorter: true, default: 6,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '付费金额', dataIndex: 'totalAmount', label: '游戏区服数据', align: 'right', width: 65, sorter: true, default: 7,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: 'ARPPU(人均付费金额)', tips: 'ARPPU(人均付费金额)=付费金额/付费角色数量', dataIndex: 'gsArppu', label: '游戏区服数据', align: 'right', width: 95, sorter: true, default: 8,
+                    render: (a: string) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '客单价', tips: '客单价(平均每次付费金额)=付费金额/付费次数', dataIndex: 'gsAvg', label: '游戏区服数据', align: 'right', width: 75, sorter: true, default: 9,
+                    render: (a: string) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '付费率', tips: '付费率=付费角色数量/指派角色数量', dataIndex: 'gsRate', label: '游戏区服数据', align: 'center', width: 80, sorter: true, default: 10,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 50 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                ...Dn,
+                ...Mn
+            ]
+        }
+    ]
+}
+
+export default columns12

+ 21 - 1
src/services/gsData/bidREveryday.ts → src/services/gsData/index.ts

@@ -3,6 +3,7 @@ import { api } from '../api';
 import { Paging, SortProps } from '../gameData/rankingList';
 let wapi = api + '/gameGsData'
 
+
 export interface GetBigRProps extends Paging, SortProps {
     roleSource: 1 | 2, // 必填:角色来源:1:区服指派;2:角色指派
     sourceSystem: string, // 必填:SDK来源;默认ZX_ONE
@@ -22,7 +23,7 @@ export interface GetBigRProps extends Paging, SortProps {
     systemRemoveGameStatus?: 0 | 1 // 系统判断角色退游状态:0:未退游;1:退游
 }
 /**
- * 投手总数居
+ * 大R每日充值比
  * @param data 
  * @returns 
  */
@@ -31,4 +32,23 @@ export async function getBigRApi(data: GetBigRProps) {
         method: 'POST',
         data
     });
+}
+
+export interface GetRolePayRetainedProps extends Paging, SortProps {
+    dtBegin?: string,
+    dtEnd?: string,
+    gsIdList?: number[],
+
+}
+/**
+ * 
+GS角色付费留存
+ * @param data 
+ * @returns 
+ */
+export async function getRolePayRetainedApi(data: GetRolePayRetainedProps) {
+    return request(wapi + `/game/parent/role/pay/retained/listOfPage`, {
+        method: 'POST',
+        data
+    });
 }