Parcourir la source

feat: 对接服务与图标

bill il y a 2 ans
Parent
commit
c1109bd2fc

+ 25 - 8
src/App.vue

@@ -2,21 +2,34 @@
   <a-layout class="layout">
     <LayoutHeader />
     <a-layout-content>
-      <div class="content content-layout">
-        <RouterView v-slot="{ Component }">
-          <KeepAlive>
-            <component :is="Component" />
-          </KeepAlive>
-        </RouterView>
+      <div ref="contentRef" class="content">
+        <div class="content-layout">
+          <RouterView v-slot="{ Component }">
+            <KeepAlive>
+              <component :is="Component" />
+            </KeepAlive>
+          </RouterView>
+        </div>
       </div>
     </a-layout-content>
   </a-layout>
 </template>
 
-<script lang="ts" setup>
+<script lang="ts">
+import { defineComponent, ref } from 'vue'
 import LayoutHeader from '@/layout/header.vue'
 
-defineOptions({ name: 'App' })
+export const contentRef = ref<HTMLDivElement>()
+
+export default defineComponent({
+  name: 'App',
+  components: {
+    LayoutHeader
+  },
+  setup() {
+    return { contentRef }
+  }
+})
 </script>
 
 <style lang="scss" scoped>
@@ -24,4 +37,8 @@ defineOptions({ name: 'App' })
 .layout {
   height: 100%;
 }
+
+.content {
+  overflow-y: auto;
+}
 </style>

+ 12 - 10
src/api/instance.ts

@@ -23,22 +23,24 @@ export const {
   setHook
 } = instance
 
