copywriting.tsx 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. import TextAideInput from "@/pages/launchSystemNew/components/textAideInput"
  2. import { MinusCircleOutlined, PlusOutlined } from "@ant-design/icons"
  3. import { Button, Collapse, Form, Modal, Space } from "antd"
  4. import React, { useEffect, useState } from "react"
  5. import styles from './index.less'
  6. interface Props {
  7. value?: any[]
  8. textData?: any[],
  9. model?: 'cross' | 'corres',
  10. material?: {
  11. label: string;
  12. name: string;
  13. restriction: any;
  14. arrayProperty?: any;
  15. }[],
  16. sysAdcreative: any
  17. onChange?: (data: any) => void
  18. }
  19. /**
  20. * 文案设置
  21. * @returns
  22. */
  23. const Copywriting: React.FC<Props> = (props) => {
  24. /******************************/
  25. const { onChange, textData = [], sysAdcreative, value, model, material } = props
  26. const { adcreativeTemplateId, linkNameType } = sysAdcreative
  27. const [visible, setVisible] = useState<boolean>(false)
  28. const [form] = Form.useForm();
  29. /******************************/
  30. // 回填
  31. useEffect(() => {
  32. if (visible) {
  33. if (value && value?.length > 0) {
  34. form.setFieldsValue({ texts: value })
  35. } else {
  36. form.setFieldsValue({ texts: [undefined] })
  37. }
  38. }
  39. }, [value, visible])
  40. const handleOk = () => {
  41. form.validateFields().then(values => {
  42. console.log('values=>1', values)
  43. onChange && onChange(values?.texts)
  44. setVisible(false)
  45. })
  46. }
  47. return <>
  48. <span onClick={() => { setVisible(true) }}>{value && value?.length > 0 ? '编辑' : '添加'}</span>
  49. {visible && <Modal visible={visible} onCancel={() => setVisible(false)} title="创意文案" width={700} onOk={handleOk}>
  50. <Form name="dynamic_form_item" form={form} labelAlign='left' >
  51. <Form.List name="texts">
  52. {(fields, { add, remove }) => (<>
  53. <Collapse activeKey={fields.map(field => field.name)} bordered={false}>
  54. {fields.map((field, num) => (<Collapse.Panel
  55. showArrow={false}
  56. header={<Space>
  57. <span>{`文案组${num + 1}`}</span>
  58. <div className={styles.groups}>
  59. {material && material?.length >= num + 1 && model === 'corres' && [material[num]]?.map((item: any, index: number) => {
  60. let keys = Object.keys(item)
  61. if (keys?.includes('imageUrlList')) {
  62. return <div key={index} className={styles.group}>
  63. {item?.imageUrlList?.map((url: string, index: number) => <div key={index}><img src={url} /></div>)}
  64. </div>
  65. } else if (keys?.includes('elementStory')) {
  66. return <div key={index} className={styles.group}>
  67. {item?.elementStory?.map((item: { imageUrl: string }, index: number) => <div key={index}><img src={item.imageUrl} /></div>)}
  68. </div>
  69. } else {
  70. if (keys?.length > 1) {
  71. return <div key={index} className={styles.otherGroup}>
  72. {keys?.includes('imageUrl') && <div className={styles.group}><img src={item.imageUrl} /></div>}
  73. {keys?.includes('videoUrl') && <div className={styles.group}><video src={item.videoUrl} /></div>}
  74. {keys?.includes('shortVideo1Url') && <div className={styles.group}><video src={item.shortVideo1Url} /></div>}
  75. </div>
  76. } else {
  77. if (keys?.includes('imageUrl')) {
  78. return <div key={index} className={styles.group}><img src={item.imageUrl} /></div>
  79. } else if (keys?.includes('videoUrl')) {
  80. return <div key={index} className={styles.group}><video src={item.videoUrl} /></div>
  81. } else if (keys?.includes('shortVideo1Url')) {
  82. return <div key={index} className={styles.group}><video src={item.shortVideo1Url} /></div>
  83. }
  84. }
  85. return null
  86. }
  87. })}
  88. </div>
  89. </Space>}
  90. key={(field.name).toString()}
  91. extra={fields?.length > 1 && <MinusCircleOutlined className={styles.clear}
  92. onClick={() => remove(field.name)}
  93. style={{ color: 'red' }}
  94. />}
  95. >
  96. {textData?.map((item, index) => {
  97. if (item.name === 'title') {
  98. return <div key={'title' + item.fieldType}>
  99. <Form.Item {...field} label={<strong>{item.description}(选填)</strong>} name={[field.name, item.name]} rules={[{ pattern: RegExp(item.restriction.textRestriction.textPattern?.replace(/\+/ig, `{1,${item.restriction.textRestriction.maxLength}}`)), message: '请输入正确的' + item.description }]}>
  100. <TextAideInput placeholder={'请输入' + item.description} style={{ width: 450 }} maxTextLength={item.restriction.textRestriction.maxLength} />
  101. </Form.Item>
  102. </div>
  103. }
  104. if (item.name === 'description') {
  105. let maxNum = (adcreativeTemplateId === 1708 || adcreativeTemplateId === 1707) && linkNameType ? 10 : item.restriction.textRestriction.maxLength
  106. return <div key={'description' + item.fieldType}>
  107. <Form.Item {...field} label={<strong>{item.description}</strong>} name={[field.name, item.name]} rules={[{ required: true, pattern: RegExp(item.restriction.textRestriction.textPattern?.replace(/\+/ig, `{1,${maxNum}}`)), message: '请输入正确的' + item.description }]}>
  108. <TextAideInput placeholder={'请输入' + item.description} style={{ width: 450 }} maxTextLength={maxNum} />
  109. </Form.Item>
  110. </div>
  111. }
  112. return null
  113. })}
  114. </Collapse.Panel>))}
  115. </Collapse>
  116. <Form.Item>
  117. <Button type="link" onClick={() => add()} icon={<PlusOutlined />} style={{ padding: 0 }}>
  118. 新增文案组
  119. </Button>
  120. </Form.Item>
  121. </>)}
  122. </Form.List>
  123. </Form>
  124. </Modal>}
  125. </>
  126. }
  127. export default React.memo(Copywriting)