generateTarget.tsx 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. import { Button, Card, Form, InputNumber, Modal, Select, Space, message } from "antd"
  2. import React from "react"
  3. import '../../index.less'
  4. import { getRandomElements } from "@/utils/utils"
  5. import { REGION_DATA } from "./const"
  6. interface Props {
  7. target: any
  8. visible?: boolean,
  9. onClose?: () => void
  10. onChange?: (value: any) => void
  11. }
  12. const GenerateTarget: React.FC<Props> = ({ target, visible, onChange, onClose }) => {
  13. /*********************************/
  14. const [form] = Form.useForm();
  15. /*********************************/
  16. const handleOk = (values: any) => {
  17. const zhongguo = [156, 540000, 630000, 510000, 450000, 320000, 220000, 370000, 340000, 150000, 140000, 420000, 130000, 360000, 310000, 330000, 650000, 350000, 120000, 110000, 640000, 530000, 210000, 610000, 520000, 230000, 460000, 440000, 500000, 410000, 620000, 430000]
  18. const locationTypes = ["LIVE_IN"]
  19. const { regions, count } = values
  20. let regionsData = REGION_DATA.find(item => item.value === regions)
  21. let children = regionsData?.children || []
  22. interface Region {
  23. title: string;
  24. value: number;
  25. key: number;
  26. parentId?: number;
  27. disabled?: boolean;
  28. children?: Region[];
  29. }
  30. function getRegionPaths(region: Region, parentPath: string = ''): string[] {
  31. const currentPath = parentPath ? `${parentPath},${region.value}` : `${region.value}`;
  32. const paths = [];
  33. if (region?.children?.length) {
  34. for (const child of region.children) {
  35. paths.push(...getRegionPaths(child, currentPath));
  36. }
  37. } else {
  38. paths.push(currentPath)
  39. }
  40. return paths;
  41. }
  42. function getAllPaths(regions: Region[]): string[] {
  43. let allPaths: string[] = [];
  44. for (const region of regions) {
  45. allPaths = allPaths.concat(getRegionPaths(region));
  46. }
  47. return allPaths;
  48. }
  49. let regionsList: string[] = getAllPaths(children);
  50. if (regionsList.length === 0) {
  51. message.error('请联系管理员')
  52. return
  53. }
  54. const getTarget = (count: number, regionsList: string[]): any => {
  55. let dataRandom = getRandomElements(regionsList, count)
  56. return dataRandom.map(item => {
  57. let r = item.split(',')
  58. let rData = children.find(c => c.value.toString() === r[0])
  59. let rName = rData?.title
  60. let regionsL = children.map(item => item.value)
  61. if (r.length > 1) {
  62. let lChildren = rData?.children || []
  63. let lData = lChildren.find(item => item.value.toString() === r[1])
  64. let lName = lData?.title
  65. let lRegionsL = lChildren.map(item => item.value)
  66. console.log('target?.targeting?.regions', target?.targeting)
  67. return {
  68. ...target,
  69. targetingName: `${regionsData?.title}无${rName}${lName}+` + target.targetingName,
  70. targeting: {
  71. ...(target?.targeting || {}),
  72. geoLocation: {
  73. locationTypes: (target?.targeting?.geoLocation?.locationTypes || locationTypes),
  74. regions: [...((target?.targeting?.geoLocation?.regions || zhongguo) as number[]).filter(item => item !== regions), ...regionsL.filter(item => item.toString() !== r[0]), ...lRegionsL.filter(item => item.toString() !== r[1])]
  75. }
  76. }
  77. }
  78. } else {
  79. return {
  80. ...target,
  81. targetingName: `${regionsData?.title}无${rName}+` + target.targetingName,
  82. targeting: {
  83. ...(target?.targeting || {}),
  84. geoLocation: {
  85. locationTypes: (target?.targeting?.geoLocation?.locationTypes || locationTypes),
  86. regions: [...((target?.targeting?.geoLocation?.regions || zhongguo) as number[]).filter(item => item !== regions), ...regionsL.filter(item => item.toString() !== r[0])]
  87. }
  88. }
  89. }
  90. }
  91. })
  92. }
  93. let data: any[] = []
  94. if (target?.targeting?.geoLocation) {
  95. let oldregions: number[] = target.targeting.geoLocation.regions
  96. if (oldregions.includes(regions)) {
  97. data = data.concat(getTarget(count, regionsList))
  98. } else { // 不包含 regionsList
  99. message.error('当前地域已经排除了该省下的某个区或者县')
  100. return
  101. }
  102. } else {
  103. data = data.concat(getTarget(count, regionsList))
  104. }
  105. onChange?.(data)
  106. }
  107. return <Modal
  108. title={<strong>一键生成定向配置</strong>}
  109. visible={visible}
  110. className='modalResetCss'
  111. onCancel={onClose}
  112. bodyStyle={{ padding: '0 0 40px', position: 'relative', borderRadius: '0 0 8px 8px' }}
  113. footer={null}
  114. >
  115. <Form
  116. form={form}
  117. name="generateTarget"
  118. labelAlign='left'
  119. labelCol={{ span: 4 }}
  120. colon={false}
  121. style={{ backgroundColor: '#f1f4fc', maxHeight: 600, overflow: 'hidden', overflowY: 'auto', padding: '10px 10px 10px', borderRadius: '0 0 8px 8px' }}
  122. scrollToFirstError
  123. onFinishFailed={({ errorFields }) => {
  124. message.error(errorFields?.[0]?.errors?.[0])
  125. }}
  126. onFinish={handleOk}
  127. initialValues={{
  128. regions: 540000,
  129. count: 3
  130. }}
  131. >
  132. <Card
  133. title={<strong style={{ fontSize: 14 }}>生成设置</strong>}
  134. className="cardResetCss"
  135. >
  136. <Form.Item
  137. label={<strong>地域差异</strong>}
  138. name='regions'
  139. rules={[
  140. { required: true, message: '请选择' }
  141. ]}
  142. >
  143. <Select
  144. placeholder="请选择"
  145. showSearch
  146. filterOption={(input, option) =>
  147. ((option?.children ?? '') as any).toLowerCase().includes(input.toLowerCase())
  148. }
  149. >
  150. {REGION_DATA.map(item => <Select.Option value={item.value} key={item.key}>{item.title}</Select.Option>)}
  151. </Select>
  152. </Form.Item>
  153. <Form.Item
  154. label={<strong>生成数量</strong>}
  155. name='count'
  156. rules={[
  157. { required: true, message: '请输入生成数量' }
  158. ]}
  159. >
  160. <InputNumber max={20} style={{ width: '100%' }} placeholder="请输入生成数量" />
  161. </Form.Item>
  162. </Card>
  163. <Form.Item className="submit_pull">
  164. <Space>
  165. <Button onClick={onClose}>取消</Button>
  166. <Button type="primary" htmlType="submit" className="modalResetCss">
  167. 确定
  168. </Button>
  169. </Space>
  170. </Form.Item>
  171. </Form>
  172. </Modal>
  173. }
  174. export default React.memo(GenerateTarget)