123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523 |
- import React, { useCallback, useEffect, useState } from 'react';
- import style from '../../businessPlan/create/index.less'
- import { useAjax } from '@/Hook/useAjax';
- import { welcomeMsgJobTypeApi } from '@/pages/weComTask/API/weMaterial/weMaterial';
- import { addTaskApi, getCreateDetailsApi, updateTaskApi } from '@/pages/weComTask/API/businessPlan/create';
- import { getBindMpListApi } from '@/pages/weComTask/API/corpUserAssign';
- import { App, Button, Card, Empty, Form, Input, Popconfirm, Select, Space, Spin, Table } from 'antd';
- import SelectCorpUserGroup from '../../corpUserManage/selectCorpUserGroup';
- import { useNavigate } from 'react-router-dom';
- import { toJS } from 'mobx';
- import { inject, observer } from 'mobx-react';
- import Strategy from './components/Strategy';
- import Content from './components/content';
- import { SaveOutlined, RedoOutlined, SearchOutlined, PlusOutlined } from '@ant-design/icons';
- import SelectCorpUser from '../../corpUserManage/selectCorpUser';
- import { monmentsColumns } from './tableConfig';
- import SubmitModal from '../../businessPlan/create/submitModal';
- import { groupBy } from '@/utils/utils';
- export const DispatchMomentsTaskCreate = React.createContext<TASK_MOMENTS_CREATE.DispatchMomentsTaskCreate | null>(null);
- /**
- * 朋友圈创建
- * @param param0
- * @returns
- */
- const MomentsCreatePage: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE.BookListProps[], bookPlatForm: TASK_CREATE.BookPlatFormProps[] } } }> = ({ weComTaskStore }) => {
- /*************************************/
- const navigate = useNavigate();
- const { bookList, bookPlatForm } = toJS(weComTaskStore.data)
- const { message, modal } = App.useApp()
- const [settings, setSettings] = useState<TASK_MOMENTS_CREATE.SettingsProps>();
- const [msgJobTypeList, setMsgJobTypeList] = useState<{ value: string, label: string }[]>([])
- const [previewData, setPreviewData] = useState<TASK_MOMENTS_CREATE.previewDataProps>([])
- const [previewDataOld, setPreviewDataOld] = useState<TASK_MOMENTS_CREATE.previewDataProps>([])
- const [mpList, setMplist] = useState<{ label: string, value: number }[]>([])
- const [previewContent, setPreviewContent] = useState<{ [x: string]: any }>({})
- const [projectId, setProjectId] = useState<number>()
- const [subVisible, setSubVisible] = useState<boolean>(false) // 选择设置名称弹窗控制
- const welcomeMsgJobType = useAjax(() => welcomeMsgJobTypeApi())//获取欢迎语类型
- const addTask = useAjax((params) => addTaskApi(params))
- const updateTask = useAjax((params) => updateTaskApi(params))
- const getCreateDetails = useAjax((params) => getCreateDetailsApi(params))
- const getBindMpList = useAjax(() => getBindMpListApi())
- /*************************************/
- useEffect(() => {
- const project = sessionStorage.getItem('MOMENTSTASKID')
- if (project) {
- const { id, isCopy } = JSON.parse(project)
- if (!isCopy) {
- setProjectId(id)
- }
- getCreateDetails.run(id).then(res => {
- sessionStorage.removeItem('MOMENTSTASKID')
- if (res?.data) {
- const { corpUsers, bizType, platform, templateProductId, momentCreateDTO } = res.data
- const corpUserGroups = corpUsers.map(item => {
- return {
- corpUsers: item.corpUserList.map(({ corpUserId, name, corpId, mpAccountId, mpAccountInfo, id }) => {
- return { id: id || (corpId + '_' + corpUserId), corpUserId, name, corpName: item.corpName, corpId, mpAccountId, mpAccountName: mpAccountInfo?.name }
- })
- }
- })
- const newSettings: TASK_MOMENTS_CREATE.SettingsProps = {
- bizType,
- platform: Number(platform) as any,
- templateProductId,
- corpUserGroups,
- massSendingStrategy: {
- momentSendName: momentCreateDTO?.momentSendName || '',
- strategyList: momentCreateDTO?.strategyList || []
- }
- }
- setSettings(newSettings)
- let id = 1;
- const newPreviewContent: { [x: string]: any } = {};
- corpUsers.forEach((cu) => {
- const momentSendContent = cu?.momentSendContent;
- (momentCreateDTO?.strategyList || []).forEach((str, s_index) => {
- const { taskDetail } = str
- taskDetail?.contentDTO?.forEach((_, c_index) => {
- const content = momentSendContent?.[s_index]?.[c_index] || {}
- newPreviewContent[id] = content
- id++;
- })
- });
- })
- setPreviewContent(newPreviewContent)
- }
- })
- } else {
- const task = localStorage.getItem('TASK_MOMENTS_CREATE')
- if (task) {
- setSettings(JSON.parse(task).settings)
- }
- }
- }, [])
- useEffect(() => {
- welcomeMsgJobType.run().then(res => {
- if (res?.data) {
- setMsgJobTypeList(Object.keys(res.data).map(key => ({ value: key, label: res.data[key] })))
- }
- })
- getBindMpList.run().then(res => {
- setMplist(res?.data?.map((item: any) => ({ label: item.name, value: item.id })))
- })
- }, [])
- // 预览
- const preview = () => {
- const { bizType, platform, templateProductId, channel, massSendingStrategy, corpUserGroups } = settings
- if (!corpUserGroups || corpUserGroups?.length === 0) {
- message.error('请先选择客服号')
- return
- }
- if (!bizType) {
- message.error('请选择业务类型')
- return
- }
- if (!platform) {
- message.error('请选择书城')
- return
- }
- const list: any[] = []
- if (!massSendingStrategy?.strategyList?.every((str, s_index) => {
- const { taskDetail, ...sdto } = str
- if (taskDetail?.contentDTO?.length) {
- return taskDetail?.contentDTO?.every((cd, c_index, row) => {
- 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 = []
- const contentReactNode = mediaItem.map(item => {
- switch (item.msgType) {
- case 'TASK_CONTENT_LINK':
- linkData.push(item)
- return `<span style="color: red">链接</span>`
- case 'TASK_STATUS_MINIPROGRAM':
- miniProgramData.push(item)
- return `<span style="color: red">小程序</span>`
- case 'TASK_STATUS_FILE':
- return `<span>文件</span>`
- case 'TASK_STATUS_VIDEO':
- return `<span>视频</span>`
- case 'TASK_CONTENT_IMAGE':
- return `<span>图片</span>`
- case 'TASK_CONTENT_TEXT':
- return `<span>文本</span>`
- default:
- return `<span style="color: red">请联系管理员</span>`
- }
- })
- list.push({
- bizType,
- platform,
- templateProductId,
- channel,
- taskName: settings?.massSendingStrategy?.momentSendName,
- strategyData: sdto,
- contentReactNode,
- content: cd,
- strategyIndex: s_index,
- contentIndex: c_index,
- linkData,
- miniProgramData,
- strategyRowSpan: c_index === 0 ? row.length : 0,
- })
- return true
- } else {
- message.error(`策略:${str?.strategyName}请填写发送内容`)
- return false
- }
- })
- } else {
- message.error(`策略:${str?.strategyName}请填写发送内容`)
- return false
- }
- })) {
- return
- }
- let id = 1
- const newPreviewData = corpUserGroups.reduce((pre, cur, index) => {
- return pre.concat(...list.map((item, i) => {
- return {
- ...item,
- id: id++,
- corpUserGroupName: `客服组${index + 1}`,
- corpUsers: cur.corpUsers,
- mpAccountId: cur.corpUsers?.[0]?.mpAccountId,
- mpAccountName: cur.corpUsers?.[0]?.mpAccountName,
- corpUserStrList: cur.corpUsers?.map(item => item.corpId + '_' + item.corpUserId),
- groupIndex: index,
- groupRowSpan: i === 0 ? list.length : 0, // 用于表格合并
- }
- }))
- }, [])
- console.log(newPreviewData)
- setPreviewData(newPreviewData)
- setPreviewDataOld(newPreviewData)
- }
- const setTaskName = () => {
- if (previewDataOld.every((item, index) => {
- if ((item?.linkData?.length > 0 ? previewContent?.[index + 1]?.linkUrl : true) && (item?.miniProgramData?.length > 0 ? (previewContent?.[index + 1]?.miniprogramAppid && previewContent?.[index + 1]?.miniprogramPage) : true)) {
- return true
- } else {
- message.error('请补充图文或者小程序内容')
- return false
- }
- })) {
- setSubVisible(true)
- }
- }
- const onSubmit = (values: any) => {
- const groupData = groupBy(previewDataOld, (item) => item['groupIndex'], true);
- const { bizType, platform, templateProductId, corpUserGroups, massSendingStrategy } = settings
- const params = {
- ...values,
- bizType,
- platform,
- templateProductId,
- corpUsers: corpUserGroups?.map((item, index) => {
- const params: { [x: string]: any } = {
- corpId: item.corpUsers[0].corpId,
- corpUserIds: item.corpUsers.map(item => item.corpUserId)
- }
- const data = groupData[index] || []
- const momentSendContent: any[] = []
- data.forEach(d => {
- const { strategyIndex, contentIndex, id } = d
- if (!momentSendContent[strategyIndex]) momentSendContent[strategyIndex] = [];
- momentSendContent[strategyIndex][contentIndex] = previewContent?.[id] || {};
- })
- params.momentSendContent = momentSendContent
- return params
- })
- }
- params.momentCreateDTO = {
- momentSendName: massSendingStrategy.momentSendName,
- strategyList: massSendingStrategy?.strategyList
- }
- if (projectId) {
- params.projectId = projectId
- updateTask.run(params).then(res => {
- if (res?.data) {
- message.success('修改提交成功')
- setProjectId(undefined)
- sessionStorage.setItem('CAMPCORP', values?.projectName)
- navigate('/weComTask/moments/taskList')
- }
- })
- } else {
- addTask.run(params).then(res => {
- if (res?.data) {
- modal.success({
- content: '任务提交成功',
- styles: { body: { fontWeight: 700 } },
- okText: '跳转任务列表',
- closable: true,
- onOk: () => {
- sessionStorage.setItem('CAMPCORP', values?.projectName)
- navigate('/weComTask/moments/taskList')
- },
- onCancel: () => {
- setSubVisible(false)
- }
- })
- }
- })
- }
- }
- // 重置表格
- const onPreviewReset = () => {
- setPreviewData([])
- setPreviewDataOld([])
- setPreviewContent({})
- }
- const severBd = () => {
- localStorage.setItem('TASK_MOMENTS_CREATE', JSON.stringify({ settings }))
- message.success('存储成功')
- }
- const tableSearch = useCallback((values) => {
- console.log(values)
- if (values?.mpAccountIds?.length > 0 || values?.corpUserIds?.length > 0) {
- let newPreviewData: TASK_MOMENTS_CREATE.previewDataProps = []
- const corpUserStrList = values?.corpUserIds?.map(item => item.corpId + '_' + item.corpUserId)
- if (previewDataOld?.length > 0) {
- newPreviewData = previewDataOld.filter(item => (
- (values?.mpAccountIds?.length > 0 ? values.mpAccountIds.includes(item?.mpAccountId) : true)
- &&
- (corpUserStrList?.length > 0 ? item.corpUserStrList.some(str => corpUserStrList.includes(str)) : true)
- )).map(item => ({ ...item, userRowSpan: 1, strategyRowSpan: 1, sendDataRowSpan: 1 }))
- }
- setPreviewData(newPreviewData)
- } else {
- setPreviewData(previewDataOld)
- }
- }, [previewDataOld, previewData])
- return <div className={style.create}>
- <Spin spinning={getCreateDetails.loading}>
- <Card title={<strong>{projectId ? getCreateDetails?.data?.data?.projectName + '任务编辑' : ''}配置区</strong>} className={`${style.card} ${style.config}`}>
- <Space wrap>
- <Space.Compact>
- <Button>客服组</Button>
- <SelectCorpUserGroup
- value={settings?.corpUserGroups}
- onChange={(corpUserGroups) => {
- setSettings({
- ...settings, corpUserGroups: corpUserGroups.map(item => {
- return {
- ...item, corpUsers: item.corpUsers.map((item: any) => {
- const { corpUserId, name, corpName, corpId, mpAccountId, mpAccountInfo, id } = item
- return { corpUserId, name, corpName, corpId, mpAccountId, mpAccountName: mpAccountInfo?.name || item?.mpAccountName, id }
- })
- }
- })
- })
- onPreviewReset()
- }}
- />
- </Space.Compact>
- <Space.Compact>
- <Button>业务类型</Button>
- <Select
- showSearch
- style={{ width: 120 }}
- allowClear
- placeholder="请选择类型"
- filterOption={(input, option) =>
- ((option?.label ?? '') as string).toLowerCase().includes(input.toLowerCase())
- }
- value={settings?.bizType}
- onChange={(e) => {
- setSettings({ ...settings, bizType: e })
- onPreviewReset()
- }}
- options={msgJobTypeList.filter(item => item.value === 'novel')}
- />
- </Space.Compact>
- {settings?.bizType === 'novel' ? <>
- <Space.Compact>
- <Button>书城</Button>
- <Select
- showSearch
- allowClear
- placeholder="请选择书城"
- style={{ width: 120 }}
- filterOption={(input, option) =>
- ((option?.label ?? '') as string).toLowerCase().includes(input.toLowerCase())
- }
- value={settings?.platform}
- onChange={(e) => {
- setSettings({ ...settings, platform: e, templateProductId: undefined })
- onPreviewReset()
- }}
- options={bookPlatForm.map(item => ({ value: item.id, label: item.platformName }))}
- />
- </Space.Compact>
- <Space.Compact>
- <Button>适用产品</Button>
- <Select
- showSearch
- style={{ width: 150 }}
- allowClear
- placeholder="请选择模板适用产品"
- filterOption={(input, option) =>
- ((option?.label ?? '') as string).toLowerCase().includes(input.toLowerCase())
- }
- value={settings?.templateProductId}
- onChange={(e) => {
- setSettings({ ...settings, templateProductId: e })
- onPreviewReset()
- }}
- options={bookList.filter(item => settings?.platform ? item.platformId === settings?.platform : true).map(item => ({ value: item.id, label: item.bookName }))}
- />
- </Space.Compact>
- </> : settings?.bizType === 'game' ? <Space.Compact>
- <Button>游戏渠道</Button>
- <Input
- style={{ width: 200 }}
- allowClear
- placeholder="请输入游戏渠道"
- value={settings.channel}
- onChange={(e) => {
- setSettings({ ...settings, channel: e.target.value })
- onPreviewReset()
- }}
- />
- </Space.Compact> : undefined}
- </Space>
- <div className={style.settingsBody}>
- <div className={style.settingsBody_content}>
- <DispatchMomentsTaskCreate.Provider
- value={{
- settings, setSettings,
- bookPlatForm,
- bookList,
- msgJobTypeList,
- onPreviewReset
- }}
- >
- {/* 朋友圈策略 */}
- <Strategy />
- {/* 朋友圈内容 */}
- <Content />
- </DispatchMomentsTaskCreate.Provider>
- </div>
- </div>
- <Space className={style.bts} wrap>
- <Button icon={<SaveOutlined />} onClick={severBd}>存为预设</Button>
- <Popconfirm
- title="确定清空?"
- onConfirm={() => {
- setSettings(undefined)
- setPreviewData([])
- setPreviewDataOld([])
- localStorage.removeItem('TASK_MOMENTS_CREATE')
- }}
- >
- <Button icon={<RedoOutlined />} danger>清空配置/预设</Button>
- </Popconfirm>
- <Button type='primary' onClick={preview}><SearchOutlined />预览任务/配置内容</Button>
- </Space>
- </Card>
- </Spin>
- <Card
- className={style.card}
- style={{ marginTop: 10, marginBottom: 10 }}
- extra={previewDataOld?.length > 0 ? <Button type='primary' icon={<PlusOutlined />} onClick={() => {
- setTaskName()
- }}>提交</Button> : undefined}
- >
- {previewDataOld?.length > 0 ? <div style={{ minHeight: 300 }}>
- <Form
- layout={'inline'}
- onFinish={tableSearch}
- style={{ marginBottom: 10 }}
- >
- <Form.Item label={<strong>公众号</strong>} name="mpAccountIds">
- <Select
- showSearch
- style={{ minWidth: 160 }}
- maxTagCount={1}
- placeholder="公众号"
- filterOption={(input, option) =>
- ((option?.label ?? '') as string).toLowerCase().includes(input.toLowerCase())
- }
- allowClear
- mode='multiple'
- options={mpList}
- />
- </Form.Item>
- <Space.Compact>
- <Button>客服组</Button>
- <Form.Item name="corpUserIds">
- <SelectCorpUser placeholder="请选择客服号" />
- </Form.Item>
- </Space.Compact>
- <Form.Item>
- <Space>
- <Button htmlType="reset">重置</Button>
- <Button type="primary" htmlType='submit'>搜索</Button>
- </Space>
- </Form.Item>
- </Form>
- <Table
- dataSource={previewData}
- columns={monmentsColumns(bookPlatForm, bookList, bookPlatForm.find(item => item.id === Number(settings?.platform)).platformKey, previewContent, setPreviewContent)}
- rowKey={'id'}
- bordered={true}
- scroll={{ y: 550 }}
- pagination={false}
- />
- </div> : <div style={{ minHeight: 400, display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
- <Empty description="请先完成模块配置后,再预览" />
- </div>}
- </Card>
- {/* 提交配置 */}
- {subVisible && <SubmitModal
- visible={subVisible}
- loading={addTask.loading || updateTask.loading}
- projectName={projectId ? getCreateDetails?.data?.data?.projectName : undefined}
- onChange={(values) => {
- onSubmit(values)
- }}
- onClose={() => {
- setSubVisible(false)
- }}
- />}
- </div>;
- };
- export default inject('store')(observer((props: any) => MomentsCreatePage(props.store)))
|