index.tsx 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. import HocError from '@/Hoc/HocError'
  2. import { Col, Modal, Row, Input, message, Space, Tabs, Button, Radio, Select } from 'antd'
  3. import React, { useCallback, useEffect, useState } from 'react'
  4. import { columnsMp } from './tableConfig'
  5. import { useAjax } from '@/Hook/useAjax'
  6. import { getAdAccountGameListApi, GetAdAccountParams, putAdAccountApi } from '@/services/launchAdq/adAuthorize'
  7. import style from './index.less'
  8. import TableData from '../../components/TableData'
  9. import GroupLeft from './groupLeft'
  10. import QQAuth from '../components/qqAuto'
  11. import { MenuFoldOutlined, MenuUnfoldOutlined, PlusOutlined, SwapOutlined } from '@ant-design/icons'
  12. import TeamMembers from '../../components/teamMembers'
  13. import { getAdAccountAllOfMemberGame, getErpUserAll, getServiceProviderAll, putConfigServiceProvider, putRefreshTokenApi } from '@/services/launchAdq/adq'
  14. import AddAccountToGroup from './addAccountToGroup'
  15. import { delAccountToGroupApi } from '@/services/launchAdq/subgroup'
  16. import { useModel } from 'umi'
  17. import ChangeRecord from './changeRecord'
  18. import CheckAccount from './checkAccount'
  19. import AppointPut from './appointPut'
  20. import SetEarlyWarningsAccount from '@/components/EarlyWarning/setEarlyWarningsAccount'
  21. /** 投放管理 */
  22. const AdAuthorize: React.FC = () => {
  23. let [visible, setVisible] = useState(false)
  24. let [newVisible, setNewVisible] = useState(false)
  25. /*************************/
  26. const { groupListInit } = useModel('useLaunchAdq.useAdAuthorize')
  27. const userInfo = useModel('@@initialState', model => model.initialState?.currentUser)
  28. const [queryForm, setQueryForm] = useState<GetAdAccountParams>({ pageNum: 1, pageSize: 20 })
  29. const [remarkData, set_remarkData] = useState<{ visible: boolean, remark: string, data: any }>({
  30. visible: false,
  31. remark: '',
  32. data: null
  33. })
  34. const [activeKey, setActiveKey] = useState<string>('1')
  35. const [showLeft, setShowLeft] = useState<boolean>(false)
  36. const [crShow, setCrShow] = useState<boolean>(false) // 变更记录控制
  37. const [crData, setCrData] = useState<{ name: number, id: number } | null>(null)
  38. const [checkAccShow, setCheckAccShow] = useState<boolean>(false)
  39. const [openServer, setOpenServer] = useState<any[]>([])//配置服务商数据
  40. const [serverName, setServerName] = useState<any>(null)//选择的服务商名称
  41. const [data, setData] = useState<{
  42. putResourceId?: number | undefined,
  43. beginTime?: string | undefined,
  44. gdtAccountId?: number,
  45. accountIds?: string,
  46. accountId?: string,
  47. gdtAccountIds?: string,
  48. advertiserId?: string,
  49. accountName?: string,
  50. account?: string,
  51. accountPassword?: string,
  52. quickAppAccountIds?: string
  53. resourceNames?: string
  54. } | undefined>(undefined)
  55. const [selectAccData, setSelectAccData] = useState<any[]>([])
  56. const [puShow, setPuShow] = useState<boolean>(false)
  57. const [puData, setPuData] = useState<any[]>([])
  58. const [switchType, setSwitchType] = useState<'account' | 'putUser' | 'setServer'>('account')
  59. const putRemark = useAjax((adAccountId: any, remark: any) => putAdAccountApi(adAccountId, remark))
  60. const delAccountToGroup = useAjax((params) => delAccountToGroupApi(params))
  61. const getAdAccountList = useAjax((params) => getAdAccountGameListApi(params), { formatResult: true })
  62. const allOfMemberGame = useAjax(() => getAdAccountAllOfMemberGame(), { formatResult: true })
  63. const erpUserALL = useAjax(() => getErpUserAll(), { formatResult: true })
  64. const api_getServiceProviderAll = useAjax(() => getServiceProviderAll(), { formatResult: true })
  65. const api_putConfigServiceProvider = useAjax((params) => putConfigServiceProvider(params), { formatResult: true })
  66. const putRefreshToken = useAjax((params) => putRefreshTokenApi(params), { formatResult: true })
  67. /*************************/
  68. useEffect(() => {
  69. groupListInit()
  70. !erpUserALL.data && erpUserALL.run()
  71. !api_getServiceProviderAll.data && api_getServiceProviderAll.run()
  72. }, [])
  73. useEffect(() => {
  74. getList()
  75. }, [queryForm])
  76. /** 获取账号列表 */
  77. const getList = () => {
  78. let params = JSON.parse(JSON.stringify(queryForm))
  79. if (params.accountIds) {
  80. params.accountIds = params.accountIds.split(/[\,\,]/)
  81. } else {
  82. delete params?.accountIds
  83. }
  84. getAdAccountList.run(params)
  85. }
  86. const remark = () => {
  87. if (remarkData.remark && remarkData.data) {
  88. putRemark.run(remarkData.data.accountId, remarkData.remark).then(res => {
  89. set_remarkData({ ...remarkData, visible: false, remark: '', data: null })
  90. getList()
  91. })
  92. } else {
  93. message.error('请输入备注!')
  94. }
  95. }
  96. const edit = useCallback((data) => {
  97. set_remarkData({ ...remarkData, visible: true, data, remark: data.remark })
  98. }, [remarkData])
  99. /** 移除分组里账号 */
  100. const del = (groupId: number, accountId: number) => {
  101. delAccountToGroup.run({ currGroupId: groupId, accountIds: [accountId] }).then(res => {
  102. message.success('移出成功')
  103. getAdAccountList.refresh()
  104. })
  105. }
  106. /** 切号 */
  107. const checkAccount = (value: any[]) => {
  108. let ids = value?.map((item: any) => item.id)
  109. setData({ resourceNames: value?.map((item: any) => item.putResourceName).toString(), accountIds: value?.map((item: any) => item.accountId).toString(), gdtAccountIds: ids.toString(), putResourceId: undefined, beginTime: undefined })
  110. setCheckAccShow(true);
  111. }
  112. /** 变更记录 */
  113. const changeRecord = (name: number, id: number) => {
  114. setCrData({ name, id })
  115. setCrShow(true)
  116. }
  117. /** 指派投手 */
  118. const putUserHandle = (data: any[]) => {
  119. setPuData(data)
  120. setPuShow(true)
  121. }
  122. // 批量配置服务商
  123. const setServiceProviderName = (accountIds: any) => {
  124. api_putConfigServiceProvider.run({ accountIds, serviceProviderName: serverName.label }).then(res => {
  125. if (res.data) {
  126. message.success("配置成功!")
  127. setOpenServer([]);
  128. setServerName(null)
  129. getAdAccountList.refresh()
  130. } else {
  131. message.error("配置失败!")
  132. }
  133. })
  134. }
  135. /** 刷新token */
  136. const handleRefreshToken = () => {
  137. putRefreshToken.run(selectAccData.map(item => item.accountId)).then(res => {
  138. console.log(res)
  139. if (res?.data?.length) {
  140. message.error(res.data.toString())
  141. } else {
  142. setSelectAccData([])
  143. message.success('刷新成功')
  144. }
  145. })
  146. }
  147. //
  148. return <div style={{ height: '100%' }}>
  149. <Tabs
  150. tabBarStyle={{ marginBottom: 1 }}
  151. activeKey={activeKey}
  152. type="card"
  153. // tabBarExtraContent={<Button type='primary' onClick={()=>setVisible(true)}><PlusOutlined />广告账号授权</Button>}
  154. onChange={(activeKey) => {
  155. if (activeKey !== 'contract') {
  156. let newQueryForm = JSON.parse(JSON.stringify(queryForm))
  157. delete newQueryForm?.groupId
  158. delete newQueryForm?.putUserId
  159. setQueryForm(newQueryForm)
  160. setActiveKey(activeKey)
  161. } else {
  162. setShowLeft(!showLeft)
  163. }
  164. }}
  165. >
  166. <Tabs.TabPane tab='我的' key='1' />
  167. <Tabs.TabPane tab='组员' key='2' />
  168. <Tabs.TabPane tab={showLeft ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />} key='contract' />
  169. </Tabs>
  170. <div className={style.manage}>
  171. {!showLeft && activeKey === '1' && <GroupLeft onChange={(groupId) => setQueryForm({ ...queryForm, groupId, pageNum: 1 })} value={queryForm?.groupId} />}
  172. {!showLeft && activeKey === '2' && <TeamMembers allOfMember={allOfMemberGame} onChange={(putUserId) => setQueryForm({ ...queryForm, putUserId, pageNum: 1 })} value={queryForm?.putUserId} />}
  173. <div className={style.manage__left} style={showLeft ? { width: '100%' } : { width: 'calc(100% - 200px)' }}>
  174. <TableData
  175. ajax={getAdAccountList}
  176. dataSource={getAdAccountList?.data?.data?.records}
  177. loading={getAdAccountList?.loading}
  178. columns={() => columnsMp(edit, setOpenServer, del, checkAccount, changeRecord, putUserHandle, () => getAdAccountList.refresh(), activeKey, userInfo?.userId?.toString(), queryForm?.groupId, getAdAccountList)}
  179. total={getAdAccountList?.data?.data?.total}
  180. page={getAdAccountList?.data?.data?.current}
  181. pageSize={getAdAccountList?.data?.data?.size}
  182. size="small"
  183. scroll={{ y: 600 }}
  184. leftChild={<Space wrap>
  185. <Select
  186. style={{ width: 120 }}
  187. placeholder="选择操作类型"
  188. onChange={(e) => {
  189. setSwitchType(e);
  190. setSelectAccData([])
  191. }}
  192. value={switchType}
  193. dropdownMatchSelectWidth={false}
  194. options={[{ label: '批量切号', value: 'account' }, { label: '批量指派投放助理', value: 'putUser' }, { label: '批量配置服务商', value: 'setServer' }]}
  195. />
  196. <Input.TextArea
  197. placeholder="多个广告账号以,隔开(id1,id2)"
  198. allowClear
  199. style={{ minWidth: 200 }}
  200. value={queryForm?.accountIds}
  201. rows={1}
  202. onChange={(e) => {
  203. setQueryForm({ ...queryForm, accountIds: e.target.value.replaceAll(/\s/ig, '') })
  204. }}
  205. />
  206. <Select
  207. style={{ width: 120 }}
  208. placeholder="是3.0账号?"
  209. allowClear
  210. onChange={(e) => {
  211. setQueryForm({ ...queryForm, addV3: e })
  212. }}
  213. value={queryForm?.addV3}
  214. options={[{ label: '是', value: true }, { label: '否', value: false }]}
  215. />
  216. <Select
  217. style={{ width: 120 }}
  218. placeholder="是业务单元?"
  219. allowClear
  220. onChange={(e) => {
  221. setQueryForm({ ...queryForm, adUnitAccount: e })
  222. }}
  223. value={queryForm?.adUnitAccount}
  224. options={[{ label: '是', value: true }, { label: '否', value: false }]}
  225. />
  226. <Button onClick={getList} type='primary' loading={getAdAccountList.loading}>搜索</Button>
  227. <AddAccountToGroup onChange={() => getAdAccountList.refresh()} />
  228. <Button type='primary' onClick={() => setVisible(true)}><PlusOutlined />广告账号授权</Button>
  229. <Button type='primary' onClick={() => setNewVisible(true)}><PlusOutlined />广告业务单元批量授权</Button>
  230. {switchType === 'account' ?
  231. (selectAccData?.length > 0 && <>
  232. <Button type="primary" ghost icon={<SwapOutlined />} onClick={() => { checkAccount(selectAccData) }}>批量切号</Button>
  233. <SetEarlyWarningsAccount onChange={() => { setSelectAccData([]); }} accountIds={selectAccData.map(item => item.accountId)?.toString()} />
  234. </>) :
  235. switchType === 'putUser' ? (selectAccData?.length > 0 && <Button type="primary" ghost icon={<SwapOutlined />} onClick={() => { putUserHandle(selectAccData) }}>批量指派投放助理</Button>) : switchType === 'setServer' ?
  236. selectAccData?.length > 0 && <Button type="primary" ghost icon={<SwapOutlined />} onClick={() => { setOpenServer(selectAccData) }}>批量配置服务商</Button> :
  237. selectAccData.length > 0 && <Button type="primary" ghost icon={<SwapOutlined />} loading={putRefreshToken.loading} onClick={() => { handleRefreshToken() }}>批量刷新TOKEN</Button>
  238. }
  239. </Space>}
  240. rowSelection={{
  241. selectedRowKeys: selectAccData?.map((item: any) => item.id?.toString()),
  242. getCheckboxProps: (record: any) => ({
  243. disabled: switchType === 'putUser' ? activeKey === '2' || userInfo?.userId !== record?.putUserInfo?.userId : false
  244. }),
  245. onSelect: (record: { id: number, mpName: string }, selected: boolean) => {
  246. if (selected) {
  247. selectAccData.push({ ...record })
  248. setSelectAccData([...selectAccData])
  249. } else {
  250. let newSelectAccData = selectAccData.filter((item: { id: number }) => item.id !== record.id)
  251. setSelectAccData([...newSelectAccData])
  252. }
  253. },
  254. onSelectAll: (selected: boolean, selectedRows: { id: number }[], changeRows: { id: number }[]) => {
  255. if (selected) {
  256. let newSelectAccData = [...selectAccData]
  257. changeRows.forEach((item: { id: number }) => {
  258. let index = newSelectAccData.findIndex((ite: { id: number }) => ite.id === item.id)
  259. if (index === -1) {
  260. newSelectAccData.push({ ...item })
  261. }
  262. })
  263. setSelectAccData([...newSelectAccData])
  264. } else {
  265. let newSelectAccData = selectAccData.filter((item: { id: number }) => {
  266. let index = changeRows.findIndex((ite: { id: number }) => ite.id === item.id)
  267. if (index !== -1) {
  268. return false
  269. } else {
  270. return true
  271. }
  272. })
  273. setSelectAccData([...newSelectAccData])
  274. }
  275. }
  276. }}
  277. onChange={(props: any) => {
  278. let { pagination } = props
  279. let { current, pageSize } = pagination
  280. setQueryForm({ ...queryForm, pageNum: current, pageSize })
  281. }}
  282. />
  283. </div>
  284. </div>
  285. {/* 批量设置服务商 */}
  286. {openServer.length > 0 && <Modal
  287. title="配置服务商"
  288. onOk={() => setServiceProviderName(openServer?.map(item => item.accountId))}
  289. onCancel={() => { setOpenServer([]); setServerName(null) }}
  290. visible={openServer.length > 0}
  291. confirmLoading={api_putConfigServiceProvider.loading}
  292. >
  293. <Row gutter={[20, 20]}>
  294. <Col span={24}>
  295. <Row>
  296. <Col span={3}><b>广告主:</b></Col>
  297. <Col span={21}>
  298. {openServer.map((item, index) => {
  299. return index === openServer.length - 1 ? item.accountId : item.accountId + ','
  300. })}
  301. </Col>
  302. </Row>
  303. </Col>
  304. <Col span={24}>
  305. <Row>
  306. <Col span={3}><b>服务商:</b></Col>
  307. <Col span={21}>
  308. <Select
  309. style={{ minWidth: 200 }}
  310. showSearch
  311. allowClear
  312. placeholder="请选择服务商"
  313. optionFilterProp="children"
  314. onChange={(value: any, option: any) => {
  315. setServerName(option)
  316. }}
  317. filterOption={(input, option: any) =>
  318. (option?.label ?? '').toLowerCase().includes(input.toLowerCase())
  319. }
  320. value={serverName}
  321. options={api_getServiceProviderAll?.data?.data?.map((item: { id: any, serviceProviderName: any }) => {
  322. return { value: item.id, label: item.serviceProviderName }
  323. })}
  324. />
  325. </Col>
  326. </Row>
  327. </Col>
  328. </Row>
  329. </Modal>}
  330. {/* 广告授权 */}
  331. {visible && <QQAuth qqVisible={visible} callBack={() => setVisible(false)} adAppType={1} title='游戏广告账号授权' isOld={true}/>}
  332. {/* 广告业务单元批量授权 */}
  333. {newVisible && <QQAuth qqVisible={newVisible} callBack={() => setNewVisible(false)} adAppType={1} smType={"WX"} title='游戏广告业务单元批量授权'/>}
  334. {/* 变更记录 */}
  335. {crShow && <ChangeRecord visible={crShow} data={crData} onClose={() => { setCrShow(false); setCrData(null) }} />}
  336. {/* 切号 */}
  337. {checkAccShow && <CheckAccount value={data} visible={checkAccShow} onChange={() => { getList(); setCheckAccShow(false); setSelectAccData([]) }} onClose={() => { setCheckAccShow(false) }} />}
  338. {/* 指派 */}
  339. {puShow && <AppointPut value={puData} visible={puShow} onClose={() => { setPuShow(false) }} allOfMember={erpUserALL} onChange={() => { setPuShow(false); getAdAccountList.refresh(); setSelectAccData([]) }} />}
  340. {remarkData.visible && <Modal
  341. visible={remarkData.visible}
  342. title='编辑账户'
  343. onCancel={() => { set_remarkData({ ...remarkData, visible: false, data: null }) }}
  344. onOk={remark}
  345. confirmLoading={putRemark.loading}
  346. >
  347. <Row gutter={[20, 20]}>
  348. <Col span={24} className={style.boxCol}><strong>广告主ID:</strong><span>{remarkData?.data.accountId}</span></Col>
  349. <Col span={24} className={style.boxCol}><strong>类型:</strong><span>{remarkData?.data.sourceType === 0 ? '微信' : 'QQ'}</span></Col>
  350. <Col span={24} className={style.boxCol}><strong>公众号信息:</strong><span>{remarkData?.data.wechatAccountName || '无'}</span></Col>
  351. <Col span={24} className={style.boxCol}><strong>企业名称:</strong><span>{remarkData?.data.corporationName || '无'}</span></Col>
  352. <Col span={24} className={style.boxCol}><strong>服务商ID列表:</strong><span>{remarkData?.data.agencyIdList ? remarkData.data.agencyIdList?.join() : '无'}</span></Col>
  353. <Col span={24} className={style.boxCol}><strong>行业ID:</strong><span>{remarkData?.data.systemIndustryId || '无'}</span></Col>
  354. <Col span={24} className={style.boxCol}><strong>授权状态:</strong><span>{remarkData?.data.authStatus || '无'}</span></Col>
  355. <Col span={24} className={style.boxCol}><strong>日限额(分):</strong><span>{remarkData?.data.dailyBudget || '无'}</span></Col>
  356. <Col span={24} className={style.boxCol}><strong>授权时间:</strong><span>{remarkData?.data.createTime || '无'}</span></Col>
  357. <Col span={24} className={style.boxCol}><strong>备注:</strong><span><Input.TextArea rows={5} maxLength={200} value={remarkData.remark} onChange={(e) => {
  358. let value = e.target.value
  359. set_remarkData({ ...remarkData, remark: value })
  360. }} /></span></Col>
  361. </Row>
  362. </Modal>}
  363. </div>
  364. }
  365. export default HocError(AdAuthorize)