소스 검색

addd some page

allen 2 년 전
부모
커밋
e82db24663

+ 11 - 0
package-lock.json

@@ -17,6 +17,7 @@
         "core-js": "3.25.3",
         "echarts": "4.9.0",
         "element-ui": "2.15.10",
+        "fetch-jsonp": "^1.2.1",
         "file-saver": "2.0.5",
         "fuse.js": "6.4.3",
         "highlight.js": "9.18.5",
@@ -7128,6 +7129,11 @@
         "node": ">=0.8.0"
       }
     },
+    "node_modules/fetch-jsonp": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmmirror.com/fetch-jsonp/-/fetch-jsonp-1.2.3.tgz",
+      "integrity": "sha512-C13k1o7R9JTN1wmhKkrW5bU/00LwixXnkufQUR6Rbf4KCS0i8mycQaovt4WVbHnA2NKgi7Ryp9Whpy/CGcij6Q=="
+    },
     "node_modules/figgy-pudding": {
       "version": "3.5.2",
       "dev": true,
@@ -22034,6 +22040,11 @@
         "websocket-driver": ">=0.5.1"
       }
     },
+    "fetch-jsonp": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmmirror.com/fetch-jsonp/-/fetch-jsonp-1.2.3.tgz",
+      "integrity": "sha512-C13k1o7R9JTN1wmhKkrW5bU/00LwixXnkufQUR6Rbf4KCS0i8mycQaovt4WVbHnA2NKgi7Ryp9Whpy/CGcij6Q=="
+    },
     "figgy-pudding": {
       "version": "3.5.2",
       "dev": true

+ 2 - 1
package.json

@@ -65,7 +65,8 @@
     "jquery": "~3.4.1",
     "@ztree/ztree_v3": "^3.5.48",
     "vue-runtime-helpers": "^1.1.2",
-    "less": "^2.3.1"
+    "less": "^2.3.1",
+    "fetch-jsonp": "^1.2.1"
   },
   "devDependencies": {
     "@vue/cli-plugin-babel": "4.4.6",

BIN
src/assets/images/robot-img.png


BIN
src/assets/images/search/1.jpg


BIN
src/assets/images/search/610.png


BIN
src/assets/images/search/620.png


BIN
src/assets/images/search/author.png


BIN
src/assets/images/search/clear.png


BIN
src/assets/images/search/favicon_1024.png


BIN
src/assets/images/search/favicon_128.png


BIN
src/assets/images/search/favicon_196.png


BIN
src/assets/images/search/favicon_32.png


BIN
src/assets/images/search/favicon_512.png


BIN
src/assets/images/search/logo.ico


BIN
src/assets/images/search/logo2.png


BIN
src/assets/images/search/search.png


+ 12 - 0
src/assets/images/search/search.svg

@@ -0,0 +1,12 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+        "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg t="1577894428082" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7348"
+     width="200" height="200">
+    <defs>
+        <style type="text/css"></style>
+    </defs>
+    <path d="M251.52 300.16a343.9872 343.9872 0 0 0-125.1072 23.3728 345.7536 345.7536 0 0 0 447.3344 447.3344A345.7536 345.7536 0 0 0 251.52 300.16z"
+          fill="#EE7C3D" p-id="7349"></path>
+    <path d="M908.9536 851.0464l-185.6-185.6a34.8672 34.8672 0 0 0-3.2512-2.9184 345.6 345.6 0 1 0-57.5744 57.5744 34.8672 34.8672 0 0 0 2.9184 3.2512l185.6 185.6a40.96 40.96 0 0 0 57.9072-57.9072z m-460.3136-138.7264a263.68 263.68 0 1 1 263.68-263.68 263.9872 263.9872 0 0 1-263.68 263.68z"
+          fill="#333333" p-id="7350"></path>
+</svg>

+ 45 - 0
src/assets/images/search/simple-so.svg

@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Creator: CorelDRAW 2020 (64-Bit) -->
+<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="519px" height="140px" version="1.1"
+     style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd"
+     viewBox="0 0 519 140"
+>
+ <defs>
+  <style type="text/css">
+   <![CDATA[
+    .fil0 {fill:#444444;fill-rule:nonzero}
+   ]]>
+  </style>
+ </defs>
+    <g id="图层_x0020_1">
+  <metadata id="CorelCorpID_0Corel-Layer"/>
+        <g id="SIMPLE_x0020_SO">
+   <g data-width="345.68603515625">
+    <path class="fil0"
+          d="M12 106.96l0 0c-0.82,-0.47 -1.53,-0.97 -2.13,-1.49 -0.59,-0.52 -0.89,-1.16 -0.89,-1.95l0 0c0,-0.4 0.12,-0.73 0.37,-1.01 0.25,-0.27 0.61,-0.4 1.07,-0.4l0 0c0.4,0 0.74,0.08 1.02,0.23 0.28,0.15 0.67,0.47 1.16,0.94l0 0c0.72,0.64 1.56,1.22 2.52,1.75 0.96,0.53 2.01,0.98 3.13,1.36 1.13,0.38 2.31,0.67 3.55,0.87 1.24,0.2 2.52,0.3 3.83,0.3l0 0c1.33,0 2.53,-0.13 3.59,-0.39 1.07,-0.26 1.97,-0.62 2.71,-1.08 0.74,-0.46 1.3,-1 1.7,-1.62 0.4,-0.63 0.6,-1.32 0.6,-2.07l0 0c0,-0.43 -0.05,-0.85 -0.14,-1.27 -0.1,-0.4 -0.29,-0.85 -0.58,-1.33 -0.29,-0.49 -0.72,-1.03 -1.28,-1.64 -0.56,-0.59 -1.31,-1.31 -2.27,-2.16 -0.95,-0.83 -2.12,-1.81 -3.51,-2.93 -1.39,-1.12 -3.06,-2.43 -5,-3.95l0 0c-2.13,-1.64 -3.91,-3.18 -5.34,-4.61 -1.43,-1.42 -2.57,-2.81 -3.44,-4.16 -0.87,-1.34 -1.49,-2.68 -1.86,-4.02 -0.37,-1.35 -0.56,-2.77 -0.56,-4.26l0 0c0,-1.81 0.37,-3.52 1.11,-5.13 0.73,-1.6 1.82,-3 3.26,-4.21 1.44,-1.2 3.23,-2.16 5.36,-2.86 2.13,-0.71 4.58,-1.06 7.37,-1.06l0 0c1.36,0 2.71,0.12 4.05,0.36 1.35,0.23 2.59,0.54 3.71,0.95l0 0c1.92,0.75 3.28,1.45 4.07,2.08 0.8,0.64 1.2,1.29 1.2,1.95l0 0c0,0.4 -0.13,0.74 -0.37,1.01 -0.25,0.27 -0.57,0.4 -0.97,0.4l0 0c-0.33,0 -0.61,-0.06 -0.86,-0.2 -0.25,-0.12 -0.57,-0.35 -0.97,-0.69l0 0c-0.46,-0.44 -1.05,-0.86 -1.77,-1.25 -0.71,-0.38 -1.53,-0.73 -2.44,-1.03 -0.91,-0.31 -1.9,-0.56 -2.97,-0.74 -1.06,-0.18 -2.18,-0.26 -3.35,-0.26l0 0c-1.57,0 -2.75,0.32 -3.53,0.97 -0.78,0.66 -1.18,1.49 -1.18,2.5l0 0c0,0.42 0.08,0.86 0.22,1.31 0.14,0.44 0.46,0.99 0.96,1.65 0.5,0.64 1.25,1.43 2.25,2.36 1,0.93 2.33,2.09 4.02,3.49l0 0c3.32,2.71 5.98,5.07 7.95,7.07 1.98,2.01 3.49,3.81 4.51,5.4 1.04,1.59 1.71,3.06 2.01,4.4 0.31,1.35 0.46,2.72 0.46,4.11l0 0c0,2.3 -0.48,4.41 -1.43,6.31 -0.95,1.9 -2.28,3.53 -3.98,4.9 -1.72,1.37 -3.74,2.43 -6.08,3.18 -2.34,0.76 -4.9,1.13 -7.69,1.13l0 0c-2.53,0 -4.92,-0.28 -7.18,-0.84 -2.26,-0.57 -4.26,-1.36 -5.99,-2.37z"
+          data-glyph-w="36.6064453125"/>
+       <polygon class="fil0" points="53.19,109.5 53.19,59.44 71.1,59.44 71.1,109.5 " data-glyph-w="25.50146484375"/>
+       <path class="fil0"
+             d="M77.14 108.19l0 0c0.05,-0.37 0.13,-0.71 0.23,-1.02 0.11,-0.31 0.31,-0.74 0.62,-1.31l0 0c0.18,-0.35 0.35,-0.68 0.5,-0.99 0.15,-0.31 0.31,-0.64 0.48,-1.01 0.16,-0.36 0.35,-0.79 0.56,-1.29 0.21,-0.5 0.47,-1.11 0.78,-1.84l0 0 14.43 -43.55 15.52 30.21 15.06 -30.21 18.02 52.32 -18.85 0 -8.71 -27.02 -13.49 28.3 -14.19 -25.47 -4.92 15.45c-0.39,0.9 -0.71,1.69 -0.94,2.36 -0.24,0.67 -0.44,1.26 -0.6,1.78 -0.17,0.53 -0.31,1 -0.42,1.42 -0.12,0.43 -0.25,0.83 -0.39,1.21l0 0c-0.28,0.96 -0.62,1.63 -1.01,2.01 -0.41,0.37 -0.88,0.54 -1.41,0.49l0 0c-0.45,-0.04 -0.79,-0.24 -1.01,-0.59 -0.24,-0.36 -0.32,-0.77 -0.26,-1.25z"
+             data-glyph-w="59.15478515625"/>
+       <path class="fil0"
+             d="M150.43 109.5l0 -50.06 13.46 0c2.68,0 4.91,0.01 6.66,0.04 1.76,0.02 3.24,0.07 4.43,0.15 1.2,0.07 2.21,0.16 3.04,0.27 0.83,0.12 1.67,0.27 2.51,0.43l0 0c2.41,0.5 4.56,1.3 6.44,2.4 1.89,1.11 3.48,2.43 4.78,3.95 1.3,1.52 2.27,3.22 2.93,5.09 0.66,1.88 0.96,3.84 0.91,5.89l0 0c-0.07,2.67 -0.5,5.13 -1.29,7.38 -0.8,2.26 -1.93,4.25 -3.38,5.98 -1.45,1.74 -3.22,3.17 -5.33,4.32 -2.11,1.14 -4.5,1.92 -7.17,2.35l0 0c-1.55,0.21 -2.76,0.31 -3.65,0.31l0 0c-1.12,0 -1.93,-0.14 -2.42,-0.43 -0.5,-0.3 -0.75,-0.73 -0.75,-1.29l0 0c0,-0.43 0.19,-0.78 0.58,-1.05 0.37,-0.27 0.87,-0.41 1.5,-0.41l0 0c0.28,0 0.55,0.01 0.79,0.02 0.24,0.01 0.48,0.03 0.72,0.06l0 0c0.26,0.02 0.53,0.04 0.82,0.04 0.3,0.02 0.56,0.03 0.8,0.03l0 0c2.25,0 4.33,-0.4 6.24,-1.19 1.92,-0.79 3.59,-1.9 5.02,-3.34 1.41,-1.45 2.53,-3.17 3.34,-5.17 0.82,-2.01 1.27,-4.22 1.34,-6.65l0 0c0.06,-2 -0.14,-3.81 -0.62,-5.41 -0.48,-1.6 -1.19,-3.03 -2.12,-4.27 -0.94,-1.23 -2.08,-2.3 -3.43,-3.2 -1.34,-0.89 -2.84,-1.64 -4.51,-2.23l0 0c-1.38,-0.49 -2.97,-0.87 -4.79,-1.11 -1.81,-0.25 -3.81,-0.37 -5.98,-0.37l0 0 -2.96 0 0 47.47 -17.91 0z"
+             data-glyph-w="46.66552734375"/>
+       <path class="fil0"
+             d="M203.7 109.5l0 -50.06 17.91 0 0 47.73 6.58 0c0.91,0 1.65,-0.05 2.22,-0.16 0.57,-0.11 1.06,-0.21 1.47,-0.3l0 0c0.46,-0.09 0.86,-0.19 1.2,-0.29 0.34,-0.09 0.58,-0.14 0.72,-0.14l0 0c0.61,0 1.07,0.13 1.38,0.37 0.32,0.26 0.48,0.66 0.48,1.22l0 0c0,0.43 -0.25,0.81 -0.75,1.14 -0.5,0.33 -1.4,0.49 -2.69,0.49l0 0 -28.52 0z"
+             data-glyph-w="33.86865234375"/>
+       <path class="fil0"
+             d="M241.77 109.5l0 -50.06 26.49 0c0.46,0 0.86,0 1.2,0 0.34,0 0.65,-0.01 0.93,-0.03l0 0c0.45,-0.03 0.82,-0.04 1.11,-0.05 0.29,-0.01 0.57,-0.02 0.82,-0.02l0 0c0.87,0 1.52,0.14 1.97,0.42 0.45,0.29 0.67,0.66 0.67,1.13l0 0c0,0.41 -0.15,0.78 -0.44,1.12 -0.29,0.34 -0.75,0.51 -1.36,0.51l0 0c-0.16,0 -0.35,-0.01 -0.57,-0.03 -0.23,-0.02 -0.56,-0.08 -1,-0.18l0 0c-0.45,-0.1 -1.02,-0.17 -1.7,-0.23 -0.69,-0.06 -1.51,-0.08 -2.45,-0.08l0 0 -7.76 0 0 10.78 6.4 0c0.58,0 1.08,-0.01 1.5,-0.02 0.43,-0.01 0.78,-0.02 1.05,-0.05l0 0c0.36,-0.02 0.66,-0.04 0.9,-0.07 0.25,-0.02 0.53,-0.03 0.86,-0.03l0 0c0.52,0 0.96,0.12 1.32,0.37 0.36,0.24 0.54,0.59 0.54,1.04l0 0c0,0.5 -0.17,0.86 -0.52,1.11 -0.35,0.25 -0.83,0.38 -1.44,0.38l0 0c-0.22,0 -0.43,-0.01 -0.63,-0.02 -0.21,-0.01 -0.51,-0.02 -0.88,-0.02l0 0c-0.26,-0.02 -0.55,-0.04 -0.87,-0.06 -0.31,-0.04 -0.66,-0.05 -1.06,-0.05l0 0 -7.17 0 0 31.56 7.76 0c0.94,0 1.76,-0.03 2.45,-0.07 0.68,-0.05 1.25,-0.11 1.7,-0.18l0 0c0.44,-0.11 0.77,-0.18 1,-0.19 0.22,-0.02 0.41,-0.02 0.57,-0.02l0 0c0.61,0 1.07,0.13 1.36,0.39 0.29,0.26 0.44,0.6 0.44,1.02l0 0c0,0.43 -0.26,0.81 -0.78,1.14 -0.51,0.33 -1.4,0.49 -2.66,0.49l0 0 -29.75 0z"
+             data-glyph-w="36.791015625"/>
+       <path class="fil0"
+             d="M300.38 106.96l0 0c-0.82,-0.47 -1.52,-0.97 -2.13,-1.49 -0.59,-0.52 -0.89,-1.16 -0.89,-1.95l0 0c0,-0.4 0.13,-0.73 0.37,-1.01 0.25,-0.27 0.61,-0.4 1.07,-0.4l0 0c0.4,0 0.74,0.08 1.02,0.23 0.28,0.15 0.67,0.47 1.16,0.94l0 0c0.73,0.64 1.57,1.22 2.53,1.75 0.95,0.53 2,0.98 3.12,1.36 1.13,0.38 2.31,0.67 3.55,0.87 1.24,0.2 2.52,0.3 3.83,0.3l0 0c1.33,0 2.53,-0.13 3.59,-0.39 1.07,-0.26 1.97,-0.62 2.71,-1.08 0.74,-0.46 1.3,-1 1.7,-1.62 0.4,-0.63 0.61,-1.32 0.61,-2.07l0 0c0,-0.43 -0.05,-0.85 -0.15,-1.27 -0.09,-0.4 -0.28,-0.85 -0.57,-1.33 -0.3,-0.49 -0.73,-1.03 -1.29,-1.64 -0.56,-0.59 -1.31,-1.31 -2.26,-2.16 -0.96,-0.83 -2.13,-1.81 -3.52,-2.93 -1.39,-1.12 -3.06,-2.43 -5,-3.95l0 0c-2.13,-1.64 -3.91,-3.18 -5.34,-4.61 -1.43,-1.42 -2.57,-2.81 -3.44,-4.16 -0.87,-1.34 -1.49,-2.68 -1.86,-4.02 -0.37,-1.35 -0.56,-2.77 -0.56,-4.26l0 0c0,-1.81 0.37,-3.52 1.11,-5.13 0.73,-1.6 1.82,-3 3.26,-4.21 1.44,-1.2 3.23,-2.16 5.36,-2.86 2.13,-0.71 4.59,-1.06 7.37,-1.06l0 0c1.36,0 2.71,0.12 4.05,0.36 1.35,0.23 2.59,0.54 3.71,0.95l0 0c1.92,0.75 3.28,1.45 4.07,2.08 0.8,0.64 1.2,1.29 1.2,1.95l0 0c0,0.4 -0.12,0.74 -0.37,1.01 -0.25,0.27 -0.57,0.4 -0.97,0.4l0 0c-0.33,0 -0.61,-0.06 -0.85,-0.2 -0.26,-0.12 -0.58,-0.35 -0.97,-0.69l0 0c-0.47,-0.44 -1.06,-0.86 -1.77,-1.25 -0.72,-0.38 -1.53,-0.73 -2.45,-1.03 -0.91,-0.31 -1.9,-0.56 -2.97,-0.74 -1.06,-0.18 -2.18,-0.26 -3.35,-0.26l0 0c-1.57,0 -2.74,0.32 -3.53,0.97 -0.78,0.66 -1.18,1.49 -1.18,2.5l0 0c0,0.42 0.08,0.86 0.22,1.31 0.14,0.44 0.46,0.99 0.96,1.65 0.5,0.64 1.25,1.43 2.25,2.36 1,0.93 2.34,2.09 4.02,3.49l0 0c3.32,2.71 5.98,5.07 7.96,7.07 1.97,2.01 3.48,3.81 4.5,5.4 1.04,1.59 1.71,3.06 2.01,4.4 0.31,1.35 0.46,2.72 0.46,4.11l0 0c0,2.3 -0.48,4.41 -1.43,6.31 -0.95,1.9 -2.28,3.53 -3.98,4.9 -1.71,1.37 -3.74,2.43 -6.07,3.18 -2.35,0.76 -4.91,1.13 -7.7,1.13l0 0c-2.53,0 -4.92,-0.28 -7.18,-0.84 -2.26,-0.57 -4.26,-1.36 -5.99,-2.37z"
+             data-glyph-w="14.02734375"/>
+       <path class="fil0"
+             d="M339.78 83.89l0 0c0,-3.61 0.65,-6.94 1.95,-9.99 1.3,-3.06 3.11,-5.71 5.41,-7.95 2.31,-2.24 5.04,-3.99 8.19,-5.25 3.14,-1.26 6.58,-1.89 10.3,-1.89l0 0c3.65,0 7.02,0.61 10.11,1.84 3.09,1.23 5.76,2.96 8.01,5.2 2.25,2.24 4,4.93 5.27,8.08 1.26,3.15 1.89,6.64 1.89,10.46l0 0c0,2.54 -0.29,4.95 -0.89,7.23 -0.6,2.28 -1.44,4.37 -2.53,6.28 -1.09,1.91 -2.4,3.63 -3.93,5.15 -1.54,1.52 -3.25,2.8 -5.15,3.86 -1.89,1.05 -3.95,1.85 -6.16,2.42 -2.21,0.56 -4.53,0.84 -6.97,0.84l0 0c-3.44,0 -6.71,-0.61 -9.8,-1.82 -3.09,-1.21 -5.79,-2.95 -8.11,-5.23 -2.32,-2.28 -4.16,-5.04 -5.53,-8.28 -1.37,-3.24 -2.06,-6.89 -2.06,-10.95zm22.19 -22.22l0 45.64c0.69,0.12 1.34,0.2 1.95,0.23 0.63,0.03 1.18,0.05 1.67,0.05l0 0c3.02,0 5.9,-0.54 8.62,-1.63 2.73,-1.08 5.13,-2.63 7.19,-4.65 2.06,-2.01 3.69,-4.45 4.9,-7.32 1.2,-2.87 1.8,-6.07 1.8,-9.6l0 0c0,-3.26 -0.54,-6.29 -1.64,-9.1 -1.1,-2.81 -2.65,-5.24 -4.65,-7.3 -1.98,-2.07 -4.35,-3.68 -7.1,-4.84 -2.75,-1.18 -5.79,-1.76 -9.12,-1.76l0 0c-0.46,0 -1.01,0.02 -1.63,0.05 -0.62,0.04 -1.28,0.12 -1.99,0.23l0 0z"
+             data-glyph-w="51.46435546875"/>
+   </g>
+            <polygon id="箭头" class="fil0" points="365.15,23.65 509.02,26.93 404.59,116.34 410.03,66.2 "/>
+  </g>
+ </g>
+</svg>

BIN
src/assets/images/user.png


+ 256 - 0
src/assets/styles/common.less

@@ -0,0 +1,256 @@
+@import (css) url("https://fonts.googleapis.com/css?family=Noto+Sans+SC:400,700&display=swap?subset=chinese-simplified");
+
+*, :after, :before {
+  margin: 0;
+  padding: 0;
+  outline: 0;
+  border: 0;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  -webkit-tap-highlight-color: transparent;
+  scroll-behavior: smooth;
+}
+
+input[type=email], input[type=number], input[type=password], input[type=search], input[type=tel], input[type=text], input[type=url], select {
+  width: 100%;
+  height: 46px;
+  line-height: 26px;
+  font-family: inherit;
+  font-size: inherit;
+  padding: 0 15px;
+  color: #333333;
+  background: #fff;
+  border-radius: 0;
+  -webkit-appearance: none
+}
+
+button, input[type=button], input[type=reset], input[type=submit], textarea {
+  height: 46px;
+  font-family: inherit;
+  font-size: inherit;
+  border-radius: 0;
+  -webkit-appearance: none
+}
+
+button, input[type=button], input[type=reset], input[type=submit] {
+  text-transform: uppercase;
+  padding: 0 15px;
+  cursor: pointer;
+  color: #fff;
+  background: #444444;
+  -webkit-transition: .2s;
+  transition: .2s
+}
+
+button:hover, input[type=button]:hover, input[type=reset]:hover, input[type=submit]:hover {
+  background-color: #2d2d2d
+}
+
+input[type="search"]::-webkit-search-cancel-button {
+  -webkit-appearance: none;
+  cursor: pointer;
+  height: 15px;
+  width: 15px;
+  color: #444444;
+  background: url("../../assets/images/search/clear.png") no-repeat;
+  background-size: contain;
+}
+
+/*通用元素样式*/
+.tag_box {
+  border: 1px solid #444444;
+  color: #444444;
+  border-radius: 3px;
+  padding: .1rem .2rem;
+  vertical-align: middle;
+  font-size: 80%;
+  font-weight: 700;
+}
+
+a {
+  text-decoration: none;
+  color: #444444;
+}
+
+ul li {
+  list-style: none;
+
+  a {
+    display: inline-block;
+    cursor: pointer;
+    color: #666666;
+    -webkit-transition: all .2s ease-in;
+    transition: all .2s ease-in
+  }
+}
+
+li.selected a {
+  background: #e5e5e5;
+  color: #444444;
+}
+
+li a:hover {
+  color: #444444;
+  background: #e5e5e5;
+}
+
+li a:active {
+  color: #444444;
+  background: #838383;
+}
+
+.scrollbar {
+  width: 4px;
+  height: auto;
+  margin: 0 auto;
+}
+
+::-webkit-scrollbar {
+  width: 4px;
+  height: 4px;
+}
+
+::-webkit-scrollbar-thumb {
+  /*滚动条里面小方块*/
+  border-radius: 2px;
+  background: #666666;
+}
+
+::-webkit-scrollbar-track {
+  /*滚动条里面轨道*/
+  border-radius: 0;
+  background: #e5e5e5;
+}
+
+@media (max-width: 640px) {
+  #menu,
+  .beian,
+  #top-menu-list,
+  .exchange {
+    display: none;
+  }
+
+}
+
+@media (max-height: 420px) {
+  #menu,
+  #foot,
+  .beian,
+  #top-menu-list,
+  .exchange {
+    display: none;
+  }
+}
+
+@media screen and (max-width: 1024px) {
+  #container {
+    width: 90%
+  }
+
+  #site-main {
+    margin: 0
+  }
+}
+
+@media screen and (max-width: 768px) {
+  #container {
+    width: 70%
+  }
+
+  #search-hot {
+    width: 100%;
+  }
+
+  #burger {
+    margin-top: 43px
+  }
+
+  #headline-content {
+    max-width: 100%
+  }
+
+  #search-bar {
+    padding-bottom: 60px
+  }
+
+  #search-tab span {
+    font-size: 15px
+  }
+
+  #work-link #container {
+    width: 85%
+  }
+}
+
+@media screen and (max-width: 480px) {
+  #container {
+    width: 90%
+  }
+}
+
+/*全局自适应样式结束*/
+
+#frame-box {
+  height: 85%;
+  width: 85%;
+  margin: 0 auto;
+  padding: 57px 0 0 0;
+  /*background: #ffefc0;*/
+  min-width: 640px;
+}
+
+#left-menu {
+  height: auto;
+  width: 128px;
+  /*background: aqua;*/
+  margin: 28px 0;
+  border-right: 1px solid #e9e9e9;
+  float: left;
+}
+
+#left-menu ul li {
+  text-align: center;
+  list-style: none;
+  height: 40px;
+  padding: 0;
+  margin: 6px 0;
+  border-right: 2px solid #ffffff;
+}
+
+#left-menu ul li.selected {
+  border-right: 2px solid #838383;
+}
+
+#left-menu ul li a {
+  vertical-align: middle;
+  height: 32px;
+  line-height: 32px;
+  padding: 0 16px;
+  margin: 4px 0;
+}
+
+#right-main {
+  font-size: 14px;
+  padding: 0 0 0 10px;
+  margin: 28px 0 0 0;
+  line-height: 32px;
+  height: 100%;
+  width: auto;
+  overflow-y: auto;
+  overflow-x: hidden;
+  white-space: normal;
+  word-break: break-all;
+}
+
+#right-main span {
+  line-height: 24px;
+  margin: 0;
+  padding: 0 0 3px 0;
+  border-bottom: 2px solid #838383;
+  cursor: text;
+  color: #999999;
+  font-size: 14px;
+}
+
+/*OS模块框架结束*/