-const gotoLogin = () => {
+export const gotoLogin = () => {
   const loginHref = import.meta.env.DEV
     ? 'https://test.4dkankan.com'
     : 'https://www.4dkankan.com'
 
-  if (import.meta.env.PROD) {
-    location.href = loginHref + '?redirect=' + escape(location.href)
-  } else {
-    message.error('token已过期')
-  }
+  // location.replace(
+  //   loginHref + '?redirect=' + escape(location.href) + '#/login/login'
+  // )
+}
+
+const tokenInvalid = () => {
+  message.error(ResCodeDesc[ResCode.TOKEN_INVALID])
+  setTimeout(gotoLogin, 1000)
 }
 
 addReqErrorHandler(err => {
-  message.error(err.message)
   showLoading()
-  gotoLogin()
+  tokenInvalid()
 })
 
 addResErrorHandler((response, data) => {
@@ -49,7 +51,7 @@ addResErrorHandler((response, data) => {
         ? ResCodeDesc[data.code]
         : data?.message || data?.msg
     if (data.code === ResCode.TOKEN_INVALID) {
-      gotoLogin()
+      tokenInvalid()
     } else {
       message.error(msg)
     }
@@ -64,7 +66,7 @@ addHook({
 setDefaultURI(baseURL)
 
 if (!token) {
-  gotoLogin()
+  tokenInvalid()
 } else {
   setToken(token)
 }

+ 2 - 1
src/api/room.ts

@@ -59,7 +59,8 @@ export const fetchRomms = async (): Promise<Rooms> => {
     pageNum: 1,
     pageSize: 1000
   })
-  return res.list.map(serverToLocal)
+  const rooms = res.list.map(serverToLocal)
+  return rooms
 }
 
 export const deleteRoom = async (room: Room) => {

+ 539 - 0
src/assets/iconfont/demo.css

@@ -0,0 +1,539 @@
+/* Logo 字体 */
+@font-face {
+  font-family: "iconfont logo";
+  src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
+  src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
+}
+
+.logo {
+  font-family: "iconfont logo";
+  font-size: 160px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+/* tabs */
+.nav-tabs {
+  position: relative;
+}
+
+.nav-tabs .nav-more {
+  position: absolute;
+  right: 0;
+  bottom: 0;
+  height: 42px;
+  line-height: 42px;
+  color: #666;
+}
+
+#tabs {
+  border-bottom: 1px solid #eee;
+}
+
+#tabs li {
+  cursor: pointer;
+  width: 100px;
+  height: 40px;
+  line-height: 40px;
+  text-align: center;
+  font-size: 16px;
+  border-bottom: 2px solid transparent;
+  position: relative;
+  z-index: 1;
+  margin-bottom: -1px;
+  color: #666;
+}
+
+
+#tabs .active {
+  border-bottom-color: #f00;
+  color: #222;
+}
+
+.tab-container .content {
+  display: none;
+}
+
+/* 页面布局 */
+.main {
+  padding: 30px 100px;
+  width: 960px;
+  margin: 0 auto;
+}
+
+.main .logo {
+  color: #333;
+  text-align: left;
+  margin-bottom: 30px;
+  line-height: 1;
+  height: 110px;
+  margin-top: -50px;
+  overflow: hidden;
+  *zoom: 1;
+}
+
+.main .logo a {
+  font-size: 160px;
+  color: #333;
+}
+
+.helps {
+  margin-top: 40px;
+}
+
+.helps pre {
+  padding: 20px;
+  margin: 10px 0;
+  border: solid 1px #e7e1cd;
+  background-color: #fffdef;
+  overflow: auto;
+}
+
+.icon_lists {
+  width: 100% !important;
+  overflow: hidden;
+  *zoom: 1;
+}
+
+.icon_lists li {
+  width: 100px;
+  margin-bottom: 10px;
+  margin-right: 20px;
+  text-align: center;
+  list-style: none !important;
+  cursor: default;
+}
+
+.icon_lists li .code-name {
+  line-height: 1.2;
+}
+
+.icon_lists .icon {
+  display: block;
+  height: 100px;
+  line-height: 100px;
+  font-size: 42px;
+  margin: 10px auto;
+  color: #333;
+  -webkit-transition: font-size 0.25s linear, width 0.25s linear;
+  -moz-transition: font-size 0.25s linear, width 0.25s linear;
+  transition: font-size 0.25s linear, width 0.25s linear;
+}
+
+.icon_lists .icon:hover {
+  font-size: 100px;
+}
+
+.icon_lists .svg-icon {
+  /* 通过设置 font-size 来改变图标大小 */
+  width: 1em;
+  /* 图标和文字相邻时,垂直对齐 */
+  vertical-align: -0.15em;
+  /* 通过设置 color 来改变 SVG 的颜色/fill */
+  fill: currentColor;
+  /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
+      normalize.css 中也包含这行 */
+  overflow: hidden;
+}
+
+.icon_lists li .name,
+.icon_lists li .code-name {
+  color: #666;
+}
+
+/* markdown 样式 */
+.markdown {
+  color: #666;
+  font-size: 14px;
+  line-height: 1.8;
+}
+
+.highlight {
+  line-height: 1.5;
+}
+
+.markdown img {
+  vertical-align: middle;
+  max-width: 100%;
+}
+
+.markdown h1 {
+  color: #404040;
+  font-weight: 500;
+  line-height: 40px;
+  margin-bottom: 24px;
+}
+
+.markdown h2,
+.markdown h3,
+.markdown h4,
+.markdown h5,
+.markdown h6 {
+  color: #404040;
+  margin: 1.6em 0 0.6em 0;
+  font-weight: 500;
+  clear: both;
+}
+
+.markdown h1 {
+  font-size: 28px;
+}
+
+.markdown h2 {
+  font-size: 22px;
+}
+
+.markdown h3 {
+  font-size: 16px;
+}
+
+.markdown h4 {
+  font-size: 14px;
+}
+
+.markdown h5 {
+  font-size: 12px;
+}
+
+.markdown h6 {
+  font-size: 12px;
+}
+
+.markdown hr {
+  height: 1px;
+  border: 0;
+  background: #e9e9e9;
+  margin: 16px 0;
+  clear: both;
+}
+
+.markdown p {
+  margin: 1em 0;
+}
+
+.markdown>p,
+.markdown>blockquote,
+.markdown>.highlight,
+.markdown>ol,
+.markdown>ul {
+  width: 80%;
+}
+
+.markdown ul>li {
+  list-style: circle;
+}
+
+.markdown>ul li,
+.markdown blockquote ul>li {
+  margin-left: 20px;
+  padding-left: 4px;
+}
+
+.markdown>ul li p,
+.markdown>ol li p {
+  margin: 0.6em 0;
+}
+
+.markdown ol>li {
+  list-style: decimal;
+}
+
+.markdown>ol li,
+.markdown blockquote ol>li {
+  margin-left: 20px;
+  padding-left: 4px;
+}
+
+.markdown code {
+  margin: 0 3px;
+  padding: 0 5px;
+  background: #eee;
+  border-radius: 3px;
+}
+
+.markdown strong,
+.markdown b {
+  font-weight: 600;
+}
+
+.markdown>table {
+  border-collapse: collapse;
+  border-spacing: 0px;
+  empty-cells: show;
+  border: 1px solid #e9e9e9;
+  width: 95%;
+  margin-bottom: 24px;
+}
+
+.markdown>table th {
+  white-space: nowrap;
+  color: #333;
+  font-weight: 600;
+}
+
+.markdown>table th,
+.markdown>table td {
+  border: 1px solid #e9e9e9;
+  padding: 8px 16px;
+  text-align: left;
+}
+
+.markdown>table th {
+  background: #F7F7F7;
+}
+
+.markdown blockquote {
+  font-size: 90%;
+  color: #999;
+  border-left: 4px solid #e9e9e9;
+  padding-left: 0.8em;
+  margin: 1em 0;
+}
+
+.markdown blockquote p {
+  margin: 0;
+}
+
+.markdown .anchor {
+  opacity: 0;
+  transition: opacity 0.3s ease;
+  margin-left: 8px;
+}
+
+.markdown .waiting {
+  color: #ccc;
+}
+
+.markdown h1:hover .anchor,
+.markdown h2:hover .anchor,
+.markdown h3:hover .anchor,
+.markdown h4:hover .anchor,
+.markdown h5:hover .anchor,
+.markdown h6:hover .anchor {
+  opacity: 1;
+  display: inline-block;
+}
+
+.markdown>br,
+.markdown>p>br {
+  clear: both;
+}
+
+
+.hljs {
+  display: block;
+  background: white;
+  padding: 0.5em;
+  color: #333333;
+  overflow-x: auto;
+}
+
+.hljs-comment,
+.hljs-meta {
+  color: #969896;
+}
+
+.hljs-string,
+.hljs-variable,
+.hljs-template-variable,
+.hljs-strong,
+.hljs-emphasis,
+.hljs-quote {
+  color: #df5000;
+}
+
+.hljs-keyword,
+.hljs-selector-tag,
+.hljs-type {
+  color: #a71d5d;
+}
+
+.hljs-literal,
+.hljs-symbol,
+.hljs-bullet,
+.hljs-attribute {
+  color: #0086b3;
+}
+
+.hljs-section,
+.hljs-name {
+  color: #63a35c;
+}
+
+.hljs-tag {
+  color: #333333;
+}
+
+.hljs-title,
+.hljs-attr,
+.hljs-selector-id,
+.hljs-selector-class,
+.hljs-selector-attr,
+.hljs-selector-pseudo {
+  color: #795da3;
+}
+
+.hljs-addition {
+  color: #55a532;
+  background-color: #eaffea;
+}
+
+.hljs-deletion {
+  color: #bd2c00;
+  background-color: #ffecec;
+}
+
+.hljs-link {
+  text-decoration: underline;
+}
+
+/* 代码高亮 */
+/* PrismJS 1.15.0
+https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
+/**
+ * prism.js default theme for JavaScript, CSS and HTML
+ * Based on dabblet (http://dabblet.com)
+ * @author Lea Verou
+ */
+code[class*="language-"],
+pre[class*="language-"] {
+  color: black;
+  background: none;
+  text-shadow: 0 1px white;
+  font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
+  text-align: left;
+  white-space: pre;
+  word-spacing: normal;
+  word-break: normal;
+  word-wrap: normal;
+  line-height: 1.5;
+
+  -moz-tab-size: 4;
+  -o-tab-size: 4;
+  tab-size: 4;
+
+  -webkit-hyphens: none;
+  -moz-hyphens: none;
+  -ms-hyphens: none;
+  hyphens: none;
+}
+
+pre[class*="language-"]::-moz-selection,
+pre[class*="language-"] ::-moz-selection,
+code[class*="language-"]::-moz-selection,
+code[class*="language-"] ::-moz-selection {
+  text-shadow: none;
+  background: #b3d4fc;
+}
+
+pre[class*="language-"]::selection,
+pre[class*="language-"] ::selection,
+code[class*="language-"]::selection,
+code[class*="language-"] ::selection {
+  text-shadow: none;
+  background: #b3d4fc;
+}
+
+@media print {
+
+  code[class*="language-"],
+  pre[class*="language-"] {
+    text-shadow: none;
+  }
+}
+
+/* Code blocks */
+pre[class*="language-"] {
+  padding: 1em;
+  margin: .5em 0;
+  overflow: auto;
+}
+
+:not(pre)>code[class*="language-"],
+pre[class*="language-"] {
+  background: #f5f2f0;
+}
+
+/* Inline code */
+:not(pre)>code[class*="language-"] {
+  padding: .1em;
+  border-radius: .3em;
+  white-space: normal;
+}
+
+.token.comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+  color: slategray;
+}
+
+.token.punctuation {
+  color: #999;
+}
+
+.namespace {
+  opacity: .7;
+}
+
+.token.property,
+.token.tag,
+.token.boolean,
+.token.number,
+.token.constant,
+.token.symbol,
+.token.deleted {
+  color: #905;
+}
+
+.token.selector,
+.token.attr-name,
+.token.string,
+.token.char,
+.token.builtin,
+.token.inserted {
+  color: #690;
+}
+
+.token.operator,
+.token.entity,
+.token.url,
+.language-css .token.string,
+.style .token.string {
+  color: #9a6e3a;
+  background: hsla(0, 0%, 100%, .5);
+}
+
+.token.atrule,
+.token.attr-value,
+.token.keyword {
+  color: #07a;
+}
+
+.token.function,
+.token.class-name {
+  color: #DD4A68;
+}
+
+.token.regex,
+.token.important,
+.token.variable {
+  color: #e90;
+}
+
+.token.important,
+.token.bold {
+  font-weight: bold;
+}
+
+.token.italic {
+  font-style: italic;
+}
+
+.token.entity {
+  cursor: help;
+}

+ 925 - 0
src/assets/iconfont/demo_index.html

@@ -0,0 +1,925 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8"/>
+  <title>iconfont Demo</title>
+  <link rel="shortcut icon" href="//img.alicdn.com/imgextra/i4/O1CN01Z5paLz1O0zuCC7osS_!!6000000001644-55-tps-83-82.svg" type="image/x-icon"/>
+  <link rel="icon" type="image/svg+xml" href="//img.alicdn.com/imgextra/i4/O1CN01Z5paLz1O0zuCC7osS_!!6000000001644-55-tps-83-82.svg"/>
+  <link rel="stylesheet" href="https://g.alicdn.com/thx/cube/1.3.2/cube.min.css">
+  <link rel="stylesheet" href="demo.css">
+  <link rel="stylesheet" href="iconfont.css">
+  <script src="iconfont.js"></script>
+  <!-- jQuery -->
+  <script src="https://a1.alicdn.com/oss/uploads/2018/12/26/7bfddb60-08e8-11e9-9b04-53e73bb6408b.js"></script>
+  <!-- 代码高亮 -->
+  <script src="https://a1.alicdn.com/oss/uploads/2018/12/26/a3f714d0-08e6-11e9-8a15-ebf944d7534c.js"></script>
+  <style>
+    .main .logo {
+      margin-top: 0;
+      height: auto;
+    }
+
+    .main .logo a {
+      display: flex;
+      align-items: center;
+    }
+
+    .main .logo .sub-title {
+      margin-left: 0.5em;
+      font-size: 22px;
+      color: #fff;
+      background: linear-gradient(-45deg, #3967FF, #B500FE);
+      -webkit-background-clip: text;
+      -webkit-text-fill-color: transparent;
+    }
+  </style>
+</head>
+<body>
+  <div class="main">
+    <h1 class="logo"><a href="https://www.iconfont.cn/" title="iconfont 首页" target="_blank">
+      <img width="200" src="https://img.alicdn.com/imgextra/i3/O1CN01Mn65HV1FfSEzR6DKv_!!6000000000514-55-tps-228-59.svg">
+      
+    </a></h1>
+    <div class="nav-tabs">
+      <ul id="tabs" class="dib-box">
+        <li class="dib active"><span>Unicode</span></li>
+        <li class="dib"><span>Font class</span></li>
+        <li class="dib"><span>Symbol</span></li>
+      </ul>
+      
+      <a href="https://www.iconfont.cn/manage/index?manage_type=myprojects&projectId=3676870" target="_blank" class="nav-more">查看项目</a>
+      
+    </div>
+    <div class="tab-container">
+      <div class="content unicode" style="display: block;">
+          <ul class="icon_lists dib-box">
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe704;</span>
+                <div class="name">brushes</div>
+                <div class="code-name">&amp;#xe704;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe710;</span>
+                <div class="name">pop-up_screen_off</div>
+                <div class="code-name">&amp;#xe710;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe712;</span>
+                <div class="name">pop-up_screen_on</div>
+                <div class="code-name">&amp;#xe712;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe703;</span>
+                <div class="name">arrow</div>
+                <div class="code-name">&amp;#xe703;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe705;</span>
+                <div class="name">arrows</div>
+                <div class="code-name">&amp;#xe705;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe706;</span>
+                <div class="name">chat_on</div>
+                <div class="code-name">&amp;#xe706;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe707;</span>
+                <div class="name">exit</div>
+                <div class="code-name">&amp;#xe707;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe708;</span>
+                <div class="name">cross</div>
+                <div class="code-name">&amp;#xe708;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe709;</span>
+                <div class="name">chat_off</div>
+                <div class="code-name">&amp;#xe709;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe70a;</span>
+                <div class="name">guided</div>
+                <div class="code-name">&amp;#xe70a;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe70b;</span>
+                <div class="name">members</div>
+                <div class="code-name">&amp;#xe70b;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe70c;</span>
+                <div class="name">list</div>
+                <div class="code-name">&amp;#xe70c;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe70d;</span>
+                <div class="name">mic_off</div>
+                <div class="code-name">&amp;#xe70d;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe70e;</span>
+                <div class="name">mic_on</div>
+                <div class="code-name">&amp;#xe70e;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe70f;</span>
+                <div class="name">invitation</div>
+                <div class="code-name">&amp;#xe70f;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe711;</span>
+                <div class="name">revocation</div>
+                <div class="code-name">&amp;#xe711;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe713;</span>
+                <div class="name">show</div>
+                <div class="code-name">&amp;#xe713;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe702;</span>
+                <div class="name">Checkbox-off</div>
+                <div class="code-name">&amp;#xe702;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe6fd;</span>
+                <div class="name">works_delete</div>
+                <div class="code-name">&amp;#xe6fd;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe6fc;</span>
+                <div class="name">Checkbox-on</div>
+                <div class="code-name">&amp;#xe6fc;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe6fe;</span>
+                <div class="name">works_cancel</div>
+                <div class="code-name">&amp;#xe6fe;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe6ff;</span>
+                <div class="name">toast_green</div>
+                <div class="code-name">&amp;#xe6ff;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe700;</span>
+                <div class="name">toast_red</div>
+                <div class="code-name">&amp;#xe700;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe701;</span>
+                <div class="name">toast_yellow</div>
+                <div class="code-name">&amp;#xe701;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe6f4;</span>
+                <div class="name">material_preview_upload_collect</div>
+                <div class="code-name">&amp;#xe6f4;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe6f5;</span>
+                <div class="name">pop-ups_shut-down</div>
+                <div class="code-name">&amp;#xe6f5;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe6f6;</span>
+                <div class="name">works_add</div>
+                <div class="code-name">&amp;#xe6f6;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe6f7;</span>
+                <div class="name">works_search</div>
+                <div class="code-name">&amp;#xe6f7;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe6f8;</span>
+                <div class="name">top</div>
+                <div class="code-name">&amp;#xe6f8;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe6f9;</span>
+                <div class="name">works_share</div>
+                <div class="code-name">&amp;#xe6f9;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe6fa;</span>
+                <div class="name">works_look</div>
+                <div class="code-name">&amp;#xe6fa;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe6fb;</span>
+                <div class="name">works_editor</div>
+                <div class="code-name">&amp;#xe6fb;</div>
+              </li>
+          
+          </ul>
+          <div class="article markdown">
+          <h2 id="unicode-">Unicode 引用</h2>
+          <hr>
+
+          <p>Unicode 是字体在网页端最原始的应用方式,特点是:</p>
+          <ul>
+            <li>支持按字体的方式去动态调整图标大小,颜色等等。</li>
+            <li>默认情况下不支持多色,直接添加多色图标会自动去色。</li>
+          </ul>
+          <blockquote>
+            <p>注意:新版 iconfont 支持两种方式引用多色图标:SVG symbol 引用方式和彩色字体图标模式。(使用彩色字体图标需要在「编辑项目」中开启「彩色」选项后并重新生成。)</p>
+          </blockquote>
+          <p>Unicode 使用步骤如下:</p>
+          <h3 id="-font-face">第一步:拷贝项目下面生成的 <code>@font-face</code></h3>
+<pre><code class="language-css"
+>@font-face {
+  font-family: 'iconfont';
+  src: url('iconfont.woff2?t=1664433387288') format('woff2'),
+       url('iconfont.woff?t=1664433387288') format('woff'),
+       url('iconfont.ttf?t=1664433387288') format('truetype'),
+       url('iconfont.svg?t=1664433387288#iconfont') format('svg');
+}
+</code></pre>
+          <h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
+<pre><code class="language-css"
+>.iconfont {
+  font-family: "iconfont" !important;
+  font-size: 16px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+</code></pre>
+          <h3 id="-">第三步:挑选相应图标并获取字体编码,应用于页面</h3>
+<pre>
+<code class="language-html"
+>&lt;span class="iconfont"&gt;&amp;#x33;&lt;/span&gt;
+</code></pre>
+          <blockquote>
+            <p>"iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p>
+          </blockquote>
+          </div>
+      </div>
+      <div class="content font-class">
+        <ul class="icon_lists dib-box">
+          
+          <li class="dib">
+            <span class="icon iconfont icon-brushes"></span>
+            <div class="name">
+              brushes
+            </div>
+            <div class="code-name">.icon-brushes
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-pop-up_screen_off"></span>
+            <div class="name">
+              pop-up_screen_off
+            </div>
+            <div class="code-name">.icon-pop-up_screen_off
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-pop-up_screen_on"></span>
+            <div class="name">
+              pop-up_screen_on
+            </div>
+            <div class="code-name">.icon-pop-up_screen_on
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-arrow"></span>
+            <div class="name">
+              arrow
+            </div>
+            <div class="code-name">.icon-arrow
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-arrows"></span>
+            <div class="name">
+              arrows
+            </div>
+            <div class="code-name">.icon-arrows
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-chat_on"></span>
+            <div class="name">
+              chat_on
+            </div>
+            <div class="code-name">.icon-chat_on
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-exit"></span>
+            <div class="name">
+              exit
+            </div>
+            <div class="code-name">.icon-exit
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-cross"></span>
+            <div class="name">
+              cross
+            </div>
+            <div class="code-name">.icon-cross
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-chat_off"></span>
+            <div class="name">
+              chat_off
+            </div>
+            <div class="code-name">.icon-chat_off
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-guided"></span>
+            <div class="name">
+              guided
+            </div>
+            <div class="code-name">.icon-guided
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-members"></span>
+            <div class="name">
+              members
+            </div>
+            <div class="code-name">.icon-members
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-list"></span>
+            <div class="name">
+              list
+            </div>
+            <div class="code-name">.icon-list
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-mic_off"></span>
+            <div class="name">
+              mic_off
+            </div>
+            <div class="code-name">.icon-mic_off
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-mic_on"></span>
+            <div class="name">
+              mic_on
+            </div>
+            <div class="code-name">.icon-mic_on
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-invitation"></span>
+            <div class="name">
+              invitation
+            </div>
+            <div class="code-name">.icon-invitation
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-revocation"></span>
+            <div class="name">
+              revocation
+            </div>
+            <div class="code-name">.icon-revocation
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-show"></span>
+            <div class="name">
+              show
+            </div>
+            <div class="code-name">.icon-show
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-Checkbox-off"></span>
+            <div class="name">
+              Checkbox-off
+            </div>
+            <div class="code-name">.icon-Checkbox-off
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-works_delete"></span>
+            <div class="name">
+              works_delete
+            </div>
+            <div class="code-name">.icon-works_delete
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-Checkbox-on"></span>
+            <div class="name">
+              Checkbox-on
+            </div>
+            <div class="code-name">.icon-Checkbox-on
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-works_cancel"></span>
+            <div class="name">
+              works_cancel
+            </div>
+            <div class="code-name">.icon-works_cancel
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-toast_green"></span>
+            <div class="name">
+              toast_green
+            </div>
+            <div class="code-name">.icon-toast_green
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-toast_red"></span>
+            <div class="name">
+              toast_red
+            </div>
+            <div class="code-name">.icon-toast_red
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-toast_yellow"></span>
+            <div class="name">
+              toast_yellow
+            </div>
+            <div class="code-name">.icon-toast_yellow
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-material_preview_upload_collect"></span>
+            <div class="name">
+              material_preview_upload_collect
+            </div>
+            <div class="code-name">.icon-material_preview_upload_collect
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-pop-ups_shut-down"></span>
+            <div class="name">
+              pop-ups_shut-down
+            </div>
+            <div class="code-name">.icon-pop-ups_shut-down
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-works_add"></span>
+            <div class="name">
+              works_add
+            </div>
+            <div class="code-name">.icon-works_add
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-works_search"></span>
+            <div class="name">
+              works_search
+            </div>
+            <div class="code-name">.icon-works_search
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-top"></span>
+            <div class="name">
+              top
+            </div>
+            <div class="code-name">.icon-top
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-works_share"></span>
+            <div class="name">
+              works_share
+            </div>
+            <div class="code-name">.icon-works_share
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-works_look"></span>
+            <div class="name">
+              works_look
+            </div>
+            <div class="code-name">.icon-works_look
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-works_editor"></span>
+            <div class="name">
+              works_editor
+            </div>
+            <div class="code-name">.icon-works_editor
+            </div>
+          </li>
+          
+        </ul>
+        <div class="article markdown">
+        <h2 id="font-class-">font-class 引用</h2>
+        <hr>
+
+        <p>font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。</p>
+        <p>与 Unicode 使用方式相比,具有如下特点:</p>
+        <ul>
+          <li>相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。</li>
+          <li>因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。</li>
+        </ul>
+        <p>使用步骤如下:</p>
+        <h3 id="-fontclass-">第一步:引入项目下面生成的 fontclass 代码:</h3>
+<pre><code class="language-html">&lt;link rel="stylesheet" href="./iconfont.css"&gt;
+</code></pre>
+        <h3 id="-">第二步:挑选相应图标并获取类名,应用于页面:</h3>
+<pre><code class="language-html">&lt;span class="iconfont icon-xxx"&gt;&lt;/span&gt;
+</code></pre>
+        <blockquote>
+          <p>"
+            iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p>
+        </blockquote>
+      </div>
+      </div>
+      <div class="content symbol">
+          <ul class="icon_lists dib-box">
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-brushes"></use>
+                </svg>
+                <div class="name">brushes</div>
+                <div class="code-name">#icon-brushes</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-pop-up_screen_off"></use>
+                </svg>
+                <div class="name">pop-up_screen_off</div>
+                <div class="code-name">#icon-pop-up_screen_off</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-pop-up_screen_on"></use>
+                </svg>
+                <div class="name">pop-up_screen_on</div>
+                <div class="code-name">#icon-pop-up_screen_on</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-arrow"></use>
+                </svg>
+                <div class="name">arrow</div>
+                <div class="code-name">#icon-arrow</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-arrows"></use>
+                </svg>
+                <div class="name">arrows</div>
+                <div class="code-name">#icon-arrows</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-chat_on"></use>
+                </svg>
+                <div class="name">chat_on</div>
+                <div class="code-name">#icon-chat_on</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-exit"></use>
+                </svg>
+                <div class="name">exit</div>
+                <div class="code-name">#icon-exit</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-cross"></use>
+                </svg>
+                <div class="name">cross</div>
+                <div class="code-name">#icon-cross</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-chat_off"></use>
+                </svg>
+                <div class="name">chat_off</div>
+                <div class="code-name">#icon-chat_off</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-guided"></use>
+                </svg>
+                <div class="name">guided</div>
+                <div class="code-name">#icon-guided</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-members"></use>
+                </svg>
+                <div class="name">members</div>
+                <div class="code-name">#icon-members</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-list"></use>
+                </svg>
+                <div class="name">list</div>
+                <div class="code-name">#icon-list</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-mic_off"></use>
+                </svg>
+                <div class="name">mic_off</div>
+                <div class="code-name">#icon-mic_off</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-mic_on"></use>
+                </svg>
+                <div class="name">mic_on</div>
+                <div class="code-name">#icon-mic_on</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-invitation"></use>
+                </svg>
+                <div class="name">invitation</div>
+                <div class="code-name">#icon-invitation</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-revocation"></use>
+                </svg>
+                <div class="name">revocation</div>
+                <div class="code-name">#icon-revocation</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-show"></use>
+                </svg>
+                <div class="name">show</div>
+                <div class="code-name">#icon-show</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-Checkbox-off"></use>
+                </svg>
+                <div class="name">Checkbox-off</div>
+                <div class="code-name">#icon-Checkbox-off</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-works_delete"></use>
+                </svg>
+                <div class="name">works_delete</div>
+                <div class="code-name">#icon-works_delete</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-Checkbox-on"></use>
+                </svg>
+                <div class="name">Checkbox-on</div>
+                <div class="code-name">#icon-Checkbox-on</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-works_cancel"></use>
+                </svg>
+                <div class="name">works_cancel</div>
+                <div class="code-name">#icon-works_cancel</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-toast_green"></use>
+                </svg>
+                <div class="name">toast_green</div>
+                <div class="code-name">#icon-toast_green</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-toast_red"></use>
+                </svg>
+                <div class="name">toast_red</div>
+                <div class="code-name">#icon-toast_red</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-toast_yellow"></use>
+                </svg>
+                <div class="name">toast_yellow</div>
+                <div class="code-name">#icon-toast_yellow</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-material_preview_upload_collect"></use>
+                </svg>
+                <div class="name">material_preview_upload_collect</div>
+                <div class="code-name">#icon-material_preview_upload_collect</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-pop-ups_shut-down"></use>
+                </svg>
+                <div class="name">pop-ups_shut-down</div>
+                <div class="code-name">#icon-pop-ups_shut-down</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-works_add"></use>
+                </svg>
+                <div class="name">works_add</div>
+                <div class="code-name">#icon-works_add</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-works_search"></use>
+                </svg>
+                <div class="name">works_search</div>
+                <div class="code-name">#icon-works_search</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-top"></use>
+                </svg>
+                <div class="name">top</div>
+                <div class="code-name">#icon-top</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-works_share"></use>
+                </svg>
+                <div class="name">works_share</div>
+                <div class="code-name">#icon-works_share</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-works_look"></use>
+                </svg>
+                <div class="name">works_look</div>
+                <div class="code-name">#icon-works_look</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-works_editor"></use>
+                </svg>
+                <div class="name">works_editor</div>
+                <div class="code-name">#icon-works_editor</div>
+            </li>
+          
+          </ul>
+          <div class="article markdown">
+          <h2 id="symbol-">Symbol 引用</h2>
+          <hr>
+
+          <p>这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇<a href="">文章</a>
+            这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:</p>
+          <ul>
+            <li>支持多色图标了,不再受单色限制。</li>
+            <li>通过一些技巧,支持像字体那样,通过 <code>font-size</code>, <code>color</code> 来调整样式。</li>
+            <li>兼容性较差,支持 IE9+,及现代浏览器。</li>
+            <li>浏览器渲染 SVG 的性能一般,还不如 png。</li>
+          </ul>
+          <p>使用步骤如下:</p>
+          <h3 id="-symbol-">第一步:引入项目下面生成的 symbol 代码:</h3>
+<pre><code class="language-html">&lt;script src="./iconfont.js"&gt;&lt;/script&gt;
+</code></pre>
+          <h3 id="-css-">第二步:加入通用 CSS 代码(引入一次就行):</h3>
+<pre><code class="language-html">&lt;style&gt;
+.icon {
+  width: 1em;
+  height: 1em;
+  vertical-align: -0.15em;
+  fill: currentColor;
+  overflow: hidden;
+}
+&lt;/style&gt;
+</code></pre>
+          <h3 id="-">第三步:挑选相应图标并获取类名,应用于页面:</h3>
+<pre><code class="language-html">&lt;svg class="icon" aria-hidden="true"&gt;
+  &lt;use xlink:href="#icon-xxx"&gt;&lt;/use&gt;
+&lt;/svg&gt;
+</code></pre>
+          </div>
+      </div>
+
+    </div>
+  </div>
+  <script>
+  $(document).ready(function () {
+      $('.tab-container .content:first').show()
+
+      $('#tabs li').click(function (e) {
+        var tabContent = $('.tab-container .content')
+        var index = $(this).index()
+
+        if ($(this).hasClass('active')) {
+          return
+        } else {
+          $('#tabs li').removeClass('active')
+          $(this).addClass('active')
+
+          tabContent.hide().eq(index).fadeIn()
+        }
+      })
+    })
+  </script>
+</body>
+</html>

+ 144 - 0
src/assets/iconfont/iconfont.css

@@ -0,0 +1,144 @@
+@font-face {
+  font-family: "iconfont"; /* Project id 3676870 */
+  src: url('iconfont.woff2?t=1664433387288') format('woff2'),
+       url('iconfont.woff?t=1664433387288') format('woff'),
+       url('iconfont.ttf?t=1664433387288') format('truetype'),
+       url('iconfont.svg?t=1664433387288#iconfont') format('svg');
+}
+
+.iconfont {
+  font-family: "iconfont" !important;
+  font-size: 16px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+.icon-brushes:before {
+  content: "\e704";
+}
+
+.icon-pop-up_screen_off:before {
+  content: "\e710";
+}
+
+.icon-pop-up_screen_on:before {
+  content: "\e712";
+}
+
+.icon-arrow:before {
+  content: "\e703";
+}
+
+.icon-arrows:before {
+  content: "\e705";
+}
+
+.icon-chat_on:before {
+  content: "\e706";
+}
+
+.icon-exit:before {
+  content: "\e707";
+}
+
+.icon-cross:before {
+  content: "\e708";
+}
+
+.icon-chat_off:before {
+  content: "\e709";
+}
+
+.icon-guided:before {
+  content: "\e70a";
+}
+
+.icon-members:before {
+  content: "\e70b";
+}
+
+.icon-list:before {
+  content: "\e70c";
+}
+
+.icon-mic_off:before {
+  content: "\e70d";
+}
+
+.icon-mic_on:before {
+  content: "\e70e";
+}
+
+.icon-invitation:before {
+  content: "\e70f";
+}
+
+.icon-revocation:before {
+  content: "\e711";
+}
+
+.icon-show:before {
+  content: "\e713";
+}
+
+.icon-Checkbox-off:before {
+  content: "\e702";
+}
+
+.icon-works_delete:before {
+  content: "\e6fd";
+}
+
+.icon-Checkbox-on:before {
+  content: "\e6fc";
+}
+
+.icon-works_cancel:before {
+  content: "\e6fe";
+}
+
+.icon-toast_green:before {
+  content: "\e6ff";
+}
+
+.icon-toast_red:before {
+  content: "\e700";
+}
+
+.icon-toast_yellow:before {
+  content: "\e701";
+}
+
+.icon-material_preview_upload_collect:before {
+  content: "\e6f4";
+}
+
+.icon-pop-ups_shut-down:before {
+  content: "\e6f5";
+}
+
+.icon-works_add:before {
+  content: "\e6f6";
+}
+
+.icon-works_search:before {
+  content: "\e6f7";
+}
+
+.icon-top:before {
+  content: "\e6f8";
+}
+
+.icon-works_share:before {
+  content: "\e6f9";
+}
+
+.icon-works_look:before {
+  content: "\e6fa";
+}
+
+.icon-works_editor:before {
+  content: "\e6fb";
+}
+

Fichier diff supprimé car celui-ci est trop grand
+ 1 - 0
src/assets/iconfont/iconfont.js


+ 233 - 0
src/assets/iconfont/iconfont.json

@@ -0,0 +1,233 @@
+{
+  "id": "3676870",
+  "name": "四维带看2.0",
+  "font_family": "iconfont",
+  "css_prefix_text": "icon-",
+  "description": "",
+  "glyphs": [
+    {
+      "icon_id": "32082999",
+      "name": "brushes",
+      "font_class": "brushes",
+      "unicode": "e704",
+      "unicode_decimal": 59140
+    },
+    {
+      "icon_id": "32083001",
+      "name": "pop-up_screen_off",
+      "font_class": "pop-up_screen_off",
+      "unicode": "e710",
+      "unicode_decimal": 59152
+    },
+    {
+      "icon_id": "32083004",
+      "name": "pop-up_screen_on",
+      "font_class": "pop-up_screen_on",
+      "unicode": "e712",
+      "unicode_decimal": 59154
+    },
+    {
+      "icon_id": "32082923",
+      "name": "arrow",
+      "font_class": "arrow",
+      "unicode": "e703",
+      "unicode_decimal": 59139
+    },
+    {
+      "icon_id": "32082925",
+      "name": "arrows",
+      "font_class": "arrows",
+      "unicode": "e705",
+      "unicode_decimal": 59141
+    },
+    {
+      "icon_id": "32082926",
+      "name": "chat_on",
+      "font_class": "chat_on",
+      "unicode": "e706",
+      "unicode_decimal": 59142
+    },
+    {
+      "icon_id": "32082927",
+      "name": "exit",
+      "font_class": "exit",
+      "unicode": "e707",
+      "unicode_decimal": 59143
+    },
+    {
+      "icon_id": "32082928",
+      "name": "cross",
+      "font_class": "cross",
+      "unicode": "e708",
+      "unicode_decimal": 59144
+    },
+    {
+      "icon_id": "32082929",
+      "name": "chat_off",
+      "font_class": "chat_off",
+      "unicode": "e709",
+      "unicode_decimal": 59145
+    },
+    {
+      "icon_id": "32082930",
+      "name": "guided",
+      "font_class": "guided",
+      "unicode": "e70a",
+      "unicode_decimal": 59146
+    },
+    {
+      "icon_id": "32082931",
+      "name": "members",
+      "font_class": "members",
+      "unicode": "e70b",
+      "unicode_decimal": 59147
+    },
+    {
+      "icon_id": "32082932",
+      "name": "list",
+      "font_class": "list",
+      "unicode": "e70c",
+      "unicode_decimal": 59148
+    },
+    {
+      "icon_id": "32082933",
+      "name": "mic_off",
+      "font_class": "mic_off",
+      "unicode": "e70d",
+      "unicode_decimal": 59149
+    },
+    {
+      "icon_id": "32082934",
+      "name": "mic_on",
+      "font_class": "mic_on",
+      "unicode": "e70e",
+      "unicode_decimal": 59150
+    },
+    {
+      "icon_id": "32082935",
+      "name": "invitation",
+      "font_class": "invitation",
+      "unicode": "e70f",
+      "unicode_decimal": 59151
+    },
+    {
+      "icon_id": "32082937",
+      "name": "revocation",
+      "font_class": "revocation",
+      "unicode": "e711",
+      "unicode_decimal": 59153
+    },
+    {
+      "icon_id": "32082939",
+      "name": "show",
+      "font_class": "show",
+      "unicode": "e713",
+      "unicode_decimal": 59155
+    },
+    {
+      "icon_id": "32081381",
+      "name": "Checkbox-off",
+      "font_class": "Checkbox-off",
+      "unicode": "e702",
+      "unicode_decimal": 59138
+    },
+    {
+      "icon_id": "32081238",
+      "name": "works_delete",
+      "font_class": "works_delete",
+      "unicode": "e6fd",
+      "unicode_decimal": 59133
+    },
+    {
+      "icon_id": "32079562",
+      "name": "Checkbox-on",
+      "font_class": "Checkbox-on",
+      "unicode": "e6fc",
+      "unicode_decimal": 59132
+    },
+    {
+      "icon_id": "32079564",
+      "name": "works_cancel",
+      "font_class": "works_cancel",
+      "unicode": "e6fe",
+      "unicode_decimal": 59134
+    },
+    {
+      "icon_id": "32079565",
+      "name": "toast_green",
+      "font_class": "toast_green",
+      "unicode": "e6ff",
+      "unicode_decimal": 59135
+    },
+    {
+      "icon_id": "32079566",
+      "name": "toast_red",
+      "font_class": "toast_red",
+      "unicode": "e700",
+      "unicode_decimal": 59136
+    },
+    {
+      "icon_id": "32079567",
+      "name": "toast_yellow",
+      "font_class": "toast_yellow",
+      "unicode": "e701",
+      "unicode_decimal": 59137
+    },
+    {
+      "icon_id": "32078822",
+      "name": "material_preview_upload_collect",
+      "font_class": "material_preview_upload_collect",
+      "unicode": "e6f4",
+      "unicode_decimal": 59124
+    },
+    {
+      "icon_id": "32078823",
+      "name": "pop-ups_shut-down",
+      "font_class": "pop-ups_shut-down",
+      "unicode": "e6f5",
+      "unicode_decimal": 59125
+    },
+    {
+      "icon_id": "32078825",
+      "name": "works_add",
+      "font_class": "works_add",
+      "unicode": "e6f6",
+      "unicode_decimal": 59126
+    },
+    {
+      "icon_id": "32078826",
+      "name": "works_search",
+      "font_class": "works_search",
+      "unicode": "e6f7",
+      "unicode_decimal": 59127
+    },
+    {
+      "icon_id": "32078827",
+      "name": "top",
+      "font_class": "top",
+      "unicode": "e6f8",
+      "unicode_decimal": 59128
+    },
+    {
+      "icon_id": "32078828",
+      "name": "works_share",
+      "font_class": "works_share",
+      "unicode": "e6f9",
+      "unicode_decimal": 59129
+    },
+    {
+      "icon_id": "32078829",
+      "name": "works_look",
+      "font_class": "works_look",
+      "unicode": "e6fa",
+      "unicode_decimal": 59130
+    },
+    {
+      "icon_id": "32078830",
+      "name": "works_editor",
+      "font_class": "works_editor",
+      "unicode": "e6fb",
+      "unicode_decimal": 59131
+    }
+  ]
+}

Fichier diff supprimé car celui-ci est trop grand
+ 83 - 0
src/assets/iconfont/iconfont.svg


BIN
src/assets/iconfont/iconfont.ttf


BIN
src/assets/iconfont/iconfont.woff


BIN
src/assets/iconfont/iconfont.woff2


BIN
src/assets/images/un-data.png


BIN
src/assets/images/un-scene.png


+ 1 - 10
src/components.d.ts

@@ -10,19 +10,15 @@ declare module '@vue/runtime-core' {
     AAvatar: typeof import('ant-design-vue/es')['Avatar']
     AButton: typeof import('ant-design-vue/es')['Button']
     ACard: typeof import('ant-design-vue/es')['Card']
-    ACardMeta: typeof import('ant-design-vue/es')['CardMeta']
     ADropdown: typeof import('ant-design-vue/es')['Dropdown']
-    AEmpty: typeof import('ant-design-vue/es')['Empty']
     AForm: typeof import('ant-design-vue/es')['Form']
     AFormItem: typeof import('ant-design-vue/es')['FormItem']
     AInput: typeof import('ant-design-vue/es')['Input']
     ALayout: typeof import('ant-design-vue/es')['Layout']
     ALayoutContent: typeof import('ant-design-vue/es')['LayoutContent']
-    ALayoutFooter: typeof import('ant-design-vue/es')['LayoutFooter']
     ALayoutHeader: typeof import('ant-design-vue/es')['LayoutHeader']
     AList: typeof import('ant-design-vue/es')['List']
     AListItem: typeof import('ant-design-vue/es')['ListItem']
-    AliyunOutlined: typeof import('@ant-design/icons-vue')['AliyunOutlined']
     AMenu: typeof import('ant-design-vue/es')['Menu']
     AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
     AModal: typeof import('ant-design-vue/es')['Modal']
@@ -31,18 +27,13 @@ declare module '@vue/runtime-core' {
     ATextarea: typeof import('ant-design-vue/es')['Textarea']
     CloseOutlined: typeof import('@ant-design/icons-vue')['CloseOutlined']
     DataList: typeof import('./components/data-list/index.vue')['default']
-    DeleteOutlined: typeof import('@ant-design/icons-vue')['DeleteOutlined']
-    DownloadOutlined: typeof import('@ant-design/icons-vue')['DownloadOutlined']
     DownOutlined: typeof import('@ant-design/icons-vue')['DownOutlined']
-    EditOutlined: typeof import('@ant-design/icons-vue')['EditOutlined']
     EyeOutlined: typeof import('@ant-design/icons-vue')['EyeOutlined']
-    List: typeof import('./components/list/index.vue')['default']
     Loading: typeof import('./components/loading/index.vue')['default']
     PlusOutlined: typeof import('@ant-design/icons-vue')['PlusOutlined']
     RouterLink: typeof import('vue-router')['RouterLink']
     RouterView: typeof import('vue-router')['RouterView']
     SearchOutlined: typeof import('@ant-design/icons-vue')['SearchOutlined']
-    ShareAltOutlined: typeof import('@ant-design/icons-vue')['ShareAltOutlined']
-    UserOutlined: typeof import('@ant-design/icons-vue')['UserOutlined']
+    VerticalAlignTopOutlined: typeof import('@ant-design/icons-vue')['VerticalAlignTopOutlined']
   }
 }

+ 4 - 2
src/components/data-list/index.vue

@@ -1,7 +1,7 @@
 <template>
   <slot v-if="dataSource.length"></slot>
   <div v-else class="un-data">
-    <aliyun-outlined class="icon" />
+    <img :src="unDataPng" class="icon" />
     <p v-if="keyword">未搜索到结果,</p>
     <p>您还没有{{ name || '数据' }},请先创建{{ name || '数据' }}~</p>
     <div class="undata">
@@ -11,6 +11,8 @@
 </template>
 
 <script lang="ts" setup>
+import unDataPng from '@/assets/images/un-data.png'
+
 defineOptions({ name: 'DataList' })
 defineProps<{
   dataSource: Array<any>
@@ -25,8 +27,8 @@ defineProps<{
   text-align: center;
 
   .icon {
-    font-size: 80px;
     margin-bottom: 20px;
+    width: 80px;
   }
 
   p {

+ 1 - 0
src/hook/index.ts

@@ -0,0 +1 @@
+export * from './useVisible'

+ 40 - 0
src/hook/useVisible.ts

@@ -0,0 +1,40 @@
+import { computed, isRef, watchEffect, ref } from 'vue'
+import { throttle, isVisible } from '@/shared'
+import type { Ref } from 'vue'
+
+export type VisibleEl = Ref<HTMLElement | undefined | null> | HTMLElement
+
+const getEl = (target: VisibleEl) => (isRef(target) ? target.value : target)
+
+export type UseVisibleProps = {
+  target: VisibleEl
+  parent?: VisibleEl
+  bound?: number
+}
+export const useVisible = ({ target, parent, bound = 0 }: UseVisibleProps) => {
+  const visible = ref(true)
+  const targetComputed = computed(() => getEl(target))
+  const parentComputed = computed(() =>
+    parent ? getEl(parent) : targetComputed.value?.parentElement
+  )
+
+  watchEffect(onCleanup => {
+    if (!targetComputed.value || !parentComputed.value) {
+      return
+    }
+    const parent = parentComputed.value
+    const target = targetComputed.value
+    const scrollHandler = throttle(() => {
+      visible.value = isVisible({ parent, target, bound })
+    }, 500)
+
+    scrollHandler()
+    parent.addEventListener('scroll', scrollHandler)
+
+    onCleanup(() => {
+      console.log('清除清除')
+      parent.removeEventListener('scroll', scrollHandler)
+    })
+  })
+  return visible
+}

+ 2 - 1
src/layout/header.vue

@@ -30,6 +30,7 @@
 <script lang="ts" setup>
 import { MenuProps } from 'ant-design-vue'
 import { useUserStore } from '@/store'
+import { gotoLogin } from '@/api'
 
 defineOptions({ name: 'LayoutHeader' })
 
@@ -39,7 +40,7 @@ userStore.fetch()
 const menus = [{ label: '退出', key: 'logout' }]
 const handlerMenuClick: MenuProps['onClick'] = e => {
   if (e.key === 'logout') {
-    console.log('退出')
+    gotoLogin()
   }
 }
 </script>

+ 1 - 0
src/main.ts

@@ -1,4 +1,5 @@
 import { createApp } from 'vue'
+import '@/assets/iconfont/iconfont.css'
 import 'ant-design-vue/lib/message/style/index.less'
 import './style.css'
 import App from './App.vue'

+ 15 - 0
src/shared/el.ts

@@ -0,0 +1,15 @@
+export type IsVisibleProps = {
+  target: HTMLElement
+  parent?: HTMLElement
+  bound?: number
+}
+export const isVisible = ({
+  target,
+  parent = document.body,
+  bound = 0
+}: IsVisibleProps) => {
+  const parentRect = parent.getBoundingClientRect()
+  const targetRect = target.getBoundingClientRect()
+  const targetTop = targetRect.top - parentRect.top
+  return targetTop + targetRect.height > bound
+}

+ 57 - 0
src/shared/index.ts

@@ -2,3 +2,60 @@ export * from './mount'
 export * from './params'
 export * from './code'
 export * from './diff'
+export * from './el'
+
+export const throttle = <Args extends any[]>(
+  fn: (...args: Args) => void,
+  deley: number
+) => {
+  let valib = false
+  let lastCtx: { self: any; args: Args } | null = null
+
+  return function (this: any, ...args: Args) {
+    lastCtx = {
+      args,
+      self: this
+    }
+    if (valib) {
+      return
+    }
+    const currentCtx = lastCtx
+    valib = true
+
+    setTimeout(() => {
+      fn.apply(currentCtx.self, currentCtx.args)
+      currentCtx !== lastCtx && fn.apply(lastCtx!.self, lastCtx!.args)
+      valib = false
+    }, deley)
+  }
+}
+
+type BatchAsyncFn<Args extends any[] = any[], Result = any> = (
+  ...args: Args
+) => Promise<Result>
+
+export const batchFetchPick = (max: number) => {
+  const tasks: (Promise<any> | null)[] = []
+  let workTaskCount = 0
+
+  return <Args extends any[], Result>(
+    fetchFunction: BatchAsyncFn<Args, Result>
+  ) => {
+    return function fetch(this: any, ...args: Args): Promise<Result> {
+      if (workTaskCount >= max) {
+        const getResult = () => fetch.apply(this, args)
+        return Promise.race(tasks).then(getResult).catch(getResult)
+      } else {
+        workTaskCount = tasks.length + 1
+        const result = fetchFunction.apply(this, args)
+        const pickResult = result.finally(() => {
+          const currentIndex = tasks.indexOf(pickResult)
+          ~currentIndex && tasks.splice(currentIndex, 1)
+          workTaskCount = tasks.length
+        })
+        tasks.push(pickResult)
+        return result
+      }
+    }
+  }
+}

+ 3 - 2
src/style.css

@@ -4,9 +4,10 @@
 
 .content-layout { 
   width: 100%;
-  max-width: 1340px;
+  max-width: 1460px;
   margin: 0 auto;
-  padding: 0 30px;
+  padding: 0 90px;
+  position: relative;
 }
 
 body .ant-modal-confirm .ant-modal-body {

+ 11 - 1
src/views/room/edit-room/index.vue

@@ -35,6 +35,7 @@
           :src="`https://test.4dkankan.com/spg.html?m=${current.scenes[0].num}`"
           frameborder="0"
         />
+        <img v-else :src="unScenePng" />
       </div>
       <a-form
         ref="formRef"
@@ -88,6 +89,7 @@ import { createRoom, useRoomStore } from '@/store'
 import { props } from './props'
 import { message } from 'ant-design-vue'
 import EditScenes from './scene-list.vue'
+import unScenePng from '@/assets/images/un-scene.png'
 
 import type { Scene } from '@/store'
 import type { FormInstance } from 'ant-design-vue'
@@ -127,7 +129,8 @@ export default defineComponent({
       formRef,
       deleteScene,
       saveRoom,
-      startSync
+      startSync,
+      unScenePng
     }
   }
 })
@@ -143,11 +146,18 @@ export default defineComponent({
   margin-right: 30px;
   height: 692px;
   background: #f7f8fa;
+  display: flex;
+  align-items: center;
 
   iframe {
     width: 100%;
     height: 100%;
   }
+
+  img {
+    width: 100%;
+    display: block;
+  }
 }
 
 .info {

+ 52 - 3
src/views/room/list.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="header">
+  <div ref="headerRef" class="header">
     <h3>我的房间({{ roomStore.list.length }})</h3>
     <a-input
       v-model:value="keyword"
@@ -32,7 +32,7 @@
             :room="item"
             @web-sync="webSyncRoom(item)"
             @delete="deleteRoom(item)"
-            @share="shareRoom(item)"
+            @share="miniSyncRoom(item)"
             @mini-sync="miniSyncRoom(item)"
             @edit="editRoom(item)"
           />
@@ -46,6 +46,17 @@
       </template>
     </a-list>
   </DataList>
+
+  <teleport v-if="!headerVisible" to="#app">
+    <div class="content-layout goto-layer">
+      <div
+        class="goto-top"
+        @click="contentRef?.scroll({ left: 0, top: 0, behavior: 'smooth' })"
+      >
+        <vertical-align-top-outlined />
+      </div>
+    </div>
+  </teleport>
 </template>
 
 <script setup lang="ts">
@@ -54,12 +65,14 @@ import { ref, computed, createVNode } from 'vue'
 import { message, Modal } from 'ant-design-vue'
 import { copyText } from '@/shared'
 import { renderModal } from '@/helper'
+import { app } from '@/main'
+import { useVisible } from '@/hook'
+import { contentRef } from '@/App.vue'
 import EditRoom from './edit-room'
 import RoomSign from './sign.vue'
 import Share from './modal/share.vue'
 import MiniSync from './modal/mini-sync.vue'
 import DataList from '@/components/data-list/index.vue'
-import { app } from '@/main'
 
 import type { Room } from '@/store'
 
@@ -127,6 +140,13 @@ const editRoom = async (room?: Room) => {
     }
   })
 }
+
+const headerRef = ref<HTMLElement>()
+const headerVisible = useVisible({
+  target: headerRef,
+  parent: contentRef,
+  bound: -140
+})
 </script>
 
 <style scoped lang="scss">
@@ -173,6 +193,35 @@ const editRoom = async (room?: Room) => {
     margin-top: 10px;
   }
 }
+
+.goto-layer {
+  position: fixed;
+  left: 50%;
+  transform: translateX(-50%);
+  pointer-events: none;
+}
+.goto-top {
+  pointer-events: all;
+  right: 20px;
+  bottom: 20px;
+  background-color: #fff;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  border-radius: 8px;
+  width: 60px;
+  height: 60px;
+  font-size: 24px;
+  color: #747575;
+  position: absolute;
+  opacity: 0.5;
+  transition: opacity 0.3s ease;
+  cursor: pointer;
+
+  &:hover {
+    opacity: 1;
+  }
+}
 </style>
 
 <style>

+ 7 - 6
src/views/room/sign.vue

@@ -13,7 +13,7 @@
           >
             小程序带看
           </a-button>
-          <a-button
+          <!-- <a-button
             class="botton"
             shape="round"
             type="ghost"
@@ -21,19 +21,20 @@
             @click="$emit('webSync')"
           >
             网页带看
-          </a-button>
+          </a-button> -->
           <div class="more">
             <span style="--hover-color: #0076f6" @click="$emit('edit')">
-              <edit-outlined />编辑
+              <i class="iconfont icon-works_editor" />编辑
+              <!-- <edit-outlined /> -->
             </span>
             <span
               style="--hover-color: rgba(255, 255, 255, 0.5)"
               @click="$emit('share')"
             >
-              <share-alt-outlined />分享
+              <i class="iconfont icon-works_share" />分享
             </span>
             <span style="--hover-color: #fa5555" @click="$emit('delete')">
-              <delete-outlined />删除
+              <i class="iconfont icon-works_delete" />删除
             </span>
           </div>
         </div>
@@ -124,7 +125,7 @@ defineEmits<RoomSignEmit>()
         color: #fff;
         transition: color 0.3s ease;
 
-        span {
+        i {
           margin-right: 4px;
         }
         &:hover {

+ 1 - 1
vite.config.ts

@@ -8,7 +8,7 @@ import { resolve } from 'path'
 
 const proxy = {
   '/api': {
-    target: 'http://v4-test.4dkankan.com/',
+    target: 'http://test.4dkankan.com/',
     changeOrigin: true,
     rewrite: path => path.replace(/^\/api/, '')
   }