wjx 3 months ago
parent
commit
78299a18e6

+ 6 - 0
config/routerConfig.ts

@@ -492,6 +492,12 @@ const gsData = {
             name: '游戏区服管理',
             access: 'serverManage',
             component: './gsData/serverManage',
+        },
+        {
+            path: '/gsData/xjRoleGrade',
+            name: '角色等级表(仙剑)',
+            access: 'xjRoleGrade',
+            component: './gsData/xjRoleGrade',
         }
     ]
 }

+ 14 - 3
src/components/QueryForm/index.tsx

@@ -48,6 +48,7 @@ interface Props {
     /** 是否开启 最近活跃时间 搜索 */
     isLastActiveTime?: {
         ranges?: any
+        placeholder?: [string, string]
     }
     /** 是否开启 操作设备 搜索 */
     isDevice?: boolean
@@ -276,6 +277,8 @@ interface Props {
     isLoginIpCity?: boolean
     /** 最新登录归属地 */
     isLoginIpProv?: boolean
+    /** 是否仙剑指定表 */
+    isXjRole?: boolean
 }
 /**
  * 游戏数据系统 请求参数
@@ -290,7 +293,7 @@ const QueryForm: React.FC<Props> = (props) => {
         isSysUserName, isRechargeDate, LastRechargeDay, isBGGameClassify, isGameUserId, isSysUserId, isSysUserIds, isUserName, isUserId, isSelectRanking, isGameType, isConsumeDay, rechargeDay, isBeginDay, isType, isAdTTStatus, isUserEnterType, isServerName, isServerId, isServerDay, isAdTXStatus,
         payTimeDay, placeAnOrderDay, isPayIntervalTime, isActiveTypes, isNickname, isMobile, isRegIp, isIsAuth, isIsBindMobile, isIsRecharge, isUserStatus, isCreateRole, isRoleCount, isVipLevel, isRoleLevel, isCreateRoleDay, isLastActiveTime, isIsChange, isIsSendMail, isWeChatCompany, isWeChat,
         isCustomerServerId, isOperatorId, isGsId, isServerIds, isRankingNum, isIsMergeServer, isIsParticipateMerge, isSuperParentGameId, isGameServerName, isIp, isDeviceType, isLoginType, isServerIdUn, isSourceServerName, isProjectId1, isDynamicCreativeId, isRemoveGame, isRemoveGameForSystem, isOrderLy, isAddCorpWechat,
-        isWakeUp, isUserPhoneStatus, isBackStatus, isGameDimension, isUserLastRegTime, isUserLastRegAgentId, isUserLastPitcherId, isRechargeAmountWithin24h, isRechargeTotalAmountWithin24h, isRegisterType, isConfiguredStatus, isIpCity, isIpProv, isLoginIpCity, isLoginIpProv
+        isWakeUp, isUserPhoneStatus, isBackStatus, isGameDimension, isUserLastRegTime, isUserLastRegAgentId, isUserLastPitcherId, isRechargeAmountWithin24h, isRechargeTotalAmountWithin24h, isRegisterType, isConfiguredStatus, isIpCity, isIpProv, isLoginIpCity, isLoginIpProv, isXjRole
     } = props
     const [form] = Form.useForm()
     const parentId = Form.useWatch('parentId', form)
@@ -544,6 +547,14 @@ const QueryForm: React.FC<Props> = (props) => {
         return current && current > moment().endOf('day');
     };
 
+    useEffect(() => {
+        if (isXjRole && superParentGameId) {
+            form.setFieldsValue({ serverIds: undefined })
+            getGameServerList.run({ gameId: superParentGameId })
+            getGameUnMergeServerList.run({ gameId: superParentGameId })
+        }
+    }, [isXjRole, superParentGameId])
+
     return <Form layout="inline" className='queryForm' initialValues={initialValues} name="basic" form={form} onFinish={onFinish}>
         <Row gutter={[0, 6]}>
             {/* 数据源搜索 */}
@@ -904,7 +915,7 @@ const QueryForm: React.FC<Props> = (props) => {
             </Form.Item></Col>}
 
             {/* 超父游戏ID */}
