From 018f4a9aca3e8693eb0514457b1ad71b3af10f5d Mon Sep 17 00:00:00 2001
From: XiaoDaiGua-Ray <443547225@qq.com>
Date: Fri, 11 Aug 2023 21:50:58 +0800
Subject: [PATCH 1/2] mock

---
 CHANGELOG.md                                  |  11 ++
 LICENSE                                       |  21 +++
 MANUAL.md                                     | 171 -----------------
 README.md                                     | 128 +++++--------
 cfg.ts                                        |   9 +-
 mock/demo/person.mock.ts                      |  51 ++++++
 mock/shared/database.ts                       |  14 ++
 mock/shared/utils.ts                          |  64 +++++++
 package.json                                  |  10 +-
 src/axios/api/demo/mock/person.ts             |  27 +++
 src/axios/api/{ => demo}/test.ts              |   2 +-
 src/components/RayCollapseGrid/src/index.tsx  |  12 +-
 src/components/RayTable/src/index.tsx         |   3 +-
 src/locales/lang/en-US/menu.json              |   3 +-
 src/locales/lang/zh-CN/menu.json              |   3 +-
 src/router/modules/demo/axios.ts              |   2 +-
 src/router/modules/demo/directive.ts          |   2 +-
 src/router/modules/demo/doc.ts                |   2 +-
 src/router/modules/demo/echart.ts             |   2 +-
 src/router/modules/demo/iframe.ts             |   2 +-
 src/router/modules/demo/mock.ts               |  18 ++
 src/router/modules/demo/multi-menu.ts         |   6 +-
 src/router/modules/demo/office.ts             |   8 +-
 src/router/modules/demo/precision.ts          |   2 +-
 src/router/modules/demo/rely.ts               |   2 +-
 src/router/modules/demo/router-demo.ts        |   6 +-
 src/router/modules/demo/scroll-reveal.ts      |   2 +-
 src/router/modules/demo/table.ts              |   2 +-
 src/types/modules/axios.ts                    |   9 +-
 src/views/{ => demo}/axios/index.scss         |   0
 src/views/{ => demo}/axios/index.tsx          |   2 +-
 src/views/{ => demo}/directive/index.tsx      |   0
 src/views/{ => demo}/doc/index.tsx            |   0
 src/views/{ => demo}/echart/index.scss        |   0
 src/views/{ => demo}/echart/index.tsx         |   0
 src/views/{ => demo}/iframe/index.tsx         |   0
 src/views/demo/mock-demo/index.tsx            | 173 ++++++++++++++++++
 .../multi/views/multi-menu-one/index.tsx      |   0
 .../views/sub-menu-other/index.tsx            |   0
 .../views/multi-menu-two-one/index.tsx        |   0
 src/views/{ => demo}/office/index.tsx         |   0
 .../office/views/document/index.tsx           |   0
 .../office/views/presentation/index.tsx       |   0
 .../office/views/spreadsheet/index.tsx        |   0
 src/views/{ => demo}/precision/index.tsx      |   0
 .../rely/views/rely-about/index.scss          |   0
 .../rely/views/rely-about/index.tsx           |   0
 .../router-demo/router-demo-detail/index.tsx  |   0
 .../router-demo/router-demo-home/index.tsx    |   0
 src/views/{ => demo}/scroll-reveal/index.scss |   0
 src/views/{ => demo}/scroll-reveal/index.tsx  |   0
 src/views/{ => demo}/table/index.tsx          |   0
 vite.config.ts                                |  15 ++
 53 files changed, 489 insertions(+), 295 deletions(-)
 create mode 100644 LICENSE
 delete mode 100644 MANUAL.md
 create mode 100644 mock/demo/person.mock.ts
 create mode 100644 mock/shared/database.ts
 create mode 100644 mock/shared/utils.ts
 create mode 100644 src/axios/api/demo/mock/person.ts
 rename src/axios/api/{ => demo}/test.ts (94%)
 create mode 100644 src/router/modules/demo/mock.ts
 rename src/views/{ => demo}/axios/index.scss (100%)
 rename src/views/{ => demo}/axios/index.tsx (98%)
 rename src/views/{ => demo}/directive/index.tsx (100%)
 rename src/views/{ => demo}/doc/index.tsx (100%)
 rename src/views/{ => demo}/echart/index.scss (100%)
 rename src/views/{ => demo}/echart/index.tsx (100%)
 rename src/views/{ => demo}/iframe/index.tsx (100%)
 create mode 100644 src/views/demo/mock-demo/index.tsx
 rename src/views/{ => demo}/multi/views/multi-menu-one/index.tsx (100%)
 rename src/views/{ => demo}/multi/views/multi-menu-two/views/sub-menu-other/index.tsx (100%)
 rename src/views/{ => demo}/multi/views/multi-menu-two/views/sub-menu/views/multi-menu-two-one/index.tsx (100%)
 rename src/views/{ => demo}/office/index.tsx (100%)
 rename src/views/{ => demo}/office/views/document/index.tsx (100%)
 rename src/views/{ => demo}/office/views/presentation/index.tsx (100%)
 rename src/views/{ => demo}/office/views/spreadsheet/index.tsx (100%)
 rename src/views/{ => demo}/precision/index.tsx (100%)
 rename src/views/{ => demo}/rely/views/rely-about/index.scss (100%)
 rename src/views/{ => demo}/rely/views/rely-about/index.tsx (100%)
 rename src/views/{ => demo}/router-demo/router-demo-detail/index.tsx (100%)
 rename src/views/{ => demo}/router-demo/router-demo-home/index.tsx (100%)
 rename src/views/{ => demo}/scroll-reveal/index.scss (100%)
 rename src/views/{ => demo}/scroll-reveal/index.tsx (100%)
 rename src/views/{ => demo}/table/index.tsx (100%)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index af49a10d..cfe443df 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,16 @@
 # CHANGE LOG
 
