fangmingyue 1 year ago
parent
commit
7de543bc1d

+ 1
- 0
jsconfig.json View File

@@ -7,6 +7,7 @@
7 7
     "paths": {
8 8
       "@/components/*": ["src/components/*"],
9 9
       "@/layouts/*": ["src/layouts/*"],
10
+      "@/data/*": ["src/data/*"],
10 11
       "@/services/*": ["src/services/*"],
11 12
       "@/utils/*": ["src/utils/*"]
12 13
     }

+ 182
- 0
package-lock.json View File

@@ -15,8 +15,12 @@
15 15
         "@types/react-dom": "^18.2.18",
16 16
         "astro": "^4.1.3",
17 17
         "axios": "^1.6.5",
18
+        "classnames": "^2.5.1",
18 19
         "react": "^18.2.0",
19 20
         "react-dom": "^18.2.0"
21
+      },
22
+      "devDependencies": {
23
+        "less": "^4.2.0"
20 24
       }
21 25
     },
22 26
     "node_modules/@ampproject/remapping": {
@@ -1713,6 +1717,11 @@
1713 1717
         "node": ">=8"
1714 1718
       }
1715 1719
     },
1720
+    "node_modules/classnames": {
1721
+      "version": "2.5.1",
1722
+      "resolved": "https://registry.npmmirror.com/classnames/-/classnames-2.5.1.tgz",
1723
+      "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow=="
1724
+    },
1716 1725
     "node_modules/cli-boxes": {
1717 1726
       "version": "3.0.0",
1718 1727
       "resolved": "https://registry.npmmirror.com/cli-boxes/-/cli-boxes-3.0.0.tgz",
@@ -1836,6 +1845,15 @@
1836 1845
         "node": ">= 0.6"
1837 1846
       }
1838 1847
     },
1848
+    "node_modules/copy-anything": {
1849
+      "version": "2.0.6",
1850
+      "resolved": "https://registry.npmmirror.com/copy-anything/-/copy-anything-2.0.6.tgz",
1851
+      "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==",
1852
+      "devOptional": true,
1853
+      "dependencies": {
1854
+        "is-what": "^3.14.1"
1855
+      }
1856
+    },
1839 1857
     "node_modules/cross-spawn": {
1840 1858
       "version": "7.0.3",
1841 1859
       "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -2042,6 +2060,19 @@
2042 2060
         "node": ">=0.12"
2043 2061
       }
2044 2062
     },
2063
+    "node_modules/errno": {
2064
+      "version": "0.1.8",
2065
+      "resolved": "https://registry.npmmirror.com/errno/-/errno-0.1.8.tgz",
2066
+      "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
2067
+      "dev": true,
2068
+      "optional": true,
2069
+      "dependencies": {
2070
+        "prr": "~1.0.1"
2071
+      },
2072
+      "bin": {
2073
+        "errno": "cli.js"
2074
+      }
2075
+    },
2045 2076
     "node_modules/es-module-lexer": {
2046 2077
       "version": "1.5.0",
2047 2078
       "resolved": "https://registry.npmmirror.com/es-module-lexer/-/es-module-lexer-1.5.0.tgz",
@@ -2587,11 +2618,37 @@
2587 2618
         "node": ">=16.17.0"
2588 2619
       }
2589 2620
     },
2621
+    "node_modules/iconv-lite": {
2622
+      "version": "0.6.3",
2623
+      "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz",
2624
+      "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
2625
+      "dev": true,
2626
+      "optional": true,
2627
+      "dependencies": {
2628
+        "safer-buffer": ">= 2.1.2 < 3.0.0"
2629
+      },
2630
+      "engines": {
2631
+        "node": ">=0.10.0"
2632
+      }
2633
+    },
2590 2634
     "node_modules/ieee754": {
2591 2635
       "version": "1.2.1",
2592 2636
       "resolved": "https://registry.npmmirror.com/ieee754/-/ieee754-1.2.1.tgz",
2593 2637
       "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
2594 2638
     },