+ 155 - 0
src/assets/styles/search.less

@@ -0,0 +1,155 @@
+#logo {
+  text-align: center;
+  width: 100%;
+  height: 25%;
+
+  img {
+    padding: 0;
+    height: 70px;
+    position: relative;
+    top: 70%;
+  }
+}
+
+#search-hot {
+  max-width: 470px;
+  width: 74%;
+  background: #f5f5f5;
+  overflow: hidden;
+  position: relative;
+  top: 0;
+
+  ul {
+    font-size: 15px;
+
+    li {
+      list-style: none;
+      cursor: pointer;
+      height: 25px;
+      line-height: 25px;
+      color: #838383;
+
+      span {
+        -webkit-tap-highlight-color: #00000000;
+        list-style: none;
+        cursor: pointer;
+        display: inline-block;
+        width: 25px;
+        height: 25px;
+        line-height: 25px;
+        text-align: center;
+        background: #e5e5e5;
+        margin-right: 10px;
+        color: #535353;
+        border: 1px solid #f5f5f5;
+      }
+
+      .search_index0 {
+        color: rgb(255, 255, 255);
+        background: rgb(245, 69, 69);
+      }
+
+      .search_index1 {
+        color: rgb(255, 255, 255);
+        background: rgb(255, 133, 71);
+      }
+
+      .search_index2 {
+        color: rgb(255, 255, 255);
+        background: rgb(255, 172, 56);
+      }
+    }
+
+    li:hover {
+      background: white;
+      color: #444444;
+    }
+
+    li.selected {
+      background: white;
+      color: #444444;
+    }
+  }
+}
+
+#container {
+  width: 85%;
+  margin: 0 auto;
+  position: relative
+}
+
+.float-left {
+  float: left
+}
+
+.float-right {
+  float: right
+}
+
+#headline-content {
+  max-width: 650px;
+  margin: 0 auto
+}
+
+
+#search-bar {
+  padding: 40px 0 70px
+}
+
+#search-tab {
+  font-weight: 700;
+  max-width: 470px;
+  height: 33px;
+  margin: 0 0 20px;
+  display: flex;
+  align-items: center;
+  flex-direction: row;
+  justify-content: space-between;
+  border-bottom: 1px solid #e9e9e9;
+  -webkit-tap-highlight-color: transparent;
+
+  span {
+    height: 32px;
+    padding: 0 8px;
+    display: inline-block;
+    font-size: 16px;
+    line-height: 1;
+    opacity: .6;
+    color: #ffffff;
+    border-bottom: 2px solid transparent;
+    cursor: pointer;
+    white-space: nowrap;
+    overflow: hidden;
+    -webkit-transition: all .2s ease-in;
+    transition: all .2s ease-in
+  }
+
+  span.active, span:hover {
+    opacity: 1;
+    border-color: #838383
+  }
+}
+
+#search-form input[type=search] {
+  max-width: 470px;
+  width: 74%;
+  background: #f5f5f5;
+  overflow: hidden
+}
+
+#search-form input[type=submit] {
+  max-width: 130px;
+  width: 26%;
+  font-weight: 700;
+}
+
+#search-keyword {
+  border-top: 2px solid #f5f5f5;
+  border-bottom: 2px solid #f5f5f5;
+}
+
+#search-keyword:focus {
+  border-bottom: 2px solid #444444;
+  -webkit-transition: all .2s ease-in;
+  transition: all .2s ease-in
+}

