page.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. import React from 'react';
  2. import { Form, Input, Button, Row, Col, DatePicker, List, Icon, Typography, Avatar } from 'antd';
  3. import './index.less';
  4. import Page from '@src/containers/Page';
  5. import Block from '@src/components/Block';
  6. import Select from '@src/components/Select';
  7. import DragList from '@src/components/DragList';
  8. // import FileUpload from '@src/components/FileUpload';
  9. import { formatFormError, generateSearch, getMap } from '@src/services/Tools';
  10. import { asyncSMessage } from '@src/services/AsyncTools';
  11. import { Preview } from '../../../stores/preview';
  12. import { User } from '../../../stores/user';
  13. import { Question } from '../../../stores/question';
  14. import { Exercise } from '../../../stores/exercise';
  15. import config from './index';
  16. export default class extends Page {
  17. constructor(props) {
  18. super(props);
  19. const { id } = this.params;
  20. if (id) {
  21. config.title = '编辑预习作业';
  22. } else {
  23. config.title = '添加预习作业';
  24. }
  25. }
  26. init() {
  27. Exercise.allStruct().then(result => {
  28. result = result.filter(row => row.level === 2).map(row => { row.title = `${row.titleZh}/${row.titleEn}`; row.value = row.id; return row; });
  29. this.setState({ exercise: result });
  30. });
  31. }
  32. initData() {
  33. const { id } = this.params;
  34. const { form } = this.props;
  35. let handler;
  36. if (id) {
  37. handler = Preview.get({ id });
  38. } else {
  39. handler = Promise.resolve({ questionNos: [] });
  40. }
  41. handler
  42. .then(result => {
  43. const { questionNos } = result;
  44. result.questionNos = result.questionNos.map(row => row.no);
  45. form.setFieldsValue(result);
  46. generateSearch('userIds', { mode: 'multiple' }, this, (search) => {
  47. return User.list(search);
  48. }, (row) => {
  49. return {
  50. title: `${row.nickname}(${row.mobile})`,
  51. value: row.id,
  52. };
  53. }, result.userIds || [], null);
  54. this.setState({ questionNos });
  55. });
  56. }
  57. deleteQuestion(index) {
  58. const { questionNos } = this.state;
  59. questionNos.splice(index, 1);
  60. this.setState({ questionNos });
  61. this.props.form.setFieldsValue({ questionNos: questionNos.map(row => row.no) });
  62. }
  63. orderQuestion(oldIndex, newIndex) {
  64. const { questionNos } = this.state;
  65. const tmp = questionNos[oldIndex];
  66. questionNos[oldIndex] = questionNos[newIndex];
  67. questionNos[newIndex] = tmp;
  68. this.setState({ questionNos });
  69. this.props.form.setFieldsValue({ questionNos: questionNos.map(row => row.no) });
  70. }
  71. submit() {
  72. const { form } = this.props;
  73. form.validateFields((err) => {
  74. if (!err) {
  75. const data = form.getFieldsValue();
  76. let handler;
  77. data.questionNoIds = this.state.questionNos.map(row => row.id);
  78. if (data.id) {
  79. handler = Preview.add(data);
  80. } else {
  81. handler = Preview.edit(data);
  82. }
  83. handler.then(() => {
  84. asyncSMessage('保存成功');
  85. }).catch((e) => {
  86. if (e.result) form.setFields(formatFormError(data, e.result));
  87. });
  88. }
  89. });
  90. }
  91. searchQuestion(values) {
  92. if (values.length === 0) {
  93. this.setState({ questionNos: [] });
  94. return;
  95. }
  96. // 查找练习题目
  97. Question.listNo({ no: values, module: 'exercise' }).then(result => {
  98. const map = getMap(result, 'no');
  99. const questionNos = values.map(no => map[no]).filter(row => row);
  100. this.setState({ questionNos });
  101. this.props.form.setFieldsValue({ questionNos: questionNos.map(row => row.no) });
  102. });
  103. }
  104. renderBase() {
  105. const { getFieldDecorator } = this.props.form;
  106. return <Block>
  107. <Form>
  108. {getFieldDecorator('id')(<input hidden />)}
  109. <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='选择课程'>
  110. {getFieldDecorator('category', {
  111. rules: [
  112. { required: true, message: '请选择课程' },
  113. ],
  114. })(
  115. <Select select={this.state.exercise} placeholder='请选择课程' />,
  116. )}
  117. </Form.Item>
  118. <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='起止时间'>
  119. {getFieldDecorator('time', {
  120. rules: [
  121. { required: true, message: '请输入起止时间' },
  122. ],
  123. })(
  124. <DatePicker.RangePicker />,
  125. )}
  126. </Form.Item>
  127. <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='作业标题'>
  128. {getFieldDecorator('title', {
  129. rules: [
  130. { required: true, message: '请输入作业标题' },
  131. ],
  132. })(
  133. <Input placeholder='请输入作业标题' />,
  134. )}
  135. </Form.Item>
  136. <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='指定做题人'>
  137. {getFieldDecorator('userIds', {
  138. rules: [
  139. { required: true, message: '请指定做题人' },
  140. ],
  141. })(
  142. <Select {...this.state.userIds} placeholder='请指定做题人' />,
  143. )}
  144. </Form.Item>
  145. <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='选择作业题'>
  146. {getFieldDecorator('questionNos', {
  147. rules: [
  148. { required: true, message: '请选择作业题' },
  149. ],
  150. })(
  151. <Select mode='tags' maxTagCount={200} notFoundContent={null} placeholder='输入题目id, 逗号分隔' tokenSeparators={[',', ',']} onChange={(values) => {
  152. this.searchQuestion(values);
  153. }} />,
  154. )}
  155. </Form.Item>
  156. </Form>
  157. </Block>;
  158. }
  159. renderQuestionList() {
  160. return <Block>
  161. <h1>题目预览</h1>
  162. <DragList
  163. loading={this.props.core.loading}
  164. dataSource={this.state.questionNos || []}
  165. handle={'.icon'}
  166. onMove={(oldIndex, newIndex) => {
  167. this.orderQuestion(oldIndex, newIndex);
  168. }}
  169. renderItem={(item, index) => (
  170. <List.Item actions={[<Icon type='delete' onClick={() => {
  171. this.deleteQuestion(index);
  172. }} />, <Icon type='bars' className='icon' />]}>
  173. <List.Item.Meta
  174. avatar={<Avatar alt={index + 1} size='small' >{index + 1}</Avatar>}
  175. title={item.no}
  176. description={<Typography.Text ellipsis disabled>{item.stem}</Typography.Text>}
  177. />
  178. </List.Item>
  179. )}
  180. /></Block>;
  181. }
  182. renderView() {
  183. return <div flex>
  184. {this.renderBase()}
  185. {this.renderQuestionList()}
  186. <Row type="flex" justify="center">
  187. <Col>
  188. <Button type="primary" onClick={() => {
  189. this.submit();
  190. }}>保存</Button>
  191. </Col>
  192. </Row>
  193. </div>;
  194. }
  195. }