2639
+    "node_modules/image-size": {
2640
+      "version": "0.5.5",
2641
+      "resolved": "https://registry.npmmirror.com/image-size/-/image-size-0.5.5.tgz",
2642
+      "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==",
2643
+      "dev": true,
2644
+      "optional": true,
2645
+      "bin": {
2646
+        "image-size": "bin/image-size.js"
2647
+      },
2648
+      "engines": {
2649
+        "node": ">=0.10.0"
2650
+      }
2651
+    },
2595 2652
     "node_modules/import-meta-resolve": {
2596 2653
       "version": "4.0.0",
2597 2654
       "resolved": "https://registry.npmmirror.com/import-meta-resolve/-/import-meta-resolve-4.0.0.tgz",
@@ -2741,6 +2798,12 @@
2741 2798
         "node": ">=12"
2742 2799
       }
2743 2800
     },
2801
+    "node_modules/is-what": {
2802
+      "version": "3.14.1",
2803
+      "resolved": "https://registry.npmmirror.com/is-what/-/is-what-3.14.1.tgz",
2804
+      "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==",
2805
+      "devOptional": true
2806
+    },
2744 2807
     "node_modules/is-wsl": {
2745 2808
       "version": "3.1.0",
2746 2809
       "resolved": "https://registry.npmmirror.com/is-wsl/-/is-wsl-3.1.0.tgz",
@@ -2811,6 +2874,45 @@
2811 2874
         "node": ">=6"
2812 2875
       }
2813 2876
     },
2877
+    "node_modules/less": {
2878
+      "version": "4.2.0",
2879
+      "resolved": "https://registry.npmmirror.com/less/-/less-4.2.0.tgz",
2880
+      "integrity": "sha512-P3b3HJDBtSzsXUl0im2L7gTO5Ubg8mEN6G8qoTS77iXxXX4Hvu4Qj540PZDvQ8V6DmX6iXo98k7Md0Cm1PrLaA==",
2881
+      "devOptional": true,
2882
+      "dependencies": {
2883
+        "copy-anything": "^2.0.1",
2884
+        "parse-node-version": "^1.0.1",
2885
+        "tslib": "^2.3.0"
2886
+      },
2887
+      "bin": {
2888
+        "lessc": "bin/lessc"
2889
+      },
2890
+      "engines": {
2891
+        "node": ">=6"
2892
+      },
2893
+      "optionalDependencies": {
2894
+        "errno": "^0.1.1",
2895
+        "graceful-fs": "^4.1.2",
2896
+        "image-size": "~0.5.0",
2897
+        "make-dir": "^2.1.0",
2898
+        "mime": "^1.4.1",
2899
+        "needle": "^3.1.0",
2900
+        "source-map": "~0.6.0"
2901
+      }
2902
+    },
2903
+    "node_modules/less/node_modules/mime": {
2904
+      "version": "1.6.0",
2905
+      "resolved": "https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz",
2906
+      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
2907
+      "dev": true,
2908
+      "optional": true,
2909
+      "bin": {
2910
+        "mime": "cli.js"
2911
+      },
2912
+      "engines": {
2913
+        "node": ">=4"
2914
+      }
2915
+    },
2814 2916
     "node_modules/load-yaml-file": {
2815 2917
       "version": "0.2.0",
2816 2918
       "resolved": "https://registry.npmmirror.com/load-yaml-file/-/load-yaml-file-0.2.0.tgz",
@@ -2911,6 +3013,30 @@
2911 3013
         "node": ">=12"
2912 3014
       }
2913 3015
     },
3016
+    "node_modules/make-dir": {
3017
+      "version": "2.1.0",
3018
+      "resolved": "https://registry.npmmirror.com/make-dir/-/make-dir-2.1.0.tgz",
3019
+      "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
3020
+      "dev": true,
3021
+      "optional": true,
3022
+      "dependencies": {
3023
+        "pify": "^4.0.1",
3024
+        "semver": "^5.6.0"
3025
+      },
3026
+      "engines": {
3027
+        "node": ">=6"
3028
+      }
3029
+    },
3030
+    "node_modules/make-dir/node_modules/semver": {
3031
+      "version": "5.7.2",
3032
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-5.7.2.tgz",
3033
+      "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
3034
+      "dev": true,
3035
+      "optional": true,
3036
+      "bin": {
3037
+        "semver": "bin/semver"
3038
+      }
3039
+    },
2914 3040
     "node_modules/markdown-table": {
2915 3041
       "version": "3.0.3",
2916 3042
       "resolved": "https://registry.npmmirror.com/markdown-table/-/markdown-table-3.0.3.tgz",
@@ -3486,6 +3612,23 @@
3486 3612
       "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==",
3487 3613
       "optional": true
3488 3614
     },
