wjx 7 月之前
父节点
当前提交
4ce6455f72

+ 5 - 2
src/Hook/useAjax.tsx

@@ -62,9 +62,12 @@ export function useAjax(fnc: (params?: any) => Promise<any>, options?: { type: '
             }
             }
             return res//返回data
             return res//返回data
         }).catch(err => {
         }).catch(err => {
-            console.log(err)
+            console.log('err---->',err)
             setLoding(() => false)//关闭请求加载
             setLoding(() => false)//关闭请求加载
-            return err
+            return {
+                code: 500,
+                data: false
+            }
         })
         })
     }
     }
     async function refresh() {//上次的请求
     async function refresh() {//上次的请求

+ 2 - 1
src/app.tsx

@@ -27,6 +27,7 @@ import { ReactComponent as AppEveryDataSvg } from '@/assets/appEveryData.svg'
 import { ReactComponent as AdListSvg } from '@/assets/adList.svg'
 import { ReactComponent as AdListSvg } from '@/assets/adList.svg'
 import { ReactComponent as DynamicSvg } from '@/assets/dynamic.svg'
 import { ReactComponent as DynamicSvg } from '@/assets/dynamic.svg'
 import versions from './utils/versions';
 import versions from './utils/versions';
+import data from '@@@/mock/data';
 
 
 
 
 interface CurrentUser {
 interface CurrentUser {
@@ -310,7 +311,7 @@ export const request: any = {
                 }
                 }
             }
             }
             return {
             return {
-                ...resData,
+                ...resData
             }
             }
         },
         },
     },
     },

+ 12 - 12
src/pages/iaaData/ocenaengineIaa/appEveryDayData/tableConfig.tsx

