wjx 1 місяць тому
батько
коміт
09a0333b80

+ 6 - 0
config/routerConfig.ts

@@ -191,6 +191,12 @@ const launchSystemV3 = {
                     path: '/launchSystemV3/tencenTasset/application',
                     access: 'application',
                     component: './launchSystemV3/tencenTasset/application',
+                },
+                {
+                    name: '创意组件',
+                    path: '/launchSystemV3/tencenTasset/manageComponent',
+                    access: 'manageComponent',
+                    component: './launchSystemV3/tencenTasset/manageComponent',
                 }
             ],
         },

+ 10 - 0
src/pages/launchSystemV3/components/GoodsModal/tableConfig.tsx

@@ -21,6 +21,16 @@ let columns = (): TableProps<any>['columns'] => {
                 return <img src={a} style={{ height: 35 }} />
             }
         },
+        {
+            title: '书城',
+            dataIndex: 'mall',
+            key: 'mall',
+            ellipsis: true,
+            align: 'center',
+            render: (a: any) => {
+                return <span style={{ fontSize: "12px" }}>{a}</span>
+            }
+        },
         {
             title: '分类',
             dataIndex: 'fictionType',

+ 72 - 29
src/pages/launchSystemV3/material/cloudNew/material.tsx

@@ -20,6 +20,7 @@ import useFileDrop from "@/Hook/useFileDrop"
 import UploadsTable from "./uploadsTable"
 import Lazyimg from "react-lazyimg-component"
 import CopyFile from "./copyFile"
+import MoveToTencent from "./moveToTencent"
 const { Text } = Typography;
 
 interface Props {
@@ -51,17 +52,20 @@ const Material = forwardRef(({ onAddFolder, onUpdateFolder, onDelFolder }: Props
     const [folderList, setFolderList] = useState<{ id: number, folderName: string, createBy: number, description?: string }[]>([])
     const [rowNum, setRowNum] = useState<number>(0)
     const [checkedFolderList, setCheckedFolderList] = useState<CheckboxValueType[]>([])
+    const [checkedDataList, setCheckedDataList] = useState<any[]>([])
     const [checkFolderAll, setCheckFolderAll] = useState<boolean>(false);
     const [indeterminateFolder, setIndeterminateFolder] = useState<boolean>(false);
     const [moveVisible, setMoveVisible] = useState<boolean>(false)
     const [moveType, setMoveType] = useState<'folder' | 'file'>('folder')
     const [batchType, setBatchType] = useState<'folder' | 'file'>()
+    const [isMoveTencent, setIsMoveTencent] = useState<boolean>(false)
     const [checkedList, setCheckedList] = useState<CheckboxValueType[]>([])
     const [uploadVisible, setUploadVisible] = useState<boolean>(false)
     const [updateOwnerData, setUpdateOwnerData] = useState<{ visible?: boolean, folderId: number }>({ folderId: 0 })
     const [updateFileData, setUpdateFileData] = useState<{ visible?: boolean, initialValues: any }>({ visible: false, initialValues: {} })
     const [detailsData, setDetailsData] = useState<{ visible?: boolean, data: any }>({ visible: false, data: {} })
     const [copyVisible, setCopyVisible] = useState<boolean>(false)
+    const [moveTencentVisible, setMoveTencentVisible] = useState<boolean>(false)
 
     const getFolderList = useAjax((params) => getFolderListApi(params))
     const delMaterial = useAjax((params) => delMaterialApi(params))
@@ -143,6 +147,9 @@ const Material = forwardRef(({ onAddFolder, onUpdateFolder, onDelFolder }: Props
             data = getMaterialList?.data?.records || []
         }
         setCheckedFolderList(checkedValues)
+        if (isMoveTencent) {
+            setCheckedDataList(getMaterialList?.data?.records?.filter((item: { id: number }) => checkedValues.includes(item.id)))
+        }
         setIndeterminateFolder(!!checkedValues.length && checkedValues.length < data.length);
         setCheckFolderAll(checkedValues.length === data.length);
     };
@@ -151,8 +158,10 @@ const Material = forwardRef(({ onAddFolder, onUpdateFolder, onDelFolder }: Props
     const cancelSelect = () => {
         setCheckFolderAll(false)
         setCheckedFolderList([])
+        setCheckedDataList([])
         setIndeterminateFolder(false)
         setCheckedList([])
+        setIsMoveTencent(false)
     }
 
     // 是否管理员
@@ -162,6 +171,10 @@ const Material = forwardRef(({ onAddFolder, onUpdateFolder, onDelFolder }: Props
 
     // 是否有权限
     const isPermission = (createBy: any) => {
+        // 上传至腾讯没有权限
+        if (isMoveTencent) {
+            return true
+        }
         return initialState?.currentUser?.userId?.toString() === createBy.toString()
     }
 
@@ -290,6 +303,7 @@ const Material = forwardRef(({ onAddFolder, onUpdateFolder, onDelFolder }: Props
                         setHandleType(e.target.checked ? 'folder' : 'file')
                         setMaterialParams({ pageNum: 1, pageSize: 30 })
                         setBatchFolderVisible(false)
+                        setIsMoveTencent(false)
                         cancelSelect()
                     }}
                     checked={handleType === 'folder'}
@@ -299,10 +313,15 @@ const Material = forwardRef(({ onAddFolder, onUpdateFolder, onDelFolder }: Props
                     <Button type="primary" disabled={folderCreateBy ? !isPermission(folderCreateBy) : false} onClick={() => setUploadVisible(true)}>上传素材</Button>
                 </>}
                 {handleType === 'folder' ? <>
-                    {!!selectedKeys?.[0] && <Button onClick={() => { setBatchFolderVisible(true); setBatchType('folder') }} disabled={folderCreateBy ? !isPermission(folderCreateBy) : false}>批量操作文件夹</Button>}
+                    {!!selectedKeys?.[0] && <Button onClick={() => { setBatchFolderVisible(true); setBatchType('folder'); setIsMoveTencent(false) }} disabled={folderCreateBy ? !isPermission(folderCreateBy) : false}>批量操作文件夹</Button>}
                 </> : <>
                     <Button type="primary" disabled={folderCreateBy ? !isPermission(folderCreateBy) : false} onClick={() => setUploadVisible(true)}>上传素材</Button>
-                    <Button onClick={() => { setBatchFolderVisible(true); setBatchType('file') }} disabled={folderCreateBy ? !isPermission(folderCreateBy) : false}>批量操作素材</Button>
+                    <Button onClick={() => { setBatchFolderVisible(true); setBatchType('file'); setIsMoveTencent(false) }} disabled={folderCreateBy ? !isPermission(folderCreateBy) : false}>批量操作素材</Button>
+                    <Button onClick={() => {
+                        setBatchFolderVisible(true);
+                        setBatchType('file')
+                        setIsMoveTencent(true)
+                    }} type="primary">素材上传到腾讯</Button>
                 </>}
             </div>
             <div className={style.left_bts}>
@@ -321,6 +340,9 @@ const Material = forwardRef(({ onAddFolder, onUpdateFolder, onDelFolder }: Props
                                 getMaterialList?.data?.records?.filter((item: { createBy: any }) => isPermission(item.createBy)).map((item: { id: any }) => item.id) :
                                 []
                         )
+                        if (isMoveTencent) {
+                            setCheckedDataList(e.target.checked ? getMaterialList?.data?.records : [])
+                        }
                         setIndeterminateFolder(false)
                         setCheckFolderAll(e.target.checked)
                     }}
@@ -331,35 +353,43 @@ const Material = forwardRef(({ onAddFolder, onUpdateFolder, onDelFolder }: Props
                 <span style={{ color: '#1890FF' }}>已选{checkedFolderList?.length || 0}个{batchType === 'file' ? '素材' : '文件夹'}</span>
             </div>
             <div className={style.left_bts}>
-                <Button disabled={checkedFolderList?.length === 0} onClick={() => {
-                    setCheckedList(checkedFolderList)
-                    setMoveVisible(true)
-                    setMoveType(batchType as any)
-                }}>{batchType === 'folder' ? '移动文件夹' : '移动素材'}</Button>
-                {batchType === 'file' && <Button
-                    disabled={checkedFolderList?.length === 0}
-                    onClick={() => {
-                        setCheckedList(checkedFolderList)
-                        setCopyVisible(true)
-                    }}
-                >复制素材到</Button>}
-                {batchType === 'file' && <Popconfirm
-                    title="确定删除?"
-                    onConfirm={() => {
-                        const hide = message.loading('正在删除...', 0, () => { });
-                        deleteBatch.run(checkedFolderList).then(res => {
-                            hide()
-                            if (res) {
-                                getMaterialList.refresh()
-                                message.success('删除成功')
-                            }
-                        }).catch(() => hide())
-                    }}
-                >
-                    <Button danger disabled={checkedFolderList?.length === 0} loading={deleteBatch.loading}>删除</Button>
-                </Popconfirm>}
+                {isMoveTencent ? <>
+                    <Button disabled={checkedFolderList?.length === 0} onClick={() => {
+                        setMoveTencentVisible(true)
+                    }}>上传至腾讯</Button>
+                </> :
+                    <>
+                        <Button disabled={checkedFolderList?.length === 0} onClick={() => {
+                            setCheckedList(checkedFolderList)
+                            setMoveVisible(true)
+                            setMoveType(batchType as any)
+                        }}>{batchType === 'folder' ? '移动文件夹' : '移动素材'}</Button>
+                        {batchType === 'file' && <Button
+                            disabled={checkedFolderList?.length === 0}
+                            onClick={() => {
+                                setCheckedList(checkedFolderList)
+                                setCopyVisible(true)
+                            }}
+                        >复制素材到</Button>}
+                        {batchType === 'file' && <Popconfirm
+                            title="确定删除?"
+                            onConfirm={() => {
+                                const hide = message.loading('正在删除...', 0, () => { });
+                                deleteBatch.run(checkedFolderList).then(res => {
+                                    hide()
+                                    if (res) {
+                                        getMaterialList.refresh()
+                                        message.success('删除成功')
+                                    }
+                                }).catch(() => hide())
+                            }}
+                        >
+                            <Button danger disabled={checkedFolderList?.length === 0} loading={deleteBatch.loading}>删除</Button>
+                        </Popconfirm>}
+                    </>}
                 <Button type="primary" onClick={() => {
                     setBatchFolderVisible(false)
+                    cancelSelect()
                 }}>完成</Button>
             </div>
         </div> : (materialParams?.materialName || materialParams?.materialType || (materialParams?.designerIds && materialParams?.designerIds?.length > 0) || materialParams?.width || materialParams?.height) ? <div className={style.operates}>
@@ -598,6 +628,19 @@ const Material = forwardRef(({ onAddFolder, onUpdateFolder, onDelFolder }: Props
                 getMaterialList.refresh()
             }}
         />}
+
+        {/* 上传至腾讯 */}
+        {moveTencentVisible && <MoveToTencent
+            data={checkedDataList}
+            visible={moveTencentVisible}
+            onChange={() => {
+                setMoveTencentVisible(false)
+                cancelSelect()
+            }}
+            onClose={() => {
+                setMoveTencentVisible(false)
+            }}
+        />}
     </div>
 })
 

+ 246 - 0
src/pages/launchSystemV3/material/cloudNew/moveToTencent.tsx

@@ -0,0 +1,246 @@
+import { useAjax } from "@/Hook/useAjax"
+import { setMaterialTencentApi } from "@/services/adqV3/cloudNew"
+import { getAccountAssetsGroupListAllApi } from "@/services/adqV3/global"
+import { getUserAccountListApi } from "@/services/launchAdq/adAuthorize"
+import { getGroupListApi } from "@/services/launchAdq/subgroup"
+import { Button, Col, Form, Input, message, Modal, Row, Select, Space, Table } from "antd"
+import React, { useEffect, useState } from "react"
+
+
+
+interface Props {
+    data: any[]
+    visible?: boolean
+    onClose?: () => void
+    onChange?: () => void
+}
+
+/**
+ * 上传素材到腾讯
+ * @param param0 
+ * @returns 
+ */
+const MoveToTencent: React.FC<Props> = ({ data, visible, onClose, onChange }) => {
+
+    /***********************************/
+    const [form] = Form.useForm()
+    const [queryForm, setQueryForm] = useState<{ putInType?: string, accountIdList?: number[], adUnitTypeList?: string[], groupId?: number, remark?: string, sysGroupId?: number, pageNum: number, pageSize: number }>({ pageNum: 1, pageSize: 50 })
+    const [selectedRows, setSelectedRows] = useState<any[]>([])
+    const [loading, setLoading] = useState<boolean>(false)
+
+    const getUserAccountList = useAjax((params) => getUserAccountListApi(params))
+    const getGroupList = useAjax(() => getGroupListApi())
+    const getAccountAssetsGroupListAll = useAjax((params) => getAccountAssetsGroupListAllApi(params))
+    /***********************************/
+
+    const onFinish = (data: any) => {
+        let oldQueryFrom = JSON.parse(JSON.stringify(queryForm))
+        let params = { ...oldQueryFrom, ...data, pageNum: 1 }
+        if (params?.accountIdList) {
+            params.accountIdList = params?.accountIdList.split(/[,,\n\s]+/ig).filter((item: any) => item)
+        } else {
+            delete params?.accountIdList
+        }
+        setQueryForm(params)
+    }
+
+    useEffect(() => {
+        getGroupList.run()
+    }, [])
+
+    useEffect(() => {
+        const { putInType, ...params } = queryForm
+        getUserAccountList.run({ ...params, adUnitTypeList: putInType === 'NOVEL' ? ['NOVEL', 'NOVEL_IAA', 'SKIT_IAA'] : putInType === 'GAME' ? ['GAME', 'GAME_IAA'] : undefined })
+    }, [queryForm])
+
+    const handleOk = () => {
+        console.log(data)
+        if (selectedRows.length) {
+            const typeDatalist = data.reduce((pre, cur) => {
+                if (cur.materialType === 'image') {
+                    pre['image']?.length ? pre['image'].push(cur.id) : pre['image'] = [cur.id]
+                } else if (cur.materialType === 'video') {
+                    pre['video']?.length ? pre['video'].push(cur.id) : pre['video'] = [cur.id]
+                }
+                return pre
+            }, {})
+            setLoading(true)
+            const ajaxs = Object.keys(typeDatalist).map(key => {
+                if (key == 'image') {
+                    return setMaterialTencentApi({ type: 'IMAGE', accountId: selectedRows[0].accountId, sysFileId: typeDatalist[key] })
+                } else {
+                    return setMaterialTencentApi({ type: 'VIDEO', accountId: selectedRows[0].accountId, sysFileId: typeDatalist[key] })
+                }
+            })
+            Promise.all(ajaxs).then(res => {
+                setLoading(false)
+                console.log('66666666', res)
+            }).catch(() => setLoading(false))
+            console.log(typeDatalist)
+        } else {
+            message.error('请选择账号')
+        }
+    }
+
+    return <Modal
+        title={<strong>素材上传至腾讯</strong>}
+        open={visible}
+        onCancel={onClose}
+        onOk={handleOk}
+        className="modalResetCss"
+        maskClosable={false}
+        confirmLoading={loading}
+        width={1000}
+    >
+        <Space direction="vertical" style={{ width: '100%' }}>
+            <Form layout="inline" className='queryForm' name="basicSelectAcc" form={form} onFinish={onFinish}>
+                <Row gutter={[0, 6]}>
+                    <Col><Form.Item name='putInType'>
+                        <Select
+                            style={{ width: 120 }}
+                            placeholder="账号类型"
+                            allowClear
+                            filterOption={(input: any, option: any) => {
+                                return option!.children?.toString().toLowerCase().includes(input.toLowerCase())
+                            }}
+                        >
+                            <Select.Option value="NOVEL">小说/短剧</Select.Option>
+                            <Select.Option value="GAME">游戏</Select.Option>
+                        </Select>
+                    </Form.Item></Col>
+                    <Col><Form.Item name='accountIdList'>
+                        <Input.TextArea
+                            rows={1}
+                            autoSize={{ minRows: 1, maxRows: 1 }}
+                            placeholder="账户(多个,,空格换行)"
+                            style={{ width: 180 }}
+                            allowClear
+                        />
+                    </Form.Item></Col>
+                    <Col><Form.Item name='remark'>
+                        <Input
+                            placeholder="备注"
+                            style={{ width: 120 }}
+                            allowClear
+                        />
+                    </Form.Item></Col>
+                    <Col><Form.Item name='sysGroupId'>
+                        <Select
+                            mode="multiple"
+                            style={{ minWidth: 180 }}
+                            placeholder="快捷选择媒体账户组"
+                            maxTagCount={1}
+                            allowClear
+                            filterOption={(input: any, option: any) => {
+                                return option!.children?.toString().toLowerCase().includes(input.toLowerCase())
+                            }}
+                        >
+                            {getGroupList?.data && getGroupList?.data?.map((item: any) => <Select.Option value={item.groupId} key={item.groupId}>{item.groupName}</Select.Option>)}
+                        </Select>
+                    </Form.Item></Col>
+                    <Col><Form.Item name='groupId'>
+                        <Select
+                            allowClear
+                            showSearch
+                            placeholder="账户资产共享组"
+                            filterOption={(input: any, option: any) => {
+                                return option!.children?.toString().toLowerCase().includes(input.toLowerCase())
+                            }}
+                            style={{ width: 145 }}
+                        >
+                            {getAccountAssetsGroupListAll?.data?.map((item: { accountId: any; authMainAccountId: number; id: number; accountGroupName: string }) => <Select.Option value={item.id} key={item.id}>{item.accountGroupName}({item.authMainAccountId})</Select.Option>)}
+                        </Select>
+                    </Form.Item></Col>
+                    <Col>
+                        <Space>
+                            <Button type="primary" htmlType="submit">搜索</Button>
+                            <Button onClick={() => form.resetFields()}>重置</Button>
+                        </Space>
+                    </Col>
+                </Row>
+            </Form>
+
+            <Table
+                size={'small'}
+                bordered
+                dataSource={getUserAccountList?.data?.records}
+                rowKey={'accountId'}
+                scroll={{ y: 220 }}
+                pagination={{
+                    pageSize: getUserAccountList?.data?.size || 50,
+                    current: getUserAccountList?.data?.current || 1,
+                    showTotal: total => `总共 ${total} 账户`,
+                    total: getUserAccountList?.data?.total,
+                    showSizeChanger: true,
+                    showLessItems: true,
+                    defaultCurrent: 1,
+                    defaultPageSize: 50,//默认初始的每页条数
+                    onChange: (page, pageSize) => {
+                        setQueryForm({ ...queryForm, pageNum: page, pageSize })
+                    }
+                }}
+                loading={getUserAccountList.loading}
+                columns={[
+                    {
+                        title: '账号',
+                        dataIndex: 'accountId',
+                        key: 'accountId',
+                        width: 80,
+                        align: 'center',
+                        render(value) {
+                            return <span style={{ fontSize: 12 }}>{value}</span>
+                        }
+                    },
+                    {
+                        title: '企业',
+                        dataIndex: 'corporationName',
+                        key: 'corporationName',
+                        width: 180,
+                        ellipsis: true,
+                        render(value) {
+                            return <span style={{ fontSize: 12 }}>{value}</span>
+                        }
+                    },
+                    {
+                        title: '企业标识',
+                        dataIndex: 'corporationLicence',
+                        key: 'corporationLicence',
+                        width: 150,
+                        ellipsis: true,
+                        render(value) {
+                            return <span style={{ fontSize: 12 }}>{value}</span>
+                        }
+                    },
+                    {
+                        title: '业务单元ID',
+                        dataIndex: 'adUnitAccountId',
+                        key: 'adUnitAccountId',
+                        width: 90,
+                        align: 'center',
+                        render(value) {
+                            return <span style={{ fontSize: 12 }}>{value || '--'}</span>
+                        }
+                    },
+                    {
+                        title: '备注',
+                        dataIndex: 'remark',
+                        key: 'remark',
+                        ellipsis: true,
+                        render(value) {
+                            return <span style={{ fontSize: 12 }}>{value || '--'}</span>
+                        }
+                    },
+                ]}
+                rowSelection={{
+                    selectedRowKeys: selectedRows.map(item => item.accountId),
+                    type: 'radio',
+                    onChange(_, selectedRows) {
+                        setSelectedRows(selectedRows)
+                    },
+                }}
+            />
+        </Space>
+    </Modal>
+}
+
+export default React.memo(MoveToTencent)

+ 6 - 0
src/pages/launchSystemV3/material/typings.d.ts

@@ -188,4 +188,10 @@ declare namespace CLOUDNEW {
         md5: string
         url: string
     }
+
+    interface SetMaterialTencentProps {
+        accountId: number
+        sysFileId: number[]
+        type: 'IMAGE' | 'VIDEO'
+    }
 }

+ 15 - 0
src/pages/launchSystemV3/tencenTasset/manageComponent/index.tsx

@@ -0,0 +1,15 @@
+import React from "react"
+
+/**
+ * 创意组件
+ * @returns 
+ */
+const ManageComponent: React.FC = () => {
+
+
+    return <div>
+        111111111111111
+    </div>
+}
+
+export default ManageComponent

+ 18 - 0
src/services/adqV3/cloudNew.ts

@@ -287,4 +287,22 @@ export async function addRemoteMaterialApi(d: { folderId: number, data: CLOUDNEW
         data,
         params: { folderId }
     })
+}
+
+/**
+ * 上传本地素材到腾讯
+ * @param data 
+ * @returns 
+ */
+export async function setMaterialTencentApi({ type, ...data }: CLOUDNEW.SetMaterialTencentProps) {
+    if (type === 'IMAGE')
+        return request(api + `/adq/v3/marketingAssets/imagesAdd/batch/new`, {
+            method: 'POST',
+            data
+        })
+    else
+        return request(api + `/adq/v3/marketingAssets/videosAdd/batch/new`, {
+            method: 'POST',
+            data
+        })
 }