Explorar el Código

docs: 新增文档

zhangyuhan hace 1 año
padre
commit
d9d31db7ea
Se han modificado 81 ficheros con 3993 adiciones y 57 borrados
  1. 128 0
      docs/.gitignore
  2. 86 0
      docs/.vitepress/config.mts
  3. 15 0
      docs/.vitepress/layout/PageLayout.vue
  4. 251 0
      docs/.vitepress/layout/component/Footer.vue
  5. 7 0
      docs/.vitepress/theme/custom.css
  6. 8 0
      docs/.vitepress/theme/index.js
  7. 74 0
      docs/check/index.md
  8. BIN
      docs/cli/img.png
  9. BIN
      docs/cli/img_1.png
  10. BIN
      docs/cli/img_2.png
  11. 41 0
      docs/cli/index.md
  12. 103 0
      docs/components/card/item.vue
  13. 24 0
      docs/components/card/layout.vue
  14. 28 0
      docs/components/card/title.vue
  15. 331 0
      docs/docs/.vitepress/cache/deps/@theme_index.js
  16. 3 0
      docs/docs/.vitepress/cache/deps/@theme_index.js.map
  17. 29 0
      docs/docs/.vitepress/cache/deps/_metadata.json
  18. 181 0
      docs/docs/.vitepress/cache/deps/chunk-WEGWPILI.js
  19. 3 0
      docs/docs/.vitepress/cache/deps/chunk-WEGWPILI.js.map
  20. 3 0
      docs/docs/.vitepress/cache/deps/package.json
  21. 162 0
      docs/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js
  22. 3 0
      docs/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js.map
  23. 313 0
      docs/docs/.vitepress/cache/deps/vue.js
  24. 7 0
      docs/docs/.vitepress/cache/deps/vue.js.map
  25. 108 0
      docs/guide/development.md
  26. 41 0
      docs/guide/getting-started.md
  27. 29 0
      docs/guide/introduce.md
  28. 19 0
      docs/guide/style/base.md
  29. 93 0
      docs/guide/style/css.md
  30. 106 0
      docs/guide/style/html.md
  31. 39 0
      docs/guide/style/introduce.md
  32. 90 0
      docs/guide/style/js.md
  33. 58 0
      docs/guide/style/naming.md
  34. 61 0
      docs/guide/style/vue.md
  35. BIN
      docs/img.png
  36. 58 0
      docs/index.md
  37. 20 0
      docs/package.json
  38. BIN
      docs/public/icon/HuggingChat.png
  39. BIN
      docs/public/icon/caniuse.png
  40. BIN
      docs/public/icon/code-geex.png
  41. 2 0
      docs/public/icon/codewhisperer.svg
  42. 3 0
      docs/public/icon/cursor.svg
  43. BIN
      docs/public/icon/exercism.png
  44. BIN
      docs/public/icon/figma.png
  45. BIN
      docs/public/icon/git.png
  46. BIN
      docs/public/icon/gitlab.png
  47. BIN
      docs/public/icon/hackr.png
  48. BIN
      docs/public/icon/logo-npm.png
  49. BIN
      docs/public/icon/mdn.png
  50. BIN
      docs/public/icon/pdf.png
  51. BIN
      docs/public/icon/perplexity.ai.png
  52. BIN
      docs/public/icon/poe.com.ico
  53. 3 0
      docs/public/icon/sass.svg
  54. BIN
      docs/public/icon/stackoverflow.png
  55. BIN
      docs/public/icon/th.jpg
  56. BIN
      docs/public/icon/wenxin-chat.jpg
  57. BIN
      docs/public/icon/xmind.png
  58. BIN
      docs/public/images/track-demo.png
  59. BIN
      docs/public/images/track-hj-open-page.png
  60. BIN
      docs/public/images/track-hj.png
  61. BIN
      docs/public/images/track-page-maps.png
  62. BIN
      docs/public/images/track-tools.png
  63. BIN
      docs/public/logo.png
  64. BIN
      docs/public/pdf/前端知识点.pdf
  65. BIN
      docs/public/pdf/前端项目工程化要点.pdf
  66. BIN
      docs/public/pdf/我的-页面功能梳理.pdf
  67. BIN
      docs/public/pdf/组件拆分示例.pdf
  68. BIN
      docs/public/pdf/订阅-页面功能梳理.pdf
  69. BIN
      docs/public/xmind/前端项目工程化要点.xmind
  70. BIN
      docs/public/xmind/我的-页面功能梳理.xmind
  71. 245 0
      docs/resource.md
  72. 47 0
      docs/to-do/index.md
  73. BIN
      docs/track/img.png
  74. BIN
      docs/track/img_1.png
  75. BIN
      docs/track/img_2.png
  76. BIN
      docs/track/img_3.png
  77. BIN
      docs/track/img_4.png
  78. BIN
      docs/track/img_5.png
  79. 266 0
      docs/track/index-new.md
  80. 101 0
      docs/track/index-old.md
  81. 804 57
      pnpm-lock.yaml

+ 128 - 0
docs/.gitignore

@@ -0,0 +1,128 @@
+### Intellij+all ###
+# User-specific stuff
+.idea/*
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+### macOS ###
+# General
+.DS_Store
+.AppleDouble
+.LSOverride
+
+### Node ###
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+lerna-debug.log*
+
+# Dependency directories
+node_modules/
+
+# TypeScript v1 declaration files
+typings/
+
+# TypeScript cache
+*.tsbuildinfo
+
+# Optional npm cache directory
+.npm
+
+# Optional eslint cache
+.eslintcache
+
+# Optional stylelint cache
+.stylelintcache
+
+# Output of 'npm pack'
+*.tgz
+
+# Yarn Integrity file
+.yarn-integrity
+
+# dotenv environment variables file
+.env.test
+.env*.local
+
+# parcel-bundler cache (https://parceljs.org/)
+.cache
+.parcel-cache
+
+# Next.js build output
+.next
+
+# Nuxt.js build / generate output
+.nuxt
+dist
+
+# Gatsby files
+.cache/
+# Comment in the public line in if your project uses Gatsby and not Next.js
+# https://nextjs.org/blog/next-9-1#public-directory-support
+# public
+
+# vuepress build output
+.vuepress/dist
+
+# Serverless directories
+.serverless/
+
+# FuseBox cache
+.fusebox/
+
+# DynamoDB Local files
+.dynamodb/
+
+# TernJS port file
+.tern-port
+
+# Stores VSCode versions used for testing VSCode extensions
+.vscode-test
+
+### vscode ###
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+*.code-workspace
+
+### Vue ###
+# gitignore template for Vue.js projects
+#
+# Recommended template: Node.gitignore
+
+### Windows ###
+# Windows thumbnail cache files
+Thumbs.db
+Thumbs.db:encryptable
+ehthumbs.db
+ehthumbs_vista.db
+
+# Dump file
+*.stackdump
+
+# Folder config file
+[Dd]esktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Windows Installer files
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# Windows shortcuts
+*.lnk
+
+# End of https://www.toptal.com/developers/gitignore/api/vue,node,macos,windows,linux,vscode,intellij+all
+
+efe-docs/
+.vitepress/cache/

+ 86 - 0
docs/.vitepress/config.mts

@@ -0,0 +1,86 @@
+import { defineConfig } from 'vitepress'
+
+// https://vitepress.dev/reference/site-config
+export default defineConfig({
+  base: '/efe-docs/',
+  outDir: './efe-docs',
+  title: '文档',
+  description: "剑鱼前端团队内部文档 - 探索前端世界,从文档开始",
+  lang: 'zh-CN',
+  themeConfig: {
+    siteTitle: ' ',
+    logo: {
+      light: 'https://cdn-ali.jianyu360.com/images/index/logo_main.png',
+      dark: 'https://cdn-ali.jianyu360.com/images/index/logo_white.png'
+    },
+    nav: [
+      { text: '指南', link: '/guide/getting-started' },
+      { text: '组件', link: '/component/' },
+      {
+        text: '工具库',
+        items: [
+          { text: '@jianyu/cli', link: '/cli/' },
+        ]
+      },
+      {
+        text: '知识库',
+        items: [
+          { text: '常见问题自检清单', link: '/check/' },
+          { text: '通用埋点相关', link: '/track/index-new' }
+        ]
+      },
+      { text: '资源', link: '/resource' },
+      { text: '参与建设', link: '/to-do/' }
+    ],
+    sidebar: {
+      '/guide/': {
+        base: '/guide/',
+        items: [
+          {
+            text: '开发指南',
+            base: '/guide/',
+            items: [
+              { text: '项目简介', link: 'introduce' },
+              { text: '环境配置', link: 'development' },
+              { text: '快速上手', link: 'getting-started' },
+            ]
+          },
+          {
+            text: '代码风格',
+            base: '/guide/style/',
+            items: [
+              { text: '前言', link: 'introduce' },
+              { text: '文件命名规则', link: 'naming' },
+              { text: '通用规则', link: 'base' },
+              { text: 'HTML', link: 'html' },
+              { text: 'CSS', link: 'css' },
+              { text: 'JS', link: 'js' },
+              { text: 'Vue', link: 'vue' },
+            ]
+          },
+        ]
+      }
+    },
+    outline: {
+      label: '目录'
+    },
+    search: {
+      provider: 'local'
+    },
+    lastUpdated: {
+      text: '上次更新:',
+      formatOptions: {
+        dateStyle: 'full',
+        timeStyle: 'medium'
+      }
+    },
+    editLink: {
+      pattern: 'https://jygit.jydev.jianyu360.cn/jianyu/web/src/main/docs/:path',
+      text: '编辑'
+    },
+    docFooter: {
+      prev: '返回',
+      next: '继续阅读'
+    }
+  }
+})

+ 15 - 0
docs/.vitepress/layout/PageLayout.vue

@@ -0,0 +1,15 @@
+<script setup>
+import DefaultTheme from 'vitepress/theme'
+import Footer from './component/Footer.vue'
+const { Layout } = DefaultTheme
+
+
+</script>
+
+<template>
+  <Layout>
+    <template #layout-bottom>
+      <Footer/>
+    </template>
+  </Layout>
+</template>

+ 251 - 0
docs/.vitepress/layout/component/Footer.vue

@@ -0,0 +1,251 @@
+<script setup>
+const footerGroups = [
+  {
+    mainLink: { text: '品牌', url: 'https://www.jianyu360.cn/brand/index', target: '_blank' },
+    links: [
+      { text: '公司介绍', url: 'https://www.jianyu360.cn/brand/index', target: '_blank' },
+      { text: '发展历程', url: 'https://www.jianyu360.cn/brand/index#history', target: '_blank' },
+      { text: '公司动态', url: 'https://www.jianyu360.cn/brand/index#Company_Dynamic', target: '_blank' },
+      { text: '加入我们', url: 'https://www.jianyu360.cn/brand/index#join_us', target: '_blank' },
+      { text: '联系我们', url: 'https://www.jianyu360.cn/brand/index#contact_us', target: '_blank' }
+    ]
+  },
+  {
+    mainLink: { text: '业界团队', url: 'javascript:;' },
+    links: [
+      { text: '拓普前端技术文档', url: 'http://192.168.3.42/doc/home/', target: '_blank' },
+      { text: '凹凸实验室', url: 'https://o2team.github.io/', target: '_blank' },
+      { text: '淘系前端团队', url: 'https://fed.taobao.org/', target: '_blank' },
+      { text: '百度 FEX', url: 'https://fex-team.github.io/', target: '_blank' },
+      { text: 'AlloyTeam', url: 'https://www.alloyteam.com/', target: '_blank' }
+    ]
+  },
+  {
+    mainLink: { text: '内网相关', url: 'javascript:;' },
+    links: [
+      { text: 'OA 办公', url: 'http://1.192.217.143:8985/seeyon/main.do', target: '_blank' },
+      { text: 'KB 看板', url: 'https://jykb.jydev.jianyu360.com/dashboard', target: '_blank' },
+      { text: 'Verdaccio', url: 'http://192.168.3.71:4873/', target: '_blank' },
+      { text: 'Sentry 监控', url: 'https://jysentry.jydev.jianyu360.cn/', target: '_blank' },
+      { text: 'YAPI 文档', url: 'http://192.168.3.71:4000/', target: '_blank' }
+    ]
+  },
+  {
+    mainLink: { text: '快捷链接', url: 'javascript:;' },
+    links: [
+      { text: 'MDN', url: 'https://developer.mozilla.org/zh-CN/', target: '_blank' },
+      { text: 'BrowsersList', url: 'https://browserslist.dev/', target: '_blank' },
+      { text: 'Can I use', url: 'https://caniuse.com/', target: '_blank' },
+      { text: '可视化正则工具', url: 'https://jex.im/regulex/', target: '_blank' },
+      { text: '可视化 AST', url: 'https://astexplorer.net/', target: '_blank' }
+    ]
+  }
+]
+</script>
+
+<template>
+  <section class='common-footer-container'>
+    <div class='footer-links'>
+      <div class='footer-links-content w'>
+        <div class='footer-service-links'>
+          <div class='service-links-left'>
+            <dl v-for='(group, index) in footerGroups' :key='index' class='service-links-item'>
+              <dt class='service-links-name'>
+                <a :href='group.mainLink.url' :target='group.mainLink.target'
+                   class='service-link cms-link'>{{ group.mainLink.text }}</a>
+              </dt>
+              <dd v-for='(link, linkIndex) in group.links' :key='linkIndex' class='service-links-children'>
+                <a :href='link.url' :target='link.target' class='service-link cms-link'>{{ link.text }}</a>
+              </dd>
+            </dl>
+          </div>
+          <div class='service-links-right'>
+            <div class='service-links-right-content'>
+              <!-- 右侧内容 -->
+              <div class='service-links-right-module logo'>
+                <div class='logo-large'>
+                  <img alt='logo-large' src='https://cdn-ali2.jianyu360.com/images/pc/logo.png?v=24487'>
+                </div>
+              </div>
+              <div class='service-links-right-module customer-phone'></div>
+              <div class='service-links-right-module qr-list'>
+                <div class='qr-box'>
+                  <div class='qr-img'>
+                    <img alt='download-app'
+                         src='https://www.jianyu360.cn/front/downloadJyApp/qr?page=pc_bottom&amp;source=pc_scan'>
+                  </div>
+                  <p class='qr-text'>扫码下载</p>
+                </div>
+                <div class='qr-box'>
+                  <div class='qr-img'>
+                    <img alt='follow-me' src='https://www.jianyu360.cn/front/share/NQMKDCRFBAgGA0xXSF5XQAQEBABEDgIn'>
+                  </div>
+                  <p class='qr-text'>扫码关注</p>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class='footer-copyright'>
+      <p class='copyright w'><span>©2015至今 jianyu360.cn 版权所有 </span></p>
+    </div>
+  </section>
+</template>
+
+<style scoped>
+.common-footer-container {
+  position: relative;
+  z-index: 11;
+}
+.footer-links {
+  padding: 16px 48px;
+  background-color: #2B2D30;
+  color: rgba(255, 255, 255, .8);
+  text-align: center;
+  font-weight: normal;
+}
+
+.footer-service-links {
+  display: flex;
+  justify-content: space-between;
+  text-align: left;
+}
+
+.service-links-left {
+  position: relative;
+  display: flex;
+  flex: 1;
+}
+
+.service-links-right {
+  position: relative;
+}
+
+a.service-link:active,
+a.service-link:hover {
+  text-decoration: none;
+}
+
+.service-links-item {
+  margin-right: 40px;
+  flex: 1;
+}
+
+.service-links-name {
+  margin-bottom: 8px;
+  font-size: 14px;
+  line-height: 22px;
+  font-weight: 400;
+}
+
+.service-links-name a {
+  white-space: nowrap;
+  font-size: inherit;
+  color: rgba(255, 255, 255, .8);
+}
+
+.service-links-children {
+  margin-left: 2px;
+}
+
+.service-links-children a {
+  display: inline-block;
+  font-size: 12px;
+  color: rgba(255, 255, 255, .6);
+  line-height: 20px;
+  white-space: nowrap;
+}
+
+.service-links-right {
+  padding-right: 20px;
+  border-left: 1px solid rgba(255, 255, 255, 0.12);
+  text-align: right;
+}
+
+.service-links-right-content {
+  display: inline-block;
+  padding-left: 64px;
+}
+
+.service-links-right-content img {
+  display: block;
+  width: 100%;
+}
+
+.service-links-right-content .logo-large {
+  width: 132px;
+  height: 38px;
+}
+
+.service-links-right-module {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 140px;
+}
+
+.service-links-right-content .phone-text {
+  margin-left: 6px;
+}
+
+.customer-phone {
+  margin-top: 12px;
+  margin-bottom: 16px;
+}
+
+.qr-list {
+  justify-content: space-between;
+}
+
+.qr-box {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: space-between;
+}
+
+.qr-box .qr-img {
+  display: block;
+  width: 64px;
+  height: 64px;
+  border-radius: 4px;
+  overflow: hidden;
+}
+
+.qr-box .qr-text {
+  margin-top: 4px;
+  font-size: 12px;
+  line-height: 18px;
+  color: rgba(255, 255, 255, 0.8);
+}
+
+.footer-copyright {
+  padding-left: 32px;
+  background-color: #121314;
+}
+
+.copyright {
+  padding: 10px 0 12px;
+  text-align: left;
+  font-size: 12px;
+  line-height: 18px;
+  color: rgba(255, 255, 255, 0.6);
+}
+
+.copyright a:hover {
+  text-decoration: underline;
+}
+
+@media (max-width: 960px) {
+  .service-links-left,
+  .footer-service-links {
+    flex-wrap: wrap;
+  }
+  .service-links-right {
+    border-left-color: transparent;
+  }
+}
+
+</style>

+ 7 - 0
docs/.vitepress/theme/custom.css

@@ -0,0 +1,7 @@
+/* .vitepress/theme/custom.css */
+:root {
+    --vp-c-brand-1: #2ABED1;
+    --vp-c-brand-2: #747bff;
+    --vp-button-brand-bg: var(--vp-c-brand-1);
+    --vp-button-brand-hover-bg: #0BA3B8;
+}

