wjx 1 年之前
父節點
當前提交
25995c4854

+ 6 - 0
config/routerConfig.ts

@@ -152,6 +152,12 @@ const gameDataStatistics = {
                     name: '有效创角配置',
                     access: 'createRoleConfig',
                     component: './gameDataStatistics/roleOperate/createRoleConfig',
+                },
+                {
+                    path: '/gameDataStatistics/roleOperate/vip',
+                    name: '游戏VIP挡位',
+                    access: 'vip',
+                    component: './gameDataStatistics/roleOperate/vip',
                 }
             ]
         },

+ 7 - 1
src/components/QueryForm/index.tsx

@@ -1270,6 +1270,7 @@ const QueryForm: React.FC<Props> = (props) => {
                         (option?.children as any)?.toLowerCase().indexOf(input.toLowerCase()) >= 0
                     }
                 >
+                    <Select.Option value="2">未操作</Select.Option>
                     <Select.Option value="1">是</Select.Option>
                     <Select.Option value="0">不转端</Select.Option>
                 </Select>
@@ -1301,6 +1302,7 @@ const QueryForm: React.FC<Props> = (props) => {
                         (option?.children as any)?.toLowerCase().indexOf(input.toLowerCase()) >= 0
                     }
                 >
+                    <Select.Option value="2">未操作</Select.Option>
                     <Select.Option value="1">退游</Select.Option>
                     <Select.Option value="0">未退游</Select.Option>
                 </Select>
@@ -1333,6 +1335,7 @@ const QueryForm: React.FC<Props> = (props) => {
                         (option?.children as any)?.toLowerCase().indexOf(input.toLowerCase()) >= 0
                     }
                 >
+                    <Select.Option value="2">未操作</Select.Option>
                     <Select.Option value="1">是</Select.Option>
                     <Select.Option value="0">否</Select.Option>
                 </Select>
@@ -1349,6 +1352,7 @@ const QueryForm: React.FC<Props> = (props) => {
                         (option?.children as any)?.toLowerCase().indexOf(input.toLowerCase()) >= 0
                     }
                 >
+                    <Select.Option value="2">未操作</Select.Option>
                     <Select.Option value="1">是</Select.Option>
                     <Select.Option value="0">否</Select.Option>
                 </Select>
