index.tsx 18 KB

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