Compound.tsx 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. import { List, Select, Typography } from "antd";
  2. import { useEffect, useState } from "react";
  3. import { TeamOutlined, RobotOutlined } from "@ant-design/icons";
  4. import { get } from "../../request";
  5. import type {
  6. IApiResponseDictList,
  7. IDictFirstMeaningResponse,
  8. IFirstMeaning,
  9. } from "../../api/Dict";
  10. const { Text, Link } = Typography;
  11. interface IFactorInfo {
  12. factors: string;
  13. type: string;
  14. confidence: number;
  15. }
  16. interface IOptions {
  17. value: string;
  18. label: React.ReactNode;
  19. }
  20. interface IWidget {
  21. word?: string;
  22. add?: string;
  23. split?: string;
  24. onSearch?: Function;
  25. }
  26. const CompoundWidget = ({ word, add, onSearch }: IWidget) => {
  27. const [compound, setCompound] = useState<IOptions[]>([]);
  28. const [factors, setFactors] = useState<IOptions[]>([]);
  29. const [meaningData, setMeaningData] = useState<IFirstMeaning[]>();
  30. const [currValue, setCurrValue] = useState<string>();
  31. const onSelectChange = (value?: string) => {
  32. console.log("selected", value);
  33. setCurrValue(value);
  34. if (typeof value === "undefined") {
  35. setMeaningData(undefined);
  36. } else {
  37. const url =
  38. `/v2/dict-meaning?lang=zh-Hans&word=` + value.replaceAll("+", "-");
  39. console.info("dict compound url", url);
  40. get<IDictFirstMeaningResponse>(url).then((json) => {
  41. if (json.ok) {
  42. setMeaningData(json.data);
  43. }
  44. });
  45. }
  46. };
  47. useEffect(() => {
  48. console.debug("compound changed", add, compound);
  49. if (typeof add === "undefined") {
  50. setFactors(compound);
  51. const value = compound.length > 0 ? compound[0].value : undefined;
  52. setCurrValue(value);
  53. onSelectChange(value);
  54. } else {
  55. setFactors([{ value: add, label: add }, ...compound]);
  56. setCurrValue(add);
  57. onSelectChange(add);
  58. }
  59. }, [add, compound]);
  60. useEffect(() => {
  61. setMeaningData([]);
  62. setFactors([]);
  63. if (typeof word === "undefined") {
  64. return;
  65. }
  66. const url = `/v2/userdict?view=word&word=${word}`;
  67. console.info("dict compound url", url);
  68. get<IApiResponseDictList>(url).then((json) => {
  69. if (json.ok) {
  70. const factors = new Map<string, IFactorInfo>();
  71. json.data.rows
  72. .filter((value) => typeof value.factors === "string")
  73. .forEach((value) => {
  74. let type = "";
  75. if (value.source?.includes("_USER")) {
  76. type = "user";
  77. }
  78. if (value.type === ".cp.") {
  79. type = "robot";
  80. }
  81. if (value.factors) {
  82. factors.set(value.factors, {
  83. factors: value.factors,
  84. type: type,
  85. confidence: value.confidence,
  86. });
  87. }
  88. });
  89. const arrFactors: IFactorInfo[] = [];
  90. factors.forEach((value) => {
  91. arrFactors.push(value);
  92. });
  93. arrFactors.sort((a, b) => b.confidence - a.confidence);
  94. setCompound(
  95. arrFactors.map((item) => {
  96. return {
  97. value: item.factors,
  98. label: (
  99. <div
  100. style={{
  101. display: "flex",
  102. justifyContent: "space-between",
  103. }}
  104. >
  105. {item.factors}
  106. {item.type === "user" ? (
  107. <TeamOutlined />
  108. ) : item.type === "robot" ? (
  109. <RobotOutlined />
  110. ) : (
  111. <></>
  112. )}
  113. </div>
  114. ),
  115. };
  116. })
  117. );
  118. }
  119. });
  120. }, [word]);
  121. return (
  122. <div
  123. className="dict_compound_div"
  124. style={{
  125. width: "100%",
  126. maxWidth: 560,
  127. marginLeft: "auto",
  128. marginRight: "auto",
  129. }}
  130. >
  131. <Select
  132. getPopupContainer={(_node: HTMLElement) =>
  133. document.getElementsByClassName("dict_compound_div")[0] as HTMLElement
  134. }
  135. value={currValue}
  136. style={{ width: "100%" }}
  137. onChange={onSelectChange}
  138. options={factors}
  139. />
  140. {meaningData && meaningData.length > 0 ? (
  141. <List
  142. size="small"
  143. dataSource={meaningData}
  144. renderItem={(item) => (
  145. <List.Item>
  146. <div>
  147. <Link
  148. strong
  149. onClick={() => {
  150. if (typeof onSearch !== "undefined") {
  151. onSearch(item.word, true);
  152. }
  153. }}
  154. >
  155. {item.word}
  156. </Link>{" "}
  157. <Text type="secondary">{item.meaning}</Text>
  158. </div>
  159. </List.Item>
  160. )}
  161. />
  162. ) : undefined}
  163. </div>
  164. );
  165. };
  166. export default CompoundWidget;