3615
+    "node_modules/needle": {
3616
+      "version": "3.3.1",
3617
+      "resolved": "https://registry.npmmirror.com/needle/-/needle-3.3.1.tgz",
3618
+      "integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==",
3619
+      "dev": true,
3620
+      "optional": true,
3621
+      "dependencies": {
3622
+        "iconv-lite": "^0.6.3",
3623
+        "sax": "^1.2.4"
3624
+      },
3625
+      "bin": {
3626
+        "needle": "bin/needle"
3627
+      },
3628
+      "engines": {
3629
+        "node": ">= 4.4.x"
3630
+      }
3631
+    },
3489 3632
     "node_modules/nlcst-to-string": {
3490 3633
       "version": "3.1.1",
3491 3634
       "resolved": "https://registry.npmmirror.com/nlcst-to-string/-/nlcst-to-string-3.1.1.tgz",
@@ -3727,6 +3870,15 @@
3727 3870
         "unist-util-visit-children": "^2.0.0"
3728 3871
       }
3729 3872
     },
3873
+    "node_modules/parse-node-version": {
3874
+      "version": "1.0.1",
3875
+      "resolved": "https://registry.npmmirror.com/parse-node-version/-/parse-node-version-1.0.1.tgz",
3876
+      "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==",
3877
+      "devOptional": true,
3878
+      "engines": {
3879
+        "node": ">= 0.10"
3880
+      }
3881
+    },
3730 3882
     "node_modules/parse5": {
3731 3883
       "version": "7.1.2",
3732 3884
       "resolved": "https://registry.npmmirror.com/parse5/-/parse5-7.1.2.tgz",
@@ -3990,6 +4142,13 @@
3990 4142
       "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
3991 4143
       "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
3992 4144
     },
4145
+    "node_modules/prr": {
4146
+      "version": "1.0.1",
4147
+      "resolved": "https://registry.npmmirror.com/prr/-/prr-1.0.1.tgz",
4148
+      "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==",
4149
+      "dev": true,
4150
+      "optional": true
4151
+    },
3993 4152
     "node_modules/pump": {
3994 4153
       "version": "3.0.0",
3995 4154
       "resolved": "https://registry.npmmirror.com/pump/-/pump-3.0.0.tgz",
@@ -4551,6 +4710,13 @@
4551 4710
       "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz",
4552 4711
       "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
4553 4712
     },
4713
+    "node_modules/safer-buffer": {
4714
+      "version": "2.1.2",
4715
+      "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz",
4716
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
4717
+      "dev": true,
4718
+      "optional": true
4719
+    },
4554 4720
     "node_modules/sax": {
4555 4721
       "version": "1.3.0",
4556 4722
       "resolved": "https://registry.npmmirror.com/sax/-/sax-1.3.0.tgz",
@@ -4788,6 +4954,16 @@
4788 4954
       "resolved": "https://registry.npmmirror.com/@types/node/-/node-17.0.45.tgz",
4789 4955
       "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw=="
4790 4956
     },
4957
+    "node_modules/source-map": {
4958
+      "version": "0.6.1",
4959
+      "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
4960
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
4961
+      "dev": true,
4962
+      "optional": true,
4963
+      "engines": {
4964
+        "node": ">=0.10.0"
4965
+      }
4966
+    },
4791 4967
     "node_modules/source-map-js": {
4792 4968
       "version": "1.2.0",
4793 4969
       "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.0.tgz",
@@ -5012,6 +5188,12 @@
5012 5188
         }
5013 5189
       }
5014 5190
     },
5191
+    "node_modules/tslib": {
5192
+      "version": "2.6.2",
5193
+      "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.6.2.tgz",
5194
+      "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
5195
+      "devOptional": true
5196
+    },
5015 5197
     "node_modules/tunnel-agent": {
5016 5198
       "version": "0.6.0",
5017 5199
       "resolved": "https://registry.npmmirror.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz",

+ 4
- 0
package.json View File

@@ -17,7 +17,11 @@
17 17
     "@types/react-dom": "^18.2.18",
18 18
     "astro": "^4.1.3",
19 19
     "axios": "^1.6.5",
20
+    "classnames": "^2.5.1",
20 21
     "react": "^18.2.0",
21 22
     "react-dom": "^18.2.0"
23
+  },
24
+  "devDependencies": {
25
+    "less": "^4.2.0"
22 26
   }
