list.tsx 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. import { useParams } from "react-router-dom";
  2. import { ProTable } from "@ant-design/pro-components";
  3. import { useIntl } from "react-intl";
  4. import { Link } from "react-router-dom";
  5. import { Space, Table, Typography } from "antd";
  6. import { PlusOutlined } from "@ant-design/icons";
  7. import type { MenuProps } from "antd";
  8. import { Button, Dropdown, Menu, Popover } from "antd";
  9. import { SearchOutlined } from "@ant-design/icons";
  10. import AnthologyCreate from "../../../components/anthology/AnthologyCreate";
  11. import { IAnthologyListResponse } from "../../../components/api/Article";
  12. import { get } from "../../../request";
  13. import { PublicityValueEnum } from "../../../components/studio/table";
  14. const { Text } = Typography;
  15. const onMenuClick: MenuProps["onClick"] = (e) => {
  16. console.log("click", e);
  17. };
  18. const menu = (
  19. <Menu
  20. onClick={onMenuClick}
  21. items={[
  22. {
  23. key: "1",
  24. label: "在藏经阁中打开",
  25. icon: <SearchOutlined />,
  26. },
  27. {
  28. key: "2",
  29. label: "分享",
  30. icon: <SearchOutlined />,
  31. },
  32. ]}
  33. />
  34. );
  35. interface IItem {
  36. sn: number;
  37. id: string;
  38. title: string;
  39. subtitle: string;
  40. publicity: number;
  41. articles: number;
  42. createdAt: number;
  43. }
  44. const Widget = () => {
  45. const intl = useIntl();
  46. const { studioname } = useParams();
  47. const anthologyCreate = <AnthologyCreate studio={studioname} />;
  48. return (
  49. <>
  50. <ProTable<IItem>
  51. columns={[
  52. {
  53. title: intl.formatMessage({
  54. id: "dict.fields.sn.label",
  55. }),
  56. dataIndex: "sn",
  57. key: "sn",
  58. width: 50,
  59. search: false,
  60. },
  61. {
  62. title: intl.formatMessage({
  63. id: "forms.fields.title.label",
  64. }),
  65. dataIndex: "title",
  66. key: "title",
  67. tip: "过长会自动收缩",
  68. ellipsis: true,
  69. render: (text, row, index, action) => {
  70. return (
  71. <div>
  72. <div>
  73. <Link to={`/studio/${studioname}/anthology/${row.id}/edit`}>
  74. {row.title}
  75. </Link>
  76. </div>
  77. <Text type="secondary">{row.subtitle}</Text>
  78. </div>
  79. );
  80. },
  81. },
  82. {
  83. title: intl.formatMessage({
  84. id: "forms.fields.publicity.label",
  85. }),
  86. dataIndex: "publicity",
  87. key: "publicity",
  88. width: 100,
  89. search: false,
  90. filters: true,
  91. onFilter: true,
  92. valueEnum: PublicityValueEnum(),
  93. },
  94. {
  95. title: intl.formatMessage({
  96. id: "article.fields.article.count.label",
  97. }),
  98. dataIndex: "articles",
  99. key: "articles",
  100. width: 100,
  101. search: false,
  102. sorter: (a, b) => a.articles - b.articles,
  103. },
  104. {
  105. title: intl.formatMessage({
  106. id: "forms.fields.created-at.label",
  107. }),
  108. key: "created-at",
  109. width: 100,
  110. search: false,
  111. dataIndex: "createdAt",
  112. valueType: "date",
  113. sorter: (a, b) => a.createdAt - b.createdAt,
  114. },
  115. {
  116. title: intl.formatMessage({ id: "buttons.option" }),
  117. key: "option",
  118. width: 120,
  119. valueType: "option",
  120. render: (text, row, index, action) => [
  121. <Dropdown.Button type="link" key={index} overlay={menu}>
  122. {intl.formatMessage({
  123. id: "buttons.edit",
  124. })}
  125. </Dropdown.Button>,
  126. ],
  127. },
  128. ]}
  129. rowSelection={{
  130. // 自定义选择项参考: https://ant.design/components/table-cn/#components-table-demo-row-selection-custom
  131. // 注释该行则默认不显示下拉选项
  132. selections: [Table.SELECTION_ALL, Table.SELECTION_INVERT],
  133. }}
  134. tableAlertRender={({
  135. selectedRowKeys,
  136. selectedRows,
  137. onCleanSelected,
  138. }) => (
  139. <Space size={24}>
  140. <span>
  141. {intl.formatMessage({ id: "buttons.selected" })}{" "}
  142. {selectedRowKeys.length}
  143. <Button
  144. type="link"
  145. style={{ marginInlineStart: 8 }}
  146. onClick={onCleanSelected}
  147. >
  148. {intl.formatMessage({ id: "buttons.unselect" })}
  149. </Button>
  150. </span>
  151. </Space>
  152. )}
  153. tableAlertOptionRender={() => {
  154. return (
  155. <Space size={16}>
  156. <Button type="link">批量删除</Button>
  157. </Space>
  158. );
  159. }}
  160. request={async (params = {}, sorter, filter) => {
  161. // TODO
  162. console.log(params, sorter, filter);
  163. let url = `/v2/anthology?view=studio&name=${studioname}`;
  164. const offset =
  165. ((params.current ? params.current : 1) - 1) *
  166. (params.pageSize ? params.pageSize : 20);
  167. url += `&limit=${params.pageSize}&offset=${offset}`;
  168. if (typeof params.keyword !== "undefined") {
  169. url += "&search=" + (params.keyword ? params.keyword : "");
  170. }
  171. const res = await get<IAnthologyListResponse>(url);
  172. const items: IItem[] = res.data.rows.map((item, id) => {
  173. const date = new Date(item.created_at);
  174. return {
  175. sn: id + 1,
  176. id: item.uid,
  177. title: item.title,
  178. subtitle: item.subtitle,
  179. publicity: item.status,
  180. articles: item.childrenNumber,
  181. createdAt: date.getTime(),
  182. };
  183. });
  184. console.log(items);
  185. return {
  186. total: res.data.count,
  187. succcess: true,
  188. data: items,
  189. };
  190. }}
  191. rowKey="id"
  192. bordered
  193. pagination={{
  194. showQuickJumper: true,
  195. showSizeChanger: true,
  196. }}
  197. search={false}
  198. options={{
  199. search: true,
  200. }}
  201. toolBarRender={() => [
  202. <Popover
  203. content={anthologyCreate}
  204. title="new article"
  205. placement="bottomRight"
  206. >
  207. <Button key="button" icon={<PlusOutlined />} type="primary">
  208. {intl.formatMessage({ id: "buttons.create" })}
  209. </Button>
  210. </Popover>,
  211. ]}
  212. />
  213. </>
  214. );
  215. };
  216. export default Widget;