+## 4.1.7
+
+### Feats
+
+- 新增 mock 支持
+- 重新梳理 demo views 包
+
+### Fixes
+
+- 修复 RayCollapseGrid 组件显示问题,现在如果未存在溢出情况,不会显示 展开/收起 按钮
+
 ## 4.1.6
 
 ### Feats
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 00000000..198bbf60
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020-present, Ray
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/MANUAL.md b/MANUAL.md
deleted file mode 100644
index faef0ab5..00000000
--- a/MANUAL.md
+++ /dev/null
@@ -1,171 +0,0 @@
-## Ray Template 使用手册
-
-## 前言
-
-> `Ray Template` 默认使用 `pnpm` 作为包管理器,并且默认启用严格模式的 `eslint`。在导入模块的时候除 `.ts` `.tsx` `.d.ts` 文件等不需要手动补全后缀名,其余的模块导入应该手动补全所有后缀名。
-
-### 使用
-
-#### 项目安装
-
-```sh
-# github
-git clone https://github.com/XiaoDaiGua-Ray/ray-template.git
-
-# 如果你的下载速度很慢,可以切换到下面的代理地址
-git clone https://gh.yka.moe/https://github.com/XiaoDaiGua-Ray/ray-template.git
-```
-
-#### 依赖安装
-
-```sh
-# yarn
-yarn
-
-# npm
-npm i
-```
-
-#### 启动项目
-
-```sh
-# yarn
-yarn dev
-
-# npm
-npm run dev
-```
-
-#### 构建项目
-
-```sh
-# yarn
-yarn build
-
-# npm
-npm run build
-```
-
-### 国际化
-
-#### Tip
-
-- 每个新的语言包文件的文件名视为 path 开头(menu.json => menu.xxx)
-
-#### 新增语言包、新增语言模块
-
-> 项目国际化管理模块,统一放置于 `src/locales` 下。
-
-##### 文件包
-
-- lang
-- helper.ts
-- index.ts
-- useI18n.ts
-
-> 项目中使用 t locale 方法时,使用模板提供方法(useI18n.ts)
-
-```tsx
-// 引入包
-import { useI18n } from '@/locales/useI18n'
-
-const { t, locale } = useI18n()
-
-/**
- *
- * t: 用于绑定国际化 path
- * locale: 用于切换系统语言。参数 key 必须与 lang 包中的语言包一致
- */
-
-const demo = () => <span>{t('demo.demo')}</span>
-
-locale('zh-CN')
-locale('en-US')
-```
-
-##### 新增语言包
-
-> 我们举例新增台湾地区语言包。
-
-- `src/locales/lang` 文件下创建对应新语言包文件夹与语言文件
-  - zh-TW 文件夹
-  - zh-TW.ts 文件
-- 创建与原有语言格式一样的文件夹(可以直接 cv 过去)
-- 配置语言下拉项(LOCAL_OPTIONS)
-- 配置 dayjs 国际化映射(DAYJS_LOCAL_MAP)
-
-> 具体注意事项看注释。
-
-##### 最后
-
-> 按照上述步骤操作后,就已经给模板添加了一个新的语言包了。可以在页面的右上角国际化下拉框中看到新增的下拉选项,点击切换后,即可切换到对应的语言了。
-
-### 路由
-
-#### Tip
-
-- 在该模板中,路由 path 属性视 `/` 开头的路由为根路由
-- 路由会在初始化的时候将所有路由进行提升(全部提升为顶级路由),所以注意第一条 Tip
-- 路由模块会影响菜单的输出显示(菜单模块与路由模块进行拆分开来的)
-- 具体路由支持配置属性看 router/README.md 文件
-
-#### 文件包
-
-- constant 文件放置一些公共东西
-- helper 文件放置 router 的一些 hook 方法
-- modules 页面路由入口(modules 文件中每一个 xxx.ts 文件都会被视为是一个路由模块)
-- utils router 拓展方法
-- ...
-
-##### 新增路由页面
-
-- modules 中添加一个新的模块(log.ts)
-- 配置路由的相关信息
-- views 中创建 log 相关的页面信息
-
-```ts
-// 辅助函数,配合 i18n-ally 插件使用
-import { t } from '@/locales/useI18n'
-
-// 路由配置类型提示
-import type { AppRouteRecordRaw } from '@/router/type'
-
-const log: AppRouteRecordRaw = {
-  path: '/log',
-  name: 'Log',
-  component: () => import('@/views/log/index.vue'),
-  meta: {
-    i18nKey: t('menu.Log'),
-    icon: 'log',
-    order: 3,
-  },
-  children: [
-    {
-      path: 'my-log',
-      name: 'MyLog',
-      component: () => import('@/views/my-log/index.vue'),
-      meta: {
-        i18nKey: t('menu.MyLog'),
-        order: 0,
-      },
-    },
-    {
-      path: 'group-log',
-      name: 'MyLog',
-      component: () => import('@/views/group-log/index.vue'),
-      meta: {
-        i18nKey: t('menu.GroupLog'),
-        order: 0,
-      },
-    },
-  ],
-}
-
-export default log
-```
-
-##### 最后
-
-> 打开浏览器可以看到页面菜单上已经有一个日志菜单。
-
-#### 未完待续。。。后续慢慢更新该手册
diff --git a/README.md b/README.md
index f639b5ef..9d93aeb9 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,7 @@
-# `Ray Template`
+<div align="center"> <a href="https://github.com/XiaoDaiGua-Ray/ray-template"> <img alt="Ray Template" width="200" height="200" src="https://usc1.contabostorage.com/c2e495d7890844d392e8ec0c6e5d77eb:alist/ray/ray.svg?sign=ZklU9Bh5b6oKp1X0LOhGwkx4g5mW4wk_w9Jt5zlZ5EQ=:0"> </a> <br> <br>
+
+<h1>Ray Template</h1>
+</div>
 
 <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
 
@@ -6,9 +9,16 @@
 
 <!-- ALL-CONTRIBUTORS-BADGE:END -->
 
+## 前言
+
+> 该项目模板采用 `vue3.x` `vite4.x` `pinia` `tsx` 进行开发。
+> 使用 `naive ui` 作为组件库。
+> 预设了最佳构建体验的配置与常用搬砖工具。意在提供一个简洁、快速上手的模板。
+> 该模板不支持移动端设备。
+
 ## 感谢
 
