TableForm.js 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. import React, { PureComponent, Fragment } from 'react';
  2. import {
  3. Table,
  4. Button,
  5. Select,
  6. InputNumber,
  7. Popconfirm,
  8. Divider,
  9. Modal,
  10. message,
  11. } from 'antd';
  12. import Selector from '../../components/AXTableSelector/Selector';
  13. import { chargeUnitMap, durationMap, genAbsolutePicUrl, sortMap } from '../../utils/utils';
  14. import shopqr from '../../assets/shopqr.png';
  15. import styles from './TableForm.less';
  16. export default class TableForm extends PureComponent {
  17. constructor(props) {
  18. super(props);
  19. this.state = {
  20. data: null,
  21. loading: props.loading,
  22. currentKey: null,
  23. };
  24. }
  25. componentWillReceiveProps(nextProps) {
  26. if ('value' in nextProps && !this.state.data) {
  27. this.setState({
  28. data: nextProps.value,
  29. });
  30. }
  31. }
  32. getRowByKey(key, newData) {
  33. return (newData || this.state.data).filter(item => item.key === key)[0];
  34. }
  35. index = 0;
  36. cacheOriginData = {};
  37. toggleEditable=(e, key) => {
  38. e.preventDefault();
  39. const newData = this.state.data.map(item => ({ ...item }));
  40. const target = this.getRowByKey(key, newData);
  41. if (target) {
  42. // 进入编辑状态时保存原始数据
  43. if (!target.editable) {
  44. this.cacheOriginData[key] = { ...target };
  45. }
  46. target.editable = !target.editable;
  47. this.setState({ data: newData });
  48. }
  49. };
  50. chargeUnitSelectable=(value) => {
  51. const tmp = this.state.data.find(item => item.chargeUnit === value);
  52. return tmp !== undefined;
  53. };
  54. remove(record) {
  55. const { key, isNew } = record;
  56. const newData = this.state.data.filter(item => item.key !== key);
  57. this.setState({ data: newData });
  58. if (!isNew) {
  59. this.props.onDelete({ goodsId: key });
  60. }
  61. }
  62. newPrice = () => {
  63. const newData = this.state.data ? this.state.data.map(item => ({ ...item })) : [];
  64. newData.push({
  65. key: `NEW_TEMP_ID_${this.index}`,
  66. cpPrice: '',
  67. merchantPrice: '',
  68. terminalPrice: '',
  69. editable: true,
  70. isNew: true,
  71. });
  72. this.index += 1;
  73. this.setState({ data: newData });
  74. };
  75. handleFieldChange(value, fieldName, key) {
  76. const newData = this.state.data.map(item => ({ ...item }));
  77. const target = this.getRowByKey(key, newData);
  78. if (target) {
  79. target[fieldName] = value;
  80. this.setState({ data: newData });
  81. }
  82. }
  83. handleSelectChange(value, key) {
  84. const newData = this.state.data.map(item => ({ ...item }));
  85. const target = this.getRowByKey(key, newData);
  86. if (target) {
  87. target.chargeUnit = value;
  88. target.duration = durationMap[value];
  89. this.setState({ data: newData });
  90. }
  91. }
  92. handleQRSelectShow(key) {
  93. this.setState({
  94. currentKey: key,
  95. }, () => this.props.onQRShow());
  96. }
  97. handleQRSelectFinish(rows) {
  98. const newData = this.state.data.map(item => ({ ...item }));
  99. const target = this.getRowByKey(this.state.currentKey, newData);
  100. if (target) {
  101. target.shopQR = rows[0].path;
  102. this.setState({ data: newData });
  103. }
  104. this.props.onQRHide();
  105. }
  106. saveRow(e, key) {
  107. e.persist();
  108. if (this.clickedCancel) {
  109. this.clickedCancel = false;
  110. return;
  111. }
  112. const target = this.getRowByKey(key) || {};
  113. if (!target.chargeUnit || (typeof target.cpPrice !== 'number')
  114. || (typeof target.merchantPrice !== 'number') || (typeof target.terminalPrice !== 'number')) {
  115. message.error('请填写完整价格信息');
  116. e.target.focus();
  117. return;
  118. }
  119. const { id, chargeUnit, cpPrice, merchantPrice, terminalPrice, duration, shopQR } = target;
  120. const sort = sortMap[chargeUnit];
  121. if (target.isNew) {
  122. this.props.onCreate({
  123. sort,
  124. cpPrice,
  125. shopQR,
  126. duration,
  127. chargeUnit,
  128. merchantPrice,
  129. terminalPrice,
  130. });
  131. } else {
  132. this.props.onUpdate({
  133. id,
  134. sort,
  135. shopQR,
  136. cpPrice,
  137. duration,
  138. chargeUnit,
  139. merchantPrice,
  140. terminalPrice,
  141. });
  142. }
  143. delete target.isNew;
  144. this.toggleEditable(e, key);
  145. }
  146. cancel(e, key) {
  147. this.clickedCancel = true;
  148. e.preventDefault();
  149. const newData = this.state.data.map(item => ({ ...item }));
  150. const target = this.getRowByKey(key, newData);
  151. if (this.cacheOriginData[key]) {
  152. Object.assign(target, this.cacheOriginData[key]);
  153. target.editable = false;
  154. delete this.cacheOriginData[key];
  155. }
  156. this.setState({ data: newData });
  157. this.clickedCancel = false;
  158. }
  159. render() {
  160. const columns = [{
  161. title: '计价单位',
  162. dataIndex: 'chargeUnit',
  163. key: 'chargeUnit',
  164. width: '15%',
  165. align: 'center',
  166. render: (text, record) => {
  167. if (record.editable) {
  168. return (
  169. <Select
  170. placeholder="请选择"
  171. style={{ width: '100%' }}
  172. value={text}
  173. onChange={value => this.handleSelectChange(value, record.key)}
  174. className={styles.select}
  175. >
  176. {
  177. Object.keys(chargeUnitMap).map(key => (
  178. <Select.Option
  179. key={key}
  180. value={key}
  181. disabled={this.chargeUnitSelectable(key)}
  182. >
  183. {chargeUnitMap[key]}
  184. </Select.Option>
  185. ))
  186. }
  187. </Select>
  188. );
  189. }
  190. return text;
  191. },
  192. }, {
  193. title: '时长(天)',
  194. dataIndex: 'duration',
  195. key: 'duration',
  196. width: '10%',
  197. align: 'center',
  198. }, {
  199. title: '二维码',
  200. dataIndex: 'shopQR',
  201. key: 'shopQR',
  202. width: '15%',
  203. align: 'center',
  204. render: (text, record) => {
  205. const { editable, key } = record;
  206. return (
  207. <div className={styles.qrWrapper}>
  208. {
  209. editable && (
  210. <div className={styles.qrBtn}>
  211. <a onClick={() => this.handleQRSelectShow(key)}>{!text ? '选择' : '更换'}</a>
  212. </div>
  213. )
  214. }
  215. <img src={!text ? shopqr : genAbsolutePicUrl(text)} alt="二维码" />
  216. </div>
  217. );
  218. },
  219. }, {
  220. title: '平台方售价(¥)',
  221. dataIndex: 'merchantPrice',
  222. key: 'merchantPrice',
  223. width: '20%',
  224. align: 'center',
  225. render: (text, record) => {
  226. if (record.editable) {
  227. return (
  228. <InputNumber
  229. min={1}
  230. value={text}
  231. onChange={value => this.handleFieldChange(value, 'merchantPrice', record.key)}
  232. style={{ width: '100%' }}
  233. placeholder="请输入"
  234. />
  235. );
  236. }
  237. return text;
  238. },
  239. }, {
  240. title: '终端显示价格(¥)',
  241. dataIndex: 'terminalPrice',
  242. key: 'terminalPrice',
  243. width: '20%',
  244. align: 'center',
  245. render: (text, record) => {
  246. if (record.editable) {
  247. return (
  248. <InputNumber
  249. min={1}
  250. value={text}
  251. onChange={value => this.handleFieldChange(value, 'terminalPrice', record.key)}
  252. style={{ width: '100%' }}
  253. placeholder="请输入"
  254. />
  255. );
  256. }
  257. return text;
  258. },
  259. }];
  260. /* 二维码选择模态框 */
  261. const getResourceModal = () => {
  262. return (
  263. <Modal
  264. width={1100}
  265. footer={null}
  266. visible
  267. title="图片资源"
  268. maskClosable={false}
  269. onCancel={this.props.onQRHide}
  270. >
  271. <Selector
  272. multiple={false}
  273. loading={this.props.qrLoading}
  274. selectorName="PictureSingle"
  275. list={this.props.qrData.list}
  276. pageNo={this.props.qrData.pageNo}
  277. pageSize={this.props.qrData.pageSize}
  278. totalSize={this.props.qrData.totalSize}
  279. onCancel={this.props.onQRHide}
  280. onChange={this.props.onQRChange}
  281. onFinish={rows => this.handleQRSelectFinish(rows)}
  282. />
  283. </Modal>
  284. );
  285. };
  286. return (
  287. <Fragment>
  288. <Table
  289. bordered
  290. pagination={false}
  291. columns={columns}
  292. loading={this.state.loading}
  293. dataSource={this.state.data}
  294. rowClassName={() => {
  295. return styles.editable;
  296. }}
  297. />
  298. {!this.props.qrDestroy && getResourceModal()}
  299. </Fragment>
  300. );
  301. }
  302. }