index.tsx 20 KB

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