index.tsx 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  1. import { inject, observer } from 'mobx-react';
  2. import React, { useEffect, useState } from 'react';
  3. import style from './index.less'
  4. import { App, Button, Card, Empty, Input, Popconfirm, Select, Space, Spin, Table, Tabs } from 'antd';
  5. import MassSending from './components/massSending';
  6. import { useAjax } from '@/Hook/useAjax';
  7. import { MediaContentProps, welcomeMsgJobTypeApi } from '@/pages/weComTask/API/weMaterial/weMaterial';
  8. import SelectCorpUser from '../../corpUserManage/selectCorpUser';
  9. import { SearchOutlined, PlusOutlined, RedoOutlined, SaveOutlined, CheckOutlined } from '@ant-design/icons';
  10. import { getGroupData, getHighGroupData, getUserInDataData } from './const';
  11. import { highMassSendingColumns, massSendingColumns, userInheritColumns, welcomeColumns } from './tableConfig';
  12. import SubmitModal from './submitModal';
  13. import { addTaskApi } from '@/pages/weComTask/API/businessPlan/create';
  14. import { useNavigate } from 'react-router-dom';
  15. import SelectExternalAccount from '@/pages/weComTask/components/selectExternalAccount';
  16. import Welcome from './components/welcome';
  17. import UserInherit from './components/userInherit';
  18. import HighMassSending from './components/highMassSending';
  19. import { toJS } from 'mobx';
  20. import Friends from './components/friends';
  21. export const DispatchTaskCreate = React.createContext<TASK_CREATE.DispatchTaskCreate | null>(null);
  22. /**
  23. * 任务创建
  24. * @param props
  25. * @returns
  26. */
  27. const Create: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE.BookListProps[], bookPlatForm: TASK_CREATE.BookPlatFormProps[] } } }> = ({ weComTaskStore }) => {
  28. /***********************************************/
  29. const navigate = useNavigate();
  30. const { bookList, bookPlatForm } = toJS(weComTaskStore.data)
  31. const [settings, setSettings] = useState<TASK_CREATE.SettingsProps>();
  32. console.log(settings)
  33. const { message, modal } = App.useApp()
  34. const [msgJobTypeList, setMsgJobTypeList] = useState<{ value: string, label: string }[]>([])
  35. const [previewData, setPreviewData] = useState<TASK_CREATE.previewDataProps>({})
  36. const [subVisible, setSubVisible] = useState<boolean>(false) // 选择设置名称弹窗控制
  37. const [eaVisible, setEaVisible] = useState<boolean>(false)
  38. const welcomeMsgJobType = useAjax(() => welcomeMsgJobTypeApi())//获取欢迎语类型
  39. const addTask = useAjax((params) => addTaskApi(params))
  40. /***********************************************/
  41. useEffect(() => {
  42. const task = localStorage.getItem('TASK_CORP_CREATE')
  43. if (task) {
  44. setSettings(JSON.parse(task).settings)
  45. }
  46. }, [])
  47. useEffect(() => {
  48. welcomeMsgJobType.run().then(res => {
  49. if (res?.data) {
  50. setMsgJobTypeList(Object.keys(res.data).map(key => ({ value: key, label: res.data[key] })))
  51. }
  52. })
  53. }, [])
  54. // 预览
  55. const preview = () => {
  56. const newPreviewData: TASK_CREATE.previewDataProps = {}
  57. if (!settings?.corpUsers || settings?.corpUsers?.length === 0) {
  58. message.error('请先选择客服号')
  59. return
  60. }
  61. const corpUsersLength = settings?.corpUsers?.length
  62. // 欢迎语
  63. if (settings?.welcomeMsgTemplateDTO && Object.keys(settings?.welcomeMsgTemplateDTO).length) {
  64. if (settings?.welcomeMsgTemplateDTO?.mediaContentList?.some(item => item?.some(i => i?.mediaType === 'link' || i?.mediaType === 'miniprogram')) && settings?.corpUsers?.every(item => !item?.welcomeMsgContent?.length)) {
  65. message.error('请先上传欢迎语Excel内容')
  66. return
  67. }
  68. const welcome = []
  69. if (!settings?.corpUsers?.every((item, i) => {
  70. return settings?.welcomeMsgTemplateDTO?.mediaContentList?.every((mediaItem, index, row) => {
  71. const welcomeMsgContent = item.welcomeMsgContent?.[index]
  72. if (mediaItem?.some(media => media?.mediaType === 'link' ? !welcomeMsgContent?.linkUrl : media?.mediaType === 'miniprogram' ? (!welcomeMsgContent?.miniprogramAppid || !welcomeMsgContent?.miniprogramPage) : false)) {
  73. message.error('欢迎语内容配置错误,请检查')
  74. return false
  75. }
  76. const contentReactNode = mediaItem.map(item => {
  77. switch (item.mediaType) {
  78. case 'link':
  79. return `<span style="color: red">链接</span>`
  80. case 'miniprogram':
  81. return `<span style="color: red">小程序</span>`
  82. case 'file':
  83. return `<span>文件</span>`
  84. case 'video':
  85. return `<span>视频</span>`
  86. case 'image':
  87. return `<span>图片</span>`
  88. case 'text':
  89. return `<span>文本</span>`
  90. default:
  91. return `<span style="color: red">请联系管理员</span>`
  92. }
  93. })
  94. welcome.push({
  95. ...settings?.welcomeMsgTemplateDTO,
  96. sendData: mediaItem,
  97. contentReactNode,
  98. welcomeMsgContent,
  99. contentIndex: index + 1,
  100. corpUserId: item.corpUserId,
  101. corpUserName: item.name,
  102. bizType: settings?.bizType,
  103. channel: settings?.channel,
  104. platform: settings?.platform,
  105. templateProductId: settings?.templateProductId,
  106. id: i * row.length + (index + 1),
  107. rowSpan: index === 0 ? row.length : 0
  108. })
  109. return true
  110. })
  111. })) {
  112. return
  113. }
  114. console.log('welcome--->', welcome)
  115. newPreviewData.welcome = welcome
  116. }
  117. // 群发
  118. if ((settings?.massSendingContent && Object.keys(settings?.massSendingContent).length) && (settings?.massSendingStrategy && Object.keys(settings?.massSendingStrategy).length)) {
  119. if (settings?.massSendingContent?.massSendingContentDTO?.some(item => item?.sendContentDto?.some(si => si?.contentDTO?.some(i => i?.attachmentList?.some(a => ['TASK_CONTENT_LINK', 'TASK_STATUS_MINIPROGRAM'].includes(a?.msgType))))) && settings?.corpUsers?.every(item => !item?.groupMsgContent?.length)) {
  120. message.error('需要配置小程序、链接,请上传配置好的群发Excel文件')
  121. return
  122. }
  123. const massSendingData = getGroupData(settings)
  124. const massSending = []
  125. if (!settings?.corpUsers?.every((item, i) => {
  126. let strategyIndex = 0
  127. return massSendingData.every((dataItem, li, row) => {
  128. const groupMsgContent = item.groupMsgContent?.[dataItem.strategyIndex - 1]?.[dataItem.sendDataIndex - 1]?.[dataItem.contentIndex - 1]
  129. if (dataItem?.content?.attachmentList?.length && dataItem?.content?.attachmentList?.some(item => (item?.msgType === 'TASK_CONTENT_LINK' ? !groupMsgContent?.linkUrl : item?.msgType === 'TASK_STATUS_MINIPROGRAM' ? (!groupMsgContent?.miniprogramAppid || !groupMsgContent?.miniprogramPage) : false))) {
  130. message.error('群发内容配置错误,请检查')
  131. return false
  132. }
  133. const mediaItem = JSON.parse(JSON.stringify(dataItem?.content?.attachmentList || []))
  134. if (dataItem?.content?.text?.content) {
  135. mediaItem.push({
  136. msgType: 'TASK_CONTENT_TEXT',
  137. textContent: dataItem?.content?.text?.content
  138. })
  139. }
  140. const contentReactNode = mediaItem.map(item => {
  141. switch (item.msgType) {
  142. case 'TASK_CONTENT_LINK':
  143. return `<span style="color: red">链接</span>`
  144. case 'TASK_STATUS_MINIPROGRAM':
  145. return `<span style="color: red">小程序</span>`
  146. case 'TASK_STATUS_FILE':
  147. return `<span>文件</span>`
  148. case 'TASK_STATUS_VIDEO':
  149. return `<span>视频</span>`
  150. case 'TASK_CONTENT_IMAGE':
  151. return `<span>图片</span>`
  152. case 'TASK_CONTENT_TEXT':
  153. return `<span>文本</span>`
  154. default:
  155. return `<span style="color: red">请联系管理员</span>`
  156. }
  157. })
  158. massSending.push({
  159. ...dataItem,
  160. groupMsgContent,
  161. contentReactNode,
  162. corpUserId: item.corpUserId,
  163. corpUserName: item.name,
  164. bizType: settings?.bizType,
  165. channel: settings?.channel,
  166. platform: settings?.platform,
  167. templateProductId: settings?.templateProductId,
  168. id: i * row.length + (li + 1),
  169. userRowSpan: li % row.length === 0 ? row.length : 0,
  170. strategyRowSpan: strategyIndex !== dataItem.strategyIndex ? dataItem.strategyDataCount : 0
  171. })
  172. strategyIndex = dataItem.strategyIndex
  173. return true
  174. })
  175. })) {
  176. return
  177. }
  178. console.log('massSending---->', massSending)
  179. newPreviewData.massSending = massSending
  180. }
  181. // 是否有客户继承配置
  182. if (settings?.userInherit && Object.keys(settings?.userInherit).length) {
  183. if (settings?.corpUsers?.every(item => !item?.externalUserTransferContent?.length)) {
  184. message.error('请上传配置好的客户继承Excel文件')
  185. return
  186. }
  187. const userInData = getUserInDataData(settings?.userInherit?.schedulingStrategyDTO, settings?.userInherit?.taskName)
  188. const userInherit = []
  189. // 数据内容
  190. if (!settings?.corpUsers?.every((item, i) => {
  191. return userInData.every((dataItem, ii, row) => {
  192. const externalUser = item.externalUserTransferContent?.[dataItem.strategyIndex - 1]?.[dataItem.inheritIndex - 1]
  193. if (!externalUser || !externalUser?.corpUserName || !externalUser?.corpUserId) {
  194. message.error('Excel配置错误,' + JSON.stringify(dataItem) + ',' + JSON.stringify(item.externalUserTransferContent))
  195. return false
  196. }
  197. userInherit.push({
  198. ...dataItem,
  199. externalUser,
  200. taskName: dataItem?.taskName,
  201. corpUserId: item.corpUserId,
  202. corpUserName: item.name,
  203. bizType: settings?.bizType,
  204. channel: settings?.channel,
  205. platform: settings?.platform,
  206. templateProductId: settings?.templateProductId,
  207. id: i * row.length + (ii + 1)
  208. })
  209. return true
  210. })
  211. })) {
  212. return
  213. }
  214. console.log('userInherit-->', userInherit)
  215. newPreviewData.userInherit = userInherit
  216. }
  217. // 是否有高级群发
  218. if ((settings?.highMassSendingContent && Object.keys(settings?.highMassSendingContent).length) && (settings?.highMassSendingStrategy && Object.keys(settings?.highMassSendingStrategy).length)) {
  219. 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)) {
  220. message.error('需要配置小程序、链接,请上传配置好的高级群发Excel文件')
  221. return
  222. }
  223. const massSendingData = getHighGroupData(settings)
  224. console.log('massSendingData---->', massSendingData)
  225. const highMassSending = []
  226. let rowLength = 0
  227. if (!settings?.corpUsers?.every((item, i) => {
  228. let strategyIndex = 0
  229. let corpUserCount = 0
  230. return massSendingData.every((dataItem, li, row) => {
  231. const mediaItem = JSON.parse(JSON.stringify(dataItem?.content || []))
  232. const contentReactNode = mediaItem.map(item => {
  233. switch (item.mediaType) {
  234. case 'link':
  235. return `<span style="color: red">链接</span>`
  236. case 'miniprogram':
  237. return `<span style="color: red">小程序</span>`
  238. case 'file':
  239. return `<span>文件</span>`
  240. case 'video':
  241. return `<span>视频</span>`
  242. case 'image':
  243. return `<span>图片</span>`
  244. case 'text':
  245. return `<span>文本</span>`
  246. default:
  247. return `<span style="color: red">请联系管理员</span>`
  248. }
  249. })
  250. const externalUserListLength = item.externalUserList.length
  251. return item.externalUserList?.every((externalUser, ii) => {
  252. const layer3 = externalUser.corpId + '-' + externalUser.externalUserId
  253. const externalUserMsg = item.highGroupMsgContent?.[dataItem.strategyIndex - 1]?.[dataItem.sendDataIndex - 1]?.[layer3]?.[dataItem.contentIndex - 1]
  254. if (mediaItem?.some(media => media?.mediaType === 'link' ? !externalUserMsg?.linkUrl : media?.mediaType === 'miniprogram' ? (!externalUserMsg?.miniprogramAppid || !externalUserMsg?.miniprogramPage) : false)) {
  255. message.error('高级群发配置错误,请检查')
  256. return false
  257. }
  258. rowLength++;
  259. highMassSending.push({
  260. ...dataItem,
  261. groupMsgContent: externalUserMsg,
  262. contentReactNode,
  263. externalUser,
  264. corpUserId: item.corpUserId,
  265. corpUserName: item.name,
  266. bizType: settings?.bizType,
  267. channel: settings?.channel,
  268. platform: settings?.platform,
  269. templateProductId: settings?.templateProductId,
  270. id: rowLength,
  271. userRowSpan: corpUserCount === 0 ? (massSendingData.length * externalUserListLength) : 0,
  272. strategyRowSpan: strategyIndex !== dataItem.strategyIndex ? dataItem.sendDataRowSpan * externalUserListLength * dataItem.strategyItemSendDataCount : 0,
  273. sendDataRowSpan: ii === 0 ? externalUserListLength * dataItem.sendDataRowSpan : 0
  274. })
  275. corpUserCount++;
  276. strategyIndex = dataItem.strategyIndex
  277. return true
  278. })
  279. })
  280. })) {
  281. return
  282. }
  283. newPreviewData.highMassSending = highMassSending
  284. }
  285. if (newPreviewData && Object.keys(newPreviewData).length) {
  286. setPreviewData(newPreviewData)
  287. } else {
  288. message.error('请填写至少填写一项内容')
  289. }
  290. }
  291. const onSubmit = (values: any) => {
  292. const { bizType, platform, templateProductId, corpUsers, welcomeMsgTemplateDTO, massSendingContent, massSendingStrategy, highMassSendingContent, highMassSendingStrategy, userInherit } = settings
  293. const params = {
  294. ...values,
  295. bizType,
  296. platform,
  297. templateProductId,
  298. corpUsers: corpUsers?.map(item => {
  299. const params: { [x: string]: any } = {
  300. corpId: item.corpId,
  301. corpUserId: item.corpUserId
  302. }
  303. // 欢迎语
  304. if (item?.welcomeMsgContent) {
  305. params.welcomeMsgContent = item?.welcomeMsgContent
  306. }
  307. // 群发
  308. if (item?.groupMsgContent) {
  309. params.groupMsgContent = item?.groupMsgContent
  310. }
  311. // 继承
  312. if (item?.externalUserTransferContent) {
  313. params.takeoverUserIds = item?.externalUserTransferContent
  314. }
  315. // 高级群发
  316. if (item?.highGroupMsgContent) {
  317. params.messageSendContent = item?.highGroupMsgContent
  318. // 外部成员
  319. if (item?.externalUserList) {
  320. params.corpList = item?.externalUserList.map(item => ({
  321. externalUserId: item.externalUserId,
  322. corpId: item.corpId
  323. }))
  324. }
  325. }
  326. return params
  327. })
  328. }
  329. // 欢迎语
  330. if (welcomeMsgTemplateDTO && Object.keys(welcomeMsgTemplateDTO).length) {
  331. params.welcomeMsgTemplateDTO = welcomeMsgTemplateDTO
  332. }
  333. // 群发
  334. if (massSendingStrategy && Object.keys(massSendingStrategy).length) {
  335. params.groupSendTaskAddDTO = {
  336. groupSendName: massSendingStrategy.groupSendName,
  337. strategyList: massSendingStrategy?.strategySettings?.map((settingsItem, settingsIndex) => {
  338. const {
  339. // 发送对象
  340. sendData,
  341. // 策略
  342. ...strategy
  343. } = settingsItem
  344. return {
  345. ...strategy,
  346. taskDetail: sendData.map((sendItem, sendIndex) => {
  347. // 发送内容
  348. const { contentDTO, sendMode } = massSendingContent.massSendingContentDTO[settingsIndex]['sendContentDto'][sendIndex]
  349. const detail: { [x: string]: any } = {
  350. sendMode,
  351. contentDTO
  352. }
  353. if (sendItem.externalUserType === 'specify') {
  354. detail.externalUserFilter = {
  355. configName: sendItem.externalUserFilter.configName,
  356. ...sendItem.externalUserFilter.configContent
  357. }
  358. }
  359. return detail
  360. })
  361. }
  362. })
  363. }
  364. }
  365. // 高级群发
  366. if (highMassSendingStrategy && Object.keys(highMassSendingStrategy).length) {
  367. params.messageSendTaskAddDTO = {
  368. groupSendName: highMassSendingStrategy.groupSendName,
  369. strategyList: highMassSendingStrategy?.strategySettings?.map((settingsItem, settingsIndex) => {
  370. const {
  371. // 发送对象
  372. sendData,
  373. // 策略
  374. ...strategy
  375. } = settingsItem
  376. return {
  377. ...strategy,
  378. taskDetail: sendData.map((sendItem, sendIndex) => {
  379. // 发送内容
  380. const { contentDTO, sendMode } = highMassSendingContent.massSendingContentDTO[settingsIndex]['sendContentDto'][sendIndex]
  381. const detail: { [x: string]: any } = {
  382. sendMode,
  383. contentDTO: contentDTO.map(item => {
  384. let newContentDTO: { [x: string]: any } = {}
  385. item.forEach((item: MediaContentProps) => {
  386. switch (item.mediaType) {
  387. case "text":
  388. newContentDTO = {
  389. text: {
  390. content: item?.textContent
  391. },
  392. msgType: 'TASK_CONTENT_TEXT'
  393. }
  394. break
  395. case "miniprogram":
  396. newContentDTO = {
  397. miniprogram: {
  398. appId: item?.miniprogramAppid,
  399. page: item?.miniprogramPage,
  400. title: item?.miniprogramTitle,
  401. picUrl: item?.miniprogramPicurl
  402. },
  403. msgType: 'TASK_STATUS_MINIPROGRAM'
  404. }
  405. break
  406. case "link":
  407. newContentDTO = {
  408. link: {
  409. desc: item?.linkDesc,
  410. picUrl: item?.linkPicurl,
  411. title: item?.linkTitle,
  412. url: item?.linkUrl
  413. },
  414. msgType: 'TASK_CONTENT_LINK'
  415. }
  416. break
  417. case "image":
  418. newContentDTO = {
  419. image: {
  420. picUrl: item?.imageUrl
  421. },
  422. msgType: 'TASK_CONTENT_IMAGE'
  423. }
  424. break
  425. case "video":
  426. newContentDTO = {
  427. video: {
  428. videoUrl: item?.videoUrl
  429. },
  430. msgType: 'TASK_STATUS_VIDEO'
  431. }
  432. break
  433. case "file":
  434. newContentDTO = {
  435. file: {
  436. fileUrl: item?.fileUrl
  437. },
  438. msgType: 'TASK_STATUS_FILE'
  439. }
  440. break
  441. }
  442. })
  443. return newContentDTO
  444. })
  445. }
  446. if (sendItem.externalUserType === 'specify') {
  447. detail.externalUserFilter = {
  448. configName: sendItem.externalUserFilter.configName,
  449. ...sendItem.externalUserFilter.configContent
  450. }
  451. }
  452. return detail
  453. })
  454. }
  455. })
  456. }
  457. }
  458. if (userInherit && Object.keys(userInherit).length) {
  459. params.externalUserTransferTasksDTO = {
  460. taskName: userInherit.taskName,
  461. schedulingStrategyDTO: userInherit.schedulingStrategyDTO.map(strategyItem => {
  462. const {
  463. inheritDto,
  464. ...strategy
  465. } = strategyItem
  466. return {
  467. ...strategy,
  468. transferStrategyContentDTOS: inheritDto.map(inheritItem => {
  469. const inherit: { [x: string]: any } = {
  470. transferSuccessMsg: inheritItem.transferSuccessMsg
  471. }
  472. if (inheritItem.transferType === 'specify') {
  473. inherit.externalUserFilter = {
  474. configName: inheritItem.transferUserDto.configName,
  475. ...inheritItem.transferUserDto.configContent
  476. }
  477. }
  478. return inherit
  479. })
  480. }
  481. })
  482. }
  483. }
  484. console.log('params---->', params)
  485. addTask.run(params).then(res => {
  486. console.log(res)
  487. if (res?.data) {
  488. modal.success({
  489. content: '任务提交成功',
  490. styles: { body: { fontWeight: 700 } },
  491. okText: '跳转任务列表',
  492. closable: true,
  493. onOk: () => {
  494. sessionStorage.setItem('CAMPCORP', values?.projectName)
  495. navigate('/weComTask/businessPlan/taskList')
  496. },
  497. onCancel: () => {
  498. setSubVisible(false)
  499. }
  500. })
  501. }
  502. })
  503. }
  504. const onPreviewReset = () => {
  505. setPreviewData({})
  506. }
  507. const severBd = () => {
  508. localStorage.setItem('TASK_CORP_CREATE', JSON.stringify({ settings }))
  509. message.success('存储成功')
  510. }
  511. return <div className={style.create}>
  512. <Spin spinning={false}>
  513. <Card title={<strong>配置区</strong>} className={`${style.card} ${style.config}`}>
  514. <Space wrap>
  515. <Space.Compact>
  516. <Button>客服号</Button>
  517. <SelectCorpUser
  518. value={settings?.corpUsers}
  519. onChange={(corpUsers) => {
  520. console.log(corpUsers)
  521. setSettings({
  522. ...settings, corpUsers: corpUsers.map(item => {
  523. const { corpUserId, name, corpName, corpId } = item
  524. return { corpUserId, name, corpName, corpId }
  525. })
  526. })
  527. onPreviewReset()
  528. }}
  529. />
  530. </Space.Compact>
  531. <Space.Compact>
  532. <Button>业务类型</Button>
  533. <Select
  534. showSearch
  535. style={{ width: 120 }}
  536. allowClear
  537. placeholder="请选择类型"
  538. filterOption={(input, option) =>
  539. ((option?.label ?? '') as string).toLowerCase().includes(input.toLowerCase())
  540. }
  541. value={settings?.bizType}
  542. onChange={(e) => {
  543. setSettings({ ...settings, bizType: e })
  544. onPreviewReset()
  545. }}
  546. options={msgJobTypeList.filter(item => item.value === 'novel')}
  547. />
  548. </Space.Compact>
  549. {settings?.bizType === 'novel' ? <>
  550. <Space.Compact>
  551. <Button>书城</Button>
  552. <Select
  553. showSearch
  554. allowClear
  555. placeholder="请选择书城"
  556. style={{ width: 200 }}
  557. filterOption={(input, option) =>
  558. ((option?.label ?? '') as string).toLowerCase().includes(input.toLowerCase())
  559. }
  560. value={settings?.platform}
  561. onChange={(e) => {
  562. setSettings({ ...settings, platform: e })
  563. onPreviewReset()
  564. }}
  565. options={bookPlatForm.map(item => ({ value: item.id, label: item.platformName }))}
  566. />
  567. </Space.Compact>
  568. <Space.Compact>
  569. <Button>适用产品</Button>
  570. <Select
  571. showSearch
  572. style={{ width: 200 }}
  573. allowClear
  574. placeholder="请选择模板适用产品"
  575. filterOption={(input, option) =>
  576. ((option?.label ?? '') as string).toLowerCase().includes(input.toLowerCase())
  577. }
  578. value={settings?.templateProductId}
  579. onChange={(e) => {
  580. setSettings({ ...settings, templateProductId: e })
  581. onPreviewReset()
  582. }}
  583. options={bookList.map(item => ({ value: item.id, label: item.bookName }))}
  584. />
  585. </Space.Compact>
  586. </> : settings?.bizType === 'game' ? <Space.Compact>
  587. <Button>游戏渠道</Button>
  588. <Input
  589. style={{ width: 200 }}
  590. allowClear
  591. placeholder="请输入游戏渠道"
  592. value={settings.channel}
  593. onChange={(e) => {
  594. setSettings({ ...settings, channel: e.target.value })
  595. onPreviewReset()
  596. }}
  597. />
  598. </Space.Compact> : undefined}
  599. {(settings?.highMassSendingStrategy && Object.keys(settings?.highMassSendingStrategy).length > 0) && <Button
  600. onClick={() => setEaVisible(true)}
  601. type={settings?.corpUsers?.every(item => item?.externalUserList?.length) ? 'primary' : 'default'}
  602. >
  603. {settings?.corpUsers?.every(item => item?.externalUserList?.length) ? <>
  604. 重选高级群发外部客户
  605. <CheckOutlined style={{ marginLeft: 5 }} />
  606. </> : '高级群发外部客户选择'}
  607. </Button>}
  608. </Space>
  609. <div className={style.settingsBody}>
  610. <div className={style.settingsBody_content}>
  611. <DispatchTaskCreate.Provider
  612. value={{
  613. settings, setSettings,
  614. bookPlatForm,
  615. bookList,
  616. msgJobTypeList,
  617. onPreviewReset
  618. }}>
  619. <div className={style.settingsBody_content_right}>
  620. {/* 欢迎语 */}
  621. <Welcome />
  622. {/* 群发设置 */}
  623. <MassSending />
  624. {/* 高级群发 */}
  625. <HighMassSending />
  626. {/* 朋友圈 */}
  627. {/* <Friends /> */}
  628. {/* 客户继承 */}
  629. <UserInherit />
  630. </div>
  631. </DispatchTaskCreate.Provider>
  632. </div>
  633. </div>
  634. <Space className={style.bts} wrap>
  635. <Button icon={<SaveOutlined />} onClick={severBd}>存为预设</Button>
  636. <Popconfirm
  637. title="确定清空?"
  638. onConfirm={() => {
  639. setSettings(undefined)
  640. localStorage.removeItem('TASK_CORP_CREATE')
  641. }}
  642. >
  643. <Button icon={<RedoOutlined />} danger>清空配置/预设</Button>
  644. </Popconfirm>
  645. <Button type='primary' onClick={preview}><SearchOutlined />预览广告</Button>
  646. </Space>
  647. </Card>
  648. </Spin>
  649. <Card className={style.card} style={{ marginTop: 10, marginBottom: 10 }}>
  650. {Object.keys(previewData).length > 0 ? <div style={{ minHeight: 300 }}>
  651. <Tabs
  652. defaultActiveKey="1"
  653. items={Object.keys(previewData).map(key => ({
  654. key: key,
  655. label: { 'userInherit': '客户继承', 'massSending': '客户群发', 'welcome': '欢迎语', 'highMassSending': '高级群发' }[key],
  656. children: key === 'userInherit' ? <>
  657. <Table
  658. dataSource={previewData[key]}
  659. columns={userInheritColumns()}
  660. rowKey={'id'}
  661. bordered={true}
  662. scroll={{ y: 550 }}
  663. pagination={false}
  664. />
  665. </> : key === 'massSending' ? <>
  666. <Table
  667. dataSource={previewData[key]}
  668. columns={massSendingColumns()}
  669. rowKey={'id'}
  670. bordered={true}
  671. scroll={{ y: 550 }}
  672. pagination={false}
  673. />
  674. </> : key === 'welcome' ? <>
  675. <Table
  676. dataSource={previewData[key]}
  677. columns={welcomeColumns(bookPlatForm, bookList)}
  678. rowKey={'id'}
  679. bordered={true}
  680. scroll={{ y: 550 }}
  681. pagination={false}
  682. />
  683. </> : key === 'highMassSending' ? <>
  684. <Table
  685. dataSource={previewData[key]}
  686. columns={highMassSendingColumns()}
  687. rowKey={'id'}
  688. bordered={true}
  689. scroll={{ y: 550 }}
  690. pagination={false}
  691. />
  692. </> : undefined
  693. }))}
  694. tabBarExtraContent={<Space size={10}>
  695. {/* <Text strong>欢迎语:{previewData?.welcome?.length || 0},群发:{previewData?.massSending?.length || 0},客户继承:{previewData?.userInherit?.length || 0}</Text> */}
  696. <Button type='primary' icon={<PlusOutlined />} onClick={() => {
  697. setSubVisible(true)
  698. }}>提交</Button>
  699. </Space>}
  700. />
  701. </div> : <div style={{ minHeight: 400, display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
  702. <Empty description="请先完成模块配置后,再预览" />
  703. </div>}
  704. </Card>
  705. {/* 提交配置 */}
  706. {subVisible && <SubmitModal
  707. visible={subVisible}
  708. ajax={addTask}
  709. onChange={(values) => {
  710. onSubmit(values)
  711. }}
  712. onClose={() => {
  713. setSubVisible(false)
  714. }}
  715. />}
  716. {/* 选择外部客户 */}
  717. {eaVisible && <SelectExternalAccount
  718. corpUsers={settings?.corpUsers || []}
  719. visible={eaVisible}
  720. onClose={() => {
  721. setEaVisible(false)
  722. }}
  723. onChange={(value) => {
  724. setEaVisible(false)
  725. setSettings({
  726. ...settings,
  727. corpUsers: value
  728. })
  729. }}
  730. />}
  731. </div>
  732. };
  733. export default inject('store')(observer((props: any) => Create(props.store)))