index.tsx 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. import { useAjax } from "@/Hook/useAjax"
  2. import { CheckOutlined, CloseOutlined, QuestionCircleOutlined, SyncOutlined } from "@ant-design/icons"
  3. import { Button, Input, message, Modal, Space, Table, Tooltip, Typography } from "antd"
  4. import React, { useEffect, useState } from "react"
  5. import style from './index.less'
  6. import columns from './tableConfig'
  7. import { getByRemotemarketingAssetContentApi } from "@/services/adqV3/global"
  8. import { MARKETING_TARGET_TYPE_ENUM } from "../../tencentAdPutIn/const"
  9. const { Title, Text } = Typography;
  10. /**
  11. * 获取商品列表
  12. * @returns
  13. */
  14. interface Props {
  15. marketingTargetType: MARKETING_TARGET_TYPE_ENUM,
  16. visible?: boolean,
  17. onClose?: () => void,
  18. onChange?: (data: PULLIN.AccountCreateLogsProps[]) => void,
  19. data: PULLIN.AccountCreateLogsProps[]
  20. }
  21. const GoodsModal: React.FC<Props> = (props) => {
  22. /************************/
  23. const { marketingTargetType, visible, onClose, data: data1, onChange } = props
  24. const [selectAdz, setSelectAdz] = useState<number>(1) // 选择广告主
  25. const [data, setData] = useState<PULLIN.AccountCreateLogsProps[]>(data1)
  26. const [queryForm, setQueryForm] = useState<{
  27. marketingAssetType?: string,
  28. marketingAssetName?: string,
  29. pageNum: number,
  30. pageSize: number,
  31. accountId?: number
  32. }>({ pageNum: 1, pageSize: 10 })
  33. const getByRemotemarketingAssetContent = useAjax((params) => getByRemotemarketingAssetContentApi(params))
  34. // const synMarketingAssetContent = useAjax((params) => synMarketingAssetContentApi(params))
  35. /************************/
  36. useEffect(() => {
  37. if (data?.length > 0) {
  38. getList({ accountId: data[selectAdz - 1].accountId, pageNum: 1, pageSize: 10 })
  39. } else {
  40. getByRemotemarketingAssetContent.data && getByRemotemarketingAssetContent.mutate({ records: [] })
  41. }
  42. }, [selectAdz])
  43. // 获取商品列表
  44. const getList = (data: {
  45. marketingAssetType?: string,
  46. marketingAssetName?: string,
  47. pageNum: number,
  48. pageSize: number,
  49. accountId?: number
  50. }) => {
  51. setQueryForm(data)
  52. getByRemotemarketingAssetContent.run({ ...data, marketingAssetType: marketingTargetType })
  53. }
  54. const handleOk = () => {
  55. if (data.every(item => item?.productList?.length)) {
  56. onChange && onChange(data)
  57. } else {
  58. message.error('请完善所有账号产品')
  59. }
  60. }
  61. // 同步小说
  62. // const synGoodsList = () => {
  63. // synMarketingAssetContent.run({ accountId: data[selectAdz - 1].accountId }).then(res => {
  64. // if (res) {
  65. // message.success('同步成功,结果可能几分钟后展示,请勿重复点击同步')
  66. // }
  67. // })
  68. // }
  69. /** 设置选中广告主 */
  70. const handleSelectAdz = (value: number) => {
  71. if (value === selectAdz) {
  72. return
  73. }
  74. setSelectAdz(value)
  75. }
  76. /** 表格选折 */
  77. const onChangeTable = (_: React.Key[], selectedRows: any) => {
  78. let newData = JSON.parse(JSON.stringify(data))
  79. newData[selectAdz - 1]['productList'] = selectedRows
  80. setData([...newData])
  81. }
  82. // 清空已选
  83. const clearGoods = () => {
  84. let newData = JSON.parse(JSON.stringify(data))
  85. newData[selectAdz - 1]['productList'] = []
  86. setData([...newData])
  87. }
  88. /** 一键设置 */
  89. const setOnekey = () => {
  90. let marketingIdList: number[] = data[selectAdz - 1]['productList']?.map((item: { marketingAssetId: number }) => item.marketingAssetId) || []
  91. let newData: PULLIN.AccountCreateLogsProps[] = JSON.parse(JSON.stringify(data))
  92. const hide = message.loading(`正在设置...`, 0, () => {
  93. message.success('设置成功');
  94. });
  95. let dataAjax = newData?.filter(item => item.accountId !== data[selectAdz - 1].accountId)?.map(item => item?.accountId).map(accountId => {
  96. return getByRemotemarketingAssetContentApi({ pageNum: 1, pageSize: 10, accountId: accountId, marketingIdList })
  97. })
  98. Promise.all(dataAjax).then(res => {
  99. if (res?.length > 0) {
  100. res.forEach(ajax => {
  101. let data = ajax.data?.records
  102. if (data?.length > 0) {
  103. let accountId = data[0].accountId
  104. newData = newData.map(item => {
  105. if (item.accountId.toString() === accountId.toString()) {
  106. return { ...item, productList: ajax.data?.records }
  107. }
  108. return item
  109. })
  110. }
  111. })
  112. }
  113. setData(newData)
  114. message.success('设置完成');
  115. hide()
  116. }).catch(() => {
  117. hide()
  118. message.error('设置失败')
  119. })
  120. }
  121. return <Modal
  122. title={<Space>
  123. <strong>产品库</strong>
  124. {/* <Button size="small" style={{ padding: 0 }} onClick={() => { synGoodsList() }} type="link" loading={synMarketingAssetContent?.loading}>同步小说</Button> */}
  125. </Space>}
  126. open={visible}
  127. onCancel={() => { onClose && onClose() }}
  128. onOk={handleOk}
  129. width={1000}
  130. className={`${style.SelectPackage} modalResetCss`}
  131. bodyStyle={{ padding: '0 10px 0 10px' }}
  132. >
  133. <div className={style.content}>
  134. <div className={style.left}>
  135. <h4 className={style.title}>媒体账户</h4>
  136. <div className={style.accountIdList}>
  137. {data?.map((item, index) => {
  138. let productList = data[index].productList || []
  139. return <div key={index} onClick={() => { handleSelectAdz(index + 1) }} className={`${style.accItem} ${selectAdz === index + 1 && style.select} `}>
  140. {item?.accountId}
  141. {productList?.length > 0 && <CheckOutlined style={{ color: '#1890ff' }} />}
  142. </div>
  143. })}
  144. </div>
  145. </div>
  146. <div className={style.right}>
  147. <Space style={{ marginBottom: 10 }} align="end" size={0}>
  148. <Input.Search enterButton allowClear placeholder="请输入商品名称" onSearch={(value) => getList({ ...queryForm, marketingAssetName: value, pageNum: 1 })} />
  149. <Button icon={<SyncOutlined />} type='link' loading={getByRemotemarketingAssetContent?.loading} onClick={() => { getList({ ...queryForm, accountId: data[selectAdz - 1].accountId }) }}>刷新</Button>
  150. {data?.length > 1 && <Button disabled={!data[selectAdz - 1]['productList']?.length} onClick={setOnekey} type="link" loading={getByRemotemarketingAssetContent.loading}>
  151. <Space>
  152. <span>一键设置</span>
  153. <Tooltip color="#FFF" overlayInnerStyle={{ color: '#000' }} title="设置其它账号有相同产品Id为那个账号的产品(注意需要产品Id相同,否则不设置)">
  154. <QuestionCircleOutlined />
  155. </Tooltip>
  156. </Space>
  157. </Button>}
  158. {(data[selectAdz - 1]?.productList || [])?.length > 0 && <Button type='link' onClick={() => { clearGoods() }}>清空</Button>}
  159. </Space>
  160. <Table
  161. columns={columns()}
  162. dataSource={getByRemotemarketingAssetContent.data?.records}
  163. size="small"
  164. loading={getByRemotemarketingAssetContent?.loading}
  165. scroll={{ y: 400 }}
  166. bordered
  167. pagination={{
  168. defaultPageSize: 100,
  169. current: getByRemotemarketingAssetContent.data?.current || 1,
  170. pageSize: getByRemotemarketingAssetContent.data?.size || 10,
  171. total: getByRemotemarketingAssetContent.data?.total || 0
  172. }}
  173. rowKey={'marketingAssetId'}
  174. rowSelection={{
  175. getCheckboxProps(record) {
  176. let length = data[selectAdz - 1]?.productList?.length || 0
  177. return {
  178. disabled: length >= 10 && data[selectAdz - 1]?.productList?.every((item: any) => item?.marketingAssetId !== record?.marketingAssetId)
  179. }
  180. },
  181. type: 'checkbox',
  182. selectedRowKeys: data[selectAdz - 1]?.productList?.map((item: any) => item?.marketingAssetId),
  183. onChange: onChangeTable
  184. }}
  185. onChange={(pagination) => {
  186. const { current, pageSize } = pagination
  187. getList({ ...queryForm, pageNum: current || 1, pageSize: pageSize || 10 })
  188. }}
  189. />
  190. </div>
  191. <div className={style.center}>
  192. <Title level={5}>已选:{data[selectAdz - 1]?.productList?.length || 0}/10</Title>
  193. <div className={style.select_content}>
  194. {data[selectAdz - 1]?.productList?.map(item => <div key={item.marketingAssetId}>
  195. <Text ellipsis={{ tooltip: true }} className={style.marketingAssetName}>{item.marketingAssetName}</Text>
  196. <CloseOutlined className={style.close} onClick={() => {
  197. let newData: PULLIN.AccountCreateLogsProps[] = JSON.parse(JSON.stringify(data))
  198. newData[selectAdz - 1].productList = newData[selectAdz - 1]?.productList?.filter((i: any) => i?.marketingAssetId !== item.marketingAssetId)
  199. setData(newData)
  200. }} />
  201. </div>)}
  202. </div>
  203. </div>
  204. </div>
  205. </Modal>
  206. }
  207. export default React.memo(GoodsModal)