@@ -1359,7 +1363,9 @@ const QueryForm: React.FC<Props> = (props) => {
                 <Select
                     showSearch
                     allowClear
-                    style={{ width: 98 }}
+                    maxTagCount={1}
+                    mode="multiple"
+                    style={{ minWidth: 98 }}
                     placeholder={'角色VIP'}
                     filterOption={(input, option) =>
                         (option?.children as any)?.toLowerCase().indexOf(input.toLowerCase()) >= 0

+ 162 - 0
src/pages/gameDataStatistics/roleOperate/vip/index.tsx

@@ -0,0 +1,162 @@
+import { useAjax } from "@/Hook/useAjax"
+import { getGameListNewApi } from "@/services/gameData"
+import { GameVipProps, delGameVipApi, getGameVipApi } from "@/services/gameData/roleOperate"
+import { PlusOutlined } from "@ant-design/icons"
+import { Button, Card, Col, Form, Input, Row, Select, Space, message } from "antd"
+import React, { useEffect, useState } from "react"
+import VipModal from "./vipModal"
+import Tables from "@/components/Tables"
+import style from '../../components/TableData/index.less'
+import columnsPos from "./tableConfig"
+
+/**
+ * 游戏VIP挡位
+ * @returns 
+ */
+const Vip: React.FC = () => {
+
+    /******************************/
+    const [form] = Form.useForm()
+    const [initialValues, setInitialValues] = useState<any>({})
+    const [queryFrom, setQueryForm] = useState<GameVipProps>({ pageNum: 1, pageSize: 20 })
+    const [thatStoreData, setThatStoreData] = useState<{ gameList: any[] }>({ gameList: [] })
+    const [superGameList, setSuperGameList] = useState<any[]>([])
+    const [visible, setVisible] = useState<boolean>(false)
+    const getGameVip = useAjax((params) => getGameVipApi(params))
+    const delGameVip = useAjax((params) => delGameVipApi(params))
+    const getGameList = useAjax((params) => getGameListNewApi(params))
+    /******************************/
+
+    const onFinish = (data: any) => {
+        let oldQueryFrom = JSON.parse(JSON.stringify(queryFrom))
+        setQueryForm({ ...oldQueryFrom, ...data, pageNum: 1 })
+    }
+
+    useEffect(() => {
+        getGameVip.run(queryFrom)
+    }, [queryFrom])
+
+    useEffect(() => {
+        getGameList.run({ sourceSystem: 'ZX_ONE' }).then(res => {
+            if (res) {
+                const { parentGameList, superGameList } = res
+                setSuperGameList(superGameList)
+                setThatStoreData({ gameList: parentGameList?.map((item: { parent_game_name: any; super_game_id: any, parent_game_id: any }) => ({ name: item.parent_game_name, id: item.parent_game_id, superId: item.super_game_id })) })
+            }
+        })
+    }, [])
+
+    const editVip = (data: any) => {
+        setInitialValues(data)
+        setVisible(true)
+    }
+
+    const del = (id: number) => {
+        delGameVip.run(id).then(res => {
+            if (res) {
+                message.success('删除成功')
+                getGameVip.refresh()
+            }
+        })
+    }
+
+    return <Card
+        style={{ borderRadius: 8 }}
+        headStyle={{ textAlign: 'left' }}
+        bodyStyle={{ padding: '5px 10px' }}
+    >
+        <div style={{ textAlign: 'center', fontWeight: 'bold', padding: '4px 6px 6px', fontSize: 16, marginBottom: 4, position: 'relative' }}>
+            VIP挡位
+        </div>
+        <Space style={{ width: '100%' }} direction="vertical" size={10}>
+            <Form layout="inline" className='queryForm' initialValues={initialValues} name="basicGameVip" form={form} onFinish={onFinish}>
+                <Row gutter={[0, 6]}>
+                    <Col><Form.Item name='vipLevel'>
+                        <Input placeholder="VIP档位" allowClear style={{ width: 140 }} />
+                    </Form.Item></Col>
+                    <Col><Form.Item name='superGameId'>
+                        <Select
+                            maxTagCount={1}
+                            showSearch
+                            style={{ minWidth: 140 }}
+                            allowClear
+                            placeholder={'请选择超父游戏'}
+                            filterOption={(input, option) =>
+                                (option?.children as any)?.toLowerCase().indexOf(input.toLowerCase()) >= 0
+                            }
+                        >
+                            {superGameList?.map((item: any) => <Select.Option value={item.super_game_id} key={item.super_game_id}>{item.super_game_name}</Select.Option>)}
+                        </Select>
+                    </Form.Item></Col>
+                    <Col><Form.Item name='parentGameId'>
+                        <Select
+                            maxTagCount={1}
+                            showSearch
+                            style={{ minWidth: 140 }}
+                            allowClear
+                            placeholder={'请选择父游戏'}
+                            filterOption={(input, option) =>
+                                (option?.children as any)?.toLowerCase().indexOf(input.toLowerCase()) >= 0
+                            }
+                        >
+                            {thatStoreData?.gameList?.map((item: any) => <Select.Option value={item.id} key={item.id}>{item.name}</Select.Option>)}
+                        </Select>
+                    </Form.Item></Col>
+                    <Col>
+                        <Space>
+                            <Button type="primary" htmlType="submit">搜索</Button>
+                            <Button onClick={() => form.resetFields()}>重置</Button>
+                            <Button icon={<PlusOutlined />} type="primary" onClick={() => { setVisible(true); setInitialValues({}) }}>新增VIP挡位</Button>
+                        </Space>
+                    </Col>
+                </Row>
+            </Form>
+
+            <div className={`${style['small']}`}>
+                <Tables
+                    className={`all_table content_table_body`}
+                    bordered
+                    sortDirections={['ascend', 'descend', null]}
+                    current={queryFrom.pageNum}
+                    pageSize={queryFrom.pageSize}
+                    columns={columnsPos(editVip, del)}
+                    dataSource={getGameVip?.data?.records}
+                    scroll={{ x: 1000, y: 600 }}
+                    onChange={(pagination: any, filters: any, sortData: any) => {
+                        let { current, pageSize } = pagination
+                        let newQueryForm = JSON.parse(JSON.stringify(queryFrom))
+                        if (sortData && sortData?.order) {
+                            newQueryForm['sortType'] = sortData?.order === 'ascend' ? 'asc' : 'desc'
+                            newQueryForm['sortFiled'] = sortData?.field
+                        } else {
+                            delete newQueryForm['sortType']
+                            delete newQueryForm['sortFiled']
+                        }
+                        newQueryForm.pageNum = current
+                        newQueryForm.pageSize = pageSize
+                        setQueryForm({ ...newQueryForm })
+                    }}
+                    size="small"
+                    total={getGameVip?.data?.total}
+                    loading={getGameVip?.loading}
+                    defaultPageSize={20}
+                />
+            </div>
+        </Space>
+
+        {visible && <VipModal
+            visible={visible}
+            onClose={() => { setInitialValues({}); setVisible(false) }}
+            superGameList={superGameList}
+            thatStoreData={thatStoreData}
+            initialValues={initialValues}
+            onChange={() => {
+                setInitialValues({}); 
+                getGameVip.refresh()
+                setVisible(false)
+            }}
+        />}
+    </Card>
+}
+
+export default Vip

+ 111 - 0
src/pages/gameDataStatistics/roleOperate/vip/tableConfig.tsx

@@ -0,0 +1,111 @@
+
+
+import { Row, Col, Popconfirm } from "antd"
+import { DeleteOutlined, EditOutlined } from "@ant-design/icons"
+import WidthEllipsis from "@/components/widthEllipsis"
+import React from "react"
+
+function columnsPos(editPack: (data: any) => void, del: (id: number) => void) {
+
+    let newArr: any = [
+        {
+            title: 'VIP挡位',
+            dataIndex: 'vipLevel',
+            key: 'vipLevel',
+            align: 'center',
+            width: 90,
+            render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+        },
+        {
+            title: '超父游戏名称',
+            dataIndex: 'superGameName',
+            key: 'superGameName',
+            align: 'center',
+            width: 90,
+            render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+        },
+        {
+            title: '游戏名称',
+            dataIndex: 'parentGameName',
+            key: 'parentGameName',
+            align: 'center',
+            width: 90,
+            render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+        },
+        {
+            title: '最小充值金额(包含)',
+            dataIndex: 'rechargeMoneyMin',
+            key: 'rechargeMoneyMin',
+            align: 'center',
+            width: 100,
+            render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+        },
+        {
+            title: '最大充值金额(不包含)',
+            dataIndex: 'rechargeMoneyMax',
+            key: 'rechargeMoneyMax',
+            align: 'center',
+            width: 120,
+            render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+        },
+        {
+            title: '创建人',
+            dataIndex: 'createName',
+            key: 'createName',
+            align: 'center',
+            width: 100,
+            render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+        },
+        {
+            title: '创建时间',
+            dataIndex: 'createTime',
+            key: 'createTime',
+            align: 'center',
+            width: 135,
+            render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+        },
+        {
+            title: '更新人',
+            dataIndex: 'updateName',
+            key: 'updateName',
+            align: 'center',
+            width: 100,
+            render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+        },
+        {
+            title: '更新时间',
+            dataIndex: 'updateTime',
+            key: 'updateTime',
+            align: 'center',
+            width: 135,
+            render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+        },
+        {
+            title: '操作',
+            dataIndex: 'cz',
+            key: 'cz',
+            align: 'center',
+            width: 100,
+            fixed: 'right',
+            render: (a: string, b: any) => (
+                <Row justify='center' gutter={[10, 0]}>
+                    <Col><a style={{ fontSize: "12px" }} onClick={() => { editPack(b) }}><EditOutlined /> 修改</a></Col>
+                    <Col>
+                        <Popconfirm
+                            title="确定删除?"
+                            onConfirm={() => { del(b.id) }}
+                            okText="是"
+                            cancelText="否"
+                        >
+                            <a style={{ fontSize: "12px", color: 'red' }}><DeleteOutlined /> 删除</a>
+                        </Popconfirm>
+                    </Col>
+                </Row>
+            )
+        }
+    ]
+    return newArr
+}
+
+
+export default columnsPos

+ 131 - 0
src/pages/gameDataStatistics/roleOperate/vip/vipModal.tsx

@@ -0,0 +1,131 @@
+import { useAjax } from "@/Hook/useAjax"
+import { modalGameVipApi } from "@/services/gameData/roleOperate"
+import { Form, InputNumber, Modal, Select, Space, message } from "antd"
+import React from "react"
+
+interface Props {
+    superGameList: any[]
+    thatStoreData: { gameList: any[] }
+    initialValues?: any
+    visible?: boolean
+    onClose?: () => void
+    onChange?: () => void
+}
+const VipModal: React.FC<Props> = ({ superGameList = [], thatStoreData = { gameList: [] }, initialValues, visible, onClose, onChange }) => {
+
+    /*******************************/
+    const [form] = Form.useForm()
+    const superGameId = Form.useWatch('superGameId', form)
+    const rechargeMoneyMin = Form.useWatch('rechargeMoneyMin', form)
+    const rechargeMoneyMax = Form.useWatch('rechargeMoneyMax', form)
+    const modalGameVip = useAjax((params) => modalGameVipApi(params))
+    /*******************************/
+
+    const handleOk = async () => {
+        form.submit()
+        let data = await form.validateFields()
+        console.log('===========>', data)
+        if (initialValues?.id) {
+            data.id = initialValues?.id
+        }
+        modalGameVip.run(data).then(res => {
+            if (res) {
+                if (initialValues?.id) {
+                    message.success('修改成功')
+                } else {
+                    message.success('新增成功')
+                }
+                onChange && onChange()
+            }
+        })
+    }
+
+    return <Modal
+        title={`${initialValues?.id ? '修改' : '新增'}VIP挡位`}
+        visible={visible}
+        onCancel={onClose}
+        onOk={handleOk}
+        confirmLoading={modalGameVip.loading}
+    >
+        <Form
+            name="basicVip"
+            labelCol={{ span: 4 }}
+            wrapperCol={{ span: 20 }}
+            form={form}
+            autoComplete="off"
+            labelAlign="left"
+            colon={false}
+            initialValues={{ ...initialValues }}
+        >
+            <Form.Item label="VIP挡位" name="vipLevel" rules={[{ required: true, message: '请输入vip挡位!' }]}>
+                <InputNumber min={0} placeholder="请输入vip挡位" style={{ minWidth: 130 }} />
+            </Form.Item>
+            <Form.Item label="超父游戏" name='superGameId' rules={[{ required: true, message: '请选择超父游戏!' }]}>
+                <Select
+                    showSearch
+                    allowClear
+                    placeholder={'请选择超父游戏'}
+                    filterOption={(input, option) =>
+                        (option?.children as any)?.toLowerCase().indexOf(input.toLowerCase()) >= 0
+                    }
+                >
+                    {superGameList?.map((item: any) => <Select.Option value={item.super_game_id} key={item.super_game_id}>{item.super_game_name}</Select.Option>)}
+                </Select>
+            </Form.Item>
+            <Form.Item label="父游戏" name='parentGameId' rules={[{ required: true, message: '请选择父游戏!' }]}>
+                <Select
+                    showSearch
+                    allowClear
+                    disabled={!superGameId}
+                    placeholder={'请选择父游戏'}
+                    filterOption={(input, option) =>
+                        (option?.children as any)?.toLowerCase().indexOf(input.toLowerCase()) >= 0
+                    }
+                >
+                    {thatStoreData?.gameList?.filter(item => item.superId === superGameId)?.map((item: any) => <Select.Option value={item.id} key={item.id}>{item.name}</Select.Option>)}
+                </Select>
+            </Form.Item>
+            <Form.Item label="充值金额" tooltip={'最小充值金额(包含),最大充值金额(不包含)'}>
+                <Space>
+                    <Form.Item
+                        name="rechargeMoneyMin"
+                        rules={[{
+                            validator: (_: any, value: number) => {
+                                if (!value && value !== 0) {
+                                    return Promise.reject(new Error('请输入最小充值金额!'));
+                                }
+                                if ((rechargeMoneyMax || rechargeMoneyMax === 0) && rechargeMoneyMax <= value) {
+                                    return Promise.reject(new Error('最小充值金额小于最大金额要!'));
+                                }
+                                return Promise.resolve();
+                            }
+                        }]}
+                        noStyle
+                    >
+                        <InputNumber min={0} placeholder="最小充值金额" style={{ minWidth: 140 }} />
+                    </Form.Item>
+                    -
+                    <Form.Item
+                        name="rechargeMoneyMax"
+                        rules={[{
+                            validator: (_: any, value: number) => {
+                                if (!value && value !== 0) {
+                                    return Promise.reject(new Error('请输入最大充值金额!'));
+                                }
+                                if ((rechargeMoneyMin || rechargeMoneyMin === 0) && rechargeMoneyMin >= value) {
+                                    return Promise.reject(new Error('最大金额要大于最小充值金额!'));
+                                }
+                                return Promise.resolve();
+                            }
+                        }]}
+                        noStyle
+                    >
+                        <InputNumber min={0} placeholder="最小充值金额" style={{ minWidth: 140 }} />
+                    </Form.Item>
+                </Space>
+            </Form.Item>
+        </Form>
+    </Modal>
+}
+
+export default React.memo(VipModal)

+ 51 - 0
src/services/gameData/roleOperate.ts

@@ -444,4 +444,55 @@ export async function delGameUserConfigApi(params: { id: number }) {
         method: 'DELETE',
         params
     });
+}
+
+export interface GameVipProps {
+    pageNum: number,
+    pageSize: number,
+    parentGameId?: number
+    superGameId?: number
+    vipLevel?: number
+}
+/**
+ * vip挡位列表
+ * @param data 
+ * @returns 
+ */
+export async function getGameVipApi(data: GameVipProps) {
+    return request(apiManage + '/game/vip/list', {
+        method: 'POST',
+        data
+    });
+}
+
+/**
+ * 删除vip挡位
+ * @param ids 
+ * @returns 
+ */
+export async function delGameVipApi(ids: string) {
+    return request(apiManage + `/game/vip/delete/${ids}`, {
+        method: 'DELETE'
+    });
+}
+
+
+export interface modalGameVipApi {
+    parentGameId: number
+    superGameId: number
+    vipLevel: number
+    rechargeMoneyMin: number
+    rechargeMoneyMax: number
+    id?: number
+}
+/**
+ * 新增修改vip挡位
+ * @param data 
+ * @returns 
+ */
+export async function modalGameVipApi(data: modalGameVipApi) {
+    return request(apiManage + '/game/vip/add/or/update', {
+        method: 'POST',
+        data
+    });
 }