index.tsx 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. import React, { useCallback, useEffect, useRef, useState } from 'react'
  2. import styles from './index.module.scss'
  3. import classNames from 'classnames'
  4. import { A1EditInfoType } from '../data'
  5. import {
  6. Button,
  7. Form,
  8. FormInstance,
  9. Input,
  10. DatePicker,
  11. Select,
  12. InputNumber,
  13. TimePicker
  14. } from 'antd'
  15. import TextArea from 'antd/es/input/TextArea'
  16. import { A5_APIgetInfo, A5_APIadd, A5_APIedit } from '@/store/action/A5activity'
  17. import { MessageFu } from '@/utils/message'
  18. import ZupOne from '@/components/ZupOne'
  19. import MyPopconfirm from '@/components/MyPopconfirm'
  20. import dayjs from 'dayjs'
  21. import ZRichTexts from '@/components/ZRichTexts'
  22. import { A5AddType, A5tableType } from '@/types/api/A5activity'
  23. type Props = {
  24. editInfo: A1EditInfoType
  25. closeFu: () => void
  26. addTableFu: () => void
  27. editTableFu: () => void
  28. }
  29. function A5add({ editInfo, closeFu, addTableFu, editTableFu }: Props) {
  30. // 表单的ref
  31. const FormBoxRef = useRef<FormInstance>(null)
  32. // 封面图的ref
  33. const ZupThumbRef1 = useRef<any>(null)
  34. const ZupThumbRef2 = useRef<any>(null)
  35. // 正文的ref
  36. const ZRichTextRef = useRef<any>(null)
  37. // 回显数据的方法调用
  38. const dataShow = useCallback((info: A5tableType) => {
  39. let editObj = null
  40. if (info.status === 0) {
  41. editObj = {
  42. ...info,
  43. title: info.titleB,
  44. publish: info.publishB,
  45. remark: info.remarkB,
  46. context: info.contextB,
  47. indexImg: info.indexImgB,
  48. indexImgTh: info.indexImgThB,
  49. infoImg: info.infoImgB,
  50. infoImgTh: info.infoImgThB
  51. }
  52. } else {
  53. editObj = { ...info }
  54. }
  55. FormBoxRef.current?.setFieldsValue({
  56. ...editObj,
  57. publish: dayjs(editObj.publish),
  58. date: editObj.subscribe === 1 ? [dayjs(editObj.startTime), dayjs(editObj.endTime)] : [],
  59. time:
  60. editObj.subscribe === 1
  61. ? [dayjs(editObj.time.split('-')[0], 'HH:mm'), dayjs(editObj.time.split('-')[1], 'HH:mm')]
  62. : []
  63. })
  64. // 设置封面图
  65. ZupThumbRef1.current?.setFileComFileFu({
  66. fileName: '',
  67. thUrl: editObj.indexImgTh,
  68. url: editObj.indexImg
  69. })
  70. ZupThumbRef2.current?.setFileComFileFu({
  71. fileName: '',
  72. thUrl: editObj.infoImgTh,
  73. url: editObj.infoImg
  74. })
  75. // 设置正文
  76. ZRichTextRef.current?.ritxtShowFu({
  77. txtArr: [
  78. {
  79. id: editObj.activityId,
  80. name: '正文',
  81. txt: editObj.context,
  82. fileInfo: { fileName: '', filePath: '' }
  83. }
  84. ]
  85. })
  86. }, [])
  87. // 编辑 进入页面 获取信息
  88. const getInfoFu = useCallback(
  89. async (id: number) => {
  90. if (editInfo.info) dataShow(editInfo.info)
  91. else {
  92. const res = await A5_APIgetInfo(id)
  93. if (res.code === 0) {
  94. dataShow(res.data)
  95. setIsReserve(res.data.subscribe || 0)
  96. }
  97. }
  98. },
  99. [dataShow, editInfo.info]
  100. )
  101. // 附件 是否 已经点击过确定
  102. const [fileCheck, setFileCheck] = useState(false)
  103. // 编辑填入数据
  104. useEffect(() => {
  105. if (editInfo.id > 0) {
  106. getInfoFu(editInfo.id)
  107. }
  108. }, [editInfo.id, getInfoFu])
  109. // 没有通过校验
  110. const onFinishFailed = useCallback(() => {
  111. setFileCheck(true)
  112. }, [])
  113. // 通过校验点击确定
  114. const onFinish = useCallback(
  115. async (values: any) => {
  116. setFileCheck(true)
  117. const coverUrl1 = ZupThumbRef1.current?.fileComFileResFu()
  118. const coverUrl2 = ZupThumbRef2.current?.fileComFileResFu()
  119. const context = ZRichTextRef.current?.fatherBtnOkFu()
  120. // 没有传 封面图
  121. if (!coverUrl1.url) return MessageFu.warning('请上传首页封面图!')
  122. if (!coverUrl2.url) return MessageFu.warning('请上传详情封面图!')
  123. if (!context.val.txtArr[0].txt) return MessageFu.warning('请输入正文!')
  124. // 发布
  125. const obj1: A5AddType = {
  126. ...values,
  127. indexImg: coverUrl1.url,
  128. indexImgTh: coverUrl1.thUrl,
  129. infoImg: coverUrl2.url,
  130. infoImgTh: coverUrl2.thUrl,
  131. context: context.val.txtArr[0].txt,
  132. publish: values.publish?.format('YYYY-MM-DD') || '',
  133. publishB: '',
  134. status: 1,
  135. titleB: '',
  136. urlB: '',
  137. startTime: values?.date?.[0]?.format('YYYY-MM-DD') || '',
  138. endTime: values?.date?.[1]?.format('YYYY-MM-DD') || '',
  139. personCount: values?.personCount || 1,
  140. time: values?.time?.map((item: any) => item.format('HH:mm')).join('-') || '',
  141. guide: values?.guide || ''
  142. }
  143. // 预发布
  144. const obj2: A5AddType = {
  145. indexImg: '',
  146. indexImgB: coverUrl1.url,
  147. indexImgTh: '',
  148. indexImgThB: coverUrl1.thUrl,
  149. infoImg: '',
  150. infoImgB: coverUrl2.url,
  151. infoImgTh: '',
  152. infoImgThB: coverUrl2.thUrl,
  153. publish: '',
  154. publishB: values.publish?.format('YYYY-MM-DD') || '',
  155. status: 0,
  156. subscribe: values.subscribe,
  157. title: '',
  158. titleB: values.title,
  159. remark: '',
  160. remarkB: values.remark,
  161. context: '',
  162. contextB: context.val.txtArr[0].txt,
  163. startTime: values?.date?.[0]?.format('YYYY-MM-DD') || '',
  164. endTime: values?.date?.[1]?.format('YYYY-MM-DD') || '',
  165. personCount: values?.personCount || 1,
  166. time: values?.time?.map((item: any) => item.format('HH:mm')).join('-') || '',
  167. guide: values?.guide || ''
  168. }
  169. let res: any
  170. if (btnRef.current === '1') {
  171. res =
  172. editInfo.txt === '新增'
  173. ? await A5_APIadd(obj1)
  174. : await A5_APIedit({ ...obj1, activityId: editInfo.id })
  175. } else {
  176. res =
  177. editInfo.txt === '新增'
  178. ? await A5_APIadd(obj2)
  179. : await A5_APIedit({ ...obj2, activityId: editInfo.id })
  180. }
  181. if (res.code === 0) {
  182. MessageFu.success(`${editInfo.txt}成功!`)
  183. editInfo.id > 0 ? editTableFu() : addTableFu()
  184. closeFu()
  185. }
  186. },
  187. [addTableFu, closeFu, editInfo.id, editInfo.txt, editTableFu]
  188. )
  189. const formOkBtnRef = useRef<any>(null)
  190. const btnRef = useRef('')
  191. const [isReserve, setIsReserve] = useState(0)
  192. return (
  193. <div className={styles.A5add}>
  194. <div className={classNames('A5aMain')}>
  195. <Form
  196. ref={FormBoxRef}
  197. name='basic'
  198. labelCol={{ span: 3 }}
  199. onFinish={onFinish}
  200. onFinishFailed={onFinishFailed}
  201. autoComplete='off'
  202. scrollToFirstError
  203. >
  204. <Form.Item
  205. label='标题'
  206. name='title'
  207. rules={[{ required: true, message: '请输入标题!' }]}
  208. >
  209. <Input placeholder='请输入内容,不超过30个字' maxLength={30} showCount />
  210. </Form.Item>
  211. <Form.Item
  212. label='发布日期'
  213. name='publish'
  214. initialValue={dayjs()}
  215. rules={[{ required: true, message: '请选择日期!' }]}
  216. >
  217. <DatePicker
  218. allowClear
  219. defaultValue={dayjs()}
  220. placeholder='请选择日期'
  221. style={{ width: 200 }}
  222. />
  223. </Form.Item>
  224. <Form.Item label='摘要' name='remark'>
  225. <TextArea maxLength={200} showCount placeholder='请输入内容,不超过200个字' />
  226. </Form.Item>
  227. <Form.Item label='正文' name='context'>
  228. <ZRichTexts
  229. check={true}
  230. dirCode={'A4news'}
  231. isLook={false}
  232. ref={ZRichTextRef}
  233. myUrl='museum/upload/upload'
  234. isOne={true}
  235. upAudioBtnNone={true}
  236. />
  237. </Form.Item>
  238. {/* 封面 */}
  239. <div className='formRow'>
  240. <div className='formLeft'>
  241. <span>* </span>
  242. 首页封面:
  243. </div>
  244. <div className='formRight'>
  245. <ZupOne
  246. ref={ZupThumbRef1}
  247. fileCheck={fileCheck}
  248. size={5}
  249. dirCode={'A5'}
  250. myUrl='museum/upload/uploadImg'
  251. format={['image/jpg', 'image/png']}
  252. inchTxt='5:6'
  253. formatTxt='png、jpg'
  254. checkTxt='请上传封面图!'
  255. upTxt='最多1张'
  256. myType='thumb'
  257. />
  258. </div>
  259. </div>
  260. <div className='formRow'>
  261. <div className='formLeft'>
  262. <span>* </span>
  263. 详情封面:
  264. </div>
  265. <div className='formRight'>
  266. <ZupOne
  267. ref={ZupThumbRef2}
  268. fileCheck={fileCheck}
  269. size={5}
  270. dirCode={'A5'}
  271. myUrl='museum/upload/uploadImg'
  272. format={['image/jpg', 'image/png']}
  273. inchTxt='3:2'
  274. formatTxt='png、jpg'
  275. checkTxt='请上传封面图!'
  276. upTxt='最多1张'
  277. myType='thumb'
  278. />
  279. </div>
  280. </div>
  281. <Form.Item
  282. label='需要预约'
  283. name='subscribe'
  284. initialValue={0}
  285. rules={[{ required: true, message: '请选择预约类型!' }]}
  286. >
  287. <Select
  288. defaultValue={0}
  289. onChange={val => {
  290. setIsReserve(val)
  291. }}
  292. options={[
  293. { label: '是', value: 1 },
  294. { label: '否', value: 0 }
  295. ]}
  296. />
  297. </Form.Item>
  298. {isReserve === 1 && (
  299. <div className='reserveBox'>
  300. <Form.Item
  301. label='活动日期'
  302. name='date'
  303. rules={[{ required: !!isReserve, message: '请选择活动日期' }]}
  304. >
  305. <DatePicker.RangePicker />
  306. </Form.Item>
  307. <Form.Item
  308. label='可预约人数'
  309. name='personCount'
  310. initialValue={1}
  311. rules={[{ required: !!isReserve, message: '请输入可预约人数' }]}
  312. >
  313. <InputNumber defaultValue={1} min={1} max={9999} />
  314. </Form.Item>
  315. <Form.Item
  316. label='活动时间段'
  317. name='time'
  318. rules={[{ required: !!isReserve, message: '请选择活动时间段' }]}
  319. >
  320. <TimePicker.RangePicker
  321. format='HH:mm'
  322. disabledTime={() => ({
  323. disabledHours: () => [0, 1, 2, 3, 4, 5, 6, 7, 21, 22, 23],
  324. disabledMinutes: currentHour => {
  325. if (currentHour === 20) {
  326. return Array.from({ length: 59 }, (_, i) => i + 1)
  327. }
  328. return []
  329. }
  330. })}
  331. />
  332. </Form.Item>
  333. </div>
  334. )}
  335. {/* 确定和取消按钮 */}
  336. <Form.Item className='A5abtn'>
  337. <div className='A5abtnBox'>
  338. <Button
  339. type='primary'
  340. htmlType='submit'
  341. onClick={() => {
  342. btnRef.current = '1'
  343. formOkBtnRef.current?.click()
  344. }}
  345. >
  346. 发布
  347. </Button>
  348. <Button
  349. type='primary'
  350. htmlType='submit'
  351. onClick={() => {
  352. btnRef.current = '0'
  353. formOkBtnRef.current?.click()
  354. }}
  355. >
  356. 预发布
  357. </Button>
  358. <MyPopconfirm txtK='取消' onConfirm={closeFu} />
  359. </div>
  360. </Form.Item>
  361. </Form>
  362. </div>
  363. </div>
  364. )
  365. }
  366. const MemoA5add = React.memo(A5add)
  367. export default MemoA5add