wjx 4 tuần trước cách đây
mục cha
commit
99f96867b7

+ 90 - 0
src/pages/weComTask/components/groupChatGroups/index.tsx

@@ -0,0 +1,90 @@
+import React, { useState } from 'react';
+import '../../page/corpUserManage/global.less'
+import useNewToken from '@/Hook/useNewToken';
+import { DefaultOptionType } from 'antd/es/select';
+import SelectMpCorp from '../../page/groupChatSend/official/create/components/SelectMpCorp';
+import { Tag, Tooltip } from 'antd';
+
+interface GroupChatGroupsProps {
+    corpList: DefaultOptionType[]
+    mpList: DefaultOptionType[]
+    value?: OFFICIAL_CHAT_CREATE.GroupsProps[];
+    onChange?: (value?: OFFICIAL_CHAT_CREATE.GroupsProps[]) => void;
+    placeholder?: React.ReactNode
+}
+
+/**
+ * 群发组配置
+ * @param param0 
+ * @returns 
+ */
+const GroupChatGroups: React.FC<GroupChatGroupsProps> = ({ corpList, mpList, value, onChange, placeholder }) => {
+
+    /************************************************************/
+    const { token } = useNewToken()
+    const [visible, setVisible] = useState<boolean>(false);
+    /************************************************************/
+
+    return <>
+        <div
+            className='selectCorpUser'
+            style={{
+                border: `1px solid ${token.colorBorder}`,
+                padding: `0px ${token.paddingXS}px`,
+                borderRadius: token.borderRadius,
+                height: token.controlHeight,
+            }}
+            onClick={() => {
+                setVisible(true)
+            }}
+        >
+            <div className='selectCorpUserContent'>
+                {(value && value?.length > 0) ? <>
+                    <Tag
+                        closable
+                        onClose={(e) => {
+                            e.preventDefault();
+                            const newData = value?.filter((_, i) => i !== 0)
+                            onChange(newData)
+                        }}
+                    >
+                        {value?.[0]?.mpAccount?.label || '群发主1'}
+                    </Tag>
+                    {value?.length > 1 && <Tooltip
+                        color="#FFF"
+                        title={<span style={{ color: '#000' }}>
+                            {value?.filter((_, index) => index !== 0)?.map((item, index) => <Tag
+                                key={index}
+                                closable
+                                onClose={(e) => {
+                                    e.stopPropagation()
+                                    const newData = value?.filter((_, i) => i !== index + 1)
+                                    onChange(newData)
+                                }}
+                            >{item?.mpAccount?.label || `群发组${index + 2}`}</Tag>)}</span>
+                        }
+                    >
+                        <Tag>+{value.length - 1} ...</Tag>
+                    </Tooltip>}
+                </> : <span style={{ color: token.colorTextDisabled }}>{placeholder || '请选择主体'}</span>}
+            </div>
+        </div>
+
+        {/* 选择关联主体 */}
+        {visible && <SelectMpCorp
+            corpList={corpList}
+            mpList={mpList}
+            visible={visible}
+            group={value}
+            onChange={(group) => {
+                onChange?.(group)
+                setVisible(false)
+            }}
+            onClose={() => {
+                setVisible(false)
+            }}
+        />}
+    </>;
+};
+
+export default GroupChatGroups;

+ 33 - 313
src/pages/weComTask/page/businessPlan/create/index.tsx

@@ -4,20 +4,18 @@ import style from './index.less'
 import { App, Button, Card, Empty, Flex, Form, Input, Popconfirm, Select, Space, Spin, Table, Tabs } from 'antd';
 import MassSending from './components/massSending';
 import { useAjax } from '@/Hook/useAjax';
-import { MediaContentProps, welcomeMsgJobTypeApi } from '@/pages/weComTask/API/weMaterial/weMaterial';
+import { welcomeMsgJobTypeApi } from '@/pages/weComTask/API/weMaterial/weMaterial';
 import SelectCorpUser from '../../corpUserManage/selectCorpUser';
 import { SearchOutlined, PlusOutlined, RedoOutlined, SaveOutlined, CheckOutlined } from '@ant-design/icons';
-import { getGroupData, getHighGroupData, getUserInDataData, restoreGroupData, restoreUserInheritData } from './const';
+import { getGroupData, getUserInDataData, restoreGroupData, restoreUserInheritData } from './const';
 import { friendsColumns, highMassSendingColumns, massSendingColumns, userInheritColumns, welcomeColumns } from './tableConfig';
 import SubmitModal from './submitModal';
-import { addTaskApi, getCreateDetailsApi, getProjectDetailsApi, updateTaskApi } from '@/pages/weComTask/API/businessPlan/create';
+import { addTaskApi, getCreateDetailsApi, updateTaskApi } from '@/pages/weComTask/API/businessPlan/create';
 import { useNavigate } from 'react-router-dom';
 import SelectExternalAccount from '@/pages/weComTask/components/selectExternalAccount';
 import Welcome from './components/welcome';
 import UserInherit from './components/userInherit';
-import HighMassSending from './components/highMassSending';
 import { toJS } from 'mobx';
-import Friends from './components/friends';
 import SelectCwTag from '@/pages/weComTask/components/selectCwTag';
 import SelectCorpUserGroup from '../../corpUserManage/selectCorpUserGroup';
 import { getBindMpListApi } from '@/pages/weComTask/API/corpUserAssign';
@@ -62,7 +60,7 @@ const Create: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE.BookLis
                 setProjectId(id)
             }
             getCreateDetails.run(id).then(res => {
-                sessionStorage.removeItem('OFFICIALTASKID')
+                // sessionStorage.removeItem('OFFICIALTASKID')
                 if (res?.data) {
                     const { corpUsers, bizType, platform, templateProductId, welcomeMsgTemplateDTO, groupSendTaskAddDTO, externalUserTransferTasksDTO } = res.data
                     let newSettings: TASK_CREATE.SettingsProps = {
@@ -87,6 +85,34 @@ const Create: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE.BookLis
                         newSettings.userInherit = data
                     }
                     setSettings(newSettings)
+
+                    // 历史数据回填
+
+                    const welcomeMsgContent: any[] = []
+                    const groupMsgContent: any[] = []
+                    corpUsers.forEach((c, c_index) => {
+                        if (c?.welcomeMsgContent?.length > 0) {
+                            welcomeMsgContent[c_index] = c?.welcomeMsgContent?.map(item => ({
+                                linkUrl: item?.linkUrl,
+                                miniprogramAppid: item?.miniprogramAppid,
+                                miniprogramPage: item?.miniprogramPage
+                            }))
+                        }
+                        if (c?.groupMsgContent?.length > 0) {
+                            groupMsgContent[c_index] = c?.groupMsgContent?.map(item => {
+                                return item?.map(i2 => i2?.map(item => ({
+                                    linkUrl: item?.linkUrl,
+                                    miniprogramAppid: item?.miniprogramAppid,
+                                    miniprogramPage: item?.miniprogramPage
+                                })))
+                            })
+                        }
+                    })
+                    const newPreviewContent: { groupMsgContent?: any[], welcomeMsgContent?: any[], externalUserTransferContent?: any[] } = {
+                        welcomeMsgContent,
+                        groupMsgContent
+                    }
+                    setPreviewContent(newPreviewContent)
                 }
             })
         } else {
@@ -280,157 +306,6 @@ const Create: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE.BookLis
             console.log('userInherit-->', userInherit)
             newPreviewData.userInherit = userInherit
         }