+ 8 - 0
docs/.vitepress/theme/index.js

@@ -0,0 +1,8 @@
+import DefaultTheme from 'vitepress/theme'
+import './custom.css'
+import PageLayout from '../layout/PageLayout.vue'
+
+export default {
+  extends: DefaultTheme,
+  Layout: PageLayout
+}

+ 74 - 0
docs/check/index.md

@@ -0,0 +1,74 @@
+# 前端项目常见问题检查清单
+
+## 项目检查
+
+### 代码规范
+- [ ] 是否符合代码规范?
+
+### 模版渲染项目
+- [ ] 使用正确使用对应环境的模版变量?
+  ```
+    # 剑鱼项目 PC / WX 端 CDN 模版变量前缀
+    {{Msg "seo" "cdn"}}
+    
+    # 剑鱼项目 APP 端 CDN 模版变量前缀
+    {{Cdns .Host "seo" "cdn"|SafeUrl}}
+  
+    # 资源版本后缀
+    {{Msg "seo" "version"}}
+  
+    # 模版变量全局统一获取,使用方式
+    window.goTemplateData
+  ```
+  ```html
+  <link href='{{Msg "seo" "cdn"}}/pccss/reset_pc.css?v={{Msg "seo" "version"}}' rel="stylesheet" type="text/css"/>
+  
+  <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/js/common.js?v={{Msg "seo" "version"}}'></script>
+  ```
+- [ ] 是否引用跨端资源?
+  > 该问题将导致生产环境因跨域无法正确访问资源
+  > 
+  > 剑鱼项目中 app 资源与 pc/wx 资源隔离,生产环境域名隔离,如需使用跨端共享资源,需使用 **common-module** 资源目录
+  ```html
+  <script src='{{Msg "seo" "cdn"}}/common-module/public/js/china-map-data.js?v={{Msg "seo" "version"}}'></script>
+  <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/public/js/china-map-data.js?v={{Msg "seo" "version"}}'></script>
+  ```
+
+### 前后的分离项目
+- [ ] 使用正确的剑鱼 CDN 资源?
+  ```html
+  <script src=//cdn-common.jianyu360.com/cdn/lib/vue/2.6.11/vue.min.js></script>
+  <script src=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/vant.min.js></script>
+  ```
+- [ ] 新增的项目依赖版本是否锁定?是否已更新至 CDN?
+
+## 资源检查
+### 图标
+- [ ] iconfont剑鱼图标库中是否存在该图标?
+  > 优化采用 iconfont 图标
+
+### 图片
+- [ ] 图片是否使用二倍图?
+- [ ] 图片(大于 100K)是否进行压缩?
+- [ ] 图片(大于 300K)是否进行渐进式渲染支持?
+
+### JS三方库
+- [ ] 三方库是否使用剑鱼CDN引用?
+
+## 常见问题检查
+
+### CSS
+- [ ] 无特殊字体时,是否重复定义 font-family?
+  > 从蓝湖 / Figma 中复用样式代码时,除特殊字体外,不应设置 font-family,该问题将导致跨平台字体差异
+
+### JS
+- [ ] 非Babel项目,PC端 语法是否兼容IE11?
+  > 使用 can i use 网站进行判断
+- [ ] 不兼容语法是否进行使用前前置判断?
+
+### 埋点
+- [ ] 可交互按钮、区域是否添加唯一语义化 ID?
+- [ ] 新增页面、项目是否正常引用埋点SDK?
+  > 验证页面是否加载 huiju、baidu域名的 SDK
+  >   
+  > 点击按钮验证是否有埋点请求

BIN
docs/cli/img.png


BIN
docs/cli/img_1.png


BIN
docs/cli/img_2.png


+ 41 - 0
docs/cli/index.md

@@ -0,0 +1,41 @@
+# 剑鱼CLI @jianyu/cli
+
+## 安装
+
+
+::: code-group
+
+```shell [npm]
+npm i -g --registry=http://192.168.3.207:4873 @jianyu/cli
+```
+
+```shell [yarn]
+yarn golbal add --registry=http://192.168.3.207:4873 @jianyu/cli
+```
+
+:::
+
+## 相关命令
+
+### 使用
+
+```shell
+jianyu help
+```
+
+![img.png](img.png)
+
+### jianyu cz
+> 用于替代 git commit 命令,通过交互式命令规范提交信息
+
+#### 使用
+```shell
+jianyu cz
+# 或者
+jianyu-cz
+```
+#### 使用示例
+![img_1.png](img_1.png)
+![img_2.png](img_2.png)
+
+

+ 103 - 0
docs/components/card/item.vue

@@ -0,0 +1,103 @@
+<template>
+  <a class="card-item" :href="href" :target="target" rel="noopener noreferrer">
+    <div class="icon-group" :class="{ 'has-fill': !icon }">
+      <img v-if="icon" :src="withBase(icon)" :alt="title">
+      <span v-else>{{fill}}</span>
+    </div>
+    <div class="info-group">
+      <strong>{{title}}</strong>
+      <br>
+      <p>{{desc}}</p>
+    </div>
+  </a>
+</template>
+
+<script setup>
+import { withBase } from 'vitepress';
+defineProps({
+  href: {
+    type: String,
+    default: '#'
+  },
+  target: {
+    type: String,
+    default: '_blank'
+  },
+  icon: {
+    type: String,
+    default: ''
+  },
+  fill: {
+    type: String,
+    default: ''
+  },
+  title: {
+    type: String,
+    default: ''
+  },
+  desc: {
+    type: String,
+    default: ''
+  }
+})
+</script>
+
+<style scoped lang="scss">
+.card-item {
+  color: var(--vp-c-indigo);
+  margin: 4px;
+  cursor: pointer;
+  width: 16em;
+  height: 120px;
+  vertical-align: middle;
+  overflow: hidden;
+  display: inline-flex;
+  flex-direction: row;
+  border-radius: 8px;
+  box-shadow: 0 8px 16px -4px #2c2d300c;
+  background: var(--vp-c-indigo-lighter);
+  padding: 8px 12px 8px 8px;
+
+  &:hover {
+    background: var(--vp-c-indigo-light);
+    .icon-group {
+      width: 0;
+      opacity: 0;
+    }
+    .info-group {
+      color: var(--vp-c-gray-dark-1);
+    }
+  }
+
+  .info-group {
+    strong {
+      font-size: 20px;
+    }
+    p {
+      opacity: 0.66;
+    }
+  }
+
+  .icon-group {
+    flex-shrink: 0;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    width: 60px;
+    height: 60px;
+    transition: all 0.3s;
+    margin-right: 12px;
+    &.has-fill {
+      background: rgba(41, 190, 209, 0.22);
+      border: 1px solid rgb(225, 225, 225);
+      border-radius: 12px;
+    }
+    img {
+      max-width: 100%;
+      max-height: 100%;
+      width: 40px;
+      object-fit: contain;
+    }
+  }
+}
+</style>

+ 24 - 0
docs/components/card/layout.vue

@@ -0,0 +1,24 @@
+<template>
+  <div v-for="card in cards">
+    <CardTitle :title="card.title" :desc="card.desc"/>
+    <CardItem
+        v-for="item in card.child"
+        v-bind="item"
+    >
+    </CardItem>
+  </div>
+</template>
+
+<script setup>
+import CardTitle from './title.vue'
+import CardItem from './item.vue'
+
+defineProps({
+  cards: {
+    type: Array,
+    default: () => {
+      return []
+    }
+  }
+})
+</script>

+ 28 - 0
docs/components/card/title.vue

@@ -0,0 +1,28 @@
+<template>
+  <h3 v-if="title">{{ title }}</h3>
+  <h4 v-if="desc">{{ desc }}</h4>
+</template>
+
+<script setup>
+defineProps({
+  title: {
+    type: String,
+    default: ''
+  },
+  desc: {
+    type: String,
+    default: ''
+  }
+})
+</script>
+
+<style scoped>
+h3 {
+  line-height: 2;
+  font-size: 20px;
+}
+h4 {
+  opacity: 0.6;
+  font-size: 16px;
+}
+</style>

+ 331 - 0
docs/docs/.vitepress/cache/deps/@theme_index.js

