Просмотр исходного кода

Merge branch 'develop' of http://git.zanxiangnet.com/wjx/ad-manage

wjx 1 год назад
Родитель
Сommit
95e7790edf
34 измененных файлов с 1639 добавлено и 225 удалено
  1. 14 1
      config/routerConfig.ts
  2. 3 2
      src/models/useAdMonitor/useMonitor.ts
  3. 2 2
      src/pages/launchSystemNew/account/game/addAccountToGroup.tsx
  4. 0 0
      src/pages/launchSystemNew/account/game/appointPut.tsx
  5. 0 0
      src/pages/launchSystemNew/account/game/changeRecord.tsx
  6. 0 0
      src/pages/launchSystemNew/account/game/checkAccount.tsx
  7. 0 0
      src/pages/launchSystemNew/account/game/divideIntoGroups.tsx
  8. 0 0
      src/pages/launchSystemNew/account/game/groupLeft.tsx
  9. 0 0
      src/pages/launchSystemNew/account/game/index.less
  10. 337 0
      src/pages/launchSystemNew/account/game/index.tsx
  11. 161 0
      src/pages/launchSystemNew/account/game/qqAuto.tsx
  12. 0 0
      src/pages/launchSystemNew/account/game/tableConfig.tsx
  13. 0 0
      src/pages/launchSystemNew/account/game/tablesConfig.tsx
  14. 104 0
      src/pages/launchSystemNew/account/novel/addAccountToGroup.tsx
  15. 93 0
      src/pages/launchSystemNew/account/novel/appointPut.tsx
  16. 127 0
      src/pages/launchSystemNew/account/novel/changeRecord.tsx
  17. 69 0
      src/pages/launchSystemNew/account/novel/checkAccount.tsx
  18. 71 0
      src/pages/launchSystemNew/account/novel/divideIntoGroups.tsx
  19. 156 0
      src/pages/launchSystemNew/account/novel/groupLeft.tsx
  20. 162 0
      src/pages/launchSystemNew/account/novel/index.less
  21. 2 2
      src/pages/launchSystemNew/account/novel/index.tsx
  22. 1 1
      src/pages/launchSystemNew/account/novel/qqAuto.tsx
  23. 222 0
      src/pages/launchSystemNew/account/novel/tableConfig.tsx
  24. 78 0
      src/pages/launchSystemNew/account/novel/tablesConfig.tsx
  25. 3 2
      src/pages/launchSystemNew/adq/ad/adIdSearch.tsx
  26. 0 7
      src/pages/launchSystemNew/adq/ad/index.tsx
  27. 0 108
      src/pages/launchSystemNew/adq/adAccount/index.tsx
  28. 0 74
      src/pages/launchSystemNew/adq/adAccount/tableConfig.tsx
  29. 1 3
      src/pages/launchSystemNew/adq/index.tsx
  30. 2 2
      src/pages/toutiao/ttAccountManage/index.tsx
  31. 0 11
      src/services/adMonitor/adMonitor.ts
  32. 9 2
      src/services/launchAdq/adAuthorize.ts
  33. 22 3
      src/services/launchAdq/adq.ts
  34. 0 5
      src/services/toutiao/ttAccountManage.ts

+ 14 - 1
config/routerConfig.ts