-
-        // 是否有高级群发
-        // if ((settings?.highMassSendingContent && Object.keys(settings?.highMassSendingContent).length) && (settings?.highMassSendingStrategy && Object.keys(settings?.highMassSendingStrategy).length)) {
-        //     if (settings?.highMassSendingContent?.massSendingContentDTO?.some(item => item?.sendContentDto?.some(si => si?.contentDTO?.some(i => i?.some(a => ["miniprogram", 'link'].includes(a?.mediaType))))) && settings?.corpUsers?.every(item => !item?.highGroupMsgContent?.length)) {
-        //         message.error('需要配置小程序、链接,请上传配置好的高级群发Excel文件')
-        //         return
-        //     }
-        //     const massSendingData = getHighGroupData(settings)
-        //     console.log('massSendingData---->', massSendingData)
-        //     const highMassSending = []
-        //     let rowLength = 0
-        //     if (!settings?.corpUsers?.every((item, i) => {
-
-        //         let strategyIndex = 0
-        //         let corpUserCount = 0
-        //         return massSendingData.every((dataItem, li, row) => {
-
-        //             const mediaItem = JSON.parse(JSON.stringify(dataItem?.content || []))
-        //             const contentReactNode = mediaItem.map(item => {
-        //                 switch (item.mediaType) {
-        //                     case 'link':
-        //                         return `<span style="color: red">链接</span>`
-        //                     case 'miniprogram':
-        //                         return `<span style="color: red">小程序</span>`
-        //                     case 'file':
-        //                         return `<span>文件</span>`
-        //                     case 'video':
-        //                         return `<span>视频</span>`
-        //                     case 'image':
-        //                         return `<span>图片</span>`
-        //                     case 'text':
-        //                         return `<span>文本</span>`
-        //                     default:
-        //                         return `<span style="color: red">请联系管理员</span>`
-        //                 }
-        //             })
-        //             const externalUserListLength = item.externalUserList.length
-        //             return item.externalUserList?.every((externalUser, ii) => {
-        //                 const layer3 = externalUser.corpId + '-' + externalUser.externalUserId
-        //                 const externalUserMsg = item.highGroupMsgContent?.[dataItem.strategyIndex - 1]?.[dataItem.sendDataIndex - 1]?.[layer3]?.[dataItem.contentIndex - 1]
-        //                 if (mediaItem?.some(media => media?.mediaType === 'link' ? !externalUserMsg?.linkUrl : media?.mediaType === 'miniprogram' ? (!externalUserMsg?.miniprogramAppid || !externalUserMsg?.miniprogramPage) : false)) {
-        //                     message.error('高级群发配置错误,请检查')
-        //                     return false
-        //                 }
-        //                 rowLength++;
-        //                 highMassSending.push({
-        //                     ...dataItem,
-        //                     groupMsgContent: externalUserMsg,
-        //                     contentReactNode,
-        //                     externalUser,
-        //                     corpUserId: item.corpUserId,
-        //                     corpUserName: item.name,
-        //                     bizType: settings?.bizType,
-        //                     channel: settings?.channel,
-        //                     platform: settings?.platform,
-        //                     templateProductId: settings?.templateProductId,
-        //                     id: rowLength,
-        //                     userRowSpan: corpUserCount === 0 ? (massSendingData.length * externalUserListLength) : 0,
-        //                     strategyRowSpan: strategyIndex !== dataItem.strategyIndex ? dataItem.sendDataRowSpan * externalUserListLength * dataItem.strategyItemSendDataCount : 0,
-        //                     sendDataRowSpan: ii === 0 ? externalUserListLength * dataItem.sendDataRowSpan : 0
-        //                 })
-        //                 corpUserCount++;
-        //                 strategyIndex = dataItem.strategyIndex
-
-        //                 return true
-        //             })
-        //         })
-        //     })) {
-        //         return
-        //     }
-        //     newPreviewData.highMassSending = highMassSending
-        // }
-
-        // 是否有朋友圈任务
-        // if ((settings?.friendsContent && Object.keys(settings?.friendsContent).length) && (settings?.friendsStrategy && Object.keys(settings?.friendsStrategy).length)) {
-        //     if (settings?.friendsContent?.friendsContentDTO?.some(item => item?.contentDTO?.some(i => i?.attachmentList?.some(a => ['link', 'miniprogram'].includes(a?.mediaType)))) && settings?.corpUsers?.every(item => !item?.friendsMsgContent?.length)) {
-        //         message.error('朋友圈需要配置小程序、链接,请上传配置好的群发Excel文件')
-        //         return
-        //     }
-        //     const friends = []
-        //     let rowLength = 1
-        //     if (!settings?.corpUsers?.every((item, i) => {
-        //         let uIndex = 0
-        //         const uLength = settings?.friendsStrategy?.strategySettings?.reduce((pre, _, i) => settings?.friendsContent?.friendsContentDTO?.[i]?.contentDTO?.length + pre, 0)
-        //         return settings?.friendsStrategy?.strategySettings?.every((strategyItem, strategyIndex) => {
-        //             const friendsContentDTO = settings?.friendsContent?.friendsContentDTO?.[strategyIndex]
-        //             let sIndex = 0
-        //             return friendsContentDTO.contentDTO.every((contentItem, contentIndex) => {
-        //                 const msgContent = item.friendsMsgContent?.[strategyIndex]?.[contentIndex]
-        //                 if (contentItem?.attachmentList?.length && contentItem?.attachmentList?.some(item => (item?.mediaType === 'link' ? !msgContent?.linkUrl : item?.mediaType === 'miniprogram' ? (!msgContent?.miniprogramAppid || !msgContent?.miniprogramPage) : false))) {
-        //                     message.error('朋友圈内容配置错误,请检查')
-        //                     return false
-        //                 }
-
-        //                 const mediaItem = JSON.parse(JSON.stringify(contentItem?.attachmentList || []))
-        //                 if (contentItem?.text?.content) {
-        //                     mediaItem.push({
-        //                         mediaType: 'text',
-        //                         textContent: contentItem?.text?.content
-        //                     })
-        //                 }
-        //                 const contentReactNode = mediaItem.map(item => {
-        //                     switch (item.mediaType) {
-        //                         case 'link':
-        //                             return `<span style="color: red">链接</span>`
-        //                         case 'miniprogram':
-        //                             return `<span style="color: red">小程序</span>`
-        //                         case 'file':
-        //                             return `<span>文件</span>`
-        //                         case 'video':
-        //                             return `<span>视频</span>`
-        //                         case 'image':
-        //                             return `<span>图片</span>`
-        //                         case 'text':
-        //                             return `<span>文本</span>`
-        //                         default:
-        //                             return `<span style="color: red">请联系管理员</span>`
-        //                     }
-        //                 })
-
-        //                 friends.push({
-        //                     corpUserId: item.corpUserId,
-        //                     corpUserName: item.name,
-        //                     bizType: settings?.bizType,
-        //                     channel: settings?.channel,
-        //                     platform: settings?.platform,
-        //                     templateProductId: settings?.templateProductId,
-        //                     momentSendName: settings?.friendsStrategy?.momentSendName,
-        //                     strategyData: strategyItem,
-        //                     strategyIndex: strategyIndex,
-        //                     sendData: item?.friendsTagContent,
-        //                     contentReactNode,
-        //                     contentIndex,
-        //                     sendMode: friendsContentDTO?.sendMode,
-        //                     content: contentItem,
-        //                     friendsContent: msgContent,
-        //                     id: rowLength,
-        //                     userRowSpan: uIndex === 0 ? uLength : 0,
-        //                     strategyRowSpan: sIndex === 0 ? friendsContentDTO.contentDTO.length : 0
-        //                 })
-        //                 rowLength++;
-        //                 uIndex++;
-        //                 sIndex++;
-        //                 return true
-        //             })
-        //         })
-        //     })) {
-        //         return
-        //     }
-        //     newPreviewData.friends = friends
-        // }
         if (newPreviewData && Object.keys(newPreviewData).length) {
             setPreviewData(newPreviewData)
             setPreviewDataOld(newPreviewData)
@@ -441,6 +316,7 @@ const Create: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE.BookLis
 
     // 设置任务名称
     const setTaskName = () => {
+        console.log('---------->', previewContent)
         // 欢迎语
         if (settings?.welcomeMsgTemplateDTO && Object.keys(settings?.welcomeMsgTemplateDTO).length) {
             if (settings?.welcomeMsgTemplateDTO?.mediaContentList?.some(item => item?.some(i => i?.mediaType === 'link' || i?.mediaType === 'miniprogram')) && !(previewContent?.welcomeMsgContent?.length > 0)) {
@@ -564,101 +440,7 @@ const Create: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE.BookLis
                 })
             }
         }
