1
0

page.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. import React from 'react';
  2. import { Form, Button, Row, Col, Icon, Input, InputNumber, Upload } from 'antd';
  3. import './index.less';
  4. import Editor from '@src/components/Editor';
  5. import Page from '@src/containers/Page';
  6. import Block from '@src/components/Block';
  7. import Radio from '@src/components/Radio';
  8. import TreeSelect from '@src/components/TreeSelect';
  9. import EditTableCell from '@src/components/EditTableCell';
  10. import ActionLayout from '@src/layouts/ActionLayout';
  11. import TableLayout from '@src/layouts/TableLayout';
  12. import { formatFormError, formatTreeData, getMap, formatDate } from '@src/services/Tools';
  13. import { asyncSMessage } from '@src/services/AsyncTools';
  14. import { SwitchSelect, DataType } from '../../../../Constant';
  15. // import { User } from '../../../stores/user';
  16. import { Exercise } from '../../../stores/exercise';
  17. import { Course } from '../../../stores/course';
  18. import { System } from '../../../stores/system';
  19. export default class extends Page {
  20. initState() {
  21. return { history: false };
  22. }
  23. init() {
  24. this.exerciseMap = {};
  25. this.actionList = [{
  26. key: 'add',
  27. type: 'primary',
  28. name: '上传pdf文件',
  29. render: (item) => {
  30. return <Upload
  31. showUploadList={false}
  32. beforeUpload={(file) => System.uploadImage(file).then((result) => {
  33. return Course.addDataHistory({ resource: result.url });
  34. }).then(() => {
  35. this.refreshHistory();
  36. })}
  37. >
  38. <Button>{item.name}</Button>
  39. </Upload>;
  40. },
  41. }];
  42. this.columns = [{
  43. title: '上传时间',
  44. dataIndex: 'createTime',
  45. render: (text) => {
  46. return formatDate(text);
  47. },
  48. }, {
  49. title: '文件地址',
  50. dataIndex: 'resource',
  51. render: (text) => {
  52. return <a href={text} target='_blank'>下载</a>;
  53. },
  54. }, {
  55. title: '版本名称',
  56. dataIndex: 'version',
  57. render: (text, record) => {
  58. return <EditTableCell value={text} onChange={(v) => {
  59. this.changeHistory('version', record.id, v);
  60. }} />;
  61. },
  62. }, {
  63. title: '变更页数',
  64. dataIndex: 'changePage',
  65. render: (text, record) => {
  66. return <EditTableCell value={text} onChange={(v) => {
  67. this.changeHistory('changePage', record.id, v);
  68. }} />;
  69. },
  70. }, {
  71. title: '原文',
  72. dataIndex: 'originContent',
  73. render: (text, record) => {
  74. return <EditTableCell value={text} onChange={(v) => {
  75. this.changeHistory('originContent', record.id, v);
  76. }} />;
  77. },
  78. }, {
  79. title: '更正为',
  80. dataIndex: 'content',
  81. render: (text, record) => {
  82. return <EditTableCell value={text} onChange={(v) => {
  83. this.changeHistory('content', record.id, v);
  84. }} />;
  85. },
  86. }];
  87. Exercise.courseStruct().then((result) => {
  88. const list = result.map(row => { row.title = `${row.titleZh}`; row.value = row.id; return row; });
  89. const tree = formatTreeData(list, 'id', 'title', 'parentId');
  90. this.exerciseMap = getMap(result.map(row => {
  91. row.title = `${row.titleZh}`;
  92. row.value = row.id;
  93. return row;
  94. }), 'id');
  95. this.setState({ exercise: tree });
  96. });
  97. }
  98. initData() {
  99. const { id } = this.params;
  100. let handler;
  101. if (id) {
  102. handler = Course.getData({ id });
  103. } else {
  104. handler = Promise.resolve({ structId: 0 });
  105. }
  106. handler
  107. .then(result => {
  108. const { setFieldsValue } = this.props.form;
  109. result.structId = `${result.structId}`;
  110. // getFieldDecorator('id');
  111. // getFieldDecorator('structId');
  112. // getFieldDecorator('dataType');
  113. // getFieldDecorator('isNovice');
  114. // getFieldDecorator('isOriginal');
  115. // getFieldDecorator('title');
  116. // getFieldDecorator('price');
  117. // getFieldDecorator('pages');
  118. // getFieldDecorator('content');
  119. // getFieldDecorator('content');
  120. // getFieldDecorator('authorContent');
  121. // getFieldDecorator('methondContent');
  122. setFieldsValue(result);
  123. this.setState({ data: result });
  124. if (result.dataType === 'electron') {
  125. this.refreshHistory();
  126. }
  127. });
  128. }
  129. refreshHistory() {
  130. const { id } = this.params;
  131. Course.listDataHistory({ dataId: id }).then(result => {
  132. this.setState({ list: result.list, total: result.total, history: true });
  133. });
  134. }
  135. changeHistory(field, id, value) {
  136. Course.editDataHistory({ id, [field]: value }).then(() => {
  137. this.refreshHistory();
  138. });
  139. }
  140. submit() {
  141. const { form } = this.props;
  142. form.validateFields((err) => {
  143. if (!err) {
  144. const data = form.getFieldsValue();
  145. data.parentStructId = this.exerciseMap[data.structId] ? this.exerciseMap[data.structId].parentId : 0;
  146. Course.editData(data).then(() => {
  147. asyncSMessage('保存成功');
  148. }).catch((e) => {
  149. if (e.result) form.setFields(formatFormError(data, e.result));
  150. });
  151. }
  152. });
  153. }
  154. renderBase() {
  155. const { exercise, data } = this.state;
  156. const { getFieldDecorator } = this.props.form;
  157. return <Block>
  158. <h1>基本信息</h1>
  159. <Form>
  160. {getFieldDecorator('id')(<input hidden />)}
  161. {exercise && data.structId && <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='学科'>
  162. {getFieldDecorator('structId', {
  163. rules: [{
  164. required: true, message: '请选择学科',
  165. }],
  166. initialValue: data.structId,
  167. })(
  168. <TreeSelect treeData={exercise} />,
  169. )}
  170. </Form.Item>}
  171. <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='资料形式'>
  172. {getFieldDecorator('dataType', {
  173. rules: [{
  174. required: true, message: '请选择类型',
  175. }],
  176. })(
  177. <Radio select={DataType} onChange={(e) => {
  178. if (e.target.value === 'electron') {
  179. this.refreshHistory();
  180. } else {
  181. this.setState({ history: false });
  182. }
  183. }} />,
  184. )}
  185. </Form.Item>
  186. <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='适合新手'>
  187. {getFieldDecorator('isNovice', {
  188. rules: [{
  189. required: true, message: '请选择',
  190. }],
  191. })(
  192. <Radio select={SwitchSelect} />,
  193. )}
  194. </Form.Item>
  195. <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='原创资料'>
  196. {getFieldDecorator('isOriginal', {
  197. rules: [{
  198. required: true, message: '请选择',
  199. }],
  200. })(
  201. <Radio select={SwitchSelect} />,
  202. )}
  203. </Form.Item>
  204. <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='资料名称'>
  205. {getFieldDecorator('title', {
  206. rules: [{
  207. required: true, message: '请输入名称',
  208. }],
  209. })(
  210. <Input placeholder='请输入' />,
  211. )}
  212. </Form.Item>
  213. <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='价格'>
  214. {getFieldDecorator('price', {
  215. rules: [{
  216. required: true, message: '请输入价格',
  217. }],
  218. })(
  219. <InputNumber placeholder='请输入' />,
  220. )}
  221. </Form.Item>
  222. <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='页数'>
  223. {getFieldDecorator('pages', {
  224. rules: [{
  225. required: true, message: '请输入页数',
  226. }],
  227. })(
  228. <InputNumber placeholder='请输入' />,
  229. )}
  230. </Form.Item>
  231. <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='链接地址'>
  232. {getFieldDecorator('link', {
  233. rules: [{
  234. required: true, message: '请输入地址',
  235. }],
  236. })(
  237. <Input placeholder='请输入' />,
  238. )}
  239. </Form.Item>
  240. </Form>
  241. </Block>;
  242. }
  243. renderInfo() {
  244. const { getFieldDecorator, setFieldsValue, getFieldValue } = this.props.form;
  245. const cover = getFieldValue('cover');
  246. return <Block>
  247. <h1>宣传信息</h1>
  248. <Form>
  249. <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='资料封面'>
  250. {getFieldDecorator('cover', {
  251. rules: [
  252. { required: true, message: '上传图片' },
  253. ],
  254. })(
  255. <Upload
  256. listType="picture-card"
  257. showUploadList={false}
  258. beforeUpload={(file) => System.uploadImage(file).then((result) => {
  259. setFieldsValue({ cover: result.url });
  260. return Promise.reject();
  261. })}
  262. >
  263. {cover ? <img src={cover} alt="avatar" /> : <div>
  264. <Icon type={this.state.loading ? 'loading' : 'plus'} />
  265. <div className="ant-upload-text">Upload</div>
  266. </div>}
  267. </Upload>,
  268. )}
  269. </Form.Item>
  270. <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='摘要介绍'>
  271. {getFieldDecorator('description', {
  272. rules: [{
  273. required: true, message: '请输入摘要',
  274. }],
  275. })(
  276. <Input placeholder='请输入' />,
  277. )}
  278. </Form.Item>
  279. </Form>
  280. </Block>;
  281. }
  282. renderHistory() {
  283. return <Block>
  284. <h1>资料版本</h1>
  285. <ActionLayout
  286. itemList={this.actionList}
  287. selectedKeys={this.state.selectedKeys}
  288. onAction={key => this.onAction(key)}
  289. />
  290. <TableLayout
  291. columns={this.columns}
  292. list={this.state.list}
  293. pagination={false}
  294. loading={this.props.core.loading}
  295. onChange={(pagination, filters, sorter) => this.tableChange(pagination, filters, sorter)}
  296. onSelect={(keys, rows) => this.tableSelect(keys, rows)}
  297. selectedKeys={this.state.selectedKeys}
  298. />
  299. </Block>;
  300. }
  301. renderContent() {
  302. const { getFieldDecorator } = this.props.form;
  303. return <Block flex>
  304. <Form>
  305. <Form.Item label='资料介绍'>
  306. {getFieldDecorator('content', {
  307. })(
  308. <Editor placeholder='输入内容' />,
  309. )}
  310. </Form.Item>
  311. </Form>
  312. </Block>;
  313. }
  314. renderAuthor() {
  315. const { getFieldDecorator } = this.props.form;
  316. return <Block flex>
  317. <Form>
  318. <Form.Item label='作者介绍'>
  319. {getFieldDecorator('authorContent', {
  320. })(
  321. <Editor placeholder='输入内容' />,
  322. )}
  323. </Form.Item>
  324. </Form>
  325. </Block>;
  326. }
  327. renderMethod() {
  328. const { getFieldDecorator } = this.props.form;
  329. return <Block flex>
  330. <Form>
  331. <Form.Item label='获取方式'>
  332. {getFieldDecorator('methodContent', {
  333. })(
  334. <Editor placeholder='输入内容' />,
  335. )}
  336. </Form.Item>
  337. </Form>
  338. </Block>;
  339. }
  340. renderView() {
  341. const { history } = this.state;
  342. return <div flex>
  343. {this.renderBase()}
  344. {this.renderInfo()}
  345. {history && this.renderHistory()}
  346. {this.renderContent()}
  347. {this.renderAuthor()}
  348. {this.renderMethod()}
  349. <Row type="flex" justify="center">
  350. <Col>
  351. <Button type="primary" onClick={() => {
  352. this.submit();
  353. }}>保存</Button>
  354. </Col>
  355. </Row>
  356. </div>;
  357. }
  358. }