page.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. import React from 'react';
  2. import moment from 'moment';
  3. import { DatePicker, Checkbox, Modal, Form, Input, Row, Col, Button, Upload } from 'antd';
  4. import './index.less';
  5. import Page from '@src/containers/Page';
  6. import Block from '@src/components/Block';
  7. // import FilterLayout from '@src/layouts/FilterLayout';
  8. import ActionLayout from '@src/layouts/ActionLayout';
  9. import TableLayout from '@src/layouts/TableLayout';
  10. import { formatDate } from '@src/services/Tools';
  11. import { asyncSMessage, asyncForm } from '@src/services/AsyncTools';
  12. import { UserUrl } from '../../../../Constant';
  13. import { Course } from '../../../stores/course';
  14. import { User } from '../../../stores/user';
  15. import { System } from '../../../stores/system';
  16. export default class extends Page {
  17. init() {
  18. this.videoColumns = [{
  19. title: '时间段',
  20. dataIndex: 'time',
  21. render: (text) => {
  22. return `${formatDate(text.startTime, 'YYYY-MM-DD')}~${formatDate(text.endTime, 'YYYY-MM-DD')}`;
  23. },
  24. }, {
  25. title: '学员id',
  26. dataIndex: 'userId',
  27. }, {
  28. title: '学员名称',
  29. dataIndex: 'user.nickname',
  30. }, {
  31. title: '手机号',
  32. dataIndex: 'user.mobile',
  33. }, {
  34. title: '操作',
  35. dataIndex: 'handler',
  36. render: (text, record) => {
  37. return <div className="table-button">
  38. {<a onClick={() => {
  39. this.deleteOnlineStudent(record);
  40. }}>删除</a>}
  41. </div>;
  42. },
  43. }];
  44. this.vsAction = [{
  45. key: 'addAppointment',
  46. name: '添加预约',
  47. }];
  48. this.vsList = [{
  49. key: 'id',
  50. type: 'hidden',
  51. }, {
  52. key: 'title',
  53. type: 'input',
  54. name: '课程名称',
  55. }, {
  56. key: 'timerange',
  57. type: 'daterange',
  58. showTime: true,
  59. name: '上课时间',
  60. }, {
  61. key: 'channel',
  62. type: 'input',
  63. name: '频道号',
  64. }];
  65. this.vsColumns = [{
  66. title: '课时序号',
  67. dataIndex: 'no',
  68. render: (text) => {
  69. const { data } = this.state;
  70. return `${text}/${data.vsNumber}`;
  71. },
  72. }, {
  73. title: '上课时间',
  74. dataIndex: 'time',
  75. render: (text, record) => {
  76. return <DatePicker.RangePicker showTime value={[record.startTime, record.endTime]} onChange={(value) => {
  77. this.changeAppointment(record.id, { startTime: value[0], endTime: value[1] });
  78. }} />;
  79. },
  80. }, {
  81. title: '课程名称',
  82. dataIndex: 'title',
  83. }, {
  84. title: '频道号',
  85. dataIndex: 'channel',
  86. }, {
  87. title: '学习进度',
  88. dataIndex: 'isFinish',
  89. render: (text, record) => {
  90. return <Checkbox checked={text > 0} onChange={(e) => {
  91. this.changeAppointment(record.id, { isFinish: e.target.value ? 1 : 0 });
  92. }} />;
  93. },
  94. }, {
  95. title: '预习作业',
  96. dataIndex: 'userPaper',
  97. render: (text, record) => {
  98. return text ? <a onClick={() => {
  99. User.locationUser(record.userId, `${UserUrl}/paper/report/${record.reportId}`);
  100. }}>查看{text.times > 0 ? '(已完成)' : ''}</a> : '';
  101. },
  102. }, {
  103. title: '笔记批阅',
  104. dataIndex: 'noteList',
  105. render: (text, record) => {
  106. return <a onClick={() => {
  107. this.noteAction(record);
  108. }}>查看</a>;
  109. },
  110. }, {
  111. title: '课后补充',
  112. dataIndex: 'supplyList',
  113. render: (text, record) => {
  114. return <a onClick={() => {
  115. this.supplyAction(record);
  116. }}>查看</a>;
  117. },
  118. }];
  119. }
  120. initData() {
  121. const { id } = this.params;
  122. let handler;
  123. if (id) {
  124. handler = Course.listStudy({ ids: [id] });
  125. }
  126. handler
  127. .then(result => {
  128. const [row] = result.list;
  129. if (!row) {
  130. asyncSMessage('记录不存在');
  131. return;
  132. }
  133. const { course } = row;
  134. this.setState({ module: course.courseModule });
  135. this.setState({ data: row });
  136. this.refresh();
  137. });
  138. }
  139. refresh() {
  140. // const { id } = this.params;
  141. const { module } = this.state;
  142. switch (module) {
  143. case 'video':
  144. this.refreshVideo();
  145. break;
  146. case 'online':
  147. break;
  148. case 'vs':
  149. this.refreshVs();
  150. break;
  151. default:
  152. }
  153. }
  154. refreshVideo() {
  155. // const { id } = this.params;
  156. // Course.listStudentOnline(Object.assign({ courseId: id }, this.state.search)).then(result => {
  157. // this.setTableData(result.list, result.total);
  158. // });
  159. }
  160. refreshVs() {
  161. const { id } = this.params;
  162. User.listCourseAppointment(Object.assign({ courseId: id }, this.state.search)).then(result => {
  163. result.list = result.list.map(row => {
  164. row.startTime = moment(row.startTime);
  165. row.endTime = moment(row.endTime);
  166. return row;
  167. });
  168. this.setTableData(result.list, result.total);
  169. });
  170. }
  171. changeAppointment(id, data) {
  172. data.id = id;
  173. return User.editCourseAppointment(data).then(() => {
  174. this.refreshVs();
  175. this.cleanInfo();
  176. });
  177. }
  178. addAppointmentAction() {
  179. const { id } = this.params;
  180. asyncForm('添加', this.vsList, {}, info => {
  181. const { data } = this.state;
  182. ([info.startTime, info.endTime] = info.timerange);
  183. return User.addCourseAppointment(Object.assign({ recordId: id, userId: data.userId, courseId: data.courseId, noteList: [], supplyList: [] }, info)).then(() => {
  184. asyncSMessage('添加成功!');
  185. this.refreshVs();
  186. });
  187. }).catch(err => {
  188. console.log(err);
  189. });
  190. }
  191. noteAction(record) {
  192. this.open(record, 'note');
  193. }
  194. supplyAction(record) {
  195. this.open(record, 'supply');
  196. }
  197. deleteAppointment(row) {
  198. User.delCourseAppointment({ id: row.id }).then(() => {
  199. asyncSMessage('删除成功!');
  200. this.refresh();
  201. });
  202. }
  203. changeInfo(key, data) {
  204. const info = this.state[key] || {};
  205. this.setState({ [key]: Object.assign(info, data) });
  206. }
  207. cleanInfo() {
  208. this.setState({ supplyInfo: null, noteInfo: null });
  209. }
  210. renderVs() {
  211. const { data, page } = this.state;
  212. return <Block flex>
  213. {data.vsNumber > page.total && <ActionLayout
  214. itemList={this.vsAction}
  215. selectedKeys={this.state.selectedKeys}
  216. onAction={key => this.onAction(key)}
  217. />}
  218. <TableLayout
  219. columns={this.vsColumns}
  220. list={this.state.list}
  221. pagination={this.state.page}
  222. loading={this.props.core.loading}
  223. onChange={(pagination, filters, sorter) => this.tableChange(pagination, filters, sorter)}
  224. onSelect={(keys, rows) => this.tableSelect(keys, rows)}
  225. selectedKeys={this.state.selectedKeys}
  226. />
  227. {this.state.note && <Modal visible closable title='课后笔记' footer={null} onCancel={() => {
  228. this.cleanInfo();
  229. this.close(false, 'note');
  230. }}>
  231. {(this.state.note.noteList || []).map(row => {
  232. return <p>{formatDate(row.time)}: {<a href={row.url} target='_blank'>{row.name}</a>}</p>;
  233. })}
  234. <Form>
  235. <Row>
  236. <Col span={1}><Upload
  237. showUploadList={false}
  238. beforeUpload={(file) => System.uploadImage(file).then((result) => {
  239. this.changeInfo('noteInfo', { url: result.url, name: file.name, time: new Date() });
  240. return Promise.reject();
  241. })}
  242. >
  243. <Button>上传文档{(this.state.noteInfo || {}).url ? '(已上传)' : ''}</Button>
  244. </Upload></Col>
  245. <Col span={1} offset={20}><Button type='primary' onClick={() => {
  246. if (!this.state.noteInfo || !this.state.noteInfo.url) return;
  247. let { noteList = [] } = this.state.note;
  248. noteList = noteList || [];
  249. noteList.push(this.state.noteInfo);
  250. this.changeAppointment(this.state.note.id, { noteList });
  251. }}>发布</Button></Col>
  252. </Row>
  253. </Form>
  254. </Modal>}
  255. {this.state.supply && <Modal visible closable title='课后补充' footer={null} onCancel={() => {
  256. this.cleanInfo();
  257. this.close(false, 'supply');
  258. }}>
  259. {(this.state.supply.supplyList || []).map(row => {
  260. return [<p>{formatDate(row.time)}:{<a href={row.url} target='_blank'>{row.name}</a>}</p>, <p>留言 - {row.content}</p>];
  261. })}
  262. <Form>
  263. <Row>
  264. <Col span={12}>
  265. <Input value={(this.state.supplyInfo || {}).content || ''} onChange={value => {
  266. this.changeInfo('supplyInfo', { content: value });
  267. }} />
  268. </Col>
  269. <Col span={1}><Upload
  270. showUploadList={false}
  271. beforeUpload={(file) => System.uploadImage(file).then((result) => {
  272. this.changeInfo('supplyInfo', { url: result.url, name: file.name, time: new Date() });
  273. return Promise.reject();
  274. })}
  275. >
  276. <Button>上传文档{(this.state.supplyInfo || {}).url ? '(已上传)' : ''}</Button>
  277. </Upload></Col>
  278. <Col span={1} offset={8}><Button type='primary' onClick={() => {
  279. if (!this.state.supplyInfo || !this.state.supplyInfo.url) return;
  280. let { supplyList = [] } = this.state.supply;
  281. supplyList = supplyList || [];
  282. supplyList.push(this.state.supplyInfo);
  283. this.changeAppointment(this.state.supply.id, { supplyList });
  284. }}>发布</Button></Col>
  285. </Row>
  286. </Form>
  287. </Modal>}
  288. </Block>;
  289. }
  290. renderVideo() {
  291. return <Block flex>
  292. <TableLayout
  293. columns={this.videoColumns}
  294. list={this.state.list}
  295. pagination={this.state.page}
  296. loading={this.props.core.loading}
  297. onChange={(pagination, filters, sorter) => this.tableChange(pagination, filters, sorter)}
  298. onSelect={(keys, rows) => this.tableSelect(keys, rows)}
  299. selectedKeys={this.state.selectedKeys}
  300. />
  301. </Block>;
  302. }
  303. renderView() {
  304. switch (this.state.module) {
  305. case 'online':
  306. return [];
  307. case 'vs':
  308. return [this.renderVs()];
  309. case 'video':
  310. return [this.renderVideo()];
  311. default:
  312. return <div />;
  313. }
  314. }
  315. }