Переглянути джерело

Merge branch 'master' of http://git.zanxiangnet.com/wjx/qc-gameDataStatistics

wjx 10 місяців тому
батько
коміт
be66a6ff62

+ 6 - 1
src/Hook/useAjax.tsx

@@ -12,6 +12,7 @@ interface Options {
     onSuccess?: (data: any, params: any[]) => void,//service resolve 时触发,参数为 data 和 params
     onError?: (error: Error, params: any[]) => void,//service 报错时触发,参数为 error 和 params。
     formatResult?: boolean,//格式化请求结果
+    isExcelData?:boolean,//是否是excel数据,返回原始内容
     initialData?: any,//默认的 data
     msgNmae?: string,
 }
@@ -41,7 +42,11 @@ export function useAjax(fnc: (params?: any) => Promise<any>, options?: Options)
         // throttleInterval:500,
         formatResult: (res) => {
             let reqTime = moment().format('YYYY-MM-DD HH:mm:ss')
-            return options?.formatResult ? {...res,reqTime} : res?.data
+            if(options?.isExcelData){
+                return res
+            }else{
+                return options?.formatResult ? {...res,reqTime} : res?.data
+            }
         },
         onSuccess: (res) => {
             if (res) {

+ 42 - 0
src/components/DownloadExcel/index.tsx

@@ -0,0 +1,42 @@
+import { formatDate } from "@/utils/downloadFile";
+import { CloudDownloadOutlined } from "@ant-design/icons";
+import { Button, message } from "antd";
+import moment from "moment";
+import React from 'react'
+/**
+ *  
+ * @param api 需要再请求设置 responseType: 'blob' 返回blob数据
+ * @returns 
+ */
+function DownloadExcel(props: { api: any, querys: any }) {
+    const { api, querys } = props
+    const downloadFile = (data: any, type: any, fileName: string) => {
+        let blob = new Blob([data], { type: `application/${type};charset=utf-8` });
+        let downloadElement = document.createElement('a');
+        let href = window.URL.createObjectURL(blob);
+        downloadElement.href = href;
+        downloadElement.download = fileName;
+        document.body.appendChild(downloadElement);
+        downloadElement.click();
+        document.body.removeChild(downloadElement);
+        window.URL.revokeObjectURL(href);
+    }
+    const download = () => {
+        // 判断querys是否是函数,函数执行函数,否则直接赋值
+        let params = typeof querys === 'function' ? querys() : querys
+        if (params?.date) {
+            params['startTime'] = moment(params.date[0]).format('YYYY-MM-DD')
+            params['endTime'] = moment(params.date[1]).format('YYYY-MM-DD')
+        } else {
+            delete params['startTime']
+            delete params['endTime']
+        }
+        delete params['date']
+        api.run({ ...params, pageSize: 20, pageNum: 1 }).then((res: any) => {
+            downloadFile(res, 'octet-stream', formatDate(new Date()) + ".xlsx")
+            message.success("下载成功!")
+        })
+    }
+    return <Button type='primary' onClick={download} loading={api?.loading}><CloudDownloadOutlined />下载Excel</Button>
+}
+export default DownloadExcel

+ 4 - 1
src/pages/gameDataStatistics/roleOperate/gameServer/index.tsx

@@ -1,5 +1,5 @@
 import { useAjax } from "@/Hook/useAjax"
-import { GameServerListProps, delGameServerApi, gameSupperListApi, getGameServerListApi, mergeAddOrUpdateApi, unMergeServerListApi } from "@/services/gameData/roleOperate"
+import { GameServerListProps, delGameServerApi, gameSupperListApi, getGameServerListApi, mergeAddOrUpdateApi, unMergeServerListApi,gameServerlistexcelApi } from "@/services/gameData/roleOperate"
 import { Button, Card, Col, DatePicker, Form, Input, Modal, Radio, Row, Select, Space, message } from "antd"
 import React, { useCallback, useEffect, useState } from "react"
 import moment from "moment"
@@ -12,6 +12,7 @@ import { PlusOutlined } from "@ant-design/icons"
 import EditModal from "./editModal"
 import UploadExcel from "./uploadExcel"
 import AssignUser from "./assignUser"
+import DownloadExcel from "@/components/DownloadExcel"
 
 let hfParmasInit = {
     gameId: "",//超父游戏id
@@ -44,6 +45,7 @@ const GameServer: React.FC = () => {
     const un_merge_server_list_api = useAjax((params) => unMergeServerListApi(params))//获取合服超父游戏列表
     const merge_add_or_update_api = useAjax((params) => mergeAddOrUpdateApi(params))//新增合服
     const getGameChoiceList = useAjax(() => getGameChoiceListApi())
+    const gameServerlistexcel = useAjax((params) => gameServerlistexcelApi(params),{isExcelData:true})
     /********************************/
 
     useEffect(() => {
@@ -178,6 +180,7 @@ const GameServer: React.FC = () => {
                             <Button icon={<PlusOutlined />} type="primary" onClick={() => { setVisible(true); setInitialValues({ startTime: moment().add(90, 'd') }) }}>新增游戏区服</Button>
                             <Button icon={<PlusOutlined />} type="primary" onClick={() => { set_show(true) }}>新增合服</Button>
                             <UploadExcel gameList={game_supper_list_api?.data} onChange={() => getGameServerList.refresh()} />
+                            <DownloadExcel  api={gameServerlistexcel} querys={form.getFieldsValue}/>
                             <Button icon={<PlusOutlined />} disabled={selectedRowKeys?.length === 0} type="primary" onClick={() => {
                                 setAssignType('GAME_SERVER_ASSIGN_CUSTOMER')
                                 setAssignData({ idList: selectedRowKeys.map(item => item.id), assignUserIdList: [] })

+ 23 - 5
src/pages/gameDataStatistics/roleOperate/roleRechargeRanking/roleCz.tsx

@@ -1,8 +1,9 @@
 import { useAjax } from "@/Hook/useAjax"
+import { getRoleUserListApi } from "@/services/gameData"
 // import { getSubUserWithSelfListApi } from "@/services/gameData"
 import { modifyRoleDataApi } from "@/services/gameData/roleOperate"
 import { Col, Form, Input, Modal, Radio, Row, Select, Space, message } from "antd"
-import React, { useEffect } from "react"
+import React, { useEffect, useState } from "react"
 
 interface Props {
     data: any[]
@@ -19,11 +20,19 @@ const RoleCz: React.FC<Props> = ({ data = [], visible, onClose, onChange }) => {
     /**************************/
     const [form] = Form.useForm()
     // const [userIdList, setUserIdList] = useState<any[]>([])
-
+    const [gsList, setGsList] = useState<any[]>([])
     // const getSubUserWithSelfList = useAjax(() => getSubUserWithSelfListApi())
     const modifyRoleData = useAjax((params) => modifyRoleDataApi(params))
+    const getRoleUserList = useAjax((params) => getRoleUserListApi(params))
     /**************************/
-
+    useEffect(() => {
+        getRoleUserList.run({ authType: 'GS' }).then((res:any) => {
+            if (res) {
+                let arr = Object.keys(res).map(key => ({ value: Number(key), label: res[key] }))
+                setGsList(arr)
+            }
+        })
+    }, [])
     useEffect(() => {
         if (data?.length === 1) {
             const { user_wechat, user_phone, is_remove_game, is_wake_up, remark, add_corp_user_id, is_add_corp_wechat, is_change_game_type, gsAccount, corpId, external_user_id } = data[0]
@@ -70,7 +79,8 @@ const RoleCz: React.FC<Props> = ({ data = [], visible, onClose, onChange }) => {
             }
         })
     }
-
+    const filterOption = (input: string, option?: { label: string; value: string }) =>
+    (option?.label ?? '').toLowerCase().includes(input.toLowerCase());
     return <Modal
         title={<Space>
             <strong>角色操作</strong>
@@ -107,7 +117,15 @@ const RoleCz: React.FC<Props> = ({ data = [], visible, onClose, onChange }) => {
                 </Col>
                 <Col span={12}>
                     <Form.Item label="GS账号" name="gsAccount">
-                        <Input placeholder="请输入GS账号" />
+                        <Select
+                            maxTagCount={1}
+                            showSearch
+                            style={{ width: '100%' }}
+                            allowClear
+                            placeholder={'请选择游戏GS'}
+                            filterOption={filterOption}
+                            options={gsList}
+                        />
                     </Form.Item>
                 </Col>
                 <Col span={12}>

+ 23 - 10
src/pages/gameDataStatistics/roleOperate/roleRechargeRanking/tableConfig.tsx

@@ -1,6 +1,6 @@
 import ProgressTable from "@/components/ProgressTable"
 import WidthEllipsis from "@/components/widthEllipsis"
-import { Badge, Popconfirm, Space, Statistic, Tag } from "antd"
+import { Badge, Button, Popconfirm, Space, Spin, Statistic, Tag } from "antd"
 import React from "react"
 import SendEmailDetails from "./sendEmailDetails"
 import './index.less'
@@ -288,7 +288,7 @@ function columns12(
                     },
                 },
                 {
-                    title: 'GS账号', dataIndex: 'gsAccount', label: '客户运营操作', align: 'center', width: 80,ellipsis: true
+                    title: 'GS账号', dataIndex: 'gsAccount', label: '客户运营操作', align: 'center', width: 80, ellipsis: true
                 },
                 {
                     title: '企业ID', dataIndex: 'corpId', label: '客户运营操作', align: 'center', width: 80, ellipsis: true
@@ -614,8 +614,7 @@ export const columnsChangeLog = (update: (data: any) => void, del: (id: number[]
  * @param sendLog 
  * @returns 
  */
-export const columnsMsgTask = (sendLog: (data: any) => void) => {
-
+export const columnsMsgTask = (sendLog: (data: any) => void, reloadSend: (id: any) => void, loading: boolean) => {
     return [
         {
             title: '任务名称',
@@ -684,13 +683,14 @@ export const columnsMsgTask = (sendLog: (data: any) => void) => {
             title: '操作',
             dataIndex: 'cz',
             key: 'cz',
-            width: 70,
+            width: 120,
             fixed: 'right',
             align: 'center',
             render: (a: any, b: any) => {
-                return <Space>
-                    <a style={{ fontSize: 12 }} onClick={() => sendLog(b)}>发送记录</a>
-                </Space>
+                return <Space style={{ fontSize: 12 }}>
+                    <a onClick={() => sendLog(b)}>发送记录</a>
+                    <Spin spinning={loading}><a onClick={() => { reloadSend({ taskId: b.id, gameId: b.gameId }) }}>失败重发</a></Spin>
+                </Space >
             }
         },
     ]
@@ -701,7 +701,7 @@ export const columnsMsgTask = (sendLog: (data: any) => void) => {
  * @param sendLog 
  * @returns 
  */
-export const columnsMsgTaskLog = () => {
+export const columnsMsgTaskLog = (reloadSend: (id: any) => void, loading: boolean) => {
 
     return [
         {
@@ -759,7 +759,20 @@ export const columnsMsgTaskLog = () => {
             key: 'createTime',
             width: 145,
             ellipsis: true
-        }
+        },
+        {
+            title: '操作',
+            dataIndex: 'cz',
+            key: 'cz',
+            width: 70,
+            fixed: 'right',
+            align: 'center',
+            render: (a: any, b: any) => {
+                return <Space style={{ fontSize: 12 }}>
+                    {b?.sendStatus === 'CP_SEND_ROLE_RESULT_FAIL' && <Spin spinning={loading}><a onClick={() => { reloadSend({ resultId: b.id }) }}>失败重发</a></Spin>}
+                </Space>
+            }
+        },
     ]
 }
 

+ 20 - 4
src/pages/gameDataStatistics/roleOperate/roleRechargeRanking/taskList.tsx

@@ -1,7 +1,7 @@
 import { useAjax } from "@/Hook/useAjax"
 import Tables from "@/components/Tables"
 import { getGameListNewApi } from "@/services/gameData"
-import { getSendLogListApi, getSendMsgTaskListApi } from "@/services/gameData/roleOperate"
+import { getSendLogListApi, getSendMsgTaskListApi, reSendMsgByResultIdApi, reSendMsgByTaskIdApi } from "@/services/gameData/roleOperate"
 import { SyncOutlined } from "@ant-design/icons"
 import { Button, Modal, Select, Space, message } from "antd"
 import React, { useEffect, useState } from "react"
@@ -31,6 +31,9 @@ const TaskList: React.FC<Props> = ({ sourceSystem }) => {
     const getGameListNew = useAjax((params) => getGameListNewApi(params))
     const getSendMsgTaskList = useAjax((params) => getSendMsgTaskListApi(params))
     const getSendLogList = useAjax((params) => getSendLogListApi(params))
+    const reSendMsgByTaskId = useAjax((params) => reSendMsgByTaskIdApi(params))
+    const reSendMsgByResultId = useAjax((params) => reSendMsgByResultIdApi(params))
+
     /****************************/
 
     useEffect(() => {
@@ -63,7 +66,20 @@ const TaskList: React.FC<Props> = ({ sourceSystem }) => {
         setTaskId(data.id)
         setVisibleLog(true)
     }
-
+    /**重发task*/
+    const reloadTask = (data: { gameId: any, taskId: any }) => {
+        reSendMsgByTaskId.run(data).then(res => {
+            message.success("操作成功")
+            getSendMsgTaskList.refresh()
+        })
+    }
+    /**重发result*/
+    const reloadResult = (data: { resultId: any }) => {
+        reSendMsgByResultId.run(data).then(res => {
+            message.success("操作成功")
+            getSendLogList.refresh()
+        })
+    }
     return <>
         <Button type="primary" size="small" onClick={open}>消息推送任务列表</Button>
         <Modal
@@ -110,7 +126,7 @@ const TaskList: React.FC<Props> = ({ sourceSystem }) => {
                 bordered
                 current={queryForm.pageNum}
                 pageSize={queryForm.pageSize}
-                columns={columnsMsgTask(sendLog)}
+                columns={columnsMsgTask(sendLog, reloadTask, reSendMsgByTaskId.loading)}
                 dataSource={getSendMsgTaskList?.data?.records}
                 scroll={{ x: 1000, y: 600 }}
                 onChange={(pagination: any, filters: any, sortData: any) => {
@@ -160,7 +176,7 @@ const TaskList: React.FC<Props> = ({ sourceSystem }) => {
                 bordered
                 current={queryFormLog.pageNum}
                 pageSize={queryFormLog.pageSize}
-                columns={columnsMsgTaskLog()}
+                columns={columnsMsgTaskLog(reloadResult, reSendMsgByResultId.loading)}
                 dataSource={getSendLogList?.data?.records}
                 scroll={{ x: 1000, y: 600 }}
                 onChange={(pagination: any) => {

+ 34 - 1
src/services/gameData/roleOperate.ts

@@ -275,6 +275,27 @@ export async function getSendLogListApi(data: { taskId: number, pageNum: number,
         data
     });
 }
+/**
+ * 根据任务id重发消息
+ * */
+export async function reSendMsgByTaskIdApi(data: any) {
+    return request(wapi + '/role/reSendMsgByTaskId', {
+        method: 'POST',
+        params:data
+    });
+}
+
+/**
+ * 根据发送结果id重发消息
+ * */
+export async function reSendMsgByResultIdApi(data: any) {
+    return request(wapi + '/role/reSendMsgByResultId', {
+        method: 'POST',
+        params:data
+    });
+}
+
+
 
 let apiManage = api + '/manage'
 
@@ -630,4 +651,16 @@ export async function modalStrategyApi(data: StrategyProps) {
         method: 'POST',
         data
     });
-}
+}
+
+/**
+ * 下载游戏区服Excel
+ * 
+ * */
+export async function gameServerlistexcelApi(data: any) {
+    return request(apiManage + '/gameServer/list/excel', {
+        method: 'POST',
+        data,
+        responseType: 'blob'
+    });
+}