23 27
 }

+ 84
- 0
src/components/NavMenu/SubMenu.jsx View File

@@ -0,0 +1,84 @@
1
+import React from 'react';
2
+import classNames from 'classnames';
3
+
4
+export default function SubMenu(props) {
5
+
6
+  const { pathPrefix, menus, show, onShowChange } = props;
7
+  const [style, setStyle] = React.useState({});
8
+  const [current, setCurrent] = React.useState(null);
9
+  const ref = React.useRef();
10
+
11
+  const onMouseLeaveCapture = e => {
12
+    if (e.target === ref.current) {
13
+      // onShowChange(false);
14
+    }
15
+  }
16
+
17
+  React.useEffect(() => {
18
+    const pageNav = document.getElementById('pageNav');
19
+    const rect = pageNav.getBoundingClientRect();
20
+    setStyle({
21
+      top: (rect.bottom + rect.top) + 'px',
22
+    });
23
+
24
+    // astro 暂时不支持 onXXXCapture 事件绑定模式
25
+    const el = ref.current;
26
+    el.addEventListener('mouseleave', onMouseLeaveCapture, true);
27
+
28
+    return () => {
29
+      el.removeEventListener('mouseleave', onMouseLeaveCapture, true);
30
+    }
31
+  }, []);
32
+
33
+  return (
34
+    <div
35
+      id="sub-menu"
36
+      ref={ref}
37
+      style={style}
38
+      className={classNames("container-fluid bg-white", { show })}
39
+    >
40
+      <div className="row">
41
+        {
42
+          menus?.map((menu) => (
43
+            <div className={classNames("col p-5", { 'has-level3': menu.levelDeep >= 3 })} key={menu.path}>
44
+              <p className="menu-level-1 fs-4">
45
+                <a
46
+                  className="sub-menu-link link-dark p-2 border-bottom"
47
+                  href={`${pathPrefix}${menu.path}`}
48
+                >{menu.name}</a>
49
+              </p>
50
+              <div className="row">
51
+                <div className="col pe-0">
52
+                {
53
+                  menu.children?.map((item) => (
54
+                    <p
55
+                      key={item.path}
56
+                      className={classNames("menu-level-2 mb-1", { 'bg-white': item === current })}
57
+                      onMouseEnter={() => setCurrent(item)}
58
+                    >
59
+                      <a className="sub-menu-link link-dark p-2" href={`${pathPrefix}${item.path}`}>{item.name}</a>
60
+                    </p>
61
+                  ))
62
+                }
63
+                </div>
64
+                {
65
+                  menu.levelDeep >= 3 && (
66
+                    <div className={classNames("col", { 'bg-white': current?.children?.length > 0 })}>
67
+                      {
68
+                        current?.children?.map((it) => (
69
+                          <p className="menu-level-3 mb-1">
70
+                            <a className="sub-menu-link link-dark p-2" href={`${pathPrefix}${it.path}`}>{it.name}</a>
71
+                          </p>
72
+                        ))
73
+                      }
74
+                    </div>
75
+                  )
76
+                }
77
+              </div>
78
+            </div>
79
+          ))
80
+        }
81
+      </div>
82
+    </div>
83
+  );
84
+}

+ 82
- 0
src/components/NavMenu/index.jsx View File