+ 1 - 1
src/components/TopNav/index.vue

@@ -5,7 +5,7 @@
     @select="handleSelect"
     active-text-color="#409EFF"
   >
-    <el-menu-item :style="{'--theme': theme}" index="/knowledge"
+    <el-menu-item :style="{'--theme': theme}" index="/search"
         ><svg-icon icon-class="dashboard" />
       检索中心
     </el-menu-item>

+ 193 - 0
src/components/echarts/graph.vue

@@ -0,0 +1,193 @@
+<template>
+  <div id="chart" class="chart"></div>
+</template>
+<script>
+//codenong.com/jsf795393b5d9c/
+// var echarts = require("echarts/lib/echarts");
+import * as echarts from "echarts";
+// require("echarts/lib/chart/graph");
+// require("echarts/lib/component/tooltip");
+// require("echarts/lib/component/title");
+export default {
+  name: "Charts",
+  props: {
+    chartList: {
+      type: Object,
+      required: true,
+    },
+  },
+  watch: {
+    chartList: {
+      handler(val) {
+        this.formatData(val || [], true);
+      },
+    },
+  },
+  data() {
+    return {
+      myChart: "",
+      seriesData: [],
+      seriesLinks: [],
+      categories: [],
+      lastClickId: "",
+      colors: [
+        "#a3d2ca",
+        "#056676",
+        "#ea2c62",
+        "#16a596",
+        "#03c4a1",
+        "#f5a25d",
+        "#8CD282",
+        "#32e0c4",
+        "#00FAE1",
+        "#f05454",
+      ],
+    };
+  },
+  mounted() {
+    this.formatData(this.chartList, true);
+    this.initCharts();
+  },
+  methods: {
+    /**
+     * 节点点击事件
+     */
+    async nodeClick(params) {
+      const index = this.seriesData.findIndex((item) => item.id === params.data.id);
+      console.log("点了节点:" + index + 1, "clicked");
+    },
+    /**
+     * 设置echarts配置项,重绘画布
+     */
+    initCharts() {
+      const that = this;
+      if (!this.myChart) {
+        this.myChart = echarts.init(document.getElementById("chart"));
+        this.myChart.on("click", (params) => {
+          if (params.dataType === "node") {
+            //判断点击的是图表的节点部分
+            this.nodeClick(params);
+          }
+        });
+      }
+      // 指定图表的配置项和数据
+      let option = {
+        // 动画更新变化时间
+        animationDurationUpdate: 1500,
+        animationEasingUpdate: "quinticInOut",
+        tooltip: {
+          show: false,
+        },
+        series: [
+          {
+            type: "graph",
+            layout: "force",
+            legendHoverLink: true, //是否启用图例 hover(悬停) 时的联动高亮。
+            hoverAnimation: true, //是否开启鼠标悬停节点的显示动画
+            focusNodeAdjacency: true,
+            edgeLabel: {
+              position: "middle", //边上的文字样式
+              normal: {
+                show: true,
+                textStyle: {
+                  fontSize: 12,
+                },
+                position: "middle",
+                formatter: function (x) {
+                  return x.data.name;
+                },
+              },
+            },
+            edgeSymbol: ["", "arrow"],
+            force: {
+              edgeLength: 150,
+               repulsion: 500,
+            },
+            roam: true,
+            draggable: true, //每个节点的拖拉
+            itemStyle: {
+              normal: {
+                color: "#00FAE1",
+                cursor: "pointer",
+                //color:Math.floor(Math.random()*16777215).toString(16),
+                //color: ['#fc853e','#28cad8','#9564bf','#bd407e','#28cad8','#fc853e','#e5a214'],
+                label: {
+                  show: true,
+                  position: [-10, -15],
+                  textStyle: {
+                    //标签的字体样式
+                    color: "#fff", //字体颜色
+                    fontStyle: "normal", //文字字体的风格 'normal'标准 'italic'斜体 'oblique' 倾斜
+                    fontWeight: "bold", //'normal'标准'bold'粗的'bolder'更粗的'lighter'更细的或100 | 200 | 300 | 400...
+                    fontFamily: "sans-serif", //文字的字体系列
+                    fontSize: 12, //字体大小
+                  },
+                },
+                nodeStyle: {
+                  brushType: "both",
+                  borderColor: "rgba(255,215,0,0.4)",
+                  borderWidth: 1,
+                },
+              },
+              //鼠标放上去有阴影效果
+              emphasis: {
+                shadowColor: "#00FAE1",
+                shadowOffsetX: 0,
+                shadowOffsetY: 0,
+                shadowBlur: 40,
+              },
+            },
+            lineStyle: {
+              width: 3,
+            },
+            label: {
+              fontSize: 18,
+            },
+            symbolSize: 24, //节点大小
+            links: this.seriesLinks,
+            data: this.seriesData,
+            categories: this.categories,
+            cursor: "pointer",
+          },
+        ],
+      };
+      // 使用刚指定的配置项和数据显示图表。
+      this.myChart.setOption(option);
+    },
+    /**
+     * 格式化数据到表格需要的数据
+     */
+    formatData(list, reset = false) {
+      const that = this;
+      let nodes = list.seriesData;
+      this.seriesData = [];
+      this.seriesLinks = [];
+      let colorIndex = 0;
+      let data = [];
+      let loadedCat = [];
+      nodes.forEach((item, index) => {
+        if (item.categary && loadedCat.indexOf(item.categary) === -1) {
+          colorIndex = Math.floor(Math.random() * that.colors.length);
+          loadedCat.push(item.categary);
+          this.categories.push({ name: item.categary });
+        }
+        item.itemStyle = {
+          color: that.colors[colorIndex],
+          borderColor: "#ffffff",
+        };
+        data.push(item);
+      });
+      this.seriesData.push(...data);
+      this.seriesLinks.push(...list.linksData);
+      this.initCharts();
+    },
+  },
+  beforeDestroy() {},
+};
+</script>
+<style scoped>
+.chart {
+  width: 600px;
+  height: 300px;
+}
+</style>