@@ -98,7 +98,20 @@ const launchSystem = {
             path: '/launchSystemNew/account',
             name: '广告账户管理',
             access: 'account',
-            component: './launchSystemNew/account',
+            routes: [
+                {
+                    name: '小说',
+                    path: '/launchSystemNew/account/novel',
+                    access: 'novel',
+                    component: './launchSystemNew/account/novel',
+                },
+                {
+                    name: '游戏',
+                    path: '/launchSystemNew/account/game',
+                    access: 'game',
+                    component: './launchSystemNew/account/game',
+                },
+            ],
         },
         {
             path: '/launchSystemNew/adq',

+ 3 - 2
src/models/useAdMonitor/useMonitor.ts

@@ -3,8 +3,9 @@ import {
     ListType, getPlanListApi, getTotalCostApi, getPlanCostApi, getCostSpeedApi, getUserGroupApi, getAllPlanListApi,
     allPlanProps, getDetailListApi, getMinuteListApi, downLoadUpAdApi, downLoadDetailApi,
     downLoadDetailMinuteApi, downLoadSpeedApi, downLoadAllAdListApi, addEditGroupApi, getAdGroupListApi, deleteAdGroupApi, 
-    getAccountListApi, AccountListProps, addDelAccountApi, getBookListAllApi, getAdqAccountListApi, getCostTopListApi, getCostTrendListApi, getListForHourApi, getColumnTrendApi, getAdTotalDataApi, getListForAdApi
+    getAccountListApi, AccountListProps, addDelAccountApi, getBookListAllApi, getCostTopListApi, getCostTrendListApi, getListForHourApi, getColumnTrendApi, getAdTotalDataApi, getListForAdApi
 } from '@/services/adMonitor/adMonitor'
+import { getAdAccountApi } from '@/services/launchAdq/adAuthorize'
 
 
 export default function useMonitor() {
@@ -39,7 +40,7 @@ export default function useMonitor() {
     const addDelAccount = useAjax((params: { accountIdList: number[], groupId: number, type: 0 | 1 }) => addDelAccountApi(params), { formatResult: true })
 
     // 获取广告账号列表
-    const getAdqAccountList = useAjax(() => getAdqAccountListApi(), { formatResult: true })
+    const getAdqAccountList = useAjax(() => getAdAccountApi(), { formatResult: true })
 
     // NEW
     const getListForHour = useAjax((params) => getListForHourApi(params), { formatResult: true, debounceInterval: 100 })

+ 2 - 2
src/pages/launchSystemNew/account/addAccountToGroup.tsx → src/pages/launchSystemNew/account/game/addAccountToGroup.tsx

@@ -1,6 +1,6 @@
 import { useAjax } from "@/Hook/useAjax"
-import { getAdAccountApi, getAllUserAccountApi } from "@/services/launchAdq/adAuthorize"
-import { addNewAccountToGroupApi, getAccountListApi, getGroupListApi } from "@/services/launchAdq/subgroup"
+import { getAllUserAccountApi } from "@/services/launchAdq/adAuthorize"
+import { addNewAccountToGroupApi, getAccountListApi } from "@/services/launchAdq/subgroup"
 import { PlusOutlined } from "@ant-design/icons"
 import { Button, Form, message, Modal, Select, Transfer } from "antd"
 import React, { useEffect, useState } from "react"

+ 0 - 0
src/pages/launchSystemNew/account/appointPut.tsx → src/pages/launchSystemNew/account/game/appointPut.tsx


+ 0 - 0
src/pages/launchSystemNew/account/changeRecord.tsx → src/pages/launchSystemNew/account/game/changeRecord.tsx


+ 0 - 0
src/pages/launchSystemNew/account/checkAccount.tsx → src/pages/launchSystemNew/account/game/checkAccount.tsx


+ 0 - 0
src/pages/launchSystemNew/account/divideIntoGroups.tsx → src/pages/launchSystemNew/account/game/divideIntoGroups.tsx


+ 0 - 0
src/pages/launchSystemNew/account/groupLeft.tsx → src/pages/launchSystemNew/account/game/groupLeft.tsx


+ 0 - 0
src/pages/launchSystemNew/account/index.less → src/pages/launchSystemNew/account/game/index.less


+ 337 - 0
src/pages/launchSystemNew/account/game/index.tsx

@@ -0,0 +1,337 @@
+
+import HocError from '@/Hoc/HocError'
+import { Col, Modal, Row, Input, message, Space, Tabs, Button, Radio, Select } from 'antd'
+import React, { useCallback, useEffect, useState } from 'react'
+import { columnsMp } from './tableConfig'
+import { useAjax } from '@/Hook/useAjax'
+import { getAdAccountGameListApi, GetAdAccountParams, putAdAccountApi } from '@/services/launchAdq/adAuthorize'
+import style from './index.less'
+import TableData from '../../components/TableData'
+import GroupLeft from './groupLeft'
+import QQAuth from './qqAuto'
+import { MenuFoldOutlined, MenuUnfoldOutlined, PlusOutlined, SwapOutlined } from '@ant-design/icons'
+import TeamMembers from '../../components/teamMembers'
+import { getAdAccountAllOfMemberGame, getErpUserAll, getServiceProviderAll, putConfigServiceProvider } from '@/services/launchAdq/adq'
+import AddAccountToGroup from './addAccountToGroup'
+import { delAccountToGroupApi } from '@/services/launchAdq/subgroup'
+import { useModel } from 'umi'
+import ChangeRecord from './changeRecord'
+import CheckAccount from './checkAccount'
+import AppointPut from './appointPut'
+import SetEarlyWarningsAccount from '@/components/EarlyWarning/setEarlyWarningsAccount'
+
+/** 投放管理 */
+const AdAuthorize: React.FC = () => {
+    let [visible, setVisible] = useState(false)
+    /*************************/
+    const { groupListInit } = useModel('useLaunchAdq.useAdAuthorize')
+    const userInfo = useModel('@@initialState', model => model.initialState?.currentUser)
+    const [queryForm, setQueryForm] = useState<GetAdAccountParams>({ pageNum: 1, pageSize: 20 })
+    const [remarkData, set_remarkData] = useState<{ visible: boolean, remark: string, data: any }>({
+        visible: false,
+        remark: '',
+        data: null
+    })
+    const [activeKey, setActiveKey] = useState<string>('1')
+    const [showLeft, setShowLeft] = useState<boolean>(false)
+    const [crShow, setCrShow] = useState<boolean>(false) // 变更记录控制
+    const [crData, setCrData] = useState<{ name: number, id: number } | null>(null)
+    const [checkAccShow, setCheckAccShow] = useState<boolean>(false)
+    const [openServer, setOpenServer] = useState<any[]>([])//配置服务商数据
+    const [serverName, setServerName] = useState<any>(null)//选择的服务商名称
+    const [data, setData] = useState<{
+        putResourceId?: number | undefined,
+        beginTime?: string | undefined,
+        gdtAccountId?: number,
+        accountIds?: string,
+        accountId?: string,
+        gdtAccountIds?: string,
+        advertiserId?: string,
+        accountName?: string,
+        account?: string,
+        accountPassword?: string,
+        quickAppAccountIds?: string
+        resourceNames?: string
+    } | undefined>(undefined)
+    const [selectAccData, setSelectAccData] = useState<any[]>([])
+    const [puShow, setPuShow] = useState<boolean>(false)
+    const [puData, setPuData] = useState<any[]>([])
+    const [switchType, setSwitchType] = useState<'account' | 'putUser' | 'setServer'>('account')
+    const putRemark = useAjax((adAccountId: any, remark: any) => putAdAccountApi(adAccountId, remark))
+    const delAccountToGroup = useAjax((params) => delAccountToGroupApi(params))
+    const getAdAccountList = useAjax((params) => getAdAccountGameListApi(params), { formatResult: true })
+    const allOfMemberGame = useAjax(() => getAdAccountAllOfMemberGame(), { formatResult: true })
+    const erpUserALL = useAjax(() => getErpUserAll(), { formatResult: true })
+    const api_getServiceProviderAll = useAjax(() => getServiceProviderAll(), { formatResult: true })
+    const api_putConfigServiceProvider = useAjax((params) => putConfigServiceProvider(params), { formatResult: true })
+    /*************************/
+
+    useEffect(() => {
+        groupListInit()
+        !erpUserALL.data && erpUserALL.run()
+        !api_getServiceProviderAll.data && api_getServiceProviderAll.run()
+    }, [])
+
+    useEffect(() => {
+        getList()
+    }, [queryForm])
+
+    /** 获取账号列表 */
+    const getList = () => {
+        let params = JSON.parse(JSON.stringify(queryForm))
+        if (params.accountIds) {
+            params.accountIds = params.accountIds.split(/[\,\,]/)
+        } else {
+            delete params?.accountIds
+        }
+        getAdAccountList.run(params)
+    }
+
+    const remark = () => {
+        if (remarkData.remark && remarkData.data) {
+            putRemark.run(remarkData.data.accountId, remarkData.remark).then(res => {
+                set_remarkData({ ...remarkData, visible: false, remark: '', data: null })
+                getList()
+            })
+        } else {
+            message.error('请输入备注!')
+        }
+
+    }
+    const edit = useCallback((data) => {
+        set_remarkData({ ...remarkData, visible: true, data, remark: data.remark })
+    }, [remarkData])
+
+    /** 移除分组里账号 */
+    const del = (groupId: number, accountId: number) => {
+        delAccountToGroup.run({ currGroupId: groupId, accountIds: [accountId] }).then(res => {
+            message.success('移出成功')
+            getAdAccountList.refresh()
+        })
+    }
+
+    /** 切号 */
+    const checkAccount = (value: any[]) => {
+        let ids = value?.map((item: any) => item.id)
+        setData({ resourceNames: value?.map((item: any) => item.putResourceName).toString(), accountIds: value?.map((item: any) => item.accountId).toString(), gdtAccountIds: ids.toString(), putResourceId: undefined, beginTime: undefined })
+        setCheckAccShow(true);
+    }
+
+    /** 变更记录 */
+    const changeRecord = (name: number, id: number) => {
+        setCrData({ name, id })
+        setCrShow(true)
+    }
+
+    /** 指派投手 */
+    const putUserHandle = (data: any[]) => {
+        setPuData(data)
+        setPuShow(true)
+    }
+    // 批量配置服务商
+    const setServiceProviderName = (accountIds: any) => {
+        api_putConfigServiceProvider.run({ accountIds, serviceProviderName: serverName.label }).then(res => {
+            if (res.data) {
+                message.success("配置成功!")
+                setOpenServer([]);
+                setServerName(null)
+                getAdAccountList.refresh()
+            } else {
+                message.error("配置失败!")
+            }
+        })
+    }
+    // 
+    return <div style={{ height: '100%' }}>
+        <Tabs
+            tabBarStyle={{ marginBottom: 1 }}
+            activeKey={activeKey}
+            type="card"
+            // tabBarExtraContent={<Button type='primary' onClick={()=>setVisible(true)}><PlusOutlined />广告账号授权</Button>}
+            onChange={(activeKey) => {
+                if (activeKey !== 'contract') {
+                    let newQueryForm = JSON.parse(JSON.stringify(queryForm))
+                    delete newQueryForm?.groupId
+                    delete newQueryForm?.putUserId
+                    setQueryForm(newQueryForm)
+                    setActiveKey(activeKey)
+                } else {
+                    setShowLeft(!showLeft)
+                }
+            }}
+        >
+            <Tabs.TabPane tab='我的' key='1' />
+            <Tabs.TabPane tab='组员' key='2' />
+            <Tabs.TabPane tab={showLeft ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />} key='contract' />
+        </Tabs>
+
+        <div className={style.manage}>
+            {!showLeft && activeKey === '1' && <GroupLeft onChange={(groupId) => setQueryForm({ ...queryForm, groupId, pageNum: 1 })} value={queryForm?.groupId} />}
+            {!showLeft && activeKey === '2' && <TeamMembers allOfMember={allOfMemberGame} onChange={(putUserId) => setQueryForm({ ...queryForm, putUserId, pageNum: 1 })} value={queryForm?.putUserId} />}
+
+            <div className={style.manage__left} style={showLeft ? { width: '100%' } : { width: 'calc(100% - 200px)' }}>
+                <TableData
+                    ajax={getAdAccountList}
+                    dataSource={getAdAccountList?.data?.data?.records}
+                    loading={getAdAccountList?.loading}
+                    columns={() => columnsMp(edit, setOpenServer, del, checkAccount, changeRecord, putUserHandle, activeKey, userInfo?.userId?.toString(), queryForm?.groupId, getAdAccountList)}
+                    total={getAdAccountList?.data?.data?.total}
+                    page={getAdAccountList?.data?.data?.current}
+                    pageSize={getAdAccountList?.data?.data?.size}
+                    size="small"
+                    scroll={{ y: 600 }}
+                    leftChild={<Space wrap>
+                        <Radio.Group value={switchType} onChange={(e) => { setSwitchType(e.target.value); setSelectAccData([]) }}>
+                            <Radio.Button value="account">批量切号</Radio.Button>
+                            <Radio.Button value="putUser">批量指派投放助理</Radio.Button>
+                            <Radio.Button value="setServer">批量配置服务商</Radio.Button>
+                        </Radio.Group>
+                        <Input.TextArea
+                            placeholder="多个广告账号以,隔开(id1,id2)"
+                            allowClear
+                            style={{ minWidth: 200 }}
+                            value={queryForm?.accountIds}
+                            rows={1}
+                            onChange={(e) => {
+                                setQueryForm({ ...queryForm, accountIds: e.target.value.replaceAll(/\s/ig, '') })
+                            }}
+                        />
+                        <Button onClick={getList} type='primary' loading={getAdAccountList.loading}>搜索</Button>
+                        <AddAccountToGroup onChange={() => getAdAccountList.refresh()} />
+                        <Button type='primary' onClick={() => setVisible(true)}><PlusOutlined />广告账号授权</Button>
+                        {switchType === 'account' ?
+                            (selectAccData?.length > 0 && <>
+                                <Button type="primary" ghost icon={<SwapOutlined />} onClick={() => { checkAccount(selectAccData) }}>批量切号</Button>
+                                <SetEarlyWarningsAccount onChange={() => { setSelectAccData([]); }} accountIds={selectAccData.map(item => item.accountId)?.toString()}/>
+                            </>) :
+                            switchType === 'putUser' ? (selectAccData?.length > 0 && <Button type="primary" ghost icon={<SwapOutlined />} onClick={() => { putUserHandle(selectAccData) }}>批量指派投放助理</Button>) :
+                                selectAccData?.length > 0 && <Button type="primary" ghost icon={<SwapOutlined />} onClick={() => { setOpenServer(selectAccData) }}>批量配置服务商</Button>
+                        }
+                    </Space>}
+                    rowSelection={{
+                        selectedRowKeys: selectAccData?.map((item: any) => item.id?.toString()),
+                        getCheckboxProps: (record: any) => ({
+                            disabled: switchType === 'putUser' ? activeKey === '2' || userInfo?.userId !== record?.putUserInfo?.userId : false
+                        }),
+                        onSelect: (record: { id: number, mpName: string }, selected: boolean) => {
+                            if (selected) {
+                                selectAccData.push({ ...record })
+                                setSelectAccData([...selectAccData])
+                            } else {
+                                let newSelectAccData = selectAccData.filter((item: { id: number }) => item.id !== record.id)
+                                setSelectAccData([...newSelectAccData])
+                            }
+                        },
+                        onSelectAll: (selected: boolean, selectedRows: { id: number }[], changeRows: { id: number }[]) => {
+                            if (selected) {
+                                let newSelectAccData = [...selectAccData]
+                                changeRows.forEach((item: { id: number }) => {
+                                    let index = newSelectAccData.findIndex((ite: { id: number }) => ite.id === item.id)
+                                    if (index === -1) {
+                                        newSelectAccData.push({ ...item })
+                                    }
+                                })
+                                setSelectAccData([...newSelectAccData])
+                            } else {
+                                let newSelectAccData = selectAccData.filter((item: { id: number }) => {
+                                    let index = changeRows.findIndex((ite: { id: number }) => ite.id === item.id)
+                                    if (index !== -1) {
+                                        return false
+                                    } else {
+                                        return true
+                                    }
+                                })
+                                setSelectAccData([...newSelectAccData])
+                            }
+                        }
+                    }}
+                    onChange={(props: any) => {
+                        let { pagination } = props
+                        let { current, pageSize } = pagination
+                        setQueryForm({ ...queryForm, pageNum: current, pageSize })
+                    }}
+                />
+            </div>
+        </div>
+        {/* 批量设置服务商 */}
+        {openServer.length > 0 && <Modal
+            title="配置服务商"
+            onOk={() => setServiceProviderName(openServer?.map(item => item.accountId))}
+            onCancel={() => { setOpenServer([]); setServerName(null) }}
+            visible={openServer.length > 0}
+            confirmLoading={api_putConfigServiceProvider.loading}
+        >
+            <Row gutter={[20, 20]}>
+                <Col span={24}>
+                    <Row>
+                        <Col span={3}><b>广告主:</b></Col>
+                        <Col span={21}>
+                            {openServer.map((item, index) => {
+                                return index === openServer.length - 1 ? item.accountId : item.accountId + ','
+                            })}
+                        </Col>
+                    </Row>
+                </Col>
+                <Col span={24}>
+                    <Row>
+                        <Col span={3}><b>服务商:</b></Col>
+                        <Col span={21}>
+                            <Select
+                                style={{ minWidth: 200 }}
+                                showSearch
+                                allowClear
+                                placeholder="请选择服务商"
+                                optionFilterProp="children"
+                                onChange={(value: any, option: any) => {
+                                    setServerName(option)
+                                }}
+                                filterOption={(input, option: any) =>
+                                    (option?.label ?? '').toLowerCase().includes(input.toLowerCase())
+                                }
+                                value={serverName}
+                                options={api_getServiceProviderAll?.data?.data?.map((item: { id: any, serviceProviderName: any }) => {
+                                    return { value: item.id, label: item.serviceProviderName }
+                                })}
+                            />
+                        </Col>
+                    </Row>
+                </Col>
+            </Row>
+
+        </Modal>}
+        {/* 广告授权 */}
+        {visible && <QQAuth qqVisible={visible} callBack={() => setVisible(false)} />}
+        {/* 变更记录 */}
+        {crShow && <ChangeRecord visible={crShow} data={crData} onClose={() => { setCrShow(false); setCrData(null) }} />}
+        {/* 切号 */}
+        {checkAccShow && <CheckAccount value={data} visible={checkAccShow} onChange={() => { getList(); setCheckAccShow(false); setSelectAccData([]) }} onClose={() => { setCheckAccShow(false) }} />}
+        {/* 指派 */}
+        {puShow && <AppointPut value={puData} visible={puShow} onClose={() => { setPuShow(false) }} allOfMember={erpUserALL} onChange={() => { setPuShow(false); getAdAccountList.refresh(); setSelectAccData([]) }} />}
+
+        {remarkData.visible && <Modal
+            visible={remarkData.visible}
+            title='编辑账户'
+            onCancel={() => { set_remarkData({ ...remarkData, visible: false, data: null }) }}
+            onOk={remark}
+            confirmLoading={putRemark.loading}
+        >
+            <Row gutter={[20, 20]}>
+                <Col span={24} className={style.boxCol}><strong>广告主ID:</strong><span>{remarkData?.data.accountId}</span></Col>
+                <Col span={24} className={style.boxCol}><strong>类型:</strong><span>{remarkData?.data.sourceType === 0 ? '微信' : 'QQ'}</span></Col>
+                <Col span={24} className={style.boxCol}><strong>公众号信息:</strong><span>{remarkData?.data.wechatAccountName || '无'}</span></Col>
+                <Col span={24} className={style.boxCol}><strong>企业名称:</strong><span>{remarkData?.data.corporationName || '无'}</span></Col>
+                <Col span={24} className={style.boxCol}><strong>服务商ID列表:</strong><span>{remarkData?.data.agencyIdList ? remarkData.data.agencyIdList?.join() : '无'}</span></Col>
+                <Col span={24} className={style.boxCol}><strong>行业ID:</strong><span>{remarkData?.data.systemIndustryId || '无'}</span></Col>
+                <Col span={24} className={style.boxCol}><strong>授权状态:</strong><span>{remarkData?.data.authStatus || '无'}</span></Col>
+                <Col span={24} className={style.boxCol}><strong>日限额(分):</strong><span>{remarkData?.data.dailyBudget || '无'}</span></Col>
+                <Col span={24} className={style.boxCol}><strong>授权时间:</strong><span>{remarkData?.data.createTime || '无'}</span></Col>
+                <Col span={24} className={style.boxCol}><strong>备注:</strong><span><Input.TextArea rows={5} maxLength={200} value={remarkData.remark} onChange={(e) => {
+                    let value = e.target.value
+                    set_remarkData({ ...remarkData, remark: value })
+                }} /></span></Col>
+            </Row>
+        </Modal>}
+    </div>
+}
+
+export default HocError(AdAuthorize)

+ 161 - 0
src/pages/launchSystemNew/account/game/qqAuto.tsx

@@ -0,0 +1,161 @@
+import { useCallback, useState } from "react"
+import React from 'react'
+import { Col, Row, Radio, Input, Button, message, Space, Image, Modal, Popconfirm } from "antd";
+let name = {
+    0: '小说账号失败列表:',
+    1: '游戏账号失败列表:',
+}
+var time: any = null
+let api= "http://47.99.157.216:8023"
+// let api= "http://127.0.0.1:8023"
+function QQAuth(props: { qqVisible: boolean, callBack: () => void }) {
+    const { qqVisible, callBack } = props
+    let [visible, setVisible] = useState(false)
+    let [loading,setLoading]=useState(false)
+    let [codeUrl, setCodeUrl] = useState('')
+    let [err, setErr] = useState({})
+    let [data, setData] = useState({
+        userId: localStorage.getItem('userId'),
+        adAppType: 1,
+        users: [],
+        callbackPage: 'http%3A%2F%2Ferp.zanxiangnet.com%2FadCode',
+        authorization: `Bearer ${sessionStorage.getItem('Admin-Token')}`
+    })
+    let adAppIdonChange = useCallback((checkedValue) => {
+        let v = checkedValue.target.value
+        console.log("checkedValue===>",v)
+        setData({ ...data, adAppType:v})
+    }, [data])
+    let submit = useCallback(() => {
+        if (data.users.some(user => isNaN(user))) {
+            message.error('账号请使用数字!!!!!!')
+            return
+        }
+        setLoading(true)
+        fetch(api+'/qq/auth', {
+            method: 'POST',
+            headers: {
+                "content-type": "application/json",
+            },
+            body: JSON.stringify(data)
+        }).then(res => res.json()).then(r => {
+            if (r?.data?.codeImgUrl) {
+                setCodeUrl(r?.data?.codeImgUrl)
+                setVisible(true)
+                let n=0
+                time = setInterval(() => {
+                    if(n< 60){
+                        n+=1
+                        fetch(`${api}/qq/isOk?userId=${localStorage.getItem('userId')}`, {
+                            method: 'GET'
+                        }).then(res => res.json()).then(r => {
+                            if (r.data) {
+                                setVisible(false)
+                                setCodeUrl("")
+                                clearInterval(time)
+                                setLoading(false)
+                            }
+                        })
+                    }else{
+                        message.error('扫码超时请重新扫码!')
+                        setVisible(false)
+                        setCodeUrl("")
+                        clearInterval(time)
+                        setLoading(false)
+                    }
+                   
+                }, 1000)
+            } else {
+                message.success('已经开始授权,稍后自行查看结果!')
+                setLoading(false)
+            }
+            console.log(r)
+        })
+    }, [data])
+    let query = () => {
+        fetch(`${api}/qq/queryErr?userId=${localStorage.getItem('userId')}`, {
+            method: 'GET'
+        }).then(res => res.json()).then(r => {
+            console.log(r)
+            setErr(r.data)
+        })
+    }
+    let del = () => {
+        fetch(`${api}/qq/delCookie?userId=${localStorage.getItem('userId')}`, {
+            method: 'GET'
+        }).then(res => res.json()).then(r => {
+            console.log(r)
+            message.success('清理成功!!!!请重新扫码授权登录!!!')
+        })
+    }
+    let userIdChange = useCallback((e) => {
+        let value = e.target.value
+        let arr = value.split(/,|,/)
+        let newArr = arr?.map((str: string) => Number(str.replace(/\s/ig, '')))
+        setData({ ...data, users: newArr })
+    }, [data])
+    return <Modal
+        visible={qqVisible}
+        footer={null}
+        width={800}
+        onCancel={callBack}
+        maskClosable={false}
+    >
+        <div>
+            <Row>
+                <Col span='24'>
+                    <Row>
+                        <Col span={3}><h3>平台选择:</h3></Col>
+                        <Col span={20}>
+                            <Radio.Group style={{ width: '100%' }} onChange={adAppIdonChange} defaultValue={data.adAppType}>
+                                {/* <Radio value={0}>小说</Radio> */}
+                                <Radio value={1}>游戏</Radio>
+                            </Radio.Group>
+                        </Col>
+                    </Row>
+                </Col>
+                <Col span='24'>
+                    <Row>
+                        <Col span={3}><h3>账号ID:</h3></Col>
+                        <Col span={20}> <Input.TextArea placeholder='多个账号请以,号隔开例:123456,222333,444444' rows={5} onChange={userIdChange} allowClear></Input.TextArea></Col>
+                    </Row>
+                </Col>
+            </Row>
+            <Row style={{ display: 'flex', justifyContent: 'center', marginTop: 20 }}>
+                <Space>
+                    <Button type='primary' onClick={submit} loading={loading}>提交</Button>
+                    <Button type='default' onClick={query} >查询授权失败账号</Button>
+                    <Popconfirm title={'清除账号状态将清除所有失败记录,并清空上一次扫码授权状态!'} onConfirm={del} >
+                        <Button type='primary' danger >清除账号状态</Button>
+                    </Popconfirm>
+
+                </Space>
+            </Row>
+            <Row>
+                {
+                    Object.keys(err).map((key, i) => {
+                        return <Col key={i} span={24}>
+                            <div>
+                                <h4>{name[key]}</h4>
+                                <p>{err[key]?.join()}</p>
+                            </div>
+                        </Col>
+                    })
+                }
+            </Row>
+            <Modal
+                visible={visible}
+                footer={null}
+                width={200}
+                onCancel={() => setVisible(false)}
+                maskClosable={false}
+            >
+                <Image
+                    style={{ width: 150 }}
+                    src={codeUrl} />
+            </Modal>
+        </div>
+    </Modal>
+
+}
+export default QQAuth

+ 0 - 0
src/pages/launchSystemNew/account/tableConfig.tsx → src/pages/launchSystemNew/account/game/tableConfig.tsx


+ 0 - 0
src/pages/launchSystemNew/account/tablesConfig.tsx → src/pages/launchSystemNew/account/game/tablesConfig.tsx


+ 104 - 0
src/pages/launchSystemNew/account/novel/addAccountToGroup.tsx

@@ -0,0 +1,104 @@
+import { useAjax } from "@/Hook/useAjax"
+import { getAllUserAccountApi } from "@/services/launchAdq/adAuthorize"
+import { addNewAccountToGroupApi, getAccountListApi } from "@/services/launchAdq/subgroup"
+import { PlusOutlined } from "@ant-design/icons"
+import { Button, Form, message, Modal, Select, Transfer } from "antd"
+import React, { useEffect, useState } from "react"
+import { useModel } from "umi"
+
+
+interface Props {
+    onChange?: () => void
+}
+/**
+ * 新增至分组
+ * @param props 
+ * @returns 
+ */
+const AddAccountToGroup: React.FC<Props> = (props) => {
+
+    /*********************************/
+    const { onChange } = props
+    const [form] = Form.useForm();
+    let currGroupId = Form.useWatch('currGroupId', form)
+    const [visible, setVisible] = useState<boolean>(false)
+    const [mockData, setMockData] = useState<{ key: string, title: string }[]>([])
+    const { getGroupList } = useModel('useLaunchAdq.useAdAuthorize')
+
+    const getAccountList = useAjax((params) => getAccountListApi(params))
+    const addNewAccountToGroup = useAjax((params) => addNewAccountToGroupApi(params))
+    const getAllUserAccount = useAjax(() => getAllUserAccountApi())
+    /*********************************/
+
+    useEffect(() => {
+        if (currGroupId) {
+            getAccountList.run(currGroupId).then(res => {
+                console.log(res);
+                form.setFieldsValue({ accountIds: res?.adAccountList?.map((item: { accountId: string }) => item.accountId.toString()) || [] })
+            })
+        }
+    }, [currGroupId])
+
+    const addAccountToGroupHandle = () => {
+        setVisible(true)
+        getAllUserAccount.run().then(res => {
+            setMockData(res?.map((item: { accountId: string, remark: string }) => ({ key: item.accountId.toString(), title: `${item.accountId}${item.remark ? '_' + item.remark : ''}` })))
+        })
+    }
+
+    const handleOk = () => {
+        form.validateFields().then(values => {
+            addNewAccountToGroup.run(values).then(res => {
+                message.success('修改成功')
+                closeHandle()
+                onChange?.()
+            })
+        })
+    }
+
+    const closeHandle = () => {
+        setVisible(false)
+        form.setFieldsValue({ currGroupId: undefined, accountIds: undefined })
+    }
+
+    return <>
+        <Button onClick={addAccountToGroupHandle} type='primary' icon={<PlusOutlined />}>修改分组中账户</Button>
+        {visible && <Modal
+            title='修改分组中账户'
+            visible={visible}
+            onOk={handleOk}
+            onCancel={closeHandle}
+            confirmLoading={addNewAccountToGroup.loading}
+        >
+            <Form
+                form={form}
+                labelCol={{ span: 4 }}
+                colon={false}
+                initialValues={{}}
+            >
+                <Form.Item label={<strong>分组</strong>} name='currGroupId' rules={[{ required: true, message: '请选择分组' }]}>
+                    <Select placeholder='请选择分组'>
+                        {getGroupList?.data?.map((item: { groupName: string, groupId: number }) => <Select.Option value={item.groupId} key={item.groupId}>{item.groupName}</Select.Option>)}
+                    </Select>
+                </Form.Item>
+                {currGroupId && <Form.Item label={<strong>账号</strong>} name='accountIds' valuePropName='targetKeys' rules={[{ required: true, message: '请选择账号' }]}>
+                    <Transfer
+                        dataSource={mockData}
+                        showSearch
+                        titles={['未选', '已选']}
+                        oneWay
+                        filterOption={(input: any, option: any) => {
+                            let newInput: string[] = input ? input?.split(/[,,\n\s]+/ig).filter((item: any) => item) : []
+                            return newInput?.some(val => option!.title?.toString().toLowerCase()?.includes(val))
+                        }}
+                        listStyle={{ minHeight: 320 }}
+                        render={item => item.title}
+                    />
+                </Form.Item>}
+            </Form>
+        </Modal>}
+    </>
+}
+
+
+export default React.memo(AddAccountToGroup)

+ 93 - 0
src/pages/launchSystemNew/account/novel/appointPut.tsx

@@ -0,0 +1,93 @@
+import { useAjax } from "@/Hook/useAjax"
+import { addAccountUserApi, cutPutApi } from "@/services/operating/accountyyb"
+import { Form, message, Modal, Select } from "antd"
+import React, { useEffect, useState } from "react"
+
+
+interface Props {
+    allOfMember: any
+    onChange?: () => void
+    onClose?: () => void
+    visible?: boolean,
+    value?: any[]
+}
+
+/**
+ * 指派
+ * @param props 
+ * @returns 
+ */
+const AppointPut: React.FC<Props> = (props) => {
+    /*******************************/
+    const { onChange, onClose, visible, allOfMember, value = [] } = props
+    const [userAll, setUserAll] = useState([])
+
+    const [form] = Form.useForm();
+    const addAccountUser = useAjax((params) => addAccountUserApi(params))
+    /*******************************/
+
+    useEffect(() => {
+        if (value.length === 1) {
+            console.log('value--->', value[0].accountUsers?.map((item: any) => item.putUserId));
+        
+            form.setFieldsValue({ putUserIds: value[0].accountUsers?.map((item: any) => item.putUserId) })
+        }
+    }, [value])
+
+    /** 获取组员 */
+    useEffect(() => {
+        (async function () {
+            let res = allOfMember?.data || await allOfMember.run()
+            if (res?.data) {
+                let useAll: any = []
+                res?.data?.forEach((item: any) => {
+                    let obj = {
+                        key: item.userId,
+                        label: item.nickname
+                    }
+                    useAll.push(obj)
+                })
+                setUserAll(useAll)
+            }
+        })()
+    }, [])
+
+    const handleOk = () => {
+        form.validateFields().then(values => {
+            addAccountUser.run({ ...values, accountIds: value.map((item: { accountId: number }) => item.accountId) }).then(res => {
+                message.success('指派成功')
+                onChange?.()
+            })
+        })
+    }
+
+    return <Modal
+        title="指派投放助理"
+        visible={visible}
+        onOk={handleOk}
+        onCancel={() => onClose?.()}
+        confirmLoading={addAccountUser.loading}
+    >
+        <Form
+            form={form}
+            labelCol={{ span: 4 }}
+            colon={false}
+            initialValues={{}}
+        >
+            <Form.Item label={<strong>组员</strong>} name='putUserIds' rules={[{ required: true, message: '请选择分组' }]}>
+                <Select
+                    placeholder='请选择组员'
+                    showSearch
+                    mode="multiple"
+                    filterOption={(input: string, option: any) => {
+                        return option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
+                    }}
+                >
+                    {userAll?.map((item: { key: string, label: number }) => <Select.Option value={item.key} key={item.key}>{item.label}</Select.Option>)}
+                </Select>
+            </Form.Item>
+        </Form>
+    </Modal>
+}
+
+export default React.memo(AppointPut)

+ 127 - 0
src/pages/launchSystemNew/account/novel/changeRecord.tsx

@@ -0,0 +1,127 @@
+import Tables from "@/components/Tables";
+import { DatePicker, Drawer, Form, Input, Modal, Select } from "antd";
+import moment from "moment";
+import React, { useCallback, useEffect, useState } from "react";
+import { useModel } from "umi";
+import { columnsCrGdt } from "./tablesConfig"
+
+type Props = {
+    data?: { name: number, id: number } | null,
+    visible?: boolean,
+    onChange?: () => void,
+    onClose?: () => void
+}
+function ChangeRecord(props: Props) {
+
+    const { data, visible, onClose } = props
+    const { getGdtChangeRecord, editAccountChangeRecord, editGdtChangeRecord, getResource } = useModel('useOperating.useAccountyyb')
+    const [accountQueryForm, setAccountQueryForm] = useState<{ quickAppAccountId: number, pageNum: number, pageSize: number }>({ quickAppAccountId: data?.id as number, pageNum: 1, pageSize: 20 })
+    const [gdtQueryForm, setGdtQueryForm] = useState<{ gdtAccountId: number, pageNum: number, pageSize: number }>({ gdtAccountId: data?.name as number, pageNum: 1, pageSize: 20 })
+    const [editTitle, setEditTitle] = useState<string>('编辑')
+    const [form] = Form.useForm()
+    const [editData, setEditData] = useState<{ recordId: number, putResourceId: number | undefined, resourceNames: string, beginTime: any, endTime: any } | null>(null)
+    const [editVisible, setEditVisible] = useState<boolean>(false)
+
+    useEffect(() => {
+        getList()
+    }, [accountQueryForm, gdtQueryForm])
+
+    const getList = () => {
+        getGdtChangeRecord.run(gdtQueryForm)
+    }
+
+    // 分页
+    const pageChange = useCallback((page: string | number, pageSize?: string | number) => {
+        setGdtQueryForm({ ...gdtQueryForm, pageNum: page as number, pageSize: pageSize as number })
+    }, [accountQueryForm, gdtQueryForm])
+
+    // 编辑
+    const editHandle = useCallback((data: any) => {
+        const { beginTime, endTime, id, putResourceName } = data
+        setEditData({ beginTime: moment(beginTime), endTime: endTime ? moment(endTime) : null, recordId: id, putResourceId: undefined, resourceNames: putResourceName })
+        setEditTitle('编辑 ' + putResourceName)
+        setEditVisible(true)
+        setTimeout(() => {
+            form.resetFields()
+        }, 100)
+    }, [editData, editTitle, editVisible, form])
+
+    // 搜索资源
+    const handleSearch = (value: string) => {
+        getResource.run({ resourceName: value, resourceType: 0 })
+    }
+
+    const handleOk = async () => {
+        form.submit()
+        let { resourceNames, ...data1 }  = await form.validateFields()
+        let proms = { ...data1, beginTime: moment(data1.beginTime).format('YYYY-MM-DD') }
+        if (data1.endTime) {
+            proms.endTime = moment(data1.endTime).format('YYYY-MM-DD')
+        }
+        editGdtChangeRecord.run({ ...proms, recordId: editData?.recordId }).then(res => {
+            if(res) {
+                setEditData(null);
+                setEditVisible(false);
+                getGdtChangeRecord.refresh()
+            }
+        })
+    }
+
+    return <div>
+
+        <Drawer title={data?.name + ' 变更记录'} placement="right" width={1200} onClose={() => { onClose && onClose() }} visible={visible}>
+            <Tables
+                columns={columnsCrGdt(editHandle)}
+                dataSource={getGdtChangeRecord?.data?.records}
+                total={getGdtChangeRecord?.data?.total}
+                loading={getGdtChangeRecord?.loading}
+                pageChange={pageChange}
+                sizeChange={pageChange}
+                current={getGdtChangeRecord?.data?.current}
+                pageSize={getGdtChangeRecord?.data?.size}
+                size={'small'}
+                scroll={{ x: 1100 }}
+            />
+        </Drawer>
+
+        {editVisible && <Modal title={editTitle} visible={editVisible} onOk={handleOk} onCancel={() => { setEditData(null); form.resetFields(); setEditVisible(false); }} confirmLoading={editAccountChangeRecord.loading || editGdtChangeRecord.loading}>
+            <Form
+                name="basic"
+                form={form}
+                labelCol={{ span: 5 }}
+                wrapperCol={{ span: 19 }}
+                autoComplete="off"
+                initialValues={{ ...editData }}
+            >
+                <Form.Item label="开始时间" name="beginTime" rules={[{ type: 'object' as const, required: true, message: '请选择时间!' }]}>
+                    <DatePicker />
+                </Form.Item>
+                <Form.Item label="结束时间" name="endTime">
+                    <DatePicker />
+                </Form.Item>
+                <Form.Item label="当前投放信息" name="resourceNames">
+                    <Input.TextArea autoSize disabled />
+                </Form.Item>
+                <Form.Item label="投放信息" name="putResourceId" rules={[{ type: 'number', required: true, message: '请选择投放信息!' }]}>
+                    <Select
+                        showSearch
+                        placeholder="选择投放信息"
+                        defaultActiveFirstOption={false}
+                        showArrow={false}
+                        filterOption={false}
+                        onSearch={handleSearch}
+                        notFoundContent={null}
+                    >
+                        {getResource?.data?.map((item: { id: number, resourceName: string }) => <Select.Option key={item.id} value={item.id}>{item.resourceName}</Select.Option>)}
+                    </Select>
+                </Form.Item>
+
+            </Form>
+
+        </Modal>}
+
+    </div>
+}
+
+
+export default React.memo(ChangeRecord)

+ 69 - 0
src/pages/launchSystemNew/account/novel/checkAccount.tsx

@@ -0,0 +1,69 @@
+import { DatePicker, Form, Input, Modal, Select } from "antd";
+import moment from "moment";
+import React from "react";
+import { useModel } from "umi";
+
+interface Props {
+    value?: any,
+    visible?: boolean,
+    onChange?: () => void,
+    onClose?: () => void
+}
+function CheckAccount(props: Props) {
+    const { value = {}, visible = false, onChange, onClose } = props
+    const { userId } = useModel('useOperating.useUser', model => ({ userId: model.state.selectdUserId }))
+    const { getResource, checkGdtAccountGdt } = useModel('useOperating.useAccountyyb')
+    const [form] = Form.useForm()
+    const handleOk = async () => {
+        form.submit()
+        let data = await form.validateFields()
+        let { accountIds, resourceNames, ...data1 } = data
+        let proms = { ...data1, beginTime: moment(data.beginTime).format('YYYY-MM-DD'), userId, gdtAccountIds: accountIds }
+        checkGdtAccountGdt.run(proms).then(res => {
+            if (res) {
+                onChange && onChange()
+            }
+        })
+    }
+
+    // 搜索资源
+    const handleSearch = (value: string) => {
+        getResource.run({ resourceName: value, resourceType: 0})
+    }
+
+    return <Modal title={`${'GDT'}切号`} visible={visible} onOk={handleOk} onCancel={() => { onClose && onClose() }} confirmLoading={checkGdtAccountGdt.loading}>
+        <Form
+            name="basic"
+            form={form}
+            labelCol={{ span: 5 }}
+            wrapperCol={{ span: 19 }}
+            autoComplete="off"
+            initialValues={{ ...value }}
+        >
+            <Form.Item label="账号ID" name="accountIds" rules={[{ type: 'string', required: true, message: '请输入账号!' }]}>
+                <Input.TextArea autoSize placeholder="请输入账号ID(id1,id2,id3)" disabled />
+            </Form.Item>
+            <Form.Item label="当前投放信息" name="resourceNames">
+                <Input.TextArea autoSize disabled />
+            </Form.Item>
+            <Form.Item label="投放信息" name="putResourceId" rules={[{ type: 'number', required: true, message: '请选择投放信息!' }]}>
+                <Select
+                    showSearch
+                    placeholder="选择投放信息"
+                    defaultActiveFirstOption={false}
+                    showArrow={false}
+                    filterOption={false}
+                    onSearch={handleSearch}
+                    notFoundContent={null}
+                >
+                    {getResource?.data?.map((item: { id: number, resourceName: string }) => <Select.Option key={item.id} value={item.id}>{item.resourceName}</Select.Option>)}
+                </Select>
+            </Form.Item>
+            <Form.Item label="开始时间" name="beginTime" rules={[{ type: 'object' as const, required: true, message: '请选择时间!' }]}>
+                <DatePicker />
+            </Form.Item>
+        </Form>
+    </Modal>
+}
+
+export default React.memo(CheckAccount)

+ 71 - 0
src/pages/launchSystemNew/account/novel/divideIntoGroups.tsx

@@ -0,0 +1,71 @@
+import { useAjax } from "@/Hook/useAjax"
+import { addAccountToGroupApi, delAccountToGroupApi } from "@/services/launchAdq/subgroup"
+import { getArrDifference } from "@/utils/utils"
+import { UsergroupAddOutlined } from "@ant-design/icons"
+import { Button, Checkbox, message, Popover, Spin, Tooltip } from "antd"
+import React, { useEffect, useState } from "react"
+import { useModel } from "umi"
+
+
+interface Props {
+    groupIds: number[],
+    accountId: number,
+    getAdAccountList?: any
+}
+/**
+ * 账号分组至xxx
+ * @param props 
+ */
+const DivideIntoGroups: React.FC<Props> = (props) => {
+
+    /********************************/
+    const { groupIds = [], accountId, getAdAccountList } = props
+    const { getGroupList } = useModel('useLaunchAdq.useAdAuthorize')
+    const [visible, setVisible] = useState<boolean>(false);
+
+    const addAccountToGroup = useAjax((params) => addAccountToGroupApi(params))
+    const delAccountToGroup = useAjax((params) => delAccountToGroupApi(params))
+    /********************************/
+
+    const handleVisibleChange = (newOpen: boolean) => {
+        setVisible(newOpen)
+    }
+    const onChange = (checkedValues: any[]) => {
+        let newGroupid = getArrDifference(checkedValues, groupIds)
+        if (newGroupid.length > 0) {
+            if (checkedValues.length > groupIds.length) {  // 新增
+                addAccountToGroup.run({ currGroupId: newGroupid[0], accountIds: [accountId] }).then(res => {
+                    getAdAccountList.refresh()
+                })
+            } else {  // 删除
+                delAccountToGroup.run({ currGroupId: newGroupid[0], accountIds: [accountId] }).then(res => {
+                    getAdAccountList.refresh()
+                })
+            }
+        }
+    }
+
+    return <Popover
+        content={<Spin spinning={delAccountToGroup.loading || addAccountToGroup.loading}>
+            <Checkbox.Group style={{ width: '100%' }} value={groupIds} onChange={onChange}>
+                <ul className="dig_ul">
+                    {getGroupList?.data?.map((item: { groupName: string, groupId: number }) => <li className="dig_ul__li" key={item.groupId}>
+                        <Checkbox value={item.groupId}>{item.groupName}</Checkbox>
+                    </li>)}
+                </ul>
+            </Checkbox.Group>
+        </Spin>}
+        title="选择分组"
+        trigger="click"
+        visible={visible}
+        overlayClassName="dig"
+        onVisibleChange={handleVisibleChange}
+    >
+        <Tooltip title="分组">
+            <Button size="small" style={{ color: '#eb2f96' }} onClick={() => setVisible(true)}><UsergroupAddOutlined /></Button>
+        </Tooltip>
+    </Popover>
+}
+
+
+export default React.memo(DivideIntoGroups)

+ 156 - 0
src/pages/launchSystemNew/account/novel/groupLeft.tsx

@@ -0,0 +1,156 @@
+import { useAjax } from "@/Hook/useAjax"
+import { addGroupApi, delGroupApi, editGroupApi, getGroupListApi } from "@/services/launchAdq/subgroup"
+import { DeleteOutlined, FormOutlined, PlusOutlined } from "@ant-design/icons"
+import { Button, Input, message, Popconfirm, Space, Spin } from "antd"
+import React, { useEffect, useRef, useState } from "react"
+import { useModel } from "umi"
+import './index.less'
+
+/**
+ * 分组管理Left 菜单
+ */
+interface Props {
+    onChange?: (groupId?: number) => void
+    value?: number
+}
+const GroupLeft: React.FC<Props> = (props) => {
+
+    /*************************/
+    const { onChange, value } = props
+    const [isNewGrouping, setIsNewGrouping] = useState<boolean>(false);  // 是否新增分组
+    const inputRef = useRef<any>(null);
+    const [groupData, setGroupData] = useState<{ groupName: string, remark?: string, groupId?: number }>({ groupName: '' }) // 分组添加
+    const [selectAccData, setSelectAccData] = useState<{ id: number, mpName: string }[]>([])  // 选中
+    const [groupId, setGroupId] = useState<number>(value || 0)
+    const { getGroupList } = useModel('useLaunchAdq.useAdAuthorize')
+
+    const addGroup = useAjax((params) => addGroupApi(params))
+    const editGroup = useAjax((params) => editGroupApi(params))
+    const delGroup = useAjax((params) => delGroupApi(params))
+    /*************************/
+
+    useEffect(() => {
+        if (value) {
+            setGroupId(value || 0)
+        }
+    }, [value])
+
+    /** 点击新增处理聚焦 */
+    useEffect(() => {
+        if (isNewGrouping && inputRef?.current) {
+            inputRef.current!.focus({
+                cursor: 'end',
+            });
+        }
+    }, [inputRef, isNewGrouping])
+
+    /** 新增修改分组 */
+    const addEditHandle = () => {
+        if (groupData?.groupName) {
+            if (groupData?.groupId) {
+                editGroup.run(groupData).then((res: any) => {
+                    message.success('修改成功')
+                    setGroupData({ groupName: '' })
+                    setIsNewGrouping(false)
+                    getGroupList.refresh()
+                })
+            } else {
+                addGroup.run(groupData).then((res: any) => {
+                    message.success('添加成功')
+                    setGroupData({ groupName: '' })
+                    setIsNewGrouping(false)
+                    getGroupList.refresh()
+                })
+            }
+        } else {
+            message.error('请填写分组名称')
+        }
+    }
+
+    /** 删除分组 */
+    const delGroupHandle = (id: number) => {
+        delGroup.run({ groupId: id }).then(res => {
+            message.success('删除成功')
+            getGroupList.refresh()
+            if (groupId === id) {
+                setGroupId(0)
+                onChange?.(undefined)
+            }
+        })
+    }
+
+    return <div className="groupLeft">
+        <div className="groupLeft_header">
+            <div>全部分组</div>
+            <Button type="link" icon={<PlusOutlined />} className="stop" onClick={(e) => {
+                e.stopPropagation()
+                setGroupData({ groupName: '' })
+                setIsNewGrouping(true)
+            }}>新增分组</Button>
+        </div>
+        <div className="groupLeft_content">
+            {isNewGrouping && <div className="groupLeft_content_item">
+                <div className="edit stop">
+                    <Space direction="vertical" className="stop">
+                        <Space className="stop">
+                            <div style={{ width: 30 }} className="stop">组名</div>
+                            <Input placeholder="输入分组名称(最多10个字)" className="stop" maxLength={10} ref={inputRef} onChange={(e) => { setGroupData({ ...groupData, groupName: e.target.value }) }} value={groupData?.groupName} />
+                        </Space>
+                        <div style={{ display: 'flex', justifyContent: 'flex-end' }} className="stop">
+                            <Space className="stop">
+                                <Button size="small" className="stop" onClick={() => { setIsNewGrouping(false); setGroupData({ groupName: '' }) }}>取消</Button>
+                                <Button type="primary" className="stop" size="small" onClick={addEditHandle} loading={getGroupList?.loading}>确定</Button>
+                            </Space>
+                        </div>
+                    </Space>
+                </div>
+            </div>}
+            <Spin spinning={getGroupList.loading}>
+                <div className="groupLeft_content_item">
+                    <div className={`con ${groupId === 0 ? 'select' : ''}`} onClick={() => { setGroupId(0); onChange?.(undefined); setSelectAccData([]) }}>
+                        <div className="left">
+                            <div className="title">全部</div>
+                        </div>
+                    </div>
+                </div>
+                {getGroupList && Array.isArray(getGroupList?.data) && getGroupList?.data?.map((item: { groupName: string, groupId: number }, index: number) => <div className="groupLeft_content_item" key={item.groupId || index}>
+                    {groupData?.groupId && groupData?.groupId === item?.groupId ? <div className="edit stop">
+                        <Space direction="vertical" className="stop">
+                            <Space className="stop">
+                                <div style={{ width: 40 }} className="stop">组名</div>
+                                <Input placeholder="输入分组名称(最多10个字)" className="stop" maxLength={10} ref={inputRef} onChange={(e) => { setGroupData({ ...groupData, groupName: e.target.value }) }} value={groupData?.groupName} />
+                            </Space>
+                            <div style={{ display: 'flex', justifyContent: 'flex-end' }} className="stop">
+                                <Space className="stop">
+                                    <Button size="small" className="stop" onClick={() => { setIsNewGrouping(false); setGroupData({ groupName: '' }) }}>取消</Button>
+                                    <Button type="primary" className="stop" size="small" onClick={addEditHandle} loading={editGroup?.loading}>修改</Button>
+                                </Space>
+                            </div>
+                        </Space>
+                    </div> : <div className={`con ${groupId === item.groupId ? 'select' : ''}`} onClick={() => { setGroupId(item.groupId); onChange?.(item.groupId); setSelectAccData([]) }} key={item.groupId || index}>
+                        <div className="left">
+                            <div className="title">{item.groupName}</div>
+                        </div>
+                        <div className="right">
+                            <Space>
+                                <FormOutlined onClick={(e) => { e.stopPropagation(); setGroupData({ ...item }); setIsNewGrouping(false) }} />
+                                <Popconfirm
+                                    title="确定删除?"
+                                    onConfirm={() => { delGroupHandle(item.groupId) }}
+                                    okText="确定"
+                                    cancelText="取消"
+                                >
+                                    <DeleteOutlined style={{ color: 'red' }} />
+                                </Popconfirm>
+                            </Space>
+                        </div>
+                    </div>}
+
+                </div>)}
+            </Spin>
+        </div>
+    </div>
+}
+
+
+export default React.memo(GroupLeft)

+ 162 - 0
src/pages/launchSystemNew/account/novel/index.less

@@ -0,0 +1,162 @@
+.verticalCenter {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  margin-left: 5px;
+}
+
+.name-wrapper>p {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.boxCol {
+  display: flex;
+
+  strong {
+    width: 25%;
+    text-align: right;
+  }
+
+  span {
+    color: #999;
+    width: 75%;
+  }
+}
+
+.manage {
+  height: calc(100% - 42px);
+  display: flex;
+  justify-content: flex-start;
+
+  &__left {
+    width: calc(100% - 200px);
+  }
+}
+
+.groupLeft {
+  width: 200px;
+  height: 100%;
+  background-color: #fff;
+
+  &_header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    height: 50px;
+    border-bottom: 1px solid rgb(236, 236, 236);
+    background-color: #f8f8f8;
+
+    &>div {
+      font-size: 16px;
+      font-weight: 600;
+      padding: 0 10px;
+    }
+  }
+
+  &_content {
+    height: calc(100% - 50px);
+    overflow-y: auto;
+
+    &_item {
+      &>.con {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        padding: 5px 12px;
+        box-sizing: border-box;
+        height: 50px;
+        border-bottom: 1px solid rgb(236, 236, 236);
+        transition: .1s;
+        box-sizing: border-box;
+        cursor: pointer;
+        border-right: 2px solid #fff;
+
+        >.left {
+          width: calc(100% - 45px);
+
+          >div {
+            overflow: hidden;
+            text-overflow: ellipsis;
+            white-space: nowrap;
+          }
+        }
+
+        >.right {
+          width: 38px;
+        }
+
+        .title {
+          color: #000;
+          font-weight: 500;
+        }
+
+        .subTitle {
+          font-size: 12px;
+          color: rgb(122, 122, 122);
+        }
+
+        &:hover {
+          background-color: #e6f7ff;
+          border-right-color: #1890ff;
+
+          .title {
+            color: #1890ff;
+          }
+
+          .subTitle {
+            color: #1890ff;
+          }
+        }
+
+        &.select {
+          background-color: #e6f7ff;
+          border-right-color: #1890ff;
+
+          .title {
+            color: #1890ff;
+          }
+
+          .subTitle {
+            color: #1890ff;
+          }
+        }
+      }
+
+      &>.edit {
+        padding: 10px 12px;
+        box-sizing: border-box;
+        border-bottom: 1px solid rgb(236, 236, 236);
+
+        // font-size: 12px;
+        .ant-input-affix-wrapper {
+          border-radius: 4px;
+        }
+      }
+    }
+
+  }
+}
+
+
+.dig {
+
+  &_ul {
+    padding: 0;
+    margin-bottom: 0;
+
+    &__li {
+      padding: 4px 16px;
+      box-sizing: border-box;
+      cursor: pointer;
+
+      &:hover {
+        color: #1890ff;
+      }
+    }
+  }
+
+  .ant-popover-inner-content {
+    padding: 0 0 8px 0;
+  }
+}

+ 2 - 2
src/pages/launchSystemNew/account/index.tsx → src/pages/launchSystemNew/account/novel/index.tsx

@@ -6,11 +6,11 @@ import { columnsMp } from './tableConfig'
 import { useAjax } from '@/Hook/useAjax'
 import { getAdAccountListApi, GetAdAccountParams, putAdAccountApi } from '@/services/launchAdq/adAuthorize'
 import style from './index.less'
-import TableData from '../components/TableData'
+import TableData from '../../components/TableData'
 import GroupLeft from './groupLeft'
 import QQAuth from './qqAuto'
 import { MenuFoldOutlined, MenuUnfoldOutlined, PlusOutlined, SwapOutlined } from '@ant-design/icons'
-import TeamMembers from '../components/teamMembers'
+import TeamMembers from '../../components/teamMembers'
 import { getAdAccountAllOfMember, getErpUserAll, getServiceProviderAll, putConfigServiceProvider } from '@/services/launchAdq/adq'
 import AddAccountToGroup from './addAccountToGroup'
 import { delAccountToGroupApi } from '@/services/launchAdq/subgroup'

+ 1 - 1
src/pages/launchSystemNew/account/qqAuto.tsx → src/pages/launchSystemNew/account/novel/qqAuto.tsx

@@ -109,7 +109,7 @@ function QQAuth(props: { qqVisible: boolean, callBack: () => void }) {
                         <Col span={20}>
                             <Radio.Group style={{ width: '100%' }} onChange={adAppIdonChange} defaultValue={data.adAppType}>
                                 <Radio value={0}>小说</Radio>
-                                <Radio value={1}>游戏</Radio>
+                                {/* <Radio value={1}>游戏</Radio> */}
                             </Radio.Group>
                         </Col>
                     </Row>

+ 222 - 0
src/pages/launchSystemNew/account/novel/tableConfig.tsx

@@ -0,0 +1,222 @@
+import { FundStatusEnum } from "@/services/launchAdq/enum"
+import { EditOutlined, FileSearchOutlined, SettingOutlined, SwapOutlined, UploadOutlined, UserSwitchOutlined } from "@ant-design/icons"
+import { Badge, Button, Popconfirm, Space, Tooltip } from "antd"
+import React from "react"
+import DivideIntoGroups from "./divideIntoGroups"
+import './index.less'
+export function columnsMp(edit: (params: any) => void, setOpenServer: (data: any) => void, del: (groupId: number, accountId: number) => void, checkAccount: (value: any[]) => void, changeRecord: (accountId: number, id: number) => void, putUserHandle: (data: any) => void, activeKey: string, userId: string | undefined, groupId?: number, getAdAccountList?: any): any {
+    return [
+        {
+            title: 'ID',
+            dataIndex: 'id',
+            key: 'id',
+            align: 'center',
+            width: 55,
+            fixed: 'left'
+        },
+        {
+            title: '广告主ID',
+            dataIndex: 'accountId',
+            key: 'accountId',
+            align: 'center',
+            width: 80,
+            fixed: 'left'
+        },
+        {
+            title: '类型',
+            dataIndex: 'sourceType',
+            key: 'sourceType',
+            align: 'center',
+            width: 60,
+            render: (a: any, b: any) => {
+                return <span>{a == 0 ? '微信' : 'QQ'}</span>
+            }
+        },
+        {
+            title: '投手',
+            dataIndex: 'putUserInfo',
+            key: 'putUserInfo',
+            width: 70,
+            align: 'center',
+            ellipsis: true,
+            render: (a: any, b: any) => {
+                return <span>{a?.nickname || '-1'}</span>
+            }
+        },
+        {
+            title: '投放助理',
+            dataIndex: 'accountUsers',
+            key: 'accountUsers',
+            width: 70,
+            align: 'center',
+            ellipsis: true,
+            render: (a: any[], b: any) => {
+                return a && a?.length > 0 ? a.map((item: { putUserName: string, putUseId: number }) => item.putUserName).toString() : '-1'
+            }
+        },
+        {
+            title: '投放信息',
+            dataIndex: 'putResourceName',
+            key: 'putResourceName',
+            width: 110,
+            align: 'center',
+            ellipsis: true,
+        },
+        {
+            title: '腾讯备注',
+            dataIndex: 'memo',
+            key: 'memo',
+            align: 'center',
+            width: 100,
+            ellipsis: true,
+        },
+        {
+            title: '本地备注',
+            dataIndex: 'remark',
+            key: 'remark',
+            align: 'center',
+            width: 100,
+            ellipsis: true,
+        },
+        {
+            title: '告警名称',
+            dataIndex: 'warningRuleList',
+            key: 'warningRuleList',
+            align: 'center',
+            width: 90,
+            ellipsis: true,
+            render: (a: any[], b: any) => {
+                return a?.length > 0 ? a?.[0]?.ruleName: '--'
+            }
+        },
+        // {
+        //     title: '公众号信息',
+        //     dataIndex: 'wechatAccountName',
+        //     key: 'wechatAccountName',
+        //     width: 150,
+        //     align: 'center',
+        //     render: (a: any, b: any) => {
+        //         return <div className="verticalCenter">
+        //             <div><strong>{a}</strong></div>
+        //             <div style={{ color: "rgb(136, 136, 136)", fontSize: 13 }}>{b?.wechatAccountId}</div>
+        //         </div>
+        //     }
+        // },
+        {
+            title: '企业名称',
+            dataIndex: 'corporationName',
+            key: 'corporationName',
+            width: 150,
+            align: 'center',
+            ellipsis: true
+        },
+        {
+            title: '服务商',
+            dataIndex: 'serviceProviderName',
+            key: 'serviceProviderName',
+            width: 150,
+            align: 'center',
+            ellipsis: true
+        },
+        // {
+        //     title: '服务商ID列表',
+        //     dataIndex: 'agencyIdList',
+        //     key: 'agencyIdList',
+        //     width: 130,
+        //     align: 'center',
+        //     render: (a: any) => {
+        //         return <Tooltip title={a}>
+        //             <div className="name-wrapper">
+        //                 <p>{ a }</p>
+        //             </div>
+        //         </Tooltip>
+        //     }
+        // },
+        {
+            title: '行业ID',
+            dataIndex: 'systemIndustryId',
+            key: 'systemIndustryId',
+            width: 105,
+            align: 'center',
+            render: (a: any) => {
+                return <Tooltip title={a}>
+                    <div className="name-wrapper">{a}</div>
+                </Tooltip>
+            }
+        },
+        {
+            title: '是否有效',
+            dataIndex: 'enabled',
+            key: 'enabled',
+            align: 'center',
+            width: 60,
+            render: (a: any, b: any) => {
+                return <Badge status={a ? "processing" : "error"} text={a ? '是' : '否'} />
+            }
+        },
+        {
+            title: '授权时间',
+            dataIndex: 'createTime',
+            key: 'createTime',
+            align: 'center',
+            width: 150
+        },
+        {
+            title: '日限额(分)',
+            dataIndex: 'dailyBudget',
+            key: 'dailyBudget',
+            align: 'center',
+            width: 80
+        },
+        {
+            title: '资金状态',
+            dataIndex: 'fundStatus',
+            key: 'fundStatus',
+            align: 'center',
+            width: 80,
+            render: (a: string | number) => {
+                return FundStatusEnum[a]
+            }
+        },
+        {
+            title: '操作',
+            dataIndex: 'cz',
+            key: 'cz',
+            align: 'center',
+            width: 200,
+            fixed: 'right',
+            render: (a: any, b: any) => {
+                return <Space>
+                    <Tooltip title="配置服务商">
+                        <Button size="small" style={{ color: "#00bcd4" }} onClick={() => setOpenServer([b])} icon={<SettingOutlined />}></Button>
+                    </Tooltip>
+                    <Tooltip title="备注">
+                        <Button size="small" style={{ color: '#52c41a' }} onClick={() => edit(b)} icon={<EditOutlined />}></Button>
+                    </Tooltip>
+                    <Tooltip title="切号">
+                        <Button size="small" style={{ color: '#ea5506' }} onClick={() => checkAccount([b])} icon={<SwapOutlined />}></Button>
+                    </Tooltip>
+                    <Tooltip title="变更记录">
+                        <Button size="small" style={{ color: '#4d5aaf' }} onClick={() => changeRecord(b?.accountId, b?.id)} icon={<FileSearchOutlined />}></Button>
+                    </Tooltip>
+                    {activeKey === '1' && <>
+                        {userId == b?.putUserInfo?.userId?.toString() && <Tooltip title="指派投放助理">
+                            <Button size="small" style={{ color: '#0eb83a' }} onClick={() => putUserHandle([b])} icon={<UserSwitchOutlined />}></Button>
+                        </Tooltip>}
+                        {!groupId && <DivideIntoGroups groupIds={b?.groupIds} getAdAccountList={getAdAccountList} accountId={b?.accountId} />}
+                    </>}
+                    {groupId && <Popconfirm
+                        title={`是否把${b?.accountId}移出该分组?`}
+                        onConfirm={() => { del(groupId, b?.accountId) }}
+                        okText="是"
+                        cancelText="否"
+                    >
+                        <Tooltip title="移出分组">
+                            <Button size="small" style={{ color: 'red' }}><UploadOutlined /></Button>
+                        </Tooltip>
+                    </Popconfirm>}
+                </Space>
+            }
+        },
+    ]
+}

+ 78 - 0
src/pages/launchSystemNew/account/novel/tablesConfig.tsx

@@ -0,0 +1,78 @@
+import { EditOutlined } from "@ant-design/icons"
+import { Button, Col, Row } from "antd"
+import React from "react"
+
+// 变更记录
+const columnsCrGdt = (editHandle: (data: any) => void) => {
+    return [
+        {
+            title: '开始时间',
+            dataIndex: 'beginTime',
+            key: 'beginTime',
+            align: 'center',
+            width: 140,
+            fixed: 'left',
+        },
+        {
+            title: '结束时间',
+            dataIndex: 'endTime',
+            key: 'endTime',
+            align: 'center',
+            fixed: 'left',
+            width: 140
+        },
+        {
+            title: '操作人',
+            dataIndex: 'createName',
+            key: 'createName',
+            align: 'center',
+            width: 80,
+            ellipsis: true,
+            render: (a: any) => {
+                return <span>{a || '<空>'}</span>
+            }
+        },
+        {
+            title: '资源名称',
+            dataIndex: 'putResourceName',
+            key: 'putResourceName',
+            width: 140,
+            ellipsis: true,
+            align: 'center',
+            render: (a: any, b: any) => {
+                return <span>{a || '<空>'}</span>
+            }
+        },
+        {
+            title: '资源标识',
+            dataIndex: 'putResourceKey',
+            key: 'putResourceKey',
+            ellipsis: true,
+            width: 180,
+            render: (a: any, b: any) => {
+                return <span>{a || '<空>'}</span>
+            }
+        },
+        {
+            title: '授权者',
+            dataIndex: 'putUserName',
+            key: 'putUserName',
+            ellipsis: true,
+            width: 80
+        },
+        {
+            title: '操作',
+            dataIndex: 'cz',
+            key: 'cz',
+            render: (a: string, b: any) => (
+                <Row gutter={[10, 0]}>
+                    <Col><Button type="link" size="small" style={{ fontSize: 12 }} icon={<EditOutlined />} onClick={() => { editHandle(b) }}>编辑</Button></Col>
+                </Row>
+            )
+        }
+    ]
+}
+
+export {
+    columnsCrGdt
+}

+ 3 - 2
src/pages/launchSystemNew/adq/ad/adIdSearch.tsx

@@ -3,13 +3,14 @@ import React, { useEffect, useState } from "react"
 import style from './index.less'
 import Draggable from "react-draggable"
 import { CloseCircleOutlined, SearchOutlined, SyncOutlined } from "@ant-design/icons"
-import { allPlanProps, getAdqAccountListApi, getAllPlanListApi } from "@/services/adMonitor/adMonitor"
+import { allPlanProps, getAllPlanListApi } from "@/services/adMonitor/adMonitor"
 import { useAjax } from "@/Hook/useAjax"
 import { ColumnsType } from "antd/lib/table"
 import { GGStateData } from "@/pages/adMonitor/adMonitorList/data"
 import { GUANGGAOZHUANGTAI } from "@/pages/adMonitor/adMonitorList/enum"
 import SearchSelect from "./searchSelect"
 import moment from "moment"
+import { getAdAccountApi } from "@/services/launchAdq/adAuthorize"
 
 interface Props {
     userId: string
@@ -28,7 +29,7 @@ const AdIdSearch: React.FC<Props> = ({ userId, onChange }) => {
 
     const getAllPlanList = useAjax((params) => getAllPlanListApi(params))
     // 获取广告账号列表
-    const getAdqAccountList = useAjax(() => getAdqAccountListApi(), { formatResult: true })
+    const getAdqAccountList = useAjax(() => getAdAccountApi(), { formatResult: true })
     /***************************/
 
     useEffect(() => {

+ 0 - 7
src/pages/launchSystemNew/adq/ad/index.tsx

@@ -9,13 +9,11 @@ import { putAdqAdgroupsSync, getAdqAdgroupsList, delListAdqAdgroupsApi, newEditA
 import { CopyOutlined, DeleteOutlined, DownOutlined, ExclamationCircleOutlined, FieldTimeOutlined, FormOutlined, PauseCircleOutlined, PlayCircleOutlined, QuestionCircleOutlined, SyncOutlined, TransactionOutlined } from '@ant-design/icons'
 import UpdateAd from './updateAd'
 import Copy from './copy'
-import PlanDetail from '@/pages/adMonitor/adMonitorList/components/planDetail'
 import { txAdConfig } from '../config'
 import Log from '../log'
 import SetEarlyWarning from '@/components/EarlyWarning/setEarlyWarning'
 import CrowdPackModal from '../../components/crowdPackModal'
 import './index.less'
-import AdIdSearch from './adIdSearch'
 import Details from '@/pages/adMonitor/adMonitorList/components/Details'
 
 type Props = {
@@ -582,11 +580,6 @@ const Ad: React.FC<Props> = (props) => {
                     <Col>
                         <Button type='dashed' onClick={() => { setCzjlShow(true) }}>操作记录</Button>
                     </Col>
-                    <Col>
-                        <AdIdSearch userId={userId} onChange={(e) => {
-                            getList({ ...queryFrom, pageNum: 1, adgroupIdList: e })
-                        }} />
-                    </Col>
                 </Row>
             </Space>}
             rowSelection={{

+ 0 - 108
src/pages/launchSystemNew/adq/adAccount/index.tsx

@@ -1,108 +0,0 @@
-
-import { useAjax } from '@/Hook/useAjax'
-import { Row, message, Input, Space, Button } from 'antd'
-import React, { useEffect, useState, useCallback } from 'react'
-import TableData from '../../components/TableData'
-import tableConfig from './tableConfig'
-import { putAdqAdAccountSyncByIds, getAdqAdAccountList } from '@/services/launchAdq/adq'
-import { getAdAccountListApi } from '@/services/launchAdq/adAuthorize'
-type Props = {
-    accountId: string,
-    adAccountId: string,
-    userId: string,
-    queryParmas: {
-        accountId?: string,//账户ID
-        campaignId?: string,//计划ID
-        adgroupId?: string,//广告ID
-        adcreativeId?: string,//创意ID
-        pageId?: string,//落地页ID
-        targetingId?: string,//定向ID}
-    },
-    tableIdClick: (props: {
-        activeKey: string, parma: {
-            accountId?: string,//账户ID
-            campaignId?: string,//计划ID
-            adgroupId?: string,//广告ID
-            adcreativeId?: string,//创意ID
-            pageId?: string,//落地页ID
-            targetingId?: string,//定向ID
-        }
-    }) => void
-}
-function AdAccount(props: Props) {
-    let { adAccountId, accountId, userId, tableIdClick, queryParmas } = props
-    let [selectedRowKeys, setSelectedRowKeys] = useState<any[]>([])
-    const [queryForm, setQueryForm] = useState<{
-        pageNum: number;
-        pageSize: number;
-        accountIds: any[];
-        adcreativeName?: string;
-    }>({ pageNum: 1, pageSize: 20, accountIds: [] })
-    // api方法
-    const listAjax = useAjax((params) => getAdAccountListApi(params), { formatResult: true })
-    const syncAjax = useAjax((params) => putAdqAdAccountSyncByIds(params))
-    useEffect(() => {
-        getList(queryForm)
-    }, [accountId, userId])
-    // 获取列表
-    const getList = useCallback((params?: any) => {
-        listAjax.run({ ...params, putUserId: userId })
-    }, [userId, listAjax])
-    // 同步 
-    const sync = useCallback(() => {
-        if (selectedRowKeys?.length === 0) {
-            message.error('请勾选要同步的广点通账号!')
-            return
-        }
-        syncAjax.run(selectedRowKeys?.map((item: any) => item.accountId)).then(res => {
-            res && listAjax.refresh()
-            res ? message.success('同步成功!') : message.error('同步失败!')
-
-        })
-    }, [adAccountId, listAjax, selectedRowKeys])
-    return <div>
-        <TableData
-            isCard={false}
-            columns={() => tableConfig(tableIdClick)}
-            ajax={listAjax}
-            syncAjax={sync}
-            dataSource={listAjax?.data?.data?.records}
-            loading={listAjax?.loading || syncAjax?.loading}
-            scroll={{ y: 550 }}
-            total={listAjax?.data?.data?.total}
-            page={listAjax?.data?.data?.current}
-            pageSize={listAjax?.data?.data?.size}
-            leftChild={<>
-                <Space>
-                    <Input
-                        placeholder='广告账号'
-                        allowClear
-                        style={{ width: 150 }}
-                        onChange={(e) => {
-                            let value = e.target.value
-                            let arr: any = []
-                            if (value) {
-                                value = value.replace(/[,,\s]/g, ',')
-                                arr = value.split(',').filter((a: any) => a)
-                            }
-                            setQueryForm({ ...queryForm, accountIds: arr })
-                        }}
-                    />
-                    <Button type='primary' onClick={() => { getList({ ...queryForm, pageNum: 1 }) }}>搜索</Button>
-                </Space>
-            </>}
-            rowSelection={{
-                onChange: (selectedRowKeys: React.Key[], selectedRows: any[]) => {
-                    setSelectedRowKeys(selectedRows)
-                }
-            }}
-            onChange={(props: any) => {
-                let { sortData, pagination } = props
-                let { current, pageSize } = pagination
-                setQueryForm({ ...queryForm, pageNum: current, pageSize })
-                getList({ ...queryForm, pageNum: current, pageSize })
-            }}
-        />
-    </div>
-}
-export default AdAccount

+ 0 - 74
src/pages/launchSystemNew/adq/adAccount/tableConfig.tsx

@@ -1,74 +0,0 @@
-import { FundStatusEnum, } from '@/services/launchAdq/enum'
-import React from 'react'
-import { Badge, Space } from 'antd'
-import { copy } from '@/utils/utils'
-import { CopyOutlined } from '@ant-design/icons'
-function tableConfig(tableIdClick: any): any {
-    return [
-        {
-            title: 'ID',
-            dataIndex: 'id',
-            key: 'id',
-            align: 'center',
-            width: 50
-        },
-        {
-            title: '账号ID',
-            dataIndex: 'accountId',
-            key: 'accountId',
-            align: 'center',
-            width: 90,
-            render: (a: string) => {
-                return <Space>
-                     <a onClick={() => copy(a)} >{a}</a>
-                </Space>
-            }
-        },
-        {
-            title: '腾讯备注',
-            dataIndex: 'memo',
-            key: 'memo',
-            align: 'center',
-            width: 100,
-            fixed: 'left',
-            ellipsis: true,
-        },
-        {
-            title: '本地备注',
-            dataIndex: 'remark',
-            key: 'remark',
-            align: 'center',
-            width: 100,
-            fixed: 'left',
-            ellipsis: true,
-        },
-        {
-            title: '账户余额(分)',
-            dataIndex: 'balance',
-            key: 'balance',
-            align: 'center',
-            width: 150,
-        },
-        {
-            title: '资金状态',
-            dataIndex: 'fundStatus',
-            key: 'fundStatus',
-            align: 'center',
-            width: 130,
-            render: (a: string | number) => {
-                return FundStatusEnum[a]
-            }
-        },
-        {
-            title: '是否有效',
-            dataIndex: 'enabled',
-            key: 'enabled',
-            align: 'center',
-            width: 130,
-            render: (a: any, b: any) => {
-                return <Badge status={a ? "processing" : "error"} text={a ? '是' : '否'} />
-            }
-        },
-    ]
-}
-export default tableConfig

+ 1 - 3
src/pages/launchSystemNew/adq/index.tsx

@@ -1,8 +1,7 @@
 import React, { useState, useEffect, useCallback } from 'react'
-import { Badge, Button, Card, Col, Menu, Row, Select, Tabs, Tag } from 'antd';
+import { Button, Card, Menu, Select, Tabs } from 'antd';
 import style from './index.less'
 import Campaign from './campaign';
-import AdAccount from './adAccount';
 import Ad from './ad';
 import Creative from './creative';
 import LandingPage from './landingPage';
@@ -15,7 +14,6 @@ import Promoted from './promoted';
 const { TabPane } = Tabs;
 let Menus: any = Menu
 const tabsConfig = [
-    // { key: '1', tab: '账户信息', jsx: (props: any) => <AdAccount {...props} /> },
     { key: '3', tab: '广告', jsx: (props: any) => <Ad {...props} /> },
     { key: '2', tab: '计划', jsx: (props: any) => <Campaign {...props} /> },
     { key: '4', tab: '创意', jsx: (props: any) => <Creative {...props} /> },

+ 2 - 2
src/pages/toutiao/ttAccountManage/index.tsx

@@ -4,7 +4,7 @@ import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons'
 import { Select, Tabs } from 'antd'
 import React, { useCallback, useEffect, useState } from 'react'
 import style from './index.less'
-import { getAdAccountAllOfMember, getErpUserAll } from '@/services/launchAdq/adq'
+import { getAdAccountAllOfMemberAll, getErpUserAll } from '@/services/launchAdq/adq'
 import { useAjax } from '@/Hook/useAjax'
 import TableData from '@/pages/launchSystemNew/components/TableData'
 import { oceanengine_adAccount_listOfUser } from '@/services/toutiao/ttAccountManage'
@@ -17,7 +17,7 @@ function ttAccountManage() {
     const [showLeft, setShowLeft] = useState<boolean>(false)
     const [queryForm, setQueryForm] = useState<any>({ pageNum: 1, pageSize: 20 })
 
-    const allOfMember = useAjax(() => getAdAccountAllOfMember(), { formatResult: true })
+    const allOfMember = useAjax(() => getAdAccountAllOfMemberAll(), { formatResult: true })
     const erpUserALL = useAjax(() => getErpUserAll(), { formatResult: true })
     const getAdAccountList = useAjax((params) => oceanengine_adAccount_listOfUser(params), { formatResult: true })
 

+ 0 - 11
src/services/adMonitor/adMonitor.ts

@@ -281,17 +281,6 @@ export async function addDelAccountApi(data: { accountIdList: number[], groupId:
     })
 }
 
-/**
- * 获取广告账户
- * @returns 
- */
-export async function getAdqAccountListApi() {
-    return request(`${api}/adq/adAccount/allOfUser`, {
-        method: 'Get'
-    })
-}
-
-
 /**
  * NEW 广告消耗趋势 获取今日计划总消耗图谱 折线图
  * @param data 

+ 9 - 2
src/services/launchAdq/adAuthorize.ts

@@ -13,7 +13,14 @@ export interface GetAdAccountParams {
     putUserId?: number
 }
 export async function getAdAccountListApi(data: GetAdAccountParams) {
-    return request(api + '/adq/adAccount/accountList', {
+    return request(api + '/adq/adAccount/accountListOfNovel', {
+        method: 'POST',
+        data
+    });
+}
+
+export async function getAdAccountGameListApi(data: GetAdAccountParams) {
+    return request(api + '/adq/adAccount/accountListOfGame', {
         method: 'POST',
         data
     });
@@ -24,7 +31,7 @@ export async function getAdAccountListApi(data: GetAdAccountParams) {
  * @returns 
  */
 export async function getAdAccountApi() {
-    return request(api + '/adq/adAccount/allOfUser', {
+    return request(api + '/adq/adAccount/allOfUserOfNovel', {
         method: 'GET',
     });
 }

+ 22 - 3
src/services/launchAdq/adq.ts

@@ -4,9 +4,17 @@ import { api } from '../api';
 /**
  * 获取组员及组员账号列表
 */
-export async function getAdAccountAllOfMember() {
+export async function getAdAccountAllOfMemberAll() {
   return request(api + '/adq/adAccount/allOfMember');
 }
+
+export async function getAdAccountAllOfMember() {
+  return request(api + '/adq/adAccount/allOfMemberOfNovel');
+}
+
+export async function getAdAccountAllOfMemberGame() {
+  return request(api + '/adq/adAccount/allOfMemberOfGame');
+}
 /***
  * 无权限限制获取全部用户列表
  * 
@@ -29,7 +37,18 @@ export async function getAdqAdAccountList(params: {
   userId?: string;//用户ID
   accountIds?: string[];//账号本地ID
 }) {
-  return request(api + '/adq/adAccount/list', {
+  return request(api + '/adq/adAccount/listOfNovel', {
+    method: 'POST',
+    data: params,
+  });
+}
+export async function getAdqAdAccountGameList(params: {
+  pageNum: number;
+  pageSize: number;
+  userId?: string;//用户ID
+  accountIds?: string[];//账号本地ID
+}) {
+  return request(api + '/adq/adAccount/listOfGame', {
     method: 'POST',
     data: params,
   });
@@ -441,7 +460,7 @@ export async function adUserTagApi(data: AduserTagProps) {
  * @param data 
  * @returns 
  */
-export async function delUserTagApi(data: {accountId: string, adgroupId: string}) {
+export async function delUserTagApi(data: { accountId: string, adgroupId: string }) {
   return request(api + `/tencentMonitor/adUserTag/removeTag/${data.accountId}/${data.adgroupId}`, {
     method: 'DELETE'
   });

+ 0 - 5
src/services/toutiao/ttAccountManage.ts

@@ -3,11 +3,6 @@ import { api } from '../api'
 
 
 
-
-/**用户所有头条账号*/ 
-// export async function oceanengine_adAccount_allOfUser(mpId: number) {
-//     return request(`${api}/oceanengine/adAccount/allOfUser`);
-// }
 /**所有有该账号操作权限的用户 投放助理回填*/ 
 export async function oceanengine_adAccount_accountOperationUser(accountId: number) {
     return request(`${api}/oceanengine/adAccount/accountOperationUser/${accountId}`);