Term.tsx 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. import { Button, Popover, Skeleton } from "antd";
  2. import { Typography } from "antd";
  3. import { SearchOutlined, EditOutlined } from "@ant-design/icons";
  4. import { ProCard } from "@ant-design/pro-components";
  5. import store from "../../store";
  6. import TermModal from "../term/TermModal";
  7. import { ITerm } from "../term/TermEdit";
  8. import { useEffect, useState } from "react";
  9. import { ITermDataResponse } from "../api/Term";
  10. import { changedTerm, refresh } from "../../reducers/term-change";
  11. import { useAppSelector } from "../../hooks";
  12. import { get } from "../../request";
  13. const { Text, Link } = Typography;
  14. interface ITermSummary {
  15. ok: boolean;
  16. message: string;
  17. data: string;
  18. }
  19. interface IWidgetTermCtl {
  20. id?: string;
  21. word?: string;
  22. meaning?: string;
  23. meaning2?: string;
  24. channel?: string;
  25. parentChannelId?: string;
  26. parentStudioId?: string;
  27. summary?: string;
  28. isCommunity?: string;
  29. }
  30. const TermCtl = ({
  31. id,
  32. word,
  33. meaning,
  34. meaning2,
  35. channel,
  36. parentChannelId,
  37. parentStudioId,
  38. summary,
  39. isCommunity,
  40. }: IWidgetTermCtl) => {
  41. const [openPopover, setOpenPopover] = useState(false);
  42. const [termData, setTermData] = useState<ITerm>();
  43. const [content, setContent] = useState<string>();
  44. const newTerm: ITermDataResponse | undefined = useAppSelector(changedTerm);
  45. useEffect(() => {
  46. setTermData({
  47. id: id,
  48. word: word,
  49. meaning: meaning,
  50. meaning2: meaning2?.split(","),
  51. summary: summary,
  52. channelId: channel,
  53. });
  54. }, []);
  55. useEffect(() => {
  56. if (newTerm?.word === word) {
  57. setTermData({
  58. id: newTerm?.guid,
  59. word: newTerm?.word,
  60. meaning: newTerm?.meaning,
  61. meaning2: newTerm?.other_meaning?.split(","),
  62. summary: newTerm?.note,
  63. channelId: newTerm?.channal,
  64. });
  65. }
  66. }, [newTerm]);
  67. const onModalClose = () => {
  68. if (document.getElementsByTagName("body")[0].hasAttribute("style")) {
  69. document.getElementsByTagName("body")[0].removeAttribute("style");
  70. }
  71. };
  72. if (typeof termData?.id === "string") {
  73. return (
  74. <>
  75. <Popover
  76. open={openPopover}
  77. onOpenChange={(visible) => {
  78. setOpenPopover(visible);
  79. if (
  80. visible &&
  81. typeof content === "undefined" &&
  82. typeof id !== "undefined"
  83. ) {
  84. const value = sessionStorage.getItem(`term/summary/${id}`);
  85. if (value !== null) {
  86. setContent(value);
  87. return;
  88. } else {
  89. const url = `/v2/term-summary/${id}`;
  90. console.log("url", url);
  91. get<ITermSummary>(url).then((json) => {
  92. if (json.ok) {
  93. setContent(json.data !== "" ? json.data : " ");
  94. sessionStorage.setItem(`term/summary/${id}`, json.data);
  95. }
  96. });
  97. }
  98. }
  99. }}
  100. content={
  101. <ProCard
  102. title={word}
  103. style={{ maxWidth: 500, minWidth: 300 }}
  104. actions={[
  105. <Button type="link" size="small" icon={<SearchOutlined />}>
  106. 更多
  107. </Button>,
  108. <Button type="link" size="small" icon={<SearchOutlined />}>
  109. 详情
  110. </Button>,
  111. <TermModal
  112. onUpdate={(value: ITermDataResponse) => {
  113. onModalClose();
  114. store.dispatch(refresh(value));
  115. }}
  116. onClose={() => {
  117. onModalClose();
  118. }}
  119. trigger={
  120. <Button
  121. onClick={() => {
  122. setOpenPopover(false);
  123. }}
  124. type="link"
  125. size="small"
  126. icon={<EditOutlined />}
  127. >
  128. 修改
  129. </Button>
  130. }
  131. id={termData.id}
  132. word={termData.word}
  133. channelId={termData.channelId}
  134. parentChannelId={parentChannelId}
  135. parentStudioId={parentStudioId}
  136. />,
  137. ]}
  138. >
  139. <div>
  140. {content ? (
  141. content
  142. ) : (
  143. <Skeleton
  144. title={{ width: 200 }}
  145. paragraph={{ rows: 4 }}
  146. active
  147. />
  148. )}
  149. </div>
  150. </ProCard>
  151. }
  152. placement="bottom"
  153. >
  154. <Link style={{ color: isCommunity ? "green" : undefined }}>
  155. {termData?.meaning
  156. ? termData?.meaning
  157. : termData?.word
  158. ? termData?.word
  159. : "unknown"}
  160. </Link>
  161. </Popover>
  162. {"("}
  163. <Text italic>{word}</Text>
  164. {termData?.meaning2 ? (
  165. <Text>{`,${termData?.meaning2}`}</Text>
  166. ) : undefined}
  167. {")"}
  168. </>
  169. );
  170. } else {
  171. //术语未创建
  172. return (
  173. <TermModal
  174. onUpdate={(value: ITermDataResponse) => {
  175. onModalClose();
  176. store.dispatch(refresh(value));
  177. }}
  178. onClose={() => {
  179. onModalClose();
  180. }}
  181. trigger={
  182. <Link>
  183. <Text type="danger">{termData?.word}</Text>
  184. </Link>
  185. }
  186. word={word}
  187. channelId={channel}
  188. />
  189. );
  190. }
  191. };
  192. interface IWidgetTerm {
  193. props: string;
  194. }
  195. const Widget = ({ props }: IWidgetTerm) => {
  196. const prop = JSON.parse(atob(props)) as IWidgetTermCtl;
  197. return (
  198. <>
  199. <TermCtl {...prop} />
  200. </>
  201. );
  202. };
  203. export default Widget;