+ 167 - 0
src/components/search/Background.vue

@@ -0,0 +1,167 @@
+<template>
+  <div>
+    <a class="exchange" @click="closed = false">换肤</a>
+    <div :class="{ closed: closed }" class="background-main">
+      <div class="background-pics">
+        <ul>
+          <li>
+            <img
+              src="https://s4.ax1x.com/2021/12/18/TEtGGV.png"
+              @click="set_background('/public/1.png')"
+            />
+            <p>预设1</p>
+          </li>
+          <li>
+            <img src="https://s4.ax1x.com/2021/12/18/TEtGGV.png" />
+            <p>预设2</p>
+          </li>
+          <li>
+            <img src="https://s4.ax1x.com/2021/12/18/TEtGGV.png" />
+            <p>预设3</p>
+          </li>
+          <li>
+            <img src="https://s4.ax1x.com/2021/12/18/TEtGGV.png" />
+            <p>预设4</p>
+          </li>
+          <li>
+            <img src="https://s4.ax1x.com/2021/12/18/TEtGGV.png" />
+            <p>预设5</p>
+          </li>
+        </ul>
+      </div>
+      <div class="background-custom">
+        自定义背景:
+        <input ref="ipt_url" placeholder="http(s)://" type="url" />
+      </div>
+      <input type="submit" value="保存" @click="save()" />
+      <input type="submit" value="取消" @click="closed = true" />
+    </div>
+  </div>
+</template>
+
+<script>
+import storage from "@/utils/storage";
+
+export default {
+  name: "Background",
+  emits: ["background"],
+  data() {
+    return {
+      data: "",
+      closed: true,
+    };
+  },
+  created() {
+    let background;
+    background = storage.get("background");
+    if (background) {
+      this.data = background;
+    }
+    this.$emit("background", this.data);
+  },
+  methods: {
+    set_background(url) {
+      this.data = "url(" + url + ") center center / cover no-repeat";
+      this.$emit("background", this.data);
+      storage.set("background", this.data);
+    },
+    save() {
+      let url;
+      url = this.$refs.ipt_url.value;
+      if (url) {
+        this.set_background(url);
+      }
+      this.closed = true;
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.background-main {
+  height: 350px;
+  position: absolute;
+  bottom: 0;
+  z-index: 1001;
+  width: 100%;
+  color: #444444;
+  line-height: 20px;
+  font-size: 14px;
+  padding: 25px 0;
+  text-align: center;
+  background-color: #e5e5e5;
+  transition: 0.3s all ease;
+}
+
+.background-main.closed {
+  bottom: -350px;
+}
+
+.background-banner,
+.background-custom {
+  font-size: 16px;
+  height: 46px;
+  margin: 15px 0;
+}
+
+.background-pics {
+  width: 1120px;
+  height: 170px;
+  margin: auto;
+
+  ul {
+    li {
+      float: left;
+      height: 170px;
+      overflow: hidden;
+      width: 20%;
+      text-align: center;
+      padding: 15px 0;
+      font-size: 16px;
+
+      img {
+        cursor: pointer;
+        height: 120px;
+        border: 3px solid #cdcdcd;
+        border-radius: 5px;
+        transition: 0.3s all ease;
+      }
+
+      img:hover {
+        border: 3px solid #838383;
+      }
+    }
+  }
+}
+
+.background-custom {
+  input[type="url"] {
+    width: 470px;
+  }
+}
+
+input[type="submit"] {
+  width: 130px;
+  margin: 0 50px;
+}
+
+.exchange {
+  width: 50px;
+  height: 50px;
+  transform: scale(0.8);
+  position: absolute;
+  right: 10px;
+  top: 80px;
+  cursor: pointer;
+  z-index: 1999;
+  text-align: center;
+  line-height: 50px;
+  border: 1px solid #e9e9e9;
+  border-radius: 5px;
+  transition: 0.3s all ease;
+}
+
+.exchange:hover {
+  border: 1px solid #838383;
+}
+</style>

+ 2 - 0
src/router/index.js

@@ -7,6 +7,7 @@ Vue.use(Router)
 import Layout from '@/layout'
 
 import Knowledge from '@/router/knowledge'
+import Search from '@/router/search'
 
 /**
  * Note: 路由配置项
@@ -92,6 +93,7 @@ export const constantRoutes = [
   },
   // 知识图谱路由
   ...Knowledge,
+  ...Search,
   ]
 
 // 动态路由,基于用户权限动态去加载

+ 37 - 0
src/router/search/index.js

@@ -0,0 +1,37 @@
+import Home from '@/views/search/Home.vue'
+// import {createRouter, createWebHistory} from 'vue-router'
+
+export default  [
+    {
+        path: '/search',
+        name: 'search',
+        component: Home
+    },
+    {
+        path: '/search/nav',
+        name: 'nav',
+        component: () => import('@/views/search/nav.vue')
+    },
+    {
+        path: '/search/os',
+        name: 'os',
+        component: () => import('@/views/search/os.vue')
+    },
+    {
+        path: '/search/software',
+        name: 'software',
+        component: () => import('@/views/search/software.vue')
+    },
+    {
+        path: '/search/background',
+        name: 'background',
+        component: () => import('@/components/search/Background.vue')
+    }
+]
+
+// const routerHistory = createWebHistory()
+// const router = createRouter({
+//     history: routerHistory,
+//     routes,
+// })
+// export default router

+ 12 - 0
src/utils/storage.js

@@ -0,0 +1,12 @@
+const storage = {
+    set(key, value) {
+        localStorage.setItem(key, JSON.stringify(value))
+    },
+    get(key) {
+        return JSON.parse(localStorage.getItem(key))
+    },
+    remove(key) {
+        localStorage.removeItem(key)
+    }
+}
+export default storage

+ 349 - 0
src/views/ai/question/chatMsg.vue

@@ -0,0 +1,349 @@
+<template>
+  <div id="chatmsg" ref="msg">
+    <!-- 动态创建 -->
+    <div v-for="(item, index) in lists" :key="index">
+      <div v-if="item.id == 122" class="user">
+        <div v-scroll>
+          <img :src="item.face" alt />
+          <div class="bubble">
+            <span>{{ item.word }}</span>
+          </div>
+        </div>
+      </div>
+      <div v-if="item.id == 1529" class="touser">
+        <div v-scroll>
+          <img :src="item.face" alt />
+          <div class="tobubble">
+            <span>{{ item.word }}</span
+            >&nbsp;&nbsp;&nbsp;&nbsp;
+            <template v-if="dialogVisible">
+              <el-button @click="hidenGraph(item.graph)">关闭关系图</el-button>
+            </template>
+            <template v-else>
+              <el-button @click="showGraph(item.graph)">显示关系图</el-button>
+            </template>
+          </div>
+        </div>
+      </div>
+    </div>
+    <!-- graph -->
+    <template v-if="dialogVisible">
+      <el-dialog :visible.sync="dialogVisible">
+        <!-- <chart-comp ref="chart"
+                        @="getInfoTooltip"
+                        :isShowContextMenu="true"
+                        @reloadChart="reloadChart"
+                        :nodes="graph.nodes"
+                        :links="graph.links"
+                        :enable="true"
+                        :isShowChart="true"></chart-comp> -->
+        <Graph ref="charts" :chartList="searchList" />
+      </el-dialog>
+    </template>
+  </div>
+</template>
+
+<script>
+// import { url } from 'inspector';
+
+// import userinfo from "./userinfo";
+import Graph from "@/components/echarts/graph";
+export default {
+  name: "ChatMsg",
+  components: { Graph },
+  data() {
+    return {
+      userimg: "",
+      lists: [],
+      userinfo: {
+        id: "122",
+        imgurl: require("@/assets/images/user.png"),
+        words: "是的!",
+        data: {
+          id: "1529",
+          imgurl: require("@/assets/images/robot-img.png"),
+          name: "易安居士",
+          answer: {
+            1: "歼击机,强击机,轰炸机,侦察机,运输机,预警机,电子干扰机、反潜机、教练机、空中加油机、舰载飞机等等",
+            2: "机翼、机身、尾翼、起落装置、操纵系统和动力装置",
+            3: "",
+            4: "",
+            5: "",
+            6: "",
+            7: "",
+            8: "",
+            9: "",
+            10: "",
+          },
+        },
+      },
+      graph: {},
+      dialogVisible: false,
+      searchList: {
+        seriesData: [
+          {
+            id: 1,
+            name: "飞机",
+          },
+          {
+            id: 2,
+            name: "机翼",
+          },
+          {
+            id: 3,
+            name: "机身",
+          },
+          {
+            id: 4,
+            name: "尾翼",
+          },
+          {
+            id: 5,
+            name: "起落装置", //node文字
+          },
+          {
+            id: 6,
+            name: "操纵系统", //node文字
+          },
+          {
+            id: 7,
+            name: "动力系统", //node文字
+          },
+        ],
+        linksData: [
+          {
+            source: 2,
+            target: 1,
+            label: {
+              show: true, // 是否显示line的文字
+              formatter: "组成" // line的文字
+            },
+          },
+          {
+            source: 3,
+            target: 1,
+            label: {
+              show: true, // 是否显示line的文字
+              formatter: "组成" // line的文字
+            },
+          },
+          {
+            source: 4,
+            target: 1,
+            label: {
+              show: true, // 是否显示line的文字
+              formatter: "组成" // line的文字
+            },
+          },
+          {
+            source: 5,
+            target: 1,
+            label: {
+              show: true, // 是否显示line的文字
+              formatter: "组成" // line的文字
+            },
+          },
+          {
+            source: 6,
+            target: 1,
+            label: {
+              show: true, // 是否显示line的文字
+              formatter: "组成" // line的文字
+            },
+          },
+          {
+            source: 7,
+            target: 1,
+            label: {
+              show: true, // 是否显示line的文字
+              formatter: "组成" // line的文字
+            },
+          },
+          
+        ],
+      },
+    };
+  },
+  created() {},
+  mounted() {
+    this.userid = this.userinfo.id;
+    this.userimg = this.userinfo.imgurl;
+  },
+  // vue自动滚动到底部
+  directives: {
+    scroll: {
+      inserted(el) {
+        el.scrollIntoView();
+      },
+    },
+  },
+  methods: {
+    saveMsg(tomsg) {
+      this.lists.push({
+        id: this.userid,
+        face: this.userimg,
+        word: tomsg,
+      });
+    },
+    randomMsg(tomsg) {
+      let touserdata = this.userinfo.data;
+      let answer = "对不起,没找到相关答案";
+      if ("飞机的种类" == tomsg) {
+        answer = this.userinfo.data.answer["1"];
+      } else if ("飞机的组成" == tomsg) {
+        answer = this.userinfo.data.answer["2"];
+      }
+
+      // let graph = {
+      //   nodes: [
+      //     {
+      //       entClsID: "1",
+      //       id: "1",
+      //       label: "机翼",
+      //       entClsName: "机翼",
+      //     },
+      //     {
+      //       entClsID: "2",
+      //       id: "2",
+      //       label: "机翼2",
+      //       entClsName: "机翼2",
+      //     },
+      //     {
+      //       entClsID: "3",
+      //       id: "3",
+      //       label: "机翼3",
+      //       entClsName: "机翼3",
+      //     },
+      //     {
+      //       entClsID: "4",
+      //       id: "4",
+      //       label: "机翼4",
+      //       entClsName: "机翼4",
+      //     },
+      //     {
+      //       entClsID: "5",
+      //       id: "5",
+      //       label: "机翼5",
+      //       entClsName: "机翼5",
+      //     },
+      //   ],
+      //   links: [{}, {}],
+      // };
+
+      this.lists.push({
+        id: touserdata.id,
+        face: touserdata.imgurl,
+        word: answer,
+      });
+    },
+    showGraph(graph) {
+      this.dialogVisible = true;
+      // this.graph = graph;
+    },
+    hidenGraph() {
+      this.dialogVisible = false;
+    },
+    // reloadChart() {
+    //   this.drawChart(this.graph.nodes, this.graph.links);
+    // },
+    // /**
+    //  * 画图
+    //  * @params nodes: 处理好的实体数据, link: 处理好的关系数据
+    //  * */
+    // drawChart(nodes, links) {
+    //   // this.nodes = nodes
+    //   // this.links = links
+    //   this.$refs.chart.destroyChart(); // 先清空chart实例,再绘图
+    //   this.$refs.chart.reDraw(undefined, nodes, links);
+    // },
+    // getInfoTooltip() {},
+  },
+};
+</script>
+
+<style lang="scss" scope>
+#chatmsg {
+  position: relative;
+  // top: 3.5rem;
+  width: 100%;
+  // min-height: 44rem;
+  height: 400px;
+  // background-color: rgba(238, 212, 238, 0.3);
+  margin-bottom: 3.5rem;
+  overflow-x: hidden;
+  overflow-y: auto;
+  .user {
+    position: relative;
+    width: 100%;
+    overflow: hidden;
+    margin: 0.8rem 0;
+    img {
+      object-fit: cover;
+      width: 3rem;
+      height: 3rem;
+      border-radius: 3px;
+      float: right;
+      margin-right: 1rem;
+    }
+    .bubble {
+      position: relative;
+      float: right;
+      margin-right: 1rem;
+      padding: 0.8rem;
+      box-sizing: border-box;
+      border-radius: 3px;
+      max-width: 65%;
+      background-color: rgb(116, 228, 116);
+      span {
+        height: 1.25rem;
+        line-height: 1.25rem;
+      }
+    }
+    .bubble::after {
+      position: absolute;
+      right: -1.3rem;
+      top: 0.8rem;
+      content: "";
+      width: 0;
+      height: 0;
+      border: 0.7rem solid;
+      border-color: transparent transparent transparent rgb(116, 228, 116);
+    }
+  }
+  .touser {
+    position: relative;
+    width: 100%;
+    overflow: hidden;
+    margin: 0.8rem 0;
+    img {
+      object-fit: cover;
+      width: 3rem;
+      height: 3rem;
+      border-radius: 3px;
+      float: left;
+      margin-left: 1rem;
+    }
+    .tobubble {
+      position: relative;
+      float: left;
+      margin-left: 1rem;
+      padding: 0 0.7rem;
+      box-sizing: border-box;
+      border-radius: 3px;
+      max-width: 65%;
+      background-color: rgb(116, 228, 116);
+      line-height: 3rem;
+    }
+    .tobubble::after {
+      position: absolute;
+      left: -1.3rem;
+      top: 0.8rem;
+      content: "";
+      width: 0;
+      height: 0;
+      border: 0.7rem solid;
+      border-color: transparent rgb(116, 228, 116) transparent transparent;
+    }
+  }
+}
+</style>

