index.tsx 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. import {
  2. PlusOutlined,
  3. } from "@ant-design/icons";
  4. import {
  5. ProConfigProvider,
  6. ProLayout,
  7. } from "@ant-design/pro-components";
  8. import { css } from "@emotion/css";
  9. import {
  10. Space,
  11. Button,
  12. ConfigProvider,
  13. Popover,
  14. } from "antd";
  15. import React, { useMemo, useRef, useState } from "react";
  16. import logo from "@/assets/logo.png";
  17. import { Icon } from "umi";
  18. import { createNew } from "@/utils";
  19. import All from "./All";
  20. import Recently from "./Recently";
  21. import Collect from "./Collect";
  22. import Template from "./Template";
  23. import { GraphType } from "@/enum";
  24. export default () => {
  25. const currentFolder = useRef('root');
  26. const basicGraph = [
  27. {
  28. id: "1",
  29. title: "流程图",
  30. subtitle: "图形化表单方式",
  31. color: "#dfecff",
  32. icon: <Icon icon="local:flow" />,
  33. onClick: () => createNew(GraphType.flowchart, currentFolder.current),
  34. },
  35. {
  36. id: "2",
  37. title: "思维导图",
  38. subtitle: "结构化表单方式",
  39. color: "#dff4ea",
  40. icon: <Icon icon="local:mind" />,
  41. onClick: () => createNew(GraphType.mindmap, currentFolder.current),
  42. },
  43. ];
  44. const appList = [
  45. {
  46. id: "1",
  47. title: "UML",
  48. icon: <Icon icon="local:uml" />,
  49. onClick: () => createNew(GraphType.uml, currentFolder.current),
  50. },
  51. {
  52. id: "2",
  53. title: "E-R图",
  54. icon: <Icon icon="local:er" />,
  55. onClick: () => createNew(GraphType.er, currentFolder.current),
  56. },
  57. {
  58. id: "3",
  59. title: "泳道图",
  60. icon: <Icon icon="local:swimlane" />,
  61. onClick: () => createNew(GraphType.lane, currentFolder.current),
  62. },
  63. {
  64. id: "4",
  65. title: "BPMN",
  66. icon: <Icon icon="local:bpmn" />,
  67. onClick: () => createNew(GraphType.bpmn, currentFolder.current),
  68. },
  69. {
  70. id: "5",
  71. title: "韦恩图",
  72. icon: <Icon icon="local:we" />,
  73. onClick: () => createNew(GraphType.venn, currentFolder.current),
  74. },
  75. {
  76. id: "6",
  77. title: "网络拓扑图",
  78. icon: <Icon icon="local:net" />,
  79. onClick: () => createNew(GraphType.net, currentFolder.current),
  80. },
  81. ];
  82. const handleMenuClick = (item: any) => {
  83. console.log("click", item);
  84. item?.onClick?.();
  85. };
  86. const renderBasicItem = (props: {
  87. title: string;
  88. subtitle: string;
  89. color: string;
  90. id: string;
  91. icon: React.ReactNode;
  92. }) => {
  93. return (
  94. <div
  95. key={props.id}
  96. className={css`
  97. width: 136px;
  98. height: 60px;
  99. padding: 8px;
  100. border-radius: 8px;
  101. display: flex;
  102. align-items: center;
  103. cursor: pointer;
  104. margin-top: 8px;
  105. background: ${props.color + "70"};
  106. &:hover {
  107. background: ${props.color};
  108. }
  109. `}
  110. onClick={() => handleMenuClick(props)}
  111. >
  112. <span className="w-32px h-33px">{props.icon}</span>
  113. <div className="flex flex-col justify-center ml-4px">
  114. <div className="text-14px">{props.title}</div>
  115. <div className="text-12px text-#9aa5b8">{props.subtitle}</div>
  116. </div>
  117. </div>
  118. );
  119. };
  120. const renderProItem = (props: {
  121. id: string;
  122. title: string;
  123. icon: React.ReactNode;
  124. }) => {
  125. return (
  126. <div
  127. key={props.id}
  128. className="w-66px h-70px flex flex-col items-center justify-center mt-8px rounded-lg hover:bg-#f3f5f9 cursor-pointer"
  129. onClick={() => handleMenuClick(props)}
  130. >
  131. {props.icon}
  132. <span className="text-12px">{props.title}</span>
  133. </div>
  134. );
  135. };
  136. const RenderAppList = () => {
  137. return (
  138. <div className="w-460px">
  139. <div className="color-#6c7d8f text-xs">基础图形</div>
  140. <Space>{basicGraph.map((item) => renderBasicItem(item))}</Space>
  141. <div className="color-#6c7d8f text-xs mt-8px">专业图形</div>
  142. <Space>{appList.map((item) => renderProItem(item))}</Space>
  143. </div>
  144. );
  145. };
  146. const handleChangeFolder = (id: string) => {
  147. currentFolder.current = id;
  148. }
  149. const [pathname, setPathname] = useState("/all");
  150. const routes = [
  151. {
  152. path: "/all",
  153. name: "全部",
  154. icon: <i className="iconfont icon-xitong" />,
  155. component: <All onChangeCurrentFolder={ handleChangeFolder }/>,
  156. },
  157. {
  158. path: "/recently",
  159. name: "最近项目",
  160. icon: <i className="iconfont icon-shijian" />,
  161. component: <Recently />,
  162. },
  163. {
  164. path: "/template",
  165. name: "我的模版",
  166. icon: <i className="iconfont icon-yingyong" />,
  167. component: <Template />,
  168. },
  169. {
  170. path: "/collect",
  171. name: "模版收藏",
  172. icon: <i className="iconfont icon-xihuan" />,
  173. component: <Collect />,
  174. },
  175. ];
  176. const content = useMemo(() => {
  177. currentFolder.current = "root";
  178. return routes.find((item) => item.path === pathname)?.component;
  179. }, [pathname]);
  180. return (
  181. <div
  182. id="test-pro-layout"
  183. style={{
  184. height: "100vh",
  185. overflow: "auto",
  186. }}
  187. >
  188. <ProLayout
  189. headerTitleRender={() => null}
  190. logo={logo}
  191. title={"系统设计"}
  192. collapsedButtonRender={() => <></>}
  193. location={{ pathname }}
  194. route={{
  195. routes,
  196. }}
  197. bgLayoutImgList={[
  198. {
  199. src: 'https://img.alicdn.com/imgextra/i2/O1CN01O4etvp1DvpFLKfuWq_!!6000000000279-2-tps-609-606.png',
  200. left: 85,
  201. bottom: 100,
  202. height: '303px',
  203. },
  204. {
  205. src: 'https://img.alicdn.com/imgextra/i2/O1CN01O4etvp1DvpFLKfuWq_!!6000000000279-2-tps-609-606.png',
  206. bottom: -68,
  207. right: -45,
  208. height: '303px',
  209. },
  210. {
  211. src: 'https://img.alicdn.com/imgextra/i3/O1CN018NxReL1shX85Yz6Cx_!!6000000005798-2-tps-884-496.png',
  212. bottom: 0,
  213. left: 0,
  214. width: '331px',
  215. },
  216. ]}
  217. menuHeaderRender={(logo, title) => {
  218. return (
  219. <div className="flex-1">
  220. <div className="flex items-center h-20px">
  221. {logo}
  222. {title}
  223. </div>
  224. <div className="mt-32px">
  225. <Popover key="1" placement="left" content={<RenderAppList />}>
  226. <Button
  227. type="primary"
  228. className="w-full"
  229. onClick={() => {}}
  230. icon={<PlusOutlined />}
  231. >
  232. 新建
  233. </Button>
  234. </Popover>
  235. </div>
  236. </div>
  237. );
  238. }}
  239. menuItemRender={(item, dom) => (
  240. <div
  241. onClick={() => {
  242. setPathname(item.path || "/all");
  243. }}
  244. >
  245. {dom}
  246. </div>
  247. )}
  248. >
  249. <ProConfigProvider hashed={false}>
  250. <ConfigProvider
  251. getTargetContainer={() => {
  252. return (
  253. document.getElementById("test-pro-layout") || document.body
  254. );
  255. }}
  256. >
  257. {content}
  258. </ConfigProvider>
  259. </ProConfigProvider>
  260. </ProLayout>
  261. </div>
  262. );
  263. };