modal.tsx 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620
  1. import React, { useCallback, useState, useEffect } from 'react'
  2. import { Modal, Form, Input, Divider, Select, Radio, Checkbox, TreeSelect } from 'antd'
  3. import { GenderEnum, EducationEnum, ExcludedDimensionEnum, MaritalStatusEnum, OptimizationGoalEnum, UserOsEnum, DevicePriceEnum, NetworkEnum, WechatAdBehaviorEnum } from '@/services/launchAdq/enum'
  4. import { ModalConfig } from '.'
  5. import { useAjax } from '@/Hook/useAjax'
  6. import { getTagsList } from '@/services/launchAdq/global'
  7. interface Props {
  8. title?: string,
  9. visible: boolean,
  10. PupFn: (arg: ModalConfig) => void,
  11. callback: (params: any) => void,
  12. confirmLoading: boolean,
  13. type?: 'add' | 'look' | 'edit',//新增,查看,编辑
  14. dataInfo?: any
  15. }
  16. const ios_os = Object.keys(UserOsEnum).filter(key => key.includes('IOS'))
  17. const android_os = Object.keys(UserOsEnum).filter(key => key.includes('ANDROID'))
  18. /**创意模板*/
  19. function AdModal(props: Props) {
  20. let { visible, confirmLoading, PupFn, callback, type, dataInfo } = props
  21. let arg = type === 'look' ? { footer: null } : {}
  22. const tagsList_REGION = useAjax((params) => getTagsList(params))
  23. const tagsList_MODEL = useAjax((params) => getTagsList(params))
  24. const [form] = Form.useForm();
  25. const [indeterminateIos, setIndeterminateIos] = useState(false);
  26. const [indeterminateAndroid, setIndeterminateAndroid] = useState(false);
  27. const [modelList, setModelList] = useState([])
  28. const [regionsList, setRegionsList] = useState<any[]>([])
  29. let educationType = Form.useWatch('educationType', form)
  30. let ageType = Form.useWatch('ageType', form)
  31. let age_min = Form.useWatch('age_min', form)
  32. let age_max = Form.useWatch('age_max', form)
  33. let maritalStatusType = Form.useWatch('maritalStatusType', form)
  34. let excludedDimension = Form.useWatch('excludedDimension', form)
  35. let userOsType = Form.useWatch('userOsType', form)
  36. let userOsIos = Form.useWatch('userOsIos', form)
  37. let userOsAndroid = Form.useWatch('userOsAndroid', form)
  38. let devicePriceType = Form.useWatch('devicePriceType', form)
  39. let networkType = Form.useWatch('networkType', form)
  40. let wechatAdBehaviorType = Form.useWatch('wechatAdBehaviorType', form)
  41. let actions = Form.useWatch('actions', form)
  42. let excludedActions = Form.useWatch('excludedActions', form)
  43. let deviceBrandModelType = Form.useWatch('deviceBrandModelType', form)
  44. let deviceBrandModelList = Form.useWatch('deviceBrandModelList', form)
  45. let geoLocationType = Form.useWatch('geoLocationType', form)
  46. // 确定事件
  47. const handleOk = useCallback(() => {
  48. form.validateFields().then(values => {
  49. let newValues = JSON.parse(JSON.stringify(values))
  50. newValues.targeting = {}
  51. Object.keys(newValues).forEach(key => {
  52. switch (key) {
  53. case 'geoLocationType':
  54. if (newValues[key] === '1') {
  55. newValues.targeting.geoLocation = {
  56. locationTypes: ['LIVE_IN'],//对于微信流量(site_set=SITE_SET_WECHAT、SITE_SET_MOMENTS、SITE_SET_MINI_GAME_WECHAT),仅能选择"LIVE_IN"(常住);
  57. regions: newValues.regions && newValues.regions[0] === 1156 ? regionsList[0]?.children?.filter((item: any) => !item.disabled)?.map((item: { value: any }) => item.value) : newValues.regions
  58. }
  59. }
  60. delete newValues[key]
  61. delete newValues.regions
  62. break;
  63. case 'ageType'://年龄处理
  64. if (newValues[key] === '1') {
  65. newValues.targeting.age = [{
  66. min: newValues.age_min,
  67. max: newValues.age_max
  68. }]
  69. }
  70. delete newValues[key]
  71. delete newValues.age_min
  72. delete newValues.age_max
  73. break;
  74. case 'gender'://性别
  75. newValues[key] !== '0' && (newValues.targeting.gender = [newValues[key]])
  76. delete newValues[key]
  77. break;
  78. case 'educationType'://学历
  79. newValues[key] === '1' && (newValues.targeting.education = newValues.education)
  80. delete newValues[key]
  81. delete newValues['education']
  82. break;
  83. case 'maritalStatusType'://婚恋
  84. newValues[key] === '1' && (newValues.targeting.maritalStatus = newValues.maritalStatus)
  85. delete newValues[key]
  86. delete newValues['maritalStatus']
  87. break;
  88. case 'customAudienceType'://定向人群
  89. break;
  90. case 'deviceBrandModelType'://品牌型号
  91. if (newValues[key] === '1') {
  92. newValues.targeting.deviceBrandModel = {}
  93. if (newValues.isexcluded) {
  94. newValues.targeting.deviceBrandModel.excludedList = newValues.deviceBrandModelList
  95. delete newValues.targeting.deviceBrandModel.includedList
  96. } else {
  97. newValues.targeting.deviceBrandModel.includedList = newValues.deviceBrandModelList
  98. delete newValues.targeting.deviceBrandModel.excludedList
  99. }
  100. if (!newValues.targeting.deviceBrandModel.excludedList && !newValues.targeting.deviceBrandModel.includedList) {
  101. delete newValues.targeting.deviceBrandModel
  102. }
  103. }
  104. delete newValues[key]
  105. delete newValues.deviceBrandModelList
  106. delete newValues.isexcluded
  107. break;
  108. case 'wechatAdBehaviorType'://微信再营销
  109. if (newValues[key] === '1') {
  110. newValues.targeting.wechatAdBehavior = {}
  111. if (newValues.actions) {
  112. newValues.targeting.wechatAdBehavior = { ...newValues.targeting.wechatAdBehavior, actions: newValues.actions }
  113. }
  114. if (newValues.excludedActions) {
  115. newValues.targeting.wechatAdBehavior = { ...newValues.targeting.wechatAdBehavior, excludedActions: newValues.excludedActions }
  116. }
  117. // 去除空值的参数
  118. Object.keys(newValues.targeting.wechatAdBehavior).forEach(key => {
  119. if (!newValues.targeting.wechatAdBehavior[key] || newValues.targeting.wechatAdBehavior[key]?.length === 0) {
  120. delete newValues.targeting.wechatAdBehavior[key]
  121. }
  122. })
  123. // 什么都没删除参数
  124. if (!newValues.targeting.wechatAdBehavior.actions && !newValues.targeting.wechatAdBehavior.excludedActions) {
  125. delete newValues.targeting.wechatAdBehavior
  126. }
  127. }
  128. delete newValues[key]
  129. delete newValues.actions
  130. delete newValues.excludedActions
  131. break;
  132. case 'networkType'://联网方式
  133. newValues[key] === '1' && (newValues.targeting.networkType = newValues.network)
  134. delete newValues[key]
  135. delete newValues.network
  136. break;
  137. case 'devicePriceType'://手机价格
  138. newValues[key] === '1' && (newValues.targeting.devicePrice = newValues.devicePrice)
  139. delete newValues[key]
  140. delete newValues.devicePrice
  141. break;
  142. case 'userOsType'://手机系统
  143. if (newValues[key] === '1') {
  144. newValues.targeting.userOs = []
  145. if (newValues.userOsIos) {
  146. newValues.targeting.userOs = [...newValues.targeting.userOs, ...newValues.userOsIos]
  147. }
  148. if (newValues.userOsAndroid) {
  149. newValues.targeting.userOs = [...newValues.targeting.userOs, ...newValues.userOsAndroid]
  150. }
  151. if (newValues.targeting.userOs.length === 0) {
  152. delete newValues.targeting.userOs
  153. }
  154. }
  155. delete newValues[key]
  156. delete newValues.userOsIosAll
  157. delete newValues.userOsAndroidAll
  158. delete newValues.userOsIos
  159. delete newValues.userOsAndroid
  160. break;
  161. case 'excludedDimension'://排除已转化用户
  162. if (newValues[key] !== '0') {
  163. newValues.targeting.excludedConvertedAudience = newValues.conversionBehaviorList ? {
  164. excludedDimension: newValues.excludedDimension,
  165. conversionBehaviorList: [newValues.conversionBehaviorList]
  166. } : {
  167. excludedDimension: newValues.excludedDimension,
  168. }
  169. }
  170. delete newValues[key]
  171. delete newValues.conversionBehaviorList
  172. break;
  173. }
  174. })
  175. // console.log(JSON.stringify(newValues))
  176. callback(newValues)
  177. })
  178. }, [form, regionsList])
  179. // 监听ios系统全选事件
  180. useEffect(() => {
  181. setIndeterminateIos(!!userOsIos?.length && userOsIos?.length < ios_os.length)
  182. form.setFieldsValue({ userOsIosAll: userOsIos?.length === ios_os.length })
  183. }, [userOsIos])
  184. // 监听android系统全选事件
  185. useEffect(() => {
  186. setIndeterminateAndroid(!!userOsAndroid?.length && userOsAndroid?.length < android_os.length)
  187. form.setFieldsValue({ userOsAndroidAll: userOsAndroid?.length === android_os.length })
  188. }, [userOsAndroid])
  189. // 获取定向标签
  190. useEffect(() => {
  191. // 获取地域
  192. tagsList_REGION.run({ type: 'REGION' }).then(res => {
  193. let arr: any = Object.values(res).filter(v => typeof v !== 'string')
  194. let parentList = arr.filter((item: { parentName: any }) => !item.parentName)
  195. let childrenList = arr.filter((item: { parentName: any }) => item.parentName)
  196. parentList = parentList.map((item: { name: any; id: any, parentId: any }) => {
  197. let children = childrenList?.filter((c: { parentId: any }) => {
  198. return item.id === c.parentId
  199. })
  200. let obj = {
  201. title: item.name,
  202. value: item.id,
  203. key: item.id,
  204. parentId: item.parentId,
  205. disabled: item.id === 710000 || item.id === 810000 || item.id === 820000,
  206. children: children.map((item: { name: any; id: any, parentId: any }) => ({
  207. title: item.name,
  208. value: item.id,
  209. key: item.id,
  210. parentId: item.parentId,
  211. disabled: item.parentId === 710000 || item.parentId === 810000 || item.parentId === 820000
  212. }))
  213. }
  214. return obj
  215. })
  216. parentList = parentList.map((item: any) => {
  217. let itemArr = item?.children?.map((c: any) => {
  218. let arr = childrenList.filter((d: { parentId: any }) => {
  219. return d.parentId === c.value
  220. })
  221. arr = arr.map((i: { name: any; id: any }) => ({
  222. title: i.name,
  223. value: i.id,
  224. key: i.id,
  225. }))
  226. return { ...c, children: arr }
  227. })
  228. return { ...item, children: itemArr }
  229. })
  230. let zg = parentList.filter((item: { title: string }) => item.title === '中国')
  231. let zg_children = parentList.filter((item: { title: string }) => (item.title !== '中国' && item.title !== '国外'))
  232. zg[0].children = zg_children
  233. setRegionsList(zg)
  234. })
  235. // 获取手机
  236. tagsList_MODEL.run({ type: 'DEVICE_BRAND_MODEL' }).then(res => {
  237. let arr: any = Object.values(res).filter(v => typeof v !== 'string')
  238. let parentList = arr.filter((item: { parentName: any }) => !item.parentName)
  239. let childrenList = arr.filter((item: { parentName: any }) => item.parentName)
  240. parentList = parentList.map((item: { name: any; id: any }) => {
  241. let children = childrenList?.filter((c: { parentId: any }) => {
  242. return item.id === c.parentId
  243. })
  244. let obj = {
  245. title: item.name,
  246. value: item.id,
  247. key: item.id,
  248. children: children.map((item: { name: any; id: any }) => ({
  249. title: item.name,
  250. value: item.id,
  251. key: item.id,
  252. }))
  253. }
  254. return obj
  255. })
  256. setModelList(parentList)
  257. })
  258. }, [])
  259. // 回填数据
  260. useEffect(() => {
  261. if (regionsList.length > 0 && dataInfo) {
  262. let newArr = regionsList[0]?.children?.filter((item: any) => !item.disabled)?.map((item: { value: any }) => item.value)//全选省列表
  263. let { description, targetingName, targeting } = dataInfo
  264. let { age, deviceBrandModel, devicePrice, education, excludedConvertedAudience, gender, geoLocation, maritalStatus, networkType, userOs, wechatAdBehavior } = targeting
  265. form.setFieldsValue({
  266. targetingName,//定向名称
  267. description,//定向描述
  268. geoLocationType: geoLocation?.regions ? '1' : '0',//地域选项
  269. regions: geoLocation?.regions && JSON.stringify(geoLocation?.regions) === JSON.stringify(newArr) ? [1156] : geoLocation?.regions,//地域回填
  270. ageType: age ? '1' : '0',//年龄选项
  271. age_min: age ? age[0].min : 14,//年龄
  272. age_max: age ? age[0].max : 66,//年龄
  273. gender: gender ? gender?.join() : '0',//性别
  274. educationType: education ? '1' : '0',//学历
  275. education,//学历
  276. maritalStatusType: maritalStatus ? '1' : '0',//婚恋
  277. maritalStatus,//婚恋
  278. excludedDimension: excludedConvertedAudience ? excludedConvertedAudience?.excludedDimension : '0',//排除已转化
  279. conversionBehaviorList: excludedConvertedAudience ? excludedConvertedAudience?.conversionBehaviorList[0] : undefined,//排除已转化
  280. deviceBrandModelType: deviceBrandModel ? '1' : '0',//设备品牌型号
  281. deviceBrandModelList: deviceBrandModel?.excludedList || deviceBrandModel?.includedList,//设备品牌型号
  282. isexcluded: deviceBrandModel && deviceBrandModel?.excludedList,//设备品牌型号
  283. userOsType:userOs?'1':'0',//操作系统
  284. userOsIos:userOs?.filter((os:string)=>os.includes('IOS')),//操作系统
  285. userOsAndroid:userOs?.filter((os:string)=>os.includes('ANDROID')),//操作系统
  286. networkType:networkType?'1':'0',//联网方式
  287. network:networkType,//联网方式
  288. devicePriceType:devicePrice?'1':'0',//设备价格
  289. devicePrice,//设备价格
  290. wechatAdBehaviorType:wechatAdBehavior?'1':'0',//微信再营销
  291. actions:wechatAdBehavior?.actions,//再营销
  292. excludedActions:wechatAdBehavior?.excludedActions,//排除再营销
  293. })
  294. }
  295. }, [regionsList, dataInfo])
  296. return <Modal
  297. visible={visible}
  298. title={type === 'add' ? '新建定向' : type === 'look' ? '定向详情' : '编辑定向'}
  299. onCancel={() => { PupFn({ visible: false ,dataInfo:null,type:'add'}) }}
  300. onOk={handleOk}
  301. width={900}
  302. confirmLoading={confirmLoading}
  303. {...arg}
  304. >
  305. <Form
  306. form={form}
  307. labelCol={{ span: 3 }}
  308. initialValues={
  309. {
  310. geoLocationType: '0',
  311. educationType: '0',
  312. ageType: '0',
  313. gender: '0',
  314. maritalStatusType: '0',
  315. age_min: 14,
  316. age_max: 66,
  317. targetingName: '',
  318. excludedDimension: '0',
  319. userOsType: '0',
  320. devicePriceType: '0',
  321. networkType: '0',
  322. wechatAdBehaviorType: '0',
  323. deviceBrandModelType: '0'
  324. }
  325. }
  326. >
  327. {/* ============================================================基本信息============================================================= */}
  328. <Divider orientation='left'><h3>基本信息</h3></Divider>
  329. {/* ====================定向名称========================= */}
  330. <Form.Item label={<strong>定向名称</strong>} name='targetingName' rules={[{ required: true, message: '请输入定向名称!' }]}>
  331. <Input placeholder='定向名称' style={{ width: 300 }} />
  332. </Form.Item>
  333. {/* ====================定向描述========================= */}
  334. <Form.Item label={<strong>定向描述</strong>} name='description' >
  335. <Input.TextArea placeholder='定向名称' style={{ width: 300 }} rows={2} />
  336. </Form.Item>
  337. {/* ============================================================排期与出价============================================================= */}
  338. <Divider orientation='left'>人口学数学</Divider>
  339. {/* ====================地理位置========================= */}
  340. <Form.Item label={<strong>地理位置</strong>} name='geoLocationType' style={geoLocationType === '1' ? { marginBottom: 5 } : {}}>
  341. <Radio.Group >
  342. <Radio.Button value="0">不限</Radio.Button>
  343. <Radio.Button value="1">按区域</Radio.Button>
  344. </Radio.Group>
  345. </Form.Item>
  346. {
  347. geoLocationType === '1' && <Form.Item
  348. style={{ marginLeft: 107, marginBottom: 10 }}
  349. name='regions'
  350. rules={[{ type: 'array', max: 1000, message: '最多选择1000' }]}
  351. >
  352. <TreeSelect
  353. showSearch={true}
  354. maxTagCount={50}
  355. treeCheckable={true}
  356. showCheckedStrategy={TreeSelect.SHOW_PARENT}
  357. treeData={regionsList}
  358. style={{ width: '100%' }}
  359. allowClear
  360. filterTreeNode={(inputValue: string, treeNode: any) => {
  361. if (treeNode.title.includes(inputValue)) {
  362. return true
  363. } else {
  364. return false
  365. }
  366. }}
  367. />
  368. </Form.Item>
  369. }
  370. {/* ====================年龄========================= */}
  371. <Form.Item label={<strong>年龄</strong>} name='ageType' style={ageType === '1' ? { marginBottom: 5 } : {}}>
  372. <Radio.Group >
  373. <Radio.Button value="0">不限</Radio.Button>
  374. <Radio.Button value="1">自定义</Radio.Button>
  375. </Radio.Group>
  376. </Form.Item>
  377. {
  378. ageType === '1' && <div style={{ display: 'flex', justifyContent: 'left', alignItems: 'center' }}>
  379. <Form.Item style={{ marginLeft: 107 }} name='age_min'>
  380. <Select style={{ width: 120 }} >
  381. {
  382. Array(66 - 13).fill('').map((n, i) => i + 14).filter(i => i !== 15 && i !== 16 && i !== 17).map(i => {
  383. return <Select.Option disabled={i > age_max} value={i} key={i}>{i === 66 ? '66 岁及以上' : i + ' 岁'}</Select.Option>
  384. })
  385. }
  386. </Select>
  387. </Form.Item>
  388. <Form.Item style={{ marginLeft: 10 }} name='age_max'>
  389. <Select style={{ width: 120 }}>
  390. {
  391. Array(66 - 17).fill('').map((n, i) => {
  392. return <Select.Option disabled={i + 18 < age_min} value={i + 18} key={i + 18}>{i + 18 === 66 ? '66 岁及以上' : i + 18 + ' 岁'}</Select.Option>
  393. })
  394. }
  395. </Select>
  396. </Form.Item>
  397. </div>
  398. }
  399. {/* ====================性别========================= */}
  400. <Form.Item label={<strong>性别</strong>} name='gender'>
  401. <Radio.Group >
  402. <Radio.Button value="0">不限</Radio.Button>
  403. {
  404. Object.keys(GenderEnum).map(key => {
  405. return <Radio.Button value={key} key={key}>{GenderEnum[key]}</Radio.Button>
  406. })
  407. }
  408. </Radio.Group>
  409. </Form.Item>
  410. {/* ====================学历========================= */}
  411. <Form.Item label={<strong>学历</strong>} name='educationType' style={educationType === '1' ? { marginBottom: 5 } : {}}>
  412. <Radio.Group >
  413. <Radio.Button value="0">不限</Radio.Button>
  414. <Radio.Button value="1">自定义</Radio.Button>
  415. </Radio.Group>
  416. </Form.Item>
  417. {
  418. educationType === '1' && <Form.Item style={{ marginLeft: 107 }} name='education'>
  419. <Checkbox.Group options={Object.keys(EducationEnum).map(key => ({ label: EducationEnum[key], value: key }))} />
  420. </Form.Item>
  421. }
  422. {/* ====================婚恋育儿状态========================= */}
  423. <Form.Item label={<strong>婚恋育儿状态</strong>} name='maritalStatusType' style={maritalStatusType === '1' ? { marginBottom: 5 } : {}}>
  424. <Radio.Group >
  425. <Radio.Button value="0">不限</Radio.Button>
  426. <Radio.Button value="1">自定义</Radio.Button>
  427. </Radio.Group>
  428. </Form.Item>
  429. {
  430. maritalStatusType === '1' && <Form.Item style={{ marginLeft: 107 }} name='maritalStatus'>
  431. <Checkbox.Group options={Object.keys(MaritalStatusEnum).map(key => ({ label: MaritalStatusEnum[key], value: key }))} />
  432. </Form.Item>
  433. }
  434. {/* ============================================================用户行为============================================================= */}
  435. <Divider orientation='left'>用户行为</Divider>
  436. {/* <Form.Item label={<strong>行为兴趣意向</strong>} name='behaviorOrInterestType'>
  437. <Radio.Group >
  438. <Radio.Button value="0">不限</Radio.Button>
  439. <Radio.Button value="1">自定义</Radio.Button>
  440. </Radio.Group>
  441. </Form.Item> */}
  442. {/* ====================排除已转化用户========================= */}
  443. <Form.Item label={<strong>排除已转化用户</strong>} name='excludedDimension' style={excludedDimension !== '0' ? { marginBottom: 5 } : {}}>
  444. <Radio.Group >
  445. <Radio.Button value="0">不限</Radio.Button>
  446. {
  447. Object.keys(ExcludedDimensionEnum).map(key => {
  448. return <Radio.Button value={key} key={key}>{ExcludedDimensionEnum[key]}</Radio.Button>
  449. })
  450. }
  451. </Radio.Group>
  452. </Form.Item>
  453. {
  454. excludedDimension !== '0' && <Form.Item style={{ marginLeft: 107 }} name='conversionBehaviorList'>
  455. <Select style={{ width: 300 }} showSearch filterOption={(input, option) =>
  456. (option!.children as unknown as string).toLowerCase().includes(input.toLowerCase())
  457. } allowClear placeholder='转化行为,不选为默认行为'>
  458. {
  459. Object.keys(OptimizationGoalEnum).map(key => {
  460. return <Select.Option value={key} key={key}>{OptimizationGoalEnum[key]}</Select.Option>
  461. })
  462. }
  463. </Select>
  464. </Form.Item>
  465. }
  466. {/* ============================================================自定义人群============================================================= */}
  467. {/* <Divider orientation='left'>自定义人群</Divider> */}
  468. {/* ====================自定义人群========================= */}
  469. {/* <Form.Item label={<strong>自定义人群</strong>} name='customAudienceType'>
  470. <Radio.Group >
  471. <Radio.Button value="0">不限</Radio.Button>
  472. <Radio.Button value="1">自定义</Radio.Button>
  473. </Radio.Group>
  474. </Form.Item> */}
  475. {/* ============================================================设备定向============================================================= */}
  476. <Divider orientation='left'>设备定向</Divider>
  477. {/* ====================设备品牌型号========================= */}
  478. <Form.Item label={<strong>设备品牌型号</strong>} name='deviceBrandModelType' style={deviceBrandModelType === '1' ? { marginBottom: 5 } : {}}>
  479. <Radio.Group >
  480. <Radio.Button value="0">不限</Radio.Button>
  481. <Radio.Button value="1">自定义</Radio.Button>
  482. </Radio.Group>
  483. </Form.Item>
  484. {
  485. deviceBrandModelType === '1' && <>
  486. <Form.Item style={{ marginLeft: 107, marginBottom: 10 }}
  487. name='deviceBrandModelList'
  488. rules={[{ type: 'array', max: 400, message: '最多选择400个设备型号' }]}
  489. >
  490. <TreeSelect
  491. showSearch={true}
  492. maxTagCount={50}
  493. treeCheckable={true}
  494. showCheckedStrategy={TreeSelect.SHOW_CHILD}
  495. treeData={modelList}
  496. style={{ width: '100%' }}
  497. allowClear
  498. filterTreeNode={(inputValue: string, treeNode: any) => {
  499. if (treeNode.title.includes(inputValue)) {
  500. return true
  501. } else {
  502. return false
  503. }
  504. }}
  505. />
  506. </Form.Item>
  507. <Form.Item name='isexcluded' valuePropName="checked" style={{ marginLeft: 107, marginBottom: 10 }} >
  508. <Checkbox ><p style={{
  509. position: 'absolute',
  510. width: '95%',
  511. top: '50%',
  512. transform: 'translate(0, -50%)'
  513. }}>排除所选设备的用户 <span style={{ float: 'right' }}>已选 <span style={deviceBrandModelList?.length > 400 ? { color: 'red' } : {}}>{deviceBrandModelList?.length ?? 0}</span>/400</span></p></Checkbox>
  514. </Form.Item>
  515. </>
  516. }
  517. {/* ====================操作系统版本========================= */}
  518. <Form.Item label={<strong>操作系统版本</strong>} name='userOsType' style={userOsType === '1' ? { marginBottom: 5 } : {}}>
  519. <Radio.Group >
  520. <Radio.Button value="0">不限</Radio.Button>
  521. <Radio.Button value="1">自定义</Radio.Button>
  522. </Radio.Group>
  523. </Form.Item>
  524. {
  525. userOsType === '1' && <>
  526. <Form.Item style={{ marginLeft: 107, marginBottom: 0 }} name='userOsIosAll' valuePropName="checked" getValueFromEvent={(e) => {
  527. let checked = e.target.checked
  528. form.setFieldsValue({ userOsIos: checked ? ios_os : [] })
  529. setIndeterminateIos(false)
  530. }}>
  531. <Checkbox indeterminate={indeterminateIos} >
  532. IOS全选
  533. </Checkbox>
  534. </Form.Item>
  535. <Form.Item style={{ marginLeft: 107 }} name='userOsIos' >
  536. <Checkbox.Group
  537. options={
  538. ios_os.map(key => {
  539. return { label: UserOsEnum[key], value: key }
  540. })
  541. }
  542. />
  543. </Form.Item>
  544. <Form.Item style={{ marginLeft: 107, marginBottom: 0 }} name='userOsAndroidAll' valuePropName="checked" getValueFromEvent={(e) => {
  545. let checked = e.target.checked
  546. form.setFieldsValue({ userOsAndroid: checked ? android_os : [] })
  547. setIndeterminateAndroid(false)
  548. }}>
  549. <Checkbox indeterminate={indeterminateAndroid}>
  550. Android全选
  551. </Checkbox>
  552. </Form.Item>
  553. <Form.Item style={{ marginLeft: 107 }} name='userOsAndroid'>
  554. <Checkbox.Group
  555. options={
  556. android_os.map(key => {
  557. return { label: UserOsEnum[key], value: key }
  558. })
  559. }
  560. />
  561. </Form.Item>
  562. </>
  563. }
  564. {/* ====================联网方式========================= */}
  565. <Form.Item label={<strong>联网方式</strong>} name='networkType' style={networkType === '1' ? { marginBottom: 5 } : {}}>
  566. <Radio.Group >
  567. <Radio.Button value="0">不限</Radio.Button>
  568. <Radio.Button value="1">自定义</Radio.Button>
  569. </Radio.Group>
  570. </Form.Item>
  571. {
  572. networkType === '1' && <Form.Item style={{ marginLeft: 107 }} name='network'>
  573. <Checkbox.Group options={Object.keys(NetworkEnum).map(key => ({ label: NetworkEnum[key], value: key }))} />
  574. </Form.Item>
  575. }
  576. {/* ====================设备价格========================= */}
  577. <Form.Item label={<strong>设备价格</strong>} name='devicePriceType' style={devicePriceType === '1' ? { marginBottom: 5 } : {}}>
  578. <Radio.Group >
  579. <Radio.Button value="0">不限</Radio.Button>
  580. <Radio.Button value="1">自定义</Radio.Button>
  581. </Radio.Group>
  582. </Form.Item>
  583. {
  584. devicePriceType === '1' && <Form.Item style={{ marginLeft: 107 }} name='devicePrice'>
  585. <Checkbox.Group options={Object.keys(DevicePriceEnum).map(key => ({ label: DevicePriceEnum[key], value: key }))} />
  586. </Form.Item>
  587. }
  588. {/* ============================================================流量方数学============================================================= */}
  589. <Divider orientation='left'>流量方数学</Divider>
  590. {/* ====================微信再营销========================= */}
  591. <Form.Item label={<strong>微信再营销</strong>} name='wechatAdBehaviorType' style={wechatAdBehaviorType === '1' ? { marginBottom: 5 } : {}}>
  592. <Radio.Group >
  593. <Radio.Button value="0">不限</Radio.Button>
  594. <Radio.Button value="1">自定义</Radio.Button>
  595. </Radio.Group>
  596. </Form.Item>
  597. {
  598. wechatAdBehaviorType === '1' && <>
  599. <p style={{ marginBottom: 5, marginLeft: 107 }}><strong style={{ marginRight: 20 }}>再营销</strong></p>
  600. <Form.Item style={{ marginLeft: 107, marginBottom: 10 }} name='actions'>
  601. <Checkbox.Group options={Object.keys(WechatAdBehaviorEnum).map(key => ({ label: WechatAdBehaviorEnum[key], value: key, disabled: excludedActions?.some((k: string) => k === key) }))} />
  602. </Form.Item>
  603. <p style={{ marginBottom: 5, marginLeft: 107 }}><strong style={{ marginRight: 20 }}>排除营销</strong></p>
  604. <Form.Item style={{ marginLeft: 107 }} name='excludedActions'>
  605. <Checkbox.Group options={Object.keys(WechatAdBehaviorEnum).map(key => ({ label: WechatAdBehaviorEnum[key], value: key, disabled: actions?.some((k: string) => k === key) }))} />
  606. </Form.Item>
  607. </>
  608. }
  609. </Form>
  610. </Modal >
  611. }
  612. export default AdModal