NissayaCardTable.tsx 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. import { Button, Space, Table, Tag, Typography } from "antd";
  2. import lodash from "lodash";
  3. import { ArrowRightOutlined } from "@ant-design/icons";
  4. import Marked from "./Marked";
  5. import GrammarLookup from "../dict/GrammarLookup";
  6. import { useIntl } from "react-intl";
  7. const { Link } = Typography;
  8. const caseTags = [
  9. { case: "fpp", tags: ["verb", "derivative", "passive-verb"] },
  10. { case: "ger", tags: ["verb"] },
  11. { case: "inf", tags: ["verb"] },
  12. { case: "grd", tags: ["verb"] },
  13. { case: "pp", tags: ["verb", "participle"] },
  14. { case: "prp", tags: ["verb", "participle"] },
  15. { case: "v", tags: ["verb"] },
  16. { case: "v:ind", tags: ["verb"] },
  17. { case: "vdn", tags: ["verb", "participle"] },
  18. ];
  19. interface ITags {
  20. tag: string;
  21. count: number;
  22. }
  23. const getCaseTags = (input: string[]): ITags[] => {
  24. const tagsMap = new Map<string, number>();
  25. input.forEach((value: string) => {
  26. const found = caseTags.find((value1) => value1.case === value);
  27. if (found !== undefined) {
  28. found.tags.forEach((value3) => {
  29. const count = tagsMap.get(value3);
  30. if (typeof count === "undefined") {
  31. tagsMap.set(value3, 1);
  32. } else {
  33. tagsMap.set(value3, count + 1);
  34. }
  35. });
  36. }
  37. });
  38. const tags: ITags[] = [];
  39. tagsMap.forEach((value, key, _map) => {
  40. tags.push({ tag: key, count: value });
  41. });
  42. tags.sort((a, b) => b.count - a.count);
  43. return tags;
  44. };
  45. const randomString = () =>
  46. lodash.times(20, () => lodash.random(35).toString(36)).join("");
  47. interface ICaseItem {
  48. label: string;
  49. case: string;
  50. link: string;
  51. }
  52. interface IRelationNode {
  53. case?: ICaseItem[];
  54. spell?: string;
  55. }
  56. interface DataType {
  57. key: string;
  58. relation: string;
  59. localRelation?: string;
  60. tags?: ITags[];
  61. to?: IRelationNode;
  62. from?: IRelationNode;
  63. category?: { name: string; note: string; meaning: string };
  64. translation?: string;
  65. isChildren?: boolean;
  66. children?: DataType[];
  67. }
  68. export interface INissayaRelation {
  69. from?: IRelationNode;
  70. to?: IRelationNode;
  71. category?: { name: string; note: string; meaning: string };
  72. local_ending: string;
  73. relation: string;
  74. local_relation?: string;
  75. relation_link: string;
  76. }
  77. interface IWidget {
  78. data?: INissayaRelation[];
  79. }
  80. const NissayaCardTableWidget = ({ data }: IWidget) => {
  81. const intl = useIntl();
  82. let tableData: DataType[] = [];
  83. if (typeof data === "undefined") {
  84. tableData = [];
  85. } else {
  86. console.log("data", data);
  87. const category: string[] = [];
  88. const newData: DataType[] = [];
  89. data.forEach((item, _index) => {
  90. if (item.category && item.category.name) {
  91. const key = `${item.from?.spell}-${item.from?.case
  92. ?.map((item) => item.label)
  93. .join()}-${item.relation}-${item.category}`;
  94. if (!category.includes(key)) {
  95. category.push(key);
  96. console.log("category", category);
  97. //处理children
  98. const children = data
  99. .filter(
  100. (value) =>
  101. `${value.from?.spell}-${value.from?.case
  102. ?.map((item) => item.label)
  103. .join()}-${value.relation}-${value.category}` === key
  104. )
  105. .map((item, _index) => {
  106. return {
  107. key: randomString(),
  108. relation: item.relation,
  109. localRelation: item.local_relation,
  110. from: item.from,
  111. to: item.to,
  112. category: item.category,
  113. translation: item.local_ending,
  114. isChildren: true,
  115. };
  116. });
  117. console.log("children", children);
  118. const caseList: string[] = [];
  119. children.forEach((value) => {
  120. value.to?.case?.forEach((value1) => {
  121. caseList.push(value1.case);
  122. });
  123. });
  124. const tags = getCaseTags(caseList);
  125. newData.push({
  126. key: randomString(),
  127. relation: item.relation,
  128. localRelation: item.local_relation,
  129. from: item.from,
  130. to: item.to,
  131. tags: tags,
  132. category: item.category,
  133. translation: item.local_ending,
  134. children: children.length > 1 ? [...children] : undefined,
  135. });
  136. }
  137. } else {
  138. newData.push({
  139. key: randomString(),
  140. relation: item.relation,
  141. localRelation: item.local_relation,
  142. from: item.from,
  143. to: item.to,
  144. category: item.category,
  145. translation: item.local_ending,
  146. });
  147. }
  148. });
  149. console.log("newData", newData);
  150. tableData = newData;
  151. }
  152. return (
  153. <Table
  154. size="small"
  155. columns={[
  156. {
  157. title: "本词特征",
  158. dataIndex: "from",
  159. key: "from",
  160. width: "10%",
  161. render: (_value, record, _index) => {
  162. return (
  163. <Space>
  164. {record.from?.case?.map((item, id) => {
  165. return (
  166. <GrammarLookup key={id} word={item.case}>
  167. <Link>
  168. <Tag>{item.label}</Tag>
  169. </Link>
  170. </GrammarLookup>
  171. );
  172. })}
  173. {record.from?.spell}
  174. </Space>
  175. );
  176. },
  177. },
  178. {
  179. title: "关系",
  180. dataIndex: "relation",
  181. key: "relation",
  182. width: "30%",
  183. render: (_value, record, _index) => {
  184. return (
  185. <Space orientation="vertical">
  186. <GrammarLookup word={record.relation}>
  187. <Link>{record.relation}</Link>
  188. </GrammarLookup>
  189. <div>{record.localRelation}</div>
  190. </Space>
  191. );
  192. },
  193. },
  194. {
  195. title: "目标词特征",
  196. dataIndex: "to",
  197. key: "to",
  198. width: "20%",
  199. render: (_value, record, _index) => {
  200. if (record.isChildren) {
  201. return (
  202. <Space>
  203. <ArrowRightOutlined />
  204. {record.to?.case?.map((item, id) => {
  205. return (
  206. <Button
  207. key={id}
  208. type="link"
  209. size="small"
  210. onClick={() => window.open(item.link, "_blank")}
  211. >
  212. <Tag key={id}>{item.label}</Tag>
  213. </Button>
  214. );
  215. })}
  216. {record.to?.spell}
  217. </Space>
  218. );
  219. } else {
  220. return (
  221. <Space>
  222. <ArrowRightOutlined />
  223. {record.tags?.map((item, id) => {
  224. return (
  225. <Tag key={id}>
  226. {intl.formatMessage({
  227. id: `dict.case.category.${item.tag}`,
  228. })}
  229. </Tag>
  230. );
  231. })}
  232. </Space>
  233. );
  234. }
  235. },
  236. },
  237. {
  238. title: "语法点",
  239. dataIndex: "to",
  240. key: "grammar",
  241. width: "20%",
  242. render: (_value, record, _index) => {
  243. if (!record.isChildren) {
  244. return (
  245. <GrammarLookup word={record.category?.name}>
  246. <Link>{record.category?.meaning}</Link>
  247. </GrammarLookup>
  248. );
  249. }
  250. },
  251. },
  252. {
  253. title: "含义",
  254. dataIndex: "address",
  255. width: "40%",
  256. key: "address",
  257. render: (_value, record, _index) => {
  258. if (record.isChildren) {
  259. return undefined;
  260. } else {
  261. return (
  262. <div>
  263. <Marked text={record.category?.note} />
  264. <div>{record.translation}</div>
  265. </div>
  266. );
  267. }
  268. },
  269. },
  270. ]}
  271. dataSource={tableData}
  272. />
  273. );
  274. };
  275. export default NissayaCardTableWidget;