知与行后台管理端

editActivity.jsx 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. import React, { useState, useEffect } from 'react';
  2. import { Form, Input, Button, Icon, Select, Tabs, Radio, DatePicker, message, Upload } from 'antd';
  3. import { FormattedMessage } from 'umi-plugin-react/locale';
  4. import styles from '../style/GoodsList.less';
  5. import apis from '../../services/apis';
  6. import moment from 'moment';
  7. import router from 'umi/router';
  8. import BuildSelect from '../../components/SelectButton/BuildSelect'
  9. import XForm, { FieldTypes } from '../../components/XForm';
  10. import Wangedit from '../../components/Wangedit/Wangedit'
  11. import request from '../../utils/request'
  12. import yinhao from '../../assets/yinhao.png'
  13. import ImageUploader from '../../components/XForm/ImageUpload';
  14. import logo from '../../assets/logo.png';
  15. import touxiang from '../../assets/touxiang.jpg';
  16. import poster1 from '../../assets/poster1.png';
  17. import poster2 from '../../assets/poster2.png';
  18. import xiaochengxu from '../../assets/xiaochengxu.png'
  19. const { MonthPicker, RangePicker, WeekPicker } = DatePicker;
  20. const { TextArea } = Input;
  21. const formItemLayout = {
  22. labelCol: { span: 6 },
  23. wrapperCol: { span: 14 },
  24. };
  25. const BasicForm = props => {
  26. const [isEnlist, setIsEnlist] = useState(1)
  27. const [activityStatus, setActivityStatus] = useState(1)
  28. const [disable, setDisable] = useState(false)
  29. const radioOnChange = e => {
  30. setIsEnlist(e.target.value)
  31. }
  32. const { dynamicId } = props
  33. // 查询详情
  34. const getDynamicData = dynamicId => {
  35. request({ ...apis.activity.details, params: { dynamicId } }).then((data) => {
  36. console.log(data)
  37. data.activityTime = [moment(data.startDate), moment(data.endDate)]
  38. data.signupTime = [moment(data.enlistStart), moment(data.enlistEnd)]
  39. setIsEnlist(data.isEnlist)
  40. setActivityStatus(data.activityStatus)
  41. setDisable(data.activityStatus === 0 ? true : false)
  42. props.form.setFieldsValue(data)
  43. })
  44. }
  45. // eslint-disable-next-line react-hooks/rules-of-hooks
  46. useEffect(() => {
  47. props.form.setFieldsValue({ isEnlist })
  48. if (dynamicId) {
  49. getDynamicData(dynamicId);
  50. }
  51. }, [])
  52. const handleSubmit = e => {
  53. e.preventDefault();
  54. props.form.validateFields((err, values) => {
  55. if (!err) {
  56. console.log('Received values of form: ', values);
  57. const { activityTime, signupTime } = values
  58. const [startDate, endDate] = activityTime
  59. values.startDate = moment(startDate).format('YYYY-MM-DD HH:mm');
  60. values.endDate = moment(endDate).format('YYYY-MM-DD HH:mm');
  61. if (signupTime) {
  62. const [enlistStart, enlistEnd] = signupTime
  63. values.enlistStart = moment(enlistStart).format('YYYY-MM-DD HH:mm');
  64. values.enlistEnd = moment(enlistEnd).format('YYYY-MM-DD HH:mm');
  65. }
  66. console.log('submit data --->', values)
  67. if (dynamicId) {
  68. values.dynamicId = dynamicId
  69. request({ ...apis.activity.update, data: values }).then(data => {
  70. message.info('保存成功')
  71. // router.go(-1)
  72. }).catch((err) => {
  73. message.info(err.msg || err.message)
  74. })
  75. } else {
  76. request({ ...apis.activity.add, data: { ...values } }).then((data) => {
  77. message.info('保存成功')
  78. // router.go(-1)
  79. }).catch((err) => {
  80. message.info(err.msg || err.message)
  81. })
  82. }
  83. }
  84. });
  85. }
  86. const { getFieldDecorator } = props.form;
  87. return (
  88. <>
  89. <Form {...formItemLayout} onSubmit={handleSubmit}>
  90. <Form.Item label="所属项目">
  91. {getFieldDecorator('buildingId', {
  92. rules: [
  93. {
  94. required: true,
  95. message: '请选择所属项目',
  96. },
  97. ],
  98. })(<BuildSelect disabled={disable}/>)}
  99. </Form.Item>
  100. <Form.Item label="活动封面图1" help="建议图片尺寸:750px*420px,比例16:9,格式:jpg,用于活动列表">
  101. {getFieldDecorator('listImgUrl', {
  102. rules: [
  103. {
  104. required: true,
  105. message: '请选择活动封面图1',
  106. },
  107. ],
  108. })(<ImageUploader />)}
  109. </Form.Item>
  110. <Form.Item label="活动详情主图" help="建议图片尺寸:750*600px,比例5:4,格式:jpg,用于普通活动详情">
  111. {getFieldDecorator('imgUrl', {
  112. rules: [
  113. {
  114. required: true,
  115. message: '请选择活动详情主图',
  116. },
  117. ],
  118. })(<ImageUploader />)}
  119. </Form.Item>
  120. <Form.Item label="活动标题">
  121. {getFieldDecorator('title', {
  122. rules: [
  123. {
  124. required: true,
  125. message: '请输入活动标题',
  126. },
  127. ],
  128. })(<Input/>)}
  129. </Form.Item>
  130. <Form.Item label="活动时间">
  131. {getFieldDecorator('activityTime', {
  132. rules: [
  133. {
  134. required: true,
  135. message: '请选择活动时间',
  136. },
  137. ],
  138. })(<RangePicker format="YYYY-MM-DD HH:mm" disabled={activityStatus===0 ? true : false}/>)}
  139. </Form.Item>
  140. <Form.Item label="活动地点">
  141. {getFieldDecorator('address', {
  142. rules: [
  143. {
  144. required: true,
  145. message: '请输入活动地点',
  146. },
  147. ],
  148. })(<Input disabled={activityStatus===0 ? true : false}/>)}
  149. </Form.Item>
  150. <Form.Item label="活动人数">
  151. {getFieldDecorator('personNum', {
  152. rules: [
  153. {
  154. required: true,
  155. message: '请输入活动人数',
  156. },
  157. ],
  158. })(<Input type="number" disabled={activityStatus===0 ? true : false}/>)}
  159. </Form.Item>
  160. <Form.Item label="最大报名人数">
  161. {getFieldDecorator('maxEnlistByPerson', {
  162. rules: [
  163. {
  164. required: true,
  165. message: '请输入最大报名人数',
  166. },
  167. ],
  168. })(<Input type="number" disabled={activityStatus===0 ? true : false}/>)}
  169. </Form.Item>
  170. <Form.Item label="活动详情">
  171. {getFieldDecorator('desc')(<Wangedit />)}
  172. </Form.Item>
  173. <Form.Item label="报名时间">
  174. {getFieldDecorator('signupTime', {
  175. rules: [
  176. {
  177. required: true,
  178. message: '请选择报名时间',
  179. },
  180. ],
  181. })(<RangePicker format="YYYY-MM-DD HH:mm" disabled={activityStatus===0 ? true : false}/>)}
  182. </Form.Item>
  183. <Form.Item label="权重">
  184. {getFieldDecorator('heavy', {
  185. rules: [
  186. {
  187. required: true,
  188. message: '请输入权重',
  189. },
  190. ],
  191. })(<Input type="number" style={{ width: 80}}/>)}<span style={{ marginLeft: 30, color:'grey'}}>数字越大越靠前</span>
  192. </Form.Item>
  193. <Form.Item wrapperCol={{ span: 12, offset: 8 }}>
  194. <Button type="primary" htmlType="submit">
  195. 确认
  196. </Button>
  197. &nbsp;&nbsp;&nbsp;&nbsp;
  198. <Button onClick={() => router.go(-1)}>
  199. 取消
  200. </Button>
  201. </Form.Item>
  202. </Form>
  203. </>
  204. )
  205. }
  206. const Basic = Form.create({ name: 'BasicForm' })(BasicForm);
  207. /**
  208. *
  209. *
  210. * @param {*} props
  211. * @returns
  212. */
  213. const Edit = props => {
  214. const [tab, changeTab] = useState('basic')
  215. const { dynamicId } = props.location.query
  216. const cancelPage = () => {
  217. router.push({
  218. pathname: '/activity/ActivityList',
  219. });
  220. }
  221. const Poster = (props) => {
  222. const [inputValue, changeInput] = useState('')
  223. const [textAreaValue, changeTextArea] = useState('')
  224. const [imgValue, changeImg] = useState('')
  225. const [posterId, setPosterId] = useState('')
  226. if (dynamicId) {
  227. console.log(dynamicId, 'dynamicId')
  228. useEffect(() => {
  229. request({ ...apis.activity.poster, params: { targetId: dynamicId, targetType: 'activity' } }).then((data) => {
  230. console.log(data, "2222")
  231. if (data.length > 0) {
  232. setPosterId(data[0].posterId)
  233. changeImg(data[0].posterImg)
  234. changeTextArea(data[0].posterDescription)
  235. changeInput(data[0].posterTitle)
  236. }
  237. }).catch((err) => {
  238. message.info(err.msg || err.message)
  239. })
  240. getMiniappName()
  241. }, [])
  242. }else{
  243. getMiniappName()
  244. }
  245. // 获取小程序名称
  246. const [miniappName, setMiniappName] = useState('')
  247. function getMiniappName() {
  248. request({ ...apis.building.getMiniappName }).then(res => {
  249. console.log(res, "0000000000000")
  250. setMiniappName(res)
  251. })
  252. }
  253. const submitPoster = () => {
  254. if (dynamicId) {
  255. if (posterId) {
  256. request({ ...apis.activity.updatePoster, urlData: { id: posterId }, data: { targetId: dynamicId, targetType: 'activity', posterImg: imgValue, posterTitle: inputValue, posterDescription: textAreaValue }, }).then((data) => {
  257. message.info("保存成功")
  258. }).catch((err) => {
  259. message.info(err.msg || err.message)
  260. })
  261. } else {
  262. request({ ...apis.activity.addPoster, data: { targetId: dynamicId, targetType: 'activity', posterImg: imgValue, posterTitle: inputValue, posterDescription: textAreaValue }, }).then((data) => {
  263. setPosterId(data.posterId)
  264. message.info("保存成功")
  265. }).catch((err) => {
  266. message.info(err.msg || err.message)
  267. })
  268. }
  269. } else {
  270. message.warn("请先保存基本信息数据")
  271. }
  272. }
  273. return <div>
  274. <div style={{ display: 'flex' }}>
  275. <div style={{ width: '420px', height: '900px', display: 'inline-block', marginTop: '30px' }}>
  276. <div style={{ width: '375px', height: '700px', backgroundColor: '#fff', boxShadow: '0px 0px 16px 6px rgba(0,0,0,0.15)', position: 'relative', margin: '0 auto' }}>
  277. <img style={{ width: '100%', height: '300px' }} src={imgValue ? imgValue : poster1} alt="" />
  278. <div style={{ display: 'flex', alignItems: 'center', marginTop: '-24px' }}>
  279. <img style={{ width: '70px', height: '70px', border: '4px solid #fff', borderRadius: '35px', marginLeft: '16px' }} src={touxiang} alt="" />
  280. <span style={{ color: '#222', fontWeight: '600', margin: '24px 10px 0 14px', fontSize: '17px' }}>喵喵</span>
  281. <span style={{ color: '#999', marginTop: '25px', fontSize: '17px' }}>邀您参与</span>
  282. <span style={{ color: '#999', margin: '25px 0 0 60px', fontSize: '17px' }}>2019.09.21</span>
  283. </div>
  284. <p style={{
  285. margin: '10px 20px',
  286. fontSize: '20px',
  287. color: '#222',
  288. fontWeight: '600',
  289. display: '-webkit-box',
  290. lineClamp: '3',
  291. height: '60px',
  292. WebkitLineClamp: '2',
  293. WebkitBoxOrient: 'vertical',
  294. overflow: 'hidden',
  295. textOverflow: 'ellipsis'
  296. }}>{inputValue ? inputValue : '海报标题'}</p>
  297. <img src={yinhao} style={{ width: '30px', marginLeft: '20px' }} alt="" />
  298. <p style={{
  299. margin: '16px 20px 28px 20px',
  300. fontSize: '17px',
  301. color: '#999',
  302. display: '-webkit-box',
  303. lineClamp: '3',
  304. height: '72px',
  305. WebkitLineClamp: '3',
  306. WebkitBoxOrient: 'vertical',
  307. overflow: 'hidden',
  308. textOverflow: 'ellipsis'
  309. }}>{textAreaValue ? textAreaValue : '海报描述'}</p>
  310. <div style={{ backgroundColor: '#f1f1f1', padding: '22px 30px', boxShadow: '0px 6px 12px -4px #dcdcdc', position: 'relative' }}>
  311. <p style={{ margin: '0', fontSize: '18px', color: '#888' }}>长按识别小程序码</p>
  312. <p style={{ margin: '0', fontSize: '18px', color: '#888' }}>进入<span style={{ margin: '0 5px', fontSize: '18px', color: '#333', fontWeight: '600' }}>{miniappName || '置业V顾问'}</span>报名活动</p>
  313. <img style={{ width: '80px', position: 'absolute', right: '30px', top: '10px' }} src={xiaochengxu} alt="" />
  314. </div>
  315. </div>
  316. <p style={{ textAlign: 'center', fontSize: '19px', color: '#666', marginTop: '30px' }}>海报模板</p>
  317. </div>
  318. <div >
  319. <div style={{ display: 'flex', width: '100%', margin: '60px 0' }}>
  320. <p style={{ minWidth: '200px', color: '#222', textAlign: 'right', margin: '0 30px 0 0' }}>活动海报图</p>
  321. <ImageUploader value={imgValue} onChange={e => changeImg(e)} />
  322. </div>
  323. <p style={{ fontSize: '0.5vw', color: '#A9A9A9', marginLeft: '230px', marginBottom: '30px'}}>建议图片尺寸:750*600px,比例5:4,格式:jpg,用于普通活动海报</p>
  324. <div style={{ display: 'flex', alignItems: 'center', width: '100%', marginBottom: '60px' }}>
  325. <p style={{ minWidth: '200px', color: '#222', textAlign: 'right', margin: '0 30px 0 0' }}>海报标题</p>
  326. <Input style={{ width: '20vw' }} value={inputValue} placeholder="请输入海报标题" onChange={e => changeInput(e.target.value)} />
  327. </div>
  328. <div style={{ display: 'flex', margin: '10px 0 40px 0', width: '100%' }}>
  329. <p style={{ minWidth: '200px', color: '#222', textAlign: 'right', margin: '0 30px 0 0' }}>海报描述</p>
  330. <TextArea rows={5} value={textAreaValue} onChange={e => changeTextArea(e.target.value)} />
  331. </div>
  332. </div>
  333. </div>
  334. <Button type="primary" onClick={submitPoster} style={{ margin: '40px 40px 40px 30vw' }}> 确定</Button>
  335. <Button onClick={() => router.go(-1)}>取消</Button>
  336. </div>
  337. }
  338. const Share = (props) => {
  339. const [inputValue, changeInput] = useState('')
  340. const [imgValue, changeImg] = useState('')
  341. const [shareContentId, setShareContentId] = useState('')
  342. if (dynamicId) {
  343. useEffect(() => {
  344. request({ ...apis.activity.shareContent, params: { targetId: dynamicId, targetType: 'activity' }, }).then((data) => {
  345. console.log(data, "2222")
  346. if (data.length > 0) {
  347. setShareContentId(data[0].shareContentId)
  348. changeImg(data[0].shareContentImg)
  349. changeInput(data[0].shareContentTitle)
  350. }
  351. }).catch((err) => {
  352. message.info(err.msg || err.message)
  353. })
  354. }, [])
  355. }
  356. const submitShare = () => {
  357. if (dynamicId) {
  358. if (shareContentId) {
  359. request({ ...apis.activity.updateShareContent, urlData: { id: shareContentId }, data: { targetId: dynamicId, shareContentType: 'activity', shareContentImg: imgValue, shareContentTitle: inputValue }, }).then((data) => {
  360. message.info("保存成功")
  361. }).catch((err) => {
  362. message.info(err.msg || err.message)
  363. })
  364. } else {
  365. request({ ...apis.activity.addShareContent, data: { targetId: dynamicId, shareContentType: 'activity', shareContentImg: imgValue, shareContentTitle: inputValue }, }).then((data) => {
  366. setShareContentId(data.shareContentId)
  367. message.info("保存成功")
  368. }).catch(err => {
  369. message.info(err.msg || err.message)
  370. })
  371. }
  372. } else {
  373. message.warn("请先保存基本信息数据")
  374. }
  375. }
  376. return <div style={{ padding: '20px' }}>
  377. <div style={{ display: 'flex', margin: '10px 0 40px 0', width: '100%' }}>
  378. <p style={{ minWidth: '200px', color: '#222', textAlign: 'right', margin: '0 30px 0 0' }}>分享模板</p>
  379. <div>
  380. <p style={{ display: 'flex', alignItems: 'center', fontSize: '14px', color: '#999', margin: '0', lineHeight: '0' }}><img src={logo} style={{ width: '22px', marginRight: '10px' }} />知与行互动</p>
  381. <p style={{ fontSize: '16px', color: '#222', fontWeight: '600', margin: '0' }}>{inputValue ? inputValue : '置业V客厅 精准获客平台'}</p>
  382. <img style={{ width: '200px', height: '140px' }} src={imgValue ? imgValue : poster2} alt="" />
  383. </div>
  384. </div>
  385. <div style={{ display: 'flex', alignItems: 'center', width: '100%' }}>
  386. <p style={{ minWidth: '200px', color: '#222', textAlign: 'right', margin: '0 30px 0 0' }}>分享标题</p>
  387. <Input placeholder="请输入分享标题" value={inputValue} onChange={e => changeInput(e.target.value)} />
  388. </div>
  389. <div style={{ display: 'flex', width: '100%', marginTop: '40px' }}>
  390. <p style={{ minWidth: '200px', color: '#222', textAlign: 'right', margin: '0 30px 0 0' }}>活动分享图</p>
  391. <ImageUploader value={imgValue} onChange={e => changeImg(e)} />
  392. </div>
  393. <p style={{ fontSize: '0.5vw', color: '#A9A9A9', marginLeft: '230px', marginTop: '20px' }}>建议图片尺寸:750*600px,比例5:4,格式:jpg,用于活动分享好友</p>
  394. <Button type="primary" htmlType="submit" onClick={submitShare} style={{ margin: '40px 40px 40px 220px' }}> 确定</Button>
  395. <Button onClick={() => router.go(-1)}>取消</Button>
  396. </div>
  397. }
  398. return (
  399. <div>
  400. <div>
  401. <Radio.Group value={tab} buttonStyle="solid" onChange={e => changeTab(e.target.value)}>
  402. <Radio.Button value="basic">基本信息</Radio.Button>
  403. <Radio.Button value="poster">海报图片</Radio.Button>
  404. <Radio.Button value="share">分享设置</Radio.Button>
  405. </Radio.Group>
  406. </div>
  407. <div>
  408. {tab === 'basic' && <Basic dynamicId={dynamicId} />}
  409. {tab === 'poster' && <Poster />}
  410. {tab === 'share' && <Share />}
  411. </div>
  412. </div>
  413. );
  414. }
  415. export default Edit