@@ -0,0 +1,331 @@
+import {
+  computed,
+  getCurrentInstance,
+  getCurrentScope,
+  onMounted,
+  onScopeDispose,
+  ref,
+  unref,
+  watch,
+  watchEffect
+} from "./chunk-WEGWPILI.js";
+
+// ../node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/index.js
+import "/Users/zz/Desktop/project/pnpm-demo/core-x/node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/styles/fonts.css";
+
+// ../node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/without-fonts.js
+import "/Users/zz/Desktop/project/pnpm-demo/core-x/node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/styles/vars.css";
+import "/Users/zz/Desktop/project/pnpm-demo/core-x/node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/styles/base.css";
+import "/Users/zz/Desktop/project/pnpm-demo/core-x/node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/styles/utils.css";
+import "/Users/zz/Desktop/project/pnpm-demo/core-x/node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/styles/components/custom-block.css";
+import "/Users/zz/Desktop/project/pnpm-demo/core-x/node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/styles/components/vp-code.css";
+import "/Users/zz/Desktop/project/pnpm-demo/core-x/node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/styles/components/vp-code-group.css";
+import "/Users/zz/Desktop/project/pnpm-demo/core-x/node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/styles/components/vp-doc.css";
+import "/Users/zz/Desktop/project/pnpm-demo/core-x/node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/styles/components/vp-sponsor.css";
+import VPBadge from "/Users/zz/Desktop/project/pnpm-demo/core-x/node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/components/VPBadge.vue";
+import Layout from "/Users/zz/Desktop/project/pnpm-demo/core-x/node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/Layout.vue";
+import { default as default2 } from "/Users/zz/Desktop/project/pnpm-demo/core-x/node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/components/VPImage.vue";
+import { default as default3 } from "/Users/zz/Desktop/project/pnpm-demo/core-x/node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/components/VPButton.vue";
+import { default as default4 } from "/Users/zz/Desktop/project/pnpm-demo/core-x/node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/components/VPHomeHero.vue";
+import { default as default5 } from "/Users/zz/Desktop/project/pnpm-demo/core-x/node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/components/VPHomeFeatures.vue";
+import { default as default6 } from "/Users/zz/Desktop/project/pnpm-demo/core-x/node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/components/VPHomeSponsors.vue";
+import { default as default7 } from "/Users/zz/Desktop/project/pnpm-demo/core-x/node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/components/VPDocAsideSponsors.vue";
+import { default as default8 } from "/Users/zz/Desktop/project/pnpm-demo/core-x/node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/components/VPSponsors.vue";
+import { default as default9 } from "/Users/zz/Desktop/project/pnpm-demo/core-x/node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/components/VPTeamPage.vue";
+import { default as default10 } from "/Users/zz/Desktop/project/pnpm-demo/core-x/node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/components/VPTeamPageTitle.vue";
+import { default as default11 } from "/Users/zz/Desktop/project/pnpm-demo/core-x/node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/components/VPTeamPageSection.vue";
+import { default as default12 } from "/Users/zz/Desktop/project/pnpm-demo/core-x/node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/components/VPTeamMembers.vue";
+
+// ../node_modules/.pnpm/@vueuse+shared@10.7.0_vue@3.3.10/node_modules/@vueuse/shared/index.mjs
+function tryOnScopeDispose(fn) {
+  if (getCurrentScope()) {
+    onScopeDispose(fn);
+    return true;
+  }
+  return false;
+}
+function toValue(r) {
+  return typeof r === "function" ? r() : unref(r);
+}
+var isClient = typeof window !== "undefined" && typeof document !== "undefined";
+var isWorker = typeof WorkerGlobalScope !== "undefined" && globalThis instanceof WorkerGlobalScope;
+var isIOS = getIsIOS();
+function getIsIOS() {
+  var _a, _b;
+  return isClient && ((_a = window == null ? void 0 : window.navigator) == null ? void 0 : _a.userAgent) && (/iP(ad|hone|od)/.test(window.navigator.userAgent) || ((_b = window == null ? void 0 : window.navigator) == null ? void 0 : _b.maxTouchPoints) > 2 && /iPad|Macintosh/.test(window == null ? void 0 : window.navigator.userAgent));
+}
+function cacheStringFunction(fn) {
+  const cache = /* @__PURE__ */ Object.create(null);
+  return (str) => {
+    const hit = cache[str];
+    return hit || (cache[str] = fn(str));
+  };
+}
+var hyphenateRE = /\B([A-Z])/g;
+var hyphenate = cacheStringFunction((str) => str.replace(hyphenateRE, "-$1").toLowerCase());
+var camelizeRE = /-(\w)/g;
+var camelize = cacheStringFunction((str) => {
+  return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : "");
+});
+function identity(arg) {
+  return arg;
+}
+
+// ../node_modules/.pnpm/@vueuse+core@10.7.0_vue@3.3.10/node_modules/@vueuse/core/index.mjs
+var defaultWindow = isClient ? window : void 0;
+var defaultDocument = isClient ? window.document : void 0;
+var defaultNavigator = isClient ? window.navigator : void 0;
+var defaultLocation = isClient ? window.location : void 0;
+function useMounted() {
+  const isMounted = ref(false);
+  if (getCurrentInstance()) {
+    onMounted(() => {
+      isMounted.value = true;
+    });
+  }
+  return isMounted;
+}
+function useSupported(callback) {
+  const isMounted = useMounted();
+  return computed(() => {
+    isMounted.value;
+    return Boolean(callback());
+  });
+}
+function useMediaQuery(query, options = {}) {
+  const { window: window2 = defaultWindow } = options;
+  const isSupported = useSupported(() => window2 && "matchMedia" in window2 && typeof window2.matchMedia === "function");
+  let mediaQuery;
+  const matches = ref(false);
+  const handler = (event) => {
+    matches.value = event.matches;
+  };
+  const cleanup = () => {
+    if (!mediaQuery)
+      return;
+    if ("removeEventListener" in mediaQuery)
+      mediaQuery.removeEventListener("change", handler);
+    else
+      mediaQuery.removeListener(handler);
+  };
+  const stopWatch = watchEffect(() => {
+    if (!isSupported.value)
+      return;
+    cleanup();
+    mediaQuery = window2.matchMedia(toValue(query));
+    if ("addEventListener" in mediaQuery)
+      mediaQuery.addEventListener("change", handler);
+    else
+      mediaQuery.addListener(handler);
+    matches.value = mediaQuery.matches;
+  });
+  tryOnScopeDispose(() => {
+    stopWatch();
+    cleanup();
+    mediaQuery = void 0;
+  });
+  return matches;
+}
+var _global = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
+var globalKey = "__vueuse_ssr_handlers__";
+var handlers = getHandlers();
+function getHandlers() {
+  if (!(globalKey in _global))
+    _global[globalKey] = _global[globalKey] || {};
+  return _global[globalKey];
+}
+var defaultState = {
+  x: 0,
+  y: 0,
+  pointerId: 0,
+  pressure: 0,
+  tiltX: 0,
+  tiltY: 0,
+  width: 0,
+  height: 0,
+  twist: 0,
+  pointerType: null
+};
+var keys = Object.keys(defaultState);
+var DEFAULT_UNITS = [
+  { max: 6e4, value: 1e3, name: "second" },
+  { max: 276e4, value: 6e4, name: "minute" },
+  { max: 72e6, value: 36e5, name: "hour" },
+  { max: 5184e5, value: 864e5, name: "day" },
+  { max: 24192e5, value: 6048e5, name: "week" },
+  { max: 28512e6, value: 2592e6, name: "month" },
+  { max: Number.POSITIVE_INFINITY, value: 31536e6, name: "year" }
+];
+var _TransitionPresets = {
+  easeInSine: [0.12, 0, 0.39, 0],
+  easeOutSine: [0.61, 1, 0.88, 1],
+  easeInOutSine: [0.37, 0, 0.63, 1],
+  easeInQuad: [0.11, 0, 0.5, 0],
+  easeOutQuad: [0.5, 1, 0.89, 1],
+  easeInOutQuad: [0.45, 0, 0.55, 1],
+  easeInCubic: [0.32, 0, 0.67, 0],
+  easeOutCubic: [0.33, 1, 0.68, 1],
+  easeInOutCubic: [0.65, 0, 0.35, 1],
+  easeInQuart: [0.5, 0, 0.75, 0],
+  easeOutQuart: [0.25, 1, 0.5, 1],
+  easeInOutQuart: [0.76, 0, 0.24, 1],
+  easeInQuint: [0.64, 0, 0.78, 0],
+  easeOutQuint: [0.22, 1, 0.36, 1],
+  easeInOutQuint: [0.83, 0, 0.17, 1],
+  easeInExpo: [0.7, 0, 0.84, 0],
+  easeOutExpo: [0.16, 1, 0.3, 1],
+  easeInOutExpo: [0.87, 0, 0.13, 1],
+  easeInCirc: [0.55, 0, 1, 0.45],
+  easeOutCirc: [0, 0.55, 0.45, 1],
+  easeInOutCirc: [0.85, 0, 0.15, 1],
+  easeInBack: [0.36, 0, 0.66, -0.56],
+  easeOutBack: [0.34, 1.56, 0.64, 1],
+  easeInOutBack: [0.68, -0.6, 0.32, 1.6]
+};
+var TransitionPresets = Object.assign({}, { linear: identity }, _TransitionPresets);
+
+// ../node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/shared.js
+var inBrowser = typeof document !== "undefined";
+
+// ../node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/support/utils.js
+import { withBase } from "vitepress";
+
+// ../node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/composables/data.js
+import { useData as useData$ } from "vitepress";
+var useData = useData$;
+
+// ../node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/support/utils.js
+function ensureStartingSlash(path) {
+  return /^\//.test(path) ? path : `/${path}`;
+}
+
+// ../node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/support/sidebar.js
+function getSidebar(_sidebar, path) {
+  if (Array.isArray(_sidebar))
+    return addBase(_sidebar);
+  if (_sidebar == null)
+    return [];
+  path = ensureStartingSlash(path);
+  const dir = Object.keys(_sidebar).sort((a, b) => {
+    return b.split("/").length - a.split("/").length;
+  }).find((dir2) => {
+    return path.startsWith(ensureStartingSlash(dir2));
+  });
+  const sidebar = dir ? _sidebar[dir] : [];
+  return Array.isArray(sidebar) ? addBase(sidebar) : addBase(sidebar.items, sidebar.base);
+}
+function getSidebarGroups(sidebar) {
+  const groups = [];
+  let lastGroupIndex = 0;
+  for (const index in sidebar) {
+    const item = sidebar[index];
+    if (item.items) {
+      lastGroupIndex = groups.push(item);
+      continue;
+    }
+    if (!groups[lastGroupIndex]) {
+      groups.push({ items: [] });
+    }
+    groups[lastGroupIndex].items.push(item);
+  }
+  return groups;
+}
+function addBase(items, _base) {
+  return [...items].map((_item) => {
+    const item = { ..._item };
+    const base = item.base || _base;
+    if (base && item.link)
+      item.link = base + item.link;
+    if (item.items)
+      item.items = addBase(item.items, base);
+    return item;
+  });
+}
+
+// ../node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/composables/sidebar.js
+function useSidebar() {
+  const { frontmatter, page, theme: theme2 } = useData();
+  const is960 = useMediaQuery("(min-width: 960px)");
+  const isOpen = ref(false);
+  const _sidebar = computed(() => {
+    const sidebarConfig = theme2.value.sidebar;
+    const relativePath = page.value.relativePath;
+    return sidebarConfig ? getSidebar(sidebarConfig, relativePath) : [];
+  });
+  const sidebar = ref(_sidebar.value);
+  watch(_sidebar, (next, prev) => {
+    if (JSON.stringify(next) !== JSON.stringify(prev))
+      sidebar.value = _sidebar.value;
+  });
+  const hasSidebar = computed(() => {
+    return frontmatter.value.sidebar !== false && sidebar.value.length > 0 && frontmatter.value.layout !== "home";
+  });
+  const leftAside = computed(() => {
+    if (hasAside)
+      return frontmatter.value.aside == null ? theme2.value.aside === "left" : frontmatter.value.aside === "left";
+    return false;
+  });
+  const hasAside = computed(() => {
+    if (frontmatter.value.layout === "home")
+      return false;
+    if (frontmatter.value.aside != null)
+      return !!frontmatter.value.aside;
+    return theme2.value.aside !== false;
+  });
+  const isSidebarEnabled = computed(() => hasSidebar.value && is960.value);
+  const sidebarGroups = computed(() => {
+    return hasSidebar.value ? getSidebarGroups(sidebar.value) : [];
+  });
+  function open() {
+    isOpen.value = true;
+  }
+  function close() {
+    isOpen.value = false;
+  }
+  function toggle() {
+    isOpen.value ? close() : open();
+  }
+  return {
+    isOpen,
+    sidebar,
+    sidebarGroups,
+    hasSidebar,
+    hasAside,
+    leftAside,
+    isSidebarEnabled,
+    open,
+    close,
+    toggle
+  };
+}
+var hashRef = ref(inBrowser ? location.hash : "");
+if (inBrowser) {
+  window.addEventListener("hashchange", () => {
+    hashRef.value = location.hash;
+  });
+}
+
+// ../node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/without-fonts.js
+var theme = {
+  Layout,
+  enhanceApp: ({ app }) => {
+    app.component("Badge", VPBadge);
+  }
+};
+var without_fonts_default = theme;
+export {
+  default3 as VPButton,
+  default7 as VPDocAsideSponsors,
+  default5 as VPHomeFeatures,
+  default4 as VPHomeHero,
+  default6 as VPHomeSponsors,
+  default2 as VPImage,
+  default8 as VPSponsors,
+  default12 as VPTeamMembers,
+  default9 as VPTeamPage,
+  default11 as VPTeamPageSection,
+  default10 as VPTeamPageTitle,
+  without_fonts_default as default,
+  useSidebar
+};
+//# sourceMappingURL=@theme_index.js.map

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 3 - 0
docs/docs/.vitepress/cache/deps/@theme_index.js.map


