strategy.tsx 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. import NewSteps, { NewStepsItem } from '@/pages/weComTask/components/newSteps';
  2. import { App, Button, Card, Form, Input, Radio } from 'antd';
  3. import React, { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';
  4. import '../../global.less';
  5. import { PlusOutlined, DeleteOutlined } from '@ant-design/icons'
  6. import SendTimeSet from '@/pages/weComTask/components/sendTimeSet';
  7. import style from '../massSending/index.less';
  8. import dayjs from 'dayjs';
  9. import FilterUser from '@/pages/weComTask/components/filterUser';
  10. /**
  11. * 朋友圈策略配置
  12. * @param param0
  13. * @returns
  14. */
  15. const Strategy = forwardRef(({ value, onChange }: TASK_CREATE.StrategyProps, ref: React.ForwardedRef<{ handleOk: (type: string) => void }>) => {
  16. /****************************************/
  17. const { message } = App.useApp()
  18. const ref1 = useRef<HTMLDivElement>(null)
  19. const [form] = Form.useForm();
  20. const strategySettings = Form.useWatch('strategySettings', form);
  21. const [stepsList, setStepsList] = useState<NewStepsItem[]>([
  22. { title: '朋友圈配置', description: '朋友圈类型、朋友圈标题、适用产品', id: 'basicInfo' },
  23. {
  24. title: '朋友圈策略', children: [{ title: `策略1`, id: 'strategy_0' }, { title: `完成` }]
  25. },
  26. { title: '完成' }
  27. ])
  28. /****************************************/
  29. useImperativeHandle(ref, () => ({
  30. handleOk(type) {
  31. handleOk(type)
  32. }
  33. }));
  34. // 回填
  35. useEffect(() => {
  36. if (value && Object.keys(value).length) {
  37. const data = {
  38. ...value, strategySettings: value?.strategySettings?.map(item => {
  39. const { sendTime, startTime, endTime, sendDay, timeRepeatType } = item
  40. if (timeRepeatType === 'TIME_TYPE_SINGLE_PLACE') {
  41. return {
  42. ...item,
  43. timeRepeatType,
  44. sendDay: sendDay ? dayjs(sendDay + ' ' + sendTime) : undefined
  45. }
  46. }
  47. return {
  48. ...item,
  49. timeRepeatType,
  50. sendTime: sendTime ? dayjs('2025-04-25 ' + sendTime) : undefined,
  51. startTime: startTime ? dayjs(startTime) : undefined,
  52. endTime: endTime ? dayjs(endTime) : undefined,
  53. sendDay: sendDay ? dayjs(sendDay) : undefined
  54. }
  55. })
  56. }
  57. filedUpdateChange(data)
  58. form.setFieldsValue(data)
  59. }
  60. }, [value])
  61. const handleOk = (type: string) => {
  62. form.validateFields().then((values) => {
  63. const data = {
  64. ...values,
  65. strategySettings: values?.strategySettings?.map(item => {
  66. const { startTime, endTime, sendDay, sendTime, timeRepeatType, repeatArray, ...rest } = item
  67. const data = { ...rest, timeRepeatType }
  68. if (timeRepeatType === 'TIME_TYPE_SINGLE_PLACE') {
  69. // 定时发送
  70. data.sendDay = dayjs(sendDay).format('YYYY-MM-DD')
  71. data.sendTime = dayjs(sendDay).format('HH:mm:ss')
  72. } else if (timeRepeatType === 'TIME_TYPE_REPEAT_DAY') {
  73. // 每日循环
  74. data.startTime = dayjs(startTime).format('YYYY-MM-DD')
  75. if (endTime) {
  76. data.endTime = dayjs(endTime).format('YYYY-MM-DD')
  77. }
  78. data.sendTime = dayjs(sendTime).format('HH:mm:ss')
  79. } else if (timeRepeatType === 'TIME_TYPE_REPEAT_WEEK' || timeRepeatType === 'TIME_TYPE_REPEAT_MONTH') {
  80. // 每周循环、每月循环
  81. data.startTime = dayjs(startTime).format('YYYY-MM-DD')
  82. data.sendTime = dayjs(sendTime).format('HH:mm:ss')
  83. if (endTime) {
  84. data.endTime = dayjs(endTime).format('YYYY-MM-DD')
  85. }
  86. data.repeatArray = repeatArray
  87. }
  88. return data
  89. })
  90. }
  91. onChange?.(data, type)
  92. }).catch((err) => {
  93. console.log('err', err)
  94. form.submit()
  95. });
  96. };
  97. const filedUpdateChange = ({ momentSendName, strategySettings }: any) => {
  98. const isChecked = (content: NewStepsItem[]) => {
  99. return content.every(item => {
  100. if (item.children) {
  101. return isChecked(item.children)
  102. }
  103. return item.checked
  104. })
  105. }
  106. const content = strategySettings?.map((item, index) => {
  107. const { timeRepeatType, sendDay, startTime, sendTime, repeatArray } = item
  108. const sendTimeChecked =
  109. timeRepeatType === "TIME_TYPE_SINGLE_TIMELY" ||
  110. (timeRepeatType === "TIME_TYPE_SINGLE_PLACE" && sendDay) ||
  111. (timeRepeatType === "TIME_TYPE_REPEAT_DAY" && startTime && sendTime) ||
  112. ((timeRepeatType === "TIME_TYPE_REPEAT_WEEK" || timeRepeatType === "TIME_TYPE_REPEAT_MONTH") && startTime && sendTime && repeatArray)
  113. return {
  114. title: `策略${index + 1}`,
  115. id: `strategy_${index}`,
  116. checked: sendTimeChecked
  117. }
  118. })
  119. const isChecked1 = !!momentSendName
  120. const isChecked2 = isChecked(content)
  121. const stepsData = [
  122. { title: '朋友圈配置', description: '朋友圈标题', checked: isChecked1, id: 'basicInfo' },
  123. {
  124. title: '朋友圈策略', checked: isChecked2, children: [...content, { title: `完成`, checked: isChecked2 }]
  125. },
  126. { title: '完成', checked: isChecked1 && isChecked2 }
  127. ]
  128. setStepsList(stepsData)
  129. }
  130. return <>
  131. <div className={`body_steps`}>
  132. <NewSteps
  133. items={stepsList}
  134. onChange={(e) => {
  135. if (e?.id)
  136. ref1.current?.querySelector('#' + e?.id)?.scrollIntoView({ behavior: 'smooth' })
  137. }}
  138. />
  139. </div>
  140. <div className={`body_content`} ref={ref1}>
  141. <Form
  142. form={form}
  143. name="newFriendsStrategy"
  144. labelAlign='left'
  145. labelCol={{ span: 5 }}
  146. colon={false}
  147. scrollToFirstError={{
  148. behavior: 'smooth',
  149. block: 'center'
  150. }}
  151. onFinishFailed={({ errorFields }) => {
  152. message.error(errorFields?.[0]?.errors?.[0])
  153. }}
  154. initialValues={{
  155. taskType: 'novel',
  156. strategySettings: [{ }],
  157. }}
  158. onFieldsChange={() => {
  159. filedUpdateChange(form.getFieldsValue())
  160. }}
  161. preserve={true}
  162. >
  163. <Card title={<strong>基础信息配置</strong>} style={{ background: '#fff', marginBottom: 10 }} hoverable id='basicInfo'>
  164. <Form.Item label={<strong>朋友圈标题</strong>} name="momentSendName" rules={[{ required: true, message: '请输入标题!' }]}>
  165. <Input placeholder="请输入标题" style={{ width: 358 }} allowClear />
  166. </Form.Item>
  167. </Card>
  168. <Form.List name="strategySettings">
  169. {(fields, { add, remove }) => (
  170. <div style={{ padding: '4px 2px 0', border: '1px dashed #d9d9d9', borderRadius: 8, background: '#f5f5f5' }}>
  171. {fields.map(({ key, name, ...restField }, index) => {
  172. const timeRepeatType = strategySettings?.[index]?.timeRepeatType
  173. return <Card
  174. key={key}
  175. title={<strong>策略{index + 1}配置</strong>}
  176. style={{ background: '#fff', marginBottom: 10 }}
  177. hoverable
  178. id={`strategy_${index}`}
  179. extra={strategySettings?.length > 1 ? <Button icon={<DeleteOutlined />} type='link' style={{ color: 'red' }} onClick={() => remove(name)}></Button> : null}
  180. >
  181. <div className={style.strategy_item} id={`strategy_${index}_strategyName`}>
  182. <Form.Item
  183. {...restField}
  184. label={<strong>策略名称</strong>}
  185. name={[name, 'strategyName']}
  186. rules={[{ required: false, message: '请输入策略名称!' }]}
  187. >
  188. <Input placeholder="请输入标题" style={{ width: 358 }} allowClear />
  189. </Form.Item>
  190. <SendTimeSet active='all' form={form} restField={restField} name={name} timeRepeatType={timeRepeatType} />
  191. </div>
  192. </Card>
  193. })}
  194. <Form.Item>
  195. <Button type="primary" onClick={() => add({})} block icon={<PlusOutlined />}>
  196. 新增策略组
  197. </Button>
  198. </Form.Item>
  199. </div>
  200. )}
  201. </Form.List>
  202. </Form>
  203. </div>
  204. </>
  205. });
  206. export default React.memo(Strategy);