+ 176 - 0
src/views/ai/question/index.vue

@@ -0,0 +1,176 @@
+<template>
+  <div id="chatdetail">
+    <!-- <div class="chattop">
+      <div @click="goback" class="chattop_back">
+        <icon-svg icon-class="houtui_shangyibu_zuojiantou_shangyiye" />
+      </div>
+      <div class="chattop_name">{{ name }}</div>
+      <div class="chattop_more">
+        <icon-svg icon-class="gengduo" />
+      </div>
+    </div> -->
+    <div class="chatcontent">
+        <!-- document.getElementById('chatdetail').clientHeight -->
+      <ChatMsg ref="chatmsg"/>
+    </div>
+    <div id="chatfooter" class="chatfooter">
+      <div @click="changeSound">
+        <icon-svg :icon-class="issound" />
+      </div>
+      <div>
+        <input ref="sendcontent" @keypress="sendmsg" :type="istype" :value="isvalue" />
+      </div>
+      <div>
+        <icon-svg icon-class="biaoqing" />
+      </div>
+      <div>
+        <icon-svg icon-class="del" />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import ChatMsg from "./chatMsg";
+export default {
+  name: "ChatDetail",
+  data() {
+    return {
+      name: null,
+      issound: "xiaoxitongzhi",
+      istype: "text",
+      isvalue: "飞机的组成",
+      isshow: false,
+      tomsg: "",
+      msgchild: null,
+    };
+  },
+  components: {
+    ChatMsg: ChatMsg,
+  },
+  mounted() {
+    this.name = this.$route.query.name;
+    this.msgchild = this.$refs.chatmsg;
+  },
+  methods: {
+    // 进行返回操作
+    goback() {
+      this.$router.go(-1);
+    },
+    // 切换input的类型
+    changeSound() {
+      // 在data中定义一个变量isshow:false,利用this.isshow与!this.isshow进行切换
+      if (!this.isshow) {
+        this.isshow = true;
+        this.issound = "yuyin";
+        this.istype = "button";
+        this.isvalue = "按住 说话";
+      } else {
+        this.isshow = false;
+        this.issound = "xiaoxitongzhi";
+        this.istype = "text";
+        this.isvalue = "";
+      }
+    },
+    // 发送消息
+    sendmsg(e) {
+      // 1、用ref定义输入回复内容的input文本框,定义sendcontent变量接收其value值(输入的内容)
+      let sendcontent = this.$refs.sendcontent.value;
+      if (e.keyCode === 13 && sendcontent.split(" ").join("").length !== 0) {
+        // 2、将ChatDetail(父)组件中的sendcontent(文本框输入的值)先用tomsg接收
+        this.tomsg = sendcontent;
+        // 3、用ref定义ChatMsg(子)组件,并在mounted中使用$refs获取,即this.msgchild
+        // 4、调子组件里的方法,并将tomsg传到ChatMsg(子)组件(具体的聊天内容)中
+        this.msgchild.saveMsg(this.tomsg);
+        // 5、发送完一条信息之后,需清空文本框
+        this.$refs.sendcontent.value = "";
+        // 回车时,调用子组件的随机消息的方法
+        this.msgchild.randomMsg(this.tomsg);
+      }
+    },
+    // chatcontentStyle(){
+    //     debugger;
+    //     let a = 'height : ' + (document.getElementById('chatdetail').clientHeight - document.getElementById('chatfooter').clientHeight)
+    //     console.info("a")
+    //     console.info(a)
+    //     return a;
+    // }
+  },
+};
+</script>
+
+<style lang="scss" scope>
+#chatdetail {
+//   position: relative;
+  background-color: transparent;
+  height: 400px;
+//   .chattop {
+//     position: fixed;
+//     top: 0;
+//     left: 0;
+//     z-index: 10;
+//     width: 100%;
+//     height: 3.5rem;
+//     line-height: 3.5rem;
+//     background-color: transparent;
+//     display: flex;
+//     flex-direction: row;
+//     .chattop_back {
+//       flex: 1;
+//       margin-left: 1rem;
+//     }
+//     .chattop_name {
+//       flex: 20;
+//       text-align: center;
+//     }
+//     .chattop_more {
+//       flex: 1;
+//       margin-right: 1rem;
+//     }
+//   }
+  .chatcontent {
+    width: 100%;
+    // height: 300px;
+  }
+  .chatfooter {
+    margin-left: 15px;
+    position: fixed;
+    left: 0;
+    bottom: 0;
+    z-index: 10;
+    width: 100%;
+    height: 3.5rem;
+    line-height: 3.5rem;
+    text-align: center;
+    background-color: rgba(240, 240, 240,0.3);
+    display: flex;
+    flex-direction: row;
+    div:nth-child(1),
+    div:nth-child(3),
+    div:nth-child(4) {
+      flex: 1;
+      svg {
+        font-size: 1.5rem;
+        margin-top: 0.9rem;
+      }
+    }
+    div:nth-child(2) {
+      flex: 5;
+      input {
+        width: 100%;
+        height: 2.5rem;
+        outline: none;
+        padding-left: 0.5rem;
+        box-sizing: border-box;
+        height: 2.5rem;
+        margin-top: 0.5rem;
+        border-style: none;
+        font-size: 0.9rem;
+        border-radius: 4px;
+        background-color: transparent;
+        color: #000;
+      }
+    }
+  }
+}
+</style>