@@ -0,0 +1,82 @@
1
+import React, { Fragment } from 'react';
2
+import menus from '@/data/menu'
3
+import SubMenu from './SubMenu';
4
+import './style.less';
5
+
6
+export default function NavMenu(props) {
7
+
8
+  const { lang } = props;
9
+  const pathPrefix = `/${lang}`;
10
+
11
+  const [current, setCurrent] = React.useState();
12
+  const [show, setShow] = React.useState(false);
13
+
14
+  const onMouseMove = (e, menu) => {
15
+    setCurrent(menu);
16
+    setShow(menu.children?.length > 0)
17
+  }
18
+
19
+  return (
20
+    <Fragment>
21
+      <nav
22
+        id="pageNav"
23
+        className="navbar navbar-expand-lg navbar-light bg-light fixed-top p-0 py-3"
24
+        style={{ '--bs-bg-opacity': 0.9 }}
25
+      >
26
+        <div className="container-fluid">
27
+          <button
28
+            className="navbar-toggler"
29
+            type="button"
30
+            data-bs-toggle="collapse"
31
+            data-bs-target="#navbarSupportedContent"
32
+            aria-controls="navbarSupportedContent"
33
+            aria-expanded="false"
34
+            aria-label="Toggle navigation"
35
+          >
36
+            <span className="navbar-toggler-icon"></span>
37
+          </button>
38
+          <a className="navbar-brand" href={`/${lang}/`}>
39
+            <img
40
+              src="https://e.huawei.com/-/mediae/images/common/logo/logo_huawei.png"
41
+              alt="Academe"
42
+              width="120"
43
+              className="d-inline-block align-text-top"
44
+            />
45
+          </a>
46
+          <div id="navbarSupportedContent" className="collapse navbar-collapse">
47
+            <div className="me-auto"></div>
48
+      
49
+            <ul id="menu-nav" className="navbar-nav me-auto mb-2 mb-lg-0">
50
+              {
51
+                menus.map((menu) => (
52
+                  <li
53
+                    className="nav-item px-2 text-center"
54
+                    key={menu.path}
55
+                    onMouseMove={(e) => onMouseMove(e, menu)}
56
+                  >
57
+                    <a
58
+                      className="nav-link"
59
+                      aria-current="page"
60
+                      href={`${pathPrefix}${menu.path}`}>{menu.name}</a>
61
+                  </li>
62
+                ))
63
+              }
64
+            </ul>
65
+            <form className="d-flex">
66
+              <input className="form-control me-2" type="search" placeholder="Search" aria-label="Search" />
67
+              <button className="btn btn-outline-success" type="submit">Search</button>
68
+            </form>
69
+      
70
+          </div>
71
+        </div>      
72
+      </nav>
73
+              
74
+      <SubMenu
75
+        show={show}
76
+        pathPrefix={pathPrefix}
77
+        menus={current?.children}
78
+        onShowChange={setShow}
79
+      />
80
+    </Fragment>
81
+  );
82
+}

+ 84
- 0
src/components/NavMenu/style.less View File

@@ -0,0 +1,84 @@
1
+
2
+#sub-menu {
3
+  visibility: hidden;
4
+  position: absolute;
5
+  max-height: 0;
6
+  left: 0;
7
+  opacity: 0;
8
+  transition: all .2s ease-in-out;
9
+  z-index: -1;
10
+
11
+  .sub-menu-link {
12
+    width: 100%;
13
+    display: inline-block;
14
+    cursor: pointer;
15
+    margin-bottom: 0;
16
+    border-bottom: 1px solid transparent;
17
+    text-decoration: none;
18
+
19
+    &:hover {
20
+      border-bottom-color: var(--bs-red) !important;
21
+    }
22
+  }
23
+  
24
+  .has-level3 {
25
+    flex: 2;
26
+    background-color: #eee;
27
+
28
+    .menu-level-2 {
29
+      & > .sub-menu-link:hover {
30
+        border-bottom-color: transparent !important;
31
+        background-color: #fff;
32
+      }
33
+    }
34
+  }
35
+
36
+}
37
+
38
+
39
+@media (min-width: 992px) {
40
+  #pageNav {
41
+
42
+    li.nav-item {
43
+      position: relative;
44
+      z-index: 1;
45
+
46
+      &::before {
47
+        content: "";
48
+        position: absolute;
49
+        top: 0.5rem;
50
+        left: 100%;
51
+        width: 0;
52
+        height: calc(100% + 0.5rem);
53
+        border-bottom: 2px solid;
54
+        border-bottom-color: var(--bs-red);
55
+        transition: 0.2s all linear;
56
+        z-index: -1;
57
+      }
58
+
59
+      &:hover {
60
+
61
+        &::before {
62
+          transition-delay: 0.1s;
63
+          width: 100%;
64
+          left: 0;
65
+        }
66
+
67
+        & ~ li.nav-item::before {
68
+          left: 0;
69
+        }
70
+
71
+      }
72
+
73
+    }
74
+  }
75
+
76
+  #sub-menu {
77
+    &.show {
78
+      visibility: visible;
79
+      opacity: 1;
80
+      max-height: 80vh;
81
+      z-index: 999;
82
+    }
83
+  }
84
+}

+ 114
- 0
src/data/menu.js View File

