index.jsx 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. import React, { useState } from 'react'
  2. import { Button, Row, Col, DatePicker, Form, Input, InputNumber, Radio, notification, Select } from 'antd'
  3. import FileUpload from '@/components/XForm/FileUpload'
  4. import ImageUpload from '@/components/XForm/ImageUpload'
  5. import ImageListUpload from '@/components/XForm/ImageListUpload'
  6. import SelectCity from '@/components/SelectButton/CitySelect'
  7. import AreaSelect from '@/components/SelectButton/AreaSelect'
  8. import { POI_TYPES_KETY, POI_TYPES, getPoiData } from '@/utils/map'
  9. import Amap from '../components/Amap'
  10. import BuildingType from '../components/BuildingTypeSelect'
  11. import OpenTimePicker from '../components/OpenTimePicker'
  12. import EditableArround from '../components/EditableArround'
  13. import FormGroupItem, { gourpItemLayout } from '../components/FormGroupItem'
  14. import { formItemLayout, validMinNum } from '../utils'
  15. const fullWidth= { width: '100%' }
  16. const Item = Form.Item
  17. const initPoiData = POI_TYPES.map((poi) => poi.key).reduce((acc, key) => ({ ...acc, [key]: undefined }), {})
  18. const BuildingBasic = React.forwardRef((props, ref) => {
  19. const [pois, setPois] = useState(initPoiData)
  20. const { form } = props;
  21. const { getFieldDecorator, getFieldValue, setFieldsValue } = form;
  22. // 视频文件上传前 回调
  23. const fileUploadBeforeUpload = (file, fileList) => {
  24. return new Promise((resolve, reject) => {
  25. if (file.type === 'video/mp4' || file.type === '.mp4') {
  26. // setVideoImage(true)
  27. resolve(file)
  28. } else {
  29. notification.error({ message: '项目视频,仅支持MP4格式' })
  30. reject()
  31. }
  32. })
  33. }
  34. // 周边设施 回调
  35. function handleMapScopeChange(e) {
  36. const coordinateValue = getFieldValue('coordinate')
  37. if (!coordinateValue) {
  38. notification.error({ message: '请先选择项目坐标位置' })
  39. return
  40. }
  41. const lngLat = getFieldValue('coordinate').split(',')
  42. let poisCopy = { ...pois }
  43. // 把支持的周边分类都去检索一遍
  44. POI_TYPES.forEach(({ key }) => {
  45. getPoiData({ type: key, location: lngLat, radius: e }).then(res => {
  46. const poiStr = (res.pois || []).map((p) => p.name).join(',')
  47. poisCopy = {
  48. ...poisCopy,
  49. [key]: poiStr
  50. }
  51. setPois({ ...poisCopy })
  52. }).catch(err => {
  53. console.error(err)
  54. notification.error({ message: '周边数据获取失败' })
  55. })
  56. })
  57. }
  58. return (
  59. <Form {...formItemLayout}>
  60. <Item label="项目Id" style={{ display: 'none' }}>
  61. {getFieldDecorator('buildingId')(<Input disabled />)}
  62. </Item>
  63. <Item label="楼盘编号" >
  64. {getFieldDecorator('code', {
  65. rules: [{ required: true, message: '请输入楼盘编号' }],
  66. })(<Input />)}
  67. </Item>
  68. <Item label="楼盘名称" >
  69. {getFieldDecorator('buildingName', {
  70. rules: [{ required: true, message: '请输入楼盘名' }],
  71. })(<Input />)}
  72. </Item>
  73. <Form.Item label="项目类型">
  74. {getFieldDecorator('buildingProjectType', {
  75. rules: [{ required: true, message: '请选择项目类型' }],
  76. })(<BuildingType />)}
  77. </Form.Item>
  78. <Form.Item label="列表均价" help="项目列表展示价格,示例:约10000元/㎡、约1000万元/套起">
  79. {getFieldDecorator('price')(<Input />)}
  80. </Form.Item>
  81. <FormGroupItem>
  82. <Form.Item label="开盘时间" {...gourpItemLayout.ab.a} >
  83. {getFieldDecorator('openingDate')(
  84. <OpenTimePicker placeholder="请选择开盘时间" style={fullWidth} />
  85. )}
  86. </Form.Item>
  87. <Form.Item label="电话" {...gourpItemLayout.ab.b } >
  88. {getFieldDecorator('tel', {
  89. rules: [
  90. {
  91. pattern: new RegExp('^[0-9]*$'),
  92. message: '请输入正确的电话号码',
  93. },
  94. ],
  95. })(<Input placeholder="手机或者座机号码" />)}
  96. </Form.Item>
  97. </FormGroupItem>
  98. <Form.Item label="项目说明" >
  99. {getFieldDecorator('dynamic')(<Input placeholder="项目动态等,不超过30个字" maxLength={30}/>)}
  100. </Form.Item>
  101. {/* <Form.Item label="物业类型" >
  102. {getFieldDecorator('propertyType')(<Input />)}
  103. </Form.Item> */}
  104. <Form.Item label="销售状态" >
  105. {getFieldDecorator('marketStatus', {
  106. rules: [{ required: true, message: '请选择销售状态' }],
  107. })(
  108. <Select placeholder="销售状态" style={fullWidth}>
  109. <Select.Option value="待售">待售</Select.Option>
  110. <Select.Option value="在售">在售</Select.Option>
  111. <Select.Option value="售罄">售罄</Select.Option>
  112. <Select.Option value="在租">在租</Select.Option>
  113. </Select>,
  114. )}
  115. </Form.Item>
  116. <Form.Item label="项目标签" >
  117. {getFieldDecorator('tag')(
  118. <Select mode="tags" placeholder="输入后选中" style={fullWidth} />
  119. )}
  120. </Form.Item>
  121. <FormGroupItem>
  122. <Form.Item label="项目视频" help="视频仅支持mp4格式,建议尺寸:750*600,比例5:4,用于楼盘详情" {...gourpItemLayout.ab.a} >
  123. {getFieldDecorator('videoUrl')(
  124. <FileUpload accept=".mp4" beforeUpload={fileUploadBeforeUpload} label="上传视频" size={1} />,
  125. )}
  126. </Form.Item>
  127. <Form.Item label="视频封面图" help="建议图片尺寸:750*600px,比例5:4,格式:jpg,用于视频封面" labelCol={{span: 8}} wrapperCol={{span:16}}>
  128. {getFieldDecorator('videoImage')(
  129. <ImageUpload />,
  130. )}
  131. </Form.Item>
  132. </FormGroupItem>
  133. <Form.Item label="楼盘主图" help="建议图片尺寸:750*600px,比例5:4,格式:jpg,用于楼盘详情">
  134. {getFieldDecorator('avatarImage', {
  135. rules: [{ required: true, message: '请选择项目主图' }],
  136. })(
  137. <ImageListUpload unlimited />,
  138. )}
  139. </Form.Item>
  140. <Form.Item label="楼盘封面图" help="建议图片尺寸:750*420px,比例16:9,格式:jpg,用于楼盘列表">
  141. {getFieldDecorator('listImage', {
  142. rules: [{ required: true, message: '请选择列表图' }],
  143. })(
  144. <ImageUpload />,
  145. )}
  146. </Form.Item>
  147. <FormGroupItem>
  148. <Form.Item label="首页推荐" {...gourpItemLayout.ab.a} >
  149. {getFieldDecorator('isMain', { initialValue: 1 })(
  150. <Radio.Group>
  151. <Radio value={1}>是</Radio>
  152. <Radio value={2}>否</Radio>
  153. </Radio.Group>,
  154. )}
  155. </Form.Item>
  156. <Form.Item label="排序" help="数值越大,楼盘在小程序列表页中展示越靠前" {...gourpItemLayout.ab.b}>
  157. {getFieldDecorator('orderNo')(<InputNumber min={0} style={fullWidth} />)}
  158. </Form.Item>
  159. </FormGroupItem>
  160. <FormGroupItem>
  161. <Form.Item label="所在城市" {...gourpItemLayout.ab.a } >
  162. {getFieldDecorator('cityId', {
  163. rules: [{ required: true, message: '请选择城市' }],
  164. })(
  165. <SelectCity style={fullWidth} />,
  166. )}
  167. </Form.Item>
  168. <Form.Item label="楼盘区域" {...gourpItemLayout.ab.b } >
  169. {getFieldDecorator('buildingArea', {
  170. rules: [{ required: true, message: '请输入楼盘区域' }],
  171. })(<AreaSelect style={fullWidth} />)}
  172. </Form.Item>
  173. </FormGroupItem>
  174. <Form.Item label="项目地址" >
  175. {getFieldDecorator('address', {
  176. rules: [{ required: true, message: '请输入项目地址' }],
  177. })(<Input />)}
  178. </Form.Item>
  179. <Form.Item label="项目坐标" >
  180. {getFieldDecorator('coordinate', {
  181. rules: [{ required: true, message: '请输入项目坐标' }],
  182. })(<Amap onChange={e => setFieldsValue({ coordinate: e })} />)}
  183. </Form.Item>
  184. <Form.Item label="周边范围" >
  185. {getFieldDecorator('mapScope', {
  186. rules: [{ required: true, message: '请选择周边设施搜索范围' }],
  187. })(
  188. <Select placeholder="周边设施搜索范围" style={fullWidth} onChange={handleMapScopeChange}>
  189. <Select.Option value={1000}>1公里</Select.Option>
  190. <Select.Option value={3000}>3公里</Select.Option>
  191. <Select.Option value={5000}>5公里</Select.Option>
  192. <Select.Option value={10000}>10公里</Select.Option>
  193. </Select>,
  194. )}
  195. </Form.Item>
  196. <Form.Item label="周边交通" >
  197. {getFieldDecorator('buildingTransport')(
  198. <EditableArround pois={pois[POI_TYPES_KETY.Transport]} />,
  199. )}
  200. </Form.Item>
  201. <Form.Item label="周边商业" >
  202. {getFieldDecorator('buildingMall')(
  203. <EditableArround pois={pois[POI_TYPES_KETY.Mall]} />,
  204. )}
  205. </Form.Item>
  206. <Form.Item label="周边学校" >
  207. {getFieldDecorator('buildingEdu')(
  208. <EditableArround pois={pois[POI_TYPES_KETY.Edu]} />,
  209. )}
  210. </Form.Item>
  211. <Form.Item label="周边医院" >
  212. {getFieldDecorator('buildingHospital')(
  213. <EditableArround pois={pois[POI_TYPES_KETY.Hospital]} />,
  214. )}
  215. </Form.Item>
  216. <Form.Item label="周边银行" >
  217. {getFieldDecorator('buildingBank')(
  218. <EditableArround pois={pois[POI_TYPES_KETY.Bank]} />,
  219. )}
  220. </Form.Item>
  221. <Form.Item label="周边餐饮" >
  222. {getFieldDecorator('buildingRestaurant')(
  223. <EditableArround pois={pois[POI_TYPES_KETY.Restaurant]} />,
  224. )}
  225. </Form.Item>
  226. <FormGroupItem>
  227. <Form.Item label="绿化率" {...gourpItemLayout.ab.a } >
  228. {getFieldDecorator('greeningRate')(<Input />)}
  229. </Form.Item>
  230. <Form.Item label="容积率" {...gourpItemLayout.ab.b }>
  231. {getFieldDecorator('volumeRate')(<Input />)}
  232. </Form.Item>
  233. </FormGroupItem>
  234. <FormGroupItem>
  235. <Form.Item label="车位数量" {...gourpItemLayout.ab.a }>
  236. {getFieldDecorator('parkingRate', {
  237. rules: [{ validator: validMinNum }]
  238. })(<InputNumber min={0} style={fullWidth}/>)}
  239. </Form.Item>
  240. <Form.Item label="规划户数" {...gourpItemLayout.ab.b }>
  241. {getFieldDecorator('familyNum', {
  242. rules: [{ validator: validMinNum }]
  243. })(<InputNumber min={0} style={fullWidth}/>)}
  244. </Form.Item>
  245. </FormGroupItem>
  246. <FormGroupItem>
  247. <Form.Item label="供水" {...gourpItemLayout.abc.a }>
  248. {getFieldDecorator('waterSupply')(
  249. <Select style={fullWidth}>
  250. <Select.Option value="民水">民水</Select.Option>
  251. <Select.Option value="商用">商用</Select.Option>
  252. </Select>
  253. )}
  254. </Form.Item>
  255. <Form.Item label="供电" {...gourpItemLayout.abc.b }>
  256. {getFieldDecorator('powerSupply')(
  257. <Select style={fullWidth}>
  258. <Select.Option value="民电">民电</Select.Option>
  259. <Select.Option value="商用">商用</Select.Option>
  260. </Select>
  261. )}
  262. </Form.Item>
  263. <Form.Item label="供暖" {...gourpItemLayout.abc.c }>
  264. {getFieldDecorator('heatingSupply')(
  265. <Select style={fullWidth}>
  266. <Select.Option value="集中供暖">集中供暖</Select.Option>
  267. <Select.Option value="自采暖">自采暖</Select.Option>
  268. </Select>
  269. )}
  270. </Form.Item>
  271. </FormGroupItem>
  272. <Form.Item label="物业公司" >
  273. {getFieldDecorator('serviceCompany', {
  274. rules: [{ max: 30, message: '不超过30个字' }]
  275. })(<Input placeholder="不超过30个字"/>)}
  276. </Form.Item>
  277. <Form.Item label="物业费" >
  278. {getFieldDecorator('serviceFee', {
  279. rules: [{ max: 30, message: '不超过30个字' }]
  280. })(<Input placeholder="不超过30个字"/>)}
  281. </Form.Item>
  282. <FormGroupItem>
  283. <Form.Item label="装修标准" {...gourpItemLayout.ab.a }>
  284. {getFieldDecorator('decoration')(
  285. <Select style={fullWidth}>
  286. <Select.Option value="精装">精装</Select.Option>
  287. <Select.Option value="毛坯">毛坯</Select.Option>
  288. </Select>
  289. )}
  290. </Form.Item>
  291. <Form.Item label="楼栋总数" {...gourpItemLayout.ab.b }>
  292. {getFieldDecorator('buildingNum', {
  293. rules: [{ validator: validMinNum }]
  294. })(<InputNumber style={fullWidth}/>)}
  295. </Form.Item>
  296. </FormGroupItem>
  297. <FormGroupItem>
  298. <Form.Item label="交房时间" {...gourpItemLayout.ab.a }>
  299. {getFieldDecorator('receivedDate')(<DatePicker style={fullWidth}/>)}
  300. </Form.Item>
  301. <Form.Item label="产权年限" {...gourpItemLayout.ab.b }>
  302. {getFieldDecorator('rightsYear', {
  303. rules: [{ validator: validMinNum }]
  304. })(<InputNumber style={fullWidth}/>)}
  305. </Form.Item>
  306. </FormGroupItem>
  307. <Form.Item label="品牌开发商" help="【品牌开发商】与【开发商】二选一">
  308. {getFieldDecorator('brandId')(<Select style={fullWidth}></Select>)}
  309. </Form.Item>
  310. <Form.Item label="开发商" >
  311. {getFieldDecorator('propertyDeveloper', {
  312. rules: [{ max: 30, message: '不超过30个字' }]
  313. })(<Input placeholder="不超过30个字"/>)}
  314. </Form.Item>
  315. <Form.Item label="备案名" >
  316. {getFieldDecorator('recordName', {
  317. rules: [{ max: 30, message: '不超过30个字' }]
  318. })(<Input placeholder="不超过30个字" />)}
  319. </Form.Item>
  320. <Form.Item label="预售许可证" >
  321. {getFieldDecorator('preSalePermit')(
  322. <ImageUpload />,
  323. )}
  324. </Form.Item>
  325. <Form.Item label=" " colon={false}>
  326. <Button style={{marginLeft: '6em'}} type="primary" htmlType="submit">
  327. 确定
  328. </Button>
  329. <Button style={{marginLeft: '2em'}} onClick={() => router.go(-1)}>
  330. 取消
  331. </Button>
  332. </Form.Item>
  333. </Form>
  334. )
  335. })
  336. export default Form.create({ onValuesChange: console.log })(BuildingBasic)