PageNumberList.tsx 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. import { Badge, Card, Select, Space, Tree } from "antd";
  2. import { useEffect, useState } from "react";
  3. import { get } from "../../request";
  4. import type { DataNode } from "antd/es/tree"
  5. import { useIntl } from "react-intl";
  6. import type { Key } from "antd/es/table/interface"
  7. import { bookName } from "./book_name";
  8. export interface IPageNumber {
  9. type: string;
  10. volume: number;
  11. page: number;
  12. book: number;
  13. paragraph: number;
  14. pcd_book_id: number;
  15. }
  16. export interface IPageNumberListResponse {
  17. ok: boolean;
  18. message: string;
  19. data: IPageNumber[];
  20. }
  21. interface IType {
  22. key: string;
  23. value: number;
  24. }
  25. interface IWidget {
  26. keyWord?: string;
  27. onSelect?: Function;
  28. }
  29. const CaseListWidget = ({ keyWord, onSelect }: IWidget) => {
  30. const intl = useIntl();
  31. const [_pageData, setPageData] = useState<IPageNumber[]>();
  32. const [types, setTypes] = useState<IType[]>();
  33. const [treeData, setTreeData] = useState<DataNode[]>();
  34. const booksTitle = (type: string): [string[], Map<string, number[]>] => {
  35. const bookNameMap = new Map<string, number[]>();
  36. bookName.forEach((value) => {
  37. let name: string;
  38. switch (type) {
  39. case "M":
  40. name = value.m_title;
  41. break;
  42. case "P":
  43. name = value.p_title;
  44. break;
  45. case "V":
  46. name = value.v_title;
  47. break;
  48. default:
  49. name = value.term;
  50. break;
  51. }
  52. if (bookNameMap.has(name)) {
  53. const id = bookNameMap.get(name);
  54. if (id) {
  55. id.push(value.id);
  56. bookNameMap.set(name, id);
  57. } else {
  58. bookNameMap.set(name, [value.id]);
  59. }
  60. } else {
  61. bookNameMap.set(name, [value.id]);
  62. }
  63. });
  64. const bookNameList: string[] = [];
  65. bookNameMap.forEach((_value, key) => {
  66. bookNameList.push(key);
  67. });
  68. return [bookNameList, bookNameMap];
  69. };
  70. useEffect(() => {
  71. if (typeof keyWord === "undefined") {
  72. return;
  73. }
  74. get<IPageNumberListResponse>(`/v2/search-page-number/${keyWord}`).then(
  75. (json) => {
  76. console.log("case", json);
  77. if (json.ok) {
  78. setPageData(json.data);
  79. const typeCount = new Map<string, number>();
  80. json.data.forEach((value) => {
  81. const old = typeCount.get(value.type);
  82. if (typeof old === "undefined") {
  83. typeCount.set(value.type, 1);
  84. } else {
  85. typeCount.set(value.type, old + 1);
  86. }
  87. });
  88. const mType: IType[] = [];
  89. typeCount.forEach((value, key) => {
  90. mType.push({ key: key, value: value });
  91. });
  92. setTypes(mType);
  93. const tData = mType.map((item, id1) => {
  94. const volumes: number[] = [];
  95. json.data
  96. .filter((value) => value.type === item.key)
  97. .forEach((value) => {
  98. if (!volumes.includes(value.volume)) {
  99. volumes.push(value.volume);
  100. }
  101. });
  102. const keys = volumes
  103. .map((item1) => {
  104. if (item.key === "para") {
  105. return `${item.key}${keyWord}`;
  106. } else {
  107. return `${item.key}${item1}.` + pageNumberToStr(keyWord);
  108. }
  109. })
  110. .join();
  111. const [bookNameList, bookNameMap] = booksTitle(item.key);
  112. return {
  113. title: (
  114. <Space>
  115. {intl.formatMessage({
  116. id: `labels.page.number.type.${item.key}`,
  117. })}
  118. <Badge
  119. size="small"
  120. status="default"
  121. color={"lime"}
  122. count={item.value}
  123. overflowCount={999}
  124. />
  125. </Space>
  126. ),
  127. key: `${id1}-${keys}-0`,
  128. children: bookNameList
  129. .map((bookItem, id2) => {
  130. const bookId = bookNameMap.get(bookItem);
  131. const bookChildren = json.data.filter(
  132. (value) =>
  133. value.type === item.key &&
  134. bookId?.includes(value.pcd_book_id)
  135. );
  136. const pcdBookId: number[] = [];
  137. bookChildren.forEach((value) => {
  138. if (!pcdBookId.includes(value.pcd_book_id)) {
  139. pcdBookId.push(value.pcd_book_id);
  140. }
  141. });
  142. return {
  143. title: bookItem + `[${bookChildren.length}]`,
  144. key: `${id1}_${id2}-${keys}-${pcdBookId.join()}`,
  145. children: bookChildren.map((item1, id3) => {
  146. return {
  147. title: `${item1.type}-${item1.volume}-${item1.page}-${item1.book}-${item1.paragraph}`,
  148. key: `${id1}-${id2}-${id3}-${item1.type}-${item1.volume}-${item1.page}-${item1.book}-${item1.paragraph}`,
  149. disabled: true,
  150. };
  151. }),
  152. };
  153. })
  154. .filter((value) => !value.title.includes("[0]"))
  155. .sort((a, b) => {
  156. const nameA = a.title?.toLowerCase(); // ignore upper and lowercase
  157. const nameB = b.title?.toLowerCase(); // ignore upper and lowercase
  158. if (!nameA || !nameB) {
  159. return 0;
  160. }
  161. if (nameA < nameB) {
  162. return -1;
  163. }
  164. if (nameA > nameB) {
  165. return 1;
  166. }
  167. // names must be equal
  168. return 0;
  169. }),
  170. };
  171. });
  172. setTreeData(tData);
  173. }
  174. }
  175. );
  176. }, [intl, keyWord]);
  177. const pageNumberToStr = (page: number | string): string => {
  178. const strPage = page.toString();
  179. const zero = 4 - strPage.length;
  180. return Array(zero).fill("0").join("") + strPage;
  181. };
  182. return (
  183. <div style={{ padding: 4 }}>
  184. <Card
  185. size="small"
  186. title={
  187. <Select
  188. value={"all"}
  189. bordered={false}
  190. onChange={(_value: string) => {}}
  191. options={types?.map((item, _id) => {
  192. return {
  193. label: (
  194. <Space>
  195. {item.key}
  196. <Badge
  197. count={item.value}
  198. color={"lime"}
  199. status="default"
  200. size="small"
  201. />
  202. </Space>
  203. ),
  204. value: item.key,
  205. };
  206. })}
  207. />
  208. }
  209. >
  210. <Tree
  211. onSelect={(selectedKeys: Key[]) => {
  212. if (typeof onSelect !== "undefined") {
  213. onSelect(selectedKeys);
  214. }
  215. }}
  216. treeData={treeData}
  217. />
  218. </Card>
  219. </div>
  220. );
  221. };
  222. export default CaseListWidget;