123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 |
- import { Button, Card, Form, InputNumber, Modal, Select, Space, message } from "antd"
- import React, { useEffect, useState } from "react"
- import '../../index.less'
- import { getRandomElements } from "@/utils/utils"
- import { REGION_DATA } from "./const"
- interface Props {
- target: any
- visible?: boolean,
- onClose?: () => void
- onChange?: (value: any) => void
- }
- interface Region {
- title: string;
- value: number;
- key: number;
- parentId?: number;
- disabled?: boolean;
- children?: Region[];
- }
- // 年龄前驱
- const START_AGE = Array(66 - 13).fill('').map((_, i) => i + 14).filter(i => i !== 15 && i !== 16 && i !== 17)
- // 年龄后驱
- const END_AGE = Array(66 - 17).fill('')
- /**
- * 一键生成
- * @param param0
- * @returns
- */
- const GenerateTarget: React.FC<Props> = ({ target, visible, onChange, onClose }) => {
- /*********************************/
- const [form] = Form.useForm();
- const startAgeMax = Form.useWatch('startAgeMax', form)
- const startAgeMin = Form.useWatch('startAgeMin', form)
- const defaultStartAge = Form.useWatch('defaultStartAge', form)
- const endAgeMax = Form.useWatch('endAgeMax', form)
- const endAgeMin = Form.useWatch('endAgeMin', form)
- const defaultEndAge = Form.useWatch('defaultEndAge', form)
- const [startAgeList, setStartAgeList] = useState<number[]>([])
- const [endAgeList, setEndAgeList] = useState<number[]>([])
- /*********************************/
- useEffect(() => {
- if (typeof startAgeMin === 'number' && typeof startAgeMax === 'number') {
- let startAgeList = Array(startAgeMin === 14 ? startAgeMax - startAgeMin + 1 : startAgeMax - startAgeMin + 1).fill('').map((_, index) => startAgeMin + index).filter(i => i !== 15 && i !== 16 && i !== 17 && i !== defaultStartAge)
- setStartAgeList(startAgeList)
- } else {
- setStartAgeList([])
- }
- }, [startAgeMin, startAgeMax, defaultStartAge])
- useEffect(() => {
- if (typeof endAgeMin === 'number' && typeof endAgeMax === 'number') {
- let endAgeList = Array(endAgeMax - endAgeMin + 1).fill('').map((_, index) => endAgeMin + index).filter(item => item !== defaultEndAge)
- setEndAgeList(endAgeList)
- } else {
- setEndAgeList([])
- }
- }, [endAgeMax, endAgeMin, defaultEndAge])
- const handleOk = (values: any) => {
- 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]
- const locationTypes = ["LIVE_IN"]
- const { regions, count, defaultStartAge, defaultEndAge } = values
- let regionsData = REGION_DATA.find(item => item.value === regions)
- let children = regionsData?.children || []
- function getRegionPaths(region: Region, parentPath: string = ''): string[] {
- const currentPath = parentPath ? `${parentPath},${region.value}` : `${region.value}`;
- const paths = [];
- if (region?.children?.length) {
- for (const child of region.children) {
- paths.push(...getRegionPaths(child, currentPath));
- }
- } else {
- paths.push(currentPath)
- }
- return paths;
- }
- function getAllPaths(regions: Region[]): string[] {
- let allPaths: string[] = [];
- for (const region of regions) {
- allPaths = allPaths.concat(getRegionPaths(region));
- }
- return allPaths;
- }
- let regionsList: string[] = getAllPaths(children);
- if (regionsList.length === 0) {
- message.error('请联系管理员')
- return
- }
- const getTarget = (count: number, regionsList: string[]): any => {
- let dataRandom = getRandomElements(regionsList, count)
- return dataRandom.map(item => {
- let r = item.split(',')
- let rData = children.find(c => c.value.toString() === r[0])
- let rName = rData?.title
- let regionsL = children.map(item => item.value)
- if (r.length > 1) {
- let lChildren = rData?.children || []
- let lData = lChildren.find(item => item.value.toString() === r[1])
- let lName = lData?.title
- let lRegionsL = lChildren.map(item => item.value)
- console.log('target?.targeting?.regions', target?.targeting)
- return {
- ...target,
- targetingName: `${regionsData?.title}无${rName}${lName}+` + target.targetingName,
- targeting: {
- ...(target?.targeting || {}),
- geoLocation: {
- locationTypes: (target?.targeting?.geoLocation?.locationTypes || locationTypes),
- 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])]
- }
- }
- }
- } else {
- return {
- ...target,
- targetingName: `${regionsData?.title}无${rName}+` + target.targetingName,
- targeting: {
- ...(target?.targeting || {}),
- geoLocation: {
- locationTypes: (target?.targeting?.geoLocation?.locationTypes || locationTypes),
- regions: [...((target?.targeting?.geoLocation?.regions || zhongguo) as number[]).filter(item => item !== regions), ...regionsL.filter(item => item.toString() !== r[0])]
- }
- }
- }
- }
- })
- }
- let data: any[] = []
- if (target?.targeting?.geoLocation) {
- let oldregions: number[] = target.targeting.geoLocation.regions
- if (oldregions.includes(regions)) {
- data = data.concat(getTarget(count, regionsList))
- } else { // 不包含 regionsList
- message.error('当前地域已经排除了该省下的某个区或者县')
- return
- }
- } else {
- data = data.concat(getTarget(count, regionsList))
- }
- data = data.map(item => {
- const { targeting, id, createTime, updateTime, createBy, ...data } = item
- let age: { min: number, max: number }
- if (startAgeList.length || endAgeList.length) {
- if (Math.random() > 0.5 && startAgeList.length > 0) {
- age = { min: startAgeList.pop() as number, max: defaultEndAge }
- } else if (endAgeList.length > 0) {
- age = { min: defaultStartAge, max: endAgeList.pop() as number }
- } else {
- if (startAgeList.length > 0) {
- age = { min: startAgeList.pop() as number, max: defaultEndAge }
- } else {
- age = { min: defaultStartAge, max: endAgeList.pop() as number }
- }
- }
- data.targetingName = data.targetingName.replace('年龄', '')
- data.targetingName += `+年龄${age.min}岁至${age.max === 66 ? '66岁及以上' : age.max + '岁'}`
- let newTargeting = {
- ...targeting,
- age: [age]
- }
- return { ...data, targeting: newTargeting }
- }
- data.targetingName = '年龄不够数量分配,请删除'
- return { ...data, targeting }
- })
- onChange?.(data)
- }
- return <Modal
- title={<strong>一键生成定向配置</strong>}
- open={visible}
- className='modalResetCss'
- onCancel={onClose}
- bodyStyle={{ padding: '0 0 40px', position: 'relative', borderRadius: '0 0 8px 8px' }}
- footer={null}
- width={700}
- >
- <Form
- form={form}
- name="generateTarget"
- labelAlign='left'
- labelCol={{ span: 5 }}
- colon={false}
- style={{ backgroundColor: '#f1f4fc', maxHeight: 600, overflow: 'hidden', overflowY: 'auto', padding: '10px 10px 10px', borderRadius: '0 0 8px 8px' }}
- scrollToFirstError
- onFinishFailed={({ errorFields }) => {
- message.error(errorFields?.[0]?.errors?.[0])
- }}
- onFinish={handleOk}
- initialValues={{
- regions: 540000,
- defaultStartAge: 35,
- startAgeMin: 30,
- startAgeMax: 40,
- defaultEndAge: 66,
- endAgeMin: 50,
- endAgeMax: 66,
- count: 3
- }}
- >
- <Card
- title={<strong style={{ fontSize: 14 }}>生成设置</strong>}
- className="cardResetCss"
- >
- <Form.Item
- label={<strong>地域差异</strong>}
- name='regions'
- rules={[
- { required: true, message: '请选择' }
- ]}
- >
- <Select
- placeholder="请选择"
- showSearch
- filterOption={(input, option) =>
- ((option?.children ?? '') as any).toLowerCase().includes(input.toLowerCase())
- }
- >
- {REGION_DATA.map(item => <Select.Option value={item.value} key={item.key}>{item.title}</Select.Option>)}
- </Select>
- </Form.Item>
- <Form.Item
- label={<strong>年龄前段扩展区间</strong>}
- required
- help={<span style={{ color: 'red', fontSize: 12 }}>{`前段扩展的时候,后段固定年龄“${defaultEndAge === 66 ? '66岁及以上' : defaultEndAge + '岁'}”,可扩展${startAgeMin === 66 ? '66岁及以上' : `${startAgeMin}岁~${startAgeMax === 66 ? '66岁及以上' : startAgeMax + '岁'}`},可扩展数量${startAgeList.length}个`}</span>}
- >
- <Space>
- <Form.Item name={'defaultStartAge'} noStyle>
- <Select style={{ width: 138 }} placeholder="前段默认年龄">
- {START_AGE.map(i => {
- return <Select.Option disabled={i > defaultEndAge} value={i} key={i}>{i === 66 ? '66岁及以上' : i + ' 岁'}</Select.Option>
- })}
- </Select>
- </Form.Item>
- <Form.Item name={'startAgeMin'} noStyle>
- <Select style={{ width: 170 }} placeholder="请选择">
- {START_AGE.map(i => {
- return <Select.Option disabled={i > startAgeMax} value={i} key={i}>{i === 66 ? '66 岁及以上' : i + ' 岁'}</Select.Option>
- })}
- </Select>
- </Form.Item>
- <span>-</span>
- <Form.Item name={'startAgeMax'} noStyle>
- <Select style={{ width: 170 }} placeholder="请选择">
- {END_AGE.map((_, i) => {
- return <Select.Option disabled={(i + 18 < startAgeMin) || (i + 18 > defaultEndAge)} value={i + 18} key={i + 18}>{i + 18 === 66 ? '66 岁及以上' : i + 18 + ' 岁'}</Select.Option>
- })}
- </Select>
- </Form.Item>
- </Space>
- </Form.Item>
- <Form.Item
- label={<strong>年龄后段扩展区间</strong>}
- required
- help={<span style={{ color: 'red', fontSize: 12 }}>{`后段扩展的时候,前段固定年龄“${defaultStartAge === 66 ? '66岁及以上' : defaultStartAge + '岁'}”,可扩展${endAgeMin === 66 ? '66岁及以上' : `${endAgeMin}岁~${endAgeMax === 66 ? '66岁及以上' : endAgeMax + '岁'}`}, 可扩展数量${endAgeList.length}个`}</span>}
- >
- <Space>
- <Form.Item name={'defaultEndAge'} noStyle>
- <Select style={{ width: 138 }} placeholder="请选择">
- {END_AGE.map((_, i) => {
- return <Select.Option disabled={i + 18 < defaultStartAge} value={i + 18} key={i + 18}>{i + 18 === 66 ? '66 岁及以上' : i + 18 + ' 岁'}</Select.Option>
- })}
- </Select>
- </Form.Item>
- <Form.Item name={'endAgeMin'} noStyle>
- <Select style={{ width: 170 }} placeholder="请选择">
- {END_AGE.map((_, i) => {
- return <Select.Option disabled={(i > endAgeMax) || (i + 18 < defaultStartAge)} value={i + 18} key={i + 18}>{i + 18 === 66 ? '66 岁及以上' : i + 18 + ' 岁'}</Select.Option>
- })}
- </Select>
- </Form.Item>
- <span>-</span>
- <Form.Item name={'endAgeMax'} noStyle>
- <Select style={{ width: 170 }} placeholder="请选择">
- {END_AGE.map((_, i) => {
- return <Select.Option disabled={i + 18 < endAgeMin} value={i + 18} key={i + 18}>{i + 18 === 66 ? '66 岁及以上' : i + 18 + ' 岁'}</Select.Option>
- })}
- </Select>
- </Form.Item>
- </Space>
- </Form.Item>
- <Form.Item
- label={<strong>生成数量</strong>}
- name='count'
- rules={[
- { required: true, message: '请输入生成数量' }
- ]}
- >
- <InputNumber max={20} style={{ width: '100%' }} placeholder="请输入生成数量" />
- </Form.Item>
- </Card>
- <Form.Item className="submit_pull">
- <Space>
- <Button onClick={onClose}>取消</Button>
- <Button type="primary" htmlType="submit" className="modalResetCss">
- 确定
- </Button>
- </Space>
- </Form.Item>
- </Form>
- </Modal>
- }
- export default React.memo(GenerateTarget)
|