-            {isSuperParentGameId && <Col><Form.Item name='superParentGameId'>
+            {isSuperParentGameId && <Col><Form.Item name='superParentGameId' hidden={isXjRole}>
                 <Select
                     maxTagCount={1}
                     showSearch
@@ -999,7 +1010,7 @@ const QueryForm: React.FC<Props> = (props) => {
                 {isServerIds && <Col><Form.Item name='serverIds'>
                     <Select
                         maxTagCount={1}
-                        mode="multiple"
+                        mode={isXjRole ? undefined : 'multiple'}
                         showSearch
                         disabled={serverName}
                         style={{ minWidth: 140 }}

+ 1 - 1
src/pages/gameDataStatistics/player/role/lookRoleDetails.tsx

@@ -22,7 +22,7 @@ const LookRoleDetails: React.FC<{ userId: any }> = ({ userId }) => {
     return <>
         <a onClick={() => setVisible(true)}>角色</a>
         {visible && <Modal
-            title={<strong>游戏角色</strong>}
+            title={<strong>游戏角色(玩家ID:{userId})</strong>}
             visible={visible}
             onCancel={() => setVisible(false)}
             footer={null}

+ 145 - 0
src/pages/gsData/xjRoleGrade/index.tsx

@@ -0,0 +1,145 @@
+import { useAjax } from "@/Hook/useAjax"
+import TablePro from "@/pages/gameDataStatistics/components/TablePro"
+import { getRoleLevelListApi, GetRoleLevelListProps } from "@/services/gsData"
+import React, { useEffect, useState } from "react"
+import moment from "moment"
+import columns12 from "./tableConfig"
+import QueryForm from "@/components/QueryForm"
+import { Button, Space } from "antd"
+import Assign from "@/pages/gameDataStatistics/roleOperate/roleRechargeRanking/assign"
+
+/**
+ * 角色等级表-仙剑
+ * @returns 
+ */
+const XjRoleGrade: React.FC = () => {
+
+    /****************************************/
+    const [data, setData] = useState<any[]>([])
+    const [assignvisible, setAssignVisible] = useState<boolean>(false)
+    const [selectedRowKeys, setSelectedRowKeys] = useState<any[]>([])
+    const [queryForm, setQueryForm] = useState<GetRoleLevelListProps>({
+        pageNum: 1,
+        pageSize: 30
+    })
+    const getRoleLevelList = useAjax((params) => getRoleLevelListApi(params))
+    /****************************************/
+
+    useEffect(() => {
+        getRoleLevelList.run(queryForm)
+    }, [queryForm])
+
+    // 指派
+    const assignHandle = (data: any[]) => {
+        setData(data.map(item => ({ ...item, customer_service_id: item?.customerServiceId, oper_user_id: item?.operUserId, role_reg_game_id: item?.gameId, role_id: item?.roleId, server_id: item?.serverId, association_user_id: item?.userId, agent_id: item?.agentId })))
+        setAssignVisible(true)
+    }
+
+    return <div>
+        <TablePro
+            czChild={<Space>
+                <Button type="primary" size="small" disabled={selectedRowKeys.length === 0} onClick={() => assignHandle(selectedRowKeys)}>批量指派</Button>
+            </Space>}
+            leftChild={<QueryForm
+                initialValues={{ superParentGameId: 12 }}
+                isXjRole
+                isGameRoleName
+                isGameRoleId
+                isSuperParentGameId
+                isGameServerName
+                isServerIds
+                isCreateRoleDay={{}}
+                isLastActiveTime={{ placeholder: ['等级上报时间开始', '等级上报时间结束'] }}
+                isPayIntervalTime={{ tips: '角色等级区间' }}
+                isSysUserId
+                isCustomerServerId
+                isOperatorId
+                isGsId
+                onChange={(data: any) => {
+                    console.log(data)
+                    const { superParentGameId, createRoleDay, serverIds, regPayIntervalTime, lastActiveTime, ...params } = data
+                    let newQueryForm = JSON.parse(JSON.stringify(queryForm))
+                    newQueryForm.pageNum = 1
+                    newQueryForm.serverId = serverIds
+                    if (createRoleDay && createRoleDay?.length === 2) {
+                        newQueryForm['createTimeMin'] = moment(createRoleDay[0]).format('YYYY-MM-DD')
+                        newQueryForm['createTimeMax'] = moment(createRoleDay[1]).format('YYYY-MM-DD')
+                    } else {
+                        delete newQueryForm['createTimeMin']
+                        delete newQueryForm['createTimeMax']
+                    }
+                    if (lastActiveTime && lastActiveTime?.length === 2) {
+                        newQueryForm['levelTimeMin'] = moment(lastActiveTime[0]).format('YYYY-MM-DD')
+                        newQueryForm['levelTimeMax'] = moment(lastActiveTime[1]).format('YYYY-MM-DD')
+                    } else {
+                        delete newQueryForm['levelTimeMin']
+                        delete newQueryForm['levelTimeMax']
+                    }
+                    if (regPayIntervalTime?.length > 0 && (regPayIntervalTime[0] || regPayIntervalTime[1])) {
+                        newQueryForm.roleLevelMin = regPayIntervalTime[0]
+                        newQueryForm.roleLevelMax = regPayIntervalTime[1]
+                    }
+                    setQueryForm({ ...newQueryForm, ...params })
+                }}
+            />}
+            config={columns12(assignHandle)}
+            configName={'角色等级表-仙剑'}
+            fixed={{ left: 2, right: 1 }}
+            scroll={{ x: 1000, y: 620 }}
+            title='角色等级表-仙剑'
+            loading={getRoleLevelList.loading}
+            ajax={getRoleLevelList}
+            page={getRoleLevelList?.data?.current || 1}
+            pageSize={getRoleLevelList?.data?.size || 20}
+            total={getRoleLevelList?.data?.total || 0}
+            dataSource={getRoleLevelList?.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 })
+            }}
+            rowSelection={{
+                getCheckboxProps: (record: any) => ({
+                    disabled: selectedRowKeys?.length > 0 && record.role_reg_game_id !== (selectedRowKeys[0] as any).role_reg_game_id
+                }),
+                selectedRowKeys: selectedRowKeys.map((item: any) => item?.id.toString()),
+                // onChange: (selectedRowKeys: React.Key[], selectedRows: any[]) => {
+                //     setSelectedRowKeys(selectedRows)
+                // },
+                onSelect: (record: any, selected: boolean, selectedRows: any) => {
+                    let newSelectedRowKeys: any[] = JSON.parse(JSON.stringify(selectedRowKeys))
+                    if (selected) {
+                        newSelectedRowKeys.push(record)
+                    } else {
+                        newSelectedRowKeys = newSelectedRowKeys.filter(item => item.id != record.id)
+                    }
+                    setSelectedRowKeys(newSelectedRowKeys)
+                },
+                onSelectAll: (selected: boolean, selectedRows: any, changeRows: any) => {
+                    let newSelectedRowKeys: any[] = JSON.parse(JSON.stringify(selectedRowKeys))
+                    let gameId = newSelectedRowKeys?.[0]?.role_reg_game_id || changeRows?.[0]?.role_reg_game_id
+                    if (selected) {
+                        newSelectedRowKeys = newSelectedRowKeys.concat(changeRows.filter((item: { role_reg_game_id: any }) => item.role_reg_game_id === gameId))
+                    } else {
+                        let changeRowsIds: any[] = changeRows.map((item: { id: any }) => item.id);
+                        newSelectedRowKeys = newSelectedRowKeys.filter(item => !changeRowsIds.includes(item.id))
+                    }
+                    setSelectedRowKeys(newSelectedRowKeys)
+                }
+            }}
+        />
+        {/* 指派 */}
+        {assignvisible && <Assign visible={assignvisible} data={data} onClose={() => setAssignVisible(false)} onChange={() => { setAssignVisible(false); getRoleLevelList?.refresh(); setSelectedRowKeys([]) }} />}
+    </div>
+}
+
+export default XjRoleGrade

+ 126 - 0
src/pages/gsData/xjRoleGrade/tableConfig.tsx

@@ -0,0 +1,126 @@
+import WidthEllipsis from "@/components/widthEllipsis"
+import LookRoleDetails from "@/pages/gameDataStatistics/player/role/lookRoleDetails"
+import { Space, Statistic } from "antd"
+import React from "react"
+
+function columns12(assignHandle: (data: any) => void): { label: string, fieldSHow?: { label: string, saveField: string, defaultValue: any[], data: any[] }, data: any[] }[] {
+
+    return [
+        {
+            label: '基本信息',
+            data: [
+                {
+                    title: '角色名称', dataIndex: 'roleName', label: '基本信息', align: 'center', width: 85, default: 1,
+                    render: (a: string) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '角色ID', dataIndex: 'roleId', label: '基本信息', align: 'center', width: 85,
+                    render: (a: string) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '玩家名称', dataIndex: 'userName', label: '基本信息', align: 'center', width: 90, default: 2,
+                    render: (a: string) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '玩家ID', dataIndex: 'userId', label: '基本信息', align: 'center', width: 85,
+                    render: (a: string) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '游戏名称', dataIndex: 'gameName', label: '基本信息', align: 'center', width: 85, default: 3,
+                    render: (a: string) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '游戏ID', dataIndex: 'gameId', label: '基本信息', align: 'center', width: 85,
+                    render: (a: string) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '区服名称', dataIndex: 'serverName', label: '基本信息', align: 'center', width: 80, default: 4,
+                    render: (a: string) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '区服ID', dataIndex: 'serverId', label: '基本信息', align: 'center', width: 80,
+                    render: (a: string) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '角色创建时间', dataIndex: 'createTime', label: '基本信息', align: 'center', width: 125, default: 5,
+                    render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '角色等级', dataIndex: 'roleLevel', label: '基本信息', align: 'center', width: 60, sorter: true, default: 6,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '等级上报时间', dataIndex: 'levelTime', label: '基本信息', align: 'center', width: 120, default: 7,
+                    render: (a: string) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '等级上报时间距今', dataIndex: 'levelTimeDiff', label: '角色游戏数据', align: 'center', width: 100, default: 8,
+                    render: (_: any, b: any) => {
+                        if (b?.createTime) {
+                            let a = (new Date().getTime() / 1000) - (new Date(b?.levelTime).getTime() / 1000)
+                            function secondsToDhms(seconds: any) {
+                                const days = Math.floor(seconds / (3600 * 24));
+                                const hours = Math.floor((seconds % (3600 * 24)) / 3600);
+                                const minutes = Math.floor((seconds % 3600) / 60);
+                                const remainingSeconds = seconds % 60;
+                                return <span style={{ fontSize: 12, color: (hours + (days * 24)) > 1 ? 'red' : '#000' }}>{`${days ? days + "天" : ''}${hours ? hours + "小时" : ''}${minutes ? minutes + "分" : ''}${remainingSeconds ? remainingSeconds.toFixed(0) + "秒" : ''}`}</span>
+                            }
+                            return a ? secondsToDhms(a) : '--'
+                        } else {
+                            return '--'
+                        }
+                    }
+                },
+                {
+                    title: '创角时间至今', dataIndex: 'createTimeDiff', label: '角色游戏数据', align: 'center', width: 100, default: 9,
+                    render: (_: any, b: any) => {
+                        if (b?.createTime) {
+                            let a = (new Date().getTime() / 1000) - (new Date(b?.createTime).getTime() / 1000)
+                            function secondsToDhms(seconds: any) {
+                                const days = Math.floor(seconds / (3600 * 24));
+                                const hours = Math.floor((seconds % (3600 * 24)) / 3600);
+                                const minutes = Math.floor((seconds % 3600) / 60);
+                                const remainingSeconds = seconds % 60;
+                                return <span style={{ fontSize: 12, color: days > 5 ? 'red' : '#000' }}>{`${days ? days + "天" : ''}${hours ? hours + "小时" : ''}${minutes ? minutes + "分" : ''}${remainingSeconds ? remainingSeconds.toFixed(0) + "秒" : ''}`}</span>
+                            }
+                            return a ? secondsToDhms(a) : '--'
+                        } else {
+                            return '--'
+                        }
+                    }
+                }
+
+            ]
+        },
+        {
+            label: '客户管理操作',
+            data: [
+                { title: 'GS', dataIndex: 'gsName', label: '客户管理操作', align: 'center', width: 80, default: 10, render: (a: string, b: any) => (<WidthEllipsis value={a} />) },
+                { title: '客服', dataIndex: 'customerServiceName', label: '客户管理操作', align: 'center', width: 80, default: 11, render: (a: string, b: any) => (<WidthEllipsis value={a} />) },
+                { title: '运营', dataIndex: 'operUserName', label: '客户管理操作', align: 'center', width: 80, default: 12, render: (a: string, b: any) => (<WidthEllipsis value={a} />) },
+                { title: '投手', dataIndex: 'putUserName', label: '客户管理操作', align: 'center', width: 80, default: 13, render: (a: string, b: any) => (<WidthEllipsis value={a} />) }
+            ]
+        },
+        {
+            label: '操作',
+            data: [
+                {
+                    title: '操作',
+                    dataIndex: 'cz',
+                    align: 'center',
+                    width: 60,
+                    label: '操作',
+                    default: 14,
+                    render: (_: any, b: any) => {
+                        return <Space>
+                            <LookRoleDetails userId={b.userId} />
+                            <a style={{ fontSize: 12 }} onClick={() => { assignHandle([b]) }}>指派</a>
+                        </Space>
+                    }
+                }
+            ]
+        }
+    ]
+}
+
+export default columns12

+ 27 - 0
src/services/gsData/index.ts

@@ -179,4 +179,31 @@ export async function getServerManageListApi(data: GetServerManageProps) {
         method: 'POST',
         data
     });
+}
+
+
+export interface GetRoleLevelListProps extends Paging, SortProps{
+    roleName?: string
+    roleId?: string
+    gameName?: string
+    gameId?: string
+    serverName?: string
+    serverId?: string
+    createTimeMin?: string
+    createTimeMax?: string
+    roleLevelMin?: number
+    roleLevelMax?: number
+    levelTimeMin?: number
+    levelTimeMax?: number
+}
+/**
+ * 角色等级列表 仙剑
+ * @param data 
+ * @returns 
+ */
+export async function getRoleLevelListApi(data: GetRoleLevelListProps) {
+    return request(api + `/gameData/role/level/listOfPage`, {
+        method: 'POST',
+        data
+    });
 }