index.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622
  1. /*
  2. *发布商品的布局(表单内容) 一行多列 左侧label 右侧内容
  3. * */
  4. import React, { PureComponent, Fragment } from 'react';
  5. import {
  6. Form, Select, Icon, Row, Col, Input, InputNumber, DatePicker, TreeSelect, Cascader, Checkbox, Radio, Upload, Button, Tooltip,
  7. } from 'antd';
  8. import global from '@/global.less';
  9. import styles from './index.less';
  10. import { sldInputAfterAddons, sldBeforeUpload, getSldComImg, sldComLanguage, getLocalStorageStingVal } from '@/utils/utils';
  11. const FormItem = Form.Item;
  12. const { RangePicker } = DatePicker;
  13. const InputGroup = Input.Group;
  14. const RadioGroup = Radio.Group;
  15. const CheckboxGroup = Checkbox.Group;
  16. const Option = Select.Option;
  17. const { TextArea } = Input;
  18. export default class SldTableRowTwo extends PureComponent {
  19. constructor(props) {
  20. super(props);
  21. this.state = {
  22. props_data: props,
  23. };
  24. }
  25. componentWillReceiveProps(props) {
  26. this.setState({
  27. props_data: props,
  28. });
  29. }
  30. //处理input内容变化事件
  31. handleInputOnchange = (e, item) => {
  32. if (item.handleChange) {
  33. item.handleChange(e);
  34. }
  35. };
  36. //处理复选框变化事件
  37. handleSingleCheckboxOnchange = (e, item) => {
  38. if (item.onChange) {
  39. item.onChange(e);
  40. }
  41. };
  42. //多选事件
  43. sldCheckShop = (items, value) => {
  44. if (items.sldCheckShop) {
  45. items.sldCheckShop(value);
  46. }
  47. };
  48. redioOnChange = (e, val) => {
  49. if (val.onChange) {
  50. val.onChange(e.target.value);
  51. }
  52. };
  53. //图品的点击预览
  54. sldShowImgPre = (val,item) => {
  55. if (val.preView) {
  56. val.preView(true, item);
  57. }
  58. };
  59. radio_select = (e, item) => {
  60. if (item.callback) {
  61. item.callback(e);
  62. }
  63. };
  64. commonCon = (val, index) => {
  65. let {
  66. form: { getFieldDecorator }, item_width,
  67. } = this.props;
  68. //普通输入框
  69. item_width = item_width != undefined ? item_width : 'auto';
  70. const uploadButton = (
  71. <div>
  72. <Icon type="plus"/>
  73. <div className="ant-upload-text">{sldComLanguage('上传图片')}</div>
  74. </div>
  75. );
  76. if (val.type == 'input') {
  77. return (<FormItem
  78. key={index}
  79. extra={val.extra}
  80. style={{ width: '80%' }}
  81. >
  82. {getFieldDecorator(val.name, { initialValue: val.initialValue, rules: val.rules })(
  83. <Input maxLength={val.maxLength!=undefined?val.maxLength:250} disabled={val.disable != undefined ? val.disable : false} className={styles.item}
  84. placeholder={val.placeholder}/>,
  85. )}
  86. </FormItem>
  87. );
  88. }else if (val.type == 'show_text') {
  89. //内容展示,目前用于商品详情页
  90. return (<FormItem
  91. key={index}
  92. extra={val.extra}
  93. style={{ width: '80%' }}
  94. >
  95. <div style={{color:this.props.r_color!=undefined?this.props.r_color:'#999',fontWeight: this.props.r_fontw!=undefined?this.props.r_fontw:'500',lineHeight:'16px'}}>
  96. {val.text.length>84
  97. ?<Tooltip placement="bottomRight" title={val.text}>
  98. <span className={styles.word_break}>{val.text.substring(0,83)}...</span>
  99. </Tooltip>
  100. :val.text
  101. }
  102. </div>
  103. </FormItem>
  104. );
  105. }else if (val.type == 'show_text1') {
  106. //内容展示,目前用于商品详情页
  107. return (<FormItem
  108. key={index}
  109. extra={val.extra}
  110. style={{ width: '80%' }}
  111. >
  112. <div style={{color:this.props.r_color!=undefined?this.props.r_color:'#999',fontWeight: this.props.r_fontw!=undefined?this.props.r_fontw:'500',lineHeight:'16px'}} title={val.text}>{val.text.length > 30 ? val.text.substring(0,30) + '...' : val.text}</div>
  113. </FormItem>
  114. );
  115. }else if (val.type == 'show_goods_img_more') {
  116. //展示商品图片(多图),目前用于商品详情页
  117. return (<FormItem
  118. key={index}
  119. extra={val.extra}
  120. style={{ width: '100%' }}
  121. >
  122. <div style={{flexDirection:'row',justifyContent:'flex-start',}}>
  123. {val.data.length > 0 && val.data.map((item,index)=>{
  124. return <div key={index} onClick={() => this.sldShowImgPre(val,item.imageUrl)} style={{flexDirection:'row',justifyContent:'center',alignItems:'center',overFlow:'hidden',width:100,height:100,display:'inline-flex',backgroundColor:'#F8F8F8',marginRight:10}}>
  125. <img style={{ maxWidth: '100%', maxHeight: '100%' }} src={item.imageUrl} />
  126. </div>;
  127. })}
  128. </div>
  129. </FormItem>
  130. );
  131. } else if (val.type == 'inputnum') {
  132. //数字搜索框
  133. return (
  134. <FormItem key={index}
  135. style={{ width: '80%' }}
  136. extra={val.extra}
  137. >
  138. {getFieldDecorator(val.name, { initialValue: val.initialValue, rules: val.rules })(<InputNumber
  139. min={val.min != undefined ? val.min : 0}
  140. max={val.max != undefined ? val.max : 999999999}
  141. step={val.step ? val.step : 0} className={styles.item} placeholder={val.placeholder}
  142. precision={val.precision != undefined ? val.precision : 0} disabled={val.disable}
  143. onChange={(e) => this.handleInputOnchange(e, val)}/>)}
  144. </FormItem>
  145. );
  146. } else if (val.type == 'select') {
  147. //下拉选择框
  148. return (<FormItem
  149. key={index}
  150. style={{ width: val.width != undefined ? val.width : ' 80%' }}
  151. extra={val.extra}
  152. >
  153. {getFieldDecorator(val.name, val.initialValue ? {
  154. initialValue: val.initialValue,
  155. rules: val.rules,
  156. } : {
  157. rules: val.rules,
  158. })(
  159. <Select placeholder={val.placeholder}
  160. className={styles.item}
  161. onChange={val.onChange}
  162. getPopupContainer={triggerNode => triggerNode.parentNode}
  163. >
  164. {val.sel_data.map((items, indexs) => {
  165. return <Option key={indexs}
  166. value={val.diy != undefined && val.diy ? items[val.sele_key] : items.key}>{val.diy != undefined && val.diy ? items[val.sele_name] : items.name}</Option>;
  167. })}
  168. </Select>,
  169. )}
  170. </FormItem>
  171. );
  172. } else if (val.type == 'multiple_select') {
  173. //下拉多选框
  174. return (<FormItem
  175. key={index}
  176. style={{ width: val.width != undefined ? val.width : ' 80%' }}
  177. extra={val.extra}
  178. >
  179. {getFieldDecorator(val.name, val.initialValue ? {
  180. initialValue: val.initialValue,
  181. rules: val.rules,
  182. } : {
  183. rules: val.rules,
  184. })(
  185. <Select mode="multiple"
  186. placeholder={val.placeholder}
  187. className={styles.item}
  188. onChange={val.onChange}
  189. getPopupContainer={triggerNode => triggerNode.parentNode}
  190. >
  191. {val.sel_data.map((items, indexs) => {
  192. return <Option key={indexs}
  193. value={val.diy != undefined && val.diy ? items[val.sele_key] : items.key}>{val.diy != undefined && val.diy ? items[val.sele_name] : items.name}</Option>;
  194. })}
  195. </Select>,
  196. )}
  197. </FormItem>
  198. );
  199. } else if (val.type == 'textarea') {
  200. return (<FormItem
  201. key={index}
  202. help={val.help}
  203. extra={val.extra}
  204. style={{ width: '100%' }}
  205. >
  206. {getFieldDecorator(val.name, { initialValue: val.initialValue, rules: val.rules })(
  207. <TextArea className={styles.item}
  208. maxLength={val.maxLength!=undefined?val.maxLength:250}
  209. disabled={val.is_disable != undefined && val.is_disable ? true : false}
  210. style={{ minHeight: 32 }} rows={2} placeholder={val.placeholder}/>,
  211. )}
  212. </FormItem>);
  213. } else if (val.type == 'rangepicker') {
  214. //时间范围选择器
  215. return (<FormItem
  216. key={index}
  217. style={{ width: '100%' }}
  218. extra={val.extra}
  219. >
  220. {getFieldDecorator(val.name)(
  221. <RangePicker
  222. showTime={val.show_time != undefined ? val.show_time : false}
  223. // className={styles.item}
  224. placeholder={[val.placeholder1, val.placeholder2]}
  225. getCalendarContainer={(triggerNode)=>{
  226. return triggerNode.parentNode
  227. }}
  228. />,
  229. )}
  230. </FormItem>
  231. );
  232. }else if (val.type == 'checkboxgroup') {
  233. //checkbox多选
  234. return (<FormItem
  235. key={index}
  236. style={{ width: '100%' }}
  237. extra={val.extra}
  238. >
  239. {getFieldDecorator(val.name, { initialValue: val.initialValue, rules: val.rules })(
  240. <CheckboxGroup options={val.sldOptions} onChange={(value) => this.sldCheckShop(val, value)}/>,
  241. )}
  242. </FormItem>
  243. );
  244. } else if (val.type == 'datepicker') {
  245. //时间选择器
  246. return (<FormItem key={index}
  247. extra={val.extra}
  248. style={{ width: '100%' }}
  249. >
  250. {val.initialValue && getFieldDecorator(val.name, {
  251. initialValue: val.initialValue,
  252. rules: val.rules,
  253. })(
  254. <DatePicker className={styles.item}
  255. placeholder={val.placeholder}
  256. showTime={val.show_time != undefined ? val.show_time : false}
  257. getCalendarContainer={(triggerNode)=>{
  258. return triggerNode.parentNode
  259. }}
  260. />,
  261. )}
  262. {!val.initialValue && getFieldDecorator(val.name, { rules: val.rules })(
  263. <DatePicker className={styles.item}
  264. placeholder={val.placeholder}
  265. showTime={val.show_time != undefined ? val.show_time : false}
  266. getCalendarContainer={(triggerNode)=>{
  267. return triggerNode.parentNode
  268. }}
  269. />,
  270. )}
  271. </FormItem>
  272. );
  273. } else if (val.type == 'rangeval') {
  274. //范围选择器
  275. return (<FormItem
  276. key={index}
  277. extra={val.extra}
  278. style={{ width: '100%' }}
  279. >
  280. <InputGroup compact className={styles.item}>
  281. {getFieldDecorator([val.name1])(<Input maxLength={250} style={{ width: '40%', textAlign: 'center' }}
  282. placeholder={val.placeholder1}/>)}
  283. <Input style={{ width: '20%', borderLeft: 0, pointerEvents: 'none', backgroundColor: '#fff' }}
  284. placeholder="~" disabled/>
  285. {getFieldDecorator([val.name2])(<Input
  286. maxLength={250}
  287. style={{ width: '40%', textAlign: 'center', borderLeft: 0 }}
  288. placeholder={val.placeholder2}/>)}
  289. </InputGroup>
  290. </FormItem>
  291. );
  292. } else if (val.type == 'input_after') {
  293. //带图标后缀
  294. return (<FormItem
  295. key={index}
  296. extra={val.extra}
  297. style={{ width: '100%' }}
  298. >
  299. <div onClick={() => val.callback(val.operate_obj)}>
  300. {getFieldDecorator(val.name, { initialValue: val.initialValue, rules: val.rules })(
  301. <Input style={{ width: 150, marginLeft: 3 }} disabled={true} addonAfter={sldInputAfterAddons()}
  302. placeholder={val.placeholder}/>,
  303. )}
  304. </div>
  305. </FormItem>);
  306. } else if (val.type == 'textarea_single') {
  307. return <FormItem
  308. key={index}
  309. extra={val.extra}
  310. style={{ width: '100%' }}
  311. >
  312. {getFieldDecorator(val.name, { initialValue: val.initialValue, rules: val.rules })(
  313. <TextArea className={styles.item} style={{ minHeight: 30 }} rows={1}/>,
  314. )}
  315. </FormItem>;
  316. } else if (val.type == 'TreeSelect') {
  317. return <FormItem key={index} extra={val.extra} style={{ width: ' 80%' }}>
  318. {getFieldDecorator(val.name, {
  319. initialValue: val.initialValue == '' ? undefined : val.initialValue,
  320. rules: val.rules,
  321. })(
  322. <TreeSelect
  323. className={styles.item}
  324. treeData={val.data}
  325. showSearch={true}
  326. placeholder={val.placeholder}
  327. allowClear={val.allowClear}
  328. onSelect={val.onSelect}
  329. dropdownStyle={{maxHeight:300}}
  330. getPopupContainer={triggerNode => triggerNode.parentNode}
  331. />,
  332. )}
  333. </FormItem>;
  334. } else if (val.type == 'cascader') {
  335. //店铺分类选择
  336. return (<FormItem
  337. key={index}
  338. extra={val.extra}
  339. style={{ width: '80%' }}
  340. >
  341. {getFieldDecorator(val.name, { initialValue: val.initialValue, rules: val.rules })(
  342. <Cascader
  343. disabled={val.disable != undefined && val.disable ? val.disable : false}
  344. fieldNames={{ label: 'title', value: 'key', children: 'children' }}
  345. className={styles.item} options={val.options}
  346. placeholder={val.placeholder}/>,
  347. )}
  348. </FormItem>
  349. );
  350. }else if (val.type == 'cascader_area') {
  351. //三级地址选择
  352. return (<FormItem
  353. key={index}
  354. extra={val.extra}
  355. style={{ width: '80%' }}
  356. >
  357. {getFieldDecorator(val.name, { initialValue: val.initialValue, rules: val.rules })(
  358. <Cascader
  359. disabled={val.disable != undefined ? val.disable : false}
  360. options={JSON.parse(localStorage.getItem('common_area_list'))}
  361. placeholder={val.placeholder}
  362. />,
  363. )}
  364. </FormItem>
  365. );
  366. } else if (val.type == 'single_checkbox') {
  367. //选择框
  368. return (<FormItem
  369. key={index}
  370. extra={val.extra}
  371. style={{ width: '100%' }}
  372. >
  373. {getFieldDecorator(val.name, {
  374. valuePropName: 'checked',
  375. initialValue: val.initialValue,
  376. rules: val.rules,
  377. })(
  378. <Checkbox
  379. disabled={val.disable != undefined && val.disable ? val.disable : false}
  380. className={styles.item}
  381. onChange={(e) => this.handleSingleCheckboxOnchange(e, val)}
  382. >
  383. {val.check_con}
  384. </Checkbox>,
  385. )}
  386. </FormItem>
  387. );
  388. } else if (val.type == 'radio') {
  389. //radio
  390. return (<FormItem
  391. key={index}
  392. extra={val.extra}
  393. style={{ width: '100%' }}
  394. >
  395. {getFieldDecorator(val.name, {
  396. valuePropName: 'checked',
  397. rules: val.rules,
  398. initialValue: val.initialValue,
  399. })(
  400. <RadioGroup size={'small'} defaultValue={val.initialValue} className={styles.item}
  401. onChange={(e) => this.redioOnChange(e, val)}>
  402. {val.sel_data.map((item, index) => {
  403. return <Radio key={index} value={item.key}>{item.name}</Radio>;
  404. })}
  405. </RadioGroup>,
  406. )}
  407. </FormItem>
  408. );
  409. } else if (val.type == 'radio_select') {
  410. return (<FormItem
  411. key={index}
  412. extra={val.extra}
  413. style={{ width: '100%' }}
  414. >
  415. {getFieldDecorator(val.name, { initialValue: val.initialValue, rules: val.rules })(
  416. <Radio.Group size={'small'} buttonStyle="solid" disabled={val.disable}
  417. onChange={(e) => this.radio_select(e, val)}>
  418. {val.data.map((cval, ckey) => {
  419. return <Radio.Button key={ckey} value={cval.key}>{cval.value}</Radio.Button>;
  420. })}
  421. </Radio.Group>,
  422. )}
  423. </FormItem>);
  424. } else if (val.type == 'checkboxgroup') {
  425. //radio
  426. return (<FormItem
  427. key={index}
  428. style={{ width: '100%' }}
  429. extra={val.extra}
  430. >
  431. {getFieldDecorator(val.name, { initialValue: val.initialValue, rules: val.rules })(
  432. <CheckboxGroup className={styles.item} options={val.sldOptions}
  433. onChange={(value) => this.sldCheckShop(val, value)}/>,
  434. )}
  435. </FormItem>
  436. );
  437. } else if (val.type == 'upload_img_upload') {
  438. return <FormItem
  439. key={index}
  440. style={{ width: '100%' }}
  441. extra={val.extra}
  442. >
  443. <Upload
  444. beforeUpload={sldBeforeUpload}
  445. withCredentials={true}
  446. accept={'.gif, .jpeg, .png,.jpg,'}
  447. name={val.upload_name}
  448. action={val.upload_url}
  449. listType="picture-card"
  450. fileList={val.fileList}
  451. onPreview={(info) => val.uploadPreview(info)}
  452. onChange={(info) => val.uploadChange(info,val.extra_param!=undefined?val.extra_param:{})}
  453. headers={{
  454. Authorization: 'Bearer ' + getLocalStorageStingVal('sld_token')
  455. }}
  456. >
  457. {val.fileList.length >= (val.num!=undefined?val.num:6) ? null : uploadButton}
  458. </Upload>
  459. </FormItem>;
  460. } else if (val.type == 'show_img_more') {
  461. return <FormItem
  462. key={index}
  463. style={{ width: '100%' }}
  464. extra={val.extra}
  465. >
  466. <div className={`${global.flex_row_start_center}`}>
  467. {val.data.map(item=>{
  468. return <div className={`${global.flex_row_center_center}`}>
  469. {getSldComImg(item,200,200,100,100)}
  470. </div>
  471. })}
  472. </div>
  473. </FormItem>;
  474. } else if (val.type == 'goods_spec_sele') {
  475. let con = <div className={styles.spec_wrap}>
  476. {
  477. val.sel_data.length > 0 && val.sel_data.map((vall, keyl) => {
  478. return <div key={keyl}
  479. className={`${styles.spec_r_wrap} ${keyl != val.sel_data.length - 1 ? styles.show_bot_border : null}`}>
  480. <span className={styles.spec_l}>{vall.name}</span>
  481. {vall.attrList.length > 0 &&
  482. <div className={styles.spec_item_wrap}>
  483. <Checkbox.Group disabled={val.disable != undefined && val.disable ? val.disable : false}
  484. style={{ width: '100%' }}>
  485. <Row>
  486. {vall.attrList.map((valr, keyr) => {
  487. return <Col key={keyr} span={4}><Checkbox
  488. value={valr.id}>{valr.name}</Checkbox>
  489. {vall.type == 2 &&
  490. <Upload
  491. beforeUpload={sldBeforeUpload}
  492. withCredentials={true}
  493. accept={'.gif, .jpeg, .png,.jpg,'}
  494. name={val.upload_name}
  495. action={val.upload_url}
  496. listType="picture-card"
  497. fileList={[]}
  498. onPreview={(info) => val.uploadPreview(info)}
  499. onChange={(info) => val.uploadChange(info)}
  500. headers={{
  501. Authorization: 'Bearer ' + getLocalStorageStingVal('sld_token')
  502. }}
  503. >
  504. {uploadButton}
  505. </Upload>
  506. }
  507. </Col>;
  508. })}
  509. </Row>
  510. </Checkbox.Group>
  511. </div>
  512. }
  513. </div>;
  514. })
  515. }
  516. </div>;
  517. return con;
  518. } else if (val.type == 'show_text_btn') {
  519. return <FormItem
  520. key={index}
  521. style={{ width: '100%' }}
  522. extra={val.extra}
  523. >
  524. <div>
  525. <span>{val.initialValue}</span>
  526. {val.btn != undefined &&
  527. <Button style={{ marginLeft: 10 }} key="submit" type="primary" loading={false}
  528. onClick={val.btn.callback}>
  529. {val.btn.text}
  530. </Button>
  531. }
  532. </div>
  533. </FormItem>;
  534. } else if (val.type == 'cascader_common') {
  535. //多级联动选择器-通用
  536. return (<FormItem
  537. key={index}
  538. style={{ width: '100%' }}
  539. extra={val.extra}
  540. >
  541. {getFieldDecorator(val.name, { initialValue: val.initialValue, rules: val.rules })(
  542. <Cascader options={val.data}
  543. fieldNames={val.fieldNames != undefined ? val.fieldNames : {
  544. label: 'label',
  545. value: 'value',
  546. children: 'children',
  547. }}
  548. onChange={(value, selectedOptions) => val.onChange(selectedOptions)}
  549. placeholder={val.placeholder}/>,
  550. )}
  551. </FormItem>
  552. );
  553. }
  554. };
  555. render() {
  556. const { data, lwidth, rwidth, totalHeght, part_width } = this.state.props_data;
  557. let {
  558. form: { getFieldDecorator },
  559. } = this.props;
  560. const total_width = document.body.clientWidth-208;
  561. const cur_height = totalHeght != undefined ? totalHeght : 70;
  562. return (
  563. <div className={styles.sld_table_row_two} style={{ height: totalHeght }}>
  564. <div className={styles.sld_det_lr_wrap}>
  565. {data != undefined && data.length > 0 && data.map((val, index) => {
  566. return <div className={styles.sld_det_lr_item_wrap} key={index} style={{
  567. width: `${(part_width != undefined ? part_width : 50)*0.01*total_width-2}px`,
  568. height: val.item_height!=undefined?val.item_height+1:cur_height + 1,
  569. }}>
  570. <span className={styles.sld_det_r_item} style={{
  571. flexDirection: 'row',
  572. alignItems: 'center',
  573. justifyContent: 'flex-end',
  574. width: `${lwidth != undefined ? lwidth : 20}%`,
  575. backgroundColor: '#FFFAF7',
  576. height: val.item_height!=undefined?val.item_height+2:cur_height + 2,
  577. }}>
  578. {val.required != undefined && val.required && <span style={{ color: 'red',fontSize:'40px' }}>*</span>}
  579. <span className={styles.sld_det_r_text} style={{ fontWeight: this.props.l_fontw!=undefined?this.props.l_fontw:'600',color:this.props.l_color!=undefined?this.props.l_color:'#333'}}>{val.label}</span>
  580. </span>
  581. <span className={styles.sld_det_r_item} style={{
  582. width: `${rwidth != undefined ? rwidth : 80}%`,
  583. alignItems: 'flex-start',
  584. paddingLeft: 20,
  585. height: val.item_height!=undefined?val.item_height+2:cur_height + 2,
  586. borderRightWidth: 1,
  587. }}>
  588. <span className={styles.sld_det_r_text} style={{ width: '100%' }}>
  589. {this.commonCon(val, index)}
  590. </span>
  591. </span>
  592. </div>;
  593. })}
  594. </div>
  595. </div>
  596. );
  597. }
  598. }