strategyModal.tsx 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. import { Form, Input, InputNumber, Modal, Select, Space, message } from "antd";
  2. import React, { useEffect, useState } from "react"
  3. import { strategyType } from ".";
  4. import { FieldTimeOutlined } from "@ant-design/icons";
  5. import { useAjax } from "@/Hook/useAjax";
  6. import { StrategyProps, modalStrategyApi } from "@/services/gameData/roleOperate";
  7. enum conditionEnum {
  8. gt = '大于',
  9. ge = '大于等于',
  10. lt = '小于',
  11. le = '小于等于',
  12. eq = '等于',
  13. }
  14. interface Props {
  15. superGameList: any[]
  16. initialValues?: any
  17. visible?: boolean
  18. onClose?: () => void
  19. onChange?: () => void
  20. }
  21. const StrategyModal: React.FC<Props> = ({ superGameList, initialValues, visible, onClose, onChange }) => {
  22. /*****************************/
  23. const [form] = Form.useForm<StrategyProps>()
  24. const type = Form.useWatch('type', form)
  25. const time = Form.useWatch('time', form)
  26. const timeCondition = Form.useWatch('timeCondition', form)
  27. const amount = Form.useWatch('amount', form)
  28. const amountCondition = Form.useWatch('amountCondition', form)
  29. const [help, setHelp] = useState<string>()
  30. const modalStrategy = useAjax((params) => modalStrategyApi(params))
  31. /*****************************/
  32. useEffect(() => {
  33. if (type) {
  34. let timeTips: string = ''
  35. let amountTips: string = ''
  36. switch (type) {
  37. case 1:
  38. // 单笔充值金额大于等于XX,并且注册时间在XX小时内的玩家
  39. timeTips = time ? `注册时间${conditionEnum[timeCondition]}${time}小时的玩家` : ''
  40. amountTips = amount ? `单笔充值金额${conditionEnum[amountCondition]}${amount}元` : ''
  41. break
  42. case 2:
  43. // 累计充值金额大于等于XX,并且最近游戏距今时间超过XX小时的玩家
  44. amountTips = amount ? `累计充值金额${conditionEnum[amountCondition]}${amount}元` : ''
  45. timeTips = time ? `最近游戏距今时间${conditionEnum[timeCondition]}${time}小时的玩家` : ''
  46. break
  47. case 3:
  48. // '新用户注册创角首日充值大于等于XX的用户'
  49. amountTips = amount ? `新用户注册创角首日充值${conditionEnum[amountCondition]}${amount}元的用户` : ''
  50. break
  51. }
  52. let helpTips = ''
  53. if (timeTips && amountTips) {
  54. helpTips = amountTips + ',并且' + timeTips + ',发送钉钉消息'
  55. } else if (timeTips) {
  56. helpTips = timeTips + ',发送钉钉消息'
  57. } else if (amountTips) {
  58. helpTips = amountTips + ',发送钉钉消息'
  59. }
  60. setHelp(helpTips)
  61. form.setFieldsValue({ configExplain: helpTips })
  62. } else {
  63. setHelp(undefined)
  64. form.setFieldsValue({ configExplain: undefined })
  65. }
  66. }, [type, time, amount, timeCondition, amountCondition])
  67. const handleOk = async () => {
  68. form.submit()
  69. let data = await form.validateFields()
  70. console.log('===========>', data)
  71. if (!data?.amount && !data?.time) {
  72. message.error('时间和金额最少填一项')
  73. return
  74. }
  75. if (initialValues?.id) {
  76. data.id = initialValues?.id
  77. }
  78. modalStrategy.run(data).then(res => {
  79. if (res) {
  80. if (initialValues?.id) {
  81. message.success('修改成功')
  82. } else {
  83. message.success('新增成功')
  84. }
  85. onChange?.()
  86. }
  87. })
  88. }
  89. // 配置 formatter 和 parser
  90. const integerFormatter = (value: any) => {
  91. // 去除非数字字符
  92. if (value && value !== 0) {
  93. const intValue = parseInt(value, 10);
  94. return isNaN(intValue) ? 0 : intValue as any;
  95. }
  96. return value
  97. };
  98. const integerParser = (value: any) => {
  99. // 去除非数字字符
  100. if (value && value !== 0) {
  101. const intValue = parseInt(value, 10);
  102. return isNaN(intValue) ? '' : String(intValue);
  103. }
  104. return value
  105. };
  106. return <Modal
  107. title={`${initialValues?.id ? '修改' : '新增'}游戏策略`}
  108. visible={visible}
  109. onCancel={onClose}
  110. onOk={handleOk}
  111. confirmLoading={modalStrategy.loading}
  112. >
  113. <Form
  114. name="basicStrategy"
  115. labelCol={{ span: 4 }}
  116. wrapperCol={{ span: 20 }}
  117. form={form}
  118. autoComplete="off"
  119. labelAlign="left"
  120. colon={false}
  121. initialValues={Object.keys(initialValues).length > 0 ? { ...initialValues } : { amountCondition: 'gt', timeCondition: 'gt' }}
  122. >
  123. <Form.Item label="超父游戏" name='superGameId' rules={[{ required: true, message: '请选择超父游戏!' }]}>
  124. <Select
  125. showSearch
  126. allowClear
  127. placeholder={'请选择超父游戏'}
  128. filterOption={(input, option) =>
  129. (option?.children as any)?.toLowerCase().indexOf(input.toLowerCase()) >= 0
  130. }
  131. >
  132. {superGameList?.map((item: any) => <Select.Option value={item.super_game_id} key={item.super_game_id}>{item.super_game_name}</Select.Option>)}
  133. </Select>
  134. </Form.Item>
  135. <Form.Item label="策略类型" help={help} name='type' rules={[{ required: true, message: '请选择策略类型!' }]}>
  136. <Select
  137. showSearch
  138. style={{ minWidth: 140 }}
  139. allowClear
  140. placeholder={'请选择策略类型'}
  141. filterOption={(input, option) =>
  142. (option?.children as any)?.toLowerCase().indexOf(input.toLowerCase()) >= 0
  143. }
  144. >
  145. {strategyType?.map((item: any) => <Select.Option value={item.value} key={item.value}>{item.label}</Select.Option>)}
  146. </Select>
  147. </Form.Item>
  148. <Form.Item
  149. label="金额(元)"
  150. >
  151. <Space style={{ width: '100%' }}>
  152. <Form.Item
  153. name='amount'
  154. noStyle
  155. >
  156. <InputNumber
  157. style={{ width: '100%' }}
  158. prefix="¥"
  159. min={0}
  160. placeholder="请输入金额"
  161. formatter={integerFormatter}
  162. parser={integerParser}
  163. />
  164. </Form.Item>
  165. {(amount || amount === 0) && <Form.Item
  166. name='amountCondition'
  167. noStyle
  168. rules={[{ required: true, message: '请选择条件' }]}
  169. >
  170. <Select
  171. style={{ width: 100 }}
  172. placeholder="条件"
  173. >
  174. <Select.Option value="gt">大于</Select.Option>
  175. <Select.Option value="ge">大于等于</Select.Option>
  176. <Select.Option value="lt">小于</Select.Option>
  177. <Select.Option value="le">小于等于</Select.Option>
  178. <Select.Option value="eq">等于</Select.Option>
  179. </Select>
  180. </Form.Item>}
  181. </Space>
  182. </Form.Item>
  183. {type !== 3 && <Form.Item
  184. label="时间(小时)"
  185. >
  186. <Space>
  187. <Form.Item
  188. name='time'
  189. noStyle
  190. >
  191. <InputNumber
  192. style={{ width: '100%' }}
  193. prefix={<FieldTimeOutlined />}
  194. min={0}
  195. placeholder="请输入时间"
  196. formatter={integerFormatter}
  197. parser={integerParser}
  198. />
  199. </Form.Item>
  200. {(time || time === 0) && <Form.Item
  201. name='timeCondition'
  202. noStyle
  203. rules={[{ required: true, message: '请选择条件' }]}
  204. >
  205. <Select
  206. style={{ width: 100 }}
  207. placeholder="条件"
  208. >
  209. <Select.Option value="gt">大于</Select.Option>
  210. <Select.Option value="ge">大于等于</Select.Option>
  211. <Select.Option value="lt">小于</Select.Option>
  212. <Select.Option value="le">小于等于</Select.Option>
  213. <Select.Option value="eq">等于</Select.Option>
  214. </Select>
  215. </Form.Item>}
  216. </Space>
  217. </Form.Item>}
  218. <Form.Item label="策略说明" name='configExplain' rules={[{ required: true, message: '请选择配置说明!' }]}>
  219. <Input.TextArea placeholder="配置说明:请写出具体的配置细节。如:首次充值金额大于等于500并且注册时间24小时内的用户,发送钉钉消息" />
  220. </Form.Item>
  221. </Form>
  222. </Modal>
  223. }
  224. export default React.memo(StrategyModal)