CourseMemberTimeLine.tsx 4.6 KB

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