+ 1 - 1
src/views/index.vue

@@ -430,7 +430,7 @@
   }
 </script>
 
-<style>
+<style scoped>
   @font-face {
     font-family: "FZZhiYi-M12S";
     src: url("../assets/knowledge/ziti.ttf");

+ 197 - 0
src/views/search/Home.vue

@@ -0,0 +1,197 @@
+<template>
+  <div>
+    <div id="logo">
+      <img alt="数据检索中心" src="../../assets/images/search/620.png"/>
+    </div>
+    <div v-if="engines" id="site-main">
+      <div id="search-bar">
+        <div id="container">
+          <div id="headline-content">
+            <div id="search-tab">
+              <span
+                v-for="engine_name in engine_names"
+                v-bind:key="engine_name"
+                :class="{ active: get_search_engine() === engine_name }"
+                @click="set_search_engine(engine_name)"
+                >{{ engines[engine_name][3] }}</span
+              >
+            </div>
+            <form
+              id="search-form"
+              ref="search_form"
+              :action="engines[search_engine][0]"
+              target="_blank"
+            >
+              <input
+                id="search-keyword"
+                ref="search_input"
+                v-model="keyword"
+                :name="engines[search_engine][1]"
+                :placeholder="engines[search_engine][2]"
+                autocomplete="off"
+                autofocus
+                class="float-left"
+                type="search"
+                @blur="blur()"
+                @focus="focus()"
+                @input="get_hot_keyword()"
+                @keydown.down="down()"
+                @keydown.prevent.up="up()"
+              />
+              <input
+                id="search-form-submit"
+                class="float-right"
+                type="submit"
+                value="搜索"
+              />
+            </form>
+            <div id="search-hot" :style="search_hot_display">
+              <ul>
+                <li
+                  v-for="(key, index) in keywords"
+                  v-bind:key="key"
+                  :class="{ selected: key_selected === index }"
+                  @click="go_submit(key)"
+                >
+                  <span :class="'search_index' + index">{{ index + 1 }}</span
+                  >{{ key }}
+                </li>
+              </ul>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+// import axios from "axios";
+import storage from "@/utils/storage";
+import fetchJsonp from "fetch-jsonp";
+
+export default {
+  name: "Home",
+  data() {
+    return {
+      search_engine: "",
+      engines: "",
+      engine_names: "",
+      keyword: "",
+      keywords: [],
+      key_selected: -1,
+      search_hot_display: "display: none",
+    };
+  },
+  created() {
+    // 将引擎列表设置为本地存储
+    if (storage.get("engines")) {
+      this.engines = storage.get("engines");
+      this.engine_names = storage.get("engines")["list"];
+      if (storage.get("search_engine")) {
+        this.set_search_engine(storage.get("search_engine"));
+      } else {
+        this.set_search_engine(this.engine_names[0]);
+      }
+    } else {
+      let engines = {
+        list: ["文档", "图片", "媒体", "图谱"],
+        文档: ["https://www.so.com/s", "q", "word pdf txt", "文档"],
+        图片: ["https://www.baidu.com/s", "wd", "jpg png bmp", "图片"],
+        媒体: ["https://www.google.com/search", "q", "mp3 mp4", "媒体"],
+        图谱: ["https://www.sogou.com/web", "query", "知识图谱数据", "图谱"],
+      };
+      storage.set("engines", engines);
+      this.engines = engines;
+      this.engine_names = storage.get("engines")["list"];
+      this.set_search_engine(this.engine_names[0]);
+    }
+  },
+  methods: {
+    set_search_engine(engine) {
+      storage.set("search_engine", engine);
+      this.search_engine = engine;
+    },
+    get_search_engine() {
+      return storage.get("search_engine");
+    },
+    get_hot_keyword() {
+      if (this.keyword === "") {
+        this.keywords = [];
+        return;
+      }
+      // https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=golang&cb=xxxxx
+      if (this.keyword !== "" && this.keyword !== "0") {
+        clearTimeout(this.timer); // 清除定时器
+        this.timer = setTimeout(() => {
+          let api =
+            "https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=" + this.keyword;
+          fetchJsonp(api, {
+            jsonpCallback: "cb",
+          })
+            .then((response) => {
+              return response.json();
+            })
+            .then((data) => {
+              this.keywords = data.s; // 用到this一定要注意this指向
+            })
+            .catch((error) => {
+              console.log(error);
+            });
+        }, 50);
+      } else {
+        this.keywords = [];
+      }
+    },
+    go_submit(val) {
+      this.keyword = val;
+      this.$refs.search_input.value = val;
+      this.$refs.search_form.submit();
+    },
+    getData(url) {
+      fetchJsonp(url, {
+        jsonpCallback: "callback",
+      })
+        .then((response) => {
+          console.log(response);
+          console.log(response.json());
+          return response.json();
+        })
+        .then((json) => {
+          this.users = json; // 在此处进行接收数据之后的操作
+        })
+        .catch((error) => {
+          console.log(error); // 此处是数据请求失败后的处理
+        });
+    },
+    down() {
+      this.key_selected = (this.key_selected + 1) % this.keywords.length;
+      this.keyword = this.keywords[this.key_selected];
+      this.$refs.search_input.value = this.keywords[this.key_selected];
+    },
+    up() {
+      this.key_selected =
+        (this.key_selected - 1 + this.keywords.length) % this.keywords.length;
+      this.keyword = this.keywords[this.key_selected];
+      this.$refs.search_input.value = this.keywords[this.key_selected];
+    },
+    blur() {
+      clearTimeout(this.timer); //清除延迟执行
+      this.timer = setTimeout(() => {
+        //设置延迟执行
+        this.search_hot_display = "display: none";
+        this.key_selected = -1;
+      }, 100);
+    },
+    focus() {
+      this.search_hot_display = "display: block";
+      this.key_selected = -1;
+      this.get_hot_keyword();
+    },
+  },
+};
+</script>
+<style lang="less" scoped>
+@import "../../assets/styles/common";
+@import "../../assets/styles/search";
+</style>

+ 39 - 0
src/views/search/nav.vue

@@ -0,0 +1,39 @@
+<template>
+  <div id="frame-box">
+    <div id="left-menu">
+      <ul id="left-menu-ul">
+        <li
+          v-for="e in list"
+          v-bind:key="e"
+          :class="{ selected: menu_selected === e }"
+          @click="menu_select(e)"
+        >
+          <a>{{ e }}</a>
+        </li>
+      </ul>
+    </div>
+    <div id="right-main"></div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "navs",
+  data() {
+    return {
+      list: ["常用", "娱乐", "学习", "设计", "开发"],
+      menu_selected: "",
+    };
+  },
+  methods: {
+    menu_select(val) {
+      this.menu_selected = val;
+    },
+  },
+  created() {
+    this.menu_selected = this.list[0];
+  },
+};
+</script>
+
+<style scoped></style>