+ 29 - 0
docs/docs/.vitepress/cache/deps/_metadata.json

@@ -0,0 +1,29 @@
+{
+  "hash": "77bca415",
+  "browserHash": "013d5fe9",
+  "optimized": {
+    "vue": {
+      "src": "../../../../../node_modules/.pnpm/vue@3.3.10_typescript@5.0.2/node_modules/vue/dist/vue.runtime.esm-bundler.js",
+      "file": "vue.js",
+      "fileHash": "f104987f",
+      "needsInterop": false
+    },
+    "vitepress > @vue/devtools-api": {
+      "src": "../../../../../node_modules/.pnpm/@vue+devtools-api@6.5.1/node_modules/@vue/devtools-api/lib/esm/index.js",
+      "file": "vitepress___@vue_devtools-api.js",
+      "fileHash": "5c26a11a",
+      "needsInterop": false
+    },
+    "@theme/index": {
+      "src": "../../../../../node_modules/.pnpm/vitepress@1.0.0-rc.31_@algolia+client-search@4.20.0_axios@1.3.6_search-insights@2.11.0_typescript@5.0.2/node_modules/vitepress/dist/client/theme-default/index.js",
+      "file": "@theme_index.js",
+      "fileHash": "b1292f8e",
+      "needsInterop": false
+    }
+  },
+  "chunks": {
+    "chunk-WEGWPILI": {
+      "file": "chunk-WEGWPILI.js"
+    }
+  }
+}

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 181 - 0
docs/docs/.vitepress/cache/deps/chunk-WEGWPILI.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 3 - 0
docs/docs/.vitepress/cache/deps/chunk-WEGWPILI.js.map


+ 3 - 0
docs/docs/.vitepress/cache/deps/package.json

@@ -0,0 +1,3 @@
+{
+  "type": "module"
+}

+ 162 - 0
docs/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js

@@ -0,0 +1,162 @@
+// ../node_modules/.pnpm/@vue+devtools-api@6.5.1/node_modules/@vue/devtools-api/lib/esm/env.js
+function getDevtoolsGlobalHook() {
+  return getTarget().__VUE_DEVTOOLS_GLOBAL_HOOK__;
+}
+function getTarget() {
+  return typeof navigator !== "undefined" && typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : {};
+}
+var isProxyAvailable = typeof Proxy === "function";
+
+// ../node_modules/.pnpm/@vue+devtools-api@6.5.1/node_modules/@vue/devtools-api/lib/esm/const.js
+var HOOK_SETUP = "devtools-plugin:setup";
+var HOOK_PLUGIN_SETTINGS_SET = "plugin:settings:set";
+
+// ../node_modules/.pnpm/@vue+devtools-api@6.5.1/node_modules/@vue/devtools-api/lib/esm/time.js
+var supported;
+var perf;
+function isPerformanceSupported() {
+  var _a;
+  if (supported !== void 0) {
+    return supported;
+  }
+  if (typeof window !== "undefined" && window.performance) {
+    supported = true;
+    perf = window.performance;
+  } else if (typeof global !== "undefined" && ((_a = global.perf_hooks) === null || _a === void 0 ? void 0 : _a.performance)) {
+    supported = true;
+    perf = global.perf_hooks.performance;
+  } else {
+    supported = false;
+  }
+  return supported;
+}
+function now() {
+  return isPerformanceSupported() ? perf.now() : Date.now();
+}
+
+// ../node_modules/.pnpm/@vue+devtools-api@6.5.1/node_modules/@vue/devtools-api/lib/esm/proxy.js
+var ApiProxy = class {
+  constructor(plugin, hook) {
+    this.target = null;
+    this.targetQueue = [];
+    this.onQueue = [];
+    this.plugin = plugin;
+    this.hook = hook;
+    const defaultSettings = {};
+    if (plugin.settings) {
+      for (const id in plugin.settings) {
+        const item = plugin.settings[id];
+        defaultSettings[id] = item.defaultValue;
+      }
+    }
+    const localSettingsSaveId = `__vue-devtools-plugin-settings__${plugin.id}`;
+    let currentSettings = Object.assign({}, defaultSettings);
+    try {
+      const raw = localStorage.getItem(localSettingsSaveId);
+      const data = JSON.parse(raw);
+      Object.assign(currentSettings, data);
+    } catch (e) {
+    }
+    this.fallbacks = {
+      getSettings() {
+        return currentSettings;
+      },
+      setSettings(value) {
+        try {
+          localStorage.setItem(localSettingsSaveId, JSON.stringify(value));
+        } catch (e) {
+        }
+        currentSettings = value;
+      },
+      now() {
+        return now();
+      }
+    };
+    if (hook) {
+      hook.on(HOOK_PLUGIN_SETTINGS_SET, (pluginId, value) => {
+        if (pluginId === this.plugin.id) {
+          this.fallbacks.setSettings(value);
+        }
+      });
+    }
+    this.proxiedOn = new Proxy({}, {
+      get: (_target, prop) => {
+        if (this.target) {
+          return this.target.on[prop];
+        } else {
+          return (...args) => {
+            this.onQueue.push({
+              method: prop,
+              args
+            });
+          };
+        }
+      }
+    });
+    this.proxiedTarget = new Proxy({}, {
+      get: (_target, prop) => {
+        if (this.target) {
+          return this.target[prop];
+        } else if (prop === "on") {
+          return this.proxiedOn;
+        } else if (Object.keys(this.fallbacks).includes(prop)) {
+          return (...args) => {
+            this.targetQueue.push({
+              method: prop,
+              args,
+              resolve: () => {
+              }
+            });
+            return this.fallbacks[prop](...args);
+          };
+        } else {
+          return (...args) => {
+            return new Promise((resolve) => {
+              this.targetQueue.push({
+                method: prop,
+                args,
+                resolve
+              });
+            });
+          };
+        }
+      }
+    });
+  }
+  async setRealTarget(target) {
+    this.target = target;
+    for (const item of this.onQueue) {
+      this.target.on[item.method](...item.args);
+    }
+    for (const item of this.targetQueue) {
+      item.resolve(await this.target[item.method](...item.args));
+    }
+  }
+};
+
+// ../node_modules/.pnpm/@vue+devtools-api@6.5.1/node_modules/@vue/devtools-api/lib/esm/index.js
+function setupDevtoolsPlugin(pluginDescriptor, setupFn) {
+  const descriptor = pluginDescriptor;
+  const target = getTarget();
+  const hook = getDevtoolsGlobalHook();
+  const enableProxy = isProxyAvailable && descriptor.enableEarlyProxy;
+  if (hook && (target.__VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__ || !enableProxy)) {
+    hook.emit(HOOK_SETUP, pluginDescriptor, setupFn);
+  } else {
+    const proxy = enableProxy ? new ApiProxy(descriptor, hook) : null;
+    const list = target.__VUE_DEVTOOLS_PLUGINS__ = target.__VUE_DEVTOOLS_PLUGINS__ || [];
+    list.push({
+      pluginDescriptor: descriptor,
+      setupFn,
+      proxy
+    });
+    if (proxy)
+      setupFn(proxy.proxiedTarget);
+  }
+}
+export {
+  isPerformanceSupported,
+  now,
+  setupDevtoolsPlugin
+};
+//# sourceMappingURL=vitepress___@vue_devtools-api.js.map

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 3 - 0
docs/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js.map


+ 313 - 0
docs/docs/.vitepress/cache/deps/vue.js

@@ -0,0 +1,313 @@
+import {
+  BaseTransition,
+  BaseTransitionPropsValidators,
+  Comment,
+  EffectScope,
+  Fragment,
+  KeepAlive,
+  ReactiveEffect,
+  Static,
+  Suspense,
+  Teleport,
+  Text,
+  Transition,
+  TransitionGroup,
+  VueElement,
+  assertNumber,
+  callWithAsyncErrorHandling,
+  callWithErrorHandling,
+  camelize,
+  capitalize,
+  cloneVNode,
+  compatUtils,
+  compile,
+  computed,
+  createApp,
+  createBaseVNode,
+  createBlock,
+  createCommentVNode,
+  createElementBlock,
+  createHydrationRenderer,
+  createPropsRestProxy,
+  createRenderer,
+  createSSRApp,
+  createSlots,
+  createStaticVNode,
+  createTextVNode,
+  createVNode,
+  customRef,
+  defineAsyncComponent,
+  defineComponent,
+  defineCustomElement,
+  defineEmits,
+  defineExpose,
+  defineModel,
+  defineOptions,
+  defineProps,
+  defineSSRCustomElement,
+  defineSlots,
+  devtools,
+  effect,
+  effectScope,
+  getCurrentInstance,
+  getCurrentScope,
+  getTransitionRawChildren,
+  guardReactiveProps,
+  h,
+  handleError,
+  hasInjectionContext,
+  hydrate,
+  initCustomFormatter,
+  initDirectivesForSSR,
+  inject,
+  isMemoSame,
+  isProxy,
+  isReactive,
+  isReadonly,
+  isRef,
+  isRuntimeOnly,
+  isShallow,
+  isVNode,
+  markRaw,
+  mergeDefaults,
+  mergeModels,
+  mergeProps,
+  nextTick,
+  normalizeClass,
+  normalizeProps,
+  normalizeStyle,
+  onActivated,
+  onBeforeMount,
+  onBeforeUnmount,
+  onBeforeUpdate,
+  onDeactivated,
+  onErrorCaptured,
+  onMounted,
+  onRenderTracked,
+  onRenderTriggered,
+  onScopeDispose,
+  onServerPrefetch,
+  onUnmounted,
+  onUpdated,
+  openBlock,
+  popScopeId,
+  provide,
+  proxyRefs,
+  pushScopeId,
+  queuePostFlushCb,
+  reactive,
+  readonly,
+  ref,
+  registerRuntimeCompiler,
+  render,
+  renderList,
+  renderSlot,
+  resolveComponent,
+  resolveDirective,
+  resolveDynamicComponent,
+  resolveFilter,
+  resolveTransitionHooks,
+  setBlockTracking,
+  setDevtoolsHook,
+  setTransitionHooks,
+  shallowReactive,
+  shallowReadonly,
+  shallowRef,
+  ssrContextKey,
+  ssrUtils,
+  stop,
+  toDisplayString,
+  toHandlerKey,
+  toHandlers,
+  toRaw,
+  toRef,
+  toRefs,
+  toValue,
+  transformVNodeArgs,
+  triggerRef,
+  unref,
+  useAttrs,
+  useCssModule,
+  useCssVars,
+  useModel,
+  useSSRContext,
+  useSlots,
+  useTransitionState,
+  vModelCheckbox,
+  vModelDynamic,
+  vModelRadio,
+  vModelSelect,
+  vModelText,
+  vShow,
+  version,
+  warn,
+  watch,
+  watchEffect,
+  watchPostEffect,
+  watchSyncEffect,
+  withAsyncContext,
+  withCtx,
+  withDefaults,
+  withDirectives,
+  withKeys,
+  withMemo,
+  withModifiers,
+  withScopeId
+} from "./chunk-WEGWPILI.js";
+export {
+  BaseTransition,
+  BaseTransitionPropsValidators,
+  Comment,
+  EffectScope,
+  Fragment,
+  KeepAlive,
+  ReactiveEffect,
+  Static,
+  Suspense,
+  Teleport,
+  Text,
+  Transition,
+  TransitionGroup,
+  VueElement,
+  assertNumber,
+  callWithAsyncErrorHandling,
+  callWithErrorHandling,
+  camelize,
+  capitalize,
+  cloneVNode,
+  compatUtils,
+  compile,
+  computed,
+  createApp,
+  createBlock,
+  createCommentVNode,
+  createElementBlock,
+  createBaseVNode as createElementVNode,
+  createHydrationRenderer,
+  createPropsRestProxy,
+  createRenderer,
+  createSSRApp,
+  createSlots,
+  createStaticVNode,
+  createTextVNode,
+  createVNode,
+  customRef,
+  defineAsyncComponent,
+  defineComponent,
+  defineCustomElement,
+  defineEmits,
+  defineExpose,
+  defineModel,
+  defineOptions,
+  defineProps,
+  defineSSRCustomElement,
+  defineSlots,
+  devtools,
+  effect,
+  effectScope,
+  getCurrentInstance,
+  getCurrentScope,
+  getTransitionRawChildren,
+  guardReactiveProps,
+  h,
+  handleError,
+  hasInjectionContext,
+  hydrate,
+  initCustomFormatter,
+  initDirectivesForSSR,
+  inject,
+  isMemoSame,
+  isProxy,
+  isReactive,
+  isReadonly,
+  isRef,
+  isRuntimeOnly,
+  isShallow,
+  isVNode,
+  markRaw,
+  mergeDefaults,
+  mergeModels,
+  mergeProps,
+  nextTick,
+  normalizeClass,
+  normalizeProps,
+  normalizeStyle,
+  onActivated,
+  onBeforeMount,
+  onBeforeUnmount,
+  onBeforeUpdate,
+  onDeactivated,
+  onErrorCaptured,
+  onMounted,
+  onRenderTracked,
+  onRenderTriggered,
+  onScopeDispose,
+  onServerPrefetch,
+  onUnmounted,
+  onUpdated,
+  openBlock,
+  popScopeId,
+  provide,
+  proxyRefs,
+  pushScopeId,
+  queuePostFlushCb,
+  reactive,
+  readonly,
+  ref,
+  registerRuntimeCompiler,
+  render,
+  renderList,
+  renderSlot,
+  resolveComponent,
+  resolveDirective,
+  resolveDynamicComponent,
+  resolveFilter,
+  resolveTransitionHooks,
+  setBlockTracking,
+  setDevtoolsHook,
+  setTransitionHooks,
+  shallowReactive,
+  shallowReadonly,
+  shallowRef,
+  ssrContextKey,
+  ssrUtils,
+  stop,
+  toDisplayString,
+  toHandlerKey,
+  toHandlers,
+  toRaw,
+  toRef,
+  toRefs,
+  toValue,
+  transformVNodeArgs,
+  triggerRef,
+  unref,
+  useAttrs,
+  useCssModule,
+  useCssVars,
+  useModel,
+  useSSRContext,
+  useSlots,
+  useTransitionState,
+  vModelCheckbox,
+  vModelDynamic,
+  vModelRadio,
+  vModelSelect,
+  vModelText,
+  vShow,
+  version,
+  warn,
+  watch,
+  watchEffect,
+  watchPostEffect,
+  watchSyncEffect,
+  withAsyncContext,
+  withCtx,
+  withDefaults,
+  withDirectives,
+  withKeys,
+  withMemo,
+  withModifiers,
+  withScopeId
+};
+//# sourceMappingURL=vue.js.map