-        // 高级群发
-        // if (highMassSendingStrategy && Object.keys(highMassSendingStrategy).length) {
-        //     params.messageSendTaskAddDTO = {
-        //         groupSendName: highMassSendingStrategy.groupSendName,
-        //         strategyList: highMassSendingStrategy?.strategySettings?.map((settingsItem, settingsIndex) => {
-        //             const {
-        //                 // 发送对象
-        //                 sendData,
-        //                 // 策略
-        //                 ...strategy
-        //             } = settingsItem
-        //             return {
-        //                 ...strategy,
-        //                 taskDetail: sendData.map((sendItem, sendIndex) => {
-        //                     // 发送内容
-        //                     const { contentDTO, sendMode } = highMassSendingContent.massSendingContentDTO[settingsIndex]['sendContentDto'][sendIndex]
-        //                     const detail: { [x: string]: any } = {
-        //                         sendMode,
-        //                         contentDTO: contentDTO.map(item => {
 
-        //                             let newContentDTO: { [x: string]: any } = {}
-        //                             item.forEach((item: MediaContentProps) => {
-        //                                 switch (item.mediaType) {
-        //                                     case "text":
-        //                                         newContentDTO = {
-        //                                             text: {
-        //                                                 content: item?.textContent
-        //                                             },
-        //                                             msgType: 'TASK_CONTENT_TEXT'
-        //                                         }
-        //                                         break
-        //                                     case "miniprogram":
-        //                                         newContentDTO = {
-        //                                             miniprogram: {
-        //                                                 appId: item?.miniprogramAppid,
-        //                                                 page: item?.miniprogramPage,
-        //                                                 title: item?.miniprogramTitle,
-        //                                                 picUrl: item?.miniprogramPicurl
-        //                                             },
-        //                                             msgType: 'TASK_STATUS_MINIPROGRAM'
-        //                                         }
-        //                                         break
-        //                                     case "link":
-        //                                         newContentDTO = {
-        //                                             link: {
-        //                                                 desc: item?.linkDesc,
-        //                                                 picUrl: item?.linkPicurl,
-        //                                                 title: item?.linkTitle,
-        //                                                 url: item?.linkUrl
-        //                                             },
-        //                                             msgType: 'TASK_CONTENT_LINK'
-        //                                         }
-        //                                         break
-        //                                     case "image":
-        //                                         newContentDTO = {
-        //                                             image: {
-        //                                                 picUrl: item?.imageUrl
-        //                                             },
-        //                                             msgType: 'TASK_CONTENT_IMAGE'
-        //                                         }
-        //                                         break
-        //                                     case "video":
-        //                                         newContentDTO = {
-        //                                             video: {
-        //                                                 videoUrl: item?.videoUrl
-        //                                             },
-        //                                             msgType: 'TASK_STATUS_VIDEO'
-        //                                         }
-        //                                         break
-        //                                     case "file":
-        //                                         newContentDTO = {
-        //                                             file: {
-        //                                                 fileUrl: item?.fileUrl
-        //                                             },
-        //                                             msgType: 'TASK_STATUS_FILE'
-        //                                         }
-        //                                         break
-        //                                 }
-        //                             })
-
-        //                             return newContentDTO
-        //                         })
-        //                     }
-        //                     if (sendItem.externalUserType === 'specify') {
-        //                         detail.externalUserFilter = {
-        //                             configName: sendItem.externalUserFilter.configName,
-        //                             ...sendItem.externalUserFilter.configContent
-        //                         }
-        //                     }
-        //                     return detail
-        //                 })
-        //             }
-        //         })
-        //     }
-        // }
         // 客户继承
         if (userInherit && Object.keys(userInherit).length) {
             params.externalUserTransferTasksDTO = {
@@ -686,68 +468,6 @@ const Create: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE.BookLis
                 })
             }
         }