+ 59 - 0
src/views/search/os.vue

@@ -0,0 +1,59 @@
+<template>
+  <div v-if="data" id="frame-box">
+    <div id="left-menu">
+      <ul id="left-menu-ul">
+        <li
+          v-for="e in data"
+          v-bind:key="e.info"
+          :class="{ selected: menu_selected === e.info }"
+          @click="menu_select(e.info)"
+        >
+          <a>{{ e.info }}</a>
+        </li>
+      </ul>
+    </div>
+    <div id="right-main">
+      <div v-for="e in data[list[menu_selected]].data" v-bind:key="e">
+        <span>{{ e.title }}</span>
+        <br />{{ e.name }} <br />{{ e.url }}
+      </div>
+    </div>
+  </div>
+  <div v-else>数据加载中...</div>
+</template>
+
+<script>
+import storage from "@/utils/storage";
+import axios from "axios";
+
+export default {
+  name: "os",
+  data() {
+    return {
+      list: {},
+      menu_selected: "",
+      data: "",
+    };
+  },
+  methods: {
+    menu_select(val) {
+      this.menu_selected = val;
+    },
+  },
+  created() {
+    let osdata;
+    osdata = () => axios.get("./json/osData.json");
+    osdata().then((res) => {
+      let i;
+      for (i in res.data) {
+        this.list[res.data[i].info] = i;
+      }
+      storage.set("data", res.data);
+      this.data = res.data;
+      this.menu_selected = this.data[0].info;
+    });
+  },
+};
+</script>
+
+<style scoped></style>

+ 22 - 0
src/views/search/software.vue

@@ -0,0 +1,22 @@
+<template>
+  <div id="frame-box">
+    <div id="left-menu">
+      <ul id="left-menu-ul">
+        <li class="selected"><a>正版</a></li>
+        <li><a>常用</a></li>
+        <li><a>专业</a></li>
+        <li><a>下载站</a></li>
+        <li><a>移动应用</a></li>
+      </ul>
+    </div>
+    <div id="right-main"></div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "software",
+};
+</script>
+
+<style scoped></style>