FtsBookList.tsx 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. import { Badge, Card, Space, Tree, Typography } from "antd";
  2. import { useEffect, useState } from "react";
  3. import { get } from "../../request";
  4. import type { Key } from "antd/es/table/interface";
  5. import type { DataNode } from "antd/es/tree";
  6. import type { ISearchView } from "./FullTextSearchResult";
  7. import type { ITag } from "../../api/Tag";
  8. const { Text } = Typography;
  9. export interface IFtsData {
  10. book: number;
  11. paragraph: number;
  12. title?: string;
  13. paliTitle: string;
  14. pcdBookId: number;
  15. count: number;
  16. tags?: ITag[];
  17. }
  18. export interface IFtsResponse {
  19. ok: boolean;
  20. string: string;
  21. data: {
  22. rows: IFtsData[];
  23. count: number;
  24. };
  25. }
  26. interface IWidget {
  27. keyWord?: string;
  28. keyWords?: string[];
  29. engin?: "wbw" | "tulip";
  30. tags?: string[];
  31. bookId?: string | null;
  32. book?: number;
  33. para?: number;
  34. match?: string | null;
  35. keyWord2?: string;
  36. view?: ISearchView;
  37. onSelect?: Function;
  38. }
  39. const FtsBookListWidget = ({
  40. keyWord,
  41. keyWords,
  42. ___engin = "wbw",
  43. tags,
  44. bookId,
  45. ___book,
  46. ___para,
  47. ___keyWord2,
  48. match,
  49. view = "pali",
  50. onSelect,
  51. }: IWidget) => {
  52. const [treeData, setTreeData] = useState<DataNode[]>();
  53. const [total, setTotal] = useState<number>();
  54. const [checkedKeys, setCheckedKeys] = useState<
  55. | {
  56. checked: Key[];
  57. halfChecked: Key[];
  58. }
  59. | Key[]
  60. >([0]);
  61. const [selectedKeys, setSelectedKeys] = useState<React.Key[]>([]);
  62. const [expandedKeys, setExpandedKeys] = useState<React.Key[]>(["all"]);
  63. const focusBooks = bookId?.split(",");
  64. console.log("focusBooks", focusBooks);
  65. useEffect(() => {
  66. const currBooks = bookId?.split(",").map((item) => parseInt(item));
  67. if (currBooks) {
  68. console.log("currBooks", currBooks);
  69. setCheckedKeys(currBooks);
  70. setSelectedKeys(currBooks);
  71. setExpandedKeys(["all"]);
  72. }
  73. }, [bookId, treeData]);
  74. useEffect(() => {
  75. let words;
  76. let api = "";
  77. if (keyWord?.trim().includes(" ")) {
  78. api = "search-book-list";
  79. words = keyWord;
  80. } else {
  81. api = "search-pali-wbw-books";
  82. words = keyWords?.join();
  83. }
  84. let url = `/v2/${api}?view=${view}&key=${words}`;
  85. if (typeof tags !== "undefined") {
  86. url += `&tags=${tags}`;
  87. }
  88. if (match) {
  89. url += `&match=${match}`;
  90. }
  91. console.info("api request", url);
  92. get<IFtsResponse>(url).then((json) => {
  93. console.info("api response", json);
  94. if (json.ok) {
  95. console.log("data", json.data.rows);
  96. let totalResult = 0;
  97. for (const iterator of json.data.rows) {
  98. totalResult += iterator.count;
  99. }
  100. setTreeData([
  101. {
  102. key: "all",
  103. title: "all " + totalResult + "个结果",
  104. children: json.data.rows.map((item, id) => {
  105. const title = item.title ? item.title : item.paliTitle;
  106. return {
  107. key: item.pcdBookId,
  108. title: (
  109. <Space>
  110. <Text
  111. style={{ whiteSpace: "nowrap", width: 200 }}
  112. ellipsis={{ tooltip: { title } }}
  113. >
  114. {id + 1}.{title}
  115. </Text>
  116. <Badge size="small" color="geekblue" count={item.count} />
  117. </Space>
  118. ),
  119. };
  120. }),
  121. },
  122. ]);
  123. setTotal(json.data.count);
  124. }
  125. });
  126. }, [keyWord, keyWords, match, tags, view]);
  127. const onExpand = (expandedKeysValue: React.Key[]) => {
  128. console.log("onExpand", expandedKeysValue);
  129. // if not set autoExpandParent to false, if children expanded, parent can not collapse.
  130. // or, you can remove all expanded children keys.
  131. setExpandedKeys(expandedKeysValue);
  132. };
  133. const onCheck = (
  134. checked:
  135. | {
  136. checked: Key[];
  137. halfChecked: Key[];
  138. }
  139. | Key[]
  140. ) => {
  141. console.log("onCheck", checked);
  142. setCheckedKeys(checked);
  143. if (typeof onSelect !== "undefined") {
  144. onSelect(checked.toString());
  145. }
  146. };
  147. return (
  148. <div style={{ padding: 4 }}>
  149. <Card
  150. size="small"
  151. title={
  152. <Space>
  153. {"总计"}
  154. <Badge
  155. size="small"
  156. count={total}
  157. overflowCount={999}
  158. color="lime"
  159. />
  160. {"本书"}
  161. </Space>
  162. }
  163. >
  164. <Tree
  165. checkable
  166. defaultExpandAll
  167. onExpand={onExpand}
  168. onCheck={onCheck}
  169. checkedKeys={checkedKeys}
  170. expandedKeys={expandedKeys}
  171. onSelect={(selectedKeysValue: React.Key[], _info: any) => {
  172. console.log("onSelect", selectedKeysValue);
  173. setSelectedKeys(selectedKeysValue);
  174. setCheckedKeys(selectedKeysValue);
  175. if (typeof onSelect !== "undefined") {
  176. if (selectedKeysValue.length > 0) {
  177. if (selectedKeysValue[0] === "all") {
  178. onSelect(0);
  179. } else {
  180. onSelect(selectedKeysValue[0]);
  181. }
  182. }
  183. }
  184. }}
  185. selectedKeys={selectedKeys}
  186. treeData={treeData}
  187. />
  188. </Card>
  189. </div>
  190. );
  191. };
  192. export default FtsBookListWidget;