page.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717
  1. import React from 'react';
  2. import { Link } from 'react-router-dom';
  3. import moment from 'moment';
  4. import { Form, Input, Button, Row, Col, InputNumber, Upload, DatePicker, Card, Icon } from 'antd';
  5. import './index.less';
  6. import Editor from '@src/components/Editor';
  7. import Page from '@src/containers/Page';
  8. import Block from '@src/components/Block';
  9. import TreeSelect from '@src/components/TreeSelect';
  10. import EditTableCell from '@src/components/EditTableCell';
  11. import Radio from '@src/components/Radio';
  12. import ActionLayout from '@src/layouts/ActionLayout';
  13. import TableLayout from '@src/layouts/TableLayout';
  14. // import FileUpload from '@src/components/FileUpload';
  15. import { formatFormError, formatSeconds, formatTreeData, getMap } from '@src/services/Tools';
  16. import { asyncSMessage } from '@src/services/AsyncTools';
  17. import { CrowdList, CourseStatus } from '../../../../Constant';
  18. import { Course } from '../../../stores/course';
  19. import { System } from '../../../stores/system';
  20. import { Exercise } from '../../../stores/exercise';
  21. const CourseStatusMap = getMap(CourseStatus, 'value', 'label');
  22. export default class extends Page {
  23. init() {
  24. this.exerciseMap = {};
  25. this.actionList = [{
  26. key: 'add',
  27. type: 'primary',
  28. name: '上传视频',
  29. render: (item) => {
  30. return <Upload
  31. showUploadList={false}
  32. beforeUpload={(file) => System.uploadVideo(file).then((result) => {
  33. return Course.addNo({ courseId: this.params.id, resource: result.url, time: result.time });
  34. }).then(() => {
  35. this.refreshNo();
  36. })}
  37. >
  38. <Button>{item.name}</Button>
  39. </Upload>;
  40. },
  41. }];
  42. this.noColumns = [{
  43. title: '课程序号',
  44. dataIndex: 'no',
  45. }, {
  46. title: '名称',
  47. dataIndex: 'title',
  48. render: (text, record) => {
  49. return <EditTableCell value={text} onChange={(v) => {
  50. this.changeNo('title', record.id, v);
  51. }} />;
  52. },
  53. }, {
  54. title: '时长',
  55. dataIndex: 'time',
  56. render: (text) => {
  57. return formatSeconds(text);
  58. },
  59. }, {
  60. title: '视频地址',
  61. dataIndex: 'resource',
  62. render: (text) => {
  63. return <a href={text} target='_blank'>访问</a>;
  64. },
  65. }, {
  66. title: '试用区间',
  67. dataIndex: 'originContent',
  68. render: (text, record) => {
  69. return <EditTableCell value={text} onChange={(v) => {
  70. this.changeNo('originContent', record.id, v);
  71. }} />;
  72. },
  73. }, {
  74. title: '操作',
  75. dataIndex: 'handler',
  76. render: (text, record) => {
  77. const { total } = this.state;
  78. return <div className="table-button">
  79. {record.no > 1 && (
  80. <a onClick={() => {
  81. this.changeNo('no', record.id, record.no - 1);
  82. }}>上移</a>
  83. )}
  84. {record.no <= total && (
  85. <a onClick={() => {
  86. this.changeNo('no', record.id, record.no + 1);
  87. }}>下移</a>
  88. )}
  89. {(
  90. <a onClick={() => {
  91. this.delNo(record.id);
  92. }}>删除</a>
  93. )}
  94. </div>;
  95. },
  96. }];
  97. this.timeColumns = [{
  98. title: '时间段',
  99. dataIndex: 'time',
  100. render: (text, record) => {
  101. return <DatePicker.RangePicker value={[record.startTime, record.endTime]} onChange={(value) => {
  102. this.changeTime(record.id, { startTime: value[0], endTime: value[1] });
  103. }} />;
  104. },
  105. }, {
  106. title: '学员数量',
  107. dataIndex: 'studentNumber',
  108. render: (text, record) => {
  109. return <Link to={`/course/student/${this.params.id}?timeId=${record.id}`}>{text}</Link>;
  110. },
  111. }, {
  112. title: '状态',
  113. dataIndex: 'status',
  114. render: (text) => {
  115. return CourseStatusMap[text] || text;
  116. },
  117. }];
  118. Exercise.courseStruct().then((result) => {
  119. const list = result.map(row => { row.title = `${row.titleZh}/${row.titleEn}`; row.value = row.id; return row; });
  120. const tree = formatTreeData(list, 'id', 'title', 'parentId');
  121. this.exerciseMap = getMap(result.map(row => {
  122. row.title = `${row.titleZh}/${row.titleEn}`;
  123. row.value = row.id;
  124. return row;
  125. }), 'id');
  126. this.setState({ exercise: tree });
  127. });
  128. }
  129. initData() {
  130. const { id } = this.params;
  131. const { module } = this.state.search;
  132. let handler;
  133. if (id) {
  134. handler = Course.get({ id });
  135. } else {
  136. handler = Promise.resolve({ structId: 0, courseModule: module });
  137. }
  138. handler
  139. .then(result => {
  140. this.setState({ module: result.courseModule });
  141. const { form } = this.props;
  142. result.structId = `${result.structId}`;
  143. // baseContent: null
  144. // courseContent: null
  145. // courseNoContent: null
  146. // crowdContent: null
  147. // messageContent: null
  148. // pointContent: null
  149. // processContent: null
  150. // promoteContent: null
  151. // serviceContent: null
  152. // syllabusContent: null
  153. // teacherContent: null
  154. // form.getFieldDecorator('id');
  155. // form.getFieldDecorator('structId');
  156. // form.getFieldDecorator('parentStructId');
  157. // form.getFieldDecorator('courseModule');
  158. // form.getFieldDecorator('title');
  159. // form.getFieldDecorator('price');
  160. // form.getFieldDecorator('crowd');
  161. // form.getFieldDecorator('teacher');
  162. // form.getFieldDecorator('wechatAvatar');
  163. // form.getFieldDecorator('minNumber');
  164. // form.getFieldDecorator('maxNumber');
  165. form.setFieldsValue(result);
  166. if (id) {
  167. switch (result.courseModule) {
  168. case 'video':
  169. this.refreshNo();
  170. break;
  171. case 'online':
  172. this.refreshTime();
  173. break;
  174. case 'vs':
  175. this.refreshTeacher();
  176. break;
  177. default:
  178. }
  179. }
  180. this.setState({ data: result });
  181. });
  182. }
  183. refreshNo() {
  184. const { id } = this.params;
  185. Course.allNo({ courseId: id }).then(result => {
  186. this.setState({ list: result, total: result.length, no: true });
  187. });
  188. }
  189. changeNo(field, id, value) {
  190. Course.editNo({ id, [field]: value }).then(() => {
  191. this.refreshNo();
  192. });
  193. }
  194. delNo(id) {
  195. Course.delNo({ id }).then(() => {
  196. this.refreshNo();
  197. });
  198. }
  199. refreshTime() {
  200. const { id } = this.params;
  201. Course.listTime({ courseId: id }).then(result => {
  202. result.list = result.list.map(row => {
  203. row.startTime = moment(row.startTime);
  204. row.endTime = moment(row.endTime);
  205. return row;
  206. });
  207. this.setState({ list: result.list, total: result.total, time: true });
  208. });
  209. }
  210. changeTime(id, data) {
  211. data.id = id;
  212. Course.editTime(data).then(() => {
  213. this.refreshTime();
  214. });
  215. }
  216. refreshTeacher() {
  217. const { id } = this.params;
  218. Course.listTeacher({ courseId: id }).then(result => {
  219. this.setState({ teachers: result.list, total: result.total, teacher: true });
  220. });
  221. }
  222. changeTeacher(field, index, value) {
  223. const { teachers } = this.state;
  224. teachers[index] = teachers[index] || {};
  225. teachers[index][field] = value;
  226. this.setState({ teachers });
  227. }
  228. addLength(key, data) {
  229. this.state[key] = this.state[key] || [];
  230. this.state[key].push(data);
  231. this.setState({ [key]: this.state[key] });
  232. }
  233. deleteLength(key, start) {
  234. this.state[key] = this.state[key] || [];
  235. this.state[key].splice(start, 1);
  236. this.setState({ [key]: this.state[key] });
  237. }
  238. submit() {
  239. const { form } = this.props;
  240. const { module } = this.state;
  241. form.validateFields((err) => {
  242. if (!err) {
  243. const data = form.getFieldsValue();
  244. data.parentStructId = this.exerciseMap[data.structId] ? this.exerciseMap[data.structId].parentId : 0;
  245. data.extend = this.exerciseMap[data.structId] ? this.exerciseMap[data.structId].extend : '';
  246. let handler;
  247. if (data.id) {
  248. handler = Course.edit(data);
  249. } else {
  250. data.courseModule = module;
  251. handler = Course.add(data);
  252. }
  253. handler.then((result) => {
  254. asyncSMessage('保存成功');
  255. if (data.id) {
  256. linkTo(`/course/detail/${data.id}`);
  257. } else {
  258. linkTo(`/course/detail/${result.id}`);
  259. }
  260. }).catch((e) => {
  261. if (e.result) form.setFields(formatFormError(data, e.result));
  262. });
  263. }
  264. });
  265. }
  266. renderVideo() {
  267. const { exercise, data } = this.state;
  268. const { getFieldDecorator } = this.props.form;
  269. return <Block>
  270. <Form>
  271. {getFieldDecorator('id')(<input hidden />)}
  272. {exercise && data.structId && <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='学科'>
  273. {getFieldDecorator('structId', {
  274. rules: [{
  275. required: true, message: '请选择学科',
  276. }],
  277. initialValue: data.structId,
  278. })(
  279. <TreeSelect treeData={exercise} />,
  280. )}
  281. </Form.Item>}
  282. <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='适合人群'>
  283. {getFieldDecorator('crowd', {
  284. rules: [
  285. { required: true, message: '请选择' },
  286. ],
  287. })(
  288. <Radio select={CrowdList} />,
  289. )}
  290. </Form.Item>
  291. <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='定价'>
  292. {getFieldDecorator('price', {
  293. rules: [
  294. { required: true, message: '请输入价格' },
  295. ],
  296. })(
  297. <InputNumber placeholder='请输入' />,
  298. )}
  299. </Form.Item>
  300. <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='课程名称'>
  301. {getFieldDecorator('title', {
  302. rules: [
  303. { required: true, message: '请输入课程名称' },
  304. ],
  305. })(
  306. <Input placeholder='请输入课程名称' />,
  307. )}
  308. </Form.Item>
  309. <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='教师'>
  310. {getFieldDecorator('teacher', {
  311. rules: [
  312. { required: true, message: '请输入教师' },
  313. ],
  314. })(
  315. <Input placeholder='请输入教师' />,
  316. )}
  317. </Form.Item>
  318. </Form>
  319. </Block>;
  320. }
  321. renderNo() {
  322. const { no } = this.state;
  323. if (!no) return null;
  324. return <Block>
  325. <h1>上传正式视频</h1>
  326. <ActionLayout
  327. itemList={this.actionList}
  328. selectedKeys={this.state.selectedKeys}
  329. onAction={key => this.onAction(key)}
  330. />
  331. <TableLayout
  332. columns={this.noColumns}
  333. list={this.state.list}
  334. pagination={false}
  335. loading={this.props.core.loading}
  336. onChange={(pagination, filters, sorter) => this.tableChange(pagination, filters, sorter)}
  337. onSelect={(keys, rows) => this.tableSelect(keys, rows)}
  338. selectedKeys={this.state.selectedKeys}
  339. />
  340. </Block>;
  341. }
  342. renderInfoVideo() {
  343. const { getFieldDecorator } = this.props.form;
  344. return <Block flex>
  345. <h1>课程介绍</h1>
  346. <Form>
  347. <Form.Item label='老师资历'>
  348. {getFieldDecorator('teacherContent', {
  349. })(
  350. <Editor placeholder='输入内容' />,
  351. )}
  352. </Form.Item>
  353. <Form.Item label='基本参数'>
  354. {getFieldDecorator('baseContent', {
  355. })(
  356. <Editor placeholder='输入内容' />,
  357. )}
  358. </Form.Item>
  359. <Form.Item label='授课内容'>
  360. {getFieldDecorator('courseContent', {
  361. })(
  362. <Editor placeholder='输入内容' />,
  363. )}
  364. </Form.Item>
  365. <Form.Item label='授课重点'>
  366. {getFieldDecorator('pointContent', {
  367. })(
  368. <Editor placeholder='输入内容' />,
  369. )}
  370. </Form.Item>
  371. <Form.Item label='适合人群'>
  372. {getFieldDecorator('crowdContent', {
  373. })(
  374. <Editor placeholder='输入内容' />,
  375. )}
  376. </Form.Item>
  377. </Form>
  378. </Block>;
  379. }
  380. renderSyllabus() {
  381. const { getFieldDecorator } = this.props.form;
  382. return <Block flex>
  383. <Form>
  384. <Form.Item label='授课大纲'>
  385. {getFieldDecorator('syllabusContent', {
  386. })(
  387. <Editor placeholder='输入内容' />,
  388. )}
  389. </Form.Item>
  390. </Form>
  391. </Block>;
  392. }
  393. renderPromote() {
  394. const { getFieldDecorator } = this.props.form;
  395. return <Block flex>
  396. <Form>
  397. <Form.Item label='优惠信息'>
  398. {getFieldDecorator('promoteContent', {
  399. })(
  400. <Editor placeholder='输入内容' />,
  401. )}
  402. </Form.Item>
  403. </Form>
  404. </Block>;
  405. }
  406. renderOnline() {
  407. const { exercise, data } = this.state;
  408. const { getFieldDecorator } = this.props.form;
  409. return <Block>
  410. <Form>
  411. {getFieldDecorator('id')(<input hidden />)}
  412. {exercise && data.structId && <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='学科'>
  413. {getFieldDecorator('structId', {
  414. rules: [{
  415. required: true, message: '请选择学科',
  416. }],
  417. initialValue: data.structId,
  418. })(
  419. <TreeSelect treeData={exercise} />,
  420. )}
  421. </Form.Item>}
  422. <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='课程名称'>
  423. {getFieldDecorator('title', {
  424. rules: [
  425. { required: true, message: '请输入课程名称' },
  426. ],
  427. })(
  428. <Input placeholder='请输入课程名称' />,
  429. )}
  430. </Form.Item>
  431. </Form>
  432. </Block>;
  433. }
  434. renderTime() {
  435. const { time, timerange } = this.state;
  436. if (!time) return null;
  437. return <Block>
  438. <h1>课时管理</h1>
  439. <TableLayout
  440. columns={this.timeColumns}
  441. list={this.state.list}
  442. pagination={false}
  443. loading={this.props.core.loading}
  444. onChange={(pagination, filters, sorter) => this.tableChange(pagination, filters, sorter)}
  445. onSelect={(keys, rows) => this.tableSelect(keys, rows)}
  446. selectedKeys={this.state.selectedKeys}
  447. />
  448. <Row>
  449. <Col span={8}>
  450. <Form.Item>
  451. <DatePicker.RangePicker value={timerange} onChange={(value) => {
  452. this.setState({ timerange: value });
  453. }} />
  454. </Form.Item>
  455. </Col>
  456. <Col span={1}>
  457. <Form.Item>
  458. <Button onClick={() => {
  459. Course.addTime({ courseId: this.params.id, startTime: timerange[0], endTime: timerange[1] }).then(() => {
  460. this.refreshTime();
  461. this.setState({ timerange: null });
  462. });
  463. }}>添加</Button>
  464. </Form.Item>
  465. </Col>
  466. </Row>
  467. </Block>;
  468. }
  469. renderVs() {
  470. const { exercise, data } = this.state;
  471. const { getFieldDecorator } = this.props.form;
  472. return <Block>
  473. <Form>
  474. {getFieldDecorator('id')(<input hidden />)}
  475. {exercise && data.structId && <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='学科'>
  476. {getFieldDecorator('structId', {
  477. rules: [{
  478. required: true, message: '请选择学科',
  479. }],
  480. initialValue: data.structId,
  481. })(
  482. <TreeSelect treeData={exercise} />,
  483. )}
  484. </Form.Item>}
  485. <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='课程名称'>
  486. {getFieldDecorator('title', {
  487. rules: [
  488. { required: true, message: '请输入课程名称' },
  489. ],
  490. })(
  491. <Input placeholder='请输入课程名称' />,
  492. )}
  493. </Form.Item>
  494. <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='定价'>
  495. {getFieldDecorator('price', {
  496. rules: [
  497. { required: true, message: '请输入价格' },
  498. ],
  499. })(
  500. <InputNumber placeholder='请输入' />,
  501. )}
  502. </Form.Item>
  503. <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='最小购买数量'>
  504. {getFieldDecorator('minNumber', {
  505. rules: [
  506. { required: true, message: '请输入最小购买数量' },
  507. ],
  508. })(
  509. <InputNumber placeholder='请输入' />,
  510. )}
  511. </Form.Item>
  512. <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='最大购买数量'>
  513. {getFieldDecorator('maxNumber', {
  514. rules: [
  515. { required: true, message: '请输入最大购买数量' },
  516. ],
  517. })(
  518. <InputNumber placeholder='请输入' />,
  519. )}
  520. </Form.Item>
  521. <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='有效期'>
  522. {getFieldDecorator('expireDays', {
  523. rules: [
  524. { required: true, message: '请输入有效期' },
  525. ],
  526. })(
  527. <InputNumber placeholder='天/10课时' />,
  528. )}
  529. </Form.Item>
  530. </Form>
  531. </Block>;
  532. }
  533. renderInfoVs() {
  534. const { getFieldDecorator, setFieldsValue, getFieldValue } = this.props.form;
  535. const image = getFieldValue('wechatAvatar') || null;
  536. return <Block flex>
  537. <h1>课程介绍</h1>
  538. <Form>
  539. <Form.Item label='服务介绍'>
  540. {getFieldDecorator('serviceContent', {
  541. })(
  542. <Editor placeholder='输入内容' />,
  543. )}
  544. </Form.Item>
  545. <Form.Item label='适合人群'>
  546. {getFieldDecorator('crowdContent', {
  547. })(
  548. <Editor placeholder='输入内容' />,
  549. )}
  550. </Form.Item>
  551. <Form.Item label='课时数'>
  552. {getFieldDecorator('courseNoContent', {
  553. })(
  554. <Editor placeholder='输入内容' />,
  555. )}
  556. </Form.Item>
  557. <Form.Item label='授课流程'>
  558. {getFieldDecorator('processContent', {
  559. })(
  560. <Editor placeholder='输入内容' />,
  561. )}
  562. </Form.Item>
  563. <Form.Item label='推广语'>
  564. {getFieldDecorator('messageContent', {
  565. })(
  566. <Editor placeholder='输入内容' />,
  567. )}
  568. </Form.Item>
  569. <Form.Item labelCol={{ span: 7 }} wrapperCol={{ span: 15 }} label='微信头像'>
  570. {getFieldDecorator('wechatAvatar', {
  571. rules: [
  572. { required: true, message: '上传图片' },
  573. ],
  574. })(
  575. <Upload
  576. listType="picture-card"
  577. showUploadList={false}
  578. beforeUpload={(file) => System.uploadImage(file).then((result) => {
  579. setFieldsValue({ wechatAvatar: result.url });
  580. return Promise.reject();
  581. })}
  582. >
  583. {image ? <img src={image} alt="avatar" /> : <div>
  584. <Icon type={this.state.loading ? 'loading' : 'plus'} />
  585. <div className="ant-upload-text">Upload</div>
  586. </div>}
  587. </Upload>,
  588. )}
  589. </Form.Item>
  590. </Form>
  591. </Block>;
  592. }
  593. renderTeacher() {
  594. const { teachers, teacher } = this.state;
  595. if (!teacher) return null;
  596. return <Block>
  597. <h1>授课老师</h1>
  598. <Form>
  599. <Row>
  600. {teachers.map((row, index) => {
  601. return <Col span={7} offset={index % 3 ? 1 : 0}><Card>
  602. <Button className="delete-button" size="small" onClick={() => {
  603. if (row.id) {
  604. Course.delTeacher(row.id).then(() => {
  605. this.deleteLength('teachers', index);
  606. });
  607. } else {
  608. this.deleteLength('teachers', index);
  609. }
  610. }}>
  611. <Icon type="delete" />
  612. </Button>
  613. <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label='姓名'>
  614. <Input placeholder='请输入姓名' value={row.realname} onChange={(e) => {
  615. this.changeTeacher('realname', index, e.target.value);
  616. }} />
  617. </Form.Item>
  618. <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label='微信'>
  619. <Input placeholder='请输入微信' value={row.wechat} onChange={(e) => {
  620. this.changeTeacher('wechat', index, e.target.value);
  621. }} />
  622. </Form.Item>
  623. <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label='二维码'>
  624. <Upload
  625. listType="picture-card"
  626. showUploadList={false}
  627. beforeUpload={(file) => System.uploadImage(file).then((result) => {
  628. this.changeTeacher('qr', index, result.url);
  629. return Promise.reject();
  630. })}
  631. >
  632. {row.qr ? <img src={row.qr} alt="avatar" /> : <div>
  633. <Icon type={this.state.loading ? 'loading' : 'plus'} />
  634. <div className="ant-upload-text">Upload</div>
  635. </div>}
  636. </Upload>
  637. </Form.Item>
  638. <Button onClick={() => {
  639. let handler = null;
  640. if (row.id) {
  641. handler = Course.editTeacher(row);
  642. } else {
  643. handler = Course.addTeacher(Object.assign({ courseId: this.params.id }, row));
  644. }
  645. handler.then(() => {
  646. this.refreshTeacher();
  647. });
  648. }}>{row.id ? '修改' : '添加'}</Button>
  649. </Card></Col>;
  650. })}
  651. <Col span={7} offset={teachers.length % 3 ? 1 : 0}>
  652. <Card className="plus" onClick={() => {
  653. this.addLength('teachers', { realname: '', wechat: '', qr: '' });
  654. }}>
  655. <Icon type={'plus'} />
  656. </Card>
  657. </Col>
  658. </Row>
  659. </Form>
  660. </Block>;
  661. }
  662. renderContent() {
  663. switch (this.state.module) {
  664. case 'online':
  665. return [this.renderOnline(), this.renderTime()];
  666. case 'vs':
  667. return [this.renderVs(), this.renderInfoVs(), this.renderTeacher()];
  668. case 'video':
  669. return [this.renderVideo(), this.renderNo(), this.renderInfoVideo(), this.renderSyllabus(), this.renderPromote()];
  670. default:
  671. return <div />;
  672. }
  673. }
  674. renderView() {
  675. return <div flex>
  676. {this.renderContent()}
  677. <Row type="flex" justify="center">
  678. <Col>
  679. <Button type="primary" onClick={() => {
  680. this.submit();
  681. }}>保存</Button>
  682. </Col>
  683. </Row>
  684. </div>;
  685. }
  686. }