-        // 朋友圈
-        // if (friendsStrategy && Object.keys(friendsStrategy).length) {
-        //     params.momentCreateDTO = {
-        //         momentSendName: friendsStrategy.momentSendName,
-        //         strategyList: friendsStrategy.strategySettings.map((item, index) => {
-        //             const { sendMode, contentDTO } = settings?.friendsContent?.friendsContentDTO?.[index]
-
-        //             return {
-        //                 ...item,
-        //                 taskDetail: {
-        //                     sendMode,
-        //                     contentDTO: contentDTO.map(item => {
-
-        //                         return {
-        //                             text: item.text,
-        //                             attachmentList: item.attachmentList.map((item: any) => {
-        //                                 switch (item.mediaType) {
-        //                                     case 'image':
-        //                                         return {
-        //                                             image: {
-        //                                                 picUrl: item.imageUrl,
-        //                                                 mediaFormat: item.mediaFormat,
-        //                                                 mediaSize: item.mediaSize,
-        //                                                 mediaPlayTime: item.mediaPlayTime,
-        //                                                 mediaWidth: item.mediaWidth,
-        //                                                 mediaHeight: item.mediaHeight
-        //                                             }, msgType: 'TASK_CONTENT_IMAGE'
-        //                                         }
-        //                                     case 'video':
-        //                                         return {
-        //                                             video: {
-        //                                                 videoUrl: item.videoUrl,
-        //                                                 mediaFormat: item.mediaFormat,
-        //                                                 mediaSize: item.mediaSize,
-        //                                                 mediaPlayTime: item.mediaPlayTime,
-        //                                                 mediaWidth: item.mediaWidth,
-        //                                                 mediaHeight: item.mediaHeight
-        //                                             }, msgType: 'TASK_STATUS_VIDEO'
-        //                                         }
-        //                                     case 'file':
-        //                                         return { file: { fileUrl: item.fileUrl }, msgType: 'TASK_STATUS_FILE' }
-        //                                     case 'link':
-        //                                         return { link: { desc: item.linkDesc, picUrl: item.linkPicurl, title: item.linkTitle, url: item.linkUrl }, msgType: 'TASK_CONTENT_LINK' }
-        //                                     case 'miniprogram':
-        //                                         return {
-        //                                             miniprogram: {
-        //                                                 appId: item.miniprogramAppid,
-        //                                                 page: item.miniprogramPage,
-        //                                                 picUrl: item.miniprogramPicurl,
-        //                                                 title: item.miniprogramTitle
-        //                                             },
-        //                                             msgType: 'TASK_STATUS_MINIPROGRAM'
-        //                                         }
-        //                                 }
-        //                             })
-        //                         }
-        //                     })
-        //                 }
-        //             }
-        //         })
-        //     }
-        // }
         console.log('11111111111111', values)
         if (projectId) {
             params.projectId = projectId

+ 9 - 9
src/pages/weComTask/page/corpUserManage/index.tsx

@@ -191,32 +191,32 @@ const CorpUserManage: React.FC = () => {
                         columns={WeTableConfig(activeKey, queryForm?.groupId, () => getCorpUser.refresh(), delHandle)}
                         bordered
                         pagination={false}
-                        rowKey={'corpUserId'}
+                        rowKey={'id'}
                         loading={getCorpUser?.loading}
                         scroll={{ y: size?.height && ref.current ? size?.height - ref.current.querySelector('.ant-table-thead').clientHeight : 300 }}
                         rowSelection={{
-                            selectedRowKeys: selectedRows?.map((item: any) => item?.corpUserId),
-                            onSelect: (record: { corpUserId: string }, selected: boolean) => {
+                            selectedRowKeys: selectedRows?.map((item: any) => item?.id),
+                            onSelect: (record: { id: string }, selected: boolean) => {
                                 let newData = JSON.parse(JSON.stringify(selectedRows))
                                 if (selected) {
                                     newData.push({ ...record })
                                 } else {
-                                    newData = newData.filter((item: { corpUserId: string }) => item.corpUserId !== record.corpUserId)
+                                    newData = newData.filter((item: { id: string }) => item.id !== record.id)
                                 }
                                 setselectedRows(newData)
                             },
-                            onSelectAll: (selected: boolean, _: { corpUserId: string }[], changeRows: { corpUserId: string }[]) => {
+                            onSelectAll: (selected: boolean, _: { id: string }[], changeRows: { id: string }[]) => {
                                 let newData = JSON.parse(JSON.stringify(selectedRows || '[]'))
                                 if (selected) {
-                                    changeRows.forEach((item: { corpUserId: string }) => {
-                                        const index = newData.findIndex((ite: { corpUserId: string }) => ite.corpUserId === item.corpUserId)
+                                    changeRows.forEach((item: { id: string }) => {
+                                        const index = newData.findIndex((ite: { id: string }) => ite.id === item.id)
                                         if (index === -1) {
                                             newData.push(item)
                                         }
                                     })
                                 } else {
-                                    const newSelectAccData = newData.filter((item: { corpUserId: string }) => {
-                                        const index = changeRows.findIndex((ite: { corpUserId: string }) => ite.corpUserId === item.corpUserId)
+                                    const newSelectAccData = newData.filter((item: { id: string }) => {
+                                        const index = changeRows.findIndex((ite: { id: string }) => ite.id === item.id)
                                         if (index !== -1) {
                                             return false
                                         } else {

+ 5 - 5
src/pages/weComTask/page/groupChat/create/index.tsx

@@ -139,10 +139,10 @@ const GroupChatCreate: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREAT
             message.error('请先选择客服号')
             return
         }
-        if (!robotCorpUsers || robotCorpUsers?.length === 0) {
-            message.error('请先选择机器人号')
-            return
-        }
+        // if (!robotCorpUsers || robotCorpUsers?.length === 0) {
+        //     message.error('请先选择机器人号')
+        //     return
+        // }
         if (!bizType) {
             message.error('请选择业务类型')
             return
@@ -227,7 +227,7 @@ const GroupChatCreate: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREAT
             platform,
             templateProductId,
             corpChatUserIds: corpUserChat.map(item => item.value),
-            corpRobots: robotCorpUsers.map(item => ({
+            corpRobots: robotCorpUsers?.map(item => ({
                 corpId: item.corpId,
                 corpUserId: item.corpUserId,
                 corpUserName: item.name,

+ 1 - 1
src/pages/weComTask/page/groupChat/create/tableConfig.tsx

@@ -52,7 +52,7 @@ export const PreviewColumns = (bookPlatForm: TASK_CREATE.BookPlatFormProps[], bo
             key: 'robotCorpUsers',
             width: 130,
             render(value) {
-                return value.map((item, index) => <Paragraph style={{ margin: 0 }} key={index}>{item.name}({item.corpName})</Paragraph>)
+                return value?.length > 0 ? value?.map((item, index) => <Paragraph style={{ margin: 0 }} key={index}>{item.name}({item.corpName})</Paragraph>) : '--'
             }
         },
         {

+ 1 - 1
src/pages/weComTask/page/groupChat/taskList/tableConfig.tsx

@@ -80,7 +80,7 @@ const taskListColumns = (
             key: 'corpRobots',
             width: 130,
             render(value) {
-                return <Paragraph style={{ margin: 0 }} ellipsis={{ tooltip: true }}>{value.map((item) => item.corpUserName + `(${item.corpName})`).join('、')}</Paragraph>
+                return value?.length > 0 ? <Paragraph style={{ margin: 0 }} ellipsis={{ tooltip: true }}>{value.map((item) => item.corpUserName + `(${item.corpName})`).join('、')}</Paragraph> : '--'
             }
         },
         {

+ 109 - 34
src/pages/weComTask/page/groupChatSend/official/create/components/SelectMpCorp/index.tsx

@@ -1,30 +1,29 @@
-import { Avatar, Button, Input, message, Modal, Select, Space, Table, Tag, Typography } from "antd";
-import React, { useEffect, useState } from "react";
+import { Button, message, Modal, Select, Space, Table, Tag, Typography } from "antd";
+import React, { useState } from "react";
 import style from '../../../../../../components/selectExternalAccount/index.less'
-import { CheckOutlined, UserOutlined, CloseOutlined } from '@ant-design/icons'
-import { useAjax } from "@/Hook/useAjax";
-import { copy } from "@/utils/utils";
+import { CheckOutlined, CloseOutlined } from '@ant-design/icons'
 import { DefaultOptionType } from "antd/es/select";
 const { Text, Title } = Typography;
 
 interface Props {
     corpList: DefaultOptionType[]
-    mpAccount?: OFFICIAL_CHAT_CREATE.MpAccountProps[];
+    mpList: DefaultOptionType[]
+    group?: OFFICIAL_CHAT_CREATE.GroupsProps[];
     visible?: boolean;
     onClose?: () => void;
-    onChange?: (value: OFFICIAL_CHAT_CREATE.MpAccountProps[]) => void;
+    onChange?: (value: OFFICIAL_CHAT_CREATE.GroupsProps[]) => void;
 }
 /**
  * 高级群发外部客户选择
  * @param param0 
  * @returns 
  */
-const SelectMpCorp: React.FC<Props> = ({ corpList, mpAccount, visible, onClose, onChange }) => {
+const SelectMpCorp: React.FC<Props> = ({ corpList, mpList, group, visible, onClose, onChange }) => {
 
     /***************************************/
-    const [data, setData] = useState<OFFICIAL_CHAT_CREATE.MpAccountProps[]>(mpAccount || []);
+    const [data, setData] = useState<OFFICIAL_CHAT_CREATE.GroupsProps[]>(group && group?.length > 0 ? group : [{}]);
     const [selectAdz, setSelectAdz] = useState<number>(1)   // 选择广告主
-    const [queryForm, setQueryForm] = useState<any>({ })
+    const [queryForm, setQueryForm] = useState<any>({})
     /***************************************/
 
     const handleOk = () => {
@@ -43,11 +42,11 @@ const SelectMpCorp: React.FC<Props> = ({ corpList, mpAccount, visible, onClose,
     }
 
     return <Modal
-        title={<strong>选择关联主体</strong>}
+        title={<strong>配置群发组</strong>}
         open={visible}
         onCancel={onClose}
         onOk={handleOk}
-        width={1000}
+        width={1100}
         className={`${style.SelectPackage}`}
         styles={{
             body: {
@@ -57,36 +56,101 @@ const SelectMpCorp: React.FC<Props> = ({ corpList, mpAccount, visible, onClose,
     >
         <div className={style.content}>
             <div className={style.left}>
-                <h4 className={style.title}>公众号</h4>
+                <div className={style.leftTitle}>
+                    <h4 className={style.title}>群发组</h4>
+                    <a onClick={() => {
+                        setData(d => ([...d, {}]))
+                    }}>新增组</a>
+                </div>
                 <div className={style.accountIdList}>
-                    {mpAccount?.map((item, index) => {
+                    {data?.map((item, index) => {
                         const corp = data[index]?.corp || []
                         return <div key={index} onClick={() => { handleSelectAdz(index + 1) }} className={`${style.accItem} ${selectAdz === index + 1 && style.select} `}>
-                            <div><Text ellipsis={{ tooltip: true }}>{item?.label}</Text></div>
+                            <div><Text ellipsis={{ tooltip: true }}>群发组{index + 1}</Text></div>
                             {corp?.length > 0 && <CheckOutlined style={{ color: '#1890ff' }} />}
                         </div>
                     })}
                 </div>
             </div>
-            <div className={style.right}>
-                <Space style={{ marginBottom: 10 }} align="end" size={5}>
-                    <Space.Compact>
-                        <Button>企业</Button>
-                        <Select
-                            showSearch
-                            style={{ width: 200 }}
-                            placeholder="请选择企业"
-                            filterOption={(input, option) =>
-                                ((option?.label ?? '') as string).toLowerCase().includes(input.toLowerCase())
+            <div className={style.right} style={{ width: 300, flex: 'none', borderRight: '1px solid #e8e8e8' }}>
+                <Space style={{ marginBottom: 10 }} align="center" size={10}>
+                    <Title level={5} style={{ margin: 0 }}>公众号(选填)</Title>
+                    <Select
+                        showSearch
+                        style={{ width: 120 }}
+                        placeholder="请选择公众号"
+                        filterOption={(input, option) =>
+                            ((option?.label ?? '') as string).toLowerCase().includes(input.toLowerCase())
+                        }
+                        value={queryForm?.mpAccountId}
+                        onChange={(e) => {
+                            setQueryForm({ ...queryForm, mpAccountId: e, pageNum: 1 })
+                        }}
+                        allowClear
+                        options={mpList}
+                    />
+                    {data[selectAdz - 1]?.mpAccount?.value && <a 
+                        style={{ color: 'red' }}
+                        onClick={() => {
+                            let newData = JSON.parse(JSON.stringify(data))
+                            let dataIten = newData[selectAdz - 1]?.mpAccount || {}
+                             dataIten = undefined
+                            newData[selectAdz - 1].mpAccount = dataIten
+                            setData(newData)
+                        }}
+                    >删除</a>}
+                    
+                </Space>
+                <Table
+                    tableLayout='fixed'
+                    dataSource={queryForm?.mpAccountId ? mpList.filter(item => item.value === queryForm.mpAccountId) : mpList}
+                    columns={[
+                        {
+                            title: '公众号名称',
+                            dataIndex: 'label',
+                            key: 'label'
+                        }
+                    ]}
+                    scroll={{ y: 400 }}
+                    rowKey={'value'}
+                    size='small'
+                    rowSelection={{
+                        selectedRowKeys: data[selectAdz - 1]?.mpAccount?.value ? [data[selectAdz - 1]?.mpAccount?.value] : [],
+                        type: 'radio',
+                        getCheckboxProps: (record: any) => ({
+                            name: record.name,
+                        }),
+                        onSelect: (record: { value: string }, selected: boolean) => {
+                            let newData = JSON.parse(JSON.stringify(data))
+                            let dataIten = newData[selectAdz - 1]?.mpAccount || {}
+                            if (selected) {
+                                dataIten = { ...record }
+                            } else {
+                                dataIten = undefined
                             }
-                            value={queryForm?.corpId}
-                            onChange={(e) => {
-                                setQueryForm({ ...queryForm, corpId: e, pageNum: 1 })
-                            }}
-                            allowClear
-                            options={corpList}
-                        />
-                    </Space.Compact>
+                            newData[selectAdz - 1].mpAccount = dataIten
+                            setData(newData)
+                        }
+                    }}
+                />
+            </div>
+            <div className={style.right}>
+                <Space style={{ marginBottom: 10 }} align="center" size={10}>
+                    <Title level={5} style={{ margin: 0 }}>主体</Title>
+                    <Select
+                        showSearch
+                        style={{ width: 200 }}
+                        placeholder="请选择企业"
+                        filterOption={(input, option) =>
+                            ((option?.label ?? '') as string).toLowerCase().includes(input.toLowerCase())
+                        }
+                        value={queryForm?.corpId}
+                        onChange={(e) => {
+                            setQueryForm({ ...queryForm, corpId: e, pageNum: 1 })
+                        }}
+                        allowClear
+                        options={corpList}
+                    />
                 </Space>
 
                 <Table
@@ -148,7 +212,18 @@ const SelectMpCorp: React.FC<Props> = ({ corpList, mpAccount, visible, onClose,
                 />
             </div>
             <div className={style.center}>
-                <Title level={5}>已选:{data[selectAdz - 1]?.corp?.length || 0}</Title>
+                <div style={{ margin: '0 0 5px', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
+                    <Title level={5} style={{ margin: 0 }}>已选:{data[selectAdz - 1]?.corp?.length || 0}</Title>
+                    {data.length > 1 && <a style={{ color: 'red' }} onClick={() => {
+                        if (selectAdz === data.length) {
+                            handleSelectAdz(selectAdz - 1)
+                        } else {
+                            handleSelectAdz(selectAdz)
+                        }
+                        const newData = data.filter((_, index) => index !== selectAdz - 1)
+                        setData(newData)
+                    }}>删除组</a>}
+                </div>
                 <div className={style.select_content}>
                     {data[selectAdz - 1]?.corp?.map(item => <div key={item.value}>
                         <Text ellipsis={{ tooltip: true }} className={style.marketingAssetName}>{item.label}</Text>

+ 94 - 91
src/pages/weComTask/page/groupChatSend/official/create/index.tsx

@@ -9,7 +9,7 @@ import Strategy from './components/Strategy';
 import { getBindMpListApi } from '@/pages/weComTask/API/corpUserAssign';
 import { DefaultOptionType } from 'antd/es/select';
 import { getCorpAllListApi } from '@/API/global';
-import { SaveOutlined, RedoOutlined, SearchOutlined, PlusOutlined, CheckOutlined } from '@ant-design/icons';
+import { SaveOutlined, RedoOutlined, SearchOutlined, PlusOutlined } from '@ant-design/icons';
 import Content from './components/content';
 import { groupBy, removeEmptyValues } from '@/utils/utils';
 import { PreviewColumns } from './tableConfig';
@@ -17,7 +17,7 @@ import SubmitModal from '../../../businessPlan/create/submitModal';
 import { addTaskApi, getCreateDetailsApi, updateTaskApi } from '@/pages/weComTask/API/businessPlan/create';
 import { useNavigate } from 'react-router-dom';
 import { getGroupChatSendData } from './const';
-import SelectMpCorp from './components/SelectMpCorp';
+import GroupChatGroups from '@/pages/weComTask/components/groupChatGroups';
 
 
 export const DispatchOfficialChatCreate = React.createContext<OFFICIAL_CHAT_CREATE.DispatchOfficialChatCreate | null>(null);
@@ -40,7 +40,6 @@ const OfficialCreate: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE
     const [corpList, setCorpList] = useState<DefaultOptionType[]>([])
     const [previewContent, setPreviewContent] = useState<{ [x: string]: { [x: string]: string } }>({})
     const [subVisible, setSubVisible] = useState<boolean>(false) // 选择设置名称弹窗控制
-    const [corpVisible, setCorpVisible] = useState<boolean>(false)
 
     const welcomeMsgJobType = useAjax(() => welcomeMsgJobTypeApi())//获取业务类型
     const getBindMpList = useAjax(() => getBindMpListApi())
@@ -59,26 +58,84 @@ const OfficialCreate: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE
                 setProjectId(id)
             }
             getCreateDetails.run(id).then(res => {
-                sessionStorage.removeItem('PGSD_OFFICIALTASKID')
+                // sessionStorage.removeItem('PGSD_OFFICIALTASKID')
                 if (res?.data) {
                     const { bizType, platform, templateProductId, channel, groupChatSendTaskAddDTO, mpAccounts } = res.data
+                    const group = mpAccounts.map(m => {
+                            return {
+                                mpAccount: m?.mpAccountVO?.name ? {
+                                    label: m?.mpAccountVO?.name || '',
+                                    value: m?.mpAccountVO?.id || '',
+                                    appId: m?.mpAccountVO?.appId || '',
+                                } : undefined,
+                                corp: m?.corpVOList?.map(c => ({ label: c.corpName, value: c.corpId })) || []
+                            }
+                        })
                     let newSettings: OFFICIAL_CHAT_CREATE.SettingsProps = {
                         bizType,
                         platform: Number(platform) as any,
                         templateProductId,
                         channel,
-                        mpAccount: mpAccounts.map(m => {
-                            return {
-                                label: m?.mpAccountVO?.name || '',
-                                value: m?.mpAccountVO?.id || '',
-                                appId: m?.mpAccountVO?.appId || '',
-                                corp: m?.corpVOList?.map(c => ({ label: c.corpName, value: c.corpId })) || []
-                            }
-                        })
+                        group
                     }
                     if (groupChatSendTaskAddDTO && Object.keys(groupChatSendTaskAddDTO).length > 0) {
                         const data = getGroupChatSendData(groupChatSendTaskAddDTO)
                         newSettings = { ...newSettings, strategyDTO: data }
+
+                        // 处理链接小程序 历史数据
+                        const list: any[] = []
+                        data?.strategyList?.forEach((str, s_index) => {
+                            str?.sendData?.forEach((sd, f_index) => {
+                                sd?.contentDTO?.forEach((cd, c_index) => {
+                                    if (cd?.attachmentList?.length || cd?.text?.content) {
+                                        const mediaItem = JSON.parse(JSON.stringify(cd?.attachmentList || []))
+                                        if (cd?.text?.content) {
+                                            mediaItem.push({
+                                                msgType: 'TASK_CONTENT_TEXT',
+                                                textContent: cd?.text?.content
+                                            })
+                                        }
+                                        const linkData = []
+                                        const miniProgramData = []
+                                        mediaItem.forEach(item => {
+                                            switch (item.msgType) {
+                                                case 'TASK_CONTENT_LINK':
+                                                    linkData.push(item)
+                                                    break
+                                                case 'TASK_STATUS_MINIPROGRAM':
+                                                    miniProgramData.push(item)
+                                                    break
+                                            }
+                                        })
+                                        list.push({
+                                            strategyIndex: s_index,
+                                            sendIndex: f_index,
+                                            contentIndex: c_index,
+                                            linkData,
+                                            miniProgramData
+                                        })
+                                        return true
+                                    }
+                                })
+                            })
+                        })
+                        let id = 1
+                        const newPreviewContent: { [x: string]: { [x: string]: string } } = {}
+                        group.forEach((g, g_index) => {
+                            list.forEach((l) => {
+                                const { strategyIndex, sendIndex, contentIndex, linkData, miniProgramData } = l
+                                if (linkData || miniProgramData) {
+                                    const content = mpAccounts?.[g_index]?.groupChatMsgContent?.[strategyIndex]?.[sendIndex]?.[contentIndex]
+                                    newPreviewContent[id] = {
+                                        linkUrl: content?.linkUrl,
+                                        miniprogramAppid: content?.miniprogramAppid,
+                                        miniprogramPage: content?.miniprogramPage
+                                    }
+                                }
+                                id++
+                            })
+                        })
+                        setPreviewContent(newPreviewContent)
                     }
                     setSettings(newSettings)
                 }
@@ -111,12 +168,11 @@ const OfficialCreate: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE
         })
     }, [])
 
-    console.log('settings--->', settings)
-
     // 重置表格
     const onPreviewReset = () => {
         setPreviewData([])
         setPreviewDataOld([])
+        setPreviewContent({})
     }
 
     const severBd = () => {
@@ -126,16 +182,12 @@ const OfficialCreate: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE
 
     // 预览
     const preview = () => {
-        const { bizType, platform, templateProductId, channel, mpAccount } = settings
+        const { bizType, platform, templateProductId, channel, group } = settings
         if (!(settings?.strategyDTO && Object.keys(settings?.strategyDTO).length > 0)) {
             message.error('请先配置内容')
             return
         }
-        if (!mpAccount?.length) {
-            message.error('请选择公众号')
-            return
-        }
-        if (mpAccount.some(item => !item?.corp?.length)) {
+        if (group.some(item => !item?.corp?.length)) {
             message.error('请选择关联主体')
             return
         }
@@ -216,14 +268,14 @@ const OfficialCreate: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE
             return
         }
         let id = 1
-        const newPreviewData = mpAccount.reduce((pre, cur, index) => {
+        const newPreviewData = group.reduce((pre, cur, index) => {
             return pre.concat(...list.map((item, i) => {
                 return {
                     ...item,
                     id: id++,
-                    mpAccountId: cur.value,
-                    mpAccountName: cur.label,
-                    mpAccountAppid: (cur as any).appId,
+                    mpAccountId: cur?.mpAccount.value || index,
+                    mpAccountName: cur?.mpAccount.label || `群发组${index + 1}`,
+                    mpAccountAppid: (cur as any)?.mpAccount.appId,
                     corpIds: cur.corp?.map(item => item.value),
                     corpNames: cur.corp?.map(item => item.label),
                     mpIndex: index,
@@ -231,10 +283,8 @@ const OfficialCreate: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE
                 }
             }))
         }, [])
-        console.log('=========================>', list, newPreviewData)
         setPreviewData(newPreviewData)
         setPreviewDataOld(newPreviewData)
-        setPreviewContent({})
     }
 
     const tableSearch = useCallback((values) => {
@@ -265,25 +315,25 @@ const OfficialCreate: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE
     }
 
     const onSubmit = (values: any) => {
-        const groupData = groupBy(previewDataOld, (item) => item['mpAccountId'], true);
-        const { bizType, platform, templateProductId, channel, strategyDTO, mpAccount } = settings
+        const groupData = groupBy(previewDataOld, (item) => item['mpIndex'], true);
+        const { bizType, platform, templateProductId, channel, strategyDTO, group } = settings
         const params = {
             ...values,
             bizType,
             platform,
             templateProductId,
             channel,
-            mpAccounts: mpAccount.map(item => {
-                const data = groupData[item.value] || []
+            mpAccounts: group.map((item, index) => {
+                const data = groupData[index] || []
                 const groupChatMsgContent: any[] = []
                 data.forEach(d => {
                     const { strategyIndex, sendIndex, contentIndex, id } = d
                     if (!groupChatMsgContent[strategyIndex]) groupChatMsgContent[strategyIndex] = [];
-                    if (!groupChatMsgContent[strategyIndex][sendIndex]) groupChatMsgContent[strategyIndex][sendIndex] = [];    
-                    groupChatMsgContent[strategyIndex][sendIndex][contentIndex] = previewContent?.[id] || {};    
+                    if (!groupChatMsgContent[strategyIndex][sendIndex]) groupChatMsgContent[strategyIndex][sendIndex] = [];
+                    groupChatMsgContent[strategyIndex][sendIndex][contentIndex] = previewContent?.[id] || {};
                 })
                 return {
-                    mpAccountId: item.value,
+                    mpAccountId: item?.mpAccount.value,
                     corpIds: item.corp?.map(c => c.value) || [],
                     groupChatMsgContent
                 }
@@ -352,45 +402,20 @@ const OfficialCreate: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE
             <Card title={<strong>{projectId ? getCreateDetails?.data?.data?.projectName + '任务编辑' : ''}配置区</strong>} className={`${style.card} ${style.config}`}>
                 <Space wrap>
                     <Space.Compact>
-                        <Button>群聊关联公众号</Button>
-                        <Select
-                            showSearch
-                            allowClear
-                            placeholder="选择公众号"
-                            filterOption={(input, option) =>
-                                (option?.label as any)?.toLowerCase().indexOf(input.toLowerCase()) >= 0
-                            }
-                            style={{ minWidth: 200 }}
-                            maxTagCount={1}
-                            mode='multiple'
-                            options={mpList}
-                            value={settings?.mpAccount?.map(item => item.value)}
-                            onChange={(_, options) => {
+                        <Button>群发组</Button>
+                        <GroupChatGroups
+                            mpList={mpList}
+                            corpList={corpList}
+                            value={settings?.group}
+                            onChange={(group) => {
+                                setSettings({
+                                    ...settings,
+                                    group
+                                })
                                 onPreviewReset()
-                                if (options.length > 0) {
-                                    const oldMpAccountIds = settings?.mpAccount?.reduce((acc, item) => {
-                                        acc[item.value] = item;
-                                        return acc;
-                                    }, {}) || []
-                                    setSettings({
-                                        ...settings,
-                                        mpAccount: options.map(item => {
-                                            if (oldMpAccountIds?.[item.value]) {
-                                                return oldMpAccountIds[item.value]
-                                            }
-                                            return item
-                                        })
-                                    })
-                                } else {
-                                    setSettings({ ...settings, mpAccount: [] })
-                                }
                             }}
                         />
                     </Space.Compact>
-                    {settings?.mpAccount?.length > 0 && <Button onClick={() => setCorpVisible(true)}>
-                        选择关联主体
-                        {settings?.mpAccount?.some(item => item?.corp?.length) && <CheckOutlined style={{ color: settings?.mpAccount?.every(item => item?.corp?.length) ? '#1890ff' : '#52C41A' }} />}
-                    </Button>}
                     <Space.Compact>
                         <Button>业务类型</Button>
                         <Select
@@ -552,11 +577,7 @@ const OfficialCreate: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE
                     rowKey={'id'}
                     bordered={true}
                     scroll={{ y: 550 }}
-                    pagination={{
-                        showTotal(total, range) {
-                            return `共 ${total} 条记录 第 ${range[0]}-${range[1]} 条`
-                        },
-                    }}
+                    pagination={false}
                 />
             </div> : <div style={{ minHeight: 400, display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
                 <Empty description="请先完成模块配置后,再预览" />
@@ -575,24 +596,6 @@ const OfficialCreate: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE
                 setSubVisible(false)
             }}
         />}
-
-        {/* 选择关联主体 */}
-        {corpVisible && <SelectMpCorp
-            corpList={corpList}
-            visible={corpVisible}
-            mpAccount={settings?.mpAccount}
-            onChange={(mpAccount) => {
-                setSettings({
-                    ...settings,
-                    mpAccount
-                })
-                setCorpVisible(false)
-                onPreviewReset()
-            }}
-            onClose={() => {
-                setCorpVisible(false)
-            }}
-        />}
     </div>;
 };
 

+ 1 - 1
src/pages/weComTask/page/groupChatSend/official/create/tableConfig.tsx

@@ -12,7 +12,7 @@ export const PreviewColumns = (bookPlatForm: TASK_CREATE.BookPlatFormProps[], bo
 
     return [
         {
-            title: '群聊关公众号',
+            title: '群聊关公众号',
             dataIndex: 'mpAccountName',
             key: 'mpAccountName',
             width: 120,

+ 7 - 5
src/pages/weComTask/page/groupChatSend/official/typings.d.ts

@@ -8,15 +8,17 @@ declare namespace OFFICIAL_CHAT_CREATE {
         mpList: DefaultOptionType[]
         corpList: DefaultOptionType[]
     }
-    interface MpAccountProps {
-        label: string;
-        value: number;
-        appid: string; // 公众号appid
+    interface GroupsProps {
+        mpAccount?: {
+            label: string;
+            value: number;
+            appid: string; // 公众号appid
+        }
         corp?: any[];
     }
     // 官方群发创建参数配置
     interface SettingsProps {
-        mpAccount?: MpAccountProps[];
+        group?: groupsProps[];
         bizType?: string; // 业务类型
         platform?: string; // 书城
         channel?: string;   // 渠道

+ 114 - 90
src/pages/weComTask/page/groupChatSend/robot/create/index.tsx

@@ -17,7 +17,7 @@ import SubmitModal from '../../../businessPlan/create/submitModal';
 import { addTaskApi, getCreateDetailsApi, updateTaskApi } from '@/pages/weComTask/API/businessPlan/create';
 import { useNavigate } from 'react-router-dom';
 import { getRobotSendData, transformData } from './const';
-import SelectMpCorp from '../../official/create/components/SelectMpCorp';
+import GroupChatGroups from '@/pages/weComTask/components/groupChatGroups';
 
 
 export const DispatchRobotChatCreate = React.createContext<ROBOT_CHAT_CREATE.DispatchRobotChatCreate | null>(null);
@@ -40,7 +40,6 @@ const OfficialCreate: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE
     const [corpList, setCorpList] = useState<DefaultOptionType[]>([])
     const [previewContent, setPreviewContent] = useState<{ [x: string]: { [x: string]: string } }>({})
     const [subVisible, setSubVisible] = useState<boolean>(false) // 选择设置名称弹窗控制
-    const [corpVisible, setCorpVisible] = useState<boolean>(false)
     const [corpGroupChat, setCorpGroupChat] = useState<{ [x: string]: any }>({})
 
     const welcomeMsgJobType = useAjax(() => welcomeMsgJobTypeApi())//获取业务类型
@@ -63,25 +62,103 @@ const OfficialCreate: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE
                 sessionStorage.removeItem('ROBOT_OFFICIALTASKID')
                 if (res?.data) {
                     const { bizType, platform, templateProductId, channel, robotGroupChatSendTaskAddDTO, mpAccounts } = res.data
+                    const group = mpAccounts.map(m => {
+                        return {
+                            mpAccount: m?.mpAccountVO?.name ? {
+                                label: m?.mpAccountVO?.name || '',
+                                value: m?.mpAccountVO?.id || '',
+                                appId: m?.mpAccountVO?.appId || '',
+                            } : undefined,
+                            corp: m?.corpVOList?.map(c => ({ label: c.corpName, value: c.corpId })) || []
+                        }
+                    })
                     let newSettings: ROBOT_CHAT_CREATE.SettingsProps = {
                         bizType,
                         platform: Number(platform) as any,
                         templateProductId,
                         channel,
-                        mpAccount: mpAccounts.map(m => {
-                            return {
-                                label: m?.mpAccountVO?.name || '',
-                                value: m?.mpAccountVO?.id || '',
-                                appId: m?.mpAccountVO?.appId || '',
-                                corp: m?.corpVOList?.map(c => ({ label: c.corpName, value: c.corpId })) || []
-                            }
-                        })
+                        group
                     }
+
                     if (robotGroupChatSendTaskAddDTO && Object.keys(robotGroupChatSendTaskAddDTO).length > 0) {
                         const data = getRobotSendData(robotGroupChatSendTaskAddDTO)
                         newSettings = { ...newSettings, strategyDTO: data }
+                        
+                        // 处理链接小程序 历史数据
+                        const list: any[] = []
+                        data?.strategyList?.forEach((str, s_index) => {
+                            str?.sendData?.forEach((sd, f_index) => {
+                                sd?.contentDTO?.forEach((cd, c_index) => {
+                                    if (cd?.attachmentList?.length || cd?.text?.content) {
+                                        const mediaItem = JSON.parse(JSON.stringify(cd?.attachmentList || []))
+                                        if (cd?.text?.content) {
+                                            mediaItem.push({
+                                                msgType: 'TASK_CONTENT_TEXT',
+                                                textContent: cd?.text?.content
+                                            })
+                                        }
+                                        const linkData = []
+                                        const miniProgramData = []
+                                        mediaItem.forEach(item => {
+                                            switch (item.msgType) {
+                                                case 'TASK_CONTENT_LINK':
+                                                    linkData.push(item)
+                                                    break
+                                                case 'TASK_STATUS_MINIPROGRAM':
+                                                    miniProgramData.push(item)
+                                                    break
+                                            }
+                                        })
+                                        list.push({
+                                            strategyIndex: s_index,
+                                            sendIndex: f_index,
+                                            contentIndex: c_index,
+                                            linkData,
+                                            miniProgramData
+                                        })
+                                        return true
+                                    }
+                                })
+                            })
+                        })
+                        let id = 1
+                        const newPreviewContent: { [x: string]: { [x: string]: string } } = {}
+                        group.forEach((g, g_index) => {
+                            list.forEach((l) => {
+                                const { strategyIndex, sendIndex, contentIndex, linkData, miniProgramData } = l
+                                if (linkData || miniProgramData) {
+                                    const content = mpAccounts?.[g_index]?.groupChatMsgContent?.[strategyIndex]?.[sendIndex]?.[contentIndex]
+                                    newPreviewContent[id] = {
+                                        linkUrl: content?.linkUrl,
+                                        miniprogramAppid: content?.miniprogramAppid,
+                                        miniprogramPage: content?.miniprogramPage
+                                    }
+                                }
+                                id++
+                            })
+                        })
+                        setPreviewContent(newPreviewContent)
                     }
                     setSettings(newSettings)
+
+                    // 处理群素材历史数据
+                    const newCorpGroupChat: { [x: string]: any } = {}
+                    mpAccounts.forEach((m, m_index) => {
+                        m?.corpGroupChat?.forEach((c, c_index) => {
+                            c?.forEach((i, i_index) => {
+                                newCorpGroupChat[m_index + '_' + c_index + '_' + i_index] = {
+                                    chatCorpId: i.corpId,
+                                    corpGroupChat: {
+                                        chatId: i?.chatId,
+                                        chatName: i?.chatName,
+                                        corpId: i?.corpId,
+                                        corpName: i?.corpName
+                                    }
+                                }
+                            })
+                        })
+                    })
+                    setCorpGroupChat(newCorpGroupChat)
                 }
             })
         } else {
@@ -118,6 +195,8 @@ const OfficialCreate: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE
     const onPreviewReset = () => {
         setPreviewData([])
         setPreviewDataOld([])
+        setPreviewContent({})
+        setCorpGroupChat({})
     }
 
     const severBd = () => {
@@ -127,16 +206,12 @@ const OfficialCreate: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE
 
     // 预览
     const preview = () => {
-        const { bizType, platform, templateProductId, channel, mpAccount } = settings
+        const { bizType, platform, templateProductId, channel, group } = settings
         if (!(settings?.strategyDTO && Object.keys(settings?.strategyDTO).length > 0)) {
             message.error('请先配置内容')
             return
         }
-        if (!mpAccount?.length) {
-            message.error('请选择公众号')
-            return
-        }
-        if (mpAccount.some(item => !item?.corp?.length)) {
+        if (group.some(item => !item?.corp?.length)) {
             message.error('请选择关联主体')
             return
         }
@@ -228,14 +303,14 @@ const OfficialCreate: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE
             return
         }
         let id = 1
-        const newPreviewData = mpAccount.reduce((pre, cur, index) => {
+        const newPreviewData = group.reduce((pre, cur, index) => {
             return pre.concat(...list.map((item, i) => {
                 return {
                     ...item,
                     id: id++,
-                    mpAccountId: cur.value,
-                    mpAccountName: cur.label,
-                    mpAccountAppid: (cur as any).appId,
+                    mpAccountId: cur?.mpAccount?.value || index,
+                    mpAccountName: cur?.mpAccount?.label || `群发组${index + 1}`,
+                    mpAccountAppid: (cur as any)?.mpAccount?.appId,
                     corpIds: cur.corp?.map(item => item.value),
                     corpNames: cur.corp?.map(item => item.label),
                     mpIndex: index,
@@ -246,8 +321,6 @@ const OfficialCreate: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE
         console.log('=========================>', newPreviewData)
         setPreviewData(newPreviewData)
         setPreviewDataOld(newPreviewData)
-        setPreviewContent({})
-        setCorpGroupChat({})
     }
 
     const tableSearch = useCallback((values) => {
@@ -265,8 +338,8 @@ const OfficialCreate: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE
     }, [previewDataOld, previewData])
 
     const setTaskName = () => {
-        if (!settings.mpAccount?.every((mp) => settings?.strategyDTO?.strategyList?.every((str, s_index) => str.sendData?.every((sd, f_index) => {
-            const chat = corpGroupChat?.[mp.value + '_' + s_index + '_' + f_index]
+        if (!settings.group?.every((_, index) => settings?.strategyDTO?.strategyList?.every((str, s_index) => str.sendData?.every((sd, f_index) => {
+            const chat = corpGroupChat?.[index + '_' + s_index + '_' + f_index]
             return chat?.chatCorpId && chat?.corpGroupChat
         })))) {
             message.error('请补充群聊主体等信息')
@@ -285,18 +358,17 @@ const OfficialCreate: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE
     }
 
     const onSubmit = (values: any) => {
-        console.log('---------->', corpGroupChat, transformData(corpGroupChat))
         const corpGroupChatData = transformData(corpGroupChat)
-        const groupData = groupBy(previewDataOld, (item) => item['mpAccountId'], true);
-        const { bizType, platform, templateProductId, channel, strategyDTO, mpAccount } = settings
+        const groupData = groupBy(previewDataOld, (item) => item['mpIndex'], true);
+        const { bizType, platform, templateProductId, channel, strategyDTO, group } = settings
         const params = {
             ...values,
             bizType,
             platform,
             templateProductId,
             channel,
-            mpAccounts: mpAccount.map(item => {
-                const data = groupData[item.value] || []
+            mpAccounts: group.map((item, index) => {
+                const data = groupData[index] || []
                 const groupChatMsgContent: any[] = []
                 data.forEach(d => {
                     const { strategyIndex, sendIndex, contentIndex, id } = d
@@ -305,10 +377,10 @@ const OfficialCreate: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE
                     groupChatMsgContent[strategyIndex][sendIndex][contentIndex] = previewContent?.[id] || {};
                 })
                 return {
-                    mpAccountId: item.value,
+                    mpAccountId: item?.mpAccount?.value,
                     corpIds: item.corp?.map(c => c.value) || [],
                     groupChatMsgContent,
-                    corpGroupChat: corpGroupChatData[item.value]
+                    corpGroupChat: corpGroupChatData[index]
                 }
             }),
             robotChatSendTaskAddDTO: {
@@ -340,7 +412,6 @@ const OfficialCreate: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE
                 })
             }
         }
-        console.log('--->', params)
         if (projectId) {
             params.projectId = projectId
             updateTask.run(params).then(res => {
@@ -378,45 +449,20 @@ const OfficialCreate: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE
             <Card title={<strong>{projectId ? getCreateDetails?.data?.data?.projectName + '任务编辑' : ''}配置区</strong>} className={`${style.card} ${style.config}`}>
                 <Space wrap>
                     <Space.Compact>
-                        <Button>群聊关联公众号</Button>
-                        <Select
-                            showSearch
-                            allowClear
-                            placeholder="选择公众号"
-                            filterOption={(input, option) =>
-                                (option?.label as any)?.toLowerCase().indexOf(input.toLowerCase()) >= 0
-                            }
-                            style={{ minWidth: 200 }}
-                            maxTagCount={1}
-                            mode='multiple'
-                            options={mpList}
-                            value={settings?.mpAccount?.map(item => item.value)}
-                            onChange={(_, options) => {
+                        <Button>群发组</Button>
+                        <GroupChatGroups
+                            mpList={mpList}
+                            corpList={corpList}
+                            value={settings?.group}
+                            onChange={(group) => {
+                                setSettings({
+                                    ...settings,
+                                    group
+                                })
                                 onPreviewReset()
-                                if (options.length > 0) {
-                                    const oldMpAccountIds = settings?.mpAccount?.reduce((acc, item) => {
-                                        acc[item.value] = item;
-                                        return acc;
-                                    }, {}) || []
-                                    setSettings({
-                                        ...settings,
-                                        mpAccount: options.map(item => {
-                                            if (oldMpAccountIds?.[item.value]) {
-                                                return oldMpAccountIds[item.value]
-                                            }
-                                            return item
-                                        })
-                                    })
-                                } else {
-                                    setSettings({ ...settings, mpAccount: [] })
-                                }
                             }}
                         />
                     </Space.Compact>
-                    {settings?.mpAccount?.length > 0 && <Button onClick={() => setCorpVisible(true)}>
-                        选择关联主体
-                        {settings?.mpAccount?.some(item => item?.corp?.length) && <CheckOutlined style={{ color: settings?.mpAccount?.every(item => item?.corp?.length) ? '#1890ff' : '#52C41A' }} />}
-                    </Button>}
                     <Space.Compact>
                         <Button>业务类型</Button>
                         <Select
@@ -578,11 +624,7 @@ const OfficialCreate: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE
                     rowKey={'id'}
                     bordered={true}
                     scroll={{ y: 550 }}
-                    pagination={{
-                        showTotal(total, range) {
-                            return `共 ${total} 条记录 第 ${range[0]}-${range[1]} 条`
-                        },
-                    }}
+                    pagination={false}
                 />
             </div> : <div style={{ minHeight: 400, display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
                 <Empty description="请先完成模块配置后,再预览" />
@@ -601,24 +643,6 @@ const OfficialCreate: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE
                 setSubVisible(false)
             }}
         />}
-
-        {/* 选择关联主体 */}
-        {corpVisible && <SelectMpCorp
-            corpList={corpList}
-            visible={corpVisible}
-            mpAccount={settings?.mpAccount}
-            onChange={(mpAccount) => {
-                setSettings({
-                    ...settings,
-                    mpAccount
-                })
-                setCorpVisible(false)
-                onPreviewReset()
-            }}
-            onClose={() => {
-                setCorpVisible(false)
-            }}
-        />}
     </div>;
 };
 

+ 2 - 2
src/pages/weComTask/page/groupChatSend/robot/create/tableConfig.tsx

@@ -125,7 +125,7 @@ export const PreviewColumns = (
             key: 'chatCorpId',
             width: 250,
             render(_, record) {
-                const key = record.mpAccountId + '_' + record.strategyIndex + '_' + record.sendIndex
+                const key = record.mpIndex + '_' + record.strategyIndex + '_' + record.sendIndex
                 return <Select
                     showSearch
                     allowClear
@@ -154,7 +154,7 @@ export const PreviewColumns = (
             key: 'corpGroupChat',
             width: 250,
             render(_, record) {
-                const key = record.mpAccountId + '_' + record.strategyIndex + '_' + record.sendIndex
+                const key = record.mpIndex + '_' + record.strategyIndex + '_' + record.sendIndex
                 return corpGroupChat?.[key]?.chatCorpId ? <SelectGroupChat
                     corpId={corpGroupChat?.[key]?.chatCorpId}
                     value={corpGroupChat?.[key]?.corpGroupChat as any}

+ 9 - 1
src/pages/weComTask/page/groupChatSend/robot/typings.d.ts

@@ -8,9 +8,17 @@ declare namespace ROBOT_CHAT_CREATE {
         mpList: DefaultOptionType[]
         corpList: DefaultOptionType[]
     }
+    interface GroupsProps {
+        mpAccount?: {
+            label: string;
+            value: number;
+            appid: string; // 公众号appid
+        }
+        corp?: any[];
+    }
     // 官方群发创建参数配置
     interface SettingsProps {
-        mpAccount?: MpAccountProps[];
+        group?: GroupsProps[];
         bizType?: string; // 业务类型
         platform?: string; // 书城
         channel?: string;   // 渠道