page.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. import React from 'react';
  2. import './index.less';
  3. import { Drawer, Tabs, ListView } from 'antd-mobile';
  4. import Page from '@src/containers/Page';
  5. import Assets from '@src/components/Assets';
  6. import { formatTreeData, getMap } from '@src/services/Tools';
  7. import ListData from '@src/services/ListData';
  8. import { CourseBlock, CoursePackageBlock } from '../../../components/Block';
  9. import { SpecialRadioGroup } from '../../../components/Radio';
  10. import Button from '../../../components/Button';
  11. import Checkbox from '../../../components/CheckBox';
  12. import { Course } from '../../../stores/course';
  13. import { Main } from '../../../stores/main';
  14. export default class extends Page {
  15. initState() {
  16. return {
  17. listMap: {},
  18. };
  19. }
  20. init() {
  21. Main.dataStruct().then(list => {
  22. list = list.map(row => {
  23. row.title = `${row.titleZh} ${row.titleEn}`;
  24. row.label = row.title;
  25. row.key = row.id;
  26. return row;
  27. });
  28. const structMap = getMap(list, 'id');
  29. const videoTree = formatTreeData(list, 'id', 'title', 'parentId');
  30. const packageTree = formatTreeData(list.filter(row => row.level === 1), 'id', 'title', 'parentId');
  31. this.setState({ videoTree, packageTree, structMap });
  32. });
  33. const { search } = this.state;
  34. if (!search.order) search.order = 'saleNumber';
  35. this.setState({ search, tab: 'video' });
  36. }
  37. initData() {
  38. return this.initListKeys(['video', 'package']).then(() => {
  39. return this.getList('video', 1);
  40. });
  41. }
  42. initListKeys(keys) {
  43. const { listMap } = this.state;
  44. keys.forEach(key => {
  45. listMap[key] = new ListData();
  46. });
  47. this.setState({ listMap });
  48. return Promise.resolve();
  49. }
  50. getList(key, page) {
  51. this.setState({ tab: key });
  52. let handler;
  53. switch (key) {
  54. case 'video':
  55. handler = Course.listVideo(Object.assign({ page }, this.state.search));
  56. break;
  57. case 'package':
  58. handler = Course.listPackage(Object.assign({ page }, this.state.search)).then(result => {
  59. const { structMap } = this.state;
  60. result.list = result.list.map(row => {
  61. row.tag = (structMap[row.structId] || {}).title;
  62. return row;
  63. });
  64. return result;
  65. });
  66. break;
  67. default:
  68. return;
  69. }
  70. handler.then(result => {
  71. const { listMap } = this.state;
  72. if (page === 1) {
  73. // todo 是否重新读取第一页为刷新所有数据
  74. listMap[key] = new ListData();
  75. }
  76. listMap[key].get(page, result, this.state.search.size);
  77. this.setState({ listMap, tab: key });
  78. });
  79. }
  80. changeStruct(value) {
  81. const { search = {} } = this.state;
  82. search.structId = value;
  83. this.setState({ search });
  84. }
  85. renderView() {
  86. const { filter } = this.state;
  87. return (
  88. <Drawer
  89. style={{ minHeight: document.documentElement.clientHeight }}
  90. position="right"
  91. open={filter}
  92. sidebar={this.renderFilter()}
  93. onOpenChange={isOpen => this.setState({ filter: isOpen })}
  94. >
  95. <div className="top">
  96. <Tabs
  97. onChange={value => {
  98. this.changeStruct(null);
  99. this.getList(value.key, 1);
  100. }}
  101. tabs={[{ title: '单次', key: 'video' }, { title: '套餐', key: 'package' }]}
  102. />
  103. <div className="right" onClick={() => this.setState({ filter: true })}>
  104. 筛选
  105. <Assets name="screen" />
  106. </div>
  107. </div>
  108. {this.renderList()}
  109. </Drawer>
  110. );
  111. }
  112. renderRow(rowData) {
  113. const { tab } = this.state;
  114. switch (tab) {
  115. case 'video':
  116. return <CourseBlock data={rowData} />;
  117. case 'package':
  118. return <CoursePackageBlock data={rowData} theme="not" />;
  119. default:
  120. return <div />;
  121. }
  122. }
  123. renderList() {
  124. const { listMap, tab } = this.state;
  125. const data = listMap[tab];
  126. if (!data) return <div />;
  127. const { dataSource = {}, bottom, loading, finish, maxSectionId = 1, total } = data;
  128. if (total === 0) return this.renderEmpty();
  129. return (
  130. <ListView
  131. className="list"
  132. ref={el => {
  133. this.lv = el;
  134. }}
  135. dataSource={dataSource}
  136. renderFooter={() => (
  137. <div style={{ padding: 30, textAlign: 'center' }}>{loading ? '加载中...' : bottom ? '没有更多了' : ''}</div>
  138. )}
  139. renderRow={(rowData, sectionID, rowID) => this.renderRow(rowData, sectionID, rowID)}
  140. style={{
  141. height: this.state.height,
  142. overflow: 'auto',
  143. }}
  144. pageSize={this.state.search.size}
  145. scrollRenderAheadDistance={500}
  146. onEndReached={() => {
  147. if (loading) return;
  148. if (bottom) {
  149. if (!finish) {
  150. data.finish = true;
  151. // this.setState({ time: new Date() })
  152. }
  153. return;
  154. }
  155. this.getList(tab, maxSectionId + 1);
  156. }}
  157. onEndReachedThreshold={10}
  158. />
  159. );
  160. }
  161. renderEmpty() {
  162. return <div />;
  163. }
  164. renderFilter() {
  165. const { search, videoTree = [], packageTree = [], tab } = this.state;
  166. return (
  167. <div className="filter">
  168. <div className="body">
  169. <div className="sub">
  170. <div className="title">筛选学科</div>
  171. {(tab === 'package' ? packageTree : videoTree).map(row => {
  172. return (
  173. <div className="item">
  174. <div className={row.children.length > 0 ? 'label' : 'label left'}>{row.title}</div>
  175. {row.children.length > 0 && (
  176. <div className="value">
  177. <SpecialRadioGroup
  178. list={row.children}
  179. value={search.structId}
  180. onChange={value => {
  181. this.changeStruct(value);
  182. }}
  183. />
  184. </div>
  185. )}
  186. {row.children.length === 0 && (
  187. <div className="value right">
  188. <Checkbox
  189. checked={search.structId === row.id}
  190. onClick={() => {
  191. this.changeStruct(row.id);
  192. }}
  193. />
  194. </div>
  195. )}
  196. </div>
  197. );
  198. })}
  199. </div>
  200. </div>
  201. <div className="footer">
  202. <Button
  203. radius
  204. width={90}
  205. onClick={() => {
  206. this.getList(tab, 1);
  207. }}
  208. >
  209. 确定
  210. </Button>
  211. </div>
  212. </div>
  213. );
  214. }
  215. }