-> 感谢 <https://me.yka.moe/> 对于本人的支持。
+> 感谢 [`yun`](https://me.yka.moe/) 对于本人的支持。
 
 ## 预览地址
 
@@ -28,48 +38,39 @@
 
 - [常见问题](https://github.com/XiaoDaiGua-Ray/ray-template/blob/main/COMMONPROBLEM.md)
 
-## 功能
+## 特性
 
-- 主题切换
-- 任意深度页面缓存
-- 系统配置化
-- 锁屏
-- 自动化路由
-- 带有拓展功能的表格
-- 封装 `axios` 自动取消重复请求,暴露拦截器注册器
-- 全局菜单搜索
-- 动态菜单(多级菜单)
-- 主题色切换
-- 错误页
-- 面包屑
-- 标签页
-- 国际化(允许按模块管理语言包)
-- 权限路由
-- 动态切换主题、贴花的 `EChart` 图
-- 最佳构建体验
-- 体积分析
-- 还有一些不值一提的小东西...
+- **最新技术栈**:使用 Vue3.x/vite4.x 等前端前沿技术开发
+- **TypeScript**:应用程序级 JavaScript 的语言
+- **主题**:可配置的主题
+- **国际化**:内置完善的国际化方案
+- **Mock 数据**:内置 Mock 数据方案
+- **权限**:内置完善的动态路由权限生成方案
+- **组件**:二次封装了多个常用的组件
+- **Axios 请求**:二次封装 axios 库
+
+## 准备
+
+- [node](http://nodejs.org/) 和 [git](https://git-scm.com/) -项目开发环境
+- [Vite](https://vitejs.dev/) - 熟悉 vite 特性
+- [Vue3](https://v3.vuejs.org/) - 熟悉 Vue 基础语法
+- [TypeScript](https://www.typescriptlang.org/) - 熟悉 TypeScript 基本语法
+- [Es6+](http://es6.ruanyifeng.com/) - 熟悉 es6 基本语法
+- [Vue-Router-Next](https://next.router.vuejs.org/) - 熟悉 vue-router4.x 基本使用
+- [Naive-UI](https://www.naiveui.com) - ui 基本使用
+- [Mock.js](https://github.com/nuysoft/Mock) - mockjs 基本语法
+- [Pinia](https://pinia.vuejs.org/zh/introduction.html) - 状态管理器 pinia 使用
+- [TSX](https://github.com/vuejs/babel-plugin-jsx/blob/main/packages/babel-plugin-jsx/README-zh_CN.md) - tsx 基本语法
 
 ## 未来
 
 > 根据个人时间空余情况,会不定时对该模板进行更新和迭代。希望将该工具的功能不断补全(虽然现在已经是足够日常开发和使用),将该模板打造为一个更加健全的中后台模板。如果你有好的想法和建议,可以直接联系我或者直接提 `issues` 即可。
 
-## 前言
-
-> 该项目模板采用 `vue3.x` `vite4.x` `pinia` `tsx` 进行开发。
-> 使用 `naive ui` 作为组件库。
-> 预设了最佳构建体验的配置与常用搬砖工具。意在提供一个简洁、快速上手的模板。
-> 该模板不支持移动端设备。
-
 ## 提示
 
 > 项目默认启用严格模式 `eslint`,但是由于 `vite-plugin-eslint` 插件优先级最高,所以如果出现自动导入类型错误提示,请优先解决其他问题。
 > 建议开启 `vscode` 保存自动修复功能。
 
-## 版本说明
-
-> 做了一些大的改动升级,让模板更加好用了一点,默认主题色也做了变更更好看了一点。啰嗦两句,好像也没啥其他的了...
-
 ## 项目安装
 
 ```sh
@@ -150,63 +151,14 @@ yarn report
 npm run report
 ```
 
-## 项目依赖
-
-- [pinia](https://pinia.vuejs.org/) `全局状态管理器`
-- [@vueuse](https://vueuse.org/) `vue3 hooks`
-- [vue-router](https://router.vuejs.org/zh/) `router`
-- [axios](http://axios-js.com/zh-cn/docs/index.html) `ajax request`
-- [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html) `国际化`
-- [scrollreveal.js](https://scrollrevealjs.org/) `滚动加载动画`(暂时移除)
-- [crypto-js](https://github.com/brix/crypto-js) `加密`
-- [vite-svg-loader](https://github.com/jpkleemans/vite-svg-loader) `svg组件化`
-- [vite-plugin-svg-icons](https://github.com/vbenjs/vite-plugin-svg-icons/blob/main/README.zh_CN.md) `svg雪碧图`
-- [echarts5](https://echarts.apache.org/examples/zh/index.html#chart-type-line) `可视化`
-- [lodash-es](https://www.lodashjs.com/) `拓展方法`
-- 还有一些后续补充的,懒得写了。。。自己看项目依赖页面
-
-## 基础组件
-
-- `RayIcon` `svg icon`
-- `RayChart` 基于 `echarts5.x` 封装可视化组件
-- `RayTransitionComponent` 带过渡动画路由组件,效果与 `RouterView` 相同
-- `RayTable` 基于 `Naive UI DataTable` 组件封装,实现了一些小功能
-- `RayCollapseGrid` 基于 `Naive UI NGrid` 组件封装的可折叠操作栏
-
-## 项目结构
-
-```
-- locales: 国际化多语言入口(本项目采用 json 格式)
-
-- assets: 项目静态资源入口
-
-- component: 全局共用组件
-
-- icons: 项目svg图标资源,需要配合 RayIcon 组件使用
-
-- language: 国际化
-
-- layout: 全局页面结构入口
-
-- router: 路由表
-
-- store: 全局状态管理入口
-
-- styles: 全局公共样式入口
-
-- types: 全局 type
-
-- utils: 工具包
-
-- views: 页面入口
-
-- vite-plugin: 插件注册
-```
-
 ## 浏览器支持
 
 > 仅支持现代浏览器,不支持 `IE`
 
+| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt=" Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt=" Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
+| :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
+|                                                                                             not support                                                                                              |                                                                                            last 2 versions                                                                                             |                                                                                                  last 2 versions                                                                                                  |                                                                                                last 2 versions                                                                                                |                                                                                                last 2 versions                                                                                                |
+
 ## 最后,希望大家搬砖愉快
 
 ## 贡献者
@@ -240,3 +192,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
 <!-- ALL-CONTRIBUTORS-LIST:END -->
 
 This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
+
+## License
+
+[MIT © Ray-2020](./LICENSE)
diff --git a/cfg.ts b/cfg.ts
index e83da677..c3367645 100644
--- a/cfg.ts
+++ b/cfg.ts
@@ -98,16 +98,11 @@ const config: AppConfigExport = {
       allow: [],
     },
     proxy: {
-      '/api': {
-        target: 'url',
+      '^/api': {
+        target: 'http://localhost',
         changeOrigin: true,
         rewrite: (path) => path.replace(/^\/api/, ''),
       },
-      '/office': {
-        target: 'https://office.yka.one/',
-        changeOrigin: true,
-        rewrite: (path) => path.replace(/^\/office/, ''),
-      },
     },
   },
   /**
diff --git a/mock/demo/person.mock.ts b/mock/demo/person.mock.ts
new file mode 100644
index 00000000..8cfefbbf
--- /dev/null
+++ b/mock/demo/person.mock.ts
@@ -0,0 +1,51 @@
+import { defineMock } from 'vite-plugin-mock-dev-server'
+import Mock from 'mockjs'
+import { pagination, stringify, response } from '../shared/utils'
+import { array } from '../shared/database'
+
+export const getPersonList = defineMock({
+  url: '/api/list',
+  method: 'GET',
+  delay: 500,
+  response: (req, res) => {
+    const person = () => ({
+      id: Mock.Random.guid(),
+      address: Mock.Random.county(true),
+      email: Mock.Random.email(),
+      name: Mock.Random.cname(),
+      age: Mock.Random.integer(18, 60),
+      createDate: Mock.Random.date(),
+    })
+
+    const {
+      query: { page, pageSize, email },
+    } = req
+    let list = array(100).map(() => person())
+    let length = list.length
+
+    if (!page || !pageSize) {
+      res.end(
+        stringify(
+          response(list, 200, '请求成功', {
+            total: length,
+          }),
+        ),
+      )
+    } else {
+      list = pagination(page, pageSize, list)
+
+      if (email) {
+        list = list.filter((curr) => curr.email.includes(email))
+        length = list.length
+      }
+
+      res.end(
+        stringify(
+          response(list, 200, '请求成功', {
+            total: length,
+          }),
+        ),
+      )
+    }
+  },
+})
diff --git a/mock/shared/database.ts b/mock/shared/database.ts
new file mode 100644
index 00000000..8652e13d
--- /dev/null
+++ b/mock/shared/database.ts
@@ -0,0 +1,14 @@
+/**
+ *
+ * @author Ray <https://github.com/XiaoDaiGua-Ray>
+ *
+ * @date 2023-08-11
+ *
+ * @workspace ray-template
+ *
+ * @remark 今天也是元气满满撸代码的一天
+ */
+
+export function array(length: number) {
+  return new Array(length).fill(0)
+}
diff --git a/mock/shared/utils.ts b/mock/shared/utils.ts
new file mode 100644
index 00000000..bfcb991b
--- /dev/null
+++ b/mock/shared/utils.ts
@@ -0,0 +1,64 @@
+/**
+ *
+ * @author Ray <https://github.com/XiaoDaiGua-Ray>
+ *
+ * @date 2023-08-11
+ *
+ * @workspace ray-template
+ *
+ * @remark 今天也是元气满满撸代码的一天
+ */
+
+/* eslint-disable @typescript-eslint/no-explicit-any */
+
+/**
+ *
+ * @param pageCurrent 当前页码
+ * @param pageSize 分页展示条数
+ * @param array 数据
+ *
+ * mock 分页展示数据
+ */
+export function pagination<T = any>(
+  pageCurrent: number,
+  pageSize: number,
+  array: T[],
+): T[] {
+  const offset = (pageCurrent - 1) * Number(pageSize)
+
+  return offset + Number(pageSize) >= array.length
+    ? array.slice(offset, array.length)
+    : array.slice(offset, offset + Number(pageSize))
+}
+
+/**
+ *
+ * @param value 原始数据
+ *
+ * 格式化数据为 json 格式
+ */
+export function stringify<T = unknown>(value: T) {
+  return JSON.stringify(value)
+}
+
+/**
+ *
+ * @param res 数据
+ * @param code 响应码
+ * @param msg 响应信息
+ */
+export function response<T = any>(
+  res: T,
+  code: number,
+  msg: string,
+  params?: object,
+) {
+  const basic = {
+    code,
+    msg,
+    data: res,
+    ...params,
+  }
+
+  return basic
+}
diff --git a/package.json b/package.json
index dc083b89..a9c15207 100644
--- a/package.json
+++ b/package.json
@@ -32,6 +32,7 @@
     "dayjs": "^1.11.7",
     "echarts": "^5.4.0",
     "lodash-es": "^4.17.21",
+    "mockjs": "1.1.0",
     "naive-ui": "^2.34.4",
     "pinia": "^2.1.4",
     "pinia-plugin-persistedstate": "^3.1.0",
@@ -54,6 +55,7 @@
     "@intlify/unplugin-vue-i18n": "^0.12.1",
     "@types/crypto-js": "^4.1.1",
     "@types/lodash-es": "^4.17.7",
+    "@types/mockjs": "1.0.7",
     "@types/scrollreveal": "^0.0.8",
     "@typescript-eslint/eslint-plugin": "^5.61.0",
     "@typescript-eslint/parser": "^5.61.0",
@@ -89,6 +91,7 @@
     "vite-plugin-eslint": "1.8.1",
     "vite-plugin-imp": "^2.3.1",
     "vite-plugin-inspect": "^0.7.26",
+    "vite-plugin-mock-dev-server": "1.3.0",
     "vite-plugin-svg-icons": "^2.0.1",
     "vite-svg-loader": "^4.0.0",
     "vue-tsc": "^1.8.4"
@@ -108,8 +111,11 @@
     "admin template",
     "中后台模板"
   ],
-  "author": "Ray",
-  "license": "ISC",
+  "license": "MIT",
+  "author": {
+    "name": "Ray",
+    "url": "https://github.com/XiaoDaiGua-Ray"
+  },
   "bugs": {
     "url": "https://github.com/XiaoDaiGua-Ray/xiaodaigua-ray.github.io/issues"
   },
diff --git a/src/axios/api/demo/mock/person.ts b/src/axios/api/demo/mock/person.ts
new file mode 100644
index 00000000..1ffa9053
--- /dev/null
+++ b/src/axios/api/demo/mock/person.ts
@@ -0,0 +1,27 @@
+import { request } from '@/axios/index'
+
+import type { BasicResponse, PaginationResponse } from '@/types/modules/axios'
+
+export interface MockListParams {
+  page: number
+  pageSize: number
+}
+
+export interface Person {
+  name: string
+  id: string
+  age: number
+  address: string
+  createDate: string
+  email: string | null
+}
+
+export const getPersonList = (
+  params: Partial<Pick<MockListParams & Person, 'email' | 'pageSize' | 'page'>>,
+) => {
+  return request<PaginationResponse<Person[]>>({
+    url: '/api/list',
+    method: 'get',
+    params,
+  })
+}
diff --git a/src/axios/api/test.ts b/src/axios/api/demo/test.ts
similarity index 94%
rename from src/axios/api/test.ts
rename to src/axios/api/demo/test.ts
index 8c6578f0..1c766b98 100644
--- a/src/axios/api/test.ts
+++ b/src/axios/api/demo/test.ts
@@ -21,7 +21,7 @@
 
 import { request } from '@/axios/index'
 
-import type { AxiosResponseBody } from '@/types/modules/axios'
+import type { BasicResponse } from '@/types/modules/axios'
 
 interface AxiosTestResponse extends UnknownObjectKey {
   data: UnknownObjectKey[]
diff --git a/src/components/RayCollapseGrid/src/index.tsx b/src/components/RayCollapseGrid/src/index.tsx
index fe626b4e..1f49d0d5 100644
--- a/src/components/RayCollapseGrid/src/index.tsx
+++ b/src/components/RayCollapseGrid/src/index.tsx
@@ -76,10 +76,14 @@ const RayCollapseGrid = defineComponent({
             >
               {this.$slots.default?.()}
               <NGridItem suffix class="ray-collapse-grid__suffix--btn">
-                <NSpace justify="end">
-                  {this.$slots.action?.()}
-                  {this.CollapseIcon()}
-                </NSpace>
+                {{
+                  default: ({ overflow }: { overflow: boolean }) => (
+                    <NSpace justify="end">
+                      {this.$slots.action?.()}
+                      {overflow ? this.CollapseIcon() : ''}
+                    </NSpace>
+                  ),
+                }}
               </NGridItem>
             </NGrid>
           ),
diff --git a/src/components/RayTable/src/index.tsx b/src/components/RayTable/src/index.tsx
index 7948658a..7a2ca908 100644
--- a/src/components/RayTable/src/index.tsx
+++ b/src/components/RayTable/src/index.tsx
@@ -255,6 +255,7 @@ const RayTable = defineComponent({
     }
   },
   render() {
+    console.log(this.action)
     return (
       <NCard
         class="ray-table"
@@ -293,7 +294,7 @@ const RayTable = defineComponent({
               )}
             </>
           ),
-          header: () => this.title,
+          header: () => this.title || <div style="display: none;"></div>,
           'header-extra': () =>
             this.action ? (
               <div class="ray-table-header-extra__space">
diff --git a/src/locales/lang/en-US/menu.json b/src/locales/lang/en-US/menu.json
index bacf1daf..83debfa9 100644
--- a/src/locales/lang/en-US/menu.json
+++ b/src/locales/lang/en-US/menu.json
@@ -17,5 +17,6 @@
   "Office_Spreadsheet": "Spreadsheet",
   "CalculatePrecision": "Precision",
   "Directive": "Directive",
-  "RouterDemo": "Same Level Router Demo"
+  "RouterDemo": "Same Level Router Demo",
+  "Mock": "Mock"
 }
diff --git a/src/locales/lang/zh-CN/menu.json b/src/locales/lang/zh-CN/menu.json
index 84844afb..2730c69e 100644
--- a/src/locales/lang/zh-CN/menu.json
+++ b/src/locales/lang/zh-CN/menu.json
@@ -17,5 +17,6 @@
   "Office_Spreadsheet": "表格",
   "CalculatePrecision": "数字精度",
   "Directive": "指令",
-  "RouterDemo": "页面详情模式"
+  "RouterDemo": "页面详情模式",
+  "Mock": "mock 数据"
 }
diff --git a/src/router/modules/demo/axios.ts b/src/router/modules/demo/axios.ts
index 79bd211b..df0d3ed9 100644
--- a/src/router/modules/demo/axios.ts
+++ b/src/router/modules/demo/axios.ts
@@ -6,7 +6,7 @@ import type { AppRouteRecordRaw } from '@/router/type'
 const axios: AppRouteRecordRaw = {
   path: '/axios',
   name: 'RAxios',
-  component: () => import('@/views/axios/index'),
+  component: () => import('@/views/demo/axios/index'),
   meta: {
     i18nKey: t('menu.Axios'),
     icon: 'axios',
diff --git a/src/router/modules/demo/directive.ts b/src/router/modules/demo/directive.ts
index 45611ad1..2b17d1e6 100644
--- a/src/router/modules/demo/directive.ts
+++ b/src/router/modules/demo/directive.ts
@@ -6,7 +6,7 @@ import type { AppRouteRecordRaw } from '@/router/type'
 const directive: AppRouteRecordRaw = {
   path: '/directive',
   name: 'RDirective',
-  component: () => import('@/views/directive/index'),
+  component: () => import('@/views/demo/directive/index'),
   meta: {
     i18nKey: t('menu.Directive'),
     icon: 'other',
diff --git a/src/router/modules/demo/doc.ts b/src/router/modules/demo/doc.ts
index 71e44238..4ace6670 100644
--- a/src/router/modules/demo/doc.ts
+++ b/src/router/modules/demo/doc.ts
@@ -16,7 +16,7 @@ const doc: AppRouteRecordRaw = {
     {
       path: 'doc-inside',
       name: 'RDocInside',
-      component: () => import('@/views/doc/index'),
+      component: () => import('@/views/demo/doc/index'),
       meta: {
         i18nKey: t('menu.DocLocalInside'),
       },
diff --git a/src/router/modules/demo/echart.ts b/src/router/modules/demo/echart.ts
index c287115e..6f7904a8 100644
--- a/src/router/modules/demo/echart.ts
+++ b/src/router/modules/demo/echart.ts
@@ -6,7 +6,7 @@ import type { AppRouteRecordRaw } from '@/router/type'
 const echart: AppRouteRecordRaw = {
   path: '/echart',
   name: 'REchart',
-  component: () => import('@/views/echart/index'),
+  component: () => import('@/views/demo/echart/index'),
   meta: {
     i18nKey: t('menu.Echart'),
     icon: 'echart',
diff --git a/src/router/modules/demo/iframe.ts b/src/router/modules/demo/iframe.ts
index 6fdf5064..37c150cc 100644
--- a/src/router/modules/demo/iframe.ts
+++ b/src/router/modules/demo/iframe.ts
@@ -5,7 +5,7 @@ import type { AppRouteRecordRaw } from '@/router/type'
 const iframe: AppRouteRecordRaw = {
   path: '/iframe',
   name: 'IframeDemo',
-  component: () => import('@/views/iframe/index'),
+  component: () => import('@/views/demo/iframe/index'),
   meta: {
     icon: 'other',
     order: 2,
diff --git a/src/router/modules/demo/mock.ts b/src/router/modules/demo/mock.ts
new file mode 100644
index 00000000..af4d5762
--- /dev/null
+++ b/src/router/modules/demo/mock.ts
@@ -0,0 +1,18 @@
+import { t } from '@/locales/useI18n'
+import { LAYOUT } from '@/router/constant/index'
+
+import type { AppRouteRecordRaw } from '@/router/type'
+
+const mockDemo: AppRouteRecordRaw = {
+  path: '/mock-demo',
+  name: 'MockDemo',
+  component: () => import('@/views/demo/mock-demo/index'),
+  meta: {
+    i18nKey: t('menu.Mock'),
+    icon: 'other',
+    order: 3,
+    keepAlive: true,
+  },
+}
+
+export default mockDemo
diff --git a/src/router/modules/demo/multi-menu.ts b/src/router/modules/demo/multi-menu.ts
index ab6149e7..c942d54f 100644
--- a/src/router/modules/demo/multi-menu.ts
+++ b/src/router/modules/demo/multi-menu.ts
@@ -16,7 +16,7 @@ const multiMenu: AppRouteRecordRaw = {
     {
       path: 'multi-menu-one',
       name: 'MultiMenuOne',
-      component: () => import('@/views/multi/views/multi-menu-one/index'),
+      component: () => import('@/views/demo/multi/views/multi-menu-one/index'),
       meta: {
         noLocalTitle: '多级菜单-1',
         keepAlive: true,
@@ -35,7 +35,7 @@ const multiMenu: AppRouteRecordRaw = {
           name: 'SubMenuOther',
           component: () =>
             import(
-              '@/views/multi/views/multi-menu-two/views/sub-menu-other/index'
+              '@/views/demo/multi/views/multi-menu-two/views/sub-menu-other/index'
             ),
           meta: {
             noLocalTitle: '多级菜单-2-1',
@@ -56,7 +56,7 @@ const multiMenu: AppRouteRecordRaw = {
               name: 'MultiMenuTwoOne',
               component: () =>
                 import(
-                  '@/views/multi/views/multi-menu-two/views/sub-menu/views/multi-menu-two-one/index'
+                  '@/views/demo/multi/views/multi-menu-two/views/sub-menu/views/multi-menu-two-one/index'
                 ),
               meta: {
                 noLocalTitle: '多级菜单-2-2-1',
diff --git a/src/router/modules/demo/office.ts b/src/router/modules/demo/office.ts
index 55c2466f..cec96641 100644
--- a/src/router/modules/demo/office.ts
+++ b/src/router/modules/demo/office.ts
@@ -6,7 +6,7 @@ import type { AppRouteRecordRaw } from '@/router/type'
 const office: AppRouteRecordRaw = {
   path: '/office',
   name: 'ROffice',
-  component: () => import('@/views/office/index'),
+  component: () => import('@/views/demo/office/index'),
   meta: {
     i18nKey: t('menu.Office'),
     icon: 'office',
@@ -16,7 +16,7 @@ const office: AppRouteRecordRaw = {
     {
       path: 'document',
       name: 'Document',
-      component: () => import('@/views/office/views/document/index'),
+      component: () => import('@/views/demo/office/views/document/index'),
       meta: {
         i18nKey: 'Office_Document',
       },
@@ -24,7 +24,7 @@ const office: AppRouteRecordRaw = {
     {
       path: 'presentation',
       name: 'Presentation',
-      component: () => import('@/views/office/views/presentation/index'),
+      component: () => import('@/views/demo/office/views/presentation/index'),
       meta: {
         i18nKey: 'Office_Presentation',
       },
@@ -32,7 +32,7 @@ const office: AppRouteRecordRaw = {
     {
       path: 'spreadsheet',
       name: 'Spreadsheet',
-      component: () => import('@/views/office/views/spreadsheet/index'),
+      component: () => import('@/views/demo/office/views/spreadsheet/index'),
       meta: {
         i18nKey: 'Office_Spreadsheet',
       },
diff --git a/src/router/modules/demo/precision.ts b/src/router/modules/demo/precision.ts
index 0dba74df..02857878 100644
--- a/src/router/modules/demo/precision.ts
+++ b/src/router/modules/demo/precision.ts
@@ -6,7 +6,7 @@ import type { AppRouteRecordRaw } from '@/router/type'
 const precision: AppRouteRecordRaw = {
   path: '/precision',
   name: 'CalculatePrecision',
-  component: () => import('@/views/precision/index'),
+  component: () => import('@/views/demo/precision/index'),
   meta: {
     i18nKey: t('menu.CalculatePrecision'),
     icon: 'other',
diff --git a/src/router/modules/demo/rely.ts b/src/router/modules/demo/rely.ts
index 1cebef37..ea8778b8 100644
--- a/src/router/modules/demo/rely.ts
+++ b/src/router/modules/demo/rely.ts
@@ -16,7 +16,7 @@ const rely: AppRouteRecordRaw = {
     {
       path: 'rely-about',
       name: 'RelyAbout',
-      component: () => import('@/views/rely/views/rely-about/index'),
+      component: () => import('@/views/demo/rely/views/rely-about/index'),
       meta: {
         i18nKey: 'RelyAbout',
       },
diff --git a/src/router/modules/demo/router-demo.ts b/src/router/modules/demo/router-demo.ts
index 192078c1..29f267cf 100644
--- a/src/router/modules/demo/router-demo.ts
+++ b/src/router/modules/demo/router-demo.ts
@@ -16,7 +16,8 @@ const routerDemo: AppRouteRecordRaw = {
     {
       path: 'router-demo-home',
       name: 'RouterDemoHome',
-      component: () => import('@/views/router-demo/router-demo-home/index'),
+      component: () =>
+        import('@/views/demo/router-demo/router-demo-home/index'),
       meta: {
         noLocalTitle: '人员信息(平级模式)',
       },
@@ -24,7 +25,8 @@ const routerDemo: AppRouteRecordRaw = {
     {
       path: 'router-demo-detail',
       name: 'RouterDemoDetail',
-      component: () => import('@/views/router-demo/router-demo-detail/index'),
+      component: () =>
+        import('@/views/demo/router-demo/router-demo-detail/index'),
       meta: {
         noLocalTitle: '信息详情',
         hidden: true,
diff --git a/src/router/modules/demo/scroll-reveal.ts b/src/router/modules/demo/scroll-reveal.ts
index ca53f267..993ddc18 100644
--- a/src/router/modules/demo/scroll-reveal.ts
+++ b/src/router/modules/demo/scroll-reveal.ts
@@ -12,7 +12,7 @@ import type { AppRouteRecordRaw } from '@/router/type'
 const scrollReveal: AppRouteRecordRaw = {
   path: '/scroll-reveal',
   name: 'ScrollReveal',
-  component: () => import('@/views/scroll-reveal/index'),
+  component: () => import('@/views/demo/scroll-reveal/index'),
   meta: {
     i18nKey: t('menu.scrollReveal'),
     icon: 'scroll_reveal',
diff --git a/src/router/modules/demo/table.ts b/src/router/modules/demo/table.ts
index a25e84b2..6ef6e2c4 100644
--- a/src/router/modules/demo/table.ts
+++ b/src/router/modules/demo/table.ts
@@ -6,7 +6,7 @@ import type { AppRouteRecordRaw } from '@/router/type'
 const table: AppRouteRecordRaw = {
   path: '/table',
   name: 'TableView',
-  component: () => import('@/views/table/index'),
+  component: () => import('@/views/demo/table/index'),
   meta: {
     i18nKey: t('menu.Table'),
     icon: 'other',
diff --git a/src/types/modules/axios.ts b/src/types/modules/axios.ts
index ad25f258..239928a6 100644
--- a/src/types/modules/axios.ts
+++ b/src/types/modules/axios.ts
@@ -1,5 +1,10 @@
-export interface AxiosResponseBody<T = unknown> {
+/* eslint-disable @typescript-eslint/no-explicit-any */
+export interface BasicResponse<T> {
   data: T
-  message: string
+  msg: string
   code: number
 }
+
+export interface PaginationResponse<T> extends BasicResponse<T> {
+  total: number
+}
diff --git a/src/views/axios/index.scss b/src/views/demo/axios/index.scss
similarity index 100%
rename from src/views/axios/index.scss
rename to src/views/demo/axios/index.scss
diff --git a/src/views/axios/index.tsx b/src/views/demo/axios/index.tsx
similarity index 98%
rename from src/views/axios/index.tsx
rename to src/views/demo/axios/index.tsx
index c266d3f3..555920b6 100644
--- a/src/views/axios/index.tsx
+++ b/src/views/demo/axios/index.tsx
@@ -1,7 +1,7 @@
 import './index.scss'
 
 import { NCard, NLayout, NSpace, NInput, NButton } from 'naive-ui'
-import { getWeather, getTypicode } from '@use-api/test'
+import { getWeather, getTypicode } from '@/axios/api/demo/test'
 import { useRequest, useHookPlusRequest } from '@/axios/index'
 
 const Axios = defineComponent({
diff --git a/src/views/directive/index.tsx b/src/views/demo/directive/index.tsx
similarity index 100%
rename from src/views/directive/index.tsx
rename to src/views/demo/directive/index.tsx
diff --git a/src/views/doc/index.tsx b/src/views/demo/doc/index.tsx
similarity index 100%
rename from src/views/doc/index.tsx
rename to src/views/demo/doc/index.tsx
diff --git a/src/views/echart/index.scss b/src/views/demo/echart/index.scss
similarity index 100%
rename from src/views/echart/index.scss
rename to src/views/demo/echart/index.scss
diff --git a/src/views/echart/index.tsx b/src/views/demo/echart/index.tsx
similarity index 100%
rename from src/views/echart/index.tsx
rename to src/views/demo/echart/index.tsx
diff --git a/src/views/iframe/index.tsx b/src/views/demo/iframe/index.tsx
similarity index 100%
rename from src/views/iframe/index.tsx
rename to src/views/demo/iframe/index.tsx
diff --git a/src/views/demo/mock-demo/index.tsx b/src/views/demo/mock-demo/index.tsx
new file mode 100644
index 00000000..ad15c57f
--- /dev/null
+++ b/src/views/demo/mock-demo/index.tsx
@@ -0,0 +1,173 @@
+/**
+ *
+ * @author Ray <https://github.com/XiaoDaiGua-Ray>
+ *
+ * @date 2023-08-11
+ *
+ * @workspace ray-template
+ *
+ * @remark 今天也是元气满满撸代码的一天
+ */
+
+import { NSpace, NCard, NButton, NFormItemGi, NInput, NForm } from 'naive-ui'
+import RayTable from '@/components/RayTable/index'
+import RayCollapseGrid from '@/components/RayCollapseGrid/index'
+
+import { useHookPlusRequest } from '@/axios/index'
+import { getPersonList } from '@/axios/api/demo/mock/person'
+
+import type { Person } from '@/axios/api/demo/mock/person'
+
+const MockDemo = defineComponent({
+  name: 'MockDemo',
+  setup() {
+    const paginationRef = reactive({
+      page: 1,
+      pageSize: 10,
+      itemCount: 0,
+      pageSizes: [10, 20, 30, 40, 50],
+      showSizePicker: true,
+      onUpdatePage: (page: number) => {
+        paginationRef.page = page
+
+        getPerson()
+      },
+      onUpdatePageSize: (pageSize: number) => {
+        paginationRef.pageSize = pageSize
+        paginationRef.page = 1
+
+        getPerson()
+      },
+    })
+    const {
+      data: personData,
+      loading: personLoading,
+      run: personFetchRun,
+    } = useHookPlusRequest(getPersonList, {
+      manual: true,
+    })
+    const columns = [
+      {
+        title: 'id',
+        key: 'id',
+      },
+      {
+        title: '邮箱',
+        key: 'email',
+      },
+      {
+        title: '地址',
+        key: 'address',
+      },
+      {
+        title: '姓名',
+        key: 'name',
+      },
+      {
+        title: '年龄',
+        key: 'age',
+      },
+      {
+        title: '创建时间',
+        key: 'createDate',
+      },
+      {
+        title: '操作',
+        key: 'action',
+        render: (row: Person) => {
+          return (
+            <NSpace align="center">
+              <NButton type="primary" text>
+                查看
+              </NButton>
+              <NButton type="primary" text>
+                编辑
+              </NButton>
+              <NButton type="error" text>
+                删除
+              </NButton>
+            </NSpace>
+          )
+        },
+      },
+    ]
+    const condition = reactive({
+      email: null,
+    })
+
+    const getPerson = () => {
+      const { pageSize, page } = paginationRef
+      const { email } = condition
+
+      personFetchRun({
+        page,
+        pageSize,
+        email,
+      })
+    }
+
+    watchEffect(() => {
+      if (personData.value) {
+        paginationRef.itemCount = personData.value.total
+      }
+    })
+
+    onBeforeMount(() => {
+      getPerson()
+    })
+
+    return {
+      personData,
+      personLoading,
+      paginationRef,
+      columns,
+      ...toRefs(condition),
+      getPerson,
+    }
+  },
+  render() {
+    return (
+      <NSpace vertical wrapItem={false}>
+        <NCard title="Mock 数据">
+          <h2>展示 mock 数据的使用。</h2>
+        </NCard>
+        <NCard title="提示">
+          <h2>
+            RayTable
+            组件有一个比较值得注意的地方就是,该组件会自动的按照数据量计算分页条数。所以你在异步获取数据的时候,一定要手动设置
+            remote 属性为 true,并且设置 itemCount 或者 pageCount。
+          </h2>
+        </NCard>
+        <NForm labelPlacement="left">
+          <RayCollapseGrid bordered={false} cols={3}>
+            {{
+              default: () => (
+                <>
+                  <NFormItemGi label="邮箱">
+                    <NInput v-model:value={this.email} clearable />
+                  </NFormItemGi>
+                  <NFormItemGi>
+                    <NButton type="primary" onClick={this.getPerson.bind(this)}>
+                      搜索
+                    </NButton>
+                  </NFormItemGi>
+                </>
+              ),
+            }}
+          </RayCollapseGrid>
+        </NForm>
+        <RayTable
+          title="分页表格"
+          data={this.personData?.data}
+          loading={this.personLoading}
+          columns={this.columns}
+          pagination={this.paginationRef}
+          remote
+          action
+        />
+      </NSpace>
+    )
+  },
+})
+
+export default MockDemo
diff --git a/src/views/multi/views/multi-menu-one/index.tsx b/src/views/demo/multi/views/multi-menu-one/index.tsx
similarity index 100%
rename from src/views/multi/views/multi-menu-one/index.tsx
rename to src/views/demo/multi/views/multi-menu-one/index.tsx
diff --git a/src/views/multi/views/multi-menu-two/views/sub-menu-other/index.tsx b/src/views/demo/multi/views/multi-menu-two/views/sub-menu-other/index.tsx
similarity index 100%
rename from src/views/multi/views/multi-menu-two/views/sub-menu-other/index.tsx
rename to src/views/demo/multi/views/multi-menu-two/views/sub-menu-other/index.tsx
diff --git a/src/views/multi/views/multi-menu-two/views/sub-menu/views/multi-menu-two-one/index.tsx b/src/views/demo/multi/views/multi-menu-two/views/sub-menu/views/multi-menu-two-one/index.tsx
similarity index 100%
rename from src/views/multi/views/multi-menu-two/views/sub-menu/views/multi-menu-two-one/index.tsx
rename to src/views/demo/multi/views/multi-menu-two/views/sub-menu/views/multi-menu-two-one/index.tsx
diff --git a/src/views/office/index.tsx b/src/views/demo/office/index.tsx
similarity index 100%
rename from src/views/office/index.tsx
rename to src/views/demo/office/index.tsx
diff --git a/src/views/office/views/document/index.tsx b/src/views/demo/office/views/document/index.tsx
similarity index 100%
rename from src/views/office/views/document/index.tsx
rename to src/views/demo/office/views/document/index.tsx
diff --git a/src/views/office/views/presentation/index.tsx b/src/views/demo/office/views/presentation/index.tsx
similarity index 100%
rename from src/views/office/views/presentation/index.tsx
rename to src/views/demo/office/views/presentation/index.tsx
diff --git a/src/views/office/views/spreadsheet/index.tsx b/src/views/demo/office/views/spreadsheet/index.tsx
similarity index 100%
rename from src/views/office/views/spreadsheet/index.tsx
rename to src/views/demo/office/views/spreadsheet/index.tsx
diff --git a/src/views/precision/index.tsx b/src/views/demo/precision/index.tsx
similarity index 100%
rename from src/views/precision/index.tsx
rename to src/views/demo/precision/index.tsx
diff --git a/src/views/rely/views/rely-about/index.scss b/src/views/demo/rely/views/rely-about/index.scss
similarity index 100%
rename from src/views/rely/views/rely-about/index.scss
rename to src/views/demo/rely/views/rely-about/index.scss
diff --git a/src/views/rely/views/rely-about/index.tsx b/src/views/demo/rely/views/rely-about/index.tsx
similarity index 100%
rename from src/views/rely/views/rely-about/index.tsx
rename to src/views/demo/rely/views/rely-about/index.tsx
diff --git a/src/views/router-demo/router-demo-detail/index.tsx b/src/views/demo/router-demo/router-demo-detail/index.tsx
similarity index 100%
rename from src/views/router-demo/router-demo-detail/index.tsx
rename to src/views/demo/router-demo/router-demo-detail/index.tsx
diff --git a/src/views/router-demo/router-demo-home/index.tsx b/src/views/demo/router-demo/router-demo-home/index.tsx
similarity index 100%
rename from src/views/router-demo/router-demo-home/index.tsx
rename to src/views/demo/router-demo/router-demo-home/index.tsx
diff --git a/src/views/scroll-reveal/index.scss b/src/views/demo/scroll-reveal/index.scss
similarity index 100%
rename from src/views/scroll-reveal/index.scss
rename to src/views/demo/scroll-reveal/index.scss
diff --git a/src/views/scroll-reveal/index.tsx b/src/views/demo/scroll-reveal/index.tsx
similarity index 100%
rename from src/views/scroll-reveal/index.tsx
rename to src/views/demo/scroll-reveal/index.tsx
diff --git a/src/views/table/index.tsx b/src/views/demo/table/index.tsx
similarity index 100%
rename from src/views/table/index.tsx
rename to src/views/demo/table/index.tsx
diff --git a/vite.config.ts b/vite.config.ts
index 7f764980..710526a6 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -16,6 +16,7 @@ import viteCompression from 'vite-plugin-compression' // 压缩打包
 import { ViteEjsPlugin as viteEjsPlugin } from 'vite-plugin-ejs'
 import viteAutoImport from 'unplugin-auto-import/vite'
 import viteEslint from 'vite-plugin-eslint'
+import mockDevServerPlugin from 'vite-plugin-mock-dev-server'
 
 import { NaiveUiResolver } from 'unplugin-vue-components/resolvers' // 模板自动导入组件并且按需打包
 import { VueHooksPlusResolver } from '@vue-hooks-plus/resolvers'
@@ -156,6 +157,20 @@ export default defineConfig(async ({ mode }) => {
         appPrimaryColor,
       }),
       viteInspect(), // 仅适用于开发模式(检查 `Vite` 插件的中间状态)
+      mockDevServerPlugin({
+        include: ['mock/**/*.mock.ts'],
+        exclude: [
+          '**/node_modules/**',
+          '**/test/**',
+          '**/cypress/**',
+          'src/**',
+          '**/.vscode/**',
+          '**/.git/**',
+          '**/dist/**',
+          'mock/shared/**',
+        ],
+        reload: true,
+      }),
     ],
     optimizeDeps: {
       include: ['vue', 'vue-router', 'pinia', 'vue-i18n', '@vueuse/core'],

From a9c7e6589fc08187c034e59a69d851ec64e61432 Mon Sep 17 00:00:00 2001
From: XiaoDaiGua-Ray <443547225@qq.com>
Date: Fri, 11 Aug 2023 22:48:39 +0800
Subject: [PATCH 2/2] =?UTF-8?q?4.1.7=E4=B8=80=E4=BA=9B=E5=B0=8F=E7=BB=86?=
 =?UTF-8?q?=E8=8A=82=E6=9B=B4=E6=96=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/views/demo/mock-demo/index.tsx | 29 +++++++++++++++++++++++++----
 vite.config.ts                     |  1 +
 2 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/src/views/demo/mock-demo/index.tsx b/src/views/demo/mock-demo/index.tsx
index ad15c57f..17bf88a2 100644
--- a/src/views/demo/mock-demo/index.tsx
+++ b/src/views/demo/mock-demo/index.tsx
@@ -77,13 +77,31 @@ const MockDemo = defineComponent({
         render: (row: Person) => {
           return (
             <NSpace align="center">
-              <NButton type="primary" text>
+              <NButton
+                type="primary"
+                text
+                onClick={() => {
+                  window.$message.info('查看')
+                }}
+              >
                 查看
               </NButton>
-              <NButton type="primary" text>
+              <NButton
+                type="primary"
+                text
+                onClick={() => {
+                  window.$message.warning('编辑')
+                }}
+              >
                 编辑
               </NButton>
-              <NButton type="error" text>
+              <NButton
+                type="error"
+                text
+                onClick={() => {
+                  window.$message.error('删除')
+                }}
+              >
                 删除
               </NButton>
             </NSpace>
@@ -129,7 +147,10 @@ const MockDemo = defineComponent({
     return (
       <NSpace vertical wrapItem={false}>
         <NCard title="Mock 数据">
-          <h2>展示 mock 数据的使用。</h2>
+          <h2>
+            mock
+            数据使用。但是,并没有启用生产环境的部署,所以生产环境结果为空。
+          </h2>
         </NCard>
         <NCard title="提示">
           <h2>
diff --git a/vite.config.ts b/vite.config.ts
index 710526a6..543a39fa 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -170,6 +170,7 @@ export default defineConfig(async ({ mode }) => {
           'mock/shared/**',
         ],
         reload: true,
+        build: true,
       }),
     ],
     optimizeDeps: {