CaseList.tsx 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. import { Badge, Button, Card, Checkbox, Select, Space, Typography } from "antd";
  2. import { DownOutlined, UpOutlined } from "@ant-design/icons";
  3. import { useEffect, useState } from "react";
  4. import { get } from "../../request";
  5. import type { ICaseItem, ICaseListResponse } from "../../api/Dict";
  6. import { CheckboxValueType } from "antd/lib/checkbox/Group";
  7. import type { CheckboxChangeEvent } from "antd/es/checkbox";
  8. const { Text } = Typography;
  9. interface IWidget {
  10. word?: string;
  11. lines?: number;
  12. onChange?: (checkedList: string[]) => void;
  13. }
  14. const CaseListWidget = ({ word, lines, onChange }: IWidget) => {
  15. const [caseData, setCaseData] = useState<ICaseListData[]>();
  16. const [showAll, setShowAll] = useState(lines ? false : true);
  17. const [words, setWords] = useState<ICaseItem[]>();
  18. const [currWord, setCurrWord] = useState<string>();
  19. const [checkedList, setCheckedList] = useState<string[]>([]);
  20. useEffect(() => {
  21. setCaseData(
  22. words
  23. ?.find((value) => value.word === currWord)
  24. ?.case.sort((a, b) => b.count - a.count)
  25. );
  26. }, [currWord, words]);
  27. useEffect(() => {
  28. if (typeof onChange !== "undefined" && checkedList.length > 0) {
  29. onChange(checkedList);
  30. }
  31. }, [checkedList]);
  32. useEffect(() => {
  33. if (caseData) {
  34. setCheckedList(caseData?.map((item) => item.word));
  35. } else {
  36. setCheckedList([]);
  37. }
  38. }, [caseData]);
  39. useEffect(() => {
  40. /**
  41. * 搜索变格
  42. * 如果 keyWord 包涵空格 不搜索
  43. */
  44. if (typeof word === "undefined") {
  45. return;
  46. }
  47. if (word?.trim().includes(" ")) {
  48. setWords([]);
  49. setCurrWord(undefined);
  50. return;
  51. }
  52. get<ICaseListResponse>(`/v2/case/${word}`).then((json) => {
  53. console.log("case", json);
  54. if (json.ok && json.data.rows.length > 0) {
  55. setWords(json.data.rows);
  56. const first = json.data.rows.sort((a, b) => b.count - a.count)[0];
  57. setCurrWord(first.word);
  58. }
  59. });
  60. }, [word]);
  61. let checkAll = true;
  62. let indeterminate = false;
  63. if (caseData && checkedList) {
  64. checkAll = caseData?.length === checkedList?.length;
  65. indeterminate =
  66. checkedList.length > 0 && checkedList.length < caseData.length;
  67. }
  68. const onWordChange = (list: CheckboxValueType[]) => {
  69. setCheckedList(list.map((item) => item.toString()));
  70. };
  71. const onCheckAllChange = (e: CheckboxChangeEvent) => {
  72. if (caseData) {
  73. setCheckedList(
  74. e.target.checked ? caseData?.map((item) => item.word) : []
  75. );
  76. } else {
  77. setCheckedList([]);
  78. }
  79. };
  80. const showWords = showAll ? caseData : caseData?.slice(0, lines);
  81. return (
  82. <div style={{ padding: 4 }}>
  83. {currWord ? (
  84. <Card
  85. size="small"
  86. extra={
  87. lines ? (
  88. <Button type="link" onClick={() => setShowAll(!showAll)}>
  89. {showAll ? (
  90. <Space>
  91. {"折叠"}
  92. <UpOutlined />
  93. </Space>
  94. ) : (
  95. <Space>
  96. {"展开"}
  97. <DownOutlined />
  98. </Space>
  99. )}
  100. </Button>
  101. ) : (
  102. <></>
  103. )
  104. }
  105. title={
  106. <Select
  107. value={currWord}
  108. bordered={false}
  109. onChange={(value: string) => {
  110. setCurrWord(value);
  111. }}
  112. options={words?.map((item, _id) => {
  113. return {
  114. label: (
  115. <Space>
  116. {item.word}
  117. <Badge
  118. count={item.count}
  119. color={"lime"}
  120. status="default"
  121. size="small"
  122. />
  123. </Space>
  124. ),
  125. value: item.word,
  126. };
  127. })}
  128. />
  129. }
  130. >
  131. <Checkbox
  132. indeterminate={indeterminate}
  133. onChange={onCheckAllChange}
  134. checked={checkAll}
  135. >
  136. Check all
  137. </Checkbox>
  138. <Checkbox.Group
  139. style={{ display: "grid" }}
  140. options={showWords?.map((item, _id) => {
  141. return {
  142. label: (
  143. <Space>
  144. <Text strong={item.bold > 0 ? true : false}>
  145. {item.word}
  146. </Text>
  147. <Badge
  148. size="small"
  149. count={item.count}
  150. overflowCount={9999}
  151. status="default"
  152. />
  153. </Space>
  154. ),
  155. value: item.word,
  156. };
  157. })}
  158. value={checkedList}
  159. onChange={onWordChange}
  160. />
  161. </Card>
  162. ) : (
  163. <Text>多词搜索没有变格词表</Text>
  164. )}
  165. </div>
  166. );
  167. };
  168. export default CaseListWidget;