page.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. import React from 'react';
  2. import { Link } from 'react-router-dom';
  3. import { Button, Modal, Checkbox, Row, Col, Switch } from 'antd';
  4. import './index.less';
  5. import Page from '@src/containers/Page';
  6. import Block from '@src/components/Block';
  7. import EditTableCell from '@src/components/EditTableCell';
  8. // import DragList from '@src/components/DragList';
  9. import FilterLayout from '@src/layouts/FilterLayout';
  10. import TreeLayout from '@src/layouts/TreeLayout';
  11. import ActionLayout from '@src/layouts/ActionLayout';
  12. import TableLayout from '@src/layouts/TableLayout';
  13. import { formatDate, getMap, formatTreeData } from '@src/services/Tools';
  14. import { asyncSMessage, asyncDelConfirm } from '@src/services/AsyncTools';
  15. // import { ArticleChannel } from '../../../../Constant';
  16. import { Ready } from '../../../stores/ready';
  17. // const ArticleChannelMap = getMap(ArticleChannel, 'value', 'label');
  18. export default class extends Page {
  19. init() {
  20. this.categoryTitleMap = {};
  21. this.categoryMap = {};
  22. this.categoryList = [];
  23. this.categoryTree = [];
  24. this.categoryColumns = [{
  25. dataIndex: 'parentId',
  26. title: '一级标题',
  27. render: (text, record) => {
  28. if (text) {
  29. return this.categoryMap[text];
  30. }
  31. return record.title;
  32. },
  33. }, {
  34. dataIndex: 'title',
  35. title: '二级标题',
  36. render: (text, record) => {
  37. if (record.parentId) {
  38. return record.title;
  39. }
  40. return '-';
  41. },
  42. }, {
  43. dataIndex: 'isData',
  44. title: '资料节点',
  45. render: (text, record) => {
  46. return record.parentId > 0 && <Checkbox onChange={(e) => {
  47. this.changeCategoryData(record.id, e.target.checked);
  48. }} checked={!!text} />;
  49. },
  50. }, {
  51. dataIndex: 'isOfficial',
  52. title: '官方资料',
  53. render: (text, record) => {
  54. return record.parentId > 0 && record.isData > 0 && <Checkbox onChange={(e) => {
  55. this.changeCategoryOfficial(record.id, e.target.checked);
  56. }} checked={!!text} />;
  57. },
  58. }];
  59. this.filterForm = [{
  60. key: 'parentCategoryId',
  61. type: 'select',
  62. allowClear: true,
  63. name: '一级标题',
  64. placeholder: '请选择',
  65. select: [],
  66. number: true,
  67. onChange: (value) => {
  68. this.changeSearch(this.filterForm, this, value);
  69. },
  70. }, {
  71. key: 'categoryId',
  72. type: 'select',
  73. allowClear: true,
  74. name: '二级标题',
  75. select: [],
  76. number: true,
  77. placeholder: '请选择',
  78. }];
  79. this.actionList = [{
  80. key: 'add',
  81. type: 'primary',
  82. name: '创建',
  83. render: (item) => {
  84. return <Link to='/ready/article/detail'><Button>{item.name}</Button></Link>;
  85. },
  86. }, {
  87. key: 'category',
  88. name: '目录',
  89. }];
  90. this.columns = [{
  91. title: '一级标题',
  92. dataIndex: 'parentCategoryId',
  93. render: (text) => {
  94. return this.categoryTitleMap[text];
  95. },
  96. }, {
  97. title: '二级标题',
  98. dataIndex: 'categoryId',
  99. render: (text) => {
  100. return this.categoryTitleMap[text];
  101. },
  102. }, {
  103. title: '文章标题',
  104. dataIndex: 'title',
  105. }, {
  106. title: '更新时间',
  107. dataIndex: 'updateTime',
  108. render: (text) => {
  109. return formatDate(text, 'YYYY-MM-DD HH:mm:ss');
  110. },
  111. }, {
  112. title: '操作',
  113. dataIndex: 'handler',
  114. render: (text, record) => {
  115. return <div className="table-button">
  116. {<Link to={`/ready/article/detail/${record.id}`}>编辑</Link>}
  117. {<a onClick={() => {
  118. this.deleteAction(record);
  119. }}>删除</a>}
  120. </div>;
  121. },
  122. }];
  123. this.refreshCategory();
  124. }
  125. refreshCategory() {
  126. Ready.allCategory().then(result => {
  127. this.categoryTitleMap = getMap(result, 'id', 'title');
  128. this.categoryTree = formatTreeData(result, 'id', 'title', 'parentId');
  129. this.categoryMap = getMap(result, 'id');
  130. this.categoryList = result.map(row => {
  131. const parent = this.categoryMap[row.parentId];
  132. row.value = row.id;
  133. row.title = <Row style={{ width: 400 }}>
  134. <Col span={11}><EditTableCell value={row.title} onChange={(value) => this.changeCategoryTitle(row.id, value)} /></Col>
  135. <Col span={5}>{row.parentId === 0 && <Switch checked={row.isData} checkedChildren='资料节点' unCheckedChildren='非资料' onChange={() => this.changeCategoryData(row.id, !row.isData)} />}{row.parentId === 0 && <Switch checked={row.isRoom} checkedChildren='考场节点' unCheckedChildren='非考场' onChange={() => this.changeCategoryRoom(row.id, !row.isRoom)} />}</Col>
  136. <Col span={5}>{row.parentId > 0 && parent.isData > 0 && <Switch checked={row.isOfficial} checkedChildren='官方资料' unCheckedChildren='非官方资料' onChange={() => this.changeCategoryOfficial(row.id, !row.isOfficial)} />}</Col>
  137. </Row>;
  138. return row;
  139. });
  140. this.filterForm[0].select = this.categoryList.filter(row => row.parentId === 0);
  141. this.changeSearch(this.filterForm, this, this.state.search.parentCategoryId);
  142. this.initData();
  143. this.setState({ categoryList: this.categoryList, categoryTree: this.categoryTree });
  144. });
  145. }
  146. changeSearch(list, component, value) {
  147. if (value) {
  148. list[1].disabled = false;
  149. list[1].select = this.categoryList.filter(row => row.parentId === value);
  150. } else {
  151. list[1].disabled = true;
  152. list[1].select = [];
  153. }
  154. component.setState({ load: false });
  155. }
  156. initData() {
  157. Ready.listArticle(this.state.search).then(result => {
  158. this.setTableData(result.list, result.total);
  159. });
  160. }
  161. deleteAction(row) {
  162. asyncDelConfirm('删除确认', '是否删除选中?', () => {
  163. const handler = Ready.delArticle({ id: row.id });
  164. return handler.then(() => {
  165. asyncSMessage('删除成功!');
  166. this.refresh();
  167. });
  168. });
  169. }
  170. changeCategoryTitle(id, title) {
  171. Ready.editCategory({ id, title })
  172. .then(() => { });
  173. }
  174. changeCategoryRoom(id, checked) {
  175. const category = this.categoryMap[id];
  176. if (category.isRoom) {
  177. if (checked) return;
  178. } else if (!checked) return;
  179. Ready.editCategory({ id, isRoom: checked ? 1 : 0, isData: 0 })
  180. .then(() => {
  181. this.refreshCategory();
  182. });
  183. }
  184. changeCategoryData(id, checked) {
  185. const category = this.categoryMap[id];
  186. if (category.isData) {
  187. if (checked) return;
  188. } else if (!checked) return;
  189. Ready.editCategory({ id, isData: checked ? 1 : 0, isRoom: 0 })
  190. .then(() => {
  191. this.refreshCategory();
  192. });
  193. }
  194. changeCategoryOfficial(id, checked) {
  195. const category = this.categoryMap[id];
  196. if (category.isData) {
  197. if (checked) return;
  198. } else if (!checked) return;
  199. Ready.editCategory({ id, isOfficial: checked ? 1 : 0 })
  200. .then(() => {
  201. this.refreshCategory();
  202. });
  203. }
  204. changeCategoryOrder(from, to) {
  205. if (from.id === to.id) return;
  206. if (from.parentId !== to.parentId) {
  207. asyncSMessage('只允许同层排序', 'warn');
  208. return;
  209. }
  210. let parent = [];
  211. if (to.parentId === 0) {
  212. parent = this.categoryTree;
  213. } else {
  214. parent = this.categoryMap[to.parentId].children;
  215. }
  216. let oldIndex = -1;
  217. let newIndex = -1;
  218. parent.forEach((row, i) => {
  219. if (row.id === from.id) oldIndex = i;
  220. if (row.id === to.id) newIndex = i;
  221. });
  222. const others = parent.map(row => row.id);
  223. const tmp = others.splice(oldIndex, 1);
  224. if (newIndex === parent.length) {
  225. others.push(tmp[0]);
  226. } else {
  227. others.splice(newIndex, 0, tmp[0]);
  228. }
  229. Ready.editCategory({ id: from.id, index: newIndex === parent.length ? parent.length : newIndex })
  230. .then(() => {
  231. this.refreshCategory();
  232. });
  233. }
  234. categoryAction() {
  235. this.open({});
  236. }
  237. renderView() {
  238. return <Block flex>
  239. <FilterLayout
  240. show
  241. itemList={this.filterForm}
  242. data={this.state.search}
  243. onChange={data => {
  244. data.page = 1;
  245. this.search(data);
  246. }} />
  247. <ActionLayout
  248. itemList={this.actionList}
  249. selectedKeys={this.state.selectedKeys}
  250. onAction={key => this.onAction(key)}
  251. />
  252. <TableLayout
  253. columns={this.tableSort(this.columns)}
  254. list={this.state.list}
  255. pagination={this.state.page}
  256. loading={this.props.core.loading}
  257. onChange={(pagination, filters, sorter) => this.tableChange(pagination, filters, sorter)}
  258. onSelect={(keys, rows) => this.tableSelect(keys, rows)}
  259. selectedKeys={this.state.selectedKeys}
  260. />
  261. {this.state.detail && <Modal visible closable title='目录结构' footer={null} onCancel={() => {
  262. this.close(false, 'detail');
  263. }} onOk={() => {
  264. this.close(true, 'detail');
  265. }}>
  266. <TreeLayout
  267. autoExpandParent
  268. defaultExpandAll
  269. itemList={this.state.categoryTree}
  270. selectable={false}
  271. draggable
  272. // onDragStart={({ event, node }) => console.log('start', event, node.props)}
  273. // onDragOver={({ event, node }) => console.log('over', event, node.props)}
  274. // onDragLeave={({ event, node }) => console.log('leave', event, node.kepropsy)}
  275. // onDragEnd={({ event, node }) => console.log('end', event, node.props)}
  276. // onDragEnter={({ event, node, expandedKeys }) => console.log('enter', event, node.props, expandedKeys)}
  277. onDrop={({ event, node, dragNode, dragNodesKeys }) => {
  278. console.log('drop', event, node.props, dragNode.props, dragNodesKeys);
  279. this.changeCategoryOrder(dragNode.props, node.props);
  280. }
  281. }
  282. />
  283. {/* <TableLayout
  284. rowKey={'id'}
  285. columns={this.categoryColumns}
  286. list={this.state.categoryList}
  287. pagination={false}
  288. /> */}
  289. {/* <DragList
  290. loading={this.props.core.loading}
  291. dataSource={this.state.categoryTree || []}
  292. handle={'.icon'}
  293. onMove={(oldIndex, newIndex) => {
  294. this.orderQuestion(oldIndex, newIndex);
  295. }}
  296. renderItem={(item) => (
  297. <List.Item actions={[<Icon type='bars' className='icon' />]}>
  298. <Row style={{ width: '100%' }}>
  299. <Col span={11}>标题: {item.title}</Col>
  300. </Row>
  301. <Row style={{ width: '100%' }}>
  302. <DragList
  303. loading={false}
  304. dataSource={item.children}
  305. handle={`.icon${item.id}`}
  306. onMove={(oldIndex, newIndex) => {
  307. this.orderQuestion(oldIndex, newIndex);
  308. }}
  309. renderItem={(row) => (
  310. <List.Item actions={[<Icon type='bars' className={`.icon${item.id}`} />]}>
  311. <Row style={{ width: '100%' }}>
  312. <Col span={11}>标题: {row.title}</Col>
  313. <Col span={5}><Switch checked={row.isData} checkedChildren='资料节点' unCheckedChildren='基本节点' onChange={() => this.changeCategoryData(row.id, !row.isData)} /></Col>
  314. <Col span={5}>{row.isData > 0 && <Switch checked={row.isOfficial} checkedChildren='官方资料' unCheckedChildren='非官方资料' onChange={() => this.changeCategoryOfficial(row.id, !row.isOfficial)} />}</Col>
  315. </Row>
  316. </List.Item>
  317. )} />
  318. </Row>
  319. </List.Item>
  320. )} /> */}
  321. </Modal>}
  322. </Block>;
  323. }
  324. }