@@ -98,11 +98,11 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
                 },
                 },
                 {
                 {
                     title: '千次曝光成本(广告)', dataIndex: 'avgShowCost', label: '广告媒体端指标', align: 'right', width: 80, default: 13, sorter: true, className: 'purple1ColorClass',
                     title: '千次曝光成本(广告)', dataIndex: 'avgShowCost', label: '广告媒体端指标', align: 'right', width: 80, default: 13, sorter: true, className: 'purple1ColorClass',
-                    render: (a: number) => <Statistic value={a || 0} />
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
                 },
                 },
                 {
                 {
                     title: '点击均价(广告)', dataIndex: 'avgClickCost', label: '广告媒体端指标', align: 'right', width: 65, default: 14, sorter: true, className: 'purple1ColorClass',
                     title: '点击均价(广告)', dataIndex: 'avgClickCost', label: '广告媒体端指标', align: 'right', width: 65, default: 14, sorter: true, className: 'purple1ColorClass',
-                    render: (a: number) => <Statistic value={a || 0} />
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
                 },
                 },
                 {
                 {
                     title: '点击率(广告)', dataIndex: 'ctr', label: '广告媒体端指标', align: 'center', width: 80, default: 15, sorter: true, className: 'purple1ColorClass',
                     title: '点击率(广告)', dataIndex: 'ctr', label: '广告媒体端指标', align: 'center', width: 80, default: 15, sorter: true, className: 'purple1ColorClass',
@@ -114,7 +114,7 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
                 },
                 },
                 {
                 {
                     title: '转化目标成本', dataIndex: 'convertCost', label: '广告媒体端指标', align: 'right', width: 65, default: 17, sorter: true, className: 'purple1ColorClass',
                     title: '转化目标成本', dataIndex: 'convertCost', label: '广告媒体端指标', align: 'right', width: 65, default: 17, sorter: true, className: 'purple1ColorClass',
-                    render: (a: number) => <Statistic value={a || 0} />
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
                 },
                 },
                 {
                 {
                     title: '转化目标率', dataIndex: 'convertRate', label: '广告媒体端指标', align: 'center', width: 80, default: 18, sorter: true, className: 'purple1ColorClass',
                     title: '转化目标率', dataIndex: 'convertRate', label: '广告媒体端指标', align: 'center', width: 80, default: 18, sorter: true, className: 'purple1ColorClass',
@@ -126,7 +126,7 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
                 },
                 },
                 {
                 {
                     title: '激活成本(广告)', dataIndex: 'activeCost', label: '广告媒体端指标', align: 'right', width: 65, default: 20, sorter: true, className: 'purple1ColorClass',
                     title: '激活成本(广告)', dataIndex: 'activeCost', label: '广告媒体端指标', align: 'right', width: 65, default: 20, sorter: true, className: 'purple1ColorClass',
-                    render: (a: number) => <Statistic value={a || 0} />
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
                 },
                 },
                 {
                 {
                     title: '激活率(广告)', dataIndex: 'activeRate', label: '广告媒体端指标', align: 'center', width: 80, default: 21, sorter: true, className: 'purple1ColorClass',
                     title: '激活率(广告)', dataIndex: 'activeRate', label: '广告媒体端指标', align: 'center', width: 80, default: 21, sorter: true, className: 'purple1ColorClass',
@@ -138,7 +138,7 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
                 },
                 },
                 {
                 {
                     title: '注册成本(广告)', dataIndex: 'activeRegisterCost', label: '广告媒体端指标', align: 'right', width: 65, default: 23, sorter: true, className: 'purple1ColorClass',
                     title: '注册成本(广告)', dataIndex: 'activeRegisterCost', label: '广告媒体端指标', align: 'right', width: 65, default: 23, sorter: true, className: 'purple1ColorClass',
-                    render: (a: number) => <Statistic value={a || 0} />
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
                 },
                 },
                 {
                 {
                     title: '注册率(广告)', dataIndex: 'activeRegisterRate', label: '广告媒体端指标', align: 'center', width: 80, default: 24, sorter: true, className: 'purple1ColorClass',
                     title: '注册率(广告)', dataIndex: 'activeRegisterRate', label: '广告媒体端指标', align: 'center', width: 80, default: 24, sorter: true, className: 'purple1ColorClass',
@@ -336,15 +336,15 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
                 },
                 },
                 {
                 {
                     title: '今日新增用户成本(应用)', dataIndex: 'newUserCost', label: '应用媒体数据', align: 'right', width: 80, sorter: true,
                     title: '今日新增用户成本(应用)', dataIndex: 'newUserCost', label: '应用媒体数据', align: 'right', width: 80, sorter: true,
-                    render: (a: number) => <Statistic value={a || 0} />
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
                 },
                 },
                 {
                 {
                     title: '人均新增成本(应用)', dataIndex: 'avgNewCost', label: '应用媒体数据', align: 'right', width: 80, sorter: true,
                     title: '人均新增成本(应用)', dataIndex: 'avgNewCost', label: '应用媒体数据', align: 'right', width: 80, sorter: true,
-                    render: (a: number) => <Statistic value={a || 0} />
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
                 },
                 },
                 {
                 {
                     title: '人均活跃成本(应用)', dataIndex: 'avgActiveCost1', label: '应用媒体数据', align: 'right', width: 80, sorter: true,
                     title: '人均活跃成本(应用)', dataIndex: 'avgActiveCost1', label: '应用媒体数据', align: 'right', width: 80, sorter: true,
-                    render: (a: number) => <Statistic value={a || 0} />
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
                 },
                 },
                 {
                 {
                     title: '分享次数', dataIndex: 'shareTime', label: '应用媒体数据', align: 'center', width: 70, sorter: true,
                     title: '分享次数', dataIndex: 'shareTime', label: '应用媒体数据', align: 'center', width: 70, sorter: true,
@@ -398,7 +398,7 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
                 },
                 },
                 {
                 {
                     title: '首日激活用户成本(应用)', dataIndex: 'costPerAction', label: '应用媒体数据', align: 'right', width: 85, sorter: true,
                     title: '首日激活用户成本(应用)', dataIndex: 'costPerAction', label: '应用媒体数据', align: 'right', width: 85, sorter: true,
-                    render: (a: number) => <Statistic value={a || 0} />
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
                 },
                 },
                 {
                 {
                     title: '注册用户首日激活率(应用)', dataIndex: 'firstUserRate', label: '应用媒体数据', align: 'center', width: 90, sorter: true,
                     title: '注册用户首日激活率(应用)', dataIndex: 'firstUserRate', label: '应用媒体数据', align: 'center', width: 90, sorter: true,
@@ -406,7 +406,7 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
                 },
                 },
                 {
                 {
                     title: '激活首日新增广告收入(应用)', dataIndex: 'newAdIncome', label: '应用媒体数据', align: 'right', width: 90, sorter: true,
                     title: '激活首日新增广告收入(应用)', dataIndex: 'newAdIncome', label: '应用媒体数据', align: 'right', width: 90, sorter: true,
-                    render: (a: number) => <Statistic value={a || 0} />
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
                 },
                 },
                 {
                 {
                     title: '激活首日新增广告ROI(应用)', dataIndex: 'newAdRoi', label: '应用媒体数据', align: 'center', width: 90, sorter: true,
                     title: '激活首日新增广告ROI(应用)', dataIndex: 'newAdRoi', label: '应用媒体数据', align: 'center', width: 90, sorter: true,
@@ -462,11 +462,11 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
                 },
                 },
                 {
                 {
                     title: '累计广告变现收入(应用)', dataIndex: 'totalAdIncome', label: '应用媒体数据', align: 'right', width: 90, sorter: true,
                     title: '累计广告变现收入(应用)', dataIndex: 'totalAdIncome', label: '应用媒体数据', align: 'right', width: 90, sorter: true,
-                    render: (a: number) => <Statistic value={a || 0} />
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
                 },
                 },
                 {
                 {
                     title: '广告变现累计利润(应用)', dataIndex: 'totalAdProfit', label: '应用媒体数据', align: 'right', width: 90, sorter: true,
                     title: '广告变现累计利润(应用)', dataIndex: 'totalAdProfit', label: '应用媒体数据', align: 'right', width: 90, sorter: true,
-                    render: (a: number) => <Statistic value={a || 0} />
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
                 },
                 },
                 {
                 {
                     title: '广告变现成本利润率(应用)', dataIndex: 'totalAdProfitRate', label: '应用媒体数据', align: 'center', width: 90, sorter: true,
                     title: '广告变现成本利润率(应用)', dataIndex: 'totalAdProfitRate', label: '应用媒体数据', align: 'center', width: 90, sorter: true,

+ 120 - 0
src/pages/iaaSystem/manage/channel/configApp.tsx

@@ -0,0 +1,120 @@
+import { useAjax } from "@/Hook/useAjax"
+import { updataAppApi } from "@/services/iaaSystem/channel"
+import { Form, message, Modal, Select, DatePicker } from "antd"
+import { RangePickerProps } from "antd/lib/date-picker"
+import { DefaultOptionType } from "antd/lib/select"
+import moment from "moment"
+import React from "react"
+
+interface Props {
+    appList: DefaultOptionType[]
+    selectedRows: any[]
+    visible?: boolean
+    onClose?: () => void
+    onChange?: () => void
+    initialValues?: any
+}
+const ConfigApp: React.FC<Props> = ({ appList, selectedRows, visible, onClose, onChange, initialValues }) => {
+
+    /***************************************/
+    const [form] = Form.useForm();
+    const putStatus = Form.useWatch('putStatus', form)
+    const putStartDate = Form.useWatch('putStartDate', form)
+    const putEndData = Form.useWatch('putEndData', form)
+
+    const updataApp = useAjax((params) => updataAppApi(params))
+    /***************************************/
+
+    const handleOk = async () => {
+        form.submit()
+        let data: any = await form.validateFields()
+        if (data?.putStartDate) {
+            data.putStartDate = moment(data.putStartDate).format('YYYY-MM-DD')
+        }
+        if (data?.putEndData) {
+            data.putEndData = moment(data.putEndData).format('YYYY-MM-DD')
+        }
+        updataApp.run({ ...data, agentIdList: selectedRows.map(item => item.id) }).then(res => {
+            if (res?.data) {
+                message.success('变更成功')
+                onChange && onChange()
+            }
+        })
+    }
+
+    // eslint-disable-next-line arrow-body-style
+    const disabledStartDate: RangePickerProps['disabledDate'] = current => {
+        // Can not select days before today and today
+        if (putEndData) {
+            return current && current > moment(putEndData).endOf('day');
+        }
+        return current && current > moment().endOf('day');
+    };
+
+    const disabledEmdDate: RangePickerProps['disabledDate'] = current => {
+        // Can not select days before today and today
+        if (putStartDate) {
+            return current && (current > moment().endOf('day') || putStartDate >= current);
+        }
+        return current && current > moment().endOf('day');
+    };
+
+    return <Modal
+        title={<strong>变更应用</strong>}
+        open={visible}
+        onCancel={onClose}
+        onOk={handleOk}
+        confirmLoading={updataApp.loading}
+    >
+        <Form
+            name="basicChannelApp"
+            layout="vertical"
+            form={form}
+            autoComplete="off"
+            colon={false}
+            initialValues={{ ...initialValues }}
+        >
+            <Form.Item label={<strong>应用</strong>} name="iaaAppId" rules={[{ required: true, message: '请选择应用!' }]}>
+                <Select
+                    placeholder="请选择应用"
+                    filterOption={(input, option) =>
+                        ((option?.label ?? '') as any).toLowerCase().includes(input.toLowerCase())
+                    }
+                    allowClear
+                    showSearch
+                    options={appList}
+                />
+            </Form.Item>
+            <Form.Item label={<strong>投放状态</strong>} name="putStatus" rules={[{ required: true, message: '请选择投放状态!' }]}>
+                <Select
+                    placeholder="请选择投放状态"
+                    options={[
+                        {
+                            value: 'PUT_STATUS_PUT_ING',
+                            label: '投放中',
+                        },
+                        {
+                            value: 'PUT_STATUS_PUT_STOP',
+                            label: '投放结束',
+                        }
+                    ]}
+                    filterOption={(input, option) =>
+                        ((option?.label ?? '') as any).toLowerCase().includes(input.toLowerCase())
+                    }
+                    showSearch
+                />
+            </Form.Item>
+            {['PUT_STATUS_PUT_ING', 'PUT_STATUS_PUT_STOP'].includes(putStatus) ? <Form.Item label={<strong>投放开始时间</strong>} name="putStartDate" rules={[{ required: true, message: '请选择投放开始时间!' }]}>
+                {/* @ts-ignore  */}
+                <DatePicker placeholder="投放开始时间" disabledDate={disabledStartDate} />
+            </Form.Item> : null}
+            {['PUT_STATUS_PUT_STOP'].includes(putStatus) ? <Form.Item label={<strong>投放结束时间</strong>} name="putEndData" rules={[{ required: true, message: '请选择投放结束时间!' }]}>
+                {/* @ts-ignore  */}
+                <DatePicker placeholder="投放结束时间" disabledDate={disabledEmdDate} />
+            </Form.Item> : null}
+
+        </Form>
+    </Modal>
+}
+
+export default React.memo(ConfigApp)

+ 22 - 2
src/pages/iaaSystem/manage/channel/configPutStatus.tsx

@@ -1,6 +1,8 @@
 import { useAjax } from "@/Hook/useAjax";
 import { useAjax } from "@/Hook/useAjax";
 import { iaaConfigPutStatusApi } from "@/services/iaaSystem/channel";
 import { iaaConfigPutStatusApi } from "@/services/iaaSystem/channel";
-import { Form, message, Modal, Select } from "antd";
+import { Form, message, Modal, Select, DatePicker } from "antd";
+import { RangePickerProps } from "antd/lib/date-picker";
+import moment from "moment";
 import React from "react"
 import React from "react"
 
 
 interface Props {
 interface Props {
@@ -14,6 +16,7 @@ const ConfigPutStatus: React.FC<Props> = ({ selectedRows, onChange, visible, onC
 
 
     /*******************************/
     /*******************************/
     const [form] = Form.useForm<IAAAPI.AddIaaAgentProps>();
     const [form] = Form.useForm<IAAAPI.AddIaaAgentProps>();
+    const putStatus = Form.useWatch('putStatus', form)
 
 
     const iaaConfigPutStatus = useAjax((params) => iaaConfigPutStatusApi(params))
     const iaaConfigPutStatus = useAjax((params) => iaaConfigPutStatusApi(params))
     /*******************************/
     /*******************************/
@@ -22,7 +25,10 @@ const ConfigPutStatus: React.FC<Props> = ({ selectedRows, onChange, visible, onC
     const handleOk = async () => {
     const handleOk = async () => {
         form.submit()
         form.submit()
         let data: any = await form.validateFields()
         let data: any = await form.validateFields()
-        iaaConfigPutStatus.run({...data, agentIds: selectedRows.map(item => item.id).toString()}).then(res => {
+        if (data?.dateTime) {
+            data.dateTime = moment(data.dateTime).format('YYYY-MM-DD')
+        }
+        iaaConfigPutStatus.run({...data, agentIdList: selectedRows.map(item => item.id)}).then(res => {
             if (res?.data) {
             if (res?.data) {
                 message.success('变更成功')
                 message.success('变更成功')
                 onChange && onChange()
                 onChange && onChange()
@@ -30,6 +36,12 @@ const ConfigPutStatus: React.FC<Props> = ({ selectedRows, onChange, visible, onC
         })
         })
     }
     }
 
 
+    // eslint-disable-next-line arrow-body-style
+    const disabledStartDate: RangePickerProps['disabledDate'] = current => {
+        // Can not select days before today and today
+        return current && current > moment().endOf('day');
+    };
+
     return <Modal
     return <Modal
         title={<strong>{'变更投放状态'}</strong>}
         title={<strong>{'变更投放状态'}</strong>}
         open={visible}
         open={visible}
@@ -59,6 +71,14 @@ const ConfigPutStatus: React.FC<Props> = ({ selectedRows, onChange, visible, onC
                     ]}
                     ]}
                 />
                 />
             </Form.Item>
             </Form.Item>
+            {['PUT_STATUS_PUT_ING'].includes(putStatus) ? <Form.Item label={<strong>投放开始时间</strong>} name="dateTime" rules={[{ required: true, message: '请选择投放开始时间!' }]}>
+                {/* @ts-ignore  */}
+                <DatePicker placeholder="投放开始时间" disabledDate={disabledStartDate} />
+            </Form.Item> : null}
+            {['PUT_STATUS_PUT_STOP'].includes(putStatus) ? <Form.Item label={<strong>投放结束时间</strong>} name="dateTime" rules={[{ required: true, message: '请选择投放结束时间!' }]}>
+                {/* @ts-ignore  */}
+                <DatePicker placeholder="投放结束时间" disabledDate={disabledStartDate}/>
+            </Form.Item> : null}
         </Form>
         </Form>
     </Modal> 
     </Modal> 
 }
 }

+ 51 - 6
src/pages/iaaSystem/manage/channel/index.tsx

@@ -9,10 +9,12 @@ import ModalChannel from "./modalChannel";
 import { getBackPolicyAllListApi } from "@/services/iaaSystem/backPolicy";
 import { getBackPolicyAllListApi } from "@/services/iaaSystem/backPolicy";
 import ConfigPutStatus from "./configPutStatus";
 import ConfigPutStatus from "./configPutStatus";
 import ConfigBackPolicy from "./configBackPolicy";
 import ConfigBackPolicy from "./configBackPolicy";
-import { getAllOfOwnerUserApi, getTtAllUserListApi } from "@/services/iaaSystem";
+import { getAllOfOwnerUserApi } from "@/services/iaaSystem";
 import { getAppAuthListApi } from "@/services/iaaSystem/application";
 import { getAppAuthListApi } from "@/services/iaaSystem/application";
 import { DefaultOptionType } from "antd/lib/select";
 import { DefaultOptionType } from "antd/lib/select";
 import { copy } from "@/utils/utils";
 import { copy } from "@/utils/utils";
+import ConfigApp from "./configApp";
+import Log from "./log";
 
 
 
 
 /**
 /**
@@ -31,11 +33,13 @@ const Channel: React.FC = () => {
     const [backPolicyVisible, setBackPolicyVisible] = useState<boolean>(false)
     const [backPolicyVisible, setBackPolicyVisible] = useState<boolean>(false)
     const [appList, setAppList] = useState<DefaultOptionType[]>([])
     const [appList, setAppList] = useState<DefaultOptionType[]>([])
     const [appObj, setAppObj] = useState<any>({})
     const [appObj, setAppObj] = useState<any>({})
+    const [appVisible, setAppVisible] = useState<boolean>(false)
+    const [selectData, setSelectData] = useState<any>()
+    const [logData, setLogData] = useState<{ data: any, visible: boolean }>({ data: undefined, visible: false })
 
 
     const getFolderList = useAjax((params) => getIaaAgentListApi(params), { type: 'table' })
     const getFolderList = useAjax((params) => getIaaAgentListApi(params), { type: 'table' })
     const getBackPolicyAllList = useAjax(() => getBackPolicyAllListApi())
     const getBackPolicyAllList = useAjax(() => getBackPolicyAllListApi())
     const getAllOfOwnerUser = useAjax(() => getAllOfOwnerUserApi())
     const getAllOfOwnerUser = useAjax(() => getAllOfOwnerUserApi())
-    const getTtAllUserList = useAjax(() => getTtAllUserListApi())
     const getAppAuthList = useAjax(() => getAppAuthListApi())
     const getAppAuthList = useAjax(() => getAppAuthListApi())
     /***************************************/
     /***************************************/
 
 
@@ -50,12 +54,11 @@ const Channel: React.FC = () => {
             setBackValueEnum(newBackValueEnum)
             setBackValueEnum(newBackValueEnum)
         })
         })
         getAllOfOwnerUser.run()
         getAllOfOwnerUser.run()
-        getTtAllUserList.run()
         getAppAuthList.run().then(res => {
         getAppAuthList.run().then(res => {
             if (res?.data) {
             if (res?.data) {
                 let newAppList: DefaultOptionType[] = []
                 let newAppList: DefaultOptionType[] = []
                 let newAppObj: any = {}
                 let newAppObj: any = {}
-                res.data?.third.forEach((item: { name: any; id: any; }) => {
+                res?.data?.third?.forEach((item: { name: any; id: any; }) => {
                     newAppList.push({ label: item.name, value: item.id })
                     newAppList.push({ label: item.name, value: item.id })
                     newAppObj[item.id] = {
                     newAppObj[item.id] = {
                         text: item.name
                         text: item.name
@@ -72,9 +75,25 @@ const Channel: React.FC = () => {
         setPutStatusVisible(true)
         setPutStatusVisible(true)
     }
     }
 
 
+    // 变更应用
+    const handleApp = () => {
+        setAppVisible(true)
+    }
+
+    // 变更应用
+    const bgApp = (data: any) => {
+        setSelectData(data)
+        setAppVisible(true)
+    }
+
+    // 日志
+    const handleLog = (data: any) => {
+        setLogData({ data, visible: true })
+    }
+
     return <>
     return <>
         <ProTable<any>
         <ProTable<any>
-            columns={tableConfig(backValueEnum, appObj)}
+            columns={tableConfig(backValueEnum, appObj, bgApp, handleLog)}
             actionRef={actionRef}
             actionRef={actionRef}
             cardBordered
             cardBordered
             request={async (params, sort, filter) => {
             request={async (params, sort, filter) => {
@@ -129,6 +148,7 @@ const Channel: React.FC = () => {
                 return (
                 return (
                     <Space size={16}>
                     <Space size={16}>
                         <a onClick={handlePutStatus}>变更投放状态</a>
                         <a onClick={handlePutStatus}>变更投放状态</a>
+                        <a onClick={handleApp}>变更应用</a>
                         <a onClick={() => setBackPolicyVisible(true)}>修改回传策略</a>
                         <a onClick={() => setBackPolicyVisible(true)}>修改回传策略</a>
                     </Space>
                     </Space>
                 );
                 );
@@ -139,7 +159,6 @@ const Channel: React.FC = () => {
         {visible && <ModalChannel
         {visible && <ModalChannel
             appList={appList}
             appList={appList}
             getAllOfOwnerUser={getAllOfOwnerUser}
             getAllOfOwnerUser={getAllOfOwnerUser}
-            getTtAllUserList={getTtAllUserList}
             getBackPolicyAllList={getBackPolicyAllList}
             getBackPolicyAllList={getBackPolicyAllList}
             visible={visible}
             visible={visible}
             initialValues={initialValues}
             initialValues={initialValues}
@@ -184,6 +203,32 @@ const Channel: React.FC = () => {
                 setBackPolicyVisible(false)
                 setBackPolicyVisible(false)
             }}
             }}
         />}
         />}
+
+        {/* 变更应用 */}
+        {appVisible && <ConfigApp
+            appList={appList}
+            visible={appVisible}
+            selectedRows={selectData ? [selectData] : selectedRows}
+            onClose={() => {
+                setAppVisible(false);
+                setSelectData(undefined)
+            }}
+            initialValues={selectData}
+            onChange={() => {
+                setSelectData(undefined)
+                setAppVisible(false)
+                actionRef.current?.reload();
+                (actionRef.current as any)?.clearSelected()
+            }}
+        />}
+
+        {/* 日志 */}
+        {logData.visible && <Log 
+            {...logData}
+            onClose={() => {
+                setLogData({data: undefined, visible: false})
+            }}
+        />}
     </>
     </>
 }
 }
 
 

+ 38 - 0
src/pages/iaaSystem/manage/channel/log.tsx

@@ -0,0 +1,38 @@
+import { useAjax } from "@/Hook/useAjax"
+import { getLogListApi } from "@/services/iaaSystem/channel"
+import ProTable, { ActionType } from "@ant-design/pro-table"
+import { Drawer } from "antd"
+import React, { useRef } from "react"
+import tableConfig from "./tableConfigLog"
+
+
+interface Props {
+    data: any
+    visible?: boolean
+    onClose?: () => void
+}
+const Log: React.FC<Props> = ({ data, visible, onClose }) => {
+
+    /***********************************/
+    const actionRef = useRef<ActionType>();
+    const getLogList = useAjax((params) => getLogListApi(params), { type: 'table' })
+    /***********************************/
+
+    return <Drawer title={`变更日志`} placement="right" onClose={onClose} open={visible} width={1100}>
+        <ProTable<any>
+            columns={tableConfig()}
+            actionRef={actionRef}
+            cardBordered
+            request={async (params, sort, filter) => {
+                console.log(sort, filter);
+                return await getLogList.run({ ...params, iaaAgentId: data.id })
+            }}
+            search={false}
+            rowKey="id"
+            headerTitle={<strong>{data?.agentName} 变更日志</strong>}
+            scroll={{ x: 900 }}
+        />
+    </Drawer>
+}
+
+export default React.memo(Log)

+ 77 - 17
src/pages/iaaSystem/manage/channel/modalChannel.tsx

@@ -1,14 +1,14 @@
 import { AjaxPromise, useAjax } from "@/Hook/useAjax";
 import { AjaxPromise, useAjax } from "@/Hook/useAjax";
 import { addIaaAgentApi } from "@/services/iaaSystem/channel";
 import { addIaaAgentApi } from "@/services/iaaSystem/channel";
-import { Form, Input, message, Modal, Select } from "antd";
+import { Checkbox, DatePicker, Divider, Form, Input, message, Modal, Select, Space } from "antd";
+import { RangePickerProps } from "antd/lib/date-picker";
 import { DefaultOptionType } from "antd/lib/select";
 import { DefaultOptionType } from "antd/lib/select";
-import React from "react"
-
+import React, { useState } from "react"
+import moment from "moment";
 
 
 interface Props {
 interface Props {
     getBackPolicyAllList: AjaxPromise
     getBackPolicyAllList: AjaxPromise
     getAllOfOwnerUser: AjaxPromise
     getAllOfOwnerUser: AjaxPromise
-    getTtAllUserList: AjaxPromise
     appList: DefaultOptionType[]
     appList: DefaultOptionType[]
     onChange?: () => void
     onChange?: () => void
     visible?: boolean
     visible?: boolean
@@ -20,11 +20,15 @@ interface Props {
  * 新增修改回传策略
  * 新增修改回传策略
  * @returns 
  * @returns 
  */
  */
-const ModalChannel: React.FC<Props> = ({ onChange, visible, onClose, initialValues, appList, getBackPolicyAllList, getAllOfOwnerUser, getTtAllUserList }) => {
+const ModalChannel: React.FC<Props> = ({ onChange, visible, onClose, initialValues, appList, getBackPolicyAllList, getAllOfOwnerUser }) => {
 
 
     /*******************************/
     /*******************************/
     const [form] = Form.useForm<IAAAPI.AddIaaAgentProps>();
     const [form] = Form.useForm<IAAAPI.AddIaaAgentProps>();
     const accountType = Form.useWatch('accountType', form)
     const accountType = Form.useWatch('accountType', form)
+    const putStatus = Form.useWatch('putStatus', form)
+    const putStartDate = Form.useWatch('putStartDate', form)
+    const putEndData = Form.useWatch('putEndData', form)
+    const [accSearch, setAccSearch] = useState<string>()
 
 
     const addIaaAgent = useAjax((params) => addIaaAgentApi(params))
     const addIaaAgent = useAjax((params) => addIaaAgentApi(params))
     /*******************************/
     /*******************************/
@@ -37,6 +41,12 @@ const ModalChannel: React.FC<Props> = ({ onChange, visible, onClose, initialValu
             data.accountIdList = data.accountIdList.replace(/[,,\s]/g, ',')
             data.accountIdList = data.accountIdList.replace(/[,,\s]/g, ',')
             data.accountIdList = data.accountIdList.split(',')
             data.accountIdList = data.accountIdList.split(',')
         }
         }
+        if (data?.putStartDate) {
+            data.putStartDate = moment(data.putStartDate).format('YYYY-MM-DD')
+        }
+        if (data?.putEndData) {
+            data.putEndData = moment(data.putEndData).format('YYYY-MM-DD')
+        }
         addIaaAgent.run(data).then(res => {
         addIaaAgent.run(data).then(res => {
             if (res?.data) {
             if (res?.data) {
                 message.success('新增成功')
                 message.success('新增成功')
@@ -44,6 +54,22 @@ const ModalChannel: React.FC<Props> = ({ onChange, visible, onClose, initialValu
             }
             }
         })
         })
     }
     }
+    // eslint-disable-next-line arrow-body-style
+    const disabledStartDate: RangePickerProps['disabledDate'] = current => {
+        // Can not select days before today and today
+        if (putEndData) {
+            return current && current > moment(putEndData).endOf('day');
+        }
+        return current && current > moment().endOf('day');
+    };
+
+    const disabledEmdDate: RangePickerProps['disabledDate'] = current => {
+        // Can not select days before today and today
+        if (putStartDate) {
+            return current && (current > moment().endOf('day') || putStartDate >= current);
+        }
+        return current && current > moment().endOf('day');
+    };
 
 
     return <Modal
     return <Modal
         title={<strong>{initialValues?.id ? '修改渠道' : '新增渠道'}</strong>}
         title={<strong>{initialValues?.id ? '修改渠道' : '新增渠道'}</strong>}
@@ -67,10 +93,6 @@ const ModalChannel: React.FC<Props> = ({ onChange, visible, onClose, initialValu
                 <Select
                 <Select
                     placeholder="请选择推广账号类型"
                     placeholder="请选择推广账号类型"
                     options={[
                     options={[
-                        {
-                            value: 'OUTSIDE_APPLICATION',
-                            label: '外部应用',
-                        },
                         {
                         {
                             value: 'TENCENT_MINI_GAME',
                             value: 'TENCENT_MINI_GAME',
                             label: '腾讯小游戏',
                             label: '腾讯小游戏',
@@ -78,6 +100,14 @@ const ModalChannel: React.FC<Props> = ({ onChange, visible, onClose, initialValu
                         {
                         {
                             value: 'OCENAENGINE_MINI_GAME',
                             value: 'OCENAENGINE_MINI_GAME',
                             label: '头条小游戏',
                             label: '头条小游戏',
+                        },
+                        {
+                            value: 'TENCENT_MP_NOVEL',
+                            label: '腾讯小说',
+                        },
+                        {
+                            value: 'TENCENT_MP_PLAYLET',
+                            label: '腾讯短剧',
                         }
                         }
                     ]}
                     ]}
                     filterOption={(input, option) =>
                     filterOption={(input, option) =>
@@ -87,18 +117,40 @@ const ModalChannel: React.FC<Props> = ({ onChange, visible, onClose, initialValu
                 />
                 />
             </Form.Item>
             </Form.Item>
             {accountType && <Form.Item label={<strong>广告账号</strong>} name="accountIdList" rules={[{ required: true, message: '请输入广告账号!' }]}>
             {accountType && <Form.Item label={<strong>广告账号</strong>} name="accountIdList" rules={[{ required: true, message: '请输入广告账号!' }]}>
-                {['TENCENT_MINI_GAME'].includes(accountType) ? <Select
+                {['TENCENT_MINI_GAME', 'TENCENT_MP_NOVEL', 'TENCENT_MP_PLAYLET'].includes(accountType) ? <Select
                     placeholder="请选择广告账号"
                     placeholder="请选择广告账号"
                     mode="multiple"
                     mode="multiple"
-                    filterOption={(input, option) =>
-                        ((option?.label ?? '') as any).toLowerCase().includes(input.toLowerCase())
-                    }
-                    options={accountType === 'TENCENT_MINI_GAME' ? getAllOfOwnerUser?.data?.data?.map((item: { memo: string; accountId: any; }) => ({
+                    filterOption={(input, option) => {
+                        let newInput: string[] = input ? input?.split(/[,,\n\s]+/ig).filter((item: any) => item) : []
+                        return newInput?.some(val => option!.label?.toString().toLowerCase()?.includes(val))
+                    }}
+                    autoClearSearchValue={false}
+                    searchValue={accSearch}
+                    onSearch={(val) => {
+                        setAccSearch(val)
+                    }}
+                    dropdownRender={menu => (
+                        <>
+                            {menu}
+                            <Divider style={{ margin: '8px 0' }} />
+                            <Space style={{ padding: '0 8px 4px' }}>
+                                <Checkbox onChange={(e) => {
+                                    let data = []
+                                    if (e.target.checked) {
+                                        data = JSON.parse(JSON.stringify(getAllOfOwnerUser?.data?.data))
+                                        if (accSearch) {
+                                            let newAccSearch = accSearch?.split(/[,,\n\s]+/ig).filter((item: any) => item)
+                                            data = data?.filter((item: any) => newAccSearch?.some(val => item!.accountId?.toString().toLowerCase()?.includes(val)))
+                                        }
+                                    }
+                                    form.setFieldsValue({ accountIdList: data?.map((item: any) => item?.accountId) })
+                                }}>全选</Checkbox>
+                            </Space>
+                        </>
+                    )}
+                    options={getAllOfOwnerUser?.data?.data?.map((item: { memo: string; accountId: any; }) => ({
                         value: item.accountId,
                         value: item.accountId,
                         label: item.accountId + (item.memo ? '_' + item.memo : '')
                         label: item.accountId + (item.memo ? '_' + item.memo : '')
-                    })) : getTtAllUserList?.data?.data?.map((item: { groupName: string; accountName: string; accountId: any; }) => ({
-                        value: item.accountId,
-                        label: item.accountId + '_' + item.accountName + (item.groupName ? '_' + item.groupName : ''),
                     }))}
                     }))}
                 /> : <Input.TextArea placeholder="请输入广告账号(多个逗号,换行隔开)" />}
                 /> : <Input.TextArea placeholder="请输入广告账号(多个逗号,换行隔开)" />}
             </Form.Item>}
             </Form.Item>}
@@ -132,6 +184,14 @@ const ModalChannel: React.FC<Props> = ({ onChange, visible, onClose, initialValu
                     showSearch
                     showSearch
                 />
                 />
             </Form.Item>
             </Form.Item>
+            {['PUT_STATUS_PUT_ING', 'PUT_STATUS_PUT_STOP'].includes(putStatus) ? <Form.Item label={<strong>投放开始时间</strong>} name="putStartDate" rules={[{ required: true, message: '请选择投放开始时间!' }]}>
+                {/* @ts-ignore  */}
+                <DatePicker placeholder="投放开始时间" disabledDate={disabledStartDate} />
+            </Form.Item> : null}
+            {['PUT_STATUS_PUT_STOP'].includes(putStatus) ? <Form.Item label={<strong>投放结束时间</strong>} name="putEndData" rules={[{ required: true, message: '请选择投放结束时间!' }]}>
+                {/* @ts-ignore  */}
+                <DatePicker placeholder="投放结束时间" disabledDate={disabledEmdDate}/>
+            </Form.Item> : null}
             <Form.Item label={<strong>回传策略</strong>} name="backPolicyId">
             <Form.Item label={<strong>回传策略</strong>} name="backPolicyId">
                 <Select
                 <Select
                     placeholder="请选择回传策略"
                     placeholder="请选择回传策略"

+ 21 - 8
src/pages/iaaSystem/manage/channel/tableConfig.tsx

@@ -4,12 +4,13 @@ import React from "react";
 import CancelBackPolicy from "./cancelBackPolicy";
 import CancelBackPolicy from "./cancelBackPolicy";
 
 
 const AccountTypeEnum = {
 const AccountTypeEnum = {
-    OUTSIDE_APPLICATION: <Tag color="#f50">外部应用</Tag>,
     TENCENT_MINI_GAME: <Tag color="#2db7f5">腾讯小游戏</Tag>,
     TENCENT_MINI_GAME: <Tag color="#2db7f5">腾讯小游戏</Tag>,
-    OCENAENGINE_MINI_GAME: <Tag color="#87d068">头条小游戏</Tag>
+    OCENAENGINE_MINI_GAME: <Tag color="#87d068">头条小游戏</Tag>,
+    TENCENT_MP_NOVEL: <Tag color="#f50">腾讯小说</Tag>,
+    TENCENT_MP_PLAYLET: <Tag color="#2db7f5">腾讯短剧</Tag>,
 }
 }
 
 
-const tableConfig = (backValueEnum: any, appObj: any) => {
+const tableConfig = (backValueEnum: any, appObj: any, bgApp?: (data: any) => void, handleLog?: (data: any) => void) => {
 
 
     const columns: ProColumns<any>[] = [
     const columns: ProColumns<any>[] = [
         {
         {
@@ -17,7 +18,8 @@ const tableConfig = (backValueEnum: any, appObj: any) => {
             dataIndex: 'agentName',
             dataIndex: 'agentName',
             copyable: true,
             copyable: true,
             ellipsis: true,
             ellipsis: true,
-            width: 220
+            width: 220,
+            fixed: 'left'
         },
         },
         {
         {
             title: '渠道标识',
             title: '渠道标识',
@@ -26,6 +28,7 @@ const tableConfig = (backValueEnum: any, appObj: any) => {
             width: 180,
             width: 180,
             ellipsis: true,
             ellipsis: true,
             copyable: true,
             copyable: true,
+            fixed: 'left'
         },
         },
         {
         {
             title: '广告账号',
             title: '广告账号',
@@ -48,7 +51,13 @@ const tableConfig = (backValueEnum: any, appObj: any) => {
                 },
                 },
                 OCENAENGINE_MINI_GAME: {
                 OCENAENGINE_MINI_GAME: {
                     text: '头条小游戏'
                     text: '头条小游戏'
-                }
+                },
+                TENCENT_MP_NOVEL: {
+                    text: '腾讯小说'
+                },
+                TENCENT_MP_PLAYLET: {
+                    text: '腾讯短剧'
+                },
             },
             },
             render: (_: any, row: { accountType: string; }) => {
             render: (_: any, row: { accountType: string; }) => {
                 return AccountTypeEnum[row.accountType as keyof typeof AccountTypeEnum]
                 return AccountTypeEnum[row.accountType as keyof typeof AccountTypeEnum]
@@ -135,11 +144,15 @@ const tableConfig = (backValueEnum: any, appObj: any) => {
         {
         {
             title: '操作',
             title: '操作',
             key: 'option',
             key: 'option',
-            width: 125,
+            width: 250,
             valueType: 'option',
             valueType: 'option',
+            fixed: 'right',
+            //  @ts-ignore
             render: (_: any, row: { iaaAgentBackPolicyDTO: any; id: number; }, index: any, action: { reload: () => void; }) => row?.iaaAgentBackPolicyDTO ? [
             render: (_: any, row: { iaaAgentBackPolicyDTO: any; id: number; }, index: any, action: { reload: () => void; }) => row?.iaaAgentBackPolicyDTO ? [
-                <div key={'qx'}><CancelBackPolicy id={row.id} onChange={() => action?.reload()}/></div>
-            ] : '-'
+                <div key={'qx'}><CancelBackPolicy id={row.id} onChange={() => action?.reload()} /></div>,
+                <a key={'log'} style={{ fontSize: 12 }} onClick={() => handleLog?.(row)}>日志</a>,
+                <a key={'bg'} style={{ fontSize: 12 }} onClick={() => bgApp?.(row)}>变更应用</a>
+            ] : [<a key={'log'} style={{ fontSize: 12 }} onClick={() => handleLog?.(row)}>日志</a>, <a key={'bg'} style={{ fontSize: 12 }} onClick={() => bgApp?.(row)}>变更应用</a>]
         },
         },
     ];
     ];
     return columns
     return columns

+ 55 - 0
src/pages/iaaSystem/manage/channel/tableConfigLog.tsx

@@ -0,0 +1,55 @@
+import { ProColumns } from "@ant-design/pro-table";
+
+const tableConfig = () => {
+
+    const columns: ProColumns<any>[] = [
+        {
+            title: '应用',
+            dataIndex: 'iaaAppIdName',
+            width: 120,
+            ellipsis: true,
+            search: false,
+        },
+        {
+            title: '应用ID',
+            dataIndex: 'iaaAppId',
+            align: 'center',
+            width: 120,
+            ellipsis: true,
+            search: false,
+        },
+        {
+            title: '开始日期',
+            key: 'startDay',
+            dataIndex: 'startDay',
+            width: 140,
+            search: false,
+            align: 'center'
+        },
+        {
+            title: '结束日期',
+            key: 'endDay',
+            dataIndex: 'endDay',
+            width: 140,
+            search: false,
+            align: 'center'
+        },
+        {
+            title: '创建人',
+            dataIndex: 'createByName',
+            search: false,
+            align: 'center',
+            width: 100
+        },
+        {
+            title: '创建时间',
+            key: 'showTime',
+            dataIndex: 'createTime',
+            width: 140,
+            search: false
+        },
+    ];
+    return columns
+}
+
+export default tableConfig

+ 29 - 4
src/services/iaaSystem/channel.ts

@@ -33,10 +33,11 @@ export async function getIaaAgentListApi(data: IAAAPI.GetIaaAgentListProps) {
  * @param param0 
  * @param param0 
  * @returns 
  * @returns 
  */
  */
-export async function iaaConfigPutStatusApi({ agentIds, putStatus }: { agentIds: string, putStatus: string }) {
-    return request(iaaApi + `/iaaAgent/configPutStatus/${agentIds}/${putStatus}`, {
-        method: 'PUT'
-    });
+export async function iaaConfigPutStatusApi(data: { agentIdList: string, putStatus: string, dateTime: string }) {
+    return request(iaaApi + `/iaaAgent/put/status/update`, {
+        method: 'POST',
+        data
+    })
 }
 }
 
 
 /**
 /**
@@ -60,4 +61,28 @@ export async function iaaConfigBackPolicyBackApi({ agentIds, backPolicyId }: { a
     return request(iaaApi + `/iaaAgent/configBackPolicy/${agentIds}/${backPolicyId}`, {
     return request(iaaApi + `/iaaAgent/configBackPolicy/${agentIds}/${backPolicyId}`, {
         method: 'PUT'
         method: 'PUT'
     });
     });
+}
+
+/**
+ * 变更应用
+ * @param data 
+ * @returns 
+ */
+export async function updataAppApi(data: { agentIdList: string[], iaaAppId: number, putStatus: string, putStartDate: string, putEndData?: string }) {
+    return request(iaaApi + `/iaaAgent/put/app/update`, {
+        method: 'POST',
+        data
+    });
+}
+
+/**
+ * 变更日志
+ * @param data 
+ * @returns 
+ */
+export async function getLogListApi(data: { pageNum: number, pageSize: number, iaaAgentId: number }) {
+    return request(iaaApi + `/iaaAgent/app/log/list`, {
+        method: 'POST',
+        data
+    });
 }
 }