+ 7 - 0
docs/docs/.vitepress/cache/deps/vue.js.map

@@ -0,0 +1,7 @@
+{
+  "version": 3,
+  "sources": [],
+  "sourcesContent": [],
+  "mappings": "",
+  "names": []
+}

+ 108 - 0
docs/guide/development.md

@@ -0,0 +1,108 @@
+在了解项目的分布后,参与开发前必然是需要搭建开发环境。
+
+希望下面的内容可以帮助你进入状态。
+
+## IDE
+
+* [vs code](https://code.visualstudio.com/)
+
+  微软出品,开源,基于Electron开发,体积小,扩展多。
+
+* [WebStorm Eap](https://www.jetbrains.com/webstorm/eap/)
+
+  有强大的智能补全和提示,写起来比 vs code 舒服很多。
+  但是是一款收费软件,这里建议使用免费的 WebStorm Eap 版,是预发布版本,每月更新体验测试。
+
+## 开发环境搭建
+
+目前项目主要分为有 `后端渲染网站类` `前后端分离应用类`。
+
+* 后端渲染网站类:采用 go 语言开发,需要安装对应环境或使用编译后的可执行文件。
+* 前后端分离应用类:需要安装 Node 环境。
+
+## 后端渲染网站类
+
+核心项目 `jy` 项目采用后端渲染网站类,所以这里主要介绍如何配置开发环境。
+
+## 使用可执行文件运行
+> 注意:如果用了测试环境接口,则要修改本地可执行文件下配置,让登录状态保持一致
+
+如果临时处理任务,可获取可执行文件运行项目。
+
+以Windows为例,执行下面两个可执行文件,来启动项目
+```
+./src/main.exe
+./src/jfw/modules/app/src/app.exe
+```
+
+## 安装go自行编译运行
+
+长期项目或新增项目,建议使用go自行编译运行。
+
+根据自己操作系统下载对应的安装包:[安装包下载地址](https://go.dev/dl/)
+
+
+## 安装nginx
+
+根据自己操作系统下载不同的平台(Windows/MAC)的安装包:[安装包下载地址](https://nginx.org/en/download.html)
+
+## nginx配置
+
+拉取配置文件
+```
+git clone http://192.168.3.207:8080/cuiyalong/nginx-conf.git
+```
+将本地 nginx.conf 配置文件替换掉,并将`/servers`目录下文件复制到 nginx.conf同级
+
+在根据自己代码位置,对`/servers/localhost.conf`进行修改
+
+### 使用测试环境接口
+```
+location /bigmember {
+    # 兼容本地http与测试环境的https
+    proxy_set_header    Host jybx2-webtest.jydev.jianyu360.com;
+    proxy_pass    https://jybx2-webtest.jydev.jianyu360.com;
+
+    # proxy_pass    http://127.0.0.1:814;
+}
+```
+
+## 前后端分离应用类
+
+这类项目大家都比较熟悉了,基于Node运行,安装依赖包。
+
+## Node
+
+Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。
+
+推荐使用 `nvm`。
+
+* [node](https://nodejs.org/en/) 官网下载最新稳定版
+
+* [nvm](https://github.com/coreybutler/nvm-windows) 使用nvm管理和切换Node版本
+
+* [npx](https://juejin.im/entry/59658035f265da6c360a19dd) 使用npx也可以用来切换Node版本
+  ```
+  npx node@4 -e "console.log(process.version)"
+  npx node@6 -e "console.log(process.version)"
+  ```
+
+## 包管理
+推荐使用 `pnpm`,优先采用[内网包管理](http://192.168.3.71:4873/), 如果网络不好,可以切换到外网。
+
+* [pnpm](https://pnpm.js.org/)
+  ```shell
+  npm install -g pnpm
+  ```
+
+::: code-group
+
+```shell [pnpm]
+pnpm set registry http://192.168.3.71:4873/
+```
+
+```shell [yarn]
+yarn config set registry http://192.168.3.71:4873/
+```
+:::
+

+ 41 - 0
docs/guide/getting-started.md

@@ -0,0 +1,41 @@
+在了解项目、配置开发环境后,接下来熟悉项目中相关的技术栈。
+
+
+## 熟悉技术栈
+项目中基于Vue生态,主要采用的技术栈如下:
+
+构建:
+- `vue-cli`
+- `vite`
+
+工具:
+- `axios`
+- `lodash`
+- `dayjs`
+- `echarts`
+- `vueuse`
+
+文档:
+- `vitepress`
+- `storybook`
+
+测试:
+- `vitest`
+
+
+### Vue2.x
+
+- `vuex`
+- `vue-router`
+- `element-ui`
+- `vant`
+
+### Vue3.x
+...
+
+
+## 熟悉项目代码
+
+选择一个项目,开始熟悉项目的目录结构。
+
+并了解相关代码风格吧。

+ 29 - 0
docs/guide/introduce.md

@@ -0,0 +1,29 @@
+首先欢迎加入剑鱼大家庭 🎉🎉
+
+北京剑鱼信息技术有限公司旗下知名产品“剑鱼标讯”于2016年发布,是国内最早的数字化营销和开源情报服务平台。剑鱼标讯基于
+云计算、大数据和人工智能技术搭建了完善的数据服务架构,全面收录权威机构公开的招标采购、企业公示等信息,为政府和企业提供大数
+据服务与解决方案,满足用户商机发现与挖掘、商机跟踪管理、市场分析与监控、决策分析等需求,实现数据驱动企业增长。
+
+下面带你了解一下剑鱼标讯以及前端团队所涉及项目的情况。
+
+### 项目、产品
+
+目前项目主要分为有 `后端渲染网站类` `前后端分离应用类`。
+* 后端渲染网站类:采用 go 语言开发,需要安装对应环境或使用编译后的可执行文件。
+* 前后端分离应用类:需要安装 Node 环境。
+
+## 后端渲染网站类
+
+### jy
+
+仓库地址:[qmx/jy](http://jygit.jydev.jianyu360.cn/qmx/jy)
+
+描述:核心网站应用,包含PC端、移动端、微信端相关功能页面,主要集中在标讯等详情页。
+
+## 前后端分离应用类
+
+### web
+
+仓库地址:[jianyu/web](http://jygit.jydev.jianyu360.cn/jianyu/web)
+
+描述:monorepo聚合,PC工作台应用,后续将包含PC端、移动端、微信端相关功能页面。

+ 19 - 0
docs/guide/style/base.md

@@ -0,0 +1,19 @@
+遵循同一套编码规范,通过 `.editorconfig` 统一编辑器配置。
+
+```.editorconfig
+[*.{js,jsx,ts,tsx,vue}]
+indent_style = space
+indent_size = 2
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+```
+
+## 缩进
+使用 2 个空格进行缩进,不使用 tab。
+
+## 换行
+
+- 换行符使用 Unix 风格,即 LF(Linux 换行符)。
+- 文件末尾空行。
+

+ 93 - 0
docs/guide/style/css.md

@@ -0,0 +1,93 @@
+以下规则适用于 css 及 scss 文件。
+
+## 语法
+* 注释统一采用 `/* 注释内容 */`。
+* 为选择器分组时,将单独的选择器单独放在一行。
+* 权重尽可能降低,不滥用 `id` 选择器,避免使用`!important`。
+
+```css
+/* Bad CSS */
+.selector, .selector-secondary, .selector[type=text] {
+    /* Typography */
+    font: normal 13px "Helvetica Neue", sans-serif;
+    line-height: 1.5;
+}
+
+/* Good CSS */
+.selector,
+.selector-secondary,
+.selector[type="text"] {
+    /* Typography */
+    font: normal 13px "Helvetica Neue", sans-serif;
+    line-height: 1.5;
+}
+```
+
+## BEM 命名原则
+* block:模块,名字单词间用 - 连接
+* element:元素,模块的子元素,以 __ 与 block 连接
+* modifier:修饰,模块的变体,定义特殊模块,以 -- 与 block 连接
+
+尽量简单语义化,明确它的用途,避免过度任意的简写。
+
+```css
+/* Bad example */
+.j-info { ... }
+.red { ... }
+.active { ... }
+
+/* Good example */
+.j-button--info { ... }
+.text-red { ... }
+.cell-active { ... }
+
+```
+
+## 属性顺序
+相关的属性声明应当归为一组,并按照下面的顺序排列:
+
+1. Positioning
+2. Box model
+3. Typographic
+4. Visual
+5. Misc
+
+...
+
+由于定位(positioning)可以从正常的文档流中移除元素,并且还能覆盖盒模型(box model)相关的样式,因此排在首位。
+
+盒模型排在第二位,因为它决定了组件的尺寸和位置。
+
+其他属性只是影响组件的 内部 或者是不影响前两组属性,因此排在后面。
+
+```css
+.declaration-order {
+  /* Positioning */
+  position: absolute;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  z-index: 100;
+
+  /* Box-model */
+  display: block;
+  float: right;
+  width: 100px;
+  height: 100px;
+
+  /* Typography */
+  font: normal 13px "Helvetica Neue", sans-serif;
+  line-height: 1.5;
+  color: #333;
+  text-align: center;
+
+  /* Visual */
+  background-color: #f5f5f5;
+  border: 1px solid #e5e5e5;
+  border-radius: 3px;
+
+  /* Misc */
+  opacity: 1;
+}
+```

+ 106 - 0
docs/guide/style/html.md

@@ -0,0 +1,106 @@
+尽量遵循HTML标准和语义,但是不应该以浪费实用性作为代价;
+
+任何时候都要用尽量小的复杂度和尽量少的标签来解决问题。
+
+## 减少标签层级
+在HTML中,标签层级越深,页面的可读性就越差。因此,在编写HTML代码时,应该尽量减少标签层级,使页面结构更清晰。
+
+```html
+
+<!-- Not so great -->
+<span class="avatar"> // [!code error]
+  <img src="...">     // [!code error]
+</span>               // [!code error]
+
+<!-- Better -->
+<img class="avatar" src="..."> // [!code focus]
+```
+
+## 语义化标签
+
+语义化标签是指在HTML中,标签的作用与内容之间建立了语义关系。语义化标签可以让浏览器更好地理解网页内容,从而提高用户体验。
+
+```html
+<!-- bad -->
+<div id="main">
+  <div class="article">
+    <div class="header">
+      <h1>Blog post</h1>
+      <p>Published: <span>21st Feb, 2015</span></p>
+    </div>
+    <p>…</p>
+  </div>
+</div>
+
+<!-- good -->
+<main>
+  <article>
+    <header>
+      <h1>Blog post</h1>
+      <p>Published: <time datetime="2015-02-21">21st Feb, 2015</time></p>
+    </header>
+    <p>…</p>
+  </article>
+</main>
+
+```
+
+## 自闭合标签无需闭合
+
+在HTML中,自闭合标签是指在标签内部同时包含了开标签和闭标签的元素,而不需要额外的闭标签。以下是一些常见的自闭合标签:
+
+```html
+<img>
+<br>
+<hr>
+<input>
+<meta>
+<link>
+...
+```
+这些标签在HTML中不需要闭合标签,因为它们没有内容或内容已经在标签内部完全指定。
+
+## 属性
+
+在属性上,使用**双引号**,不要使用单引号。
+
+## 布尔(boolean)型属性
+布尔型属性可以在声明时不赋值。
+
+`checked`, `selected`, `disabled`, `readonly` ...
+
+```html
+<input type="text" disabled>
+
+<input type="checkbox" value="1" checked>
+
+<select>
+  <option value="1" selected>1</option>
+</select>
+```
+
+
+## 属性顺序
+HTML 属性应当按照以下给出的顺序依次排列,确保代码的易读性。
+
+* `class`
+* `id`, `name`
+* `data-*`
+* src, for, type, href, value , max-length, max, min, pattern
+* placeholder, title, alt
+* aria-*, role
+* required, readonly, disabled
+
+class是为高可复用组件设计的,所以应处在第一位;
+
+id更加具体且应该尽量少使用,所以将它放在第二位。
+
+```html
+<a class="..." id="..." data-toggle="modal" href="#">
+  Example link
+</a>
+
+<input class="form-control" type="text">
+
+<img src="..." alt="...">
+```

+ 39 - 0
docs/guide/style/introduce.md

@@ -0,0 +1,39 @@
+所谓无规矩不成方圆,不同时期不同开发人员写的代码可谓五花八门。 因此我们提出了一些相关代码方面的规范,希望日后能形成团队的编码规范。
+
+制定开发规范的目的:
+
+- 统一团队的代码风格,减少代码冲突
+- 规范团队的开发流程,提高开发效率
+- 规范团队的协作方式,提高协作效率
+
+## 规范准则
+
+### 1. 一致性
+
+代码风格应该是一致的,无论团队人数多少,代码应该同出一门。
+
+不管有多少人共同参与同一项目,一定要确保每一行代码都像是同一个人编写的。
+
+这样可以减少代码冲突,提高代码可读性。
+
+### 2. 易于阅读
+
+代码应该易于阅读,注释应该是清晰的,不应该有歧义。
+
+### 3. 易于扩展
+
+代码应该易于扩展,选择合适的设计模式,预留扩展点。
+
+### 4. 易于维护
+
+代码应该易于维护,业务逻辑与UI视图分离,模型清晰。
+
+
+## 维护
+
+不过我们也不确信风格指南的所有内容对于所有的团队或工程都是理想的。
+所以根据过去的经验、周围的技术栈、个人价值观做出有意义的偏差是可取的。
+
+如果你发现本规范中有任何错误,敬请指正。
+
+如果你想要为这个规范做贡献或觉得有不合理的地方,请编辑后,提交 PR,进行讨论。

+ 90 - 0
docs/guide/style/js.md

@@ -0,0 +1,90 @@
+以下规则适用于 js、ts文件。
+
+## 语法
+* 统一使用单引号而不是双引号。
+* 避免使用直接 eval 函数。
+* 避免修改外部传入的对象。
+* 一个函数的长度控制在 50 行以内。
+* 类型检测优先使用 typeof。
+
+## 命名
+尽量简单语义化,明确它的用途,避免过度任意的简写。
+
+普通命名采用小驼峰式命名。
+
+### Const 常量
+- 常量名采用大写字母,单词间用下划线分隔,例如 `USER_NAME`、`USER_AGE`。
+- 常量名应该是所有字母都大写的,例如 `USER_NAME`、`USER_AGE`。
+
+### Class 类
+- 类名采用驼峰命名法,首字母大写,例如 `User`、`UserManager`。
+
+### Method 方法
+- 方法名采用驼峰命名法,首字母小写,例如 `getUser`、`getUserInfo`。
+
+命名需要符合语义化,可以采用加上动词前缀:
+
+* `can` 判断是否可执行某个动作
+* `has` 判断是否含有某个值
+* `is` 判断是否为某个值
+* `get` 获取某个值
+* `set` 设置某个值
+* `ajax` 请求相关
+
+## 注释
+
+### 单行注释
+
+* 位于代码上方。
+* 双斜线后,必须跟一个空格。
+* 缩进与下一行代码保持一致。
+
+```js
+if (condition) {
+    // if you made it here, then all security checks passed
+    allowed();
+}
+```
+
+### 多行注释
+遵循单行注释,采用  `jsdoc` 风格。
+
+```js
+/**
+ * 一个带参数的函数
+ * @func
+ * @desc 一个带参数的函数,用于例子
+ * @param {string} a - 参数a
+ * @param {string} b - 参数b
+ * @return {string} 结果
+ */
+function func(a, b) {
+    //...
+}
+```
+## 可读性优先
+在一般场景下,代码的可读性、正确性优先,基本上不会遇到性能瓶颈。
+
+```js
+// bad (albeit way faster)
+const arr = [1, 2, 3, 4];
+const len = arr.length;
+var i = -1;
+var result = [];
+while (++i < len) {
+  var n = arr[i];
+  if (n % 2 > 0) continue;
+  result.push(n * n);
+}
+
+// good
+const arr = [1, 2, 3, 4];
+const isEven = n => n % 2 == 0;
+const square = n => n * n;
+
+const result = arr.filter(isEven).map(square);
+
+```
+
+## 职责单一
+一个类只做一件事,一个方法只做一件事,一个变量只做一件事。

+ 58 - 0
docs/guide/style/naming.md

@@ -0,0 +1,58 @@
+业界目前广泛采用的两种命名规则: 
+1. 单词大写开头。 `驼峰` (PascalCase)
+2. 单词横线连接 (kebab-case)。
+
+这里我们根据历史项目的评估,针对`文件名`选用第二种规则 (kebab-case)。
+
+
+## 项目命名
+全部采用小写方式, 以下划线分隔。
+
+例:my_project_name
+
+## 目录命名
+参照项目命名规则;
+
+有复数结构时,要采用复数命名法。
+
+例:scripts, styles, images, data_models
+
+## JS文件命名
+参照项目命名规则。
+
+采用 `(业务/功能)_模块` 形式命名资源目录及资源。
+
+例:account_model.js
+
+## CSS, SCSS文件命名
+参照JS命名规则。
+
+例:retina_sprites.scss
+
+## HTML文件命名
+参照JS命名规则。
+
+例:error_report.html
+
+## VUE文件命名
+参照JS命名规则。
+
+例:error_report.vue
+
+## 示例
+```
+<!-- HTML -->
+
+order_list.html
+order_detail.html
+
+<!-- CSS / SCSS -->
+
+order_list.css
+order_detail.scss
+
+<!-- JS / TS -->
+
+order_list.js
+order_detail.ts
+```

+ 61 - 0
docs/guide/style/vue.md

@@ -0,0 +1,61 @@
+参照官方风格指南,语法注释遵循 JS 规范。
+
+## Prop 名大小写
+在声明 prop 的时候,其命名应该始终使用 camelCase,而在模板和 JSX 中应该始终使用 kebab-case。
+
+```vue
+props: {
+  greetingText: String
+}
+
+<empty-tip greeting-text="hi"/>
+```
+
+## 多个 attribute 的元素
+
+小于三个属性,长度清晰时可以一行。
+
+大于三个属性,进行分行。
+
+```vue
+# 小于三个属性,长度清晰时可以一行。
+<my-component foo="a" bar="b" baz="c"/>
+
+# 大于三个属性,进行分行
+<my-component
+  foo="a"
+  bar="b"
+  content="b"
+  baz="c"
+/>
+```
+
+## 清除定时器或者事件监听
+
+由于项目中有些页面难免会碰到需要定时器或者事件监听。
+
+但是在离开当前页面的时候,定时器如果不及时合理地清除,会造成业务逻辑混乱甚至应用卡死的情况,这个时就需要清除定时器事件监听,即在页面卸载(关闭)的生命周期函数里,清除定时器。
+
+```vue
+methods:{
+  resizeFun () {
+    this.tableHeight = window.innerHeight - document.getElementById('table').offsetTop - 128
+  },
+  setTimer() {
+    this.timer = setInterval(() => { })
+  },
+  clearTimer() {
+		clearInterval(this.timer)
+    this.timer = null
+	}
+},
+mounted() {
+  this.setTimer()
+  window.addEventListener('resize', this.resizeFun)
+},
+beforeDestroy() {
+  window.removeEventListener('resize', this.resizeFun)
+  this.clearTimer()
+}
+
+```

BIN
docs/img.png


+ 58 - 0
docs/index.md

@@ -0,0 +1,58 @@
+---
+layout: home
+
+title: VitePress
+titleTemplate: Vite & Vue Powered Static Site Generator
+
+hero:
+  name: "剑鱼标讯"
+  text: "前端团队内部文档"
+  tagline: 探索前端世界,从文档开始
+  actions:
+  - theme: brand
+    text: 指南
+    link: /guide/getting-started
+  - theme: alt
+    text: 代码风格
+    link: /guide/style/introduce
+  - theme: alt
+    text: 参与贡献
+    link: /
+  image:
+    src: /logo.png
+    alt: 剑鱼标讯
+
+  features:
+  - icon: 📝
+    title: Focus on Your Content
+    details: Effortlessly create beautiful documentation sites with just markdown.
+  - icon: <svg xmlns="http://www.w3.org/2000/svg" width="30" viewBox="0 0 256 256.32"><defs><linearGradient id="a" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"/><stop offset="100%" stop-color="#BD34FE"/></linearGradient><linearGradient id="b" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"/><stop offset="8.333%" stop-color="#FFDD35"/><stop offset="100%" stop-color="#FFA800"/></linearGradient></defs><path fill="url(#a)" d="M255.153 37.938 134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"/><path fill="url(#b)" d="M185.432.063 96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028 72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"/></svg>
+    title: Enjoy the Vite DX
+    details: Instant server start, lightning fast hot updates, and leverage Vite ecosystem plugins.
+  - icon: <svg xmlns="http://www.w3.org/2000/svg" width="30" viewBox="0 0 256 220.8"><path fill="#41B883" d="M204.8 0H256L128 220.8 0 0h97.92L128 51.2 157.44 0h47.36Z"/><path fill="#41B883" d="m0 0 128 220.8L256 0h-51.2L128 132.48 50.56 0H0Z"/><path fill="#35495E" d="M50.56 0 128 133.12 204.8 0h-47.36L128 51.2 97.92 0H50.56Z"/></svg>
+    title: Customize with Vue
+    details: Use Vue syntax and components directly in markdown, or build custom themes with Vue.
+  - icon: 🚀
+    title: Ship Fast Sites
+    details: Fast initial load with static HTML, fast post-load navigation with client-side routing.
+---
+
+<style>
+:root {
+
+  --vp-home-hero-image-background-image: linear-gradient(270deg, #3687FF 0%, #2ABED1 100%);
+  --vp-home-hero-image-filter: blur(44px);
+}
+
+@media (min-width: 640px) {
+  :root {
+    --vp-home-hero-image-filter: blur(56px);
+  }
+}
+
+@media (min-width: 960px) {
+  :root {
+    --vp-home-hero-image-filter: blur(68px);
+  }
+}
+</style>

+ 20 - 0
docs/package.json

@@ -0,0 +1,20 @@
+{
+  "name": "docs",
+  "description": "剑鱼前端内部文档",
+  "private": true,
+  "scripts": {
+    "dev": "vitepress dev --port 8088",
+    "build": "vitepress build",
+    "preview": "vitepress preview"
+  },
+  "keywords": [],
+  "author": "",
+  "devDependencies": {
+    "vite": "^4.3.1",
+    "vitepress": "1.0.0-rc.31"
+  },
+  "engines": {
+    "node": ">=16",
+    "pnpm": ">=8"
+  }
+}

BIN
docs/public/icon/HuggingChat.png


BIN
docs/public/icon/caniuse.png


BIN
docs/public/icon/code-geex.png


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2 - 0
docs/public/icon/codewhisperer.svg


+ 3 - 0
docs/public/icon/cursor.svg

@@ -0,0 +1,3 @@
+<svg width="24" height="23" viewBox="0 0 24 23" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M2.5 12L10.7163 11.97C10.9251 11.9693 11.1183 11.8681 11.3106 11.7868C11.4111 11.7444 11.5189 11.7221 11.628 11.7213C11.7371 11.7205 11.8452 11.7412 11.9463 11.7822C12.0474 11.8232 12.1394 11.8837 12.217 11.9603C12.2947 12.0368 12.3566 12.128 12.399 12.2284C12.4415 12.3289 12.4638 12.4367 12.4646 12.5458C12.4654 12.6549 12.4447 12.763 12.4037 12.8641C12.3251 13.0577 12.2256 13.252 12.2256 13.461V19L12.2315 20.7942C12.2388 22.9969 15.2811 23.5716 16.0913 21.5232L23.2685 3.37768C23.9175 1.73693 22.2785 0.120838 20.647 0.792768L1.78574 8.5608C-0.0417395 9.31345 0.523947 12.0373 2.5 12Z" fill="#999999"/>
+</svg>

BIN
docs/public/icon/exercism.png


BIN
docs/public/icon/figma.png


BIN
docs/public/icon/git.png


BIN
docs/public/icon/gitlab.png


BIN
docs/public/icon/hackr.png


BIN
docs/public/icon/logo-npm.png


BIN
docs/public/icon/mdn.png


BIN
docs/public/icon/pdf.png


BIN
docs/public/icon/perplexity.ai.png


BIN
docs/public/icon/poe.com.ico


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 3 - 0
docs/public/icon/sass.svg


BIN
docs/public/icon/stackoverflow.png


BIN
docs/public/icon/th.jpg


BIN
docs/public/icon/wenxin-chat.jpg


BIN
docs/public/icon/xmind.png


BIN
docs/public/images/track-demo.png


BIN
docs/public/images/track-hj-open-page.png


BIN
docs/public/images/track-hj.png


BIN
docs/public/images/track-page-maps.png


BIN
docs/public/images/track-tools.png


BIN
docs/public/logo.png


BIN
docs/public/pdf/前端知识点.pdf


BIN
docs/public/pdf/前端项目工程化要点.pdf


BIN
docs/public/pdf/我的-页面功能梳理.pdf


BIN
docs/public/pdf/组件拆分示例.pdf


BIN
docs/public/pdf/订阅-页面功能梳理.pdf


BIN
docs/public/xmind/前端项目工程化要点.xmind


BIN
docs/public/xmind/我的-页面功能梳理.xmind


+ 245 - 0
docs/resource.md

@@ -0,0 +1,245 @@
+---
+layout: page
+---
+
+<script setup>
+import CardLayout from './components/card/layout.vue';
+import { useData } from 'vitepress';
+
+const { page } = useData();
+const NavItems = [
+{
+    title: '🔗 快捷链接',
+    desc: '常用网址导航',
+    child: [
+      {
+        icon: '/icon/mdn.png',
+        title: 'MDN',
+        desc: ' 提供有关开放 Web 技术的信息, HTML、CSS 和 API。',
+        href: 'https://developer.mozilla.org/zh-CN/'
+      },
+      {
+        icon: '/icon/caniuse.png',
+        title: 'Can I Use',
+        desc: 'API浏览器兼容性检索',
+        href: 'https://caniuse.com/'
+      },
+      {
+        icon: '/icon/stackoverflow.png',
+        title: 'Stackoverflow',
+        desc: 'IT技术问答网站',
+        href: 'http://192.168.3.71:4000/'
+      }
+    ]
+  },
+  {
+    title: '🚀 AI资源导航',
+    desc: '一些AI工具',
+    child: [
+      {
+        icon: '/icon/cursor.svg',
+        title: 'Cursor',
+        desc: 'AI 编程辅助工具客户端',
+        href: 'https://www.cursor.so'
+      },
+      {
+        icon: '/icon/code-geex.png',
+        title: 'CodeGeeX',
+        desc: '插件 - 国内 AI 编程辅助工具,登录后免费',
+        href: 'https://codegeex.cn/zh-CN'
+      },
+      {
+        icon: '/icon/codewhisperer.svg',
+        title: 'CodeWhisperer',
+        desc: '插件 - 国外 AI 编程辅助工具,注册亚马逊国际账号登录后免费',
+        href: 'https://aws.amazon.com/cn/codewhisperer/'
+      }
+    ]
+  },
+  {
+    title: '🚀 ChatGPT',
+    desc: 'web 端ChatGPT。以下网站如果不能访问,可以翻墙试试',
+    child: [
+      {
+        icon: '/icon/th.jpg',
+        title: 'OpenAI',
+        desc: 'OpenAI ChatGPT(不对CN开放,记录一下)',
+        href: 'https://chat.openai.com'
+      },
+      {
+        icon: '/icon/poe.com.ico',
+        title: 'poe.com',
+        desc: 'helpful AI chat(需要翻墙和邮箱注册,但提供的模型很多)',
+        href: 'https://poe.com'
+      },
+      {
+        icon: '/icon/perplexity.ai.png',
+        title: 'perplexity.ai',
+        desc: 'AI 搜索引擎(功能类似 NewBing, 需要翻墙)',
+        href: 'https://www.perplexity.ai'
+      },
+      {
+        icon: '/icon/HuggingChat.png',
+        title: 'HuggingChat',
+        desc: 'HuggingChat 叫板 ChatGPT,300 亿参数大模型免费用',
+        shortUrl: 'https://hf.co/chat',
+        href: 'https://huggingface.co/chat/'
+      },
+      {
+        icon: '/icon/wenxin-chat.jpg',
+        title: '文心GPT',
+        desc: 'AI CHAT公益站,基于文心官方API实现,与文心GPT功能一致',
+        href: 'https://ai1.chagpt.fun'
+      },
+    ]
+  },
+  {
+    title: '🧭 资源导航',
+    desc: '常用资源导航',
+    child: [
+      {
+        icon: '/icon/logo-npm.png',
+        title: '内网 NPM',
+        desc: '用于内网的 npm 代理注册表',
+        href: 'http://192.168.3.71:4873/'
+      },
+      {
+        icon: 'http://jygit.jydev.jianyu360.cn/img/favicon.png',
+        title: 'Gogs',
+        desc: '内网 git 仓库',
+        href: 'http://jygit.jydev.jianyu360.cn/'
+      },
+      {
+        icon: 'http://192.168.3.71:4000/image/favicon.png',
+        title: 'YApi',
+        desc: '在线接口文档、Mock调试',
+        href: 'http://192.168.3.71:4000/'
+      },
+      {
+        icon: 'http://192.168.3.204:8050/jenkins/static/3d62ff7d/images/svgs/logo.svg',
+        title: 'Jenkins',
+        desc: '用于项目测试部署',
+        href: 'http://192.168.3.204:8050/jenkins/'
+      }
+    ]
+  },
+  {
+    title: '🔧 研发工具',
+    desc: '研发流程辅助工具集',
+    child: [
+      {
+        self: false,
+        fill: '加密',
+        title: 'ASCII',
+        desc: '在线加密、解密工具',
+        href: 'https://www.sojson.com/ascii.html'
+      },
+      {
+        self: false,
+        fill: '正则',
+        title: 'Regex',
+        desc: '在线可视化正则工具',
+        href: 'https://jex.im/regulex/'
+      },
+      {
+        self: false,
+        fill: 'AST',
+        title: 'AST Explorer',
+        desc: '在线可视化 AST 语法树',
+        href: 'https://astexplorer.net/'
+      },
+      {
+        fill: '辅助',
+        title: '剑鱼测试账号',
+        desc: '提供测试环境常用链接、账号筛选管理',
+        href: 'https://jybx-webtest.jydev.jianyu360.com/dev-help/account.html'
+      }
+    ]
+  },
+  {
+    title: '📦 前端基建',
+    desc: '建设中的前端组件库、CLI等',
+    child: [
+      {
+        fill: 'H5',
+        title: '移动端组件库',
+        desc: '组件库文档、使用示例',
+        href: 'http://192.168.3.11:10081/doc-serve/page_docs/'
+      },
+      {
+        fill: 'PC',
+        title: 'PC组件库',
+        desc: '组件库文档、使用示例',
+        href: 'http://192.168.3.11:10081/EFE/jy-ui-library/raw/master/docs/'
+      },
+      {
+        fill: 'CLI',
+        title: '@jianyu/cli',
+        desc: '提供远程模版项目拉取、模块包上传等',
+        href: 'http://192.168.3.207:4873/-/web/detail/@jianyu/cli'
+      }
+    ]
+  },
+  {
+    title: '📁 资料/资源',
+    desc: '内部资源分享',
+    child: [
+      {
+        icon: '/icon/figma.png',
+        title: 'Figma 组件库',
+        desc: '组件库 UI 资源,包含移动端、PC端',
+        href: 'https://www.figma.com/files/project/61897445/%E7%BB%84%E4%BB%B6%E5%BA%93?fuid=679245771498651937'
+      },
+      {
+        icon: '/icon/pdf.png',
+        title: '前端知识点.pdf',
+        desc: '前端技能图谱、团队研发涉及知识点',
+        href: './pdf/前端知识点.pdf'
+      },
+     {
+        icon: '/icon/xmind.png',
+        title: '前端项目工程化要点.xmind',
+        desc: '前端项目工程化流程、及实践要点',
+        href: './xmind/前端项目工程化要点.xmind'
+      },
+      {
+        icon: '/icon/pdf.png',
+        title: '前端项目工程化要点.pdf',
+        desc: '前端项目工程化流程、及实践要点',
+        href: './pdf/前端项目工程化要点.pdf'
+      },
+      {
+        icon: '/icon/xmind.png',
+        title: '我的-页面功能梳理.xmind',
+        desc: '移动端项目,我的-页面功能梳理',
+        href: './xmind/我的-页面功能梳理.xmind'
+      },
+      {
+        icon: '/icon/pdf.png',
+        title: '我的-页面功能梳理.pdf',
+        desc: '移动端项目,我的-页面功能梳理',
+        href: './pdf/我的-页面功能梳理.pdf'
+      },
+      {
+        icon: '/icon/pdf.png',
+        title: '订阅-页面功能梳理.pdf',
+        desc: '移动端项目,订阅-页面功能梳理',
+        href: './pdf/订阅-页面功能梳理.pdf'
+      }
+    ]
+  }
+]
+
+</script>
+
+<style>
+.navigation-page {
+    max-width: calc(var(--vp-layout-max-width) - 80px);
+    margin: 0 auto;
+    padding: 32px;
+}
+</style>
+
+<div class="navigation-page">
+    <CardLayout :cards="NavItems"></CardLayout>
+</div>

+ 47 - 0
docs/to-do/index.md

@@ -0,0 +1,47 @@
+# 参与建设
+
+## PC端组件库
+- [ ] 改造原有项目依赖
+- [ ] 从项目抽取迁移为独立 npm 包
+- [ ] 现有项目组件梳理
+- [x] v0.1版本已完成
+- [ ] ~~升级vue3~~
+
+## 移动端组件库
+- [ ] 改造原有项目依赖
+- [ ] 从项目迁移为独立 npm 包 
+- [x] v1.0版本已完成
+- [ ] ~~升级vue3~~
+
+## 工具库
+- [ ] 改造原有项目依赖
+- [ ] 整合迁移为独立 npm 包
+- [ ] 现有项目工具集梳理
+- [x] v0.1版本已完成
+
+## CLI
+- [ ] 提供 code lint 、git commit 等辅助开发流程
+- [x] 提供 CLI 版本更新
+- [x] 提供模版拉取、模块创建、发布
+
+## 技术文档
+- [ ] 持续更新完善
+- [ ] 项目技术栈及情况概述,汇集剑鱼相关项目业务分布及技术情况
+- [ ] 内网包-组件开发流程示例
+- [ ] 代码约束 + 内网 eslint 规则 完善
+- [ ] 常见问题-山川应用 完善
+- [ ] 自动构建更新
+- [x] 提供技术指南、文档等
+
+## 更多
+
+### icon 内网包 @next 迭代
+- [ ] 提供更优的注入、引用方式
+- [ ] 合并 iconfont 移动、pc端
+
+### eslint 内网规则包 @next
+- [ ] 基于 @vue/press 更新规则
+
+### element-ui 内网版本迁移更新工作
+- [ ] 原PC项目中需要进行升级更新
+- [x] qiankun 模式下 event path 内网修复包已发布

BIN
docs/track/img.png


BIN
docs/track/img_1.png


BIN
docs/track/img_2.png


BIN
docs/track/img_3.png


BIN
docs/track/img_4.png


BIN
docs/track/img_5.png


+ 266 - 0
docs/track/index-new.md

@@ -0,0 +1,266 @@
+# 剑鱼埋点相关问题
+
+::: tip
+
+**2023/6/7**
+* 更新山川BI项目集成代码示例
+* 移除文档AES加密相关内容
+
+**2023/5/29**
+* 更新山川BI项目集成说明及代码示例
+
+* **2023/5/25**
+* 新增山川BI项目集成说明及代码示例
+
+**2023/3/11**
+* 更新埋点集成方式
+* 更新埋点字段
+
+如需参照旧文档进行详细对比,[点这里](./index-old.html)
+:::
+
+
+
+## 埋点用途
+
+目前项目中存在两个统计方式:**百度统计**、**荟聚统计**。
+
+两者的区别:
+* 百度统计主要用于延续之前的分析,可分析网站流量等数据指标。
+* 荟聚统计用于统计**页面事件、页面访问**,以及运营用于营销活动、页面的使用。
+
+## 如何在新项目中集成百度统计、荟聚统计
+
+1. 如下加载对应**两**个JS文件引用
+
+2. 修改对应环境路由,需确保对应环境存在 **common-module** 资源文件映射,能正确访问。
+
+#### 代码示例
+```
+<!--S 【可选项】加载jquery获得更好的事件属性支持 -->
+<script src="https://cdn-common.jianyu360.com/cdn/lib/jquery/3.5.1/jquery.min.js"></script>
+<!--E 【可选项】加载jquery获得更好的事件属性支持 -->
+
+<!--S 加载百度统计及剑鱼自定义埋点 -->
+<script src="https://www.jianyu360.cn/common-module/public/head.js?v=版本号"></script>
+<!--E 加载百度统计及剑鱼自定义埋点 -->
+```
+
+## 如何在山川BI项目中集成百度统计、荟聚统计
+
+1. 在对应项目**资源**菜单,`public > hooks > custom.ts` 中加入下面示例代码。
+2. 检查BI开发模式域名是否正确,当前为 `bidevtest` 或  `onlinesuccbi`
+
+#### 代码示例
+```
+
+import "jquery";
+
+// 剑鱼相关资源版本号,用于版本升级刷新缓存
+const JyAssetsVersion = 120
+
+// 解决页面阻塞问题
+async function initIframeSupport() {
+	const tempL = define.amd
+	define.amd = false
+	try {
+		await import('https://www.jianyu360.cn/common-module/js/JianyuIframe.umd.min.js')
+		new JianyuIframe.easyInjectIframePage({
+			debug: true
+		})
+	} catch (e) {
+		console.warn('t', e)
+	}
+	define.amd = tempL
+}
+
+
+// 剑鱼相关埋点注入
+async function initTrackSupport() {
+	// 判断是否开发环境
+	const inDevStatus = location.origin.indexOf('bidevtest') !== -1 || location.origin.indexOf('onlinesuccbi') !== -1
+	if (inDevStatus) return
+
+	async function injectTrack() {
+		if (document.readyState !== 'complete') return
+		try {
+			await import(location.origin + '/common-module/track/j-track.min.js?v=' + JyAssetsVersion)
+		} catch (e) {
+			console.warn('t', e)
+		}
+	}
+
+	document.addEventListener('readystatechange', injectTrack);
+	await injectTrack()
+}
+
+try {
+	initIframeSupport()
+	initTrackSupport()
+} catch (e) {
+	console.warn('track', e)
+}
+```
+#### 操作示意图
+![img_5.png](img_5.png)
+
+
+## 如何验证是否成功集成
+
+1. 访问页面
+2. 打开开发者工具
+3. 切换到 Network 面板并筛选或清空
+4. 对页面元素进行点击操作
+5. 验证是否新增请求及请求中内容是否与点击内容一致
+
+
+#### 操作示意图
+![img_3.png](img_3.png)
+
+## 如何上传自定义埋点数据
+
+集成SDK后,可以通过 `window.__EasyJTrack.addTrack` 函数自定义上报,默认包含页面基础字段,可覆盖。
+
+#### 代码示例
+```
+window.__EasyJTrack.addTrack('自定义上报的埋点标识', {
+    custom: '自定义上报的字段'
+})
+```
+
+#### 效果图
+![img_4.png](img_4.png)
+
+
+## 荟聚统计相关
+
+### 页面访问数据埋点
+
+通过 JTrack SDK 针对荟聚平台原有的 open_page 字段进行了扩展,跟随每次进入页面的上报事件一同上报。
+
+主要用途:
+* 绑定用户信息,用于荟聚分析平台能使用 c_uid 进行对应关联。
+* 更新替换页面自定义属性,如页面名称、页面Id,使其能在分析时进行便捷使用。
+
+#### 使用示例
+![使用示例](/images/track-hj-open-page.png)
+
+#### 页面名称、ID定义数据
+
+* 该数据由运营、研发、产品共同制定并纳入质量部门发版SOP流程进行维护。
+* 可通过WPS文档、或企业微信文档进行查阅。 [页面信息表](https://www.kdocs.cn/l/cqmIGa3HPkf2)
+
+![img.png](img.png)
+
+表格包含以下字段:
+* 页面URL (必填项)
+* 页面功能简述
+* 页面名称
+* 产品名称
+* 页面ID
+
+转换后的JSON文件格式
+
+```
+[
+  {
+    "页面URL": "/page_workDesktop/work-bench/app/big/workspace/dashboard",
+    "页面功能简述": "PC 工作桌面-首页",
+    "产品名称": "",
+    "页面名称": "工作桌面-首页",
+    "页面ID": ""
+  },
+  {
+    "页面URL": "/page_workDesktop/work-bench/page?link=https%3A%2F%2Fjybx-webtest.jydev.jianyu360.com%2Fjylab%2Fsupsearch%2Findex.html",
+    "页面功能简述": "招招标采购公告、超前项目搜索",
+    "产品名称": "",
+    "页面名称": "信息搜索-招标采购搜索",
+    "页面ID": ""
+  }
+]
+```
+
+::: warning
+每次更新表格需同步维护更新对应的JSON文件,移动端对应 mobile.json,PC端对应 pc.json
+:::
+
+
+### 通用页面访问信息埋点
+
+通过 head.js 注入 JTrack SDK,用于收集页面访问数据,并调用荟聚上报函数。
+
+#### 上报自定义字段明细
+
+|      字段       |  描述   |                        规则                         |
+|:-------------:|:-----:|:-------------------------------------------------:|
+|  c_platform   |  平台   |        PC、H5、APP、WeChatWeb、WeChatMP、Other         |
+|   c_pageid    | 页面ID  |                  映射表中定义的**页面ID**                  |
+|     c_url     | 页面URL |                       href                        |
+|  c_pagename   | 页面名称  |                  映射表中定义的**页面名称**                  |
+| c_productname | 产品名称  |                  映射表中定义的**产品名称**                  |
+|    c_desc     | 页面功能简述  |                 映射表中定义的**页面功能简述**                 |
+|    c_title    | 页面真实title(备用)  |                  document.title                   |
+
+::: warning
+这里需要注意, 剑鱼平台PC端目前可能存在同一页面,在工作桌面嵌入时,与独立访问时出现两个 c_url
+:::
+
+#### 荟聚平台分析使用示例
+1. 访问登录荟聚分析平台
+2. 选择进入 **分析 - 常用分析 - 行为分析**
+3. 分析行为中,选择 **客户自定义事件 - 通用页面访问信息**
+4. 限制事件属性来分析指定场景的页面访问数据
+5. 选择分析维度、分析指标、分析时间等筛选条件
+
+![img_1.png](img_1.png)
+
+
+### 通用点击事件埋点
+
+通过 head.js 注入 JTrack SDK,用于收集后端渲染Go项目、前后端分离Vue项目的点击事件信息,并调用荟聚上报函数。
+
+
+#### 上报自定义字段明细
+
+|      字段       |  描述   |                        规则                        |
+|:-------------:|:-----:|:------------------------------------------------:|
+|  c_platform   |  平台   |        PC、H5、APP、WeChatWeb、WeChatMP、Other        |
+|   c_pageid    | 页面ID  | 映射表中定义的**页面ID** 或者  location.pathname |
+|     c_url     | 页面URL |                       href                       |
+|  c_pagename   | 页面名称  |        映射表中定义的**页面名称** 或者 document.title         |
+| c_productname | 产品名称  |                 映射表中定义的**产品名称**                  |
+|    c_desc     | 页面功能简述  |                映射表中定义的**页面功能简述**                 |
+|    c_title    | 页面真实title(备用)  |                  document.title                  |
+| c_breakername | 断点名称  | 点击元素或者父级元素的 innerText 或 name 或 title,最大字符长度为 15  |
+|  c_breakerid  | 断点ID  |                    点击元素 xpath                    |
+
+
+#### 荟聚平台分析使用示例
+1. 访问登录荟聚分析平台
+2. 选择进入 **分析 - 常用分析 - 行为分析**
+3. 分析行为中,选择 **客户自定义事件 - 剑鱼通用点击事件(勿删)**
+4. 限制事件属性来分析指定场景的点击数据
+5. 选择分析维度、分析指标、分析时间等筛选条件
+
+##### 👇下面示例分析 ** 再次购买 ** 按钮的点击情况
+1. 限制事件属性中,设置条件为:**断点名称** 包含 **再次购买**,与上报信息中 c_breakername 一致
+2. 分析维度中,选择根据 平台 / 页面url 分析,与上报信息中 c_platform、c_url 一致
+   ![荟聚示例](/images/track-hj.png)
+
+
+> 如需了解其他技术细节、加解密密钥请前往 [jy-track](http://192.168.3.207:8080/zhangyuhan/jy-track)
+
+> 也可以使用埋点反查询工具,寻找查看对应关系
+
+### 通用点击事件-埋点反查询工具
+![埋点反查询工具](/images/track-tools.png)
+
+::: warning
+**2023/3/11**
+* SDK 新增的通用页面访问统计暂不支持查询
+* SDK 新增的自定义参数暂不支持查询
+  :::
+
+#### 下载安装
+1. 访问企业微信 - 微盘 - 项目文件 - 埋点查询工具
+2. 根据自己操作系统下载不同的平台(Windows/MAC)的安装包

+ 101 - 0
docs/track/index-old.md

@@ -0,0 +1,101 @@
+# 剑鱼埋点相关问题
+
+::: danger
+该文档已过期
+
+新文档,[点这里](./index-new.html)
+:::
+
+## 埋点用途
+
+目前项目中存在两个统计方式:**百度统计**、**荟聚统计**。
+
+两者的区别: 
+* 百度统计主要用于延续之前的分析,可分析网站流量等数据指标。
+* 荟聚统计用于统计**页面事件、页面访问**,以及运营用于营销活动、页面的使用。
+
+## 如何在新项目中集成百度统计、荟聚统计
+
+1. 如下图加载对应三个JS文件引用
+
+2. head.js、fotter.js修改对应环境路由,需确保对应环境存在 **common-module** 资源文件映射,能正确访问。
+
+
+![代码示例](/images/track-demo.png)
+
+#### 代码示例
+```
+<!--S 加载百度统计及剑鱼自定义埋点 -->
+<script src="https://www.jianyu360.cn/common-module/public/head.js"></script>
+<!--E 加载百度统计及剑鱼自定义埋点 -->
+
+<!--S 加载荟聚SDK初始化及剑鱼自定义埋点注入 -->
+<script src="https://cdn-common.jianyu360.com/cdn/lib/jquery/3.5.1/jquery.min.js"></script>
+<script src="https://www.jianyu360.cn/common-module/public/fotter.js"></script>
+<!--E 加载荟聚SDK初始化及剑鱼自定义埋点注入 -->
+```
+
+## 荟聚统计相关
+
+### 页面访问数据埋点
+
+通过 fotter.js 针对荟聚平台原有的 open_page 字段进行了扩展,跟随每次进入页面的上报事件一同上报。
+
+主要用途:
+* 绑定用户信息,用于荟聚分析平台能使用 c_uid 进行对应关联。
+* 更新替换页面自定义属性,如页面名称、页面Id,使其能在分析时进行便捷使用。
+
+#### 使用示例
+![使用示例](/images/track-hj-open-page.png)
+
+#### 页面名称、ID定义数据
+
+* 该数据由运营、研发、产品共同制定。
+* 可通过全局变量 **jyPageMaps** 访问查阅。
+
+![页面名称、ID定义数据](/images/track-page-maps.png)
+
+
+
+
+### 通用点击事件埋点
+
+通过 head.js 注入自研 track 统计SDK,用于收集后端渲染Go项目、前后端分离Vue项目的点击事件信息,并调用荟聚上报函数。
+
+
+#### 上报自定义字段明细
+
+|      字段       |  描述   |                规则                |
+|:-------------:|:-----:|:--------------------------------:|
+|  c_platform   |  平台   | PC、APP、WeChatWeb、WeChatMP、Other  |
+|   c_pageid    | 页面ID  |  使用 AES 加密后的 location.pathname   |
+|     c_url     | 页面url |               href               |
+|  c_pagename   | 页面名称  |          document.title          |
+| c_breakername | 断点名称  | 点击元素或者父级元素的 innerText,最大字符长度为 20 |
+|  c_breakerid  | 断点ID  |      使用 AES 加密后的点击元素 xpath       |
+|  c_breakerid  | 断点ID  |      使用 AES 加密后的点击元素 xpath       |
+
+
+#### 荟聚平台分析使用示例
+1. 访问登录荟聚分析平台
+2. 选择进入 **分析 - 常用分析 - 行为分析**
+3. 分析行为中,选择 **客户自定义事件 - 剑鱼通用点击事件(勿删)**
+4. 限制事件属性来分析指定场景的点击数据
+5. 选择分析维度、分析指标、分析时间等筛选条件
+
+##### 👇下面示例分析 ** 再次购买 ** 按钮的点击情况
+1. 限制事件属性中,设置条件为:**断点名称** 包含 **再次购买**,与上报信息中 c_breakername 一致
+2. 分析维度中,选择根据 平台 / 页面url 分析,与上报信息中 c_platform、c_url 一致
+![荟聚示例](/images/track-hj.png)
+
+
+> 如需了解其他技术细节、加解密密钥请前往 [jy-track](http://192.168.3.207:8080/zhangyuhan/jy-track)
+
+> 也可以使用埋点反查询工具,寻找查看对应关系
+
+### 通用点击事件-埋点反查询工具
+![埋点反查询工具](/images/track-tools.png)
+
+#### 下载安装
+1. 访问企业微信 - 微盘 - 项目文件 - 埋点查询工具
+2. 根据自己操作系统下载不同的平台(Windows/MAC)的安装包

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 804 - 57
pnpm-lock.yaml


Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio