wjx 8 months ago
parent
commit
04bd294b98
37 changed files with 0 additions and 4516 deletions
  1. 0 115
      src/components/ActionModal/index.less
  2. 0 82
      src/components/ActionModal/index.tsx
  3. 0 205
      src/components/ActionModal/left.tsx
  4. 0 109
      src/components/ActionModal/more.less
  5. 0 301
      src/components/ActionModal/more.tsx
  6. 0 203
      src/components/ActionModal/selectLeft.tsx
  7. 0 30
      src/components/Alink/index.less
  8. 0 166
      src/components/Alink/index.tsx
  9. 0 26
      src/components/CityCascader/index.tsx
  10. 0 36
      src/components/ColorPicker/index.less
  11. 0 55
      src/components/ColorPicker/index.tsx
  12. 0 246
      src/components/Editor/AudioUploader.js
  13. 0 265
      src/components/Editor/Box/TEditor.tsx
  14. 0 32
      src/components/Editor/Box/UEditor.tsx
  15. 0 149
      src/components/Editor/Box/editorPlugin.tsx
  16. 0 25
      src/components/Editor/Box/index.less
  17. 0 516
      src/components/Editor/Box/index.tsx
  18. 0 22
      src/components/Editor/Button.js
  19. 0 25
      src/components/Editor/Input.js
  20. 0 24
      src/components/Editor/Label.js
  21. 0 101
      src/components/Editor/Link.js
  22. 0 57
      src/components/Editor/Modal.js
  23. 0 472
      src/components/Editor/ReactUeditor.js
  24. 0 22
      src/components/Editor/Select.js
  25. 0 45
      src/components/Editor/Tag.js
  26. 0 38
      src/components/Editor/Upload.js
  27. 0 247
      src/components/Editor/VideoUploader.js
  28. 0 1
      src/components/Editor/index.d.ts
  29. 0 3
      src/components/Editor/index.js
  30. 0 20
      src/components/Editor/utils.js
  31. 0 125
      src/components/NoticeIcon/NoticeIcon.tsx
  32. 0 103
      src/components/NoticeIcon/NoticeList.less
  33. 0 112
      src/components/NoticeIcon/NoticeList.tsx
  34. 0 35
      src/components/NoticeIcon/index.less
  35. 0 158
      src/components/NoticeIcon/index.tsx
  36. 0 13
      src/components/gzhMenu/index.less
  37. 0 332
      src/components/gzhMenu/index.tsx

+ 0 - 115
src/components/ActionModal/index.less

@@ -1,115 +0,0 @@
-.ico {
-    -webkit-animation: Tada 3s both infinite;
-    -moz-animation: Tada 3s both infinite;
-    -ms-animation: Tada 3s both infinite;
-    animation: Tada 3s both infinite;
-  }
-  .colud {
-    display: flex;
-    flex-flow: row nowrap;
-    > div:nth-child(2) {
-      flex: 1;
-    }
-    span.ant-checkbox {
-      display: none;
-    }
-  }
-  .box {
-    > span {
-      &:first-child {
-        display: none;
-      }
-    }
-  }
-  .card_action {
-    position: relative;
-    margin: 0 auto;
-    // text-align: center;
-    color: #4abe84;
-    background-color: #fff;
-    box-shadow: 0px 2px 7px 0px rgba(85, 110, 97, 0.35);
-    border-radius: 5px;
-    border: 1px solid rgba(74, 190, 132, 1);
-    overflow: hidden;
-    &::before {
-      content: '';
-      position: absolute;
-      right: 0;
-      bottom: 0;
-      border: 12px solid #4abe84;
-      border-top-color: transparent;
-      border-left-color: transparent;
-    }
-    &::after {
-      content: '';
-      width: 5px;
-      height: 10px;
-      position: absolute;
-      right: 5px;
-      bottom: 3px;
-      border: 2px solid #fff;
-      border-top-color: transparent;
-      border-left-color: transparent;
-      transform: rotate(45deg);
-    }
-  }
-  @keyframes Tada {
-    0% {
-      transform: scale(1);
-      transform: scale(1);
-    }
-  
-    70%,
-    73% {
-      transform: scale(0.9) rotate(-3deg);
-      transform: scale(0.9) rotate(-3deg);
-    }
-  
-    77%,
-    83%,
-    90%,
-    97% {
-      transform: scale(1.1) rotate(3deg);
-      transform: scale(1.1) rotate(3deg);
-    }
-  
-    80%,
-    87%,
-    93% {
-      transform: scale(1.1) rotate(-3deg);
-      transform: scale(1.1) rotate(-3deg);
-    }
-  
-    100% {
-      transform: scale(1) rotate(0);
-      transform: scale(1) rotate(0);
-    }
-  }
-  .card_box {
-    > div {
-      padding: 10px;
-    }
-  }
-  .disabled{
-    position: relative;
-    &::before{
-      position: absolute;
-      content: '';
-      width: 100%;
-      height: 100%;
-      display: block;
-      left: 0;
-      top:0;
-      bottom: 0;
-      right: 0;
-      background-color: rgba(199,199,199,.1);
-    }
-    div{
-      color: #a9a9a9;
-    }
-  }
-  .img{
-    width: 25px;
-    height: 25px;
-    margin-right: 5px;
-  }

+ 0 - 82
src/components/ActionModal/index.tsx

@@ -1,82 +0,0 @@
-import { Avatar, Card, Col, Radio, Row, Modal, Button, Space } from 'antd'
-import Meta from 'antd/lib/card/Meta'
-import React, { useCallback } from 'react'
-import { useModel } from 'umi'
-import Left from './left'
-import style from './index.less'
-import NoFoundPage from '@/pages/empty'
-/**本地保存并群发选择公众号弹窗*/
-type Props = {
-    visible: boolean,
-    hideWx: (cancel: boolean) => void
-}
-let ActionModal = (props: Props) => {
-    const { visible, hideWx } = props
-    const { state, actionWx } = useModel('useOperating.useWxGroupList')
-    //关闭弹窗
-    let handleCancel = useCallback((cancel: boolean) => {
-        if (state.actionWX) {
-            hideWx(cancel)
-        }
-    }, [state])
-    //选中事件
-    let action = useCallback((wx: any) => {
-        actionWx(wx)
-    }, [])
-    return <>
-        {
-            state?.actionWX ? <Modal
-                title="选择公众号"
-                width={740}
-                open={visible}
-                keyboard={false}
-                maskClosable={false}
-                closable={false}
-                footer={<>
-                    <Space>
-                        <Button type='primary' onClick={() => { handleCancel(true) }}>取消</Button>
-                        <Button type='primary' onClick={() => { handleCancel(false) }}>确定</Button>
-                    </Space>
-                </>}
-            >
-                <Row className={style.colud}>
-                    <Col>
-                        <Left />
-                    </Col>
-                    <Col>
-                        <Card style={{ height: '100%', overflowY: 'auto' }} title='分组' bodyStyle={{ maxHeight: 473, overflowY: 'auto' }}>
-                            <Radio.Group style={{ width: '100%' }} >
-                                <Row gutter={[10, 0]}>
-                                    {
-                                        state?.mpAccounts?.map((item: any) => {
-                                            return <Col key={item.id}>
-                                                <Radio value={item} className={style.box} disabled={item?.verifyTypeInfo === -1}>
-                                                    <Card
-                                                        onClick={() => { action(item) }}
-                                                        hoverable={item?.verifyTypeInfo !== -1}
-                                                        className={`${item.appid === state?.actionWX?.appid ? style.card_action : undefined} ${style.card_box} ${item?.verifyTypeInfo === -1 ? style.disabled : ''}`}
-                                                    >
-                                                        <Meta
-                                                            style={{ display: 'flex', alignItems: 'center' }}
-                                                            avatar={
-                                                                <Avatar src={item?.headImg || localStorage?.bookImg} />
-                                                            }
-                                                            title={item.nickName}
-
-                                                        />
-                                                    </Card>
-                                                </Radio>
-                                            </Col>
-                                        })
-                                    }
-                                </Row>
-                            </Radio.Group>
-                        </Card>
-                    </Col>
-                </Row>
-            </Modal > : <NoFoundPage />
-        }
-    </>
-}
-
-export default ActionModal

+ 0 - 205
src/components/ActionModal/left.tsx

@@ -1,205 +0,0 @@
-import React, { useState, useEffect, useCallback } from 'react'
-import { Menu, Select, Tabs } from 'antd'
-import { QrcodeOutlined } from '@ant-design/icons';
-import { useModel } from 'umi';
-import style from './index.less'
-const { Option } = Select
-interface Props {
-    default?: string,
-    height?: number | string,
-    type?: boolean,
-    isHideMyGroup?: boolean
-}
-function LeftPage(props: Props) {
-    const { isHideMyGroup = false } = props
-    const [selectedKeys, setSelectedKeys] = useState<string[]>([]) //选中自己的菜单
-    const [crewSelectedKeys, setCrewSelectedKeys] = useState<string[]>([]) //选中组员的菜单
-    const { getWxGroupAll, actionMp, actionWx, getAllOfMember, state, dispatch } = useModel('useOperating.useWxGroupList', model => ({ getWxGroupAll: model.getDataList, ...model }))
-    const { dispatch: userDispatch, initUserId } = useModel('useOperating.useUser')
-    const { tabsKey, actionArr, actionWX } = state
-    let bWith = document.body.clientWidth < 700
-    //自己menuitem点击
-    let menuItemClick = (e: any) => {
-        checkData(e.key, '', tabsKey)
-    };
-    //组员menuitem点击
-    let crewMenuItemClick = (e: any) => {
-        checkData(e.key, '', tabsKey)
-    };
-    //tabs选中
-    let tabsChange = useCallback((key: string) => {
-        dispatch({ type: 'setTabsKey', params: { tabsKey: key } })
-        if (key === '自己') {
-            initUserId()
-            checkData(selectedKeys[0], '', key)
-        } else {
-            checkData(crewSelectedKeys[0], '', key)
-        }
-    }, [selectedKeys, crewSelectedKeys])
-    //搜索
-    let inputChange = (v: any) => {
-        if (v) {
-            let [name, key] = v?.split('_')
-            checkData(key, name, tabsKey)
-        }
-    }
-    //设置选中的数据
-    let checkData = useCallback((key: string, ikey?: string, tabsKey?: string) => {
-        if (tabsKey === '自己') {
-            initUserId()
-            setSelectedKeys([key])
-            getWxGroupAll?.data?.forEach((item: any) => {
-                if (item.groupName === key) {//选中组
-                    actionMp(item?.mpAccounts)
-                    item?.mpAccounts?.forEach((wx: any) => {
-                        if (wx.nickName && wx.nickName === ikey) {//选中微信
-                            actionWx(wx)
-                        }
-                    })
-                }
-            })
-        } else {
-            setCrewSelectedKeys([key])
-            getAllOfMember?.data?.forEach((item: { key: { nickname: string, userId: number }, value: any[] }) => {
-                if (item?.key?.nickname + item?.key?.userId === key) {//选中组
-                    actionMp(item.value)
-                    handelUserId(item?.key?.userId, item?.key?.nickname)
-                    item?.value?.forEach((wx: any) => {
-                        if (wx?.nickName && wx?.nickName === ikey) {//选中微信
-                            actionWx(wx)
-                        }
-                    })
-                }
-            })
-        }
-    }, [getWxGroupAll, getAllOfMember])
-    useEffect(() => {
-        if (tabsKey === '自己') {
-            initUserId()
-            if (actionWX && getWxGroupAll?.data) {
-                getWxGroupAll?.data?.forEach((item: any, index: number) => {
-                    item?.mpAccounts?.forEach((mp: { appid: string }) => {
-                        if (mp.appid === actionWX.appid) {
-                            checkData(item['groupName'], '', tabsKey)
-                        }
-                    })
-                })
-            } else {
-                let action = true
-                getWxGroupAll?.data?.forEach((item: any, index: number) => {
-                    if (action && item['mpAccounts']?.length > 0) {
-                        action = false
-                        checkData(getWxGroupAll?.data[index]['groupName'], '', tabsKey)
-                    }
-                })
-            }
-        } else {
-            if (actionWX && getAllOfMember?.data) {
-                getAllOfMember?.data?.forEach((item: { key: { nickname: string, userId: number }, value: any[] }, index: number) => {
-                    item?.value?.forEach((mp: { appid: string }) => {
-                        if (mp?.appid === actionWX.appid) {
-                            checkData(item?.key?.nickname + item?.key?.userId, '', tabsKey)
-                        }
-                    })
-                })
-            } else {
-                let action = true
-                getAllOfMember?.data?.forEach((item: { key: { nickname: string, userId: number }, value: any[] }, index: number) => {
-                    if (action && item['userMpAccounts']?.length > 0) {
-                        action = false
-                        checkData(getAllOfMember?.data[index]?.key?.nickname + getAllOfMember?.data[index]['key']['userId'], '', tabsKey)
-                    }
-                })
-            }
-        }
-    }, [getWxGroupAll?.data, getAllOfMember?.data, tabsKey])
-    //选中角色
-    let handelUserId = useCallback((userId, name) => {
-        userDispatch({ type: 'setUserId', params: { userId: userId?.toString(), name } })
-    }, [])
-    return <div>
-        <Tabs type='card' activeKey={tabsKey} onChange={tabsChange} tabBarStyle={{ marginBottom: 0 }}>
-            <Tabs.TabPane tab='自己' key='自己'>
-                {!isHideMyGroup && <div style={{ width: `${bWith ? '100%' : 200}` }}>
-                    <Select style={{ minWidth: 150 }} placeholder="输入搜索公众号" onChange={inputChange} showArrow showSearch allowClear>
-                        {
-                            getWxGroupAll?.data?.map((item: any) => {
-                                return item?.mpAccounts?.map((list: any) => {
-                                    return <Option key={list.nickName + '_' + item.groupName} value={item.nickName} disabled={list?.verifyTypeInfo === -1}>
-                                        <img src={list?.headImg || localStorage?.bookImg} className={style.img} />  {list.nickName}
-                                    </Option>
-                                })
-                            })
-                        }
-                    </Select>
-                </div>
-                }
-                {!isHideMyGroup && <Menu
-                    onClick={menuItemClick}
-                    style={{ width: `${bWith ? '100%' : 200}`, height: props.height ? props.height : `${bWith ? '40' : 'calc(100vh - 390px)'} `, overflowY: 'auto', overflowX: 'hidden', borderRight: 0, backgroundColor: 'transparent' }}
-                    selectedKeys={selectedKeys}
-                    mode={"inline"}
-                >
-                    {
-                        props?.default && <Menu.Item key="all" icon={<QrcodeOutlined />}>全部公众号材料</Menu.Item>
-                    }
-                    {
-                        getWxGroupAll?.data?.map((item: any) => {
-                            return <Menu.Item
-                                key={item?.groupName}
-                            >
-                                <p style={{ margin: 0 }}>
-                                    {item?.mpAccounts?.some((mp: { appid: string }) => actionArr?.some((arr: { appid: string }) => mp.appid === arr.appid)) ? <i style={{ fontStyle: 'normal', color: 'red' }}>*</i> : ''}
-                                    {item?.groupName}
-                                    <span style={{ color: '#999' }}>({item?.mpAccounts?.length || 0})</span>
-                                </p>
-                            </Menu.Item >
-                        })
-                    }
-                </Menu>}
-            </Tabs.TabPane>
-            {
-                getAllOfMember?.data?.length > 0 && <Tabs.TabPane tab='组员' key='组员'>
-                    <div style={{ width: `${bWith ? '100%' : 200}` }}>
-                        <Select style={{ minWidth: 150 }} placeholder="输入搜索公众号" onChange={inputChange} showArrow showSearch allowClear>
-                            {
-                                getAllOfMember?.data?.map((item: { key: { nickname: string, userId: number }, value: any[] }) => {
-                                    return item?.value?.map((list: any) => {
-                                        return <Option key={item?.key?.nickname + '_' + list?.id} value={list?.nickName + '_' + item?.key?.nickname + item?.key?.userId} disabled={list?.verifyTypeInfo === -1}>
-                                            <img src={list?.headImg || localStorage?.bookImg} className={style.img} /> {list?.nickName}
-                                        </Option>
-                                    })
-                                })
-                            }
-                        </Select>
-                    </div>
-                    <Menu
-                        onClick={crewMenuItemClick}
-                        style={{ width: `${bWith ? '100%' : 200}`, height: props.height ? props.height : `${bWith ? '40' : 'calc(100vh - 390px)'} `, overflowY: 'auto', overflowX: 'hidden', borderRight: 0, backgroundColor: 'transparent' }}
-                        selectedKeys={crewSelectedKeys}
-                        mode={"inline"}
-                    >
-                        {
-                            props?.default && <Menu.Item key="all" icon={<QrcodeOutlined />}>全部公众号材料</Menu.Item>
-                        }
-                        {
-                            getAllOfMember?.data?.map((item: { key: { nickname: string, userId: number }, value: any[] }) => {
-                                return <Menu.Item
-                                    key={item?.key?.nickname + item?.key?.userId}
-                                >
-                                    <p onClick={() => { handelUserId(item?.key?.userId?.toString(), item?.key?.nickname) }} style={{ margin: 0 }}>
-                                        {item?.value?.some((mp: { appid: string }) => actionArr?.some((arr: { appid: string }) => mp.appid === arr.appid)) ? <i style={{ fontStyle: 'normal', color: 'red' }}>*</i> : ''}
-                                        {item?.key?.nickname}
-                                        <span style={{ color: '#999' }}>({item?.value?.length})</span>
-                                    </p>
-                                </Menu.Item >
-                            })
-                        }
-                    </Menu>
-                </Tabs.TabPane>
-            }
-        </Tabs>
-    </div >
-}
-
-export default LeftPage

+ 0 - 109
src/components/ActionModal/more.less

@@ -1,109 +0,0 @@
-.ico {
-  -webkit-animation: Tada 3s both infinite;
-  -moz-animation: Tada 3s both infinite;
-  -ms-animation: Tada 3s both infinite;
-  animation: Tada 3s both infinite;
-}
-.colud {
-  display: flex;
-  flex-flow: row nowrap;
-  > div:nth-child(2) {
-    flex: 0;
-  }
-  > div:nth-child(3) {
-    flex: 1;
-  }
-  span.ant-checkbox {
-    display: none;
-  }
-}
-.box {
-  > span {
-    &:first-child {
-      display: none;
-    }
-    &:last-child {
-      display: inline-block;
-    }
-  }
-}
-.card_title {
-  font-size: 12px;
-  color: #999;
-  display: block;
-}
-.card_action {
-  position: relative;
-  margin: 0 auto;
-  // text-align: center;
-  color: #4abe84;
-  background-color: #fff;
-  box-shadow: 0px 2px 7px 0px rgba(85, 110, 97, 0.35);
-  border-radius: 7px;
-  border: 1px solid rgba(74, 190, 132, 1);
-  overflow: hidden;
-  &::before {
-    content: '';
-    position: absolute;
-    right: 0;
-    bottom: 0;
-    border: 12px solid #4abe84;
-    border-top-color: transparent;
-    border-left-color: transparent;
-  }
-  &::after {
-    content: '';
-    width: 5px;
-    height: 10px;
-    position: absolute;
-    right: 5px;
-    bottom: 3px;
-    border: 2px solid #fff;
-    border-top-color: transparent;
-    border-left-color: transparent;
-    transform: rotate(45deg);
-  }
-}
-@keyframes Tada {
-  0% {
-    transform: scale(1);
-    transform: scale(1);
-  }
-
-  70%,
-  73% {
-    transform: scale(0.9) rotate(-3deg);
-    transform: scale(0.9) rotate(-3deg);
-  }
-
-  77%,
-  83%,
-  90%,
-  97% {
-    transform: scale(1.1) rotate(3deg);
-    transform: scale(1.1) rotate(3deg);
-  }
-
-  80%,
-  87%,
-  93% {
-    transform: scale(1.1) rotate(-3deg);
-    transform: scale(1.1) rotate(-3deg);
-  }
-
-  100% {
-    transform: scale(1) rotate(0);
-    transform: scale(1) rotate(0);
-  }
-}
-.card_box {
-  > div {
-    padding: 10px;
-  }
-}
-.item_img {
-  width: 25px;
-  border-radius: 2px;
-  margin-right: 5px;
-  background-color: #efefef;
-}

+ 0 - 301
src/components/ActionModal/more.tsx

@@ -1,301 +0,0 @@
-import { Button, Card, Checkbox, Col, Row } from 'antd'
-import Modal from 'antd/lib/modal/Modal'
-import React, { useCallback, useEffect, useState } from 'react'
-import { useModel } from 'umi'
-import Left from '@/components/ActionModal/left'
-import SelectLeft from '@/components/ActionModal/selectLeft'
-import style from './more.less'
-import NoFoundPage from '@/pages/empty'
-type Props = {
-    visible: boolean,
-    hideWx: () => void,
-    ok: (arr: any[]) => void,
-    defaultDtat: any[],
-    isSelect?: boolean
-}
-//更多选择弹窗
-let MoreModal = (props: Props) => {
-    const { visible, hideWx, ok, defaultDtat, isSelect = false } = props
-    const { mpAccounts, actionWX, dispatch, actionArr, getDataList, getAllOfMember } = useModel('useOperating.useWxGroupList',
-        models => ({
-            mpAccounts: models.state.mpAccounts,
-            actionWX: models.state.actionWX,
-            dispatch: models.dispatch,
-            actionArr: models.state.actionArr,
-            getDataList: models.getDataList,
-            getAllOfMember: models.getAllOfMember
-        }))
-    const [groupSyncWx, setGroupSyncWx] = useState<any[]>([])//当前组未选中的微信
-    const [selectState, setSelectState] = useState<{ isAll: boolean, isChecked: boolean }>({ isAll: false, isChecked: false })
-    const { syncWx, sync, graphicMaterialEdit } = useModel('useOperating.useMaterialContent', model => ({
-        syncWx: model.syncWx,
-        sync: model.sync,
-        graphicMaterialEdit: model.graphicMaterialEdit,
-    }))
-    //全选
-    let allSelect = useCallback(() => {
-        let isGroupWx: any[] = []//选中的数据
-        let newActionArr: any[] = []
-        let fiterMp: any[] = []
-        mpAccounts?.forEach((mp: { id: number, verifyTypeInfo: number }) => {
-            if (mp?.verifyTypeInfo !== -1) {//过滤未认证
-                fiterMp.push(mp)
-            }
-            actionArr?.forEach((wx: { id: number }) => {
-                if (wx.id === mp.id) {
-                    isGroupWx.push(wx)
-                }
-            })
-        })
-        if (isGroupWx?.length === fiterMp?.length || isGroupWx?.length === fiterMp?.length - groupSyncWx?.length) {//清空
-            newActionArr = actionArr?.filter((wx: { id: number }) => {
-                if (isGroupWx.every((groupwx: { id: number }) => wx.id !== groupwx.id)) {
-                    return wx
-                }
-                return
-            })
-            setSelectState({ isAll: false, isChecked: false })
-            dispatch({ type: 'setActionArr', params: { actionArr: newActionArr } })
-        } else {//全选
-            newActionArr = actionArr?.filter((wx: { id: number }) => {
-                if (isGroupWx.every((groupwx: { id: number }) => wx.id !== groupwx.id)) {
-                    return wx
-                }
-                return
-            })
-            newActionArr = [...newActionArr, ...fiterMp]
-            setSelectState({ isAll: false, isChecked: true })
-            dispatch({ type: 'setActionArr', params: { actionArr: newActionArr } })
-        }
-    }, [selectState, mpAccounts, actionArr, actionWX, groupSyncWx])
-    //反选
-    let returnSelct = useCallback(() => {
-        let isGroupWx: any[] = []
-        let returnWx: any[] = []
-        let newActionArr: any[] = []
-        let fiterMp: any[] = []
-        mpAccounts?.forEach((mp: { id: number, verifyTypeInfo: number }) => {
-            if (mp?.verifyTypeInfo !== -1) {//过滤未认证
-                fiterMp.push(mp)
-            }
-            actionArr?.forEach((wx: { id: number }) => {
-                if (wx.id === mp.id) {
-                    isGroupWx.push(wx)
-                }
-            })
-        })
-        returnWx = fiterMp?.filter((mp: { id: number }) => {
-            if (isGroupWx.every((wx: { id: number }) => mp.id !== wx.id)) {
-                return mp
-            }
-            return
-        })
-        newActionArr = actionArr?.filter((wx: { id: number }) => {
-            if (isGroupWx.every((groupwx: { id: number }) => wx.id !== groupwx.id)) {
-                return wx
-            }
-            return
-        })
-        if (returnWx.length !== 0 && groupSyncWx.length !== returnWx.length) {//假如选中个数的大于0
-            setSelectState({ isAll: true, isChecked: true })
-        } else {//假如等于0
-            setSelectState({ isAll: false, isChecked: false })
-        }
-        if (returnWx.length === fiterMp.length && groupSyncWx.length === 0) {
-            setSelectState({ isAll: false, isChecked: true })//假如反选值与当前组的个数一样证明全选
-        }
-        newActionArr = [...newActionArr, ...returnWx]
-        dispatch({ type: 'setActionArr', params: { actionArr: newActionArr } })
-    }, [selectState, mpAccounts, actionArr, actionWX, groupSyncWx])
-    //每次切换组检测全选状态
-    useEffect(() => {
-        let isGroupWx: any[] = []
-        let groupSyncWx: any[] = []
-        mpAccounts?.forEach((mp: { id: number }) => {
-            actionArr?.forEach((wx: { id: number }) => {
-                if (wx.id === mp.id) {
-                    isGroupWx.push(wx)
-                }
-            })
-        })
-        setGroupSyncWx(groupSyncWx)
-        // }
-        if (isGroupWx?.length === mpAccounts?.length) {
-            setSelectState({ isAll: false, isChecked: true })
-        } else {
-            setSelectState({ isAll: true, isChecked: true })
-        }
-        if (isGroupWx?.length === 0) {
-            setSelectState({ isAll: false, isChecked: false })
-        }
-    }, [mpAccounts, actionArr])
-    //关闭弹窗
-    let handleCancel = useCallback(() => {
-        dispatch({ type: 'setActionArr', params: { actionArr: [] } })
-        hideWx()
-    }, [])
-    //确定
-    let handleOk = useCallback(() => {
-        ok(actionArr)
-        dispatch({ type: 'setActionArr', params: { actionArr: [] } })
-    }, [actionArr])
-    //选中事件
-    let action = useCallback((item: any) => {
-        let isGroupWx: any[] = []//选中的数据
-        if (actionArr?.some((obj: { appid: number }) => obj.appid === item.appid)) {//删除
-            let newArr = actionArr?.filter((obj: { appid: number }) => obj.appid !== item.appid)
-            mpAccounts?.forEach((mp: { id: number }) => {
-                newArr?.forEach((wx: { id: number }) => {
-                    if (wx.id === mp.id) {
-                        isGroupWx.push(wx)
-                    }
-                })
-            })
-            if (isGroupWx.length === 0) {//假如为空
-                setSelectState({ isAll: false, isChecked: false })
-            } else {
-                setSelectState({ isAll: true, isChecked: true })
-            }
-            dispatch({ type: 'setActionArr', params: { actionArr: newArr } })
-        } else {//添加
-            let arr = [...actionArr, item]
-            if (mpAccounts?.every((mp: { id: number }) => arr?.some((wx: { id: number }) => mp.id === wx.id))) {//假如全部存在全选
-                setSelectState({ isAll: false, isChecked: true })
-            } else {
-                setSelectState({ isAll: true, isChecked: true })
-            }
-            dispatch({ type: 'setActionArr', params: { actionArr: arr } })
-        }
-    }, [actionArr, mpAccounts])
-    useEffect(() => {
-        let newArr: any[] = []
-        if (getDataList?.data) {
-            getDataList?.data?.forEach((data: { mpAccounts: any }) => {
-                if(data?.mpAccounts){
-                    newArr = [...data?.mpAccounts]
-                }
-            })
-        }
-
-        if (getAllOfMember?.data) {
-            getAllOfMember?.data?.forEach((data: { value: any }) => {
-                data?.value?.forEach((mp: { id: number }) => {
-                    if (newArr.every((arr: { id: number }) => mp?.id !== arr.id)) {
-                        newArr.push(mp)
-                    }
-                })
-            })
-        }
-    }, [getDataList?.data, getAllOfMember?.data, isSelect])
-    //编辑回填
-    useEffect(() => {
-        if (defaultDtat.length > 0) {
-            dispatch({ type: 'setActionArr', params: { actionArr: defaultDtat } })
-        }
-    }, [defaultDtat])
-    return <>
-        <Modal
-            title="批量选择公众号"
-            width={1040}
-            open={visible}
-            onOk={handleOk}
-            onCancel={handleCancel}
-            okText='确定'
-            cancelText='取消'
-            destroyOnClose
-            confirmLoading={syncWx.loading || sync.loading || graphicMaterialEdit.loading}
-        >
-            {
-                actionWX ? <Row className={style.colud}  >
-                    <Col >
-                      {isSelect ? <SelectLeft /> : <Left />}
-                        {/* <Left /> */}
-                    </Col>
-                    <Col>
-                        <Card
-                            style={{ height: '420px', overflow: 'hidden', minWidth: 290 }}
-                            title={
-                                <>
-                                    <span style={{ marginRight: 10 }}>组下成员</span>
-                                    <Checkbox
-                                        indeterminate={selectState.isAll}
-                                        onChange={allSelect}
-                                        checked={selectState.isChecked}
-                                    >
-                                        <span style={{ fontSize: 12, color: '#999' }}>全选</span>
-                                    </Checkbox>
-                                    <Button size='small' onClick={returnSelct}>反选</Button>
-                                </>
-                            }
-                            bodyStyle={{ height: 350, overflowY: 'auto' }}
-                        >
-                            <Checkbox.Group style={{ width: '100%', }} >
-                                <Row gutter={[10, 0]}>
-                                    {
-
-                                        mpAccounts?.map((item: any) => {
-                                            let isAction: any = actionArr?.some((obj: any) => obj?.appid === item?.appid)
-                                            return <Col key={item.id} span={24}>
-                                                <Checkbox value={item} className={style.box} onClick={() => action(item)} disabled={item?.verifyTypeInfo === -1}>
-                                                    <div
-                                                        className={`${isAction ? style.card_action : undefined} ${style.card_box}`}
-                                                    >
-                                                        <div
-                                                            style={{ display: 'flex', alignItems: 'center' }}
-                                                        >
-                                                            <img src={item?.headImg || localStorage?.bookImg} className={style.item_img} />
-                                                            {item.nickName}
-                                                        </div>
-                                                    </div>
-                                                </Checkbox>
-                                            </Col>
-                                        })
-                                    }
-                                </Row>
-                            </Checkbox.Group>
-                        </Card>
-                    </Col>
-                    <Col>
-                        <Card
-                            style={{ height: 420, overflow: 'hidden', minWidth: 280 }}
-                            title={
-                                <>
-                                    <span style={{ marginRight: 10 }}>已勾选</span>
-                                    <Button size='small' onClick={() => { dispatch({ type: 'setActionArr', params: { actionArr: [] } }) }}>清空</Button>
-                                </>
-                            }
-                            bodyStyle={{ height: 350, overflowY: 'auto' }}
-                        >
-                            <Checkbox.Group style={{ width: '100%' }} >
-                                <Row gutter={[10, 0]}>
-                                    {
-
-                                        actionArr?.map((item: any) => {
-                                            let isAction: any = actionArr?.some((obj: any) => obj?.appid === item?.appid)
-                                            return <Col key={item.id}>
-                                                <Checkbox value={item} className={style.box} onClick={() => action(item)}>
-                                                    <div
-                                                        className={`${isAction ? style.card_action : undefined} ${style.card_box}`}
-                                                    >
-                                                        <div
-                                                            style={{ display: 'flex', alignItems: 'center' }}
-                                                        >
-                                                            <img src={item?.headImg || localStorage?.bookImg} className={style.item_img} />
-                                                            {item.nickName}
-                                                        </div>
-                                                    </div>
-                                                </Checkbox>
-                                            </Col>
-                                        })
-                                    }
-                                </Row>
-                            </Checkbox.Group>
-                        </Card>
-                    </Col>
-                </Row> : <NoFoundPage />
-            }
-        </Modal >
-    </>
-}
-
-export default MoreModal

+ 0 - 203
src/components/ActionModal/selectLeft.tsx

@@ -1,203 +0,0 @@
-import React, { useState, useEffect, useCallback } from 'react'
-import { Menu, Select, Tabs } from 'antd'
-import { QrcodeOutlined } from '@ant-design/icons';
-import { useModel } from 'umi';
-import style from './index.less'
-const { Option } = Select
-interface Props {
-    default?: string,
-    height?: number | string,
-    type?: boolean
-}
-function LeftPage(props: Props) {
-    const [selectedKeys, setSelectedKeys] = useState<string[]>([]) //选中自己的菜单
-    const [crewSelectedKeys, setCrewSelectedKeys] = useState<string[]>([]) //选中组员的菜单
-    const { getWxGroupAll, actionMp, actionWx, getAllOfMember, state, dispatch } = useModel('useOperating.useWxGroupList', model => ({ getWxGroupAll: model.getDataList, ...model }))
-    const { userId, dispatch: userDispatch, } = useModel('useOperating.useUser', model => ({ userId: model.state.selectdUserId, dispatch: model.dispatch }))
-    const { tabsKey, actionArr } = state
-    let bWith = document.body.clientWidth < 700
-    //自己menuitem点击
-    let menuItemClick = (e: any) => {
-        checkData(e.key, '', tabsKey)
-    };
-    //组员menuitem点击
-    let crewMenuItemClick = (e: any) => {
-        checkData(e.key, '', tabsKey)
-    };
-    //tabs选中
-    let tabsChange = useCallback((key: string) => {
-        dispatch({ type: 'setTabsKey', params: { tabsKey: key } })
-        if (key === '自己') {
-            checkData(selectedKeys[0], '', key)
-        } else {
-            checkData(crewSelectedKeys[0], '', key)
-        }
-    }, [selectedKeys, crewSelectedKeys])
-    //搜索
-    let inputChange = (v: any) => {
-        if (v) {
-            let [name, key] = v.split('_')
-            checkData(key, name, tabsKey)
-        }
-    }
-    //设置选中的数据
-    let checkData = useCallback((key: string, ikey?: string, tabsKey?: string) => {
-        if (tabsKey === '自己') {
-            setSelectedKeys([key])
-            getWxGroupAll?.data?.forEach((item: any) => {
-                if (item.groupName === key) {//选中组
-                    actionMp(item?.mpAccounts)
-                    item?.mpAccounts?.forEach((wx: any) => {
-                        if (wx.nickName === ikey) {//选中微信
-                            actionWx(wx)
-                        }
-                    })
-                }
-            })
-        } else {
-            setCrewSelectedKeys([key])
-            getAllOfMember?.data?.forEach((item: {key: {nickname: string, userId: number}, value: any[]}) => {
-                if (item?.key?.nickname + item?.key?.userId === key) {//选中组
-                    actionMp(item.value)
-                    handelUserId(item?.key?.userId, item?.key?.nickname)
-                    item?.value?.forEach((wx: any) => {
-                        if (wx.nickName === ikey) {//选中微信
-                            actionWx(wx)
-                        }
-                    })
-                }
-            })
-        }
-    }, [getWxGroupAll, getAllOfMember])
-    useEffect(() => {
-        actionMp([])
-        if (tabsKey === '自己') {
-            if (getWxGroupAll?.data) {
-                let action = true
-                console.log(getWxGroupAll?.data)
-                getWxGroupAll?.data?.forEach((item: any, index: number) => {
-                    if (action && item['mpAccounts']?.length > 0) {
-                        action = false
-                        checkData(getWxGroupAll?.data[index]['groupName'], '', tabsKey)
-                    }
-                })
-            }
-        } else {
-            if (getAllOfMember?.data) {
-                let action = true
-                getAllOfMember?.data?.forEach((item: any, index: number) => {
-                    if (action && item['value']?.length > 0 && item.userId == userId) {
-                        action = false
-                        checkData(getAllOfMember?.data[index]['nickName'] + getAllOfMember?.data[index]['userId'], '', tabsKey)
-                    }
-                })
-            }
-        }
-    }, [getWxGroupAll?.data, getAllOfMember?.data, tabsKey])
-    //选中角色
-    let handelUserId = useCallback((userId, name) => {
-        userDispatch({ type: 'setUserId', params: { userId: userId?.toString(), name } })
-    }, [])
-    return <div>
-        <Tabs type='card' activeKey={tabsKey} onChange={tabsChange} tabBarStyle={{ marginBottom: 0 }}>
-            {tabsKey === '自己' && <Tabs.TabPane tab='自己' key='自己'>
-                <div style={{ width: `${bWith ? '100%' : 200}` }}>
-                    <Select style={{ minWidth: 150 }} placeholder="输入搜索公众号" onChange={inputChange} showArrow showSearch allowClear>
-                        {
-                            getWxGroupAll?.data?.map((item: any) => {
-                                return item?.mpAccounts?.map((list: any) => {
-                                    return <Option key={list.nickName + '_' + item.groupName} value={item.nickName} disabled={list?.verifyTypeInfo === -1}>
-                                        <img src={list?.headImg || localStorage?.bookImg} className={style.img} />  {list.nickName}
-                                    </Option>
-                                })
-                            })
-                        }
-                    </Select>
-                </div>
-                <Menu
-                    onClick={menuItemClick}
-                    style={{ width: `${bWith ? '100%' : 200}`, height: props.height ? props.height : `${bWith ? '40' : 'calc(100vh - 390px)'} `, overflowY: 'auto', overflowX: 'hidden', borderRight: 0, backgroundColor: 'transparent' }}
-                    selectedKeys={selectedKeys}
-                    mode={"inline"}
-                >
-                    {
-                        props?.default && <Menu.Item key="all" icon={<QrcodeOutlined />}>全部公众号材料</Menu.Item>
-                    }
-                    {
-                        getWxGroupAll?.data?.map((item: any) => {
-                            return <Menu.Item
-                                key={item?.groupName}
-                            >
-                                <p>
-                                    {item?.mpAccounts?.some((mp: { appid: string }) => actionArr?.some((arr: { appid: string }) => mp.appid === arr.appid)) ? <i style={{ fontStyle: 'normal', color: 'red' }}>*</i> : ''}
-                                    {item?.groupName}
-                                    <span style={{ color: '#999' }}>({item?.mpAccounts?.length || 0})</span>
-                                </p>
-                            </Menu.Item >
-                        })
-                    }
-                </Menu>
-            </Tabs.TabPane>}
-            {
-                getAllOfMember?.data?.length > 0 && tabsKey === '组员' && <Tabs.TabPane tab='组员' key='组员'>
-                    <div style={{ width: `${bWith ? '100%' : 200}` }}>
-                        <Select style={{ minWidth: 150 }} placeholder="输入搜索公众号" onChange={inputChange} showArrow showSearch allowClear>
-                            {
-                                getAllOfMember?.data?.map((item: any) => {
-                                    if (item.userId == userId) {
-                                        return item?.userMpAccounts?.map((list: any) => {
-                                            return <Option key={item?.nickName + '_' + list?.id} value={list?.nickName + '_' + item?.nickName + item?.userId} disabled={list?.verifyTypeInfo === -1}>
-                                                <img src={list?.headImg || localStorage?.bookImg} className={style.img} /> {list?.nickName}
-                                            </Option>
-                                        })
-                                    }
-                                })
-                            }
-                        </Select>
-                    </div>
-                    <Menu
-                        onClick={crewMenuItemClick}
-                        style={{ width: `${bWith ? '100%' : 200}`, height: props.height ? props.height : `${bWith ? '40' : 'calc(100vh - 390px)'} `, overflowY: 'auto', overflowX: 'hidden', borderRight: 0, backgroundColor: 'transparent' }}
-                        selectedKeys={crewSelectedKeys}
-                        mode={"inline"}
-                    >
-                        {
-                            props?.default && <Menu.Item key="all" icon={<QrcodeOutlined />}>全部公众号材料</Menu.Item>
-                        }
-                        {/* {
-                            getAllOfMember?.data?.map((item: any) => {
-                                if (item?.userId == userId) {
-                                    return <Menu.Item
-                                        key={item?.nickName + item?.userId}
-                                    >
-                                        <p>
-                                            {item?.userMpAccounts?.some((mp: { appid: string }) => actionArr?.some((arr: { appid: string }) => mp.appid === arr.appid)) ? <i style={{ fontStyle: 'normal', color: 'red' }}>*</i> : ''}
-                                            {item?.nickName}
-                                            <span style={{ color: '#999' }}>({item?.userMpAccounts?.length})</span>
-                                        </p>
-                                    </Menu.Item >
-                                }
-                                return
-                            })
-                        } */}
-                        {
-                            getAllOfMember?.data?.map((item: { key: { nickname: string, userId: number }, value: any[] }) => {
-                                return <Menu.Item
-                                    key={item?.key?.nickname + item?.key?.userId}
-                                >
-                                    <p onClick={() => { handelUserId(item?.key?.userId?.toString(), item?.key?.nickname) }}>
-                                        {item?.value?.some((mp: { appid: string }) => actionArr?.some((arr: { appid: string }) => mp.appid === arr.appid)) ? <i style={{ fontStyle: 'normal', color: 'red' }}>*</i> : ''}
-                                        {item?.key?.nickname}
-                                        <span style={{ color: '#999' }}>({item?.value?.length})</span>
-                                    </p>
-                                </Menu.Item >
-                            })
-                        }
-                    </Menu>
-                </Tabs.TabPane>
-            }
-        </Tabs>
-    </div >
-}
-
-export default LeftPage

+ 0 - 30
src/components/Alink/index.less

@@ -1,30 +0,0 @@
-.row_style {
-  width: 100%;
-  > div:nth-child(1) {
-    width: 120px;
-    text-align: right;
-  }
-  > div:nth-child(2) {
-    width: 100%;
-  }
-}
-.add {
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  flex-flow: column;
-  height: 100%;
-}
-.pos {
-  position: absolute;
-  top: 0;
-  left: 0;
-  height: 100%;
-  width: 100%;
-  opacity: 0;
-  color: #fff;
-}
-.pos:hover {
-  opacity: 1;
-  background: rgba(0, 0, 0, 0.6);
-}

+ 0 - 166
src/components/Alink/index.tsx

@@ -1,166 +0,0 @@
-import React, { useState } from 'react'
-import { Col, Input, message, Modal, Radio, RadioChangeEvent, Row, Space, Switch } from 'antd'
-import { useCallback } from 'react'
-import style from './index.less'
-import { PlusOutlined } from '@ant-design/icons'
-import SmMaterialModal from '@/components/MaterialModal/smModalBox';
-interface Props {
-    visible: boolean,
-    onCancel: () => void,
-    onOk: (v: any) => void,
-    title: string,
-    weCathType: 'img' | 'card',
-    defaultData?: { appid: string, appPath: string, cardTitle: string, img: string, imgInfo: any },
-    isOnUserId?: boolean
-}
-function Alink(props: Props) {
-    const { visible = false, title, onCancel, weCathType, onOk, isOnUserId = true } = props
-    const [type, setType] = useState<1 | 2>(1)
-    const [open, setOpen] = useState<boolean>(false)
-    const [imgVisible, setImgVisible] = useState<boolean>(false)
-    const [imgInfo, setImgInfo] = useState<any>(null)
-    const [img, setImg] = useState<string>('')
-    const [text, setText] = useState<string>('')
-    const [link, setLink] = useState<string>('')
-    const [size, setSize] = useState<25 | 50 | 75 | 100>(100)
-    /**确定 */
-    const handleOk = useCallback(() => {
-        let html = ''
-        if (!link) {
-            message.error('请输入连接地址')
-            return
-        }
-        if (!(text || img)) {
-            message.error('请输入文本或者选择图片')
-            return
-        }
-        if (type === 1) {
-            if (open) {
-                html = `<a data-linktype="2"  target="_blank"  tab="innerlink" data-itemshowtype="0"  href=${link}>${text}</a>`
-            } else {
-                html = ` <a data-linktype="2"  target="_blank"  tab="innerlink" data-itemshowtype="0"  href=${link} >${text}</a>`
-            }
-        } else {
-            if (open) {
-                html = `<br/><a data-itemshowtype="0" data-linktype="2" href=${link}  style="display: block;background-image: url(${img});background-repeat: no-repeat;background-size: ${size}% auto;background-position: center bottom;margin-top: 0%;padding-top: 40.85714285714286%;" tab="innerlink" target="_blank" ></a><br/>`
-            } else {
-                html = `<br/><a href=${link} data-linktype="2"  target="_blank"  tab="innerlink" data-itemshowtype="0"  style="display: block;background-image: url(${img});background-repeat: no-repeat;background-size:${size}% auto;background-position: center bottom;margin-top: 0%;padding-top: 40.85714285714286%;">&nbsp;</a><br/>`
-            }
-        }
-        onOk(html)
-    }, [open, type, img, text, link, size])
-    //类型
-    const onChange = useCallback((e: RadioChangeEvent) => {
-        setType(e.target.value)
-    }, [])
-    return <div>
-        <Modal
-            open={visible}
-            title={title}
-            onCancel={onCancel}
-            onOk={handleOk}
-            maskClosable={false}
-        >
-            <Row gutter={[10, 20]}>
-                <Col span={24}>
-                    <Space className={style.row_style}>
-                        <span>链接地址</span>
-                        <Input
-                            placeholder={'请填写链接地址https://www.*****'}
-                            onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
-                                let v = e.target.value
-                                setLink(v)
-                            }}
-                            value={link}
-                        />
-                    </Space>
-                </Col>
-                <Col span={24}>
-                    <Space className={style.row_style}>
-                        <span>链接类型</span>
-                        <Radio.Group onChange={onChange} value={type}>
-                            <Radio value={1}>文本</Radio>
-                            <Radio value={2}>图片</Radio>
-                        </Radio.Group>
-                    </Space>
-                </Col>
-                <Col span={24}>
-                    <Space className={style.row_style}>
-                        <span>{type === 1 ? '链接文本' : '链接图片'}</span>
-                        {
-                            type === 1 ?
-                                <Input
-                                    placeholder={'请填写链接文本'}
-                                    onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
-                                        let v = e.target.value
-                                        setText(v)
-                                    }}
-                                    value={text}
-                                /> :
-                                <div onClick={() => setImgVisible(true)} style={{ width: '100%', height: 200, border: '1px dashed #d8d8d8', position: 'relative', cursor: 'pointer' }}>
-                                    {
-                                        img ?
-                                            <>
-                                                <img src={img} style={{ width: '100%', height: '100%', objectFit: 'contain' }} />
-                                            </>
-                                            :
-                                            <span className={`${style.add} ${img ? style.pos : ''} `}>
-                                                <PlusOutlined style={{ fontSize: 32 }} />
-                                            </span>
-                                    }
-                                </div>
-                        }
-                        {
-                            imgVisible && <SmMaterialModal
-                                visible={imgVisible}
-                                onCancel={() => setImgVisible(false)}
-                                title='选择图片'
-                                onOk={(props: any) => {
-                                    console.log('props===>', props)
-                                    let obj: any = {}
-                                    if (props?.mediaId) {//微信素材
-                                        obj.wxMediaId = props?.id
-                                        obj.thumbUrl = props?.url
-                                    } else {
-                                        obj.thumbUrl = props?.url
-                                    }
-                                    setImg(obj?.thumbUrl)
-                                    setImgInfo(props)
-                                    setImgVisible(false)
-                                }}
-                                mediaType={1}
-                                isShowWx={false}
-                                isAllData
-                                noFile={true}
-                            />
-                        }
-                    </Space>
-                </Col>
-                {
-                    img && <Col span={24}>
-                        <Space className={style.row_style}>
-                            <span>图片大小</span>
-                            <Radio.Group onChange={(e: RadioChangeEvent) => {
-                                let v = e.target.value
-                                setSize(v)
-                            }} value={size}>
-                                <Radio value={25}>25%</Radio>
-                                <Radio value={50}>50%</Radio>
-                                <Radio value={75}>75%</Radio>
-                                <Radio value={100}>100%</Radio>
-                            </Radio.Group>
-                        </Space>
-                    </Col>
-                }
-                <Col span={24}>
-                    <Space className={style.row_style}>
-                        <span>是否开启弹窗</span>
-                        <Switch checkedChildren="开启" unCheckedChildren="关闭" onChange={(checked: boolean) => { setOpen(checked) }} checked={open} />
-                    </Space>
-                </Col>
-            </Row>
-        </Modal>
-    </div>
-}
-
-export default Alink

+ 0 - 26
src/components/CityCascader/index.tsx

@@ -1,26 +0,0 @@
-import cityList from '@/utils/city'
-import { Cascader } from 'antd'
-import React from 'react'
-type Props = {
-    change: (v: any) => void,//回调
-    fieldNames?: { label: string, value: string, childern: string },//自定义字段名称如需地域编号vlaue改id
-    disabled?: boolean
-}
-/**
- * 地域联调 
- * @param fieldNames?:{ label: 'label', value: 'value', children: 'children' }自定义字段名称如需地域编号vlaue改id
- * @param change: (v: any[]) => void 回调函数选中后返回一个数组
- */
-const CityCascader = React.memo((props: Props) => {
-    const { change, fieldNames, disabled = false } = props
-    return <Cascader
-        options={cityList()}
-        fieldNames={fieldNames || { label: 'label', value: 'value', children: 'children' }}
-        onChange={change}
-        placeholder="选择地域"
-        style={{ minWidth: 220 }}
-        disabled={disabled}
-    />
-})
-
-export default CityCascader

+ 0 - 36
src/components/ColorPicker/index.less

@@ -1,36 +0,0 @@
-.color {
-    width: 20px;
-    height: 20px;
-    border-radius: 2px;
-}
-.swatch{
-    padding: 5px;
-    background: #fff;
-    border-radius: 1px;
-    box-shadow: 0 0 0 1px rgba(0,0,0,.1);
-    display: inline-block;
-    cursor: pointer;
-    margin-top: 8px;
-} 
-.colorPicker{
-    position: relative;
-}
-.popover{
-    position: absolute;
-    top: 45px;
-    left: 0;
-    z-index: 100;
-    .cover{
-        position: fixed;
-        top: 0;
-        left: 0;
-        bottom: 0;
-        right: 0;
-    }
-    .sketchPicker{
-        position: absolute;
-    }
-}
-.swatch .color{
-    border: 1px solid rgb(199, 199, 199);
-}

+ 0 - 55
src/components/ColorPicker/index.tsx

@@ -1,55 +0,0 @@
-import React, { useCallback, useEffect, useState } from "react"
-import { SketchPicker } from 'react-color'
-import style from './index.less'
-type props = {
-    onColor: (color: string) => void,
-    defaultColor?: string,
-    value?: string,
-}
-
-const ColorPicker = (props: props) => {
-    let { onColor, defaultColor = "#000000", value } = props
-    const [displayColorPicker, setDisplayColorPicker] = useState<boolean>(false)
-    const [color, setColor] = useState<any>(defaultColor)
-
-    const handleClick = useCallback(() => {
-        setDisplayColorPicker(!displayColorPicker)
-    }, [])
-
-    const handleClose = useCallback(() => {
-        setDisplayColorPicker(false)
-    }, [])
-
-    const handleChange = useCallback((e: any) => {
-        setColor(e.hex)
-        onColor(e.hex)
-    }, [color])
-
-    useEffect(() => {
-        onColor(color)
-    }, [])
-
-    useEffect(() => {
-        if (value) {
-            setColor(value)
-            onColor(value)
-        }
-    }, [value])
-    
-    return <>
-        <div className={style.colorPicker}>
-            <div className={style.swatch} onClick={handleClick}>
-                <div className={style.color} style={{ backgroundColor: color }} />
-            </div>
-            {
-                displayColorPicker ? <div className={style.popover}>
-                    <div className={style.cover} onClick={handleClose} />
-                    <SketchPicker color={color} onChange={handleChange} className={style.sketchPicker} />
-                </div> : null
-            }
-
-        </div>
-    </>
-}
-
-export default React.memo(ColorPicker)

+ 0 - 246
src/components/Editor/AudioUploader.js

@@ -1,246 +0,0 @@
-import Button from './Button'
-import Input from './Input'
-import Label from './Label'
-import React from 'react'
-import Select from './Select'
-import Tag from './Tag'
-import Upload from './Upload'
-
-const style = {
-  paramsConfig: {
-    paddingBottom: '10px',
-    borderBottom: '1px solid rgb(217, 217, 217)',
-    display: 'flex',
-    flexWrap: 'wrap',
-  },
-  insertTitle: {
-    fontSize: '14px',
-    paddingRight: '10px',
-    color: 'rgba(0, 0, 0, 0.65)',
-  },
-  sourceList: {
-    margin: '10px 10px 10px 0',
-    border: '1px dashed rgb(217, 217, 217)',
-    borderRadius: '4px',
-  },
-  configTitle: {
-    display: 'block',
-    fontSize: '14px',
-    margin: '10px 0',
-    paddingRight: '10px',
-    color: 'rgba(0, 0, 0, 0.65)',
-  },
-  warnInfo: {
-    display: 'inline-block',
-    width: '100%',
-    margin: '5px',
-    textAlign: 'center',
-    fontSize: '12px',
-    color: '#f04134',
-  },
-}
-
-const linkRegx = /^https?:\/\/(([a-zA-Z0-9_-])+(\.)?)*(:\d+)?(\/((\.)?(\?)?=?&?[a-zA-Z0-9,_-](\?)?)*)*$/i
-
-let timeoutInstance = null
-
-class UploadModal extends React.PureComponent {
-  state = {
-    sources: [],
-    currentSource: '',
-    width: 400,
-    height: 400,
-    controls: 'true',
-    autoplay: 'false',
-    muted: 'false',
-    loop: 'false',
-    poster: '',
-    name: '',
-    author: '',
-    errorMsg: '',
-    errorMsgVisible: false,
-  }
-
-  updateCurrentSource = e => {
-    this.setState({currentSource: e.target.value})
-  }
-
-  addSource = () => {
-    let {sources, currentSource} = this.state
-    let newsources = sources.concat([currentSource])
-    if (currentSource === '') {
-      this.showErrorMsg('链接不能为空')
-    } else if (!linkRegx.test(currentSource)) {
-      this.showErrorMsg('非法的链接')
-    } else if (sources.indexOf(currentSource) !== -1) {
-      this.showErrorMsg('链接已存在')
-    } else {
-      this.setState({
-        sources: newsources,
-        currentSource: '',
-      }, () => {
-        this.props.onChange && this.props.onChange(this.generateHtml())
-      })
-    }
-  }
-
-  removeSource = index => {
-    let sourcesCopy = this.state.sources.concat([])
-    sourcesCopy.splice(index, 1)
-    this.setState({sources: sourcesCopy})
-  }
-
-  upload = e => {
-    let {upload} = this.props
-
-    if (!upload) return
-
-    upload(e).then(url => {
-      this.setState({currentSource: url})
-    }).catch(e => {
-      e.constructor === Error ? this.showErrorMsg(e.message) : this.showErrorMsg(e)
-    })
-  }
-
-  showErrorMsg = msg => {
-    this.setState({errorMsg: msg, errorMsgVisible: true})
-    clearTimeout(timeoutInstance)
-    timeoutInstance = setTimeout(() => {
-      this.setState({errorMsg: '', errorMsgVisible: false})
-    }, 4000)
-  }
-
-  getFileType = (fileUrl, mediaType) => {
-    let type = fileUrl.match(/\.(\w+)$/, 'i')
-    return type ? type[1].toLowerCase() : 'mp3'
-  }
-
-  generateHtml = () => {
-    let {sources, controls, autoplay, loop, poster, name, author} = this.state
-    let dataExtra = JSON.stringify({'poster': poster, 'name': name, 'author': author})
-    let len = sources.length
-
-    if (len > 0) {
-      let html = ''
-      let attr = ''
-
-      attr += controls === 'false' ? '' : ' controls="true" '
-      attr += autoplay === 'false' ? '' : ' autoplay="true" '
-      attr += loop === 'false' ? '' : ' loop="true" '
-
-      if (len === 1) {
-        html = `<audio src="${sources[0]}" ${attr} data-extra='${dataExtra}'>你的浏览器不支持 audio 标签</audio>`
-      } else {
-        html = `<audio ${attr} data-extra='${dataExtra}'>`
-        sources.forEach(source => {
-          html += `<source src=${source} type="audio/${this.getFileType(source, 'audio')}">`
-        })
-        html += '你的浏览器不支持 audio 标签</audio>'
-      }
-
-      return html + '<p></p>'
-    }
-  }
-
-  closeModal = () => {
-    this.props.closeModal()
-  }
-
-  changeConfig = (e, type) => {
-    let value = e.target.value
-    let boolType = ['controls', 'autoplay', 'muted', 'loop']
-    if (type === 'width' || type === 'height') {
-      if (isNaN(parseInt(value))) {
-        value = parseInt(value)
-      }
-    } else if (boolType.indexOf(type) !== -1) {
-      value = !!value
-    }
-    this.setState({[type]: value}, () => {
-      this.props.onChange && this.props.onChange(this.generateHtml())
-    })
-  }
-
-  renderSourceList = () => {
-    let {sources} = this.state
-    if (sources.length > 0) {
-      let list = sources.map((source, index) => {
-        return <Tag value={source} key={source} index={index} onRemove={this.removeSource} />
-      })
-      return list
-    } else {
-      return <span style={style.warnInfo}>至少添加一个链接</span>
-    }
-  }
-
-  renderAudioConfig = () => {
-    let {controls, autoplay, loop, poster, name, author} = this.state
-    return (
-      <form style={style.paramsConfig}>
-        <Label name='controls'>
-          <Select defaultValue={controls} onChange={e => { this.changeConfig(e, 'controls') }}>
-            <option value='true'>true</option>
-            <option value='false'>false</option>
-          </Select>
-        </Label>
-        <Label name='autoplay'>
-          <Select defaultValue={autoplay} onChange={e => { this.changeConfig(e, 'autoplay') }}>
-            <option value='true'>true</option>
-            <option value='false'>false</option>
-          </Select>
-        </Label>
-        <Label name='loop'>
-          <Select defaultValue={loop} onChange={e => { this.changeConfig(e, 'loop') }}>
-            <option value='true'>true</option>
-            <option value='false'>false</option>
-          </Select>
-        </Label>
-        <Label name='poster'>
-          <Input type='text' defaultValue={poster} onChange={e => { this.changeConfig(e, 'poster') }} />
-        </Label>
-        <Label name='name'>
-          <Input type='text' defaultValue={name} onChange={e => { this.changeConfig(e, 'name') }} />
-        </Label>
-        <Label name='author'>
-          <Input type='text' defaultValue={author} onChange={e => { this.changeConfig(e, 'author') }} />
-        </Label>
-      </form>
-    )
-  }
-
-  render() {
-    let {currentSource, errorMsg, errorMsgVisible} = this.state
-    let {progress} = this.props
-
-    return (
-      <div>
-        <div>
-          <span style={style.insertTitle}>插入链接</span>
-          <Input style={{width: '300px'}} type='text' value={currentSource} onChange={this.updateCurrentSource} />
-          <Button onClick={this.addSource}>添加</Button>
-          <Upload onChange={this.upload} />
-        </div>
-        <div>
-          <span style={{...style.warnInfo, display: progress && progress !== -1 ? 'block' : 'none'}}>
-            {progress}%
-          </span>
-          <span style={{...style.warnInfo, display: errorMsgVisible ? 'block' : 'none'}}>{errorMsg}</span>
-        </div>
-        <div style={style.sourceList}>
-          {this.renderSourceList()}
-        </div>
-        <span style={style.configTitle}>参数配置</span>
-        {this.renderAudioConfig()}
-        <div style={{textAlign: 'center', padding: '20px 10px 0 10px'}}>
-          {
-            <audio src={currentSource} controls='controls' style={{width: '400px'}}>
-              你的浏览器不支持 audio 标签
-            </audio>
-          }
-        </div>
-      </div>
-    )
-  }
-}
-
-export default UploadModal

+ 0 - 265
src/components/Editor/Box/TEditor.tsx

@@ -1,265 +0,0 @@
-import { Editor } from '@tinymce/tinymce-react';
-import React, { useRef, useEffect, useState, useCallback } from 'react';
-import SmMaterialModal from '@/components/MaterialModal/smModalBox'
-import WeChatImgCard from "@/components/WeChatImgCard"
-import Alink from '@/components/Alink'
-// https://mmbiz.qpic.cn/mmbiz_png/Bic8GaUSeMXaRjA1qiaGAu35ssNpnPejMzyY4c0HHPrO1kjh93uWIE4F9aQUfIsEiakib5TWfHls8GLHEPXOIQiaiakg/640?wx_fmt=png
-//https://zx-oss-dev.oss-cn-hangzhou.aliyuncs.com/file/B9B6AEB034044B5E9A7FC05227060789.jpg
-export default function TEditor(props: {
-    dispatch: (arg: any) => void,
-    setLoding: (arg: boolean) => void,
-    isOk: (arg: any) => void,
-    content: string,
-    actionId: any
-}) {
-    let { dispatch, setLoding, isOk, content, actionId } = props
-    let [value, setValue] = useState<any>(null)
-    let [imgVisible, setImgVisible] = useState(false)
-    let [wImgVisible, setWImgVisible] = useState(false)
-    let [wCardVisible, setWCardVisible] = useState(false)
-    let [wAVisible, setWAVisible] = useState(false)
-    const editorRef: any = useRef(null);
-    // console.log('传进来的content====>',content)
-
-    /**==================实时处理html===================*/
-    const disposeHtml = useCallback((html) => {
-        console.log(333333, '执行HTML处理方法')
-        // =================处理腾讯的图片,解决非法引用看不到图的问题==========================
-        // 筛选出是腾讯的图片,并查看是否带了随机数,以免加载失败
-        // let imgArr = html?.match(/(<img .*(\B>))/ig)?.filter((img: string ) => !img.includes('aliyuncs.com') && img.search(/=?\w{0,4}\?v/)!== -1)
-        // imgArr?.forEach((img: any) => {
-        //     // let src = img.match(/src=.*=png/)[0]
-        //     console.log('img====>', img)
-        //     let src = img.match(/(src=.*=\w{3,4})|(src=.*\/[0-9]{0,3}")/)[0]
-        //     console.log('src====>', src)
-        //     // 不存在no-referrer执行添加
-        //     if (!img.includes('referrerpolicy="no-referrer"')) {
-        //         console.log('修改IMG1')
-        //         html = html.replace(src, `${src + '?v' + Math.random() * 10}" referrerpolicy="no-referrer"`)
-        //     } else {
-        //         console.log('修改IMG2')
-        //         html = html.replace(src, src + '?v' + Math.random() * 10)
-        //     }
-        // })
-        // 处理小程序卡片假如没有外层加上外层好在本地展示
-        let mp_miniprogram = html?.match(/(<mp-miniprogram .*>\s?<\/mp-miniprogram>)/)
-        mp_miniprogram?.forEach((mp: any) => {
-            if (!mp.includes('data-bd="true"')) {
-                let imgSrc = mp?.match(/(http.*\.\w{3,4})/)[0]
-                let newMp = mp.replace('<mp-miniprogram', `<mp-miniprogram data-bd="true"`)
-                html = html.replace(mp, `
-                <div class='mp-miniprogram'>
-                ${newMp}
-                    <img src='${imgSrc}' />
-                </div>
-                `)
-            }
-        })
-        console.log(content !== html)
-        //存放处理后的html
-        if (content !== html) {
-            // console.log('setValue=====>',html)
-            console.log(444444, '改变后的HTML和当前存放的HTML不同替换旧的HTML')
-            setValue(html)
-        }
-    }, [content])
-
-    /**====================处理保存的html=======================*/
-    const disposeSaverHtml = useCallback((html) => {
-        console.log(5555555, '焦点脱离,处理HTML并保存内容dispatch=====>')
-        let divStr = html?.match(/<div\s?class="mp-miniprogram">.*<img\s?src=.*\.\w{3,4}">\s?<\/div>/)
-        divStr?.forEach((div: any) => {
-            let mpStr = div?.match(/(<mp-miniprogram .*>\s?<\/mp-miniprogram>)/)[0]
-            mpStr = mpStr?.replace(`data-bd="true"`, '')
-            html = html?.replace(div, mpStr)
-        })
-        console.log('html====>', html)
-        dispatch({ type: 'pushData', params: { menuId: actionId, content: html || '<p></p>' } })
-    }, [actionId])
-    useEffect(() => {
-        // actionId的监听因为content可能一样为默认值所以监听actionId的变化来强行执行
-        console.log(1111111111, 'props.content改变')
-        setValue(content)
-    }, [content, actionId])
-    // 腾讯图片出去referrer请求头
-    useEffect(() => {
-        let meta = document.createElement('meta')
-        meta.name = 'referrer'
-        meta.content = 'no-referrer'
-        document.head.appendChild(meta)
-        return () => {
-            let m = document.head.querySelector('[name="referrer"]')
-            if (m) {
-                document.head.removeChild(m)
-            }
-        }
-    }, [])
-    // console.log('value======>',value)
-    return <>
-        <Editor
-            apiKey='wkn1n49be4rmnjq9h33nzp15z9n9v5jn2n4dr3kav8bx7y4y'
-
-            // 初始化
-            onInit={(evt, editor) => {
-                editorRef.current = editor
-                setLoding(false)
-                isOk(editor);
-                // editor.ui.registry.addButton
-            }}
-
-            // initialValue={content}
-            value={value}
-            onBlur={() => {
-                // 假如焦点丢失时最后数据与数据存放中的数据不同执行保存
-                if (value !== content || content === '') {
-                    disposeSaverHtml(value)
-                }
-            }}
-            // 编辑变化
-            onEditorChange={(html, editor) => {
-                console.log(22222222, '监听到html变化,执行处理HTML函数方法', html)
-                // console.log('html===>',html)
-                //每次html变化去处理函数处理html
-                disposeHtml(html)
-            }}
-            init={{
-                height: 730,
-                menubar: true,
-                language: 'zh-Hans',
-                language_url: 'http://test.zanxiangnet.com/aaplugin/zh-Hans.js',
-                extended_valid_elements: 'img[src|_src|referrerpolicy|style|class],mp-miniprogram[data-*]',//自定义标签支持属性
-                custom_elements: 'mp-miniprogram',
-                branding: false,//右下角支持关闭
-                typeahead_urls: false,//输入地址时的自动完成
-                plugins: [//头部文字插件
-                    'advlist', 'autolink', 'lists', 'link', 'charmap', 'preview',
-                    'anchor', 'searchreplace', 'visualblocks', 'code', 'fullscreen',
-                    'insertdatetime', 'emoticons', 'table', 'code', 'wordcount', 'image', 'paste', 'help'
-                ],
-                // 图标插件按钮
-                toolbar: 'undo redo  blocks fontsize|bold italic forecolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent paste |img wImg wCard wA',//工具栏
-                toolbar_mode: 'wrap',//工具换行
-                paste_webkit_styles: 'all',
-                content_style: `
-                body { font-family:Helvetica,Arial,sans-serif; font-size:14px ;}
-                .mp-miniprogram{
-                    width:200px;
-                    height:200px;
-                }
-                .mp-miniprogram img{
-                    width:100%;
-                }
-                `,
-                setup(ed) {
-                    // 图
-                    ed.ui.registry.addButton('img', {
-                        text: '图片',
-                        onAction: () => {
-                            setImgVisible(true)
-                        }
-                    })
-                    // 小程序图片链插件
-                    ed.ui.registry.addButton('wImg', {
-                        text: '小程序图片',
-                        onAction: () => {
-                            setWImgVisible(true)
-                        }
-                    })
-                    // 小程序卡片链插件
-                    ed.ui.registry.addButton('wCard', {
-                        text: '小程序卡片',
-                        onAction: () => {
-                            setWCardVisible(true)
-                        }
-                    })
-                    // A链接功能插件
-                    ed.ui.registry.addButton('wA', {
-                        text: 'A链接',
-                        onAction: () => {
-                            setWAVisible(true)
-                        }
-                    })
-                }
-                // '' +
-                // 'alignright alignjustify | bullist numlist outdent indent | ' +
-                // 'removeformat |code| emoticons|media| image|help'
-            }}
-        />
-        {/* 图片选择 */}
-        <SmMaterialModal
-            mediaType={1}
-            onCancel={() => { setImgVisible(false) }}
-            title='选择图片'
-            visible={imgVisible}
-            onOk={(props: any) => {
-                let url = props.url
-                editorRef.current.insertContent(`<img 
-                style='max-width:100%'
-                src=\"${url}\" 
-                alt=\"\" 
-                data-w=\"auto\" 
-                data-ratio=\"0.66796875\" 
-                data-type=\"${url.replace(/http[s]?:\/\/\S*(wx_fmt=|\.)/ig, '') === 'gif' ? 'png' : url.replace(/http[s]?:\/\/\S*(wx_fmt=|\.)/ig, '')}\"
-                />`)
-                setImgVisible(false)
-            }}
-            // isShowWx={isShowWx}
-            isAllData
-            noFile={true}
-        />
-        {/* 小程序图片链 */}
-        {
-            wImgVisible && <WeChatImgCard
-                onCancel={() => {
-                    setWImgVisible(false)
-                }}
-                title='小程序图片链'
-                visible={wImgVisible}
-                onOk={(props: { img: string, appid: string, appPath: string, href?: string }) => {
-                    editorRef.current.insertContent(`<a data-miniprogram-appid=\"${props.appid}\" data-miniprogram-path=\"${props.appPath}\" href=\"${props.href}\"><img src=\"${props.img}\" alt=\"\" data-width=\"null\" data-ratio=\"NaN\"/></a>`)
-                    setWImgVisible(false)
-                }}
-                weCathType='img'
-                isOnUserId={false}
-            />
-        }
-        {/* 小程序卡片链 */}
-        {
-            wCardVisible && <WeChatImgCard
-                onCancel={() => {
-                    setWCardVisible(false)
-                }}
-                title='小程序卡片链'
-                visible={wCardVisible}
-                onOk={(props: { img: string, appid: string, appPath: string, cardTitle?: string }) => {
-                    editorRef.current.insertContent(`
-                    <div class='mp-miniprogram'>
-                        <mp-miniprogram data-bd="true" data-miniprogram-appid=\"${props?.appid}\" data-miniprogram-path=\"${props?.appPath}\" data-miniprogram-title=\"${props?.cardTitle}\" data-miniprogram-type=\"card\" data-miniprogram-servicetype=\"0\" data-miniprogram-imageurl=\"${props?.img}\"></mp-miniprogram>
-                        <img src='${props.img}' />
-                    </div>
-                    `)
-                    setWCardVisible(false)
-                }}
-                weCathType='card'
-                isOnUserId={false}
-            />
-        }
-        {/*A链 */}
-        {
-            wAVisible && <Alink
-                onCancel={() => { setWAVisible(false) }}
-                title='A链接'
-                visible={wAVisible}
-                onOk={(props: string) => {
-                    editorRef.current.insertContent(props)
-                    setWAVisible(false)
-                }}
-                weCathType='card'
-                isOnUserId={false}
-            />
-        }
-    </>
-}
-
-// /**图片上传插件*/
-

+ 0 - 32
src/components/Editor/Box/UEditor.tsx

@@ -1,32 +0,0 @@
-import React from 'react'
-import ReactUeditor from '@/components/Editor/ReactUeditor'
-import { uploadImagePlugin, uploadVidioPlugin, uploadWeChatImagePlugin, uploadWeChatCardPlugin, uploadALink } from './editorPlugin'
-
-export default function UEditor(props:{dispatch: (arg: any) => void,setLoding: (arg: boolean) => void,isOk: (arg: any) => void,setContent:(arg:any)=>void,isShowWx:any}) {
-    let {dispatch,setLoding,isOk,setContent,isShowWx} = props
-    return <ReactUeditor
-        ueditorPath={`/ueditor`}
-        getRef={(ref: any) => {
-            dispatch({ type: 'setRef', params: { ueditorRef: ref } })//存放实例
-        }}
-        onReady={
-            (ueditor: any) => {
-                setLoding(false)
-                isOk(ueditor)//执行编辑的操作
-            }
-        }
-        plugins={[
-            'emotion',
-            (e: any) => { return uploadImagePlugin(e, isShowWx) },
-            uploadVidioPlugin,
-            uploadWeChatImagePlugin,
-            uploadWeChatCardPlugin,
-            uploadALink
-        ]}
-        onChange={(content: any) => {
-            if (content || '<p></p>') {
-                setContent(content)
-            }
-        }}
-    />
-}

+ 0 - 149
src/components/Editor/Box/editorPlugin.tsx

@@ -1,149 +0,0 @@
-import React from "react"
-import SmMaterialModal from '@/components/MaterialModal/smModalBox'
-import WeChatImgCard from "@/components/WeChatImgCard"
-import Alink from '@/components/Alink'
-/**图片上传插件*/
-const uploadImagePlugin = (ueditor: any, isShowWx?: boolean) => {
-    return {
-        menuText: '图片上传',
-        cssRules: `background-image: url(/ueditor/themes/default/icon/tool-0332@2x.png) !important;background-size: 20px 1340px;background-position: 0 -480px;`,
-        render: (visible: any, closeModal: any) => {
-            const handleSelectImage = (url: string) => {
-                ueditor.focus()
-                ueditor.execCommand('insertHtml', `<img 
-                style='max-width:100%'
-                src=\"${url}\" 
-                alt=\"\" 
-                data-w=\"auto\" 
-                data-ratio=\"0.66796875\" 
-                data-type=\"${url.replace(/http[s]?:\/\/\S*(wx_fmt=|\.)/ig, '') === 'gif' ? 'png' : url.replace(/http[s]?:\/\/\S*(wx_fmt=|\.)/ig, '')}\"
-                />`)
-                closeModal()
-            }
-            return visible && <SmMaterialModal
-                mediaType={1}
-                onCancel={closeModal}
-                title='选择图片'
-                visible={visible}
-                onOk={(props: any) => { handleSelectImage(props?.url) }}
-                isShowWx={isShowWx}
-                isAllData
-                noFile={true}
-            />
-        }
-    }
-}
-/**音频上传插件*/
-const uploadAudioPlugin = (ueditor: any) => {
-    return {
-        menuText: '音频上传',
-        cssRules: `background-image: url(/ueditor/themes/default/icon/tool-0332@2x.png) !important;background-size: 20px 1340px;background-position: 0 -510px;`,
-        render: (visible: any, closeModal: any) => {
-            const handleSelectImage = (url: string) => {
-                ueditor.focus()
-                ueditor.execCommand('insertparagraph')
-                ueditor.execCommand('insertHtml', `<audio src="${url}" controls="true" data-extra="{}"></audio>`)
-                ueditor.execCommand('insertparagraph')
-                closeModal()
-            }
-            return visible && <SmMaterialModal mediaType={2} onCancel={closeModal} title='公众号音频素材' visible={visible} onOk={handleSelectImage} actionKey='2' />
-        }
-    }
-}
-/**视频上传插件*/
-const uploadVidioPlugin = (ueditor: any) => {
-    return {
-        menuText: '视频上传',
-        cssRules: `background-image: url(/ueditor/themes/default/icon/tool-0332@2x.png) !important;background-size: 20px 1340px;background-position: 0 -540px;`,
-        render: (visible: any, closeModal: any) => {
-            const handleSelectImage = (url: string) => {
-                ueditor.focus()
-                ueditor.execCommand('insertparagraph')
-                ueditor.execCommand('insertHtml', `
-                <iframe
-                    data-vidtype="2" 
-                    height="310" 
-                    width="500"
-                    data-ratio="1.7666666666666666" 
-                    data-w="848"
-                    frameborder="0" 
-                    data-src=${url}
-                    allowfullscreen="" 
-                    src=${url}
-                >
-                </iframe>
-                `)
-                ueditor.execCommand('insertparagraph')
-                closeModal()
-            }
-            return visible && <SmMaterialModal mediaType={3} onCancel={closeModal} title='公众号视频素材' visible={visible} onOk={handleSelectImage} actionKey='1' />
-        }
-    }
-}
-/**小程序图片链插件*/
-const uploadWeChatImagePlugin = (ueditor: any,) => {
-    return {
-        menuText: '小程序图片链',
-        cssRules: `background-image: url(/ueditor/themes/default/icon/tool-0332@2x.png) !important;background-size: 20px 1340px;background-position: 0 -1320px;`,
-        render: (visible: any, closeModal: any) => {
-            const handleSelectImage = (obj: { img: string, appid: string, appPath: string, href?: string }) => {
-                ueditor.focus()
-                ueditor.execCommand('insertHtml', `<a data-miniprogram-appid=\"${obj.appid}\" data-miniprogram-path=\"${obj.appPath}\" href=\"${obj.href}\"><img src=\"${obj.img}\" alt=\"\" data-width=\"null\" data-ratio=\"NaN\"/></a>`)
-                closeModal()
-            }
-            return visible && <WeChatImgCard
-                onCancel={closeModal}
-                title='小程序图片链'
-                visible={visible}
-                onOk={(props: { img: string, appid: string, appPath: string, href?: string }) => { handleSelectImage(props) }}
-                weCathType='img'
-                isOnUserId={false}
-            />
-        }
-    }
-}
-/**小程序卡片链插件*/
-const uploadWeChatCardPlugin = (ueditor: any,) => {
-    return {
-        menuText: '小程序卡片',
-        cssRules: `background-image: url(/ueditor/themes/default/icon/tool-0332@2x.png) !important;background-size: 20px 1340px;background-position: 0 -1290px;`,
-        render: (visible: any, closeModal: any) => {
-            const handleSelectImage = (obj: { img: string, appid: string, appPath: string, cardTitle?: string }) => {
-                ueditor.focus()
-                ueditor.execCommand('insertHtml', `<mp-miniprogram data-miniprogram-appid=\"${obj?.appid}\" data-miniprogram-path=\"${obj?.appPath}\" data-miniprogram-title=\"${obj?.cardTitle}\" data-miniprogram-type=\"card\" data-miniprogram-servicetype=\"0\" data-miniprogram-imageurl=\"${obj?.img}\"></mp-miniprogram>`)
-                closeModal()
-            }
-            return visible && <WeChatImgCard
-                onCancel={closeModal}
-                title='小程序卡片'
-                visible={visible}
-                onOk={(props: { img: string, appid: string, appPath: string, cardTitle?: string }) => { handleSelectImage(props) }}
-                weCathType='card'
-                isOnUserId={false}
-            />
-        }
-    }
-}
-/**A链接功能插件*/
-const uploadALink = (ueditor: any,) => {
-    return {
-        menuText: 'A链接',
-        cssRules: `background-image: url(/ueditor/themes/default/icon/tool-0332@2x.png) !important;background-size: 20px 1340px;background-position: 0 -1290px;`,
-        render: (visible: any, closeModal: any) => {
-            const handleSelectImage = (html: string) => {
-                ueditor.focus()
-                ueditor.execCommand('insertHtml', `${html}`)
-                closeModal()
-            }
-            return visible && <Alink
-                onCancel={closeModal}
-                title='A链接'
-                visible={visible}
-                onOk={(props: string) => { handleSelectImage(props) }}
-                weCathType='card'
-                isOnUserId={false}
-            />
-        }
-    }
-}
-export { uploadImagePlugin, uploadAudioPlugin, uploadVidioPlugin, uploadWeChatImagePlugin, uploadWeChatCardPlugin, uploadALink }

+ 0 - 25
src/components/Editor/Box/index.less

@@ -1,25 +0,0 @@
-.ueditor_title{
-    padding: 10px 30px;
-    display: flex;
-    justify-content: left;
-    align-items: center;
-    border-top: 1px solid #efefef;
-    border-bottom: 1px solid #efefef;
-    // position: absolute;
-    // left: 0;
-    width: 100%;
-    top:175px;
-    z-index: 999;
-    >input{
-        height: 52px;
-        line-height: 52px ;
-        font-size: 25px;
-        font-weight: 500;
-    }
-}
-.btn{
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    height: 50px;
-}

+ 0 - 516
src/components/Editor/Box/index.tsx

@@ -1,516 +0,0 @@
-import React, { useState, useCallback, useMemo, useEffect, useRef } from 'react'
-
-import { Button, Input, message, Space, Spin } from 'antd'
-import style from './index.less'
-
-import { useModel, history } from 'umi'
-import ActionModal from '@/components/ActionModal'
-import TEditor from './TEditor'
-import UEditor from './UEditor'
-
-
-const Title = React.memo(() => {
-    const [titleV, setTitleV] = useState<string>('') //title值
-    const { state: { actionId, dataArr }, dispatch } = useModel('useOperating.useMaterialDrawer')
-    //获取已有Title回写入
-    const defaultTitle = useMemo(() => {
-        let title = ''
-        setTitleV('')
-        dataArr.forEach((obj: any) => {
-            if (obj.menuId === actionId) {
-                if (obj.title) {
-                    title = obj.title
-                }
-            }
-        })
-        return title
-    }, [actionId, dataArr])
-    //插入数据
-    let titleValue = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
-        let value = e.target.value
-        console.log(3)
-        dispatch({ type: 'pushData', params: { menuId: actionId, title: value } })
-        setTitleV(value)
-    }, [actionId])
-    return <div className={style.ueditor_title}>
-        <Input placeholder='输入文章标题(请勿输入特殊字符)' bordered={false} maxLength={64} onChange={titleValue} value={titleV || defaultTitle} />
-    </div>
-})
-interface Props {
-    onClose: () => void, //关闭
-    editId: string,//编辑ID
-    editData: any, //编辑初始内容
-    syncNews?: boolean,//同步
-    isWx?: boolean //是否是微信素材用来判断不同接口逻辑
-    isShowWx?: boolean,
-    isAll?: boolean,
-    callback?: (data: any) => void //回调获取数据
-}
-// ======================== TEditor =========================
-export default function Editor(props: Props) {
-    let { syncNews = true, isWx, isShowWx, isAll = true, callback = null } = props
-    const [showActionModal, setShowActionModal] = useState<boolean>(false)//选择公众号弹窗
-    const [id, setId] = useState<string>('')
-    const [loding, setLoding] = useState<boolean>(true)
-    const { getWeData } = useModel('useOperating.useMaterialContent')
-    const { dispatchNews } = useModel('useOperating.useNews', model => ({ dispatchNews: model.dispatch }))
-    const { dispatch, state } = useModel('useOperating.useMaterialDrawer')
-    const { dispatch: contentDispatch } = useModel('useOperating.useMaterialContent')
-    const { actionId, actionIdold, dataArr, actionData, ueditorRef, sort = 0 } = state
-    const { actionWX } = useModel('useOperating.useWxGroupList', model => ({ actionWX: model.state.actionWX }))
-    //
-    const { add, list, edit, syncId, addWx, state: { parentId, belongUser }, eidtWxlists } = useModel(isAll ? 'useOperating.useBdMedia' : 'useOperating.useBdMediaPup')
-    const { state: { selectWx }, initSelectWx } = useModel('useOperating.useWxGroupList')//公众号筛选
-    const [sid, setSid] = useState<number>(0)//已经切换设置过的ID
-    const [content, setContent] = useState<string>('<p></p>')//内容
-    const editorRef:any = useRef(null);
-    //保存
-    let seve = useCallback((isSaveNews?: boolean) => {
-        let content = ueditorRef?.getContent()
-        let menuId = actionIdold || actionId
-        console.log('保存dataArr===>',dataArr)
-        dispatch({ type: 'pushData', params: { content } })
-        let isOk = dataArr.every((item: any) => {
-            let img = item?.thumbMediaUrl || item?.thumbUrl
-            if (!item.title) {
-                message.error(`第${item.menuId}篇标题为空`)
-                return false
-            }
-            if (!img) {
-                message.error(`第${item.menuId}篇封面为空`)
-                return false
-            }
-            if (item?.digest?.length > 54) {
-                message.error(`第${item.menuId}摘要不能超过54个字`)
-                return false
-            }
-            if (item.content === '<p></p>' || !item.content) {
-                message.error(`第${item.menuId}篇内容为空`)
-                return false
-            }
-            // if (!item.contentSourceUrl) {
-            //     message.error(`第${item.menuId}原文链接为空`)
-            //     return false
-            // }
-            return true
-        })
-        if (isOk) {
-            let news = dataArr.map((item: any) => {
-                return { ...item, showCoverPic: false, thumbUrl: item?.thumbUrl || item?.thumbMediaUrl }
-            })
-            let data: any = {
-                news,
-                folder: false,
-                fileType: 'news',
-                parentId,
-                belongUser,
-                sort
-            }
-            if (callback) {//假如有回调那么不请求接口保存直接执行回调函数
-                callback && callback(data)
-                dispatch({ type: 'initData' })
-                props.onClose()
-                return
-            }
-            if (isWx) {//执行微信接口
-                console.log('微信素材', props?.editId);
-                if (props?.editId) {//编辑走新建本地素材再同步到微信
-                    add.run({ ...data, mpIds: selectWx }).then((res: any) => {
-                        if (res) {
-                            if (isSaveNews) {//走保存去群发逻辑
-                                console.log('新建===》保存并群发', props)
-                                syncId.run({ mpIds: [actionWX?.id], sysMediaId: res }).then((syncWxres: any) => {
-                                    if (syncWxres) {
-                                        dispatchNews({ type: 'theEdit', params: { theEdit: { content: { news }, mediaId: syncWxres, msgType: 'mpnews' } } })
-                                        history.push(`/operatePage/news/advanced?show=true`)
-                                        dispatch({ type: 'initData' })
-                                        localStorage.setItem('collapsed', '0')
-                                    }
-                                })
-                            } else {
-                                syncId.run({ mpIds: [actionWX?.id], sysMediaId: res }).then((syncWxres: any) => {
-                                    if (syncWxres) {
-                                        console.log('新建==》保存')
-                                        dispatch({ type: 'initData' })
-                                        props.onClose()
-                                        getWeData.refresh().then((res) => {//刷新页面
-                                            contentDispatch({ type: 'initData', params: { data: res.records } })
-                                        })
-                                        localStorage.setItem('collapsed', '0')
-                                    }
-                                })
-                            }
-                        }
-                    })
-                } else {//新建
-                    addWx.run({ mpId: actionWX?.id, mediaType: 'news', news }).then((res: any) => {
-                        console.log(res)
-                        if (res) {
-                            if (isSaveNews) {//走保存去群发逻辑
-                                console.log('新建===》保存并群发', props)
-                                setId(res)
-                                setShowActionModal(true)
-                            } else {
-                                dispatch({ type: 'initData' })
-                                props.onClose()
-                                getWeData.refresh().then((res) => {//刷新页面
-                                    contentDispatch({ type: 'initData', params: { data: res.records } })
-                                })
-                                localStorage.setItem('collapsed', '0')
-                            }
-                        }
-                    })
-                }
-            } else {//执行本地
-                if (props?.editId) {//表示编辑
-                    edit.run({ belongUser, fileType: 'news', folder: false, news, sysMediaId: props?.editId, sort }).then((res: any) => {
-                        if (isSaveNews) {//走保存去群发逻辑
-                            console.log('编辑==》保存并群发', news, dataArr)
-                            setId(props?.editId)
-                            setShowActionModal(true)
-                        } else {
-                            console.log('编辑===》保存')
-                            dispatch({ type: 'initData' })
-                            props.onClose()
-                            list.refresh()
-                            localStorage.setItem('collapsed', '0')
-                        }
-                    })
-                    eidtWxlists.run({ sysMediaId: props?.editId, mpIds: selectWx || [] }).then((res) => {
-                        console.log(res, 'eidtWxlists')
-                        initSelectWx()
-                    })
-                } else {//新建
-                    add.run({ ...data, mpIds: selectWx }).then((res: any) => {
-                        if (res) {
-                            if (isSaveNews) {//走保存去群发逻辑
-                                console.log('新建===》保存并群发', props)
-                                setId(res)
-                                setShowActionModal(true)
-                                initSelectWx()
-                            } else {
-                                console.log('新建==》保存')
-                                dispatch({ type: 'initData' })
-                                props.onClose()
-                                list.refresh()
-                                localStorage.setItem('collapsed', '0')
-                                initSelectWx()
-                            }
-
-                        }
-                    })
-                }
-            }
-
-        }
-    }, [dataArr, props?.editId, ueditorRef, actionWX, getWeData, isWx, parentId, belongUser, list, selectWx, sort])
-    //保存并群发选择公众号后回调
-    const saverNews = useCallback((cancel: boolean) => {
-        setShowActionModal(false)
-        if (!cancel) {//假如cancel为false就是保持并群发
-            let news = dataArr.map((item: any) => { return { ...item, showCoverPic: false, thumbUrl: item?.thumbUrl || item?.thumbMediaUrl } })
-            console.log(news, dataArr, 'dataArr,news')
-            if (actionWX) {
-                if (isWx) {
-                    // dispatchNews({ type: 'theEdit', params: { theEdit: { content: { news }, mediaId: id, msgType: 'mpnews' } } })
-                    // history.push(`/operatePage/news/advanced?show=true`)
-                    // dispatch({ type: 'initData' })
-                    // localStorage.setItem('collapsed', '0')
-                } else {//本地素材先同步再群发
-                    syncId.run({ mpIds: [actionWX?.id], sysMediaId: id }).then((syncWxres: any) => {
-                        if (syncWxres) {
-                            // dispatchNews({ type: 'theEdit', params: { theEdit: { content: { news }, mediaId: syncWxres, msgType: 'mpnews' } } })
-                            // history.push(`/operatePage/news/advanced?show=true`)
-                            // dispatch({ type: 'initData' })
-                            // localStorage.setItem('collapsed', '0')
-                        }
-                    })
-                }
-            }
-            dispatchNews({ type: 'theEdit', params: { theEdit: { content: { news }, mediaId: id, msgType: 'mpnews' } } })
-            history.push(`/operatePage/news/advanced?show=true`)
-            dispatch({ type: 'initData' })
-            localStorage.setItem('collapsed', '0')
-        }
-    }, [actionWX, isWx, id, syncId, dataArr])
-    // //切换文章
-    useEffect(() => {
-        console.log('切换文章=====>',{sid,actionId})
-        if (sid !== actionId ) {
-            setSid(actionId)
-            let content = dataArr?.filter((item: { menuId: any }) => item.menuId === actionId)[0]?.content 
-            content = content !== '' ? content :  '<p></p>'
-            console.log('切换后的content====>',content)
-            setContent(content)
-        }
-    }, [actionId, dataArr,  sid])
-    //编辑回填
-    const isOk = useCallback((ueditor) => {
-        console.log('props?.editData===>',props?.editData)
-        if (actionData) {
-            let dataArr = actionData.dataArr?.map((item: any, index: number) => {
-                item.menuId = index + 1
-                return item
-            })
-            // 存放到数据中心
-            dispatch({ type: 'initData', params: { data: { ...actionData, dataArr, actionId: 1 } } })
-            setContent(dataArr[0].content)
-        }
-    }, [props?.editData])
-    return <div >
-        <h3 style={{ height: 43, lineHeight: '43px', textAlign: 'center' }}>素材编辑</h3>
-        <Spin spinning={loding} tip='初始化中请稍等。。。'>
-            <Title />
-            {/* ================================ TEditor ============================== */}
-
-            <TEditor dispatch={dispatch}  setLoding={setLoding} isOk={isOk} content={content} actionId={actionId} />
-
-             {/* ================================ UEditor ============================== */}
-            {/* <UEditor dispatch={dispatch}  setLoding={setLoding} isOk={isOk} setContent={setContent} isShowWx={isShowWx}/> */}
-            <Space className={style.btn}>
-                <Button onClick={() => { seve() }} type='primary' loading={add?.loading || edit?.loading || addWx?.loading}>保存素材</Button>
-                {syncNews && !callback && <Button onClick={() => { seve(true) }} type='primary' loading={add?.loading || addWx?.loading || edit?.loading || syncId?.loading}>保存并群发</Button>}
-                <Button onClick={() => { props.onClose(); initSelectWx() }} >取消</Button>
-            </Space>
-            <ActionModal visible={showActionModal} hideWx={saverNews} />
-        </Spin>
-    </div>
-}
-
-// ======================== UEditor =========================
-
-// export default function Editor(props: Props) {
-//     let { syncNews = true, isWx, isShowWx, isAll = true, callback = null } = props
-//     const [showActionModal, setShowActionModal] = useState<boolean>(false)//选择公众号弹窗
-//     const [id, setId] = useState<string>('')
-//     const [loding, setLoding] = useState<boolean>(true)
-//     const { getWeData } = useModel('useOperating.useMaterialContent')
-//     const { dispatchNews } = useModel('useOperating.useNews', model => ({ dispatchNews: model.dispatch }))
-//     const { dispatch, state } = useModel('useOperating.useMaterialDrawer')
-//     const { dispatch: contentDispatch } = useModel('useOperating.useMaterialContent')
-//     const { actionId, actionIdold, dataArr, actionData, ueditorRef, sort = 0 } = state
-//     const { actionWX } = useModel('useOperating.useWxGroupList', model => ({ actionWX: model.state.actionWX }))
-//     //
-//     const { add, list, edit, syncId, addWx, state: { parentId, belongUser }, eidtWxlists } = useModel(isAll ? 'useOperating.useBdMedia' : 'useOperating.useBdMediaPup')
-//     const { state: { selectWx }, initSelectWx } = useModel('useOperating.useWxGroupList')//公众号筛选
-//     const [sid, setSid] = useState<number>(0)//已经切换设置过的ID
-//     const [content, setContent] = useState<string>('<p></p>')//内容
-//     const editorRef:any = useRef(null);
-
-//     //保存
-//     let seve = useCallback((isSaveNews?: boolean) => {
-//         let content = ueditorRef?.getContent()
-//         let menuId = actionIdold || actionId
-//         dispatch({ type: 'pushData', params: { content } })
-//         let isOk = dataArr.every((item: any) => {
-//             let img = item?.thumbMediaUrl || item?.thumbUrl
-//             if (!item.title) {
-//                 message.error(`第${item.menuId}篇标题为空`)
-//                 return false
-//             }
-//             if (!img) {
-//                 message.error(`第${item.menuId}篇封面为空`)
-//                 return false
-//             }
-//             if (item?.digest?.length > 54) {
-//                 message.error(`第${item.menuId}摘要不能超过54个字`)
-//                 return false
-//             }
-//             if (item.content === '<p></p>' || !item.content) {
-//                 message.error(`第${item.menuId}篇内容为空`)
-//                 return false
-//             }
-//             // if (!item.contentSourceUrl) {
-//             //     message.error(`第${item.menuId}原文链接为空`)
-//             //     return false
-//             // }
-//             return true
-//         })
-//         if (isOk) {
-//             let news = dataArr.map((item: any) => {
-//                 return { ...item, showCoverPic: false, thumbUrl: item?.thumbUrl || item?.thumbMediaUrl }
-//             })
-//             let data: any = {
-//                 news,
-//                 folder: false,
-//                 fileType: 'news',
-//                 parentId,
-//                 belongUser,
-//                 sort
-//             }
-//             if (callback) {//假如有回调那么不请求接口保存直接执行回调函数
-//                 callback && callback(data)
-//                 dispatch({ type: 'initData' })
-//                 props.onClose()
-//                 return
-//             }
-//             if (isWx) {//执行微信接口
-//                 console.log('微信素材', props?.editId);
-//                 if (props?.editId) {//编辑走新建本地素材再同步到微信
-//                     add.run({ ...data, mpIds: selectWx }).then((res: any) => {
-//                         if (res) {
-//                             if (isSaveNews) {//走保存去群发逻辑
-//                                 console.log('新建===》保存并群发', props)
-//                                 syncId.run({ mpIds: [actionWX?.id], sysMediaId: res }).then((syncWxres: any) => {
-//                                     if (syncWxres) {
-//                                         dispatchNews({ type: 'theEdit', params: { theEdit: { content: { news }, mediaId: syncWxres, msgType: 'mpnews' } } })
-//                                         history.push(`/operatePage/news/advanced?show=true`)
-//                                         dispatch({ type: 'initData' })
-//                                         localStorage.setItem('collapsed', '0')
-//                                     }
-//                                 })
-//                             } else {
-//                                 syncId.run({ mpIds: [actionWX?.id], sysMediaId: res }).then((syncWxres: any) => {
-//                                     if (syncWxres) {
-//                                         console.log('新建==》保存')
-//                                         dispatch({ type: 'initData' })
-//                                         props.onClose()
-//                                         getWeData.refresh().then((res) => {//刷新页面
-//                                             contentDispatch({ type: 'initData', params: { data: res.records } })
-//                                         })
-//                                         localStorage.setItem('collapsed', '0')
-//                                     }
-//                                 })
-//                             }
-//                         }
-//                     })
-//                 } else {//新建
-//                     addWx.run({ mpId: actionWX?.id, mediaType: 'news', news }).then((res: any) => {
-//                         console.log(res)
-//                         if (res) {
-//                             if (isSaveNews) {//走保存去群发逻辑
-//                                 console.log('新建===》保存并群发', props)
-//                                 setId(res)
-//                                 setShowActionModal(true)
-//                             } else {
-//                                 dispatch({ type: 'initData' })
-//                                 props.onClose()
-//                                 getWeData.refresh().then((res) => {//刷新页面
-//                                     contentDispatch({ type: 'initData', params: { data: res.records } })
-//                                 })
-//                                 localStorage.setItem('collapsed', '0')
-//                             }
-//                         }
-//                     })
-//                 }
-//             } else {//执行本地
-//                 if (props?.editId) {//表示编辑
-//                     edit.run({ belongUser, fileType: 'news', folder: false, news, sysMediaId: props?.editId, sort }).then((res: any) => {
-//                         if (isSaveNews) {//走保存去群发逻辑
-//                             console.log('编辑==》保存并群发', news, dataArr)
-//                             setId(props?.editId)
-//                             setShowActionModal(true)
-//                         } else {
-//                             console.log('编辑===》保存')
-//                             dispatch({ type: 'initData' })
-//                             props.onClose()
-//                             list.refresh()
-//                             localStorage.setItem('collapsed', '0')
-//                         }
-//                     })
-//                     eidtWxlists.run({ sysMediaId: props?.editId, mpIds: selectWx || [] }).then((res) => {
-//                         console.log(res, 'eidtWxlists')
-//                         initSelectWx()
-//                     })
-//                 } else {//新建
-//                     add.run({ ...data, mpIds: selectWx }).then((res: any) => {
-//                         if (res) {
-//                             if (isSaveNews) {//走保存去群发逻辑
-//                                 console.log('新建===》保存并群发', props)
-//                                 setId(res)
-//                                 setShowActionModal(true)
-//                                 initSelectWx()
-//                             } else {
-//                                 console.log('新建==》保存')
-//                                 dispatch({ type: 'initData' })
-//                                 props.onClose()
-//                                 list.refresh()
-//                                 localStorage.setItem('collapsed', '0')
-//                                 initSelectWx()
-//                             }
-
-//                         }
-//                     })
-//                 }
-//             }
-
-//         }
-//     }, [dataArr, props?.editId, ueditorRef, actionWX, getWeData, isWx, parentId, belongUser, list, selectWx, sort])
-//     //保存并群发选择公众号后回调
-//     const saverNews = useCallback((cancel: boolean) => {
-//         setShowActionModal(false)
-//         if (!cancel) {//假如cancel为false就是保持并群发
-//             let news = dataArr.map((item: any) => { return { ...item, showCoverPic: false, thumbUrl: item?.thumbUrl || item?.thumbMediaUrl } })
-//             console.log(news, dataArr, 'dataArr,news')
-//             if (actionWX) {
-//                 if (isWx) {
-//                     // dispatchNews({ type: 'theEdit', params: { theEdit: { content: { news }, mediaId: id, msgType: 'mpnews' } } })
-//                     // history.push(`/operatePage/news/advanced?show=true`)
-//                     // dispatch({ type: 'initData' })
-//                     // localStorage.setItem('collapsed', '0')
-//                 } else {//本地素材先同步再群发
-//                     syncId.run({ mpIds: [actionWX?.id], sysMediaId: id }).then((syncWxres: any) => {
-//                         if (syncWxres) {
-//                             // dispatchNews({ type: 'theEdit', params: { theEdit: { content: { news }, mediaId: syncWxres, msgType: 'mpnews' } } })
-//                             // history.push(`/operatePage/news/advanced?show=true`)
-//                             // dispatch({ type: 'initData' })
-//                             // localStorage.setItem('collapsed', '0')
-//                         }
-//                     })
-//                 }
-//             }
-//             dispatchNews({ type: 'theEdit', params: { theEdit: { content: { news }, mediaId: id, msgType: 'mpnews' } } })
-//             history.push(`/operatePage/news/advanced?show=true`)
-//             dispatch({ type: 'initData' })
-//             localStorage.setItem('collapsed', '0')
-//         }
-//     }, [actionWX, isWx, id, syncId, dataArr])
-//     // //切换文章
-//     useEffect(() => {
-//         if (!ueditorRef?.body) {
-//             return
-//         }
-//         if (sid !== actionId) {
-//             setSid(actionId)
-//             let content = dataArr?.filter((item: { menuId: any }) => item.menuId === actionId)[0]?.content || '<p></p>'
-//             ueditorRef?.setContent(content, false)
-//         }
-//     }, [actionId, dataArr, ueditorRef?.body, sid])
-//     // 内容变化设置
-//     useEffect(() => {
-//         if (ueditorRef?.body) {
-//             dispatch({ type: 'pushData', params: { menuId: actionId, content: content || '<p></p>' } })
-//         }
-
-//     }, [ueditorRef?.body, content, actionId])
-//     //编辑回填
-//     const isOk = useCallback((ueditor) => {
-//         if (actionData) {
-//             let dataArr = actionData.dataArr?.map((item: any, index: number) => {
-//                 item.menuId = index + 1
-//                 return item
-//             })
-//             dispatch({ type: 'initData', params: { data: { ...actionData, dataArr, actionId: 1 } } })
-//             ueditor?.setContent(dataArr[0].content, false)
-//         }
-//     }, [props?.editData, ueditorRef?.setContent])
-//     return <div >
-//         <h3 style={{ height: 43, lineHeight: '43px', textAlign: 'center' }}>素材编辑</h3>
-//         <Spin spinning={loding} tip='初始化中请稍等。。。'>
-//             <Title />
-//             {/* ================================ TEditor ============================== */}
-
-//             {/* <TEditor dispatch={dispatch}  setLoding={setLoding} isOk={isOk} content={content}/> */}
-
-//              {/* ================================ UEditor ============================== */}
-//             <UEditor dispatch={dispatch}  setLoding={setLoding} isOk={isOk} setContent={setContent} isShowWx={isShowWx}/>
-//             <Space className={style.btn}>
-//                 <Button onClick={() => { seve() }} type='primary' loading={add?.loading || edit?.loading || addWx?.loading}>保存素材</Button>
-//                 {syncNews && !callback && <Button onClick={() => { seve(true) }} type='primary' loading={add?.loading || addWx?.loading || edit?.loading || syncId?.loading}>保存并群发</Button>}
-//                 <Button onClick={() => { props.onClose(); initSelectWx() }} >取消</Button>
-//             </Space>
-//             <ActionModal visible={showActionModal} hideWx={saverNews} />
-//         </Spin>
-//     </div>
-// }
-

+ 0 - 22
src/components/Editor/Button.js

@@ -1,22 +0,0 @@
-import React from 'react'
-
-const buttonStyle = {
-  height: '24px',
-  fontWeight: '500',
-  cursor: 'pointer',
-  padding: '0 15px',
-  fontSize: '12px',
-  color: 'rgba(0,0,0,.65)',
-  border: '1px solid #d9d9d9',
-  marginLeft: '10px',
-}
-
-class Button extends React.PureComponent {
-  render() {
-    let {style, children, onClick} = this.props
-    let mergedStyle = {...buttonStyle, ...style}
-    return <button style={mergedStyle} onClick={onClick}>{children}</button>
-  }
-}
-
-export default Button

+ 0 - 25
src/components/Editor/Input.js

@@ -1,25 +0,0 @@
-import React from 'react'
-
-const inputStyle = {
-  height: '18px',
-  width: '72px',
-  boxSizing: 'content-box',
-  fontSize: '12px',
-  lineHeight: '18px',
-  color: 'rgba(0,0,0,.65)',
-  backgroundColor: '#fff',
-  border: '1px solid #d9d9d9',
-  borderRadius: '4px',
-  padding: '1px 3px',
-  margin: '0 10px',
-}
-
-class Input extends React.PureComponent {
-  render() {
-    let {type, value, onChange, style} = this.props
-    let mergedStyle = {...inputStyle, ...style}
-    return <input style={mergedStyle} type={type} value={value} onChange={onChange} />
-  }
-}
-
-export default Input

+ 0 - 24
src/components/Editor/Label.js

@@ -1,24 +0,0 @@
-import React from 'react'
-
-const labelStyle = {
-  display: 'block',
-  width: '165px',
-  color: 'rgba(0, 0, 0, 0.65)',
-  marginRight: '20px',
-  marginBottom: '10px',
-}
-
-const labelName = {
-  display: 'inline-block',
-  width: '50px',
-}
-
-class Label extends React.PureComponent {
-  render() {
-    let {style, children, name} = this.props
-    let mergedStyle = {...labelStyle, ...style}
-    return <label style={mergedStyle}><span style={labelName}>{name}</span>{children}</label>
-  }
-}
-
-export default Label

