index.tsx 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. import Selector from "@/pages/launchSystemNew/launchManage/createAd/selector"
  2. import React, { useEffect, useState } from "react"
  3. import style from './index.less'
  4. import { Button, Col, Form, Input, Row, Select, Space, Table, Tag, Tooltip, Typography } from "antd";
  5. import { CloseCircleFilled } from "@ant-design/icons";
  6. import { useAjax } from "@/Hook/useAjax";
  7. import { getUserAccountListApi } from "@/services/launchAdq/adAuthorize";
  8. import { arraysHaveSameValues } from "@/utils/utils";
  9. import '@/pages/launchSystemV3/tencentAdPutIn/index.less'
  10. const { Text } = Typography;
  11. interface Props {
  12. value?: number[]
  13. onChange?: (value?: number[] | number, data?: any[] | any) => void
  14. type?: 'checkbox' | 'radio'
  15. /** 是否第一次获取的时候返回值 */
  16. isReturnFirstValue?: boolean
  17. allowClear?: boolean
  18. }
  19. const SelectAdAccount: React.FC<Props> = ({ value, onChange, isReturnFirstValue, type = 'checkbox', allowClear = true }) => {
  20. value = value && typeof value !== 'object' ? [value] : value
  21. /***********************************/
  22. const [form] = Form.useForm()
  23. const [visible, setVisible] = useState<boolean>(false)
  24. const [selectedRows, setSelectedRows] = useState<any[]>([])
  25. const [queryForm, setQueryForm] = useState<{ accountIdList?: number[], adUnitTypeList?: string[], groupId?: number, remark?: string, putInType?: 'NOVEL' | 'GAME', sysGroupId?: number, pageNum: number, pageSize: number }>({ pageNum: 1, pageSize: 50 })
  26. const [isFirstReturn, setIsFirstReturn] = useState<boolean>(false)
  27. const getUserAccountList = useAjax((params) => getUserAccountListApi(params))
  28. /***********************************/
  29. const onFinish = (data: any) => {
  30. let oldQueryFrom = JSON.parse(JSON.stringify(queryForm))
  31. let params = { ...oldQueryFrom, ...data, pageNum: 1 }
  32. if (params?.accountIdList) {
  33. params.accountIdList = params?.accountIdList.split(/[,,\n\s]+/ig).filter((item: any) => item)
  34. } else {
  35. delete params?.accountIdList
  36. }
  37. setQueryForm(params)
  38. }
  39. useEffect(() => {
  40. if (visible) {
  41. setSelectedRows(value?.map(accountId => ({ accountId })) || [])
  42. }
  43. }, [value, visible])
  44. useEffect(() => {
  45. if (visible || isReturnFirstValue) {
  46. let params = { ...queryForm }
  47. if (queryForm?.putInType) {
  48. params.adUnitTypeList = queryForm?.putInType === 'NOVEL' ? ['NOVEL', 'NOVEL_IAA', 'SKIT_IAA'] : ['GAME', 'GAME_IAA']
  49. delete queryForm.putInType
  50. } else {
  51. delete params?.adUnitTypeList
  52. }
  53. getUserAccountList.run(params).then(res => {
  54. if (isReturnFirstValue && !isFirstReturn) {
  55. setIsFirstReturn(() => true)
  56. if (res?.records?.length) {
  57. onChange?.(res.records[0].accountId, res.records[0])
  58. }
  59. }
  60. })
  61. }
  62. }, [queryForm, visible, isFirstReturn])
  63. useEffect(() => {
  64. return () => {
  65. document.body.style.overflow = 'auto';
  66. }
  67. }, [])
  68. const handleCancel = () => {
  69. document.body.style.overflow = 'auto';
  70. setSelectedRows([])
  71. setVisible(false)
  72. }
  73. return <div className={style.selectAccount}>
  74. <div className={style.selectAccount_row} style={{ zIndex: visible ? 1000 : 1 }}>
  75. <Selector
  76. label={visible ? '选择账户' : '媒体账户'}
  77. style={visible ? { borderColor: '#1890ff' } : {}}
  78. titleStyle={visible ? { borderColor: '#1890ff', color: '#1890ff' } : {}}
  79. >
  80. <div
  81. className={style.selectAccount_select}
  82. onClick={() => {
  83. document.body.style.overflow = 'hidden';
  84. setVisible(true)
  85. }}
  86. >
  87. <div className={style.selectAccount_select_content}>
  88. {(visible && selectedRows.length > 0) ? <>
  89. <Tag
  90. closable={type === 'checkbox'}
  91. color="#F5F5F5"
  92. key={selectedRows[0].accountId}
  93. className={style.content_tag}
  94. onClose={() => {
  95. setSelectedRows(selectedRows.slice(1))
  96. }}
  97. >{selectedRows[0].accountId}</Tag>
  98. {selectedRows?.length > 1 && <Tooltip
  99. color="#FFF"
  100. title={<span style={{ color: '#000' }}>
  101. {selectedRows?.filter((_, index) => index !== 0)?.map((item) => <Tag
  102. color="#F5F5F5"
  103. className={style.content_tag}
  104. key={item.accountId}
  105. closable
  106. onClose={() => {
  107. setSelectedRows(selectedRows?.filter(item1 => item1.accountId !== item.accountId))
  108. }}
  109. >{item.accountId}</Tag>)}</span>
  110. }
  111. >
  112. <Tag color="#F5F5F5" className={style.content_tag}>+{selectedRows.length - 1}</Tag>
  113. </Tooltip>}
  114. </> : (!visible && value && value?.length > 0) ? <>
  115. <Tag
  116. closable={type === 'checkbox'}
  117. color="#F5F5F5"
  118. className={style.content_tag}
  119. key={value[0]}
  120. onClose={() => {
  121. onChange?.(value.slice(1))
  122. }}
  123. >{value[0]}</Tag>
  124. {value?.length > 1 && <Tooltip
  125. color="#FFF"
  126. title={<span style={{ color: '#000' }}>
  127. {value?.filter((_, index) => index !== 0)?.map((accountId) => <Tag
  128. className={style.content_tag}
  129. color="#F5F5F5"
  130. key={accountId}
  131. closable
  132. onClose={() => {
  133. onChange?.(value?.filter(accountId1 => accountId1 !== accountId))
  134. }}
  135. >{accountId}</Tag>)}</span>
  136. }
  137. >
  138. <Tag color="#F5F5F5" className={style.content_tag}>+{value.length - 1}</Tag>
  139. </Tooltip>}
  140. </> : <Text type="secondary">请选择媒体账户</Text>}
  141. </div>
  142. {visible}
  143. {((visible && selectedRows.length > 0) || (!visible && value && value?.length > 0)) && allowClear && <a className={style.clear} onClick={(e) => {
  144. e.stopPropagation()
  145. if (visible) {
  146. setSelectedRows([])
  147. } else {
  148. onChange?.(type === 'checkbox' ? [] : undefined, type === 'checkbox' ? [] : undefined)
  149. }
  150. }}><CloseCircleFilled /></a>}
  151. </div>
  152. </Selector>
  153. {visible && <div className={style.selectAccount_list}>
  154. <div className={style.selectAccount_list_header}>
  155. <Form layout="inline" className='queryForm' name="basicSelectAcc" form={form} onFinish={onFinish}>
  156. <Row gutter={[0, 6]}>
  157. <Col><Form.Item name={'putInType'}>
  158. <Select
  159. style={{ width: 160 }}
  160. placeholder="选择账户类型"
  161. allowClear
  162. filterOption={(input: any, option: any) => {
  163. return option!.children?.toString().toLowerCase().includes(input.toLowerCase())
  164. }}
  165. >
  166. <Select.Option value='NOVEL'>小说/短剧</Select.Option>
  167. <Select.Option value='GAME'>游戏</Select.Option>
  168. </Select>
  169. </Form.Item></Col>
  170. <Col><Form.Item name='accountIdList'>
  171. <Input.TextArea
  172. rows={1}
  173. autoSize={{ minRows: 1, maxRows: 1 }}
  174. placeholder="账户(多个,,空格换行)"
  175. style={{ width: 180 }}
  176. allowClear
  177. />
  178. </Form.Item></Col>
  179. <Col><Form.Item name='remark'>
  180. <Input
  181. placeholder="备注"
  182. style={{ width: 120 }}
  183. allowClear
  184. />
  185. </Form.Item></Col>
  186. <Col>
  187. <Space>
  188. <Button type="primary" htmlType="submit">搜索</Button>
  189. <Button onClick={() => form.resetFields()}>重置</Button>
  190. </Space>
  191. </Col>
  192. </Row>
  193. </Form>
  194. </div>
  195. <div className={style.selectAccount_list_table}>
  196. <Table
  197. size={'small'}
  198. bordered
  199. dataSource={getUserAccountList?.data?.records}
  200. rowKey={'accountId'}
  201. scroll={{ y: 220 }}
  202. pagination={{
  203. pageSize: getUserAccountList?.data?.size || 50,
  204. current: getUserAccountList?.data?.current || 1,
  205. showTotal: total => `总共 ${total} 账户`,
  206. total: getUserAccountList?.data?.total,
  207. showSizeChanger: true,
  208. showLessItems: true,
  209. defaultCurrent: 1,
  210. defaultPageSize: 50,//默认初始的每页条数
  211. onChange: (page, pageSize) => {
  212. setQueryForm({ ...queryForm, pageNum: page, pageSize })
  213. }
  214. }}
  215. loading={getUserAccountList.loading}
  216. columns={[
  217. {
  218. title: '账号',
  219. dataIndex: 'accountId',
  220. key: 'accountId',
  221. width: 80,
  222. align: 'center',
  223. render(value) {
  224. return <span style={{ fontSize: 12 }}>{value}</span>
  225. }
  226. },
  227. {
  228. title: '企业',
  229. dataIndex: 'corporationName',
  230. key: 'corporationName',
  231. width: 180,
  232. ellipsis: true,
  233. render(value) {
  234. return <span style={{ fontSize: 12 }}>{value || '--'}</span>
  235. }
  236. },
  237. {
  238. title: '企业标识',
  239. dataIndex: 'corporationLicence',
  240. key: 'corporationLicence',
  241. width: 150,
  242. ellipsis: true,
  243. render(value) {
  244. return <span style={{ fontSize: 12 }}>{value || '--'}</span>
  245. }
  246. },
  247. {
  248. title: '业务单元账号',
  249. dataIndex: 'adUnitAccountId',
  250. key: 'adUnitAccountId',
  251. width: 80,
  252. align: 'center',
  253. render(value) {
  254. return <span style={{ fontSize: 12 }}>{value || '--'}</span>
  255. }
  256. },
  257. {
  258. title: '是否业务单元账号',
  259. dataIndex: 'adUnitAccount',
  260. key: 'adUnitAccount',
  261. width: 80,
  262. align: 'center',
  263. render(value) {
  264. return <span style={{ fontSize: 12 }}>{value ? '是' : '否'}</span>
  265. }
  266. },
  267. {
  268. title: '备注',
  269. dataIndex: 'remark',
  270. key: 'remark',
  271. ellipsis: true,
  272. render(value) {
  273. return <span style={{ fontSize: 12 }}>{value || '--'}</span>
  274. }
  275. },
  276. ]}
  277. rowSelection={type === 'checkbox' ? {
  278. selectedRowKeys: selectedRows.map(item => item.accountId),
  279. type,
  280. onSelect: (record: { accountId: number }, selected: boolean) => {
  281. if (selected) {
  282. selectedRows.push({ ...record })
  283. setSelectedRows([...selectedRows])
  284. } else {
  285. let newSelectAccData = selectedRows.filter((item: { accountId: number }) => item.accountId !== record.accountId)
  286. setSelectedRows([...newSelectAccData])
  287. }
  288. },
  289. onSelectAll: (selected: boolean, selectedRowss: { accountId: number }[], changeRows: { accountId: number }[]) => {
  290. if (selected) {
  291. let newSelectAccData = [...selectedRows]
  292. changeRows.forEach((item: { accountId: number }) => {
  293. let index = newSelectAccData.findIndex((ite: { accountId: number }) => ite.accountId === item.accountId)
  294. if (index === -1) {
  295. let data: any = { ...item }
  296. newSelectAccData.push(data)
  297. }
  298. })
  299. setSelectedRows([...newSelectAccData])
  300. } else {
  301. let newSelectAccData = selectedRows.filter((item: { accountId: number }) => {
  302. let index = changeRows.findIndex((ite: { accountId: number }) => ite.accountId === item.accountId)
  303. if (index !== -1) {
  304. return false
  305. } else {
  306. return true
  307. }
  308. })
  309. setSelectedRows([...newSelectAccData])
  310. }
  311. }
  312. } : {
  313. selectedRowKeys: selectedRows.map(item => item.accountId),
  314. type,
  315. onChange(selectedRowKeys, selectedRows, info) {
  316. setSelectedRows(selectedRows)
  317. },
  318. }}
  319. />
  320. </div>
  321. <div className={style.selectAccount_list_footer}>
  322. <Button className={style.resetCss} onClick={handleCancel}>取消</Button>
  323. <Button
  324. className={style.resetCss}
  325. type="primary"
  326. style={{ marginLeft: 8 }}
  327. onClick={() => {
  328. if (value?.length && arraysHaveSameValues(value, selectedRows.map(item => item.accountId))) {
  329. handleCancel()
  330. return
  331. }
  332. document.body.style.overflow = 'auto';
  333. onChange?.(type === 'checkbox' ? selectedRows.map(item => item.accountId) : selectedRows?.[0]?.accountId, type === 'checkbox' ? selectedRows : selectedRows?.[0])
  334. setSelectedRows([])
  335. setVisible(false)
  336. }}
  337. >确定</Button>
  338. </div>
  339. </div>}
  340. </div>
  341. {visible && <div className={style.selectAccount_mask}></div>}
  342. </div>
  343. }
  344. export default React.memo(SelectAdAccount)