@@ -0,0 +1,114 @@
1
+
2
+export default [
3
+  {
4
+    path: '/',
5
+    name: '首页',
6
+  },
7
+  {
8
+    path: '/products-solutions',
9
+    name: '产品与解决方案',
10
+    children: [
11
+      {
12
+        path: '/products-solutions/lot',
13
+        name: '智慧物联',
14
+        children: [
15
+          {
16
+            path: '/products-solutions/lot/building',
17
+            name: '智慧楼宇',
18
+          },
19
+          {
20
+            path: '/products-solutions/lot/agriculture',
21
+            name: '智慧农业',
22
+          },
23
+          {
24
+            path: '/products-solutions/lot/community',
25
+            name: '智慧社区',
26
+          },
27
+          {
28
+            path: '/products-solutions/lot/exhibition-all',
29
+            name: '智慧展馆',
30
+          },
31
+        ]
32
+      },
33
+      {
34
+        path: '/products-solutions/industrial-internet',
35
+        name: '工业互联网',
36
+        children: [
37
+          {
38
+            path: '/products-solutions/industrial-internet/mes',
39
+            name: '云致MES',
40
+          },
41
+          {
42
+            path: '/products-solutions/industrial-internet/erp',
43
+            name: 'ERP',
44
+          },
45
+        ],
46
+      },
47
+      {
48
+        path: '/product/gov-ent-health',
49
+        name: '政企医疗',
50
+        levelDeep: 3,
51
+        children: [
52
+          {
53
+            path: '/products-solutions/gov-ent-health/gov',
54
+            name: '政务服务',
55
+            children: [
56
+              {
57
+                path: '/products-solutions/gov-ent-health/gov/civilized-city',
58
+                name: '文明创城',
59
+              },
60
+            ],
61
+          },
62
+          {
63
+            path: '/products-solutions/gov-ent-health/bank',
64
+            name: '银行业务',
65
+            children: [
66
+              {
67
+                path: '/products-solutions/gov-ent-health/bank/custom',
68
+                name: '定制开发',
69
+              },
70
+            ],
71
+          },
72
+          {
73
+            path: '/products-solutions/gov-ent-health/healthcare',
74
+            name: '医院医疗',
75
+          },
76
+        ]
77
+      },
78
+      {
79
+        path: '/product/others',
80
+        name: '其他业务',
81
+        children: [
82
+          {
83
+            path: '/products-solutions/others/eshop',
84
+            name: '电商系统',
85
+          },
86
+          {
87
+            path: '/products-solutions/others/shigongli',
88
+            name: '旅游住宿',
89
+          },
90
+          {
91
+            path: '/products-solutions/others/house',
92
+            name: '房源交易',
93
+          },
94
+          {
95
+            path: '/products-solutions/others/crm',
96
+            name: 'CRM管理',
97
+          },
98
+        ],
99
+      }
100
+    ],
101
+  },
102
+  {
103
+    path: '/news',
104
+    name: '最新资讯',
105
+  },
106
+  {
107
+    path: '/about',
108
+    name: '关于云致',
109
+  },
110
+  {
111
+    path: '/concat-us',
112
+    name: '联系我们',
113
+  }
114
+]

+ 1
- 0
src/env.d.ts View File

@@ -1 +1,2 @@
1
+/// <reference path="../.astro/types.d.ts" />
1 2
 /// <reference types="astro/client" />

+ 2
- 1
src/pages/[lang]/index.astro View File

@@ -11,6 +11,7 @@ import BigImg from '@/components/BigImg.astro'
11 11
 import LeftMiddleRightImgText from '@/components/LeftMiddleRightImgText.astro'
12 12
 import LeftRightCarousel from '@/components/LeftRightCarousel.astro'
13 13
 import VerticalNavigationContent from '@/components/VerticalNavigationContent.astro'
14
+import NavMenu from '@/components/NavMenu/index.jsx'
14 15
 // import Dynamic from '@/components/Dynamic.astro'
15 16
 import { getContentList } from '@/services/apis'
16 17
 
@@ -34,7 +35,7 @@ const title = getName(categary)
34 35
 
35 36
 <Layout title={title}>
36 37
   <!-- 导航栏 -->
37
-  <Navbar lang={lang} />
38
+  <NavMenu lang={lang} client:load />
38 39
   <FirstScreen />
39 40
   <BigImg />
40 41
   <LeftMiddleRightImgText />

+ 3616
- 0
yarn.lock
File diff suppressed because it is too large
View File