+ 0 - 101
src/components/Editor/Link.js

@@ -1,101 +0,0 @@
-import Input from './Input'
-import React from 'react'
-
-let inputStyle = {
-  width: '300px',
-}
-let spanStyle = {
-  fontSize: '14px',
-  color: 'rgba(0, 0, 0, 0.65)',
-  display: 'inline-block',
-  width: '80px',
-}
-let formItmeStyle = {
-  marginBottom: '10px',
-}
-
-class Link extends React.Component {
-  state = {
-    text: '',
-    link: '',
-    title: '',
-    newTab: false,
-    showTips: false,
-  }
-
-  hasProtocol = link => {
-    if (link.match(/^http:|https:/) || link.match(/^\/\//)) {
-      return true
-    }
-    return false
-  }
-
-  generateHtml = () => {
-    let {text, link, title, newTab} = this.state
-
-    if (link) {
-      let html = ''
-
-      if (!this.hasProtocol(link)) {
-        link = 'http://' + link
-      }
-
-      html += `<a href="${link}" target=${newTab ? '_blank' : '_self'} title="${title}">${text || link}</a>`
-
-      return html
-    }
-  }
-
-  changeConfig = (e, type) => {
-    let value = e.target.value
-    let boolType = ['newTab']
-    if (boolType.indexOf(type) !== -1) {
-      value = !!value
-    }
-
-    if (type == 'link') {
-      if (!this.hasProtocol(value)) {
-        this.setState({
-          showTips: true,
-        })
-      } else {
-        this.setState({
-          showTips: false,
-        })
-      }
-    }
-    if (type == 'newTab') {
-      return this.setState({newTab: !this.state.newTab})
-    }
-    this.setState({[type]: value}, () => {
-      this.props.onChange && this.props.onChange(this.generateHtml())
-    })
-  }
-
-  render() {
-    let {text, link, title, newTab, showTips} = this.state
-    return (
-      <form>
-        <div style={formItmeStyle}>
-          <span style={spanStyle}>文本内容:</span>
-          <Input type='text' style={inputStyle} value={text} onChange={e => this.changeConfig(e, 'text')} />
-        </div>
-        <div style={formItmeStyle}>
-          <span style={spanStyle}>链接地址:</span>
-          <Input type='text' style={inputStyle} value={link} onChange={e => this.changeConfig(e, 'link')} />
-        </div>
-        <div style={formItmeStyle}>
-          <span style={spanStyle}>标题:</span>
-          <Input type='text' style={inputStyle} value={title} onChange={e => this.changeConfig(e, 'title')} />
-        </div>
-        <div style={formItmeStyle}>
-          <span style={{color: 'rgba(0, 0, 0, 0.65)', fontSize: '14px'}}>是否在新窗口打开:</span>
-          <input type='checkbox' checked={newTab} onChange={e => this.changeConfig(e, 'newTab')} />
-        </div>
-        {showTips && <p style={{fontSize: '14px', color: 'red'}}>您输入的超链接中不包含http等协议名称,默认将为您添加http://前缀</p>}
-      </form>
-    )
-  }
-}
-
-export default Link

+ 0 - 57
src/components/Editor/Modal.js

@@ -1,57 +0,0 @@
-import Button from './Button'
-import Dialog from 'rc-dialog'
-import PropTypes from 'prop-types'
-import React from 'react'
-import 'rc-dialog/assets/index.css'
-
-class Modal extends React.PureComponent {
-  static propTypes = {
-    title: PropTypes.string,
-    visible: PropTypes.bool,
-    beforeClose: PropTypes.func,
-    onClose: PropTypes.func,
-    onConfirm: PropTypes.func,
-  }
-
-  static defaultProps = {
-    title: '',
-    visible: false,
-    zIndex: 1050,
-    alignStyle: 'top',
-    extendControls: [],
-    debug: false,
-  }
-
-  closeModal = () => {
-    this.props.beforeClose && this.props.beforeClose()
-    this.props.onClose()
-  }
-
-  onConfirm = () => {
-    this.props.onConfirm && this.props.onConfirm()
-    this.closeModal()
-  }
-
-  render() {
-    let {title, visible, zIndex, alignStyle} = this.props
-
-    return (
-      <Dialog
-        title={title}
-        onClose={this.closeModal}
-        visible={visible}
-        footer={[
-          <Button key='close' onClick={this.closeModal}>取消</Button>,
-          <Button key='insert' onClick={this.onConfirm}>确认</Button>,
-        ]}
-        animation='zome'
-        maskAnimation='fade'
-        zIndex={zIndex}
-        style={alignStyle === 'middle' ? {top: '50%', transform: 'translateY(-50%)'} : {}}>
-        {this.props.component}
-      </Dialog>
-    )
-  }
-}
-
-export default Modal

+ 0 - 472
src/components/Editor/ReactUeditor.js

@@ -1,472 +0,0 @@
-import Link from './Link';
-import Modal from './Modal';
-import PropTypes from 'prop-types';
-import React from 'react';
-import VideoUploader from './VideoUploader';
-import AudioUploader from './AudioUploader';
-import * as utils from './utils';
-
-const MODE = {
-  INTERNAL_MODAL: 'internal-modal',
-  MODAL: 'modal',
-  NORMAL: 'normal',
-};
-
-function isModalMode(mode) {
-  return mode === MODE.INTERNAL_MODAL || mode === MODE.MODAL;
-}
-
-const simpleInsertCodeIcon =
-  'data:img/jpg;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAB9klEQVRYR+2Wy' +
-  '23CQBCGZxwUASdKgA7IIdIukhF0QCoI6YAS6CB0EDpIOgjCEbs3nApCB+EEKFI80ToYgR/7IEhIEb4hvPN/8/jHi3DmB8+sDxeA/1GBdosNi' +
-  'TAMhHhxnamTVMDnfAEAo0CI0ckBOs1mbRKGy6LArdZtswSl+VdEDSmlAtk9prPqRW0FfMb66OGjt1o3iiB8zgcAMAiEqKfFo0p5QQSDQMpxU' +
-  'QKFAFvxJ4roQRfA52yCgOFUCAVy8NjEyAWwOaiUVImjauWTCO6KBtAUKwNgOrCfos95DxGepzNh08rcah4cdBFXID5nY0CsBTPRM01/Uewdg' +
-  'Ku4EmxztiTAoa398jRigGPEdfbTVSOthUkfTdOeDrrdfv20/UytSCeMKhAQ3HvrzY1u4WQs1mIhEk7y7GeCiN1TKc8J8R3Vj+9qWXmZvNW6a' +
-  'wOR2C+KqPsm5cQkmFlQ1corAeHVatOJZ8AVIu4jwmgqZO0v4irZnQtcIFzslwBuq7bLPKn0wR6whYjtZ9jxurLvtzmzwUwQrvYryjwBzF2hO' +
-  'ojYfgC9YCabpv6bxLWf4yII39J+NuLG+8BvkPJgOpND9TJjrH7t4Yet/VS1vNVmpLO205XsWPvpWuUGoD6/AJ1jtp/zjcg0YKf636kCpxLdj' +
-  '3MBOHsFfgBLLaBN8r49lAAAAABJRU5ErkJggg==';
-const uploadAudioIcon =
-  'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACBUlEQVRYR+1VwXHbMBC8' +
-  'qyBxBXI6cCqwUkEOFUSuIHYFliuwUoGVCrAdWOlA6UCuIOpgPashNRQIOtJkHH2ID2eIA25vD7vndublZ85vI4CRgZGBkxmIiI9mdm9mMzNb' +
-  'AHgYknJEzM3sA4C7oZiTAEREmNmTuwvEi5lNSH4GsK4liIiFu38nuQRwU4s5CkBTtRILwAvJWzPbuvszyS8AVhFxZWbXAH50E0XE0t2/kbwB' +
-  'sCxBVAFExKW7TxRMUhfPVTVJXT4HsI2IaQHg1t0fFQNAAPcrpbQhqVZc/BWAaHb3XASq6pkqbf+XAPQ/pQQz+9qy0omdufsTyQRAMfvVYyCl' +
-  'pCSXLc1N5FpVF9QeMKA9tcrd/5D8CUCPdLc6/3vsDAGwnPP0rUFVY6BhYUVyAuBT0QYVsC7vfQ8AuzbknA/ubpjtFfYeANTCq5yzpNp9iJLq' +
-  '9n8wIKpXOWdJtguA5dvQZpUB9dDdd1pXEMnfRz5CyfW+1HyrrJoX9ADUZEhyY2YykkEZds79KmnuyPOiLGTIiNQ/GZCWTGkhTyep78OAEck/' +
-  'Zo1f7CXbUUtPgtUW1KTX6Fg2KpPR5fL1AyseONfODhnZtKz+aAAdQ1GVYkFDaOPuMqzBYdRITxZeTX4ygNbVmtkgujWONXKrqxliVqu8PXDU' +
-  'NHzLEf91bwQwMjAycHYGXgGLbI8w70amwwAAAABJRU5ErkJggg==';
-
-class ReactUeditor extends React.Component {
-  constructor(props) {
-    super(props);
-    this.content = props.value || ''; // 存储编辑器的实时数据,用于传递给父组件
-    this.ueditor = null;
-    this.isContentChangedByWillReceiveProps = false;
-    this.tempfileInput = null;
-    this.containerID = 'reactueditor' + Math.random().toString(36).substr(2);
-    this.fileInputID = 'fileinput' + Math.random().toString(36).substr(2);
-    this.pasteImageAmount = 0;
-    this.state = {
-      videoSource: '',
-      audioSource: '',
-      extendControls: this.props.extendControls ? this.props.extendControls : [],
-      videoHtml: '',
-      audioHtml: '',
-      pluginsWithCustomRender: [],
-    };
-  }
-
-  static propTypes = {
-    value: PropTypes.string,
-    ueditorPath: PropTypes.string.isRequired,
-    plugins: PropTypes.array,
-    onChange: PropTypes.func,
-    uploadImage: PropTypes.func,
-    getRef: PropTypes.func,
-    multipleImagesUpload: PropTypes.bool,
-    onReady: PropTypes.func,
-    pasteImageStart: PropTypes.func,
-    handlePasteImage: PropTypes.func,
-    pasteImageDone: PropTypes.func,
-    extendControls: PropTypes.array,
-    debug: PropTypes.bool,
-  };
-
-  static defaultProps = {
-    value: '',
-    multipleImagesUpload: false,
-    extendControls: [],
-    debug: false,
-  };
-
-  componentDidMount() {
-    let { ueditorPath } = this.props;
-    if (!window.UE && !window.UE_LOADING_PROMISE) {
-      window.UE_LOADING_PROMISE = this.createScript(ueditorPath + '/ueditor.config.js').then(() => {
-        return this.createScript(ueditorPath + '/ueditor.all.min.js')
-      });
-    }
-    window.UE_LOADING_PROMISE.then(() => {
-      this.tempfileInput = document.getElementById(this.fileInputID);
-      this.initEditor();
-    });
-  }
-
-  /**
-   * 这里存在两种情况会改变编辑器的内容:
-   * 1. 父组件初始化传递的 value。父组件 value 的获取是异步的,因此会触发一次 componentWillReceiveProps,这种情况不需要将更新再通知父组件
-   * 2. 用户对编辑器进行编辑
-   */
-  componentWillReceiveProps(nextProps) {
-    if ('value' in nextProps && this.props.value !== nextProps.value) {
-      this.isContentChangedByWillReceiveProps = true;
-      this.content = nextProps.value;
-      if (this.ueditor) {
-        this.ueditor.ready(() => {
-          this.ueditor.setContent(nextProps.value);
-        });
-      }
-    }
-  }
-
-  componentWillUnmount() {
-    if (this.ueditor) {
-      this.ueditor.destroy();
-    }
-  }
-
-  createScript = (url) => {
-    let scriptTags = window.document.querySelectorAll('script');
-    let len = scriptTags.length;
-    let i = 0;
-    let _url = window.location.origin + url;
-    return new Promise((resolve, reject) => {
-      for (i = 0; i < len; i++) {
-        var src = scriptTags[i].src;
-        if (src && src === _url) {
-          scriptTags[i].parentElement.removeChild(scriptTags[i]);
-        }
-      }
-
-      let node = document.createElement('script');
-      node.src = url;
-      node.onload = resolve;
-      document.body.appendChild(node);
-    });
-  };
-
-  registerInternalPlugin(pluginName) {
-    switch (pluginName) {
-      case 'uploadImage':
-        return this.registerImageUpload();
-      case 'insertCode':
-        return this.registerSimpleInsertCode();
-      case 'uploadVideo':
-        return this.registerUploadVideo();
-      case 'uploadAudio':
-        return this.registerUploadAudio();
-      case 'insertLink':
-        return this.registerLink();
-      default:
-        return;
-    }
-  }
-
-  registerPlugin(plugin) {
-    let name = Math.random().toString(36).slice(2);
-    if (window.UE.registerUI) {
-      window.UE.registerUI(
-        name,
-        (ueditor, uiName) => {
-          let config = plugin(ueditor);
-          if (!config.mode) {
-            config.mode = MODE.MODAL;
-          }
-          var btn = new window.UE.ui.Button({
-            name: uiName,
-            title: config.menuText,
-            cssRules: config.cssRules || '',
-            onclick: isModalMode(config.mode)
-              ? () => {
-                  this.setState({ [this.getVisibleName(name)]: true });
-                  config.onIconClick && config.onIconClick();
-                }
-              : config.onIconClick,
-          });
-          if (config.render) {
-            this.setState((prevState) => ({
-              pluginsWithCustomRender: [...prevState.pluginsWithCustomRender, { name, ...config }],
-            }));
-          }
-          return btn;
-        },
-        undefined,
-        this.containerID,
-      );
-    }
-  }
-
-  registerImageUpload = () =>
-    this.registerPlugin(() => ({
-      menuText: '图片上传',
-      cssRules: 'background-position: -726px -77px;',
-      mode: MODE.NORMAL,
-      onIconClick: () => {
-        this.tempfileInput.click();
-      },
-    }));
-
-  registerSimpleInsertCode = () =>
-    this.registerPlugin((ueditor) => ({
-      menuText: '插入代码',
-      cssRules:
-        'background: url(' +
-        simpleInsertCodeIcon +
-        ') !important; background-size: 20px 20px !important;',
-      mode: MODE.NORMAL,
-      onIconClick: () => {
-        ueditor.focus();
-        ueditor.execCommand('insertcode');
-      },
-    }));
-
-  registerUploadVideo = () => {
-    let { uploadVideo, progress } = this.props;
-    return this.registerPlugin((ueditor) => ({
-      menuText: '上传视频',
-      cssRules: 'background-position: -320px -20px;',
-      mode: MODE.INTERNAL_MODAL,
-      render: () => (
-        <VideoUploader upload={uploadVideo} progress={progress} onChange={this.videoChange} />
-      ),
-      onConfirm: () => {
-        ueditor.execCommand('insertparagraph');
-        ueditor.execCommand('inserthtml', this.state.videoHtml, true);
-        ueditor.execCommand('insertparagraph');
-        ueditor.execCommand('insertparagraph');
-      },
-    }));
-  };
-
-  registerUploadAudio = () => {
-    let { uploadAudio, progress } = this.props;
-    return this.registerPlugin((ueditor) => ({
-      menuText: '上传音频',
-      cssRules:
-        'background: url(' +
-        uploadAudioIcon +
-        ') !important; background-size: 20px 20px !important;',
-      mode: MODE.INTERNAL_MODAL,
-      render: () => (
-        <AudioUploader upload={uploadAudio} progress={progress} onChange={this.audioChange} />
-      ),
-      onConfirm: () => {
-        ueditor.execCommand('insertparagraph');
-        ueditor.execCommand('inserthtml', this.state.audioHtml, true);
-        ueditor.execCommand('insertparagraph');
-        ueditor.execCommand('insertparagraph');
-      },
-    }));
-  };
-
-  registerLink = () =>
-    this.registerPlugin((ueditor) => ({
-      menuText: '超链接',
-      cssRules: 'background-position: -504px 0px;',
-      mode: MODE.INTERNAL_MODAL,
-      render: () => <Link onChange={this.linkChange} />,
-      onConfirm: () => {
-        ueditor && ueditor.execCommand('inserthtml', this.state.linkHtml, true);
-      },
-    }));
-
-  videoChange = (videoHtml) => {
-    this.setState({ videoHtml });
-  };
-
-  audioChange = (audioHtml) => {
-    this.setState({ audioHtml });
-  };
-
-  linkChange = (linkHtml) => {
-    this.setState({ linkHtml });
-  };
-
-  uploadImage = (e) => {
-    let { uploadImage } = this.props;
-    if (uploadImage) {
-      let promise = uploadImage(e);
-      if (!!promise && typeof promise.then == 'function') {
-        promise.then((imageUrl) => {
-          if (imageUrl instanceof Array) {
-            imageUrl.forEach((url) => {
-              this.insertImage(url);
-            });
-          } else {
-            this.insertImage(imageUrl);
-          }
-        });
-      }
-    }
-    this.tempfileInput.value = '';
-  };
-
-  insertImage = (imageUrl) => {
-    if (this.ueditor) {
-      this.ueditor.focus();
-      this.ueditor.execCommand('inserthtml', '<img src="' + imageUrl + '" />');
-    }
-  };
-
-  handlePasteImage = () => {
-    let { pasteImageStart, handlePasteImage, pasteImageDone } = this.props;
-    if (!handlePasteImage) return;
-
-    let html = this.ueditor.getContent();
-    let images = utils.extractImageSource(html);
-
-    if (Object.prototype.toString.call(images) !== '[object Array]') return;
-
-    this.pasteImageAmount += images.length;
-    pasteImageStart && pasteImageStart(this.pasteImageAmount);
-    images.forEach((src) => {
-      let promise = handlePasteImage(src);
-      if (!!promise && typeof promise.then == 'function') {
-        promise.then((newSrc) => {
-          --this.pasteImageAmount;
-          if (this.pasteImageAmount === 0) {
-            pasteImageDone && pasteImageDone();
-          }
-          let newHtml = utils.replaceImageSource(this.ueditor.getContent(), src, newSrc);
-          this.ueditor.setContent(newHtml);
-        });
-      }
-    });
-  };
-
-  getVisibleName = (name) => {
-    return name + 'VisibleModal';
-  };
-
-  getRegisterUIName = (name) => {
-    return `${name}-${this.containerID}`;
-  };
-
-  initEditor = () => {
-    if (!window.UE.getEditor) {
-      return;
-    }
-    const { config, plugins, onChange, value, getRef, onReady } = this.props;
-
-    if (plugins && Array.isArray(plugins)) {
-      plugins.forEach((plugin) => {
-        if (typeof plugin === 'string') {
-          return this.registerInternalPlugin(plugin);
-        } else {
-          return this.registerPlugin(plugin);
-        }
-      });
-    }
-
-    // 即将废弃
-    this.state.extendControls.forEach((control) => {
-      window.UE.registerUI(
-        this.getRegisterUIName(control.name),
-        (editor, uiName) => {
-          var btn = new window.UE.ui.Button({
-            name: uiName,
-            title: control.menuText,
-            cssRules: control.cssRules ? control.cssRules : '',
-            onclick: () => {
-              this.setState({ [this.getVisibleName(control.name)]: true });
-            },
-          });
-          return btn;
-        },
-        undefined,
-        this.containerID,
-      );
-    });
-
-    this.ueditor = config
-      ? window.UE.getEditor(this.containerID, config)
-      : window.UE.getEditor(this.containerID);
-    this.ueditor._react_ref = this;
-    this.ueditor.ready(() => {
-      this.ueditor.addListener('contentChange', () => {
-        // 由 componentWillReceiveProps 导致的 contentChange 不需要通知父组件
-        if (this.isContentChangedByWillReceiveProps) {
-          this.isContentChangedByWillReceiveProps = false;
-        } else {
-          this.content = this.ueditor.getContent();
-          onChange && onChange(this.content);
-        }
-      });
-
-      this.ueditor.addListener('afterpaste', () => {
-        this.handlePasteImage();
-      });
-
-      if (this.isContentChangedByWillReceiveProps) {
-        this.isContentChangedByWillReceiveProps = false;
-        this.ueditor.setContent(this.content);
-      } else {
-        this.ueditor.setContent(value);
-      }
-
-      onReady && onReady(this.ueditor);
-    });
-    getRef && getRef(this.ueditor);
-  };
-
-  render() {
-    let { extendControls } = this.state;
-    let { multipleImagesUpload } = this.props;
-
-    return (
-      <div>
-        <script id={this.containerID} name={this.containerID} type="text/plain" />
-        <input
-          type="file"
-          id={this.fileInputID}
-          onChange={this.uploadImage}
-          style={{ visibility: 'hidden', width: 0, height: 0, margin: 0, padding: 0, fontSize: 0 }}
-          multiple={multipleImagesUpload}
-        />
-        {this.state.pluginsWithCustomRender.map((plugin) => {
-          const visible = !!this.state[this.getVisibleName(plugin.name)];
-          const onClose = () => {
-            if (isModalMode(plugin.mode)) {
-              this.setState({ [this.getVisibleName(plugin.name)]: false });
-            }
-            plugin.onClose && typeof plugin.onClose === 'function' && plugin.onClose();
-          };
-          if (plugin.mode === MODE.INTERNAL_MODAL) {
-            return (
-              <Modal
-                key={plugin.name}
-                title={plugin.title || plugin.menuText}
-                zIndex={plugin.zIndex}
-                alignStyle={plugin.alignStyle}
-                visible={visible}
-                beforeClose={plugin.beforeClose}
-                onClose={onClose}
-                onConfirm={plugin.onConfirm}
-                component={plugin.render()}
-              />
-            );
-          } else if (plugin.mode === MODE.MODAL) {
-            return <div key={plugin.name}>{plugin.render(visible, onClose)}</div>;
-          } else if (plugin.mode === MODE.NORMAL) {
-            return <div key={plugin.name}>{plugin.render()}</div>;
-          }
-        })}
-        {
-          // 即将废弃
-          extendControls.map((control) => (
-            <Modal
-              key={control.name + this.containerID}
-              name={control.name}
-              menuText={control.menuText}
-              title={control.title}
-              zIndex={control.zIndex}
-              alignStyle={control.alignStyle}
-              visible={
-                this.state[this.getVisibleName(control.name)]
-                  ? this.state[this.getVisibleName(control.name)]
-                  : false
-              }
-              beforeClose={control.beforeClose}
-              onClose={() => {
-                this.setState({ [this.getVisibleName(control.name)]: false });
-              }}
-              onConfirm={control.onConfirm}
-              component={control.component}
-            />
-          ))
-        }
-      </div>
-    );
-  }
-}
-
-export default ReactUeditor;

+ 0 - 22
src/components/Editor/Select.js

@@ -1,22 +0,0 @@
-import React from 'react'
-
-const selectStyle = {
-  height: '22px',
-  width: '80px',
-  fontSize: '14px',
-  color: 'rgba(0,0,0,.65)',
-  backgroundColor: '#fff',
-  border: '1px solid #d9d9d9',
-  borderRadius: '4px',
-  marginLeft: '10px',
-}
-
-class Select extends React.PureComponent {
-  render() {
-    let {style, children, defaultValue, onChange} = this.props
-    let mergedStyle = {...selectStyle, ...style}
-    return <select style={mergedStyle} defaultValue={defaultValue} onChange={onChange}>{children}</select>
-  }
-}
-
-export default Select

+ 0 - 45
src/components/Editor/Tag.js

@@ -1,45 +0,0 @@
-import React from 'react'
-
-const tagStyle = {
-  wrapper: {
-    display: 'inline-block',
-    lineHeight: '22px',
-    height: '22px',
-    padding: '0 0 0 8px',
-    borderRadius: '4px',
-    border: '1px solid #e9e9e9',
-    backgroundColor: '#f3f3f3',
-    fontSize: '13px',
-    color: 'rgba(0, 0, 0, 0.65)',
-    margin: '5px',
-  },
-  text: {
-    display: 'inline-block',
-    maxWidth: '500px',
-    overflow: 'hidden',
-    textOverflow: 'ellipsis',
-    whiteSpace: 'nowrap',
-  },
-  icon: {
-    display: 'inline-block',
-    width: '25px',
-    textAlign: 'center',
-    float: 'right',
-    cursor: 'pointer',
-  },
-}
-
-class Tag extends React.PureComponent {
-  render() {
-    let {value, index, onRemove, style, key} = this.props
-    let mergedStyle = {...tagStyle.wrapper, ...style}
-    return (
-      <span style={mergedStyle} key={key}>
-        <span style={tagStyle.text}>{value}</span>
-        <i style={tagStyle.icon} onClick={() => { onRemove(index) }}>×</i>
-      </span>
-    )
-  }
-}
-
-export default Tag

+ 0 - 38
src/components/Editor/Upload.js

@@ -1,38 +0,0 @@
-import React from 'react'
-
-const uploadStyle = {
-  height: '26px',
-  width: '80px',
-  display: 'inline-block',
-  boxSizing: 'border-box',
-  lineHeight: '25px',
-  textAlign: 'center',
-  borderRadius: '4px',
-  border: '1px solid transparent',
-  fontSize: '12px',
-  fontWeight: '500',
-  color: '#fff',
-  backgroundColor: '#108ee9',
-  cursor: 'pointer',
-  marginLeft: '10px',
-}
-
-class Upload extends React.PureComponent {
-  onInputChange = e => {
-    let props = this.props
-    if (props.onChange) {
-      props.onChange(e)
-    }
-    e.target.value = ''
-  }
-
-  render() {
-    return (
-      <label style={uploadStyle}>直接上传
-        <input type='file' onChange={this.onInputChange} style={{display: 'none'}} />
-      </label>
-    )
-  }
-}
-
-export default Upload

+ 0 - 247
src/components/Editor/VideoUploader.js

@@ -1,247 +0,0 @@
-import Button from './Button'
-import Input from './Input'
-import Label from './Label'
-import React from 'react'
-import Select from './Select'
-import Tag from './Tag'
-import Upload from './Upload'
-
-const style = {
-  paramsConfig: {
-    paddingBottom: '10px',
-    borderBottom: '1px solid rgb(217, 217, 217)',
-    display: 'flex',
-    flexWrap: 'wrap',
-  },
-  insertTitle: {
-    fontSize: '14px',
-    paddingRight: '10px',
-    color: 'rgba(0, 0, 0, 0.65)',
-  },
-  sourceList: {
-    margin: '10px 10px 10px 0',
-    border: '1px dashed rgb(217, 217, 217)',
-    borderRadius: '4px',
-  },
-  configTitle: {
-    display: 'block',
-    fontSize: '14px',
-    margin: '10px 0',
-    paddingRight: '10px',
-    color: 'rgba(0, 0, 0, 0.65)',
-  },
-  warnInfo: {
-    display: 'inline-block',
-    width: '100%',
-    margin: '5px',
-    textAlign: 'center',
-    fontSize: '12px',
-    color: '#f04134',
-  },
-}
-
-const linkRegx = /^https?:\/\/(([a-zA-Z0-9_-])+(\.)?)*(:\d+)?(\/((\.)?(\?)?=?&?[a-zA-Z0-9,_-](\?)?)*)*$/i
-
-let timeoutInstance = null
-
-class UploadModal extends React.PureComponent {
-  state = {
-    sources: [],
-    currentSource: '',
-    width: 400,
-    height: 400,
-    controls: 'true',
-    autoplay: 'false',
-    muted: 'false',
-    loop: 'false',
-    poster: '',
-    name: '',
-    author: '',
-    errorMsg: '',
-    errorMsgVisible: false,
-  }
-
-  updateCurrentSource = e => {
-    this.setState({currentSource: e.target.value})
-  }
-
-  addSource = () => {
-    let {sources, currentSource} = this.state
-    let newsources = sources.concat([currentSource])
-    if (currentSource === '') {
-      this.showErrorMsg('链接不能为空')
-    } else if (!linkRegx.test(currentSource)) {
-      this.showErrorMsg('非法的链接')
-    } else if (sources.indexOf(currentSource) !== -1) {
-      this.showErrorMsg('链接已存在')
-    } else {
-      this.setState({
-        sources: newsources,
-        currentSource: '',
-      }, () => {
-        this.props.onChange && this.props.onChange(this.generateHtml())
-      })
-    }
-  }
-
-  removeSource = index => {
-    let sourcesCopy = this.state.sources.concat([])
-    sourcesCopy.splice(index, 1)
-    this.setState({sources: sourcesCopy})
-  }
-
-  upload = e => {
-    let {upload} = this.props
-
-    if (!upload) return
-
-    upload(e).then(url => {
-      this.setState({currentSource: url})
-    }).catch(e => {
-      e.constructor === Error ? this.showErrorMsg(e.message) : this.showErrorMsg(e)
-    })
-  }
-
-  showErrorMsg = msg => {
-    this.setState({errorMsg: msg, errorMsgVisible: true})
-    clearTimeout(timeoutInstance)
-    timeoutInstance = setTimeout(() => {
-      this.setState({errorMsg: '', errorMsgVisible: false})
-    }, 4000)
-  }
-
-  getFileType = (fileUrl, mediaType) => {
-    let type = fileUrl.match(/\.(\w+)$/, 'i')
-    return type ? type[1].toLowerCase() : 'mp4'
-  }
-
-  generateHtml = () => {
-    let {sources, width, height, controls, autoplay, muted, loop} = this.state
-    let len = sources.length
-
-    if (len > 0) {
-      let html = ''
-      let attr = ''
-
-      attr += controls === 'false' ? '' : ' controls="true" '
-      attr += autoplay === 'false' ? '' : ' autoplay="true" '
-      attr += loop === 'false' ? '' : ' loop="true" '
-
-      attr += muted === 'false' ? '' : ' muted '
-      if (len === 1) {
-        html = `<video src="${sources[0]}" width="${width}" height="${height}" ${attr}>你的浏览器不支持 video 标签</video>`
-      } else {
-        html = `<video width="${width}" height="${height}" ${attr}>`
-        sources.forEach(source => {
-          html += `<source src=${source} type="video/${this.getFileType(source, 'video')}"}>`
-        })
-        html += '你的浏览器不支持 video 标签</video>'
-      }
-
-      return html + '<p></p>'
-    }
-  }
-
-  changeConfig = (e, type) => {
-    console.log('change config')
-    let value = e.target.value
-    let boolType = ['controls', 'autoplay', 'muted', 'loop']
-    if (type === 'width' || type === 'height') {
-      if (isNaN(parseInt(value))) {
-        value = parseInt(value)
-      }
-    } else if (boolType.indexOf(type) !== -1) {
-      value = !!value
-    }
-    this.setState({[type]: value}, () => {
-      this.props.onChange && this.props.onChange(this.generateHtml())
-    })
-  }
-
-  renderSourceList = () => {
-    let {sources} = this.state
-    if (sources.length > 0) {
-      let list = sources.map((source, index) => {
-        return <Tag value={source} key={source} index={index} onRemove={this.removeSource} />
-      })
-      return list
-    } else {
-      return <span style={style.warnInfo}>至少添加一个链接</span>
-    }
-  }
-
-  renderVideoConfig = () => {
-    let {width, height, controls, autoplay, muted, loop} = this.state
-    return (
-      <form style={style.paramsConfig}>
-        <Label name='width'>
-          <Input type='number' defaultValue={width} onChange={e => { this.changeConfig(e, 'width') }} />
-        </Label>
-        <Label name='height'>
-          <Input type='number' defaultValue={height} onChange={e => { this.changeConfig(e, 'height') }} />
-        </Label>
-        <Label name='controls'>
-          <Select defaultValue={controls} onChange={e => { this.changeConfig(e, 'controls') }}>
-            <option value='true'>true</option>
-            <option value='false'>false</option>
-          </Select>
-        </Label>
-        <Label name='autoplay'>
-          <Select defaultValue={autoplay} onChange={e => { this.changeConfig(e, 'autoplay') }}>
-            <option value='true'>true</option>
-            <option value='false'>false</option>
-          </Select>
-        </Label>
-        <Label name='muted'>
-          <Select defaultValue={muted} onChange={e => { this.changeConfig(e, 'muted') }}>
-            <option value='true'>true</option>
-            <option value='false'>false</option>
-          </Select>
-        </Label>
-        <Label name='loop'>
-          <Select defaultValue={loop} onChange={e => { this.changeConfig(e, 'loop') }}>
-            <option value='true'>true</option>
-            <option value='false'>false</option>
-          </Select>
-        </Label>
-      </form>
-    )
-  }
-
-  render() {
-    let {currentSource, errorMsg, errorMsgVisible} = this.state
-    let {progress} = this.props
-
-    return (
-      <div>
-        <div>
-          <span style={style.insertTitle}>插入链接</span>
-          <Input style={{width: '300px'}} type='text' value={currentSource} onChange={this.updateCurrentSource} />
-          <Button onClick={this.addSource}>添加</Button>
-          <Upload onChange={this.upload} />
-        </div>
-        <div>
-          <span style={{...style.warnInfo, display: progress && progress !== -1 ? 'block' : 'none'}}>
-            {progress}%
-          </span>
-          <span style={{...style.warnInfo, display: errorMsgVisible ? 'block' : 'none'}}>{errorMsg}</span>
-        </div>
-        <div style={style.sourceList}>
-          {this.renderSourceList()}
-        </div>
-        <span style={style.configTitle}>参数配置</span>
-        {this.renderVideoConfig()}
-        <div style={{textAlign: 'center', padding: '20px 10px 0 10px'}}>
-          {
-            <video src={currentSource} controls='controls'
-              style={{width: '400px', height: '250px', backgroundColor: '#000'}}>
-              你的浏览器不支持 video 标签
-            </video>
-          }
-        </div>
-      </div>
-    )
-  }
-}
-
-export default UploadModal

+ 0 - 1
src/components/Editor/index.d.ts

@@ -1 +0,0 @@
-declare module 'ifanrx-react-ueditor'

+ 0 - 3
src/components/Editor/index.js

@@ -1,3 +0,0 @@
-import ReactUeditor from './ReactUeditor'
-
-export default ReactUeditor

+ 0 - 20
src/components/Editor/utils.js

@@ -1,20 +0,0 @@
-export function extractImageSource(html) {
-  let imgReg = /<img.*?(?:>|\/>)/gi
-  let srcReg = /src=['"]?([^'"]*)['"]?/i
-  let arr = html.match(imgReg)
-  let imgSrc = []
-
-  if (!arr) return html
-
-  for (let i = 0; i < arr.length; i++) {
-    let src = arr[i].match(srcReg)[1]
-    src && imgSrc.push(src)
-  }
-  return imgSrc
-}
-
-export function replaceImageSource(html, origin, target) {
-  return html.replace(/<img.*?src="(.*?)".*?\/?>/ig, function(img, src) {
-    return src === origin ? img.replace(src, target) : img
-  })
-}

+ 0 - 125
src/components/NoticeIcon/NoticeIcon.tsx

@@ -1,125 +0,0 @@
-import { BellOutlined } from '@ant-design/icons';
-import { Badge, Spin, Tabs } from 'antd';
-import useMergeValue from 'use-merge-value';
-import React from 'react';
-import classNames from 'classnames';
-import NoticeList, { NoticeIconTabProps } from './NoticeList';
-import HeaderDropdown from '../HeaderDropdown';
-import styles from './index.less';
-
-const { TabPane } = Tabs;
-
-export interface NoticeIconProps {
-  count?: number;
-  bell?: React.ReactNode;
-  className?: string;
-  loading?: boolean;
-  onClear?: (tabName: string, tabKey: string) => void;
-  onItemClick?: (item: any, tabProps: NoticeIconTabProps) => void;
-  onViewMore?: (tabProps: NoticeIconTabProps, e: MouseEvent) => void;
-  onTabChange?: (tabTile: string) => void;
-  style?: React.CSSProperties;
-  onPopupVisibleChange?: (visible: boolean) => void;
-  popupVisible?: boolean;
-  clearText?: string;
-  viewMoreText?: string;
-  clearClose?: boolean;
-  emptyImage?: string;
-  children?: React.ReactElement<NoticeIconTabProps>[];
-}
-
-const NoticeIcon: React.FC<NoticeIconProps> & {
-  Tab: typeof NoticeList;
-} = (props) => {
-  const getNotificationBox = (): React.ReactNode => {
-    const {
-      children,
-      loading,
-      onClear,
-      onTabChange,
-      onItemClick,
-      onViewMore,
-      clearText,
-      viewMoreText,
-    } = props;
-    if (!children) {
-      return null;
-    }
-    const panes: React.ReactNode[] = [];
-    React.Children.forEach(children, (child: React.ReactElement<NoticeIconTabProps>): void => {
-      if (!child) {
-        return;
-      }
-      const { list, title, count, tabKey, showClear, showViewMore } = child.props;
-      const len = list && list.length ? list.length : 0;
-      const msgCount = count || count === 0 ? count : len;
-      const tabTitle: string = msgCount > 0 ? `${title} (${msgCount})` : title;
-      panes.push(
-        <TabPane tab={tabTitle} key={tabKey}>
-          <NoticeList
-            clearText={clearText}
-            viewMoreText={viewMoreText}
-            list={list}
-            tabKey={tabKey}
-            onClear={(): void => onClear && onClear(title, tabKey)}
-            onClick={(item): void => onItemClick && onItemClick(item, child.props)}
-            onViewMore={(event): void => onViewMore && onViewMore(child.props, event)}
-            showClear={showClear}
-            showViewMore={showViewMore}
-            title={title}
-          />
-        </TabPane>,
-      );
-    });
-    return (
-      <>
-        <Spin spinning={loading} delay={300}>
-          <Tabs className={styles.tabs} onChange={onTabChange}>
-            {panes}
-          </Tabs>
-        </Spin>
-      </>
-    );
-  };
-
-  const { className, count, bell } = props;
-
-  const [visible, setVisible] = useMergeValue<boolean>(false, {
-    value: props.popupVisible,
-    onChange: props.onPopupVisibleChange,
-  });
-  const noticeButtonClass = classNames(className, styles.noticeButton);
-  const notificationBox = getNotificationBox();
-  const NoticeBellIcon = bell || <BellOutlined className={styles.icon} />;
-  const trigger = (
-    <span className={classNames(noticeButtonClass, { opened: visible })}>
-      <Badge count={count} style={{ boxShadow: 'none' }} className={styles.badge}>
-        {NoticeBellIcon}
-      </Badge>
-    </span>
-  );
-  if (!notificationBox) {
-    return trigger;
-  }
-
-  return (
-    <HeaderDropdown
-      placement="bottomRight"
-      overlay={notificationBox}
-      overlayClassName={styles.popover}
-      trigger={['click']}
-      open={visible}
-      onOpenChange={setVisible}
-    >
-      {trigger}
-    </HeaderDropdown>
-  );
-};
-
-NoticeIcon.defaultProps = {
-  emptyImage: 'https://gw.alipayobjects.com/zos/rmsportal/wAhyIChODzsoKIOBHcBk.svg',
-};
-
-NoticeIcon.Tab = NoticeList;
-
-export default NoticeIcon;

+ 0 - 103
src/components/NoticeIcon/NoticeList.less

@@ -1,103 +0,0 @@
-@import '~antd/es/style/themes/default.less';
-
-.list {
-  max-height: 400px;
-  overflow: auto;
-  &::-webkit-scrollbar {
-    display: none;
-  }
-  .item {
-    padding-right: 24px;
-    padding-left: 24px;
-    overflow: hidden;
-    cursor: pointer;
-    transition: all 0.3s;
-
-    .meta {
-      width: 100%;
-    }
-
-    .avatar {
-      margin-top: 4px;
-      background: @component-background;
-    }
-    .iconElement {
-      font-size: 32px;
-    }
-
-    &.read {
-      opacity: 0.4;
-    }
-    &:last-child {
-      border-bottom: 0;
-    }
-    &:hover {
-      background: @primary-1;
-    }
-    .title {
-      margin-bottom: 8px;
-      font-weight: normal;
-    }
-    .description {
-      font-size: 12px;
-      line-height: @line-height-base;
-    }
-    .datetime {
-      margin-top: 4px;
-      font-size: 12px;
-      line-height: @line-height-base;
-    }
-    .extra {
-      float: right;
-      margin-top: -1.5px;
-      margin-right: 0;
-      color: @text-color-secondary;
-      font-weight: normal;
-    }
-  }
-  .loadMore {
-    padding: 8px 0;
-    color: @primary-6;
-    text-align: center;
-    cursor: pointer;
-    &.loadedAll {
-      color: rgba(0, 0, 0, 0.25);
-      cursor: unset;
-    }
-  }
-}
-
-.notFound {
-  padding: 73px 0 88px;
-  color: @text-color-secondary;
-  text-align: center;
-  img {
-    display: inline-block;
-    height: 76px;
-    margin-bottom: 16px;
-  }
-}
-
-.bottomBar {
-  height: 46px;
-  color: @text-color;
-  line-height: 46px;
-  text-align: center;
-  border-top: 1px solid @border-color-split;
-  border-radius: 0 0 @border-radius-base @border-radius-base;
-  transition: all 0.3s;
-  div {
-    display: inline-block;
-    width: 50%;
-    cursor: pointer;
-    transition: all 0.3s;
-    user-select: none;
-
-    &:only-child {
-      width: 100%;
-    }
-    &:not(:only-child):last-child {
-      border-left: 1px solid @border-color-split;
-    }
-  }
-}

+ 0 - 112
src/components/NoticeIcon/NoticeList.tsx

@@ -1,112 +0,0 @@
-import { Avatar, List } from 'antd';
-
-import React from 'react';
-import classNames from 'classnames';
-import styles from './NoticeList.less';
-
-export interface NoticeIconTabProps {
-  count?: number;
-  name?: string;
-  showClear?: boolean;
-  showViewMore?: boolean;
-  style?: React.CSSProperties;
-  title: string;
-  tabKey: string;
-  onClick?: (item: API.NoticeIconData) => void;
-  onClear?: () => void;
-  emptyText?: string;
-  clearText?: string;
-  viewMoreText?: string;
-  list: API.NoticeIconData[];
-  onViewMore?: (e: any) => void;
-}
-const NoticeList: React.FC<NoticeIconTabProps> = ({
-  list = [],
-  onClick,
-  onClear,
-  title,
-  onViewMore,
-  emptyText,
-  showClear = true,
-  clearText,
-  viewMoreText,
-  showViewMore = false,
-}) => {
-  if (!list || list.length === 0) {
-    return (
-      <div className={styles.notFound}>
-        <img
-          src="https://gw.alipayobjects.com/zos/rmsportal/sAuJeJzSKbUmHfBQRzmZ.svg"
-          alt="not found"
-        />
-        <div>{emptyText}</div>
-      </div>
-    );
-  }
-  return (
-    <div>
-      <List<API.NoticeIconData>
-        className={styles.list}
-        dataSource={list}
-        renderItem={(item, i) => {
-          const itemCls = classNames(styles.item, {
-            [styles.read]: item.read,
-          });
-          // eslint-disable-next-line no-nested-ternary
-          const leftIcon = item.avatar ? (
-            typeof item.avatar === 'string' ? (
-              <Avatar className={styles.avatar} src={item.avatar} />
-            ) : (
-              <span className={styles.iconElement}>{item.avatar}</span>
-            )
-          ) : null;
-
-          return (
-            <List.Item
-              className={itemCls}
-              key={item.id || i}
-              onClick={() => onClick && onClick(item)}
-            >
-              <List.Item.Meta
-                className={styles.meta}
-                avatar={leftIcon}
-                title={
-                  <div className={styles.title}>
-                    {item.title}
-                    <div className={styles.extra}>{item.extra}</div>
-                  </div>
-                }
-                description={
-                  <div>
-                    <div className={styles.description}>{item.description}</div>
-                    <div className={styles.datetime}>{item.datetime}</div>
-                  </div>
-                }
-              />
-            </List.Item>
-          );
-        }}
-      />
-      <div className={styles.bottomBar}>
-        {showClear ? (
-          <div onClick={onClear}>
-            {clearText} {title}
-          </div>
-        ) : null}
-        {showViewMore ? (
-          <div
-            onClick={(e) => {
-              if (onViewMore) {
-                onViewMore(e);
-              }
-            }}
-          >
-            {viewMoreText}
-          </div>
-        ) : null}
-      </div>
-    </div>
-  );
-};
-
-export default NoticeList;

+ 0 - 35
src/components/NoticeIcon/index.less

@@ -1,35 +0,0 @@
-@import '~antd/es/style/themes/default.less';
-
-.popover {
-  position: relative;
-  width: 336px;
-}
-
-.noticeButton {
-  display: inline-block;
-  cursor: pointer;
-  transition: all 0.3s;
-}
-.icon {
-  padding: 4px;
-  vertical-align: middle;
-}
-
-.badge {
-  font-size: 16px;
-}
-
-.tabs {
-  :global {
-    .ant-tabs-nav-list {
-      margin: auto;
-    }
-
-    .ant-tabs-nav-scroll {
-      text-align: center;
-    }
-    .ant-tabs-bar {
-      margin-bottom: 0;
-    }
-  }
-}

+ 0 - 158
src/components/NoticeIcon/index.tsx

@@ -1,158 +0,0 @@
-import React, { useEffect, useState, useCallback } from 'react';
-import { Tag, message } from 'antd';
-import { groupBy } from 'lodash';
-import moment from 'moment';
-import { useModel } from 'umi';
-import { queryNotices } from '@/services/user';
-
-import NoticeIcon from './NoticeIcon';
-import styles from './index.less';
-
-const getNoticeData = (
-  notices: API.NoticeIconData[],
-): {
-  [key: string]: API.NoticeIconData[];
-} => {
-  if (!notices || notices.length === 0 || !Array.isArray(notices)) {
-    return {};
-  }
-
-  const newNotices = notices.map((notice) => {
-    const newNotice = { ...notice };
-
-    if (newNotice.datetime) {
-      newNotice.datetime = moment(notice.datetime as string).fromNow();
-    }
-
-    if (newNotice.id) {
-      newNotice.key = newNotice.id;
-    }
-
-    if (newNotice.extra && newNotice.status) {
-      const color = {
-        todo: '',
-        processing: 'blue',
-        urgent: 'red',
-        doing: 'gold',
-      }[newNotice.status];
-      newNotice.extra = (
-        <Tag
-          color={color}
-          style={{
-            marginRight: 0,
-          }}
-        >
-          {newNotice.extra}
-        </Tag>
-      );
-    }
-
-    return newNotice;
-  });
-  return groupBy(newNotices, 'type');
-};
-
-const getUnreadData = (noticeData: { [key: string]: API.NoticeIconData[] }) => {
-  const unreadMsg: {
-    [key: string]: number;
-  } = {};
-  Object.keys(noticeData).forEach((key) => {
-    const value = noticeData[key];
-
-    if (!unreadMsg[key]) {
-      unreadMsg[key] = 0;
-    }
-
-    if (Array.isArray(value)) {
-      unreadMsg[key] = value.filter((item) => !item.read).length;
-    }
-  });
-  return unreadMsg;
-};
-
-export interface GlobalHeaderRightProps {
-  fetchingNotices?: boolean;
-  onNoticeVisibleChange?: (visible: boolean) => void;
-  onNoticeClear?: (tabName?: string) => void;
-}
-
-const NoticeIconView = () => {
-  const { initialState } = useModel('@@initialState');
-  const { currentUser } = initialState || {};
-  const [notices, setNotices] = useState<API.NoticeIconData[]>([]);
-
-  useEffect(() => {
-    queryNotices().then(({ data }) => setNotices(data));
-  }, []);
-
-  const noticeData = getNoticeData(notices);
-  const unreadMsg = getUnreadData(noticeData || {});
-
-  const changeReadState = useCallback((id: string) => {
-    setNotices(
-      notices.map((item) => {
-        const notice = { ...item };
-        if (notice.id === id) {
-          notice.read = true;
-        }
-        return notice;
-      }),
-    );
-  }, []);
-
-  const clearReadState = (title: string, key: string) => {
-    setNotices(
-      notices.map((item) => {
-        const notice = { ...item };
-        if (notice.type === key) {
-          notice.read = true;
-        }
-        return notice;
-      }),
-    );
-    message.success(`${'清空了'} ${title}`);
-  };
-
-  return (
-    <NoticeIcon
-      className={styles.action}
-      count={currentUser && currentUser.unreadCount}
-      onItemClick={(item) => {
-        changeReadState(item.id);
-      }}
-      onClear={(title: string, key: string) => clearReadState(title, key)}
-      loading={false}
-      clearText="清空"
-      viewMoreText="查看更多"
-      onViewMore={() => message.info('Click on view more')}
-      clearClose
-    >
-      <NoticeIcon.Tab
-        tabKey="notification"
-        count={unreadMsg.notification}
-        list={noticeData.notification}
-        title="通知"
-        emptyText="你已查看所有通知"
-        showViewMore
-      />
-      <NoticeIcon.Tab
-        tabKey="message"
-        count={unreadMsg.message}
-        list={noticeData.message}
-        title="消息"
-        emptyText="您已读完所有消息"
-        showViewMore
-      />
-      <NoticeIcon.Tab
-        tabKey="event"
-        title="待办"
-        emptyText="你已完成所有待办"
-        count={unreadMsg.event}
-        list={noticeData.event}
-        showViewMore
-      />
-    </NoticeIcon>
-  );
-};
-
-export default NoticeIconView;

+ 0 - 13
src/components/gzhMenu/index.less

@@ -1,13 +0,0 @@
-.card_container {
-  background-color: #fff;
-  > div {
-    padding-top: 22px;
-  }
-}
-
-.item_img {
-  width: 25px;
-  border-radius: 2px;
-  margin-right: 5px;
-  background-color: #efefef;
-}

+ 0 - 332
src/components/gzhMenu/index.tsx

@@ -1,332 +0,0 @@
-import React, { useState, useEffect, useCallback } from 'react'
-import { Menu, Modal, Select, Tabs } from 'antd'
-import style from './index.less'
-import { useModel } from 'umi';
-import { ExclamationCircleOutlined } from '@ant-design/icons';
-const { SubMenu } = Menu;
-const { Option } = Select
-function LeftPage(props: { isOk?: boolean, isShow?: boolean, h?: number ,isDisabled?:boolean }) {
-    const { isOk = true, isShow, h ,isDisabled = true} = props
-    const { getWxGroupAll, actionWx, getAllOfMember, state, dispatch } = useModel('useOperating.useWxGroupList', model => ({ getWxGroupAll: model.getDataList, ...model }))
-    const { tabsKey, groupAllWx, allWx } = state
-    const [openKeys, setOpenKeys] = useState<string[]>(['']) //自己栏选中展开的菜单
-    const [crewOpenKeys, setCrewOpenKeys] = useState<string[]>(['']) //组员栏选中展开的菜单
-    const [selectedKeys, setSelectedKeys] = useState<string[]>(['']) //自己栏选中的菜单
-    const [crewSelectedKeys, setCrewSelectedKeys] = useState<string[]>(['']) //组员栏选中的菜单
-    const [visible, setVisible] = useState<boolean>(false)//未保存编辑显示提示窗
-    const [wx, setWx] = useState<any>(null)//提示窗出现后暂存点击的公众号以备逻辑跳转
-    const [wxData, setWxData] = useState<any>({
-        key: '自己',
-        menuItem: null,
-        crewMenuItem: null,
-    })
-    let bWith = document.body.clientWidth < 700
-    //自己menuitem点击
-    let menuItemClick = useCallback((e: any, isOk?: any) => {
-        setWxData({ ...wxData, menuItem: e })
-        if (isOk) {
-            if (e?.keyPath) {
-                setSelectedKeys([e.keyPath[0]])
-                setOpenKeys(['', e.keyPath[1]])
-            }
-        }
-    }, [getWxGroupAll, wxData])
-    /**组员menuitem点击 */
-    let crewMenuItemClick = useCallback((e: any, isOk?: any) => {
-        setWxData({ ...wxData, crewMenuItem: e })
-        if (isOk) {
-            if (e?.keyPath) {
-                setCrewSelectedKeys([e?.keyPath[0]])
-                setCrewOpenKeys([e?.keyPath[1]])
-            }
-        }
-    }, [getAllOfMember, wxData])
-    //自己menu点击
-    let menuClick = useCallback((e: any) => {
-        setOpenKeys(e)
-    }, [getWxGroupAll])
-    /**组员menu点击 */
-    let crewMenuClick = useCallback((e: any) => {
-        setCrewOpenKeys(e)
-    }, [])
-    /**放弃保存 */
-    let outSaver = () => {
-        setVisible(false)
-        tabsChange(wxData.key, true)
-        if (wxData.key === '自己') {
-            if (typeof wxData?.menuItem === 'string') {
-                inputChange(wxData?.menuItem, true)
-            } else {
-                wxData?.menuItem && menuItemClick(wxData?.menuItem, true)
-            }
-
-        } else {
-            if (typeof wxData?.crewMenuItem === 'string') {
-                inputChange(wxData?.crewMenuItem, true)
-            } else {
-                wxData?.crewMenuItem && crewMenuItemClick(wxData?.crewMenuItem, true)
-            }
-        }
-        if (wx) {
-            selectData(wx, true)
-        }
-    }
-
-    //选中微信的数据
-    let selectData = useCallback((wx: any, isOk?: any) => {
-        setWx(wx)
-        if (isOk) {
-            actionWx(wx)
-            setVisible(false)
-        } else {
-            if (!visible) {
-                setVisible(true)
-            }
-        }
-    }, [getAllOfMember, wxData, visible])
-    //tabs选中
-    let tabsChange = useCallback((key: string, isOk?: boolean) => {
-        setWxData({ ...wxData, key })
-        if (isOk) {
-            dispatch({ type: 'setTabsKey', params: { tabsKey: key } })
-            if (key === '自己') {
-                if (openKeys[0] && selectedKeys[0]) {
-                    selectGZH(openKeys[1], selectedKeys[0], key)
-                } else {
-                    let ok = true
-                    getWxGroupAll?.data?.forEach((item: any) => {
-                        if (ok && item?.mpAccounts?.length > 0) {
-                            ok = false
-                            actionWx(item?.mpAccounts[0])
-                        }
-                    })
-                }
-
-            } else {
-                if (crewOpenKeys[0] && crewSelectedKeys[0]) {
-                    selectGZH(crewOpenKeys[0], crewSelectedKeys[0], key)
-                } else {
-                    let ok = true
-                    getAllOfMember?.data?.forEach((item: { key: any, value: any[] }) => {
-                        if (ok && item?.value?.length > 0) {
-                            ok = false
-                            actionWx(item?.value[0])
-                        }
-                    })
-                }
-            }
-            setVisible(false)
-        } else {
-            if (!visible) {
-                setVisible(true)
-            }
-
-        }
-    }, [openKeys, selectedKeys, crewOpenKeys, crewSelectedKeys, wxData, visible, getWxGroupAll, getAllOfMember])
-    /*以key筛选公众号 */
-    let selectGZH = (open: string, select: string, tabsKey?: string) => {
-        if (tabsKey === '自己') {
-            if (getWxGroupAll?.data) {//筛选出微信号
-                getWxGroupAll?.data?.forEach((item: any) => {
-                    if (item?.groupName === open) {
-                        item?.mpAccounts?.forEach((obj: any) => {
-                            if (obj?.nickName === select) {
-                                actionWx(obj)//更新当前选中微信号,触发各个组件的数据获取
-                            }
-                        })
-                    }
-                })
-            }
-        } else {
-            if (getAllOfMember?.data) {
-                getAllOfMember?.data?.forEach((item: { key: { nickname: string, userId: number }, value: any[] }) => {
-                    if (item?.key?.nickname + item?.key?.userId === open) {
-                        item?.value?.forEach((obj: any) => {
-                            if (obj?.nickName === select) {
-                                actionWx(obj)//更新当前选中微信号,触发各个组件的数据获取
-                            }
-                        })
-                    }
-                })
-            }
-        }
-    }
-    //搜索
-    let inputChange = (v: string, isOk?: boolean) => {
-        if (v) {
-            if (isOk) {
-                let [open, select] = v.split('_') //切换字符串转换成数组
-                if (tabsKey === '自己') {//设置选中key展开的菜单
-                    setOpenKeys([open])
-                    setSelectedKeys([select])
-                } else {
-                    setCrewOpenKeys([open])
-                    setCrewSelectedKeys([select])
-                }
-                selectGZH(open, select, tabsKey)//已key搜索对应的公众号并发送请求获取数据
-            } else {
-                if (!visible) {
-                    if (tabsKey === '自己') {
-                        setWxData({ ...wxData, menuItem: v })
-                    } else {
-                        setWxData({ ...wxData, crewMenuItem: v })
-                    }
-                    setVisible(true)
-                }
-            }
-        }
-    }
-    //首次加载选中当前选中的tabs有公众号的组或成员中第一个公众号
-    useEffect(() => {
-        if (tabsKey === '自己') {
-            getWxGroupAll?.data?.forEach((item: { mpAccounts?: any[], groupName: string }, index: number) => {
-                item?.mpAccounts?.forEach((wx: { nickName: string }) => {
-                    if (wx.nickName === state?.actionWX?.nickName) {
-                        setOpenKeys(['', `${item?.groupName}`])
-                        setSelectedKeys([`${wx.nickName}`])
-                    }
-                })
-            })
-        } else {
-            getAllOfMember?.data?.forEach((item: { key: { nickname: string, userId: number }, value: any[] }, index: number) => {
-                item?.value?.forEach((wx: { nickName: string }) => {
-                    if (wx.nickName === state?.actionWX?.nickName) {
-                        setCrewOpenKeys([`${item?.key?.nickname + item?.key?.userId}`])
-                        setCrewSelectedKeys([`${wx.nickName}`])
-                    }
-                })
-            })
-        }
-
-    }, [tabsKey])
-    useEffect(() => {
-        if (visible) {
-            Modal.confirm({
-                title: '有修改未保存!',
-                icon: <ExclamationCircleOutlined />,
-                onOk() {
-                    setVisible(false)
-                },
-                onCancel() {
-                    outSaver()
-                },
-                okText: '去保存修改',
-                cancelText: '放弃修改',
-            });
-        }
-    }, [visible])
-    return <div className={style.card_container}>
-        <Tabs type="card" activeKey={tabsKey} onChange={isShow ? (key: any) => tabsChange(key, isOk) : (key: any) => tabsChange(key, true)}>
-            <Tabs.TabPane tab='自己' key='自己'>
-                <div style={{ width: `${bWith ? '100%' : '200px'}` }}>
-                    <Select
-                        style={{ width: '100%' }}
-                        placeholder="输入搜索公众号"
-                        onChange={isShow ? (v: any) => { inputChange(v, isOk) } : (v: any) => { inputChange(v, true) }}
-                        showArrow
-                        showSearch
-                        allowClear
-                    >
-                        {
-                            getWxGroupAll?.data?.map((item: any, index: number) => {
-                                return item?.mpAccounts?.map((list: any, eq: number) => {
-                                    return <Option key={item.groupName + list?.id} value={item?.groupName + '_' + list?.nickName} disabled={isDisabled?list?.verifyTypeInfo === -1:false}>
-                                        <img src={list?.headImg || localStorage?.bookImg} className={style.item_img} />{list?.nickName}
-                                    </Option>
-                                })
-                            })
-                        }
-                    </Select>
-                </div>
-                <Menu
-                    onClick={isShow ? (e: any) => menuItemClick(e, isOk) : (e: any) => menuItemClick(e, true)}
-                    style={{ width: `${bWith ? '100%' : '200px'}`, height: h ? h : '100%', overflowY: 'auto', overflowX: 'hidden' }}
-                    openKeys={openKeys}
-                    selectedKeys={selectedKeys}
-                    mode={"inline"}
-                    onOpenChange={menuClick}
-                >
-                    {
-                        getWxGroupAll?.data?.map((item: any) => {
-                            return <SubMenu
-                                key={item?.groupName}
-                                title={<p>{item?.groupName}<span style={{ color: '#999' }}>({item?.mpAccounts?.length || 0})</span></p>}
-                            >
-                                {
-                                    item?.mpAccounts?.map((list: any) => {
-                                        return <Menu.Item key={list?.nickName}
-                                            onClick={isShow ? () => {
-                                                selectData(list, isOk)
-                                            } : () => { selectData(list, true) }}
-                                            disabled={isDisabled?list.verifyTypeInfo === -1:false}
-                                        >
-                                            <img src={list?.headImg || localStorage?.bookImg} className={style.item_img} />
-                                            <span>{list?.nickName}</span>
-                                        </Menu.Item>
-                                    })
-                                }
-                            </SubMenu>
-                        })
-                    }
-                </Menu>
-            </Tabs.TabPane>
-            {
-                getAllOfMember?.data?.length > 0 && <Tabs.TabPane tab='组员' key='组员'>
-                    <div style={{ width: `${bWith ? '100%' : '200px'}` }}>
-                        <Select
-                            style={{ width: '100%' }}
-                            placeholder="输入搜索公众号"
-                            onChange={isShow ? (v: any) => { inputChange(v, isOk) } : (v: any) => { inputChange(v, true) }}
-                            showArrow
-                            showSearch
-                            allowClear
-                        >
-                            {
-                                getAllOfMember?.data?.map((item: { key: { nickname: string, userId: number }, value: any[] }, index: number) => {
-                                    return item?.value?.map((list: any, eq: number) => {
-                                        return <Option key={list?.id + item?.key?.nickname} value={item?.key?.nickname + item?.key?.userId + '_' + list?.nickName} disabled={isDisabled?list?.verifyTypeInfo === -1:false}>
-                                            <img src={list?.headImg || localStorage?.bookImg} className={style.item_img} /> {list?.nickName}
-                                        </Option>
-                                    })
-                                })
-                            }
-                        </Select>
-                    </div>
-                    <Menu
-                        onClick={isShow ? (e: any) => crewMenuItemClick(e, isOk) : (e: any) => crewMenuItemClick(e, true)}
-                        style={{ width: `${bWith ? '100%' : '200px'}`, height: h ? h : '100%', overflowY: 'auto', overflowX: 'hidden' }}
-                        openKeys={crewOpenKeys}
-                        selectedKeys={crewSelectedKeys}
-                        mode={"inline"}
-                        onOpenChange={crewMenuClick}
-                    >
-                        {
-                            getAllOfMember?.data?.map((item: { key: { nickname: string, userId: number }, value: any[] }, eq: number) => {
-                                return <SubMenu
-                                    key={item?.key?.nickname + item?.key?.userId}
-                                    title={<p>{item?.key?.nickname}<span style={{ color: '#999' }}>({item?.value?.length})</span></p>}
-                                >
-                                    {
-                                        crewOpenKeys.some((name) => name === item?.key?.nickname + item?.key?.userId) && item?.value?.map((list: any, index: number) => {
-                                            return <Menu.Item key={eq + '_' + index + '_' + list?.id + '_' + list?.putUserId} onClick={isShow ? () => {
-                                                selectData(list, isOk)
-                                            } : () => { selectData(list, true) }}
-                                                disabled={isDisabled?list.verifyTypeInfo === -1:false}
-                                            >
-                                                <img src={list?.headImg || localStorage?.bookImg} className={style.item_img} />
-                                                <span>{list?.nickName}</span>
-                                            </Menu.Item>
-                                        })
-                                    }
-                                </SubMenu>
-                            })
-                        }
-                    </Menu>
-                </Tabs.TabPane>
-            }
-        </Tabs>
-
-    </div >
-}
-
-export default LeftPage