index.tsx 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. import React, { useEffect, useRef } from "react";
  2. import { Layout, ConfigProvider, Spin } from "antd";
  3. import styles from "./index.less";
  4. import "./index.less";
  5. import RightToolbar from "./components/RightToolbar";
  6. import HeaderToolbar from "./components/HeaderToolbar";
  7. import { useModel, useRequest, useParams } from "umi";
  8. import Footer from "./components/Footer";
  9. import Config from "./components/Config";
  10. import SvgComponent from "./components/SvgComponent";
  11. import { FlowchartMindMapInfo } from "@/api/systemDesigner";
  12. import { defaultProject, topicData } from "@/config/data";
  13. import { TopicItem } from "@/types";
  14. import { buildTopic } from "./mindMap";
  15. import { TopicType } from "@/enum";
  16. export default function MindMap() {
  17. const { rightToobarActive, initMindMap, setMindProjectInfo } =
  18. useModel("mindMapModel");
  19. const graphRef = useRef<HTMLDivElement>(null);
  20. useEffect(() => {
  21. graphRef.current && initMindMap(graphRef.current);
  22. }, []);
  23. // 获取项目详情
  24. const { loading, run, data } = useRequest(FlowchartMindMapInfo, {
  25. manual: true,
  26. });
  27. const transData = (item: any): TopicItem => {
  28. return {
  29. ...item,
  30. edge: JSON.parse(item.edge),
  31. fill: JSON.parse(item.fill),
  32. links: JSON.parse(item.links),
  33. text: JSON.parse(item.text),
  34. stroke: JSON.parse(item.stroke),
  35. children: JSON.parse(item.children),
  36. ...(item?.extraModules
  37. ? { extraModules: JSON.parse(item.extraModules) }
  38. : {}),
  39. ...(item?.icons ? { icons: JSON.parse(item.icons) } : {}),
  40. ...(item?.tags ? { icons: JSON.parse(item.tags) } : {}),
  41. ...(item?.href ? { icons: JSON.parse(item.href) } : {}),
  42. ...(item?.links ? { icons: JSON.parse(item.links) } : {}),
  43. ...(item?.summary ? { icons: JSON.parse(item.summary) } : {}),
  44. ...(item?.summary ? { icons: JSON.parse(item.summary) } : {}),
  45. };
  46. };
  47. useEffect(() => {
  48. if (!data) return;
  49. const graphInfo = data?.result?.graph || {};
  50. const topics = (data?.result?.elements || []).map((item: any) =>
  51. transData(item)
  52. );
  53. if (!topics.length) {
  54. const mainTopic = buildTopic(TopicType.main, {
  55. label: "中心主题",
  56. fill: {
  57. ...topicData.fill,
  58. color1: "#30304D",
  59. },
  60. text: {
  61. ...topicData.text,
  62. fontSize: 30,
  63. color: "#fff",
  64. },
  65. });
  66. if (mainTopic) {
  67. topics.push(mainTopic);
  68. }
  69. }
  70. setMindProjectInfo({
  71. name: graphInfo.name,
  72. desc: graphInfo?.desc || "",
  73. version: graphInfo.version,
  74. author: graphInfo?.author || "",
  75. theme: graphInfo?.theme || defaultProject.theme,
  76. structure: graphInfo?.structure || defaultProject.structure,
  77. pageSetting: {
  78. backgroundType:
  79. graphInfo?.backgroundType ||
  80. defaultProject.pageSetting.backgroundType,
  81. backgroundColor:
  82. graphInfo?.backgroundColor ||
  83. defaultProject.pageSetting.backgroundColor,
  84. backgroundImage:
  85. graphInfo?.backgroundImage ||
  86. defaultProject.pageSetting.backgroundImage,
  87. branchY: graphInfo?.branchY || defaultProject.pageSetting.branchY,
  88. branchX: graphInfo?.branchX || defaultProject.pageSetting.branchX,
  89. subTopicY: graphInfo?.subTopicY || defaultProject.pageSetting.subTopicY,
  90. subTopicX: graphInfo?.subTopicX || defaultProject.pageSetting.subTopicX,
  91. alignSameTopic:
  92. graphInfo?.alignSameTopic ||
  93. defaultProject.pageSetting.alignSameTopic,
  94. showWatermark:
  95. graphInfo?.showWatermark || defaultProject.pageSetting.showWatermark,
  96. watermarkText:
  97. graphInfo?.watermarkText || defaultProject.pageSetting.watermarkText,
  98. },
  99. topics,
  100. }, true);
  101. }, [data]);
  102. const params = useParams();
  103. useEffect(() => {
  104. if (params?.id) {
  105. run({ id: params.id });
  106. sessionStorage.setItem("projectId", params.id);
  107. }
  108. }, []);
  109. useEffect(() => {
  110. document.addEventListener(
  111. "mousewheel",
  112. function (e: any) {
  113. // 判断是否按下ctrl
  114. if (e.ctrlKey) {
  115. // 阻止默认事件
  116. e.preventDefault();
  117. }
  118. },
  119. { capture: false, passive: false }
  120. );
  121. document.addEventListener(
  122. "keydown",
  123. function (event) {
  124. if (
  125. (event.ctrlKey === true || event.metaKey === true) &&
  126. (event.keyCode === 61 ||
  127. event.keyCode === 107 ||
  128. event.keyCode === 173 ||
  129. event.keyCode === 109 ||
  130. event.keyCode === 187 ||
  131. event.keyCode === 189 ||
  132. event.keyCode === 80)
  133. ) {
  134. event.preventDefault();
  135. }
  136. },
  137. false
  138. );
  139. }, []);
  140. return (
  141. <ConfigProvider
  142. // componentSize="small"
  143. prefixCls="shalu"
  144. theme={{
  145. token: {
  146. colorPrimary: "#1890ff",
  147. },
  148. }}
  149. >
  150. <SvgComponent />
  151. <Spin spinning={loading}>
  152. <Layout className="w-100vw h-100vh">
  153. <Layout.Content className={styles.container + " relative"}>
  154. <div ref={graphRef} className="w-full h-full"></div>
  155. <HeaderToolbar />
  156. <RightToolbar />
  157. <Footer />
  158. </Layout.Content>
  159. <Layout.Sider
  160. className={styles.sider}
  161. width={rightToobarActive ? 280 : 0}
  162. >
  163. <Config />
  164. </Layout.Sider>
  165. </Layout>
  166. </Spin>
  167. </ConfigProvider>
  168. );
  169. }