CourseMemberTimeLine.tsx 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import { useEffect, useRef } from "react";
  2. import { useIntl } from "react-intl";
  3. import { Space, Tag, Typography } from "antd";
  4. import { ActionType, ProList } from "@ant-design/pro-components";
  5. import { get } from "../../request";
  6. import { ICourseMemberData, ICourseMemberListResponse } from "../api/Course";
  7. import User from "../auth/User";
  8. import TimeShow from "../general/TimeShow";
  9. import { getStatusColor } from "./RolePower";
  10. const { Text } = Typography;
  11. interface IParams {
  12. timeline?: string;
  13. }
  14. interface IWidget {
  15. courseId?: string;
  16. userId?: string;
  17. }
  18. const CourseMemberTimeLineWidget = ({ courseId, userId }: IWidget) => {
  19. const intl = useIntl(); //i18n
  20. const ref = useRef<ActionType>();
  21. useEffect(() => {
  22. ref.current?.reload();
  23. }, [courseId, userId]);
  24. return (
  25. <>
  26. <ProList<ICourseMemberData, IParams>
  27. actionRef={ref}
  28. search={{
  29. filterType: "light",
  30. }}
  31. metas={{
  32. avatar: {
  33. render(dom, entity, index, action, schema) {
  34. return <User {...entity.user} showName={false} />;
  35. },
  36. editable: false,
  37. },
  38. title: {
  39. dataIndex: "name",
  40. search: false,
  41. render(dom, entity, index, action, schema) {
  42. return entity.course ? (
  43. <Text strong>{entity.course.title}</Text>
  44. ) : (
  45. entity.user?.nickName
  46. );
  47. },
  48. },
  49. description: {
  50. dataIndex: "desc",
  51. search: false,
  52. render(dom, entity, index, action, schema) {
  53. return (
  54. <Space>
  55. <User {...entity.editor} showAvatar={false} />
  56. <TimeShow type="secondary" updatedAt={entity.updated_at} />
  57. </Space>
  58. );
  59. },
  60. },
  61. subTitle: {
  62. search: false,
  63. render: (
  64. dom: React.ReactNode,
  65. entity: ICourseMemberData,
  66. index: number
  67. ) => {
  68. return (
  69. <Tag>
  70. {intl.formatMessage({
  71. id: `auth.role.${entity.role}`,
  72. })}
  73. </Tag>
  74. );
  75. },
  76. },
  77. actions: {
  78. search: false,
  79. render: (text, row, index, action) => {
  80. const statusColor = getStatusColor(row.status);
  81. return [
  82. <span style={{ color: statusColor }}>
  83. {intl.formatMessage({
  84. id: `course.member.status.${row.status}.label`,
  85. })}
  86. </span>,
  87. ];
  88. },
  89. },
  90. timeline: {
  91. // 自己扩展的字段,主要用于筛选,不在列表中显示
  92. title: "筛 选",
  93. valueType: "select",
  94. valueEnum: {
  95. all: { text: intl.formatMessage({ id: "course.timeline.all" }) },
  96. current: {
  97. text: intl.formatMessage({ id: "course.timeline.current" }),
  98. },
  99. },
  100. },
  101. }}
  102. request={async (params = {}, sorter, filter) => {
  103. console.info("filter", params, sorter, filter);
  104. let url = `/v2/course-member?view=timeline&course=${courseId}&userId=${userId}`;
  105. const offset =
  106. ((params.current ? params.current : 1) - 1) *
  107. (params.pageSize ? params.pageSize : 20);
  108. url += `&limit=${params.pageSize}&offset=${offset}`;
  109. if (typeof params.keyword !== "undefined") {
  110. url += "&search=" + (params.keyword ? params.keyword : "");
  111. }
  112. if (params.timeline) {
  113. url += `&timeline=${params.timeline}&request_course=1`;
  114. }
  115. console.info("api request", url);
  116. const res = await get<ICourseMemberListResponse>(url);
  117. if (res.ok) {
  118. console.debug("api response", res.data);
  119. return {
  120. total: res.data.count,
  121. succcess: true,
  122. data: res.data.rows,
  123. };
  124. } else {
  125. console.error(res.message);
  126. return {
  127. total: 0,
  128. succcess: false,
  129. data: [],
  130. };
  131. }
  132. }}
  133. rowKey="id"
  134. bordered
  135. pagination={{
  136. showQuickJumper: true,
  137. showSizeChanger: true,
  138. }}
  139. options={{
  140. search: false,
  141. }}
  142. />
  143. </>
  144. );
  145. };
  146. export default CourseMemberTimeLineWidget;