Jelajahi Sumber

Merge branch 'wangjianxin' of http://git.zanxiangnet.com/wjx/ad-manage into shenwu

shenwu 2 tahun lalu
induk
melakukan
03a07ec9a0
27 mengubah file dengan 1019 tambahan dan 1913 penghapusan
  1. 19 138
      config/routerConfig.ts
  2. 27 27
      src/components/Cropper/index.tsx
  3. 205 0
      src/components/FileBoxAD/components/Cropper/index.tsx
  4. 2 3
      src/components/FileBoxAD/components/fileModal/index.tsx
  5. 7 3
      src/components/FileBoxAD/components/fileModal/sortModal.tsx
  6. 21 0
      src/components/FileBoxAD/components/imgModal/index.less
  7. 131 158
      src/components/FileBoxAD/components/imgModal/index.tsx
  8. 7 41
      src/components/FileBoxAD/index.tsx
  9. 12 0
      src/models/useLaunchAdq/useAdAuthorize.ts
  10. 131 140
      src/models/useLaunchAdq/useBdMedia.ts
  11. 123 131
      src/models/useLaunchAdq/useBdMediaPup.ts
  12. 0 229
      src/pages/launchSystem/launchManage/adAuthorize/customListModel.tsx
  13. 20 164
      src/pages/launchSystem/launchManage/adAuthorize/index.tsx
  14. 0 338
      src/pages/launchSystem/launchManage/adAuthorize/launchRefresh.tsx
  15. 1 58
      src/pages/launchSystem/launchManage/adAuthorize/tableConfig.tsx
  16. 0 175
      src/pages/launchSystem/launchManage/adAuthorize/tableConfigAd.tsx
  17. 0 15
      src/pages/launchSystem/launchManageAdq/weChatAdq/index.less
  18. 0 20
      src/pages/launchSystem/launchManageAdq/weChatAdq/index.tsx
  19. 3 7
      src/pages/launchSystem/material/cloud/index.tsx
  20. 12 0
      src/pages/launchSystemNew/launchManage/adAuthorize/index.less
  21. 34 0
      src/pages/launchSystemNew/launchManage/adAuthorize/index.tsx
  22. 101 0
      src/pages/launchSystemNew/launchManage/adAuthorize/tableConfig.tsx
  23. 17 0
      src/pages/launchSystemNew/material/cloud/index.less
  24. 46 0
      src/pages/launchSystemNew/material/cloud/index.tsx
  25. 12 0
      src/services/launchAdq/adAuthorize.ts
  26. 67 262
      src/services/launchAdq/material.ts
  27. 21 4
      src/utils/utils.ts

+ 19 - 138
config/routerConfig.ts

@@ -39,10 +39,10 @@ function headrRouter(initialState: any, history: any) {
         })
         // localStorage.setItem('bg', 'dark')
     }
