newText.tsx 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. import New1Radio from "@/pages/launchSystemV3/components/New1Radio"
  2. import TextAideInput from "@/pages/launchSystemV3/components/TextAideInput"
  3. import { txtLength } from "@/utils/utils"
  4. import { Button, Card, Form, Modal, Popconfirm, Space, message } from "antd"
  5. import React, { useEffect, useState } from "react"
  6. import { TextTypeList } from "../../const"
  7. import { MinusCircleOutlined, PlusOutlined } from "@ant-design/icons"
  8. interface Props {
  9. textData: any,
  10. dynamicMaterialDTos: any,
  11. value?: any,
  12. visible?: boolean
  13. onClose?: () => void
  14. onChange?: (value: any) => void
  15. }
  16. /**
  17. * 创意文案
  18. * @param param0
  19. * @returns
  20. */
  21. const NewText: React.FC<Props> = ({ visible, onClose, onChange, value, textData, dynamicMaterialDTos }) => {
  22. /*************************************/
  23. const [form] = Form.useForm();
  24. const type = Form.useWatch('type', form)
  25. const textDto = Form.useWatch('textDto', form)
  26. const [textList, setTextList] = useState<PULLIN.TextDtoProps[]>([])
  27. /*************************************/
  28. const handleOk = (values: any) => {
  29. console.log(values)
  30. const { type, textDto } = values
  31. onChange?.({
  32. type,
  33. dynamicCreativesTextDetailDTOList: textDto.map((item: any) => {
  34. let data: any = {}
  35. Object.keys(item).forEach(key => {
  36. data[key] = [item[key]]
  37. })
  38. return data
  39. })
  40. })
  41. }
  42. useEffect(() => {
  43. console.log('创意文案--->', value)
  44. if (value && Object.keys(value).length) {
  45. const { type, dynamicCreativesTextDetailDTOList } = value
  46. form.setFieldsValue({
  47. type, textDto: dynamicCreativesTextDetailDTOList.map((item: any) => {
  48. let data: any = {}
  49. Object.keys(item).forEach(key => {
  50. data[key] = item[key]?.[0]
  51. })
  52. return data
  53. })
  54. })
  55. }
  56. }, [value])
  57. useEffect(() => {
  58. if (textData && Object.keys(textData)) {
  59. let data = Object.values(textData).map((item: any) => {
  60. let content = item.children.content
  61. return { label: content.description, restriction: content.restriction, value: item.name, required: item.required }
  62. })
  63. setTextList(data)
  64. }
  65. }, [textData])
  66. return <Modal
  67. title={<strong style={{ fontSize: 20 }}>创意文案</strong>}
  68. visible={visible}
  69. onCancel={onClose}
  70. footer={null}
  71. width={800}
  72. className={`modalResetCss`}
  73. bodyStyle={{ padding: '0 0 40px', position: 'relative', borderRadius: '0 0 8px 8px' }}
  74. maskClosable={false}
  75. >
  76. <Form
  77. form={form}
  78. name="newText"
  79. labelAlign='left'
  80. labelCol={{ span: 5 }}
  81. colon={false}
  82. style={{ backgroundColor: '#f1f4fc', maxHeight: 650, overflow: 'hidden', overflowY: 'auto', padding: '0 10px 10px', borderRadius: '0 0 8px 8px' }}
  83. scrollToFirstError={{
  84. behavior: 'smooth',
  85. block: 'center'
  86. }}
  87. onFinishFailed={({ errorFields }) => {
  88. message.error(errorFields?.[0]?.errors?.[0])
  89. }}
  90. initialValues={{
  91. type: 0,
  92. textDto: [{}]
  93. }}
  94. onFinish={handleOk}
  95. >
  96. <Card className="cardResetCss" style={{ marginTop: 10 }}>
  97. <Form.Item name="type" label={<strong>文案分配规则</strong>} style={{ marginBottom: 0 }} rules={[{ required: true, message: '请选择营销目的!' }]}>
  98. <New1Radio
  99. data={TextTypeList}
  100. onChange={(value) => {
  101. let count = dynamicMaterialDTos.dynamicGroup.length
  102. let oldtextDto: PULLIN.TextDtoProps[] = JSON.parse(JSON.stringify(textDto))
  103. let length = oldtextDto.length
  104. if (value === 0) {
  105. oldtextDto = [textDto[0] || {}]
  106. } else if (value === 1) {
  107. if (count > length) {
  108. oldtextDto = oldtextDto.concat(Array(count - length).fill({}))
  109. } else {
  110. oldtextDto = oldtextDto.slice(0, count)
  111. }
  112. } else if (value === 2) {
  113. if (count < length) {
  114. oldtextDto = oldtextDto.slice(0, count)
  115. }
  116. }
  117. form.setFieldsValue({ textDto: oldtextDto })
  118. }}
  119. />
  120. </Form.Item>
  121. </Card>
  122. <Form.List name="textDto">
  123. {(fields, { add, remove }) => (<>
  124. {fields.map(({ key, name, ...restField }, num) => (
  125. <Card
  126. title={type === 1 ? <strong style={{ fontSize: 14 }}>创意组{num + 1}</strong> : type === 0 ? null : <strong style={{ fontSize: 14 }}>文案组{num + 1}</strong>}
  127. className="cardResetCss"
  128. style={{ marginTop: 10 }}
  129. key={key}
  130. >
  131. <Space style={{ display: 'flex' }} align="baseline">
  132. <Space style={{ width: '100%' }} direction="vertical" size={10}>
  133. {textList.map(item => {
  134. return <Form.Item
  135. {...restField}
  136. label={<strong>{item.label}</strong>}
  137. name={[name, item.value]}
  138. key={key}
  139. style={{ marginBottom: 0 }}
  140. rules={[{
  141. required: item.required, message: '请输入正确的' + item.label, validator: (rule, value) => {
  142. if (!value) {
  143. return Promise.reject()
  144. } else if (!value.match(RegExp(item.restriction.textRestriction.textPattern))) {
  145. return Promise.reject()
  146. } else if (txtLength(value) > item.restriction.textRestriction.maxLength) {
  147. return Promise.reject()
  148. }
  149. return Promise.resolve()
  150. }
  151. }]}
  152. >
  153. <TextAideInput placeholder={'请输入' + item.label} style={{ width: 450 }} maxTextLength={item.restriction.textRestriction.maxLength} />
  154. </Form.Item>
  155. })}
  156. </Space>
  157. {([3,2].includes(type) && textDto?.length > 1) && <Popconfirm
  158. title="你确定删除当前文案组?"
  159. onConfirm={() => remove(name)}
  160. >
  161. <MinusCircleOutlined style={{ marginLeft: 20, color: 'red' }} />
  162. </Popconfirm>}
  163. </Space>
  164. </Card>
  165. ))}
  166. {[3,2].includes(type) && !(type === 2 && textDto.length >= dynamicMaterialDTos.dynamicGroup.length) && <Form.Item style={{ marginTop: 10, marginBottom: 0 }}>
  167. <Button type="dashed" onClick={() => add({})} block icon={<PlusOutlined />} disabled={type === 3 && textDto.length >= 30}>
  168. 新增
  169. </Button>
  170. </Form.Item>}
  171. </>)}
  172. </Form.List>
  173. <Form.Item className="submit_pull">
  174. <Space>
  175. <Button onClick={onClose}>取消</Button>
  176. <Button type="primary" htmlType="submit" className="modalResetCss">
  177. 确定
  178. </Button>
  179. </Space>
  180. </Form.Item>
  181. </Form>
  182. </Modal>
  183. }
  184. export default React.memo(NewText)