-    if (history?.location?.pathname === '/launchSystem') { //当切换一级菜单的辅助跳转
+    if (history?.location?.pathname === '/launchSystemNew') { //当切换一级菜单的辅助跳转
         history?.goBack()
         initialState?.menu?.data.forEach((item: { roles: string[], path: string, routes: { path: string, routes: any[] }[] }) => {
-            if (item?.routes?.some((i: { path: string }) => i.path?.includes('/launchSystem'))) {
+            if (item?.routes?.some((i: { path: string }) => i.path?.includes('/launchSystemNew'))) {
                 let path = item?.routes?.length > 0 ? (item?.routes[0]?.routes?.length > 0 && item?.routes[0]?.routes[0]?.path) ? item?.routes[0]?.routes[0]?.path : item?.routes[0].path : item?.routes[0].path
                 // history.push(path)
                 // window.open(location.origin+'/#'+path)
@@ -546,163 +546,44 @@ const dataStatistics = {
 }
 /** 投放系统 */
 const launchSystem = {
-    path: '/launchSystem',
+    path: '/launchSystemNew',
     routes: [
         {
-            path: '/launchSystem/adMonitor',
-            name: '广告监控',
-            access: 'adMonitor',
-            routes: [
-                {
-                    path: '/launchSystem/adMonitor/adMonitorList',
-                    name: '广告监控',
-                    access: 'adMonitorList',
-                    component: './launchSystem/adMonitor/adMonitorList',
-                },
-                {
-                    path: '/launchSystem/adMonitor/monitorDataSource',
-                    name: '监控数据源',
-                    access: 'monitorDataSource',
-                    component: './launchSystem/adMonitor/monitorDataSource',
-                },
-            ]
-        },
-        {
-            path: '/launchSystem/launchManage',
+            path: '/launchSystemNew/launchManage',
             name: '广告投放',
             access: 'launchManage',
             routes: [
                 {
-                    path: '/launchSystem/launchManage/adAuthorize',
+                    path: '/launchSystemNew/launchManage/adAuthorize',
                     name: '授权',
                     access: 'adAuthorize',
-                    component: './launchSystem/launchManage/adAuthorize',
-                },
-                {
-                    path: '/launchSystem/launchManage/weChat',
-                    name: '微信',
-                    access: 'weChat',
-                    component: './launchSystem/launchManage/weChat',
-                },
-                {
-                    path: '/launchSystem/launchManage/taskList',
-                    name: '任务列表',
-                    access: 'taskList',
-                    component: './launchSystem/launchManage/taskList',
-                },
-            ]
-        },
-        {
-            path: '/launchSystem/launchManageNew',
-            name: '广告投放(new)',
-            access: 'launchManageNew',
-            routes: [
-                {
-                    path: '/launchSystem/launchManageNew/weChatNew',
-                    name: '微信',
-                    access: 'weChatNew',
-                    component: './launchSystem/launchManageNew/weChatNew',
-                },
-                {
-                    path: '/launchSystem/launchManageNew/taskList',
-                    name: '任务列表',
-                    access: 'taskList',
-                    component: './launchSystem/launchManageNew/taskList',
-                }
-            ]
-        },
-        {
-            path: '/launchSystem/launchManageAdq',
-            name: '广告投放(ADQ)',
-            access: 'launchManageAdq',
-            routes: [
-                {
-                    path: '/launchSystem/launchManageAdq/weChatAdq',
-                    name: '微信',
-                    access: 'weChatAdq',
-                    component: './launchSystem/launchManageAdq/weChatAdq',
-                }
-            ]
-        },
-        {
-            path: '/launchSystem/materialManage',
-            name: '云素材管理中心',
-            access: 'materialManage',
-            routes: [
-                {
-                    path: '/launchSystem/materialManage/adOriginality',
-                    name: '广告创意',
-                    access: 'adOriginality',
-                    component: './launchSystem/materialManage/adOriginality',
-                },
-                {
-                    path: '/launchSystem/materialManage/adMaterial',
-                    name: '广告图片/视频',
-                    access: 'adMaterial',
-                    component: './launchSystem/materialManage/adMaterial',
-                },
-                {
-                    path: '/launchSystem/materialManage/adTitle',
-                    name: '广告标题/文案',
-                    access: 'adTitle',
-                    component: './launchSystem/materialManage/adTitle',
+                    component: './launchSystemNew/launchManage/adAuthorize',
                 },
                 // {
-                //     path: '/launchSystem/materialManage/tagManage',
-                //     name: '标签管理',
-                //     access: 'tagManage',
-                //     component: './launchSystem/materialManage/tagManage',
+                //     path: '/launchSystemNew/launchManage/weChat',
+                //     name: '微信',
+                //     access: 'weChat',
+                //     component: './launchSystemNew/launchManage/weChat',
+                // },
+                // {
+                //     path: '/launchSystemNew/launchManage/taskList',
+                //     name: '任务列表',
+                //     access: 'taskList',
+                //     component: './launchSystemNew/launchManage/taskList',
                 // },
             ]
         },
         {
-            path: '/launchSystem/materialManageBd',
-            name: '本地素材管理中心',
-            access: 'materialManage',
-            routes: [
-                {
-                    path: '/launchSystem/materialManageBd/adOriginality',
-                    name: '广告创意',
-                    access: 'adOriginality',
-                    component: './launchSystem/materialManageBd/adOriginality',
-                },
-                {
-                    path: '/launchSystem/materialManageBd/adMaterial',
-                    name: '广告图片/视频',
-                    access: 'adMaterial',
-                    component: './launchSystem/materialManageBd/adMaterial',
-                },
-                {
-                    path: '/launchSystem/materialManageBd/adTitle',
-                    name: '广告标题/文案',
-                    access: 'adTitle',
-                    component: './launchSystem/materialManageBd/adTitle',
-                },
-                {
-                    path: '/launchSystem/materialManageBd/tagManage',
-                    name: '标签管理',
-                    access: 'tagManage',
-                    component: './launchSystem/materialManageBd/tagManage',
-                },
-            ]
-        },
-        {
-            path: '/launchSystem/headline/staticHtml',
-            name: '头条落地页',
-            access: 'staticHtml',
-            component: './launchSystem/headline/staticHtml',
-        },
-        {
-            path: '/launchSystem/material',
+            path: '/launchSystemNew/material',
             name: '素材管理',
             access: 'material',
             icon: 'DatabaseOutlined',
             routes: [
                 {
                     name: '本地素材',
-                    path: '/launchSystem/material/cloud',
+                    path: '/launchSystemNew/material/cloud',
                     access: 'cloud',
-                    component: './launchSystem/material/cloud',
+                    component: './launchSystemNew/material/cloud',
                 },
             ],
         },

+ 27 - 27
src/components/Cropper/index.tsx

@@ -12,7 +12,7 @@ import { blobToBase64 } from '@/utils/compress'
 interface Props {
     width?: number,//初始裁剪框宽
     height?: number,//初始裁剪框高
-    imgSize?: {width: number, height: number, size: number},
+    imgSize?: { width: number, height: number, size: number },
     disabled?: boolean, // 是否禁止传入
     btnName?: string | JSX.Element//按钮名称
     isChangeCropperSize?: boolean,  // 是否可以改变裁剪框大小
@@ -33,7 +33,7 @@ interface Props {
  */
 export const Demo = (props: Props) => {
 
-    let {  isJudgeSize = false, isChangeCropperSize = false, isLaunch = false, isCropper = false, disabled = false, imgSize } = props
+    let { isJudgeSize = false, isChangeCropperSize = false, isLaunch = false, isCropper = false, disabled = false, imgSize } = props
     const [image, setImage] = useState('');//初始图片
     const [visible, setVisible] = useState<boolean>(false)
     const [cropper, setCropper] = useState<any>();//实例
@@ -79,7 +79,7 @@ export const Demo = (props: Props) => {
                 action="#"
                 showUploadList={false}
                 multiple={true}
-                customRequest={()=>{ }}
+                customRequest={() => { }}
                 beforeUpload={(file: RcFile, FileList: RcFile[]): any => {
                     setLoading(true)
                     let img: any = new Image();
@@ -89,14 +89,14 @@ export const Demo = (props: Props) => {
                             if (!props?.width || !props?.height) {
                                 console.error('请传入"width"与"height"');
                                 setLoading(false)
-                                return 
-                            }else if (props?.width < this.width || props?.height < this.height) {
+                                return
+                            } else if (props?.width < this.width || props?.height < this.height) {
                                 message.error(`传入的图片大小不符, 图片大小${this.width}*${this.height}, 需要图片大小${props.width}*${props.height}`)
                                 setLoading(false)
                                 return
                             }
                         }
-                        
+
                         const reader = new FileReader();
                         reader.onload = async () => {
                             let size = imgSize?.size || 307200
@@ -162,10 +162,10 @@ export const Demo = (props: Props) => {
                             setLoading(false)
                             setVisible(true)
                         }
-                        
+
                     }
                     img.src = _URL.createObjectURL(file);
-                    
+
                 }}
             >
                 {
@@ -179,7 +179,7 @@ export const Demo = (props: Props) => {
                 }
             </Dragger>
         }
-        { visible && <Modal
+        {visible && <Modal
             visible={visible}
             onCancel={cancel}
             width={1000}
@@ -232,34 +232,34 @@ export const Demo = (props: Props) => {
                                 </Col>
                                 <Col>
                                     <Form>
-                                        <Form.Item label="裁剪框宽" style={{marginBottom: 0}}>
-                                            <Radio.Group disabled={isChangeCropperSize || isLaunch} onChange={(e)=>{setDetail({...detail, width: e.target.value, height: 800})}} value={detail.width}>
+                                        <Form.Item label="裁剪框宽" style={{ marginBottom: 0 }}>
+                                            <Radio.Group disabled={isChangeCropperSize || isLaunch} onChange={(e) => { setDetail({ ...detail, width: e.target.value, height: 800 }) }} value={detail.width}>
                                                 <Radio value={800}>800</Radio>
                                                 <Radio value={750}>750</Radio>
                                                 <Radio value={640}>640</Radio>
                                             </Radio.Group>
                                         </Form.Item>
-                                        <Form.Item label="裁剪框高" style={{marginBottom: 0}}>
-                                            {detail.width === 800 ? <Radio.Group disabled={isChangeCropperSize || isLaunch} onChange={(e)=>{setDetail({...detail, height: e.target.value})}} value={detail.height}>
+                                        <Form.Item label="裁剪框高" style={{ marginBottom: 0 }}>
+                                            {detail.width === 800 ? <Radio.Group disabled={isChangeCropperSize || isLaunch} onChange={(e) => { setDetail({ ...detail, height: e.target.value }) }} value={detail.height}>
                                                 <Radio value={800}>800</Radio>
                                                 <Radio value={640}>640</Radio>
                                                 <Radio value={450}>450</Radio>
-                                            </Radio.Group> 
-                                            : detail.width === 640 ? <Radio.Group disabled={isChangeCropperSize || isLaunch} onChange={(e)=>{setDetail({...detail, height: e.target.value})}} value={detail.height}>
-                                                <Radio value={800}>800</Radio>
-                                            </Radio.Group> 
-                                            :
-                                            <InputNumber
-                                                style={{ width: 200 }}
-                                                value={detail.height}
-                                                disabled={isChangeCropperSize ? isChangeCropperSize : isLaunch ? false : false}
-                                                min={1}
-                                                max={1536}
-                                                onChange={(e) => {setDetail({...detail, height: e})}}
-                                            />
+                                            </Radio.Group>
+                                                : detail.width === 640 ? <Radio.Group disabled={isChangeCropperSize || isLaunch} onChange={(e) => { setDetail({ ...detail, height: e.target.value }) }} value={detail.height}>
+                                                    <Radio value={800}>800</Radio>
+                                                </Radio.Group>
+                                                    :
+                                                    <InputNumber
+                                                        style={{ width: 200 }}
+                                                        value={detail.height}
+                                                        disabled={isChangeCropperSize ? isChangeCropperSize : isLaunch ? false : false}
+                                                        min={1}
+                                                        max={1536}
+                                                        onChange={(e) => { setDetail({ ...detail, height: e }) }}
+                                                    />
                                             }
                                         </Form.Item>
-                                    
+
                                     </Form>
                                 </Col>
                             </Row>

+ 205 - 0
src/components/FileBoxAD/components/Cropper/index.tsx

@@ -0,0 +1,205 @@
+import { Button, Col, Form, InputNumber, Modal, Radio, Row } from "antd";
+import React, { useEffect, useState } from "react";
+import Cropper from "react-cropper";
+import "cropperjs/dist/cropper.css";
+import { RcFile } from "antd/lib/upload";
+import { dataURLtoFile } from "@/utils/compress";
+
+interface Props {
+    file?: RcFile,
+    visible?: boolean,
+    onChange?: (fileList: any[], file: any) => void,
+    onClose?: () => void
+}
+/**
+ * 新投放素材剪切
+ * @param props 
+ */
+const CropperImg: React.FC<Props> = (props) => {
+
+    /**====================== */
+    const { file, visible, onChange, onClose } = props
+    const [image, setImage] = useState(''); //初始图片
+    const [cropper, setCropper] = useState<any>();//实例
+    const [type, setType] = useState<number>(6)
+    const [dragMode] = useState<'none' | 'crop' | 'move'>('none')
+    const [imgSize, setImageSize] = useState<{ width: number, height: number }>({ width: 0, height: 0 })
+    const [detail, setDetail] = useState<{ width: number, height: number, rotate: number }>({ width: 0, height: 0, rotate: 0 }); //设置数据
+    /**====================== */
+
+    /** 获取宽高 image */
+    useEffect(() => {
+        if (file) {
+            let img: any = new Image();
+            let _URL = window.URL || window.webkitURL;
+            img.onload = function (e: any) {
+                const reader = new FileReader();
+                setDetail({ ...detail, width: this.width, height: this.height })
+                setImageSize({ width: this.width, height: this.height })
+                reader.onload = async () => {
+                    setImage(reader.result as any);
+                }
+                reader.readAsDataURL(file);
+            }
+            img.src = _URL.createObjectURL(file);
+        }
+    }, [])
+
+    /**数值变化重置实例 */
+    useEffect(() => {
+        if (typeof cropper !== "undefined") {
+            setTimeout(() => {
+                cropper.setData(detail);
+            }, 300)
+        }
+    }, [cropper, detail]);
+
+    /** 初始化 */
+    useEffect(() => {
+        if (visible && cropper) {
+            setTimeout(() => {
+                cropper.reset()
+            }, 200)
+        }
+    }, [visible, cropper])
+
+    /** 处理宽高 */
+    useEffect(() => {
+        switch (type) {
+            case 1:
+                setDetail({ ...detail, width: 800, height: 800 })
+                break
+            case 2:
+                setDetail({ ...detail, width: 800, height: 640 })
+                break
+            case 3:
+                setDetail({ ...detail, width: 800, height: 450 })
+                break
+            case 4:
+                setDetail({ ...detail, width: 750, height: 800 })
+                break
+            case 5:
+                setDetail({ ...detail, width: 640, height: 800 })
+                break
+            case 6:
+
+                break
+        }
+    }, [type])
+
+    /**关闭 */
+    const cancel = () => {
+        onClose && onClose()
+        setCropper(undefined)
+        setImage('')
+    }
+
+    const getCropData = async () => {
+        if (typeof cropper !== "undefined") {
+            let newFile = await dataURLtoFile(cropper.getCroppedCanvas().toDataURL('image/jpeg'), file?.name)
+            onChange && onChange([{
+                lastModified: newFile.lastModified,
+                // lastModifiedDate: newFile.lastModifiedDate,
+                name: newFile.name,
+                percent: 0,
+                size: newFile.size,
+                thumbUrl: cropper.getCroppedCanvas().toDataURL('image/jpeg'),
+                type: newFile.type,
+                // uid: newFile.uid,
+                originFileObj: newFile
+            }], newFile)
+            setCropper(undefined)
+            setImage('')
+        }
+    }
+
+    return <Modal
+        visible={visible}
+        onCancel={cancel}
+        width={1000}
+        footer={<div style={{ display: 'flex', justifyContent: 'center' }}>
+            <Button onClick={cancel}>取消</Button>
+            <Button type='primary' onClick={getCropData}>确定</Button>
+        </div>}
+    >
+        <div>
+            <div style={{ width: "100%" }}>
+                <Row>
+                    <Col span={16}>
+                        <Cropper
+                            style={{ height: 450, width: 600, backgroundImage: `url(${require('../../../../../public/init.png')})`, border: '1px solid #efefef' }}
+                            zoomTo={0.6}
+                            initialAspectRatio={1}
+                            preview=".img-preview"
+                            src={image}
+                            viewMode={1}
+                            dragMode={dragMode} // 'crop' 重新设置裁剪框大小 'move' 移动画布
+                            guides={true}
+                            rotatable={true}
+                            minCropBoxHeight={10}
+                            minCropBoxWidth={10}
+                            background={false}
+                            responsive={true}
+                            autoCropArea={1}
+                            cropBoxResizable={false}
+                            zoomable={false} // 图片缩放
+                            movable={false} // 图片移动控制
+                            onInitialized={(instance: any) => {
+                                console.log('instance--->', instance)
+                                setCropper(instance);
+                            }}
+                            crop={() => { }}
+                        />
+                    </Col>
+                    <Col span={8}>
+                        <Row gutter={[10, 10]}>
+                            <Col span={24} style={{ height: 275 }}>
+                                <div className="box" style={{ width: "100%", float: "right", overflow: 'hidden' }}>
+                                    <h1>Preview</h1>
+                                    <div
+                                        className="img-preview"
+                                        style={{ width: "100%", float: "left", height: "200px", overflow: 'hidden' }}
+                                    />
+                                </div>
+                            </Col>
+                            <Col>
+                                <Radio.Group onChange={(e) => { setType(e.target.value) }} value={type} style={{ marginBottom: 20, }}>
+                                    <Radio value={1} disabled={800 > imgSize.width || 800 > imgSize.height}>800*800</Radio>
+                                    <Radio value={2} disabled={800 > imgSize.width || 640 > imgSize.height}>800*640</Radio>
+                                    <Radio value={3} disabled={800 > imgSize.width || 450 > imgSize.height}>800*450</Radio>
+                                    <Radio value={4} disabled={750 > imgSize.width}>{"750*<1536"}</Radio>
+                                    <Radio value={5} disabled={640 > imgSize.width || 800 > imgSize.height}>640*800</Radio>
+                                    <Radio value={6}>自定义</Radio>
+                                </Radio.Group>
+                                <Form>
+                                    {type === 6 && <Form.Item label="裁剪框宽" style={{ marginBottom: 10 }}>
+                                        <InputNumber
+                                            style={{ width: 200 }}
+                                            value={detail.width}
+                                            min={1}
+                                            onChange={(e) => { setDetail({ ...detail, width: e }) }}
+                                        />
+                                    </Form.Item>}
+
+                                    {(type === 6 || type === 4) && <Form.Item label="裁剪框高" style={{ marginBottom: 0 }}>
+                                        <InputNumber
+                                            style={{ width: 200 }}
+                                            value={detail.height}
+                                            min={1}
+                                            max={imgSize.height}
+                                            onChange={(e) => { setDetail({ ...detail, height: e }) }}
+                                        />
+                                    </Form.Item>}
+
+                                </Form>
+
+                            </Col>
+                        </Row>
+                    </Col>
+                </Row>
+            </div>
+        </div>
+    </Modal>
+}
+
+export default React.memo(CropperImg)

+ 2 - 3
src/components/FileBoxAD/components/fileModal/index.tsx

@@ -4,7 +4,7 @@ import { useModel } from 'umi'
 /**新建文件夹,修改非图文素材名称 */
 function FileModal(props: { isAll?: boolean }) {
     const { isAll } = props
-    const { state, set, fileOk, nameOk, offEditFile } = useModel(isAll ? 'useLaunchAdq.useBdMedia' : 'useLaunchAdq.useBdMediaPup')
+    const { state, set, addFolder, nameOk, offEditFile } = useModel(isAll ? 'useLaunchAdq.useBdMedia' : 'useLaunchAdq.useBdMediaPup')
     const { fileVisible, actionItem, fileName, sort, videoDescription, videoTitle } = state
     const { state: { selectWx }, initSelectWx } = useModel('useOperating.useWxGroupList')//公众号筛选
     const title = useMemo(() => {
@@ -19,11 +19,10 @@ function FileModal(props: { isAll?: boolean }) {
         }
         return '新建文件夹'
     }, [actionItem])
-    console.log(state)
     return <Modal
         visible={fileVisible}
         destroyOnClose
-        onOk={(e) => { actionItem ? nameOk(selectWx) : fileOk(e, undefined, selectWx); initSelectWx() }}
+        onOk={(e) => { actionItem ? nameOk(selectWx) : addFolder(); initSelectWx() }}
         onCancel={() => { offEditFile(); initSelectWx() }}
         width={400}
         title={title}

+ 7 - 3
src/components/FileBoxAD/components/fileModal/sortModal.tsx

@@ -8,7 +8,7 @@ interface Props {
 }
 function SortModal(props: Props) {
     const { isAll } = props
-    const { state, offEditFile, configSort, list, set } = useModel(isAll ? 'useOperating.useBdMedia' : 'useOperating.useBdMediaPup')
+    const { state, offEditFile, configSort, listImg, listVideo, set } = useModel(isAll ? 'useLaunchAdq.useBdMedia' : 'useLaunchAdq.useBdMediaPup')
     const { sortVisible, actionItem } = state
     const [sort, setSort] = useState<number>(0)
 
@@ -17,9 +17,13 @@ function SortModal(props: Props) {
     }, [actionItem?.sort])
 
     const sortHandle = () => {
-        configSort.run({ sysMediaId: actionItem?.id, sort: sort }).then(res => {
+        configSort.run({ sysMediaId: actionItem?.id, sort: sort, mediaType: state?.mediaType }).then(res => {
             if (res) {
-                list?.refresh()
+                if (state?.mediaType === 'IMG') {
+                    listImg.refresh()
+                } else if (state?.mediaType === 'VIDEO') {
+                    listVideo.refresh()
+                }
                 set({ sortVisible: false, actionItem: null })
             }
         })

+ 21 - 0
src/components/FileBoxAD/components/imgModal/index.less

@@ -0,0 +1,21 @@
+.file {
+  position: relative;
+  cursor: pointer;
+
+  >input {
+    opacity: 0;
+    position: absolute;
+    display: block;
+    top: 0;
+    left: 0;
+    cursor: pointer;
+    right: 0;
+    bottom: 0;
+    width: 100%;
+    font-size: 0;
+
+    >span {
+      display: none;
+    }
+  }
+}

+ 131 - 158
src/components/FileBoxAD/components/imgModal/index.tsx

@@ -1,10 +1,10 @@
-import React, { useCallback, useState } from 'react'
-import { Form, Input, InputNumber, Modal, Upload } from 'antd'
-import FormItem from '@/components/Formitem'
-import { FormConfig } from '@/components/Formitem/type'
+import React, { useCallback, useMemo, useState } from 'react'
+import { Button, Form, Input, InputNumber, message, Modal, Space, Upload } from 'antd'
 import { useModel } from 'umi'
 import { RcFile } from 'antd/lib/upload'
-
+import CropperImg from '../Cropper'
+import { UploadOutlined } from '@ant-design/icons'
+import style from './index.less'
 
 /**新建非图文素材 */
 let ImgModal = React.memo((props: { isAll?: boolean }) => {
@@ -13,164 +13,137 @@ let ImgModal = React.memo((props: { isAll?: boolean }) => {
     const { isAll } = props
     const [queryForm, setQueryForm] = useState<{ title: string, sort: number, file: any }>({ title: '', sort: 0, file: null })
     const [fileList, setFileList] = useState<any>([])
-    const [fromsubmit, setFromsubmit] = useState<() => Promise<any>>()//存放from提交事件
-    const callback = useCallback((fnc: () => Promise<any>) => { setFromsubmit(fnc) }, [])//回调获取from提交事件
-    const { state, typeEnum, fileOk, offEditFile } = useModel(isAll ? 'useLaunchAdq.useBdMedia' : 'useLaunchAdq.useBdMediaPup')
-    const { imgVisrible, mediaType, actionItem } = state
+    const [fileUrl, setFileUrl] = useState<string>('')
+    const [previewVisible, setPreviewVisible] = useState<boolean>(false)
+    const [visible, setVisible] = useState<boolean>(false)
+    const { state, typeEnum, addFile, offEditFile } = useModel(isAll ? 'useLaunchAdq.useBdMedia' : 'useLaunchAdq.useBdMediaPup')
+    const { imgVisrible, mediaType, actionItem, upLoadLoading } = state
     /*****========END=========*****/
 
-    const onFinish = (values: any) => {
-        console.log('Success:', values);
-    };
 
-    const onFinishFailed = (errorInfo: any) => {
-        console.log('Failed:', errorInfo);
-    };
+    const handleOk = (e: any) => {
+        e?.stopPropagation()
+        if (queryForm.file) {
+            addFile({ ...queryForm });
+        } else {
+            message.error('请上传素材')
+        }
+    }
+
+    const getVideo = useMemo(() => {
+        if (queryForm?.file) {
+            return <video src={URL.createObjectURL(queryForm?.file)} style={{ width: '100%' }} controls />
+        } else {
+            return null
+        }
+    }, [queryForm?.file])
 
-    return <Modal
-        title={(actionItem ? '编辑' : '新建') + typeEnum[mediaType as string]}
-        visible={imgVisrible}
-        onOk={(e) => { fileOk(e, fromsubmit); }}
-        onCancel={() => {
-            offEditFile();
-        }}
-        width={450}
-        destroyOnClose
-        maskClosable={false}
-    >
-        {/* <FormItem
-            formConfig={config(typeEnum[mediaType as string])}
-            flow='column'
-            getFormSubmit={callback}
-            defaultProps={{ sort: 0 }}
-            isAll={isAll}
-        /> */}
-        <Form
-            name="basic"
-            labelCol={{ span: 4 }}
-            wrapperCol={{ span: 20 }}
-            autoComplete="off"
+    return <div>
+        <Modal
+            title={(actionItem ? '编辑' : '新建') + typeEnum[mediaType as string]}
+            visible={imgVisrible}
+            onOk={(e) => { handleOk(e) }}
+            confirmLoading={upLoadLoading}
+            onCancel={() => {
+                offEditFile();
+            }}
+            width={450}
+            destroyOnClose
+            maskClosable={false}
         >
-            <Form.Item
-                label="图片名称"
-            >
-                <Input value={queryForm.title} onChange={(e) => setQueryForm({ ...queryForm, title: e.target.value })} placeholder="请输入图片名称" />
-            </Form.Item>
-            <Form.Item
-                label="排序"
-                tooltip="数值越大越靠前"
+            <Form
+                name="basic"
+                labelCol={{ span: 4 }}
+                wrapperCol={{ span: 20 }}
+                autoComplete="off"
             >
-                <InputNumber value={queryForm.sort} onChange={(e) => setQueryForm({ ...queryForm, sort: e })} placeholder="请输入排序" />
-            </Form.Item>
-            <Form.Item
-                label={'上传' + typeEnum[mediaType as string]}
-            >
-                {/* {
-                    fileList?.length < 1 && <Upload
-                        listType="picture-card"
-                        accept='image/gif,image/jpeg,image/png,image/jpg'
-                        beforeUpload={function (file: RcFile) {
-                            fileChanage(file)
-                            return false
-                        }}
-                        fileList={fileList}
-                        onChange={(newFileList: any) => {
-                            setFileList([...newFileList.fileList])
-                        }}
-                        onPreview={(file: any) => {
-                            // setPreviewVisible(true)
-                            setFileUrl(file.thumbUrl)
-                        }}
-                    >
-                        {fileList?.length < 1 && '普通上传'}
-                    </Upload>
-                } */}
-            </Form.Item>
-        </Form>
-    </Modal>
-})
-export default ImgModal
-let config: (name: string,) => FormConfig[] = (name) => {
-    let videoArr: FormConfig[] = [
-        {
-            label: name + '名称',
-            tag: 'input',
-            name: 'videoTitle',
-            width: 200,
-        },
+                <Form.Item
+                    label="图片名称"
+                >
+                    <Input value={queryForm.title} onChange={(e) => setQueryForm({ ...queryForm, title: e.target.value })} placeholder="请输入图片名称" />
+                </Form.Item>
+                <Form.Item
+                    label="排序"
+                    tooltip="数值越大越靠前"
+                >
+                    <InputNumber value={queryForm.sort} onChange={(e) => setQueryForm({ ...queryForm, sort: e })} placeholder="请输入排序" />
+                </Form.Item>
+                <Form.Item
+                    label={'上传' + typeEnum[mediaType as string]}
+                >
+                    {mediaType === 'IMG' ? <Space>
+                        <Upload
+                            listType="picture-card"
+                            accept='image/gif,image/jpeg,image/png,image/jpg'
+                            beforeUpload={(file: RcFile) => {
+                                return false
+                            }}
+                            fileList={fileList}
+                            onChange={(newFileList: any) => {
+                                console.log('newFileList-->', newFileList)
+                                setQueryForm({ ...queryForm, file: newFileList.file })
+                                setFileList([...newFileList.fileList])
+                            }}
+                            onPreview={(file: any) => {
+                                setPreviewVisible(true)
+                                setFileUrl(file.thumbUrl)
+                            }}
+                        >
+                            {fileList?.length < 1 && '普通上传'}
+                        </Upload>
+                        {
+                            fileList?.length === 0 && <Upload
+                                listType="picture-card"
+                                accept='image/gif,image/jpeg,image/png,image/jpg'
+                                beforeUpload={(file: RcFile) => {
+                                    return false
+                                }}
+                                fileList={fileList}
+                                onChange={(newFileList: any) => {
+                                    setQueryForm({ ...queryForm, file: newFileList.file })
+                                    setVisible(true)
+                                }}
+                                onPreview={(file: any) => {
+                                    setPreviewVisible(true)
+                                    setFileUrl(file.thumbUrl)
+                                }}
+                            >
+                                {fileList?.length < 1 && '裁剪上传'}
+                            </Upload>
+                        }
+                    </Space> : <>
+                        <div className={style.file}>
+                            <Button type='primary'><UploadOutlined />上传视频</Button>
+                            <input type='file' onChange={(e) => {
+                                if (e?.target?.files) {
+                                    setQueryForm({ ...queryForm, file: e?.target?.files[0] })
+                                }
+                            }} accept="video/*" />
+                        </div>
+                        {
+                            queryForm?.file && <>
+                                <p>{queryForm?.file?.name}</p>
+                                {getVideo}
+                            </>
+                        }
+                    </>}
 
-        {
-            label: name + '描述',
-            tag: 'TextArea',
-            name: 'videoDescription',
-            width: 300,
-        },
-        {
-            label: '排序',
-            tag: 'inputNumber',
-            name: 'sort',
-            width: 200,
-        },
-        {
-            label: '上传' + name,
-            tag: 'inputFile',
-            name: 'file',
-            required: true,
-            message: '请上传文件'
-        }
-    ]
-    let imgArr: FormConfig[] = [
-        {
-            label: name + '名称',
-            tag: 'input',
-            name: 'fileName',
-            width: 200,
-        },
-        {
-            label: '排序',
-            tag: 'inputNumber',
-            name: 'sort',
-            width: 200,
-        },
-        {
-            label: '上传' + name,
-            tag: 'imgCrop',
-            name: 'file',
-            required: true,
-            message: '请上传文件'
-        }
-    ]
-    let arr: FormConfig[] = [
-        {
-            label: name + '名称',
-            tag: 'input',
-            name: 'fileName',
-            width: 200,
-        },
-        {
-            label: '排序',
-            tag: 'inputNumber',
-            name: 'sort',
-            width: 200,
-        },
-        {
-            label: '上传' + name,
-            tag: 'inputFile',
-            name: 'file',
-            required: true,
-            message: '请上传文件'
-        }
-    ]
-    if (name === '编辑') {
-        return [
-            {
-                label: name + '名称',
-                tag: 'input',
-                name: 'fileName',
-                width: 200
-            },
-        ]
-    }
-    return name === '视频' ? videoArr : name === '图片' ? imgArr : arr
-}
+                </Form.Item>
+            </Form>
+        </Modal>
 
+        <Modal
+            visible={previewVisible}
+            footer={null}
+            onCancel={() => {
+                setPreviewVisible(false)
+            }}
+        >
+            <img alt="example" style={{ width: '100%' }} src={fileUrl} />
+        </Modal>
+
+        {/* 裁剪 */}
+        {visible && <CropperImg visible={visible} onClose={() => setVisible(false)} file={queryForm.file} onChange={(fileList: any[], file: any) => { setFileList(fileList); setQueryForm({ ...queryForm, file: file }); setVisible(false) }} />}
+    </div>
+})
+export default React.memo(ImgModal)

+ 7 - 41
src/components/FileBoxAD/index.tsx

@@ -5,8 +5,6 @@ import style from './index.less'
 import FileModal from './components/fileModal'
 import { useModel } from "umi"
 import ImgModal from "./components/imgModal"
-import Updata from "../MaterialModal/updata"
-import WxSelect from "../WxSelect"
 import TreeBox from "./components/tree"
 import SortModal from "./components/fileModal/sortModal"
 
@@ -39,9 +37,10 @@ interface Item {
     knewsThumbId: number,//本地图片ID
     knewsThumbInfo: any,//k客服详情
     videoTitle: string,//视频标题
+    width: number, // 宽
+    height: number,  // 高
 }
 interface Props {
-    showSync?: (props?: any) => void,//同步弹窗事件
     isAll?: boolean,//是否允许全选默认开启
     height?: any,//当使用为弹窗组件时设置高度以免太高
     noFile?: boolean,//是否禁止选择文件夹
@@ -49,11 +48,10 @@ interface Props {
 }
 function FlieBox(props: Props) {
 
-    const { showSync, isAll = true, height, noFile = false, isBd } = props
+    const { isAll = true, height, noFile = false, isBd } = props
     const { state, set, dels, listImg, listVideo, get, onFile, allFile, delPupOn, delPupOff, changeClickFile, editFile, fileClick, treeClick, pathClick, getList, edit_media_folder, get_folder_tree_img, get_folder_tree_video } = useModel(isAll || isBd ? 'useLaunchAdq.useBdMedia' : 'useLaunchAdq.useBdMediaPup')
     const { fileVisible, belongUser, selectFile, delPupId, xy, rightClickPup, path, publicPath, parentId, imgVisrible, mediaType, sortVisible } = state
     const { copy } = useCopy()
-    const [updataVisible, setUpdataVisible] = useState<boolean>(false)
     const fileImg = require('../../../public/file.png')
     const [moveId, setMoveId] = useState<any>('')//移动的素材ID
     const [treeEl, item, folderId, setActionId, setHoverId] = TreeBox({ data: mediaType === 'IMG' ? get_folder_tree_img.data : get_folder_tree_video.data, belongUser })
@@ -82,18 +80,10 @@ function FlieBox(props: Props) {
                     isAll && <li onClick={allFile}>全选/反选</li>
                 }
                 <li onClick={(e) => { delPupOn(rightClickPup.id); onFile(e, rightClickPup, isAll, true) }}> 删除</li>
-                {
-                    !rightClickPup?.folder && <li onClick={() => {
-                        showSync && showSync({ sysMediaId: rightClickPup?.id })
-                    }}>同步</li>
-                }
-                <li onClick={() => {
-                    editFile()
-                }}>编辑</li>
+                <li onClick={() => { editFile() }}>编辑</li>
                 <li onClick={() => { set({ actionItem: rightClickPup, sortVisible: true }) }}>编辑排序</li>
                 <li onClick={() => { set({ fileVisible: true }) }}>新建文件夹</li>
                 <li onClick={() => { set({ imgVisrible: true }) }}>新建素材</li>
-                <li onClick={() => { setUpdataVisible(true) }}>批量新增素材</li>
                 {
                     isAll && <li onClick={dels}>删除选中文件</li>
                 }
@@ -102,9 +92,6 @@ function FlieBox(props: Props) {
         return <ul style={{ top: xy?.y, left: xy?.x }} className={style.menu}>
             {
                 isAll && <li onClick={allFile}>全选/反选</li>
-            }
-            {
-
             }
             {//防止K图文无限嵌套创建判断
                 (isAll !== false) ? <li onClick={() => { set({ fileVisible: true }) }}>新建文件夹</li> : <li>此处无法新建操作</li>
@@ -112,7 +99,6 @@ function FlieBox(props: Props) {
             {
                 (isAll !== false) && <li onClick={() => { set({ imgVisrible: true }) }}>新建素材</li>
             }
-            <li onClick={() => { setUpdataVisible(true) }}>批量新增素材</li>
             {
                 isAll && <li onClick={dels}>删除选中文件</li>
             }
@@ -127,23 +113,6 @@ function FlieBox(props: Props) {
         set({ xy: { x, y } })
         if (isItem) {
             set({ rightClickPup: isItem })
-            if (!isItem?.folder && isItem?.mediaType === 'knews') {
-                set({
-                    knewsdefaultData: {//客服消息编辑回填弹窗中的内容预先存放
-                        newsList: [
-                            {
-                                title: isItem?.title,
-                                knewsThumbUrl: isItem?.knewsThumbUrl,
-                                knewsLink: isItem?.knewsLink,
-                                description: isItem?.description,
-                                knewsThumbInfo: isItem?.knewsThumbInfo,
-                                knewsThumbId: isItem?.knewsThumbId,
-                                sort: isItem?.sort || 0
-                            }
-                        ]
-                    }
-                })
-            }
         } else {
             set({ rightClickPup: { id: 'all' } })
         }
@@ -204,7 +173,7 @@ function FlieBox(props: Props) {
             },
             onDragEnd: (e: any) => {
                 if (folderId !== '' && moveId !== '') {
-                    edit_media_folder.run({ sysMediaId: moveId, folderId }).then(res => {
+                    edit_media_folder.run({ sysMediaId: moveId, folderId, mediaType }).then(res => {
                         message.success('操作成功')
                         if (mediaType === 'IMG') {
                             listImg.refresh()
@@ -233,7 +202,7 @@ function FlieBox(props: Props) {
             <div className={style.files} onContextMenu={rightMenu} style={height ? { height } : {}}>
                 {/* 关联公众号筛选 */}
                 <div className={style.wxSelect}>
-                    <WxSelect mode={1} isAll={isAll} />
+                    {/* <WxSelect mode={1} isAll={isAll} /> */}
                 </div>
                 {/* 层级路径 */}
                 <div className={style.path} >
@@ -328,12 +297,11 @@ function FlieBox(props: Props) {
                                             </span>
                                             {El}
                                             <span className={style.flex_box_name} onClick={(e) => { copyId(e, item?.url) }}>{item?.videoTitle || item?.title}</span>
-                                            <span className={style.flex_box_id} onClick={(e) => { copyId(e, item?.number) }} >{item?.number}</span>
+                                            <span onClick={(e) => { copyId(e, item?.number) }} >{item?.width}*{item.height}</span>
                                         </div>
                                     </Spin>
                                 </Popconfirm>
                             }
-                            return null
                         })
                     }
                 </div>
@@ -345,8 +313,6 @@ function FlieBox(props: Props) {
                 {sortVisible && <SortModal isAll={isAll} />}
                 {/* 新建非图文 */}
                 {imgVisrible && <ImgModal isAll={isAll} />}
-                {/* 批量新建素材 */}
-                {updataVisible && <Updata mediaType={mediaType === 'IMG' ? '1' : mediaType === 'VIDEO' ? '3' : '2'} callBcak={setUpdataVisible} type={1} isAll={isAll} />}
             </div>
             {
                 listData?.records?.length > 0 && <div className={style.pagination}>

+ 12 - 0
src/models/useLaunchAdq/useAdAuthorize.ts

@@ -0,0 +1,12 @@
+import { useAjax } from '@/Hook/useAjax'
+import { getAdAccountApi } from '@/services/launchAdq/adAuthorize'
+
+
+export default function useAdAuthorize() {
+
+    const getAdAccount = useAjax(() => getAdAccountApi(), { formatResult: true })
+
+    return {
+        getAdAccount
+    }
+}

+ 131 - 140
src/models/useLaunchAdq/useBdMedia.ts

@@ -1,7 +1,10 @@
 import getMD5 from '@/components/MD5';
 import { useAjax } from '@/Hook/useAjax';
-import { bdSysMediaListImg, bdSysMediaListVideo, bdSysMediaAdd, delMedia, bdSysMediaEdit, getFileUrl, syncMedia, getMedia, configSortApi, syncForSend, wxSysMediaAdd, editWxlist, getFolderTreeImg, getFolderTreeVideo, editMediaFolder } from '@/services/launchAdq/material';
+import { bdSysMediaListImg, bdSysMediaListVideo, bdSysMediaAdd, delMedia, bdSysMediaEdit, getFileUrl, getMedia, configSortApi, getFolderTreeImg, getFolderTreeVideo, editMediaFolder } from '@/services/launchAdq/material';
+import { blobToBase64, dataURLtoFile, videoMessage } from '@/utils/compress';
+import { getImgSize } from '@/utils/utils';
 import { message } from 'antd';
+import { compressAccurately } from 'image-conversion';
 import { Dispatch, useCallback, useReducer, useState } from 'react'
 import { request } from 'umi';
 
@@ -29,7 +32,11 @@ type State = {
     file?: File,//素材文件
     selectItem?: any,//单选素材时存放选中的素材
     knewsdefaultData?: any,//k图文编辑时的默认内容
-    sortVisible?:boolean,//排序弹窗
+    sortVisible?: boolean,//排序弹窗
+
+
+    size?: number,  // 需要上传素材的大小
+    upLoadLoading?: boolean,  // 上传loading
 }
 export type Action = {
     type: 'set' | 'init',
@@ -71,30 +78,26 @@ const initData: State = {
     path: [{ title: '个人本地', number: '0' }],
     imgVisrible: false,
     newsVisrible: false,
-    sortVisible:false,
-    sort: 0
+    sortVisible: false,
+    sort: 0,
 }
 /**本地素材管理器 */
 function useBdMediaPup() {
     const [state, dispatch]: [State, Dispatch<Action>] = useReducer(reducer, initData)
-    const { fileName, sort, belongUser, mediaType, parentId, selectFile, delPupId, rightClickPup, actionItem, path, publicPath, file, videoTitle, videoDescription } = state
+    const { fileName, sort, belongUser, mediaType, parentId, selectFile, delPupId, rightClickPup, actionItem, path, publicPath, size, videoTitle, videoDescription } = state
     const listImg = useAjax((params) => bdSysMediaListImg(params))
     const listVideo = useAjax((params) => bdSysMediaListVideo(params))
     const add = useAjax((params) => bdSysMediaAdd(params), { msgNmae: '新增' })
-    const addWx = useAjax((params) => wxSysMediaAdd(params), { msgNmae: '新增' })
     const del = useAjax((params) => delMedia(params), { msgNmae: '删除' })
     const edit = useAjax((params) => bdSysMediaEdit(params), { msgNmae: '编辑' })
-    const sync = useAjax((params) => syncMedia(params), { msgNmae: '同步' })
-    const syncId = useAjax((params) => syncForSend(params), { msgNmae: '同步' })
     const configSort = useAjax((params) => configSortApi(params), { msgNmae: '排序' })
     const get_folder_tree_img = useAjax((params: any) => getFolderTreeImg(params))
     const get_folder_tree_video = useAjax((params: any) => getFolderTreeVideo(params))
     const edit_media_folder = useAjax((params: any) => editMediaFolder(params))
-    const get = useAjax((params) => getMedia(params))//获取图文详情
-    const eidtWxlists = useAjax((params) => editWxlist(params))
+    const get = useAjax((params) => getMedia(params))//获取本地素材详情
     const [isOk, setIsOk] = useState<boolean>(true)
     //请求上传地址
-    const fileUrl = useAjax((params: { type: string }) => getFileUrl(params), {
+    const fileUrl = useAjax((params: { type: string, fileType: 'video' | 'image' }) => getFileUrl(params), {
         manual: true,
     })
     /**初始化数据 */
@@ -109,130 +112,128 @@ function useBdMediaPup() {
             dispatch({ type: 'set', params })
         }
     }, [])
-    /**新增K-客服模板消息 */
-    const knewsOk = useCallback((props: any) => {
-        let { title, knewsThumbUrl, knewsLink, description, knewsThumbId } = props?.newsList[0]
-        let obj = {
-            parentId,
-            belongUser: belongUser === '0' ? false : true,
-            folder: false,
-            mediaType,
-            title: title,
-            knewsThumbUrl: knewsThumbUrl,
-            knewsLink: knewsLink,
-            description: description,
-            sort: props.sort
-        }
-        if (knewsThumbId) {//数据中存在封面图本地ID加入本地ID
-            obj['knewsThumbId'] = knewsThumbId
-        }
-        if (rightClickPup?.id && rightClickPup?.id !== 'all') {//编辑时传入ID
-            obj['sysMediaId'] = rightClickPup?.id
-            edit.run(obj).then((res) => {
-                if (res) {
-                    if (mediaType === 'IMG') {
-                        listImg.refresh()
-                    } else if (mediaType === 'VIDEO') {
-                        listVideo.refresh()
-                    }
-                    set({ knewsVisrible: false, knewsdefaultData: null })
+    /**新增文件夹 */
+    const addFolder = () => {
+        if (fileName) {
+            let obj = { title: fileName, mediaType, folder: true, parentId, belongUser: belongUser === '0' ? false : true, sort }
+            add.run(obj).then((res) => {
+                if (mediaType === 'IMG') {
+                    get_folder_tree_img.refresh()
+                } else if (mediaType === 'VIDEO') {
+                    get_folder_tree_video.refresh()
                 }
-            })
-            eidtWxlists.run({ sysMediaId: rightClickPup?.id, mpIds: props?.mpIds || [] }).then((res) => {
-                console.log(res)
-            })
-        } else {
-            add.run({ ...obj, mpIds: props?.mpIds || [] }).then((res) => {
-                if (res) {
-                    if (mediaType === 'IMG') {
-                        listImg.refresh()
-                    } else if (mediaType === 'VIDEO') {
-                        listVideo.refresh()
-                    }
-                    set({ knewsVisrible: false, knewsdefaultData: null })
+
+                if (mediaType === 'IMG') {
+                    listImg.refresh()
+                } else if (mediaType === 'VIDEO') {
+                    listVideo.refresh()
                 }
+                offEditFile()//关闭弹窗并清空相关数据
             })
         }
-    }, [add, edit, listImg, listVideo, parentId, belongUser, mediaType, rightClickPup])
-    /**新增文件夹,非图文素材 */
-    const fileOk = useCallback((e: any, fnc?: () => Promise<any>, selectWx?: number[]) => {
-        e?.stopPropagation()
-        if (fnc) {//存在代表素材
-            fnc().then(res => {
-                console.log('11111111--->', res)
-                if (!res) {
-                    return
+    }
+    /** 新增图片 视频 */
+    const addFile = async (data: any) => {
+        if (data) {//存在代表素材
+            if (!data) {
+                return
+            }
+            if (data?.file) {
+                let file = data.file
+                let fileSize = size || 0
+                if (!size) {
+                    if (mediaType === 'IMG') {
+                        fileSize = 307200
+                    } else {
+                        fileSize = 104857600
+                    }
                 }
-                if (res?.file && file) {
-                    /**修改文件名以用户设置的文件title命名*/
-                    let newFile = new File([file], res?.fileName ? res?.fileName + '.' + file?.name?.split('.')[1] : file?.name, { type: file?.type })
-                    let formData = new FormData();
-                    if (mediaType === 'VIDEO' || mediaType === 'IMG') {
-                        if (newFile.size > 10485760) {
-                            message.error('请上传小于10M的素材')
-                            return
+
+                if (mediaType === 'IMG') {
+                    if (file?.size > fileSize) { // 大于300kb进入压缩
+                        let bole = await compressAccurately(file, 250)
+                        if (bole?.size > 300000) {
+                            bole = await compressAccurately(file, 200)
+                        }
+                        if (bole?.size > 300000) {
+                            bole = await compressAccurately(file, 150)
                         }
+                        if (bole?.size > 300000) {
+                            bole = await compressAccurately(file, 100)
+                        }
+                        let newFile = await blobToBase64(bole)
+                        message.warning({
+                            content: `选择的图片大于${fileSize / 1024}KB,图片已压缩`,
+                            duration: 3
+                        })
+                        file = await dataURLtoFile(newFile, file?.name)
                     }
-
-                    /**向阿里云请求上传地址*/
-                    fileUrl.run({ type: newFile.type }).then(res1 => {
-                        Object.keys(res1).forEach((key: string) => {
-                            if (key !== 'url') {
-                                formData.append(key, res1[key])
-                            }
+                } else if (mediaType === 'VIDEO') {
+                    if (file?.size > fileSize) { // 大于100mb进入压缩
+                        message.error({
+                            content: `选择的视频大于${fileSize / 1024 / 1024}MB,请重新选择提交`,
+                            duration: 3
                         })
-                        formData.append('file', newFile)
-                        /**向阿里云返回的上传地址上传文件*/
-                        request(res1?.ossUrl, { method: 'post', body: formData }).then(async (res2: { code: number, data: { url: string } }) => {
-                            if (res2.code === 200) {
-                                message.success('上传成功')
-                                if (res) {
-                                    /**取到返回的文件地址向后端发送具体数据*/
-                                    if (res2?.data?.url) {
-                                        let fileMd5 = await getMD5(file)
-                                        let obj = { title: res?.fileName, mediaType, folder: false, parentId, belongUser: belongUser === '0' ? false : true, url: res2?.data?.url, mpIds: selectWx, sort: res?.sort, fileMd5, fileSize: newFile?.size }
-                                        if (mediaType === 'VIDEO') {
-                                            obj['videoTitle'] = res?.videoTitle || res?.title
-                                            obj['videoDescription'] = res?.videoDescription
-                                        }
-                                        add.run(obj).then((res) => {
-                                            console.log(res)
-                                            if (mediaType === 'IMG') {
-                                                listImg.refresh()
-                                            } else if (mediaType === 'VIDEO') {
-                                                listVideo.refresh()
-                                            }
-                                            offEditFile()//关闭弹窗并清空相关数据
-                                        })
+                        return
+                    }
+                }
+                set({ upLoadLoading: true })
+                let width = 0
+                let height = 0
+                if (mediaType === 'IMG') {
+                    let imgData = await getImgSize(file)
+                    width = imgData.width
+                    height = imgData.height
+                } else if (mediaType === "VIDEO") {
+                    let videoInfo: any = await videoMessage([file])
+                    width = videoInfo[0].width
+                    height = videoInfo[0].height
+                }
+                /**修改文件名以用户设置的文件title命名*/
+                let newFile = new File([file], data?.title ? data?.title + '.' + file?.name?.split('.')[1] : file?.name, { type: file?.type })
+                let formData = new FormData();
+
+                /**向阿里云请求上传地址*/
+                fileUrl.run({ type: newFile.type, fileType: mediaType === 'VIDEO' ? 'video' : 'image' }).then(res1 => {
+                    Object.keys(res1).forEach((key: string) => {
+                        if (key !== 'url') {
+                            formData.append(key, res1[key])
+                        }
+                    })
+                    formData.append('file', newFile)
+                    /**向阿里云返回的上传地址上传文件*/
+                    request(res1?.ossUrl, { method: 'post', body: formData }).then(async (res2: { code: number, data: { url: string } }) => {
+                        if (res2.code === 200) {
+                            message.success('上传成功')
+                            if (data) {
+                                /**取到返回的文件地址向后端发送具体数据*/
+                                if (res2?.data?.url) {
+                                    let fileMd5 = await getMD5(newFile)
+                                    let obj = { title: data.title, mediaType, folder: false, parentId, width, height, fileMd5, belongUser: belongUser === '0' ? false : true, url: res2?.data?.url, sort: data?.sort, fileSize: newFile?.size, fileMime: newFile.type }
+                                    if (mediaType === 'VIDEO') {
+                                        obj['videoTitle'] = data?.videoTitle || data?.title
+                                        obj['videoDescription'] = data?.videoDescription
                                     }
+                                    add.run(obj).then((res) => {
+                                        console.log(res)
+                                        if (mediaType === 'IMG') {
+                                            listImg.refresh()
+                                        } else if (mediaType === 'VIDEO') {
+                                            listVideo.refresh()
+                                        }
+                                        offEditFile()//关闭弹窗并清空相关数据
+                                        set({ upLoadLoading: false })
+                                    }).catch(() => set({ upLoadLoading: false }))
                                 }
-                            } else {
-                                message.error('上传失败!')
                             }
-                        })
-                    })
-                }
-            })
-        } else {
-            if (fileName) {
-                let obj = { title: fileName, mediaType, folder: true, parentId, belongUser: belongUser === '0' ? false : true, mpIds: selectWx, sort }
-                add.run(obj).then((res) => {
-                    if (mediaType === 'IMG') {
-                        get_folder_tree_img.refresh()
-                    } else if (mediaType === 'VIDEO') {
-                        get_folder_tree_video.refresh()
-                    }
-                    
-                    if (mediaType === 'IMG') {
-                        listImg.refresh()
-                    } else if (mediaType === 'VIDEO') {
-                        listVideo.refresh()
-                    }
-                    offEditFile()//关闭弹窗并清空相关数据
-                })
+                        } else {
+                            message.error('上传失败!')
+                        }
+                    }).catch(() => set({ upLoadLoading: false }))
+                }).catch(() => set({ upLoadLoading: false }))
             }
         }
-    }, [fileName, mediaType, parentId, belongUser, listImg, listVideo, file])
+    }
     /**编辑非图文素材名称*/
     const nameOk = useCallback((selectWx?: any) => {
         if (fileName && actionItem) {
@@ -250,10 +251,6 @@ function useBdMediaPup() {
                 offEditFile()//关闭弹窗并清空相关数据
             })
         }
-        //
-        eidtWxlists.run({ sysMediaId: actionItem?.id, mpIds: selectWx || [] }).then((res) => {
-            console.log(res)
-        })
     }, [fileName, actionItem, edit, belongUser, mediaType, videoTitle, videoDescription])
     /**删除文件 */
     const dels = useCallback((id?: any) => {
@@ -261,19 +258,21 @@ function useBdMediaPup() {
         let len = arr?.length || 0
         if (len) {
             arr?.map((id, index) => {
-                del.run(id).then(() => {
+                del.run({ sysMediaId: id, mediaType }).then(() => {
                     set({ selectFile: selectFile?.filter(i => i !== id) })//清理已删除文件
                     if (index === len - 1) {
                         if (mediaType === 'IMG') {
                             listImg.refresh()
+                            get_folder_tree_img.refresh()
                         } else if (mediaType === 'VIDEO') {
                             listVideo.refresh()
+                            get_folder_tree_video.refresh()
                         }
                     }
                 })
             })
         }
-    }, [listImg, listVideo, selectFile])
+    }, [listImg, listVideo, selectFile, mediaType])
     /**获取本地素材数据列表 */
     const getList = useCallback((props?: any) => {
         let obj = { pageSize: 20, pageNum: 1, belongUser: belongUser === '0' ? false : true, parentId, ...props }
@@ -409,12 +408,12 @@ function useBdMediaPup() {
     }, [rightClickPup])
     /**取消编辑后清空选中存放的数据并关闭弹窗*/
     const offEditFile = useCallback(() => {
-        set({ fileVisible: false, imgVisrible: false,sortVisible:false, actionItem: '', fileName: '', selectFile: selectFile?.filter(id => id !== actionItem?.id), sort: 0 })
+        set({ fileVisible: false, imgVisrible: false, sortVisible: false, actionItem: '', fileName: '', selectFile: selectFile?.filter(id => id !== actionItem?.id), sort: 0 })
     }, [selectFile, actionItem])
     /**全选反选文件*/
     const allFile = useCallback(() => {
         let allArr: any[] = []
-        
+
         if (mediaType === 'IMG') {
             listImg?.data?.records?.forEach((item: { id: any }) => {
                 allArr.push(item.id)
@@ -426,15 +425,12 @@ function useBdMediaPup() {
         }
         set({ selectFile: allArr.filter((i) => selectFile?.every(id => id !== i)) })
     }, [selectFile, listImg, listVideo, mediaType])
-    /**图文素材弹窗开关 */
-    const showNews = useCallback(() => {
-
-    }, [])
     return {
         state,
         init,
         set,
-        fileOk,
+        addFile,
+        addFolder,
         getList,
         dels,
         onFile,
@@ -448,19 +444,14 @@ function useBdMediaPup() {
         fileClick,
         treeClick,
         pathClick,
-        knewsOk,
         configSort,
         fileUrl,
-        addWx,
         listImg,
         listVideo,
         add,
-        sync,
         get,
         edit,
-        syncId,
         typeEnum,
-        eidtWxlists,
         get_folder_tree_img,
         get_folder_tree_video,
         edit_media_folder

+ 123 - 131
src/models/useLaunchAdq/useBdMediaPup.ts

@@ -1,7 +1,10 @@
 import getMD5 from '@/components/MD5';
 import { useAjax } from '@/Hook/useAjax';
-import { bdSysMediaListImg, bdSysMediaListVideo, bdSysMediaAdd, delMedia, bdSysMediaEdit, getFileUrl, syncMedia, getMedia, configSortApi, syncForSend, wxSysMediaAdd, editWxlist, getFolderTreeImg, getFolderTreeVideo, editMediaFolder } from '@/services/launchAdq/material';
+import { bdSysMediaListImg, bdSysMediaListVideo, bdSysMediaAdd, delMedia, bdSysMediaEdit, getFileUrl, getMedia, configSortApi, getFolderTreeImg, getFolderTreeVideo, editMediaFolder } from '@/services/launchAdq/material';
+import { blobToBase64, dataURLtoFile, videoMessage } from '@/utils/compress';
+import { getImgSize } from '@/utils/utils';
 import { message } from 'antd';
+import { compressAccurately } from 'image-conversion';
 import { Dispatch, useCallback, useReducer, useState } from 'react'
 import { request } from 'umi';
 /**新本地素材弹窗 */
@@ -30,6 +33,9 @@ type State = {
     selectItem?: any,//单选素材时存放选中的素材
     knewsdefaultData?: any,//k图文编辑时的默认内容
     sortVisible?:boolean,//排序弹窗
+
+    size?: number,  // 需要上传素材的大小
+    upLoadLoading?: boolean
 }
 export type Action = {
     type: 'set' | 'init',
@@ -77,24 +83,20 @@ const initData: State = {
 /**本地素材管理器 */
 function useBdMediaPup() {
     const [state, dispatch]: [State, Dispatch<Action>] = useReducer(reducer, initData)
-    const { fileName, sort, belongUser, mediaType, parentId, selectFile, delPupId, rightClickPup, actionItem, path, publicPath, file, videoTitle, videoDescription } = state
+    const { fileName, sort, belongUser, mediaType, parentId, selectFile, delPupId, rightClickPup, actionItem, path, publicPath, videoTitle, videoDescription, size } = state
     const listImg = useAjax((params) => bdSysMediaListImg(params))
     const listVideo = useAjax((params) => bdSysMediaListVideo(params))
     const add = useAjax((params) => bdSysMediaAdd(params), { msgNmae: '新增' })
-    const addWx = useAjax((params) => wxSysMediaAdd(params), { msgNmae: '新增' })
     const del = useAjax((params) => delMedia(params), { msgNmae: '删除' })
     const edit = useAjax((params) => bdSysMediaEdit(params), { msgNmae: '编辑' })
-    const sync = useAjax((params) => syncMedia(params), { msgNmae: '同步' })
-    const syncId = useAjax((params) => syncForSend(params), { msgNmae: '同步' })
     const configSort = useAjax((params) => configSortApi(params), { msgNmae: '排序' })
     const get = useAjax((params) => getMedia(params))//获取图文详情
     const get_folder_tree_img = useAjax((params: any) => getFolderTreeImg(params))
     const get_folder_tree_video = useAjax((params: any) => getFolderTreeVideo(params))
     const edit_media_folder = useAjax((params: any) => editMediaFolder(params))
     const [isOk, setIsOk] = useState<boolean>(true)
-    const eidtWxlists = useAjax((params) => editWxlist(params))
     //请求上传地址
-    const fileUrl = useAjax((params: { type: string }) => getFileUrl(params), {
+    const fileUrl = useAjax((params: { type: string, fileType: 'video' | 'image' }) => getFileUrl(params), {
         manual: true,
     })
     /**初始化数据 */
@@ -107,128 +109,128 @@ function useBdMediaPup() {
             dispatch({ type: 'set', params })
         }
     }, [])
-    /**新增K-客服模板消息 */
-    const knewsOk = useCallback((props: any) => {
-        let { title, knewsThumbUrl, knewsLink, description, knewsThumbId } = props?.newsList[0]
-        let obj = {
-            parentId,
-            belongUser: belongUser === '0' ? false : true,
-            folder: false,
-            mediaType,
-            title: title,
-            knewsThumbUrl: knewsThumbUrl,
-            knewsLink: knewsLink,
-            description: description,
-            sort: props.sort
-        }
-        if (knewsThumbId) {//数据中存在封面图本地ID加入本地ID
-            obj['knewsThumbId'] = knewsThumbId
-        }
-        if (rightClickPup?.id && rightClickPup?.id !== 'all') {//编辑时传入ID
-            obj['sysMediaId'] = rightClickPup?.id
-            edit.run(obj).then((res) => {
-                if (res) {
-                    if (mediaType === 'IMG') {
-                        listImg.refresh()
-                    } else if (mediaType === 'VIDEO') {
-                        listVideo.refresh()
-                    }
-                    set({ knewsVisrible: false, knewsdefaultData: null })
+    /**新增文件夹 */
+    const addFolder = () => {
+        if (fileName) {
+            let obj = { title: fileName, mediaType, folder: true, parentId, belongUser: belongUser === '0' ? false : true, sort }
+            add.run(obj).then((res) => {
+                if (mediaType === 'IMG') {
+                    get_folder_tree_img.refresh()
+                } else if (mediaType === 'VIDEO') {
+                    get_folder_tree_video.refresh()
                 }
-            })
-            eidtWxlists.run({ sysMediaId: rightClickPup?.id, mpIds: props?.mpIds || [] }).then((res) => {
-                console.log(res)
-            })
-        } else {
-            add.run({ ...obj, mpIds: props?.mpIds }).then((res) => {
-                if (res) {
-                    if (mediaType === 'IMG') {
-                        listImg.refresh()
-                    } else if (mediaType === 'VIDEO') {
-                        listVideo.refresh()
-                    }
-                    set({ knewsVisrible: false, knewsdefaultData: null })
+
+                if (mediaType === 'IMG') {
+                    listImg.refresh()
+                } else if (mediaType === 'VIDEO') {
+                    listVideo.refresh()
                 }
+                offEditFile()//关闭弹窗并清空相关数据
             })
         }
-    }, [add, edit, listImg, listVideo, parentId, belongUser, mediaType, rightClickPup])
-    /**新增文件夹,非图文素材 */
-    const fileOk = useCallback((e: any, fnc?: () => Promise<any>, selectWx?: number[]) => {
-        e?.stopPropagation()
-        if (fnc) {//存在代表素材
-            fnc().then(res => {
-                if (!res) {
-                    return
+    }
+    /** 新增图片 视频 */
+    const addFile = async (data: any) => {
+        if (data) {//存在代表素材
+            if (!data) {
+                return
+            }
+            if (data?.file) {
+                let file = data.file
+                let fileSize = size || 0
+                if (!size) {
+                    if (mediaType === 'IMG') {
+                        fileSize = 307200
+                    } else {
+                        fileSize = 104857600
+                    }
                 }
-                if (res?.file && file) {
-                    /**修改文件名以用户设置的文件title命名*/
-                    let newFile = new File([file], res?.fileName ? res?.fileName + '.' + file?.name?.split('.')[1] : file?.name, { type: file?.type })
-                    let formData = new FormData();
 
-                    if (mediaType === 'VIDEO' || mediaType === 'IMG') {
-                        if (newFile.size > 10485760) {
-                            message.error('请上传小于10M的素材')
-                            return
+                if (mediaType === 'IMG') {
+                    if (file?.size > fileSize) { // 大于300kb进入压缩
+                        let bole = await compressAccurately(file, 250)
+                        if (bole?.size > 300000) {
+                            bole = await compressAccurately(file, 200)
+                        }
+                        if (bole?.size > 300000) {
+                            bole = await compressAccurately(file, 150)
                         }
+                        if (bole?.size > 300000) {
+                            bole = await compressAccurately(file, 100)
+                        }
+                        let newFile = await blobToBase64(bole)
+                        message.warning({
+                            content: `选择的图片大于${fileSize / 1024}KB,图片已压缩`,
+                            duration: 3
+                        })
+                        file = await dataURLtoFile(newFile, file?.name)
                     }
-
-                    /**向阿里云请求上传地址*/
-                    fileUrl.run({ type: newFile.type }).then(res1 => {
-                        Object.keys(res1).forEach((key: string) => {
-                            if (key !== 'url') {
-                                formData.append(key, res1[key])
-                            }
+                } else if (mediaType === 'VIDEO') {
+                    if (file?.size > fileSize) { // 大于100mb进入压缩
+                        message.error({
+                            content: `选择的视频大于${fileSize / 1024 / 1024}MB,请重新选择提交`,
+                            duration: 3
                         })
-                        formData.append('file', newFile)
-                        /**向阿里云返回的上传地址上传文件*/
-                        request(res1?.ossUrl, { method: 'post', body: formData }).then(async (res2: { code: number, data: { url: string } }) => {
-                            if (res2.code === 200) {
-                                message.success('上传成功')
-                                if (res) {
-                                    /**取到返回的文件地址向后端发送具体数据*/
-                                    if (res2?.data?.url) {
-                                        let fileMd5 = await getMD5(file)
-                                        let obj = { title: res?.fileName, mediaType, folder: false, parentId, belongUser: belongUser === '0' ? false : true, url: res2?.data?.url, mpIds: selectWx, sort: res?.sort, fileMd5, fileSize: newFile?.size }
-                                        if (mediaType === 'VIDEO') {
-                                            obj['videoTitle'] = res?.videoTitle || res?.title
-                                            obj['videoDescription'] = res?.videoDescription
-                                        }
-                                        add.run(obj).then((res) => {
-                                            if (mediaType === 'IMG') {
-                                                listImg.refresh()
-                                            } else if (mediaType === 'VIDEO') {
-                                                listVideo.refresh()
-                                            }
-                                            offEditFile()//关闭弹窗并清空相关数据
-                                        })
+                        return
+                    }
+                }
+                set({ upLoadLoading: true })
+                let width = 0
+                let height = 0
+                if (mediaType === 'IMG') {
+                    let imgData = await getImgSize(file)
+                    width = imgData.width
+                    height = imgData.height
+                } else if (mediaType === "VIDEO") {
+                    let videoInfo: any = await videoMessage([file])
+                    width = videoInfo[0].width
+                    height = videoInfo[0].height
+                }
+                /**修改文件名以用户设置的文件title命名*/
+                let newFile = new File([file], data?.title ? data?.title + '.' + file?.name?.split('.')[1] : file?.name, { type: file?.type })
+                let formData = new FormData();
+
+                /**向阿里云请求上传地址*/
+                fileUrl.run({ type: newFile.type, fileType: mediaType === 'VIDEO' ? 'video' : 'image' }).then(res1 => {
+                    Object.keys(res1).forEach((key: string) => {
+                        if (key !== 'url') {
+                            formData.append(key, res1[key])
+                        }
+                    })
+                    formData.append('file', newFile)
+                    /**向阿里云返回的上传地址上传文件*/
+                    request(res1?.ossUrl, { method: 'post', body: formData }).then(async (res2: { code: number, data: { url: string } }) => {
+                        if (res2.code === 200) {
+                            message.success('上传成功')
+                            if (data) {
+                                /**取到返回的文件地址向后端发送具体数据*/
+                                if (res2?.data?.url) {
+                                    let fileMd5 = await getMD5(newFile)
+                                    let obj = { title: data.title, mediaType, folder: false, parentId, width, height, fileMd5, belongUser: belongUser === '0' ? false : true, url: res2?.data?.url, sort: data?.sort, fileSize: newFile?.size, fileMime: newFile.type }
+                                    if (mediaType === 'VIDEO') {
+                                        obj['videoTitle'] = data?.videoTitle || data?.title
+                                        obj['videoDescription'] = data?.videoDescription
                                     }
+                                    add.run(obj).then((res) => {
+                                        console.log(res)
+                                        if (mediaType === 'IMG') {
+                                            listImg.refresh()
+                                        } else if (mediaType === 'VIDEO') {
+                                            listVideo.refresh()
+                                        }
+                                        offEditFile()//关闭弹窗并清空相关数据
+                                        set({ upLoadLoading: false })
+                                    }).catch(() => set({ upLoadLoading: false }))
                                 }
-                            } else {
-                                message.error('上传失败!')
                             }
-                        })
-                    })
-                }
-            })
-        } else {
-            if (fileName) {
-                let obj = { title: fileName, mediaType, folder: true, parentId, belongUser: belongUser === '0' ? false : true, mpIds: selectWx, sort }
-                add.run(obj).then((res) => {
-                    if (mediaType === 'IMG') {
-                        get_folder_tree_img.refresh()
-                    } else if (mediaType === 'VIDEO') {
-                        get_folder_tree_video.refresh()
-                    }
-                    if (mediaType === 'IMG') {
-                        listImg.refresh()
-                    } else if (mediaType === 'VIDEO') {
-                        listVideo.refresh()
-                    }
-                    offEditFile()//关闭弹窗并清空相关数据
-                })
+                        } else {
+                            message.error('上传失败!')
+                        }
+                    }).catch(() => set({ upLoadLoading: false }))
+                }).catch(() => set({ upLoadLoading: false }))
             }
         }
-    }, [fileName, mediaType, parentId, belongUser, listImg, listVideo, file])
+    }
     /**编辑非图文素材名称*/
     const nameOk = useCallback((selectWx: any) => {
         if (fileName && actionItem) {
@@ -246,10 +248,6 @@ function useBdMediaPup() {
                 offEditFile()//关闭弹窗并清空相关数据
             })
         }
-        //
-        eidtWxlists.run({ sysMediaId: actionItem?.id, mpIds: selectWx || [] }).then((res) => {
-            console.log(res)
-        })
     }, [fileName, actionItem, edit, belongUser, mediaType, videoTitle, videoDescription])
     /**删除文件 */
     const dels = useCallback((id?: any) => {
@@ -257,19 +255,21 @@ function useBdMediaPup() {
         let len = arr?.length || 0
         if (len) {
             arr?.map((id, index) => {
-                del.run(id).then(() => {
+                del.run({ sysMediaId: id, mediaType }).then(() => {
                     set({ selectFile: selectFile?.filter(i => i !== id) })//清理已删除文件
                     if (index === len - 1) {
                         if (mediaType === 'IMG') {
                             listImg.refresh()
+                            get_folder_tree_img.refresh()
                         } else if (mediaType === 'VIDEO') {
                             listVideo.refresh()
+                            get_folder_tree_video.refresh()
                         }
                     }
                 })
             })
         }
-    }, [listImg, listVideo, selectFile])
+    }, [listImg, listVideo, selectFile, mediaType])
     /**获取本地素材数据列表 */
     const getList = useCallback((props?: any) => {
         console.log('mediaType',mediaType)
@@ -424,15 +424,12 @@ function useBdMediaPup() {
         }
         set({ selectFile: allArr.filter((i) => selectFile?.every(id => id !== i)) })
     }, [selectFile, listImg, listVideo, mediaType])
-    /**图文素材弹窗开关 */
-    const showNews = useCallback(() => {
-
-    }, [])
     return {
         state,
         init,
         set,
-        fileOk,
+        addFile,
+        addFolder,
         getList,
         dels,
         onFile,
@@ -446,18 +443,13 @@ function useBdMediaPup() {
         fileClick,
         treeClick,
         pathClick,
-        knewsOk,
         configSort,
-        addWx,
         listImg,
         listVideo,
         add,
-        sync,
         get,
         edit,
-        syncId,
         typeEnum,
-        eidtWxlists,
         get_folder_tree_img,
         get_folder_tree_video,
         edit_media_folder

+ 0 - 229
src/pages/launchSystem/launchManage/adAuthorize/customListModel.tsx

@@ -1,229 +0,0 @@
-import { CloseOutlined, SearchOutlined } from "@ant-design/icons"
-import { Button, Checkbox, Input, message, Modal, Spin } from "antd"
-import React, { useCallback, useEffect, useState } from "react"
-import './index.less'
-import { ReactComponent as DrawStem } from '@/assets/drawStem.svg'
-import { SortableContainer, SortableElement, SortableHandle } from "react-sortable-hoc";
-import arrayMove from "array-move";
-import { useModel } from "umi"
-
-const DragHandle = SortableHandle(() => <DrawStem className='draw' />);
-const SortableItem = SortableElement(({ item, del }: any) => {
-    return <li className='liDraw'>
-        <div className='lileft'><DragHandle /><div>{item.index_name}</div></div>
-        {item.db_name !== 'pos_type' && <div className="clear" onClick={() => { del() }}><CloseOutlined /></div>}
-    </li>
-});
-/** 外层 */
-const SortableList = SortableContainer(({ children }: { children: any }) => (<ul className='selectedList'>{children}</ul>));
-
-interface IndexListProps {
-    index_name: string,
-    index_description: string,
-    db_name: string,
-    for_pos_type: string,
-    for_ad_level: string,
-    is_default: number,
-    format_type: string,
-    support_crowd: number,
-    name_desc: string
-}
-
-interface DataProps {
-    index_classify_name: string,
-    indexList: IndexListProps[]
-}
-
-/**
- * 自定义列
- */
-type customProps = {
-    visible?: boolean,
-    onChange?: () => void,
-    onClose?: () => void,
-    unames?: {
-        MP?: any,
-        ADQ?: any,
-        id: number
-    }[]
-}
-function CustomListModel(props: customProps) {
-    const { visible, onChange, onClose, unames } = props
-
-    const { getAdsTableConfig, getUserConfig, updateUserConfig } = useModel('useLaunch.useAdAuthorize')
-    // dataA 总数据
-    // 数据开始
-    const [dataA, setDataA] = useState<DataProps[]>([])
-    const [data, setData] = useState<DataProps[]>([])
-    const [search, setSearch] = useState<string>('')  // 搜索字段
-    const [selectData, setSelectData] = useState<IndexListProps[]>([])
-    const [serverData, setServerData] = useState<IndexListProps[]>([])
-    // 数据结束
-
-    // 获取数据
-    useEffect(() => {
-        getList(false)
-        getUserList()
-    }, [])
-
-    // 获取所有配置信息
-    const getList = (update: boolean) => {
-        getAdsTableConfig.run({ update }).then((res: any) => {
-            if (res?.data) {
-                setDataA(() => JSON.parse(res?.data))
-                setData(() => JSON.parse(res?.data))
-            }
-        })
-    }
-    // 获取个人配置
-    const getUserList = () => {
-        getUserConfig.run().then((res: any) => {
-            if (res?.data) {
-                setSelectData(() => JSON.parse(res?.data))
-                setServerData(() => JSON.parse(res?.data))
-            } else {
-                setSelectData(() => [
-                    { index_name: "广告位", index_description: "广告展现的位置。", db_name: "pos_type", for_pos_type: "mp", for_ad_level: "all", is_default: 0, format_type: "", support_crowd: 0, name_desc: "" }
-                ])
-            }
-        })
-    }
-
-    // 搜索 过滤
-    const searchHandle = useCallback((value: string) => {
-        setSearch(value)
-        if (search) {
-            let newData1: any[] = []
-            dataA.forEach((item: DataProps) => {
-                let newData = item.indexList.filter((listItem: IndexListProps) => {
-                    if (listItem?.index_name?.includes(value)) {
-                        return listItem
-                    } else {
-                        return null
-                    }
-                })
-                if (newData?.length > 0) {
-                    newData1.push({ ...item, indexList: newData })
-                }
-            })
-            setData([...newData1])
-        } else {
-            setData(dataA)
-        }
-    }, [data, dataA, search])
-
-    // 选中数据
-    const selectHandle = useCallback((checked: boolean, data: IndexListProps) => {
-        if (checked) {
-            setSelectData([...selectData, { ...data }])
-        } else {
-            let newSelectData = selectData.filter((item: IndexListProps) => {
-                if (item.db_name === data.db_name) {
-                    return null
-                } else {
-                    return item
-                }
-            })
-            setSelectData(newSelectData)
-        }
-    }, [selectData])
-
-    // 每个大项 全选
-    const checkAllHandle = useCallback((checked: boolean, value: string) => {
-        let oldData = data.find((item: DataProps) => item.index_classify_name === value)
-        if (oldData) {
-            if (checked) {
-                let newSelectData: any[] = selectData
-                oldData.indexList.forEach((item: IndexListProps) => {
-                    if (selectData.findIndex((selsectItem: IndexListProps) => selsectItem.db_name === item.db_name) === -1) {
-                        newSelectData.push(item)
-                    }
-                })
-                console.log(value,newSelectData,oldData)
-                setSelectData([...newSelectData])
-            } else {
-                let newSelectData = selectData.filter((item: IndexListProps) => {
-                    if (oldData?.indexList?.some((dataItem: IndexListProps) => dataItem.db_name === 'pos_type' ? false : dataItem?.db_name === item.db_name)) {
-                        return null
-                    } else {
-                        return item
-                    }
-                })
-                setSelectData(newSelectData)
-            }
-        }
-
-    }, [selectData, data])
-
-    const onSortEnd = ({ oldIndex, newIndex }: { oldIndex: number, newIndex: number }) => {
-        setSelectData(arrayMove(selectData, oldIndex, newIndex))
-    }
-    // 提交
-    const onSubmit = useCallback(() => {
-        let idList: any[] = []
-        unames?.forEach((item: { MP?: any, ADQ?: any, id: number }) => {
-            let { MP } = item
-            if (MP?.length > 0) {
-                let mpIds = MP?.map((m: any) => m?.id)
-                idList = idList.concat(mpIds)
-            }
-        })     
-        updateUserConfig.run({idList, tableConfig: JSON.stringify(selectData)}).then((res: any) => {
-            if (res?.data) {
-                message.success('同步成功')
-                onClose && onClose()
-            }
-        })
-    }, [unames, serverData, selectData])
-
-    return <Modal
-        title={null}
-        footer={null}
-        visible={visible}
-        width={960}
-        className='customListModel'
-        onCancel={() => { onClose && onClose() }}
-    >
-        <div className='content'>
-            <div className='left'>
-                <div className='leftSearch'>
-                    <Input size="small" placeholder="输入关键词,搜索数据指标" onChange={(e) => { searchHandle(e.target.value) }} value={search} prefix={<SearchOutlined style={{ color: '#a3a3a3', fontSize: 18 }} />} allowClear bordered={false} />
-                </div>
-
-                <div className="dataList">
-                    <Spin spinning={getAdsTableConfig.loading}>
-                        {data?.map((item: DataProps, index: number) => {
-                            return <dl key={index}>
-                                <dt>
-                                    <Checkbox onChange={(e) => { checkAllHandle(e.target.checked, item.index_classify_name) }} className='checkbox'>{item.index_classify_name}</Checkbox>
-                                </dt>
-                                {item.indexList?.map((listItem: IndexListProps, listIndex: number) => {
-                                    return <dd key={item.index_classify_name + listIndex}>
-                                        <Checkbox onChange={(e) => { selectHandle(e.target.checked, listItem) }} disabled={listItem.db_name === 'pos_type'} checked={selectData.some((selectItem: { db_name: string }) => selectItem.db_name === listItem.db_name)} className='checkbox'>{listItem.index_name}</Checkbox>
-                                    </dd>
-                                })}
-                            </dl>
-                        })}
-                    </Spin>
-                </div>
-            </div>
-            <div className='right'>
-                <div className='rightTitle'>
-                    <div className="rightTitleLeft">已选<span>{selectData?.length}</span>项</div>
-                </div>
-                <SortableList axis='y' onSortEnd={onSortEnd} useDragHandle>
-                    {selectData.map((item: IndexListProps, index: number) => <SortableItem key={'li' + index} index={index} item={item} del={() => { selectHandle(false, item) }} />)}
-                </SortableList>
-                <div className='rightOperate'>
-                    <Button type='link' loading={getAdsTableConfig.loading} onClick={() => { getList(true) }}>刷新</Button>
-                    <div>
-                        <Button onClick={() => { onClose && onClose() }}>取消</Button>
-                        <Button type='primary' className='confirm' loading={updateUserConfig.loading} onClick={() => { onSubmit() }}>确认</Button>
-                    </div>
-                </div>
-            </div>
-        </div>
-    </Modal>
-}
-
-export default React.memo(CustomListModel)

+ 20 - 164
src/pages/launchSystem/launchManage/adAuthorize/index.tsx

@@ -1,26 +1,16 @@
 
 import HocError from '@/Hoc/HocError'
-import { Button, Card, Form, Input, message, Modal, Radio, Select, Space, Table, Tag ,Tabs} from 'antd'
+import { Button, Card, Form, Input, Select, Space, Table, Tag } from 'antd'
 import React, { useCallback, useEffect, useState } from 'react'
-import { columnsMp, columnsAdq } from './tableConfig'
-import LaunchRefresh from './launchRefresh'
+import { columnsMp } from './tableConfig'
 import { useModel } from 'umi'
-import AdLogin from '../components/adLogin'
-import { getCookie, setCookie } from '@/utils/cry'
-import { CloudDownloadOutlined, EyeOutlined, QuestionCircleOutlined } from '@ant-design/icons'
 
 
 /** 投放管理 */
 const AdAuthorize: React.FC = () => {
     const [form] = Form.useForm();
-    const [refreshShow, setRefreshShow] = useState<boolean>(false) // 刷新账户弹窗控制
-    const [channel, setChannel] = useState<string>('MP') // 选择渠道
     const [paging, setPaging] = useState<{ pageSize: number, pageNum: number, withChannel: boolean, uname?: string, selectServer?: number }>({ pageSize: 20, pageNum: 1, withChannel: true }) // 用户表格参数
-    const { allOfLoginUser, adsChannelAccountAdq1, adsChannelAccountMp1, mpSc, adqSc, loginAd } = useModel('useLaunch.useAdAuthorize')
-    const userId = useModel('@@initialState',model=>model.initialState?.currentUser?.userId as string)
-    const [authData, setAuthData] = useState<{ base64: string, code: string }>({ base64: '', code: '' })
-    const [lock,setLock] = useState(false)
-    const [errShow,setErrShow]=useState(false)
+    const { getAdAccount } = useModel('useLaunchAdq.useAdAuthorize')
     /** 查询 */
     const submitForm = useCallback((values: any) => {
         setPaging({ ...paging, ...values, pageNum: 1 })
@@ -30,87 +20,18 @@ const AdAuthorize: React.FC = () => {
         form.resetFields();
     }, [])
 
-
-    /**  */
-    const onAuthorize = () => {
-        // setWarrant(true)
-        setRefreshShow(true)
-    }
-
     useEffect(() => {
-        // 获取服务商列表
-        allOfLoginUser.run()
+        // 获取账号列表
+        getAdAccount.run()
     }, [])
 
-    /** 获取列表 */
-    useEffect(() => {
-        if (channel === 'MP') {
-            adsChannelAccountMp1.run({ ...paging })
-        } else {
-            adsChannelAccountAdq1.run({ ...paging })
-        }
-    }, [channel, paging])
-
-    /**收藏*/
-    const collect = useCallback((arg: { id: any, c: boolean, name: 'adq' | 'mp' }) => {
-        let { id, c, name } = arg
-        if (name === 'mp') {
-            mpSc.run({ accountId: id, collect: c }).then((res) => {
-                adsChannelAccountMp1.refresh()
-            })
-        } else {
-            adqSc.run({ accountId: id, collect: c }).then((res) => {
-                adsChannelAccountAdq1.refresh()
-            })
-        }
-    }, [adsChannelAccountMp1, adsChannelAccountAdq1])
-
-    /**验证授权*/
-    const checkLogin = useCallback((fn: () => void) => {
-        let isLogin = getCookie('mpLogin'+userId) || getCookie(userId)
-        if (!isLogin) {
-            let hide = message.warning('验证授权状态中,成功授权后请重新点击....', 0)
-            loginAd.run({ scanCode: 'wx' }).then((res: any) => {
-                if (res?.code === 1003 && res?.data?.base64) {
-                    // setIsUpdataAcc(false)
-                    setAuthData(res?.data)
-                    // setBacse64(res?.data?.base64, res?.data?.code)
-                } else if (res?.code === 500) {
-                    console.log('接口出错')
-                } else if (res?.code === 200) {
-                    console.log('已授权3', res)
-                    setCookie('mpLogin'+userId, 'true', 1)
-                    fn()
-                }
-                hide()
-            })
-        } else {
-            fn()
-        }
-    }, [])
-    /**帮助跳转页面 */
-    const help = useCallback(() => {
-        window.open('https://shimo.im/docs/xvHKKtJgXXkrhRTy')
-    }, [])
-    const plugin=useCallback(()=>{
-        window.open('http://test.zanxiangnet.com/aaplugin/插件.zip')
-    },[])
     return <Card
         title={<Space wrap>
-            <Radio.Group value={channel} onChange={(e) => { setChannel(e.target.value); setPaging({ pageSize: 20, pageNum: 1, withChannel: true }) }}>
-                <Radio.Button value="MP">MP</Radio.Button>
-                {/* <Radio.Button value="ADQ">ADQ</Radio.Button> */}
-            </Radio.Group>
             <Form
                 layout="inline"
                 form={form}
                 onFinish={submitForm}
             >
-                <Form.Item label="服务商" name="channelId">
-                    <Select style={{ width: 180 }} placeholder="选择服务商" allowClear>
-                        {allOfLoginUser?.data?.data?.map((item: { id: number, accountName: string }) => <Select.Option value={item?.id} key={item?.id}>{item?.accountName}</Select.Option>)}
-                    </Select>
-                </Form.Item>
                 <Form.Item label="广告主名称" name="uname">
                     <Input placeholder="输入广告主" />
                 </Form.Item>
@@ -122,87 +43,22 @@ const AdAuthorize: React.FC = () => {
                 </Form.Item>
             </Form>
         </Space>}
-        extra={<Space>
-            <Button onClick={plugin} ><CloudDownloadOutlined />插件下载</Button>
-            <Button onClick={()=>{setLock(true)}} ><EyeOutlined />插件安装演示</Button>
-            <Button onClick={help} >帮助<QuestionCircleOutlined /></Button>
-            {/* <Button onClick={()=>{setErrShow(true)}} type="primary" danger>错误信息帮助<QuestionCircleOutlined /></Button> */}
-            <Button type="primary" onClick={() => { checkLogin(onAuthorize) }}>授权/刷新账户</Button>
-        </Space>}
     >
-        {refreshShow && <LaunchRefresh show={refreshShow} onClose={() => { setRefreshShow(false) }}></LaunchRefresh>}
-        {
-            channel === "MP" ? <Table dataSource={adsChannelAccountMp1?.data?.data?.records} loading={adsChannelAccountMp1?.loading} columns={columnsMp(collect)} size="small" bordered
-                pagination={{
-                    position: ['bottomRight'],
-                    total: adsChannelAccountMp1?.data?.data?.total,//总共多少条数据,服务器给,设置后分页自动计算页数
-                    showTotal: (total) => <Tag color="cyan">总共{total}数据</Tag>,
-                    showSizeChanger: true,
-                    showLessItems: true,
-                    defaultCurrent: 1,
-                    defaultPageSize: 20,//默认初始的每页条数
-                    current: paging?.pageNum || 1,
-                    pageSize: paging?.pageSize || 20,
-                    onChange: (page, pageSize) => { setPaging({ ...paging, pageNum: page, pageSize: pageSize as number }) }
-                }}
-                rowKey={(row) => row.id}
-            /> :
-                <Table dataSource={adsChannelAccountAdq1?.data?.data?.records} loading={adsChannelAccountAdq1?.loading} columns={columnsAdq(collect)} size="small" bordered
-                    pagination={{
-                        position: ['bottomRight'],
-                        total: adsChannelAccountAdq1?.data?.data?.total,//总共多少条数据,服务器给,设置后分页自动计算页数
-                        showTotal: (total) => <Tag color="cyan">总共{total}数据</Tag>,
-                        showSizeChanger: true,
-                        showLessItems: true,
-                        defaultCurrent: 1,
-                        defaultPageSize: 20,//默认初始的每页条数
-                        current: paging?.pageNum || 1,
-                        pageSize: paging?.pageSize || 20,
-                        onChange: (page, pageSize) => { setPaging({ ...paging, pageNum: page, pageSize: pageSize as number }) }
-                    }}
-                    rowKey={(row) => row.id}
-                />
-        }
-        {/* 授权登录 */}
-        <AdLogin onClose={() => { setAuthData({ base64: '', code: '' }) }} value={authData} onChange={() => { setAuthData({ base64: '', code: '' }) }} />
-        {/* 插件安装演示弹窗 */}
-        {
-            lock && <Modal
-                    visible={lock}
-                    onCancel={()=>{setLock(false)}}
-                    width={'80%'}
-                    title={<><h3>插件演示<span style={{color:'red',fontSize:14}}>(注:一定要开启无痕模式)</span></h3></>}
-                    footer={null}
-                >
-                    <Tabs defaultActiveKey={'1'}>
-                        <Tabs.TabPane tab='首次安装' key={'1'}>
-                        <video src='https://zx-oss-dev.oss-cn-hangzhou.aliyuncs.com/file/C6B091FEDB8C461898F2F0297ADFF864.mp4' style={{width:'100%'}} controls/>
-                        </Tabs.TabPane>
-                        <Tabs.TabPane tab='版本更新' key={'2'}>
-                        <video src='https://zx-oss-dev.oss-cn-hangzhou.aliyuncs.com/file/078AA816C9DE4498B78CEC0854F29530.mp4' style={{width:'100%'}} controls/>
-                        </Tabs.TabPane>
-                        <Tabs.TabPane tab='开启无痕' key={'3'}>
-                        <video src='https://zx-oss-dev.oss-cn-hangzhou.aliyuncs.com/file/82954CAE8F634CD48C8596CBFBF21AC5.mp4' style={{width:'100%'}} controls/>
-                        </Tabs.TabPane>
-                    </Tabs>
-                    
-            </Modal>
-        }
-        {/* 错误信息帮助 */}
-        {
-            errShow && <Modal
-            visible={errShow}
-            onCancel={()=>{setErrShow(false)}}
-            width={'60%'}
-            title={<><h3>任务错误信息帮助</h3></>}
-            footer={null}
-        >
-            <div>
-
-            </div>
-            
-    </Modal>
-        }
+        <Table dataSource={getAdAccount?.data?.data?.records} loading={getAdAccount?.loading} columns={columnsMp()} size="small" bordered
+            pagination={{
+                position: ['bottomRight'],
+                total: getAdAccount?.data?.data?.total,//总共多少条数据,服务器给,设置后分页自动计算页数
+                showTotal: (total) => <Tag color="cyan">总共{total}数据</Tag>,
+                showSizeChanger: true,
+                showLessItems: true,
+                defaultCurrent: 1,
+                defaultPageSize: 20,//默认初始的每页条数
+                current: paging?.pageNum || 1,
+                pageSize: paging?.pageSize || 20,
+                onChange: (page, pageSize) => { setPaging({ ...paging, pageNum: page, pageSize: pageSize as number }) }
+            }}
+            rowKey={(row) => row.id}
+        />
     </Card>
 }
 

+ 0 - 338
src/pages/launchSystem/launchManage/adAuthorize/launchRefresh.tsx

@@ -1,338 +0,0 @@
-import { CheckOutlined } from "@ant-design/icons";
-import { Button, Checkbox, Input, Modal, Radio, Space, Spin, Table, Tag, Tooltip, message } from "antd";
-import { CheckboxValueType } from "antd/es/checkbox/Group";
-import React, { useCallback, useEffect, useReducer, useState } from "react";
-import { useModel } from "umi";
-import './index.less'
-import { columnsMp, columnsAdq } from './tableConfigAd'
-import AdLogin from '../components/adLogin'
-import CustomListModel from './customListModel'
-
-interface State {
-    unames: {
-        MP?: any,
-        ADQ?: any,
-        id: number
-    }[]
-}
-
-interface Action {
-    type: 'init' | 'unames',
-    params?: any
-}
-
-function reducer(state: State, action: Action) {
-    let { type, params } = action
-    switch (type) {
-        case 'unames':
-            const newState = { ...state, unames: [...params.unames] }
-            return newState
-        case 'init':
-            return {
-                unames: []
-            }
-        default:
-            return state
-    }
-}
-
-
-
-type Props = {
-    show?: boolean
-    onClose?: () => void,
-    onChange?: () => void
-}
-export default function LaunchRefresh(props: Props) {
-    const initState = {
-        unames: []
-    }
-    const { show = false, onClose, onChange } = props
-    const [state, dispatch] = useReducer(reducer, initState)
-    const [checkAll, setCheckAll] = useState<boolean>(false);   // 全选
-    const [checkedList, setCheckedList] = useState<CheckboxValueType[]>([]);
-    const [indeterminate, setIndeterminate] = useState(false);  // 没全选
-    const [ispList, setIspList] = useState<any[]>([]);  // 服务商列表
-    const [selectServer, setSelectServer] = useState<number>(0) // 点击选中的服务商
-    const [channel, setChannel] = useState<string>('MP') // 选择渠道
-    const [isUpdataAcc, setIsUpdataAcc] = useState<boolean>(false)  // 是否是更新账号密码
-    const [paging, setPaging] = useState<{ pageSize: number, pageNum: number, uname?: string }>({ pageSize: 20, pageNum: 1 }) // 用户表格参数
-    const [authData, setAuthData] = useState<{ base64: string, code: string }>({ base64: '', code: '' })
-    const [tabConfigShow, setTabConfigShow] = useState<boolean>(false)
-
-    const { updateChannelInfo, allOfLoginUser, adsChannelAccountAdq, adsChannelAccountMp, getUserInfo, mpSc, adqSc } = useModel('useLaunch.useAdAuthorize')
-
-    useEffect(() => {
-        if (show) {
-            allOfLoginUser.run().then((res: any) => {
-                setIspList(() => res?.data)
-                if (res?.data?.length > 0) {
-                    setSelectServer(() => res?.data[0]?.id)
-                }
-            })
-            getUser()
-        }
-    }, [show])
-
-    /** 获取用户更新状态 */
-    const getUser = useCallback(() => {
-        getUserInfo.run()
-    }, [])
-
-    useEffect(() => {
-        return () => {
-            dispatch({ type: 'unames', params: { unames: [] } })
-        }
-    }, [])
-
-    useEffect(() => {
-        if (selectServer > 0) {
-            if (channel === 'MP') {
-                adsChannelAccountMp.run({ ...paging, channelId: selectServer })
-            } else {
-                adsChannelAccountAdq.run({ ...paging, channelId: selectServer })
-            }
-        }
-    }, [channel, selectServer, paging])
-
-    const checkboxOnChange = useCallback((list: CheckboxValueType[]) => {
-        setCheckedList(list);
-        setIndeterminate(!!list.length && list.length < ispList.length);
-        setCheckAll(list.length === ispList.length);
-    }, [ispList])
-
-    const onCheckAllChange = (e: any) => {
-        if (e.target.checked) {
-            setCheckedList(ispList?.map((item: any) => item?.id))
-        } else {
-            setCheckedList([])
-        }
-        setIndeterminate(false);
-        setCheckAll(e.target.checked);
-    };
-
-    const onSearch = (value: string) => {
-        setPaging({ ...paging, uname: value, pageNum: 1 })
-    }
-
-    /** 设置账号密码 */
-    const setBacse64 = useCallback((base64: string, code: string) => {
-        setAuthData({ base64, code })
-    }, [authData])
-
-
-    /** 全部更新 */
-    // const refreshAllHandle = useCallback(() => {
-    //     updateChannelInfo.run({ updateName: 'all' }).then((res: any) => {
-    //         if (res?.code === 1003 && !res?.data?.base64) {
-    //             setWarrant(true)
-    //             setIsUpdataAcc(false)
-    //         } else if (res?.code === 1003 && res?.data?.base64) {
-    //             setBacse64(res?.data?.base64, res?.data?.code)
-    //         }
-    //     })
-    // }, [warrant, isUpdataAcc])
-
-    // console.log('unames[selectServer][channel]', unames);
-    /** 更新人群包 */
-    const refreshOrientPackage = useCallback(() => {
-        let channels: number[] = []
-        let channelMpAccount: any = {}
-        let channelAdqAccount: any = {}
-        state?.unames?.forEach((item: { id: number, MP: any[], ADQ: any[] }) => {
-            let { id, MP, ADQ } = item
-            if (MP?.length > 0 || ADQ?.length > 0) {
-                channels.push(id)
-                let mpIds = MP?.map((m: any) => m?.id)
-                let adqIds = ADQ?.map((a: any) => a?.id)
-                if (mpIds?.length > 0) {
-                    channelMpAccount[id] = mpIds
-                }
-                if (adqIds?.length > 0) {
-                    channelAdqAccount[id] = adqIds
-                }
-            }
-        })
-        // dispatch({ type: 'unames', params: { unames: [] } })
-        updateChannelInfo.run({ updateName: 'crowd_package', channels, channelMpAccount, channelAdqAccount }).then((res: any) => {
-            if (res?.code === 1003 && res?.data?.base64) {
-                setBacse64(res?.data?.base64, res?.data?.code)
-                setIsUpdataAcc(false)
-            } else if (res?.code === 200) {
-                message.success('正在刷新,可关闭当前窗口,刷新完成会钉钉通知')
-                dispatch({ type: 'unames', params: { unames: [] } })
-            }
-        })
-
-    }, [state?.unames, isUpdataAcc, authData])
-
-    /** 刷新服务商 */
-    const refreshServerISP = useCallback(() => {
-        updateChannelInfo.run({ updateName: 'channel' }).then((res: any) => {
-            if (res?.code === 1003 && res?.data?.base64) {
-                setIsUpdataAcc(false)
-                setBacse64(res?.data?.base64, res?.data?.code)
-            } else if (res?.code === 200) {
-                message.success('正在刷新,可关闭当前窗口,刷新完成会钉钉通知')
-            }
-            getUserInfo.refresh()
-        })
-    }, [isUpdataAcc, authData])
-    /** 同步公众号列表 */
-    const refreshAccount = useCallback(() => {
-        updateChannelInfo.run({ updateName: 'user', channels: checkedList }).then((res: any) => {
-            if (res?.code === 1003 && res?.data?.base64) {
-                setBacse64(res?.data?.base64, res?.data?.code)
-                setIsUpdataAcc(false)
-            } else if (res?.code === 200) {
-                message.success('正在刷新,可关闭当前窗口,刷新完成会钉钉通知')
-            }
-        })
-    }, [checkedList, isUpdataAcc, authData, authData])
-
-    /** 更新账号密码 */
-    const refreshAccPwd = useCallback(() => {
-        setIsUpdataAcc(true)
-        setBacse64("", "更新账号密码")
-    }, [isUpdataAcc])
-    /**收藏*/
-    const collect = useCallback((arg: { id: any, c: boolean, name: 'adq' | 'mp' }) => {
-        let { id, c, name } = arg
-        if (name === 'mp') {
-            mpSc.run({ accountId: id, collect: c }).then((res) => {
-                adsChannelAccountMp.refresh()
-            })
-        } else {
-            adqSc.run({ accountId: id, collect: c }).then((res) => {
-                adsChannelAccountAdq.refresh()
-            })
-        }
-    }, [adsChannelAccountMp, adsChannelAccountAdq])
-    return <div>
-        {/* 广告后台字段配置 */}
-        {tabConfigShow && <CustomListModel unames={state?.unames} visible={tabConfigShow} onClose={() => { setTabConfigShow(false) }} />}
-        {/* 授权登录 */}
-        <AdLogin isUpdataAcc={isUpdataAcc} value={authData} onClose={() => { setAuthData({ base64: '', code: '' }) }} onChange={() => { setAuthData({ base64: '', code: '' }); message.success('正在刷新,可关闭当前窗口,刷新完成会钉钉通知') }} />
-        <Modal
-            title='授权/刷新账户'
-            visible={show}
-            onCancel={() => { onClose && onClose() }}
-            footer={null}
-            maskClosable
-            width={1000}
-            destroyOnClose
-            className="launchRefresh"
-        >
-            <Space className="refBts">
-                {/* <Tooltip placement="topLeft" color="#fff" title={<div className="refreshNotice">
-                    <p><CheckOutlined /> 已刷新</p>
-                    <p>上次刷新 2021/07/20</p>
-                </div>}
-                >
-                    <Button type="primary" onClick={refreshAllHandle} loading={updateChannelInfo?.loading}>全部更新</Button>
-                </Tooltip> */}
-                <Tooltip placement="topLeft" color="#fff" title={<div className="refreshNotice">
-                    <p><CheckOutlined /> 已刷新</p>
-                    <p>上次刷新 {getUserInfo?.data?.data?.lastUpdateDataTime}</p>
-                </div>}
-                >
-                    <Button type="primary" onClick={refreshServerISP} loading={updateChannelInfo?.loading}>刷新服务商列表</Button>
-                </Tooltip>
-                <Button type="primary" disabled={checkedList.length === 0} onClick={refreshAccount} loading={updateChannelInfo?.loading}>同步公众号列表</Button>
-                <Button type="primary" disabled={!state?.unames?.some((item: any) => item?.MP?.length > 0 || item?.ADQ?.length > 0)} onClick={refreshOrientPackage} loading={updateChannelInfo?.loading}>更新人群包/商品</Button>
-                {/* <Button type="primary" onClick={refreshAccPwd}>更新账号密码</Button> */}
-                <Button type="primary" onClick={()=>{ setTabConfigShow(true) }} disabled={!state?.unames?.some((item: any) => item?.MP?.length > 0 || item?.ADQ?.length > 0)}>同步自定义列</Button>
-            </Space>
-            <div className="refContent">
-                <div className="left">
-                    <Spin spinning={allOfLoginUser?.loading}>
-                        <h4>服务商账户</h4>
-                        <Checkbox indeterminate={indeterminate} onChange={onCheckAllChange} checked={checkAll} style={{ margin: '10px 0 5px' }}>全选</Checkbox>
-                        <Checkbox.Group style={{ width: '100%' }} value={checkedList} onChange={checkboxOnChange}>
-                            {ispList?.length > 0 && ispList.map((item: any, index: number) => {
-                                return <div className={`isp ${item?.id === selectServer ? 'selectServer' : ''}`} key={item?.id} onClick={() => { setSelectServer(item?.id) }}>
-                                    <Checkbox value={item?.id}></Checkbox> <span>{item?.accountName}</span> {(state?.unames?.find((it: any) => it?.id === item?.id)?.MP?.length > 0 || state?.unames?.find((it: any) => it?.id === item?.id)?.ADQ?.length > 0) && <CheckOutlined />}
-                                </div>
-                            })}
-                        </Checkbox.Group>
-                    </Spin>
-
-
-                </div>
-                <div className="right">
-                    <Space direction="vertical" style={{ width: '100%' }}>
-                        <Space>
-                            <Radio.Group value={channel} onChange={(e) => { setChannel(e.target.value); setPaging({ pageSize: 20, pageNum: 1 }) }}>
-                                <Radio.Button value="MP">MP {state?.unames?.find((it: any) => it?.id === selectServer)?.MP?.length > 0 && <CheckOutlined />}</Radio.Button>
-                                {/* <Radio.Button value="ADQ">ADQ {state?.unames?.find((it: any) => it?.id === selectServer)?.ADQ?.length > 0 && <CheckOutlined />}</Radio.Button> */}
-                            </Radio.Group>
-                            <Input.Search placeholder="请输入广告主名称" onSearch={onSearch} style={{ width: 200 }} allowClear />
-                        </Space>
-                        {
-                            channel === "MP" ? <Table dataSource={adsChannelAccountMp?.data?.data?.records} scroll={{ x: 660, y: 300 }} loading={adsChannelAccountMp?.loading} columns={columnsMp(collect)} size="small" bordered pagination={{
-                                position: ['bottomLeft'],
-                                total: adsChannelAccountMp?.data?.data?.total,//总共多少条数据,服务器给,设置后分页自动计算页数
-                                showTotal: (total) => <Tag color="cyan">总共{total}数据</Tag>,
-                                showSizeChanger: true,
-                                showLessItems: true,
-                                defaultCurrent: 1,
-                                defaultPageSize: 20,//默认初始的每页条数
-                                current: paging?.pageNum || 1,
-                                pageSize: paging?.pageSize || 20,
-                                onChange: (page, pageSize) => { setPaging({ ...paging, pageNum: page, pageSize: pageSize as number }) }
-                            }}
-                                rowKey={(row) => row.id}
-                                rowSelection={{
-                                    selectedRowKeys: state?.unames?.find((item: any) => item?.id === selectServer)?.[channel]?.map((item: any) => item.id),
-                                    onChange: (selectedRowKeys, selectedRows) => {
-                                        let index = state?.unames?.findIndex((item: any) => item?.id === selectServer)
-                                        let data = state?.unames
-                                        let ch: any = {}
-                                        ch[channel] = selectedRows
-                                        ch.id = selectServer
-                                        if (index !== -1) {
-                                            data[index] = { ...ch }
-                                        } else {
-                                            data?.push({ ...ch })
-                                        }
-                                        dispatch({ type: 'unames', params: { unames: [...data] } })
-                                    }
-                                }} /> :
-                                <Table dataSource={adsChannelAccountAdq?.data?.data?.records} scroll={{ x: 660, y: 300 }} loading={adsChannelAccountAdq?.loading} columns={columnsAdq(collect)} size="small" bordered pagination={{
-                                    position: ['bottomLeft'],
-                                    total: adsChannelAccountAdq?.data?.data?.total,//总共多少条数据,服务器给,设置后分页自动计算页数
-                                    showTotal: (total) => <Tag color="cyan">总共{total}数据</Tag>,
-                                    showSizeChanger: true,
-                                    showLessItems: true,
-                                    defaultCurrent: 1,
-                                    defaultPageSize: 20,//默认初始的每页条数
-                                    current: paging?.pageNum || 1,
-                                    pageSize: paging?.pageSize || 20,
-                                    onChange: (page, pageSize) => { setPaging({ ...paging, pageNum: page, pageSize: pageSize as number }) }
-                                }}
-                                    rowKey={(row) => row.id}
-                                    rowSelection={{
-                                        selectedRowKeys: state?.unames?.find((item: any) => item?.id === selectServer)?.[channel]?.map((item: any) => item.id),
-                                        onChange: (selectedRowKeys, selectedRows) => {
-                                            let index = state?.unames?.findIndex((item: any) => item?.id === selectServer)
-                                            let select = state?.unames?.find((item: any) => item?.id === selectServer)
-                                            let data = state?.unames
-                                            let ch: any = {}
-                                            ch[channel] = selectedRows
-                                            ch.id = selectServer
-                                            if (index !== -1) {
-                                                data[index] = { ...select, ...ch }
-                                            } else {
-                                                data?.push({ ...ch })
-                                            }
-                                            dispatch({ type: 'unames', params: { unames: [...data] } })
-                                        }
-                                    }} />
-                        }
-
-                    </Space>
-                </div>
-            </div>
-        </Modal>
-    </div>
-}

+ 1 - 58
src/pages/launchSystem/launchManage/adAuthorize/tableConfig.tsx

@@ -1,22 +1,7 @@
-import { HeartFilled, HeartOutlined } from "@ant-design/icons"
 import React from "react"
 import ToMp from '../../components/toMp'
-export function columnsMp(collect: (arg: { id: any, c: boolean, name: 'adq' | 'mp' }) => void): any {
+export function columnsMp(): any {
     return [
-        {
-            title: '收藏',
-            dataIndex: 'cz',
-            align: 'center',
-            key: 'cz',
-            width: 50,
-            render: (a: any, b: any) => {
-                return b?.collected ? <a onClick={() => {
-                    collect({ id: b.id, c: false, name: 'mp' })
-                }}><HeartFilled style={{ color: 'red' }} /></a> : <a onClick={() => {
-                    collect({ id: b.id, c: true, name: 'mp' })
-                }}><HeartOutlined /></a>
-            },
-        },
         {
             title: '广告主名称',
             dataIndex: 'uname',
@@ -77,46 +62,4 @@ export function columnsMp(collect: (arg: { id: any, c: boolean, name: 'adq' | 'm
             width: 300
         },
     ]
-}
-export function columnsAdq(collect: (arg: { id: any, c: boolean, name: 'adq' | 'mp' }) => void): any {
-    return [
-        {
-            title: '收藏',
-            dataIndex: 'cz',
-            align: 'center',
-            key: 'cz',
-            width: 50,
-            render: (a: any, b: any) => {
-                return b?.collected ? <a onClick={() => {
-                    collect({ id: b.id, c: false, name: 'adq' })
-                }}><HeartFilled style={{ color: 'red' }} /></a> : <a onClick={() => {
-                    collect({ id: b.id, c: true, name: 'adq' })
-                }}><HeartOutlined /></a>
-            },
-        },
-        {
-            title: '账号ID',
-            dataIndex: 'uid',
-            key: 'uid',
-            align: 'center',
-            width: 90,
-        },
-        {
-            title: '服务商',
-            dataIndex: 'channel',
-            key: 'channel',
-            width: 200,
-            align: 'center',
-            render: (a: any, b: any) => {
-                return <span>{a?.accountName}</span>
-            }
-        },
-        {
-            title: '广告主名称',
-            dataIndex: 'uname',
-            key: 'uname',
-            align: 'center',
-            width: 200
-        },
-    ]
 }

+ 0 - 175
src/pages/launchSystem/launchManage/adAuthorize/tableConfigAd.tsx

@@ -1,175 +0,0 @@
-import { HeartFilled, HeartOutlined } from "@ant-design/icons"
-import React from "react"
-
-export function columnsMp(collect: (arg: { id: any, c: boolean, name: 'adq' | 'mp' }) => void): any {
-    return [
-        {
-            title: '收藏',
-            dataIndex: 'cz',
-            align: 'center',
-            key: 'cz',
-            width: 50,
-            render: (a: any, b: any) => {
-                return b?.collected ? <a onClick={() => {
-                    collect({ id: b.id, c: false, name: 'mp' })
-                }}><HeartFilled style={{ color: 'red' }} /></a> : <a onClick={() => {
-                    collect({ id: b.id, c: true, name: 'mp' })
-                }}><HeartOutlined /></a>
-            },
-        },
-        {
-            title: '广告主名称',
-            dataIndex: 'uname',
-            key: 'uname',
-            align: 'center',
-            ellipsis: true,
-            width: 140
-        },
-        {
-            title: 'AppId',
-            dataIndex: 'appid',
-            key: 'appid',
-            align: 'center',
-            width: 180,
-            ellipsis: true,
-        },
-        {
-            title: '原始ID',
-            dataIndex: 'wxname',
-            key: 'wxname',
-            align: 'center',
-            width: 150,
-            ellipsis: true,
-        },
-        {
-            title: '人群包数量',
-            dataIndex: 'packageCount',
-            key: 'packageCount',
-            align: 'center',
-            width: 90,
-        },
-        {
-            title: '商品库数量',
-            dataIndex: 'goodsCount',
-            key: 'goodsCount',
-            align: 'center',
-            width: 90,
-            render: (a: any, b: any) => {
-                if (a) {
-                    a = JSON.parse(a)
-                    return <span>{a?.length || 0}</span>
-                }
-                return <span>0</span>
-            },
-        },
-        {
-            title: '商品数量',
-            dataIndex: 'goodsCount',
-            key: 'goodsCount',
-            align: 'center',
-            width: 90,
-            render: (a: any, b: any) => {
-                if (a) {
-                    a = JSON.parse(a)
-                    return <span>{a?.reduce((pre: number, b: { goodsCount: number }) => { return b?.goodsCount ? pre + b?.goodsCount : pre }, 0) || 0}</span>
-                }
-                return <span>0</span>
-            },
-        },
-        {
-            title: '客服组数量',
-            dataIndex: 'wechatInfoCount',
-            key: 'wechatInfoCount',
-            align: 'center',
-            width: 90,
-            render: (a: any, b: any) => {
-                return <span>{a || 0}</span>
-            },
-        },
-        {
-            title: '数据源数量',
-            dataIndex: 'dataSourceCount',
-            key: 'dataSourceCount',
-            align: 'center',
-            width: 90,
-            render: (a: any, b: any) => {
-                return <span>{a || 0}</span>
-            },
-        },
-        {
-            title: '更新时间',
-            dataIndex: 'updateTime',
-            key: 'updateTime',
-            width: 170,
-            align: 'center',
-        },
-        {
-            title: '账号ID',
-            dataIndex: 'uid',
-            key: 'uid',
-            align: 'center',
-            width: 100,
-        },
-        {
-            title: '所属服务商SPID',
-            dataIndex: 'spid',
-            key: 'spid',
-            width: 150,
-            align: 'center',
-            ellipsis: true,
-        },
-        {
-            title: '主体名称',
-            dataIndex: 'companyName',
-            key: 'companyName',
-            ellipsis: true,
-            width: 300
-        },
-    ]
-}
-export function columnsAdq(collect: (arg: { id: any, c: boolean, name: 'adq' | 'mp' }) => void): any {
-    return [
-        {
-            title: '收藏',
-            dataIndex: 'cz',
-            align: 'center',
-            key: 'cz',
-            width: 50,
-            render: (a: any, b: any) => {
-                return b?.collected ? <a onClick={() => {
-                    collect({ id: b.id, c: false, name: 'adq' })
-                }}><HeartFilled style={{ color: 'red' }} /></a> : <a onClick={() => {
-                    collect({ id: b.id, c: true, name: 'adq' })
-                }}><HeartOutlined /></a>
-            },
-        },
-        {
-            title: '账号ID',
-            dataIndex: 'uid',
-            key: 'uid',
-            align: 'center',
-            width: 90,
-        },
-        {
-            title: '广告主名称',
-            dataIndex: 'uname',
-            key: 'uname',
-            align: 'center',
-            width: 200
-        },
-        {
-            title: '人群包数量',
-            dataIndex: 'packageCount',
-            key: 'packageCount',
-            align: 'center',
-            width: 90,
-        },
-        {
-            title: '更新时间',
-            dataIndex: 'updateTime',
-            key: 'updateTime',
-            width: 170,
-            align: 'center',
-        },
-    ]
-}

+ 0 - 15
src/pages/launchSystem/launchManageAdq/weChatAdq/index.less

@@ -1,15 +0,0 @@
-.planPadding {
-  .ant-card-body {
-    padding: 10px;
-  }
-}
-
-.meTabs>.ant-tabs-nav {
-  margin-bottom: 0;
-}
-
-.adMonitorListTab {
-  .ant-tabs-nav {
-    margin-bottom: 0;
-  }
-}

+ 0 - 20
src/pages/launchSystem/launchManageAdq/weChatAdq/index.tsx

@@ -1,20 +0,0 @@
-import { Tabs } from "antd"
-import React, { useState } from "react"
-
-
-const WeChatAdq: React.FC = () => {
-
-    const [radioIndex, setRadioIndex] = useState<string>('a')
-
-    return <div className="weChat">
-        <Tabs activeKey={radioIndex} className="adMonitorListTab" type="card" onChange={(activeKey: string) => {
-            setRadioIndex(activeKey)
-        }}>
-            <Tabs.TabPane tab="计划列表" key="a">计划列表</Tabs.TabPane>
-            <Tabs.TabPane tab="推广页" key="b">推广页</Tabs.TabPane>
-            <Tabs.TabPane tab="创建计划" key="c">创建计划</Tabs.TabPane>
-        </Tabs>
-    </div>
-}
-
-export default WeChatAdq

+ 3 - 7
src/pages/launchSystem/material/cloud/index.tsx

@@ -1,22 +1,20 @@
 import FlieBox from '@/components/FileBoxAD'
 import HocError from '@/Hoc/HocError'
 import { Tabs } from 'antd'
-import React, { useEffect, useRef } from 'react'
+import React, { useEffect } from 'react'
 import { useModel } from 'umi'
 import style from './index.less'
-import SyncModal from '@/components/FileBox/components/syncModal'
 
 
 const { TabPane } = Tabs;
 
 function Cloud() {
     const { state, set, getList, init, typeEnum } = useModel('useLaunchAdq.useBdMedia')
-    let refSync: { current: { show: (id: string, appIds: string[]) => void } } | any = useRef()//syncModal获取实例方法
     const { mediaType, belongUser, parentId } = state
     /**加载组件或数据更新执行请求列表 */
     useEffect(() => {
         if (belongUser === '1' || belongUser === '0') {
-            getList() 
+            getList()
         }
     }, [mediaType, belongUser, parentId])
 
@@ -36,13 +34,11 @@ function Cloud() {
                             <TabPane tab={'个人本地'} key={1} />
                             <TabPane tab={'公共本地'} key={0} />
                         </Tabs>
-                        <FlieBox showSync={refSync?.current?.show} />
+                        <FlieBox />
                     </TabPane>
                 })
             }
         </Tabs>
-        {/**同步弹窗 */}
-        <SyncModal ref={refSync} />
     </div>
 
 }

+ 12 - 0
src/pages/launchSystemNew/launchManage/adAuthorize/index.less

@@ -0,0 +1,12 @@
+.verticalCenter {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  margin-left: 5px;
+}
+
+.name-wrapper>p {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}

+ 34 - 0
src/pages/launchSystemNew/launchManage/adAuthorize/index.tsx

@@ -0,0 +1,34 @@
+
+import HocError from '@/Hoc/HocError'
+import { Card, Table, Tag } from 'antd'
+import React, { useEffect } from 'react'
+import { columnsMp } from './tableConfig'
+import { useModel } from 'umi'
+
+
+/** 投放管理 */
+const AdAuthorize: React.FC = () => {
+    const { getAdAccount } = useModel('useLaunchAdq.useAdAuthorize')
+
+    useEffect(() => {
+        // 获取账号列表
+        getAdAccount.run()
+    }, [])
+
+    return <Card>
+        <Table dataSource={getAdAccount?.data?.data} loading={getAdAccount?.loading} columns={columnsMp()} size="small" bordered
+            pagination={{
+                position: ['bottomRight'],
+                total: getAdAccount?.data?.data?.length,//总共多少条数据,服务器给,设置后分页自动计算页数
+                showTotal: (total) => <Tag color="cyan">总共{total}数据</Tag>,
+                showSizeChanger: true,
+                showLessItems: true,
+                defaultCurrent: 1,
+                defaultPageSize: 20,//默认初始的每页条数
+            }}
+            rowKey={(row) => row.id}
+        />
+    </Card>
+}
+
+export default HocError(AdAuthorize)

+ 101 - 0
src/pages/launchSystemNew/launchManage/adAuthorize/tableConfig.tsx

@@ -0,0 +1,101 @@
+import { Tooltip } from "antd"
+import React from "react"
+import './index.less'
+export function columnsMp(): any {
+    return [
+        {
+            title: 'ID',
+            dataIndex: 'id',
+            key: 'id',
+            align: 'center',
+            width: 55
+        },
+        {
+            title: '广告主ID',
+            dataIndex: 'accountId',
+            key: 'accountId',
+            align: 'center',
+            width: 100,
+        },
+        {
+            title: '类型',
+            dataIndex: 'sourceType',
+            key: 'sourceType',
+            align: 'center',
+            width: 70,
+            render: (a: any, b: any) => {
+                return <span>{a == 0 ? '微信' : 'QQ'}</span>
+            }
+        },
+        {
+            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: '服务商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: 130,
+            align: 'center',
+            render: (a: any) => {
+                return <Tooltip title={a}>
+                    <div className="name-wrapper">
+                        <p>{ a }</p>
+                    </div>
+                </Tooltip>
+            }
+        },
+        {
+            title: '授权状态',
+            dataIndex: 'authStatus',
+            key: 'authStatus',
+            width: 80,
+            align: 'center',
+        },
+        {
+            title: '日限额(分)',
+            dataIndex: 'dailyBudget',
+            key: 'dailyBudget',
+            align: 'center',
+            width: 100
+        },
+        {
+            title: '授权时间',
+            dataIndex: 'createTime',
+            key: 'createTime',
+            align: 'center',
+            width: 120
+        },
+    ]
+}

+ 17 - 0
src/pages/launchSystemNew/material/cloud/index.less

@@ -0,0 +1,17 @@
+.colud {
+    // display: flex;
+    // flex-flow: row nowrap;
+    // > div:nth-child(2) {
+    //   flex: 1;
+    // }
+    width: 100%;
+    margin-bottom: 0;
+    > div {
+      > div {
+        &:first-child {
+          margin-bottom: 0;
+        }
+      }
+    }
+  }
+  

+ 46 - 0
src/pages/launchSystemNew/material/cloud/index.tsx

@@ -0,0 +1,46 @@
+import FlieBox from '@/components/FileBoxAD'
+import HocError from '@/Hoc/HocError'
+import { Tabs } from 'antd'
+import React, { useEffect } from 'react'
+import { useModel } from 'umi'
+import style from './index.less'
+
+
+const { TabPane } = Tabs;
+
+function Cloud() {
+    const { state, set, getList, init, typeEnum } = useModel('useLaunchAdq.useBdMedia')
+    const { mediaType, belongUser, parentId } = state
+    /**加载组件或数据更新执行请求列表 */
+    useEffect(() => {
+        if (belongUser === '1' || belongUser === '0') {
+            getList()
+        }
+    }, [mediaType, belongUser, parentId])
+
+    return <div className={style.colud}>
+        <Tabs
+            type="card"
+            onChange={(activeKey: any) => {
+                init({ mediaType: activeKey })//切换类型时先初始化数据,并设置类型
+            }}
+            className={style.card}
+            activeKey={mediaType}
+        >
+            {
+                ['IMG', 'VIDEO'].map((key: any) => {
+                    return <TabPane tab={typeEnum[key]} key={key} style={{ backgroundColor: '#fff', padding: '0 15px' }} >
+                        <Tabs onChange={(activeKey: any) => { set({ belongUser: activeKey }) }} activeKey={belongUser}>
+                            <TabPane tab={'个人本地'} key={1} />
+                            <TabPane tab={'公共本地'} key={0} />
+                        </Tabs>
+                        <FlieBox />
+                    </TabPane>
+                })
+            }
+        </Tabs>
+    </div>
+
+}
+
+export default HocError(Cloud)

+ 12 - 0
src/services/launchAdq/adAuthorize.ts

@@ -0,0 +1,12 @@
+import { request } from 'umi';
+import { api } from '../api'
+
+/**
+ * 获取账号列表
+ * @returns 
+ */
+export async function getAdAccountApi() {
+    return request(api + '/adq/adAccount/allOfUser', {
+        method: 'GET',
+    });
+}

+ 67 - 262
src/services/launchAdq/material.ts

@@ -1,4 +1,3 @@
-import { queryStr } from '@/utils/query';
 import { request } from 'umi';
 import { api } from '../api'
 export interface AddTag {
@@ -55,11 +54,6 @@ export interface GetGraphicList {
   pageSize: number,
   tagIds?: number[]
 }
-// export interface GetWeChatData {
-//   appId: string,
-//   count: string | number,
-//   offset: string
-// }
 export interface GetWeChatData {
   mpId: number,
   mediaType: string,
@@ -72,210 +66,26 @@ export interface GetWeChatITData {
   offset: string,
   type: string
 }
-// export async function getGzhData() {
-//   return request('/api/data/gzhsc');
-// }
 /**获取上传接口 */
-export async function getFileUrl(params: { type: string }) {
-  return request(`${api}/adq/oss/ossUpload?type=${params.type}`);
-}
-/*************************标签**********************************/
-/**新增标签 */
-export async function addTag(params?: AddTag) {
-  return request(api + '/adq/mediaTag/create', {
-    method: 'POST',
-    data: params,
-  });
-}
-/**编辑标签 */
-export async function editTag(params?: AddTag) {
-  return request(api + '/adq/mediaTag/edit', {
-    method: 'POST',
-    data: params,
-  });
-}
-
-/**删除标签 */
-export async function delTag(params: { id: string }) {
-  return request(`${api}/adq/mediaTag/${params.id}`, {
-    method: 'DELETE',
-  });
-}
-/**获取标签列表*/
-export async function getTagList(params: { type: string }) {
-  return request(`${api}/adq/mediaTag/list?type=${params.type}`);
-}
-/*************************分类**********************************/
-/**新增标签 */
-export async function addClass(params?: { groupName: string }) {
-  return request(api + '/adq/sysMediaGroup/create', {
-    method: 'POST',
-    data: params,
-  });
-}
-/**编辑标签 */
-export async function editClass(params?: { groupName: string, id: string }) {
-  return request(api + '/adq/sysMediaGroup/edit', {
-    method: 'POST',
-    data: params,
+export async function getFileUrl(params: { type: string, fileType: 'video' | 'image' }) {
+  return request(`${api}/adq/oss/form/upload`, {
+    params
   });
 }
 
-/**删除标签 */
-export async function delClass(params: { id: string }) {
-  return request(`${api}/adq/sysMediaGroup/${params.id}`, {
-    method: 'DELETE',
-  });
-}
-/**获取标签列表*/
-export async function getClass(params: any) {
-  return request(`${api}/adq/sysMediaGroup?type=${params?.type}`);
-}
-/*************************素材**********************************/
-/** 新增非图文本地素材*/
-export async function addMediaList(params?: MediaList) {
-  return request(api + '/adq/sysMedia/create', {
-    method: 'POST',
-    data: params,
-  });
-}
-/** 编辑非图文本地素材*/
-export async function editMediaList(params?: MediaList) {
-  return request(api + '/adq/sysMedia/edit', {
-    method: 'POST',
-    data: params,
-  });
-}
-/** 新增图文本地素材*/
-export async function createGraphic(params: CreateGraphic) {
-  return request(api + '/adq/sysMedia/createGraphic', {
-    method: 'POST',
-    data: params,
-  });
-}
-/** 新增图文微信素材*/
-export async function createGraphicMaterial(params: CreateGraphic) {
-  return request(api + '/adq/sysMedia/addWxGraphicMaterial', {
-    method: 'POST',
-    data: params,
-  });
-}
-/** 编辑图文本地素材*/
-export async function editGraphic(params: EditGraphic) {
-  return request(api + '/adq/sysMedia/editGraphic', {
-    method: 'POST',
-    data: params,
-  });
-}
-/** 编辑图文微信素材*/
-export async function editGraphicWxMaterial(params: EditGraphic) {
-  return request(api + '/adq/sysMedia/updateWxMaterial', {
-    method: 'POST',
-    data: params,
-  });
-}
-/** 获取本地素材*/
-export async function getMediaList(params: GetMediaList) {
-  return request(`${api}/adq/sysMedia/list${queryStr(params)}`);
-}
 /** 删除本地素材*/
-export async function delMediaList(params: { id: string }) {
-  return request(`${api}/adq/sysMedia/${params.id}`, {
-    method: 'DELETE',
-  });
-}
-/**同步本地图文素材 */
-export async function syncPermanentGraphicMedias(params: { appId: string[], mediaId: string }) {
-  return request(api + '/adq/sysMedia/syncPermanentGraphicMaterial', {
-    method: 'POST',
-    data: params,
-  });
-}
-/**同步本地非图文素材 */
-export async function syncMedias(params: { appId: string[], mediaId: string }) {
-  return request(api + '/adq/sysMedia/syncPermanent', {
-    method: 'POST',
-    data: params,
-  });
-}
-/**获取微信图文素材 */
-export async function getWeChatITData(params: GetWeChatITData) {
-  return request(`${api}/adq/sysMedia/batchGetMaterialNews${queryStr(params)}`);
-}
-
-
-// /**获取微信非图文素材 */
-// export async function getWeChatData(params: GetWeChatData) {
-//   return request(`${api}/adq/sysMedia/batchGetMateria${queryStr(params)}`);
-// }
-/**获取微信非图文素材 */
-export async function getWeChatData(params: GetWeChatData) {
-  let { mpId, ...param } = params
-  return request(`${api}/adq/mp/media/list/${mpId}`, {
-    method: 'POST',
-    data: param,
-  });
-}
-/**更新公众号下素材*/
-export async function updateMediaCache(params: { mpId: number, mediaType: string }) {
-  let { mpId, mediaType } = params
-  return request(`${api}/adq/mp/media/syncMedia/${mpId}/${mediaType}`, {
-    method: 'PUT'
-  })
-}
-/** 删除微信素材*/
-export async function delMediawx(id: number) {
-  return request(`${api}/adq/mp/media/${id}`, {
-    method: 'DELETE',
-  });
-}
-/**微信素材详情*/
-export async function getWxMediaInfo(params: { id: number, isCon?: boolean }) {
-  let { id, isCon = true } = params
-  return request(`${api}/adq/mp/media/${id}/${isCon}`);
-}
-
-/**导入文章 */
-export async function exportMediaByUrl(params: { url: string }) {
-  return request(`${api}/adq/sysMedia/exportMediaByUrl${queryStr(params)}`);
-}
-export async function exportMediaByUrl1(url: string) {
-  return fetch(`${api}/adq/mp/media/parseWxNewsByUrl?url=${url}`, {
-    headers: { ['Authorization']: 'Bearer ' + sessionStorage.getItem('Admin-Token') },
-  });
-}
-
-
-
-
-/**本地素材详情*/
-export async function getGraphicDetail(params: { id: string }) {
-  return request(`${api}/adq/sysMedia/graphicDetail/${params.id}`);
-}
-/**查询图文同步结果 */
-export async function syncResult(params: any) {
-  return request(api + '/adq/sysMedia/syncResult', {
-    method: 'POST',
-    data: params,
-  });
-}
-/**批量上传非图文素材 */
-export async function bantchAdd(params: any) {
-  return request(`${api}/adq/sysMedia/bantchAdd`, {
-    method: 'PUT',
-    data: params
-  })
-}
-/**oss删除 */
-export async function delOss(params: any) {
-  return request(`${api}/adq/oss/${params}`, {
-    method: 'DELETE',
-    // data: params
-  });
+export async function delMediaList(params: { id: string, mediaType: 'IMG' | 'VIDEO' }) {
+  if (params.mediaType === 'IMG') {
+    return request(`${api}/adq/sysMediaImage/${params.id}`, {
+      method: 'DELETE',
+    });
+  } else {
+    return request(`${api}/adq/sysMediaVideo/${params.id}`, {
+      method: 'DELETE',
+    });
+  }
 }
 
-
-
 //=========================新接口===================
 // belongUser 0 公共 1 个人
 /**获取本地素材图片列表 */
@@ -296,11 +106,18 @@ export async function bdSysMediaListVideo(params: { parentId?: any, belongUser:
 }
 /**修改本地素材 */
 export async function bdSysMediaEdit(params: { belongUser: boolean, sysMediaId: number, mediaType: "IMG" | "VIDEO" }) {
-  const { belongUser, sysMediaId, ...param } = params
-  return request(api + `/adq/sysMedia/${belongUser}/${sysMediaId}`, {
-    method: 'PUT',
-    data: param
-  });
+  const { belongUser, sysMediaId, mediaType, ...param } = params
+  if (mediaType === 'IMG') {
+    return request(api + `/adq/sysMediaImage/${sysMediaId}`, {
+      method: 'PUT',
+      data: param
+    });
+  } else {
+    return request(api + `/adq/sysMediaVideo/${sysMediaId}`, {
+      method: 'PUT',
+      data: param
+    });
+  }
 }
 /**新增本地素材 */
 export async function bdSysMediaAdd(params: { belongUser: boolean, parentId: number, mediaType: "IMG" | "VIDEO" }) {
@@ -316,55 +133,31 @@ export async function bdSysMediaAdd(params: { belongUser: boolean, parentId: num
       data: param,
     });
   }
-  
-}
-/**新增微信素材*/
-export async function wxSysMediaAdd(params: { mediaType: "image" | "news" | "voice" | "video", localMediaId: number, mpId: number, news: any }) {
-  return request(api + `/adq/mp/media`, {
-    method: 'POST',
-    data: params,
-  });
+
 }
 /**删除本地素材 */
-export async function delMedia(sysMediaId: any) {
-  return request(`${api}/adq/sysMedia/${sysMediaId}`, {
-    method: 'DELETE',
-  });
+export async function delMedia(params: { sysMediaId: any, mediaType: 'IMG' | 'VIDEO' }) {
+  if (params.mediaType === 'IMG') {
+    return request(`${api}/adq/sysMediaImage/${params.sysMediaId}`, {
+      method: 'DELETE',
+    });
+  } else {
+    return request(`${api}/adq/sysMediaVideo/${params.sysMediaId}`, {
+      method: 'DELETE',
+    });
+  }
 }
 /**获取本地素材详情*/
-export async function getMedia(sysMediaId: any) {
-  return request(`${api}/adq/sysMedia/${sysMediaId}`, {
-    method: 'GET',
-  });
-}
-/**同步素材 */
-export async function syncMedia(params: { sysMediaId: number, mpIds: number }) {
-  const { mpIds, sysMediaId } = params
-  return request(api + `/adq/sysMedia/syncToMp/${sysMediaId}/${mpIds}`, {
-    method: 'PUT',
-  });
-}
-/**返回微信媒体ID的同步接口 */
-export async function syncForSend(params: { sysMediaId: number, mpIds: number }) {
-  const { mpIds, sysMediaId } = params
-  return request(api + `/adq/sysMedia/syncForSend/${sysMediaId}/${mpIds}`, {
-    method: 'PUT',
-  });
-}
-
-/**获取素材管理的公众号*/
-export async function getWxlist(sysMediaId: number) {
-  return request(api + `/adq/sysMedia/getBindMps/${sysMediaId}`, {
-    method: 'GET'
-  })
-}
-/**编辑素材关联的公众号 */
-export async function editWxlist(params: { sysMediaId: number, mpIds: any }) {
-  const { sysMediaId, mpIds } = params
-  return request(api + `/adq/sysMedia/bindMediaMps/${sysMediaId}`, {
-    method: 'POST',
-    data: mpIds
-  })
+export async function getMedia(params: { sysMediaId: any, mediaType: 'IMG' | 'VIDEO' }) {
+  if (params.mediaType === 'IMG') {
+    return request(`${api}/adq/sysMediaImage/${params.sysMediaId}`, {
+      method: 'GET',
+    });
+  } else {
+    return request(`${api}/adq/sysMediaVideo/${params.sysMediaId}`, {
+      method: 'GET',
+    });
+  }
 }
 /**获取图片素材文件夹目录树*/
 export async function getFolderTreeImg(props: { belongUser: any }) {
@@ -381,15 +174,27 @@ export async function getFolderTreeVideo(props: { belongUser: any }) {
   })
 }
 /*改变文件位置*/
-export async function editMediaFolder(params: { sysMediaId: number, folderId: number }) {
-  const { folderId, sysMediaId } = params
-  return request(api + `/adq/sysMedia/configMediaFolder/${folderId}/${sysMediaId}`, {
-    method: 'PUT',
-  });
+export async function editMediaFolder(params: { sysMediaId: number, folderId: number, mediaType: 'IMG' | 'VIDEO' }) {
+  const { folderId, sysMediaId, mediaType } = params
+  if (mediaType === 'IMG') {
+    return request(api + `/adq/sysMediaImage/modifyParentFolder/${folderId}/${sysMediaId}`, {
+      method: 'PUT',
+    });
+  } else {
+    return request(api + `/adq/sysMediaVideo/modifyParentFolder/${folderId}/${sysMediaId}`, {
+      method: 'PUT',
+    });
+  }
 }
 /** 排序 */
-export async function configSortApi({ sysMediaId, sort }: { sysMediaId: number, sort: number }) {
-  return request(api + `/adq/sysMedia/configMediaSort/${sysMediaId}/${sort}`, {
-    method: 'PUT'
-  });
+export async function configSortApi({ sysMediaId, sort, mediaType }: { sysMediaId: number, sort: number, mediaType: 'IMG' | 'VIDEO' }) {
+  if (mediaType === 'IMG') {
+    return request(api + `/adq/sysMediaImage/configMediaSort/${sysMediaId}/${sort}`, {
+      method: 'PUT'
+    });
+  } else {
+    return request(api + `/adq/sysMediaVideo/modifySort/${sysMediaId}/${sort}`, {
+      method: 'PUT'
+    });
+  }
 }

+ 21 - 4
src/utils/utils.ts

@@ -1,3 +1,4 @@
+import { RcFile } from 'antd/lib/upload';
 import { parse } from 'querystring';
 
 /* eslint no-useless-escape:0 import/prefer-default-export:0 */
@@ -71,10 +72,26 @@ export const getChannelName = (name: string) => {
 // 输入文案时判断
 export const txtLength = (value?: string) => {
   if (value) {
-      let length = value?.length
-      let text = value?.replace(/[\x00-\xff]/g, '')
-      return text?.length + Number(((length - text?.length) / 2).toFixed())
+    let length = value?.length
+    let text = value?.replace(/[\x00-\xff]/g, '')
+    return text?.length + Number(((length - text?.length) / 2).toFixed())
   } else {
-      return 0
+    return 0
   }
+}
+
+// 返回图片宽高
+export const getImgSize = (file: RcFile): Promise<{ width: number, height: number }> => {
+  return new Promise((resolve: (value: any) => void, reject: (reason?: any) => void) => {
+    if (file) {
+      let img: any = new Image();
+      let _URL = window.URL || window.webkitURL;
+      img.onload = function (e: any) {
+        resolve({ width: this.width, height: this.height })
+      }
+      img.src = _URL.createObjectURL(file);
+    } else {
+      reject()
+    }
+  })
 }