diff --git a/docs/menu-permission-migration.md b/docs/menu-permission-migration.md
new file mode 100644
index 00000000..b44b2b8d
--- /dev/null
+++ b/docs/menu-permission-migration.md
@@ -0,0 +1,601 @@
+# Menu 权限迁移方案
+
+> 参照项目:`D:\code\company\SCTMES_MES_V5\vue-app`(以下简称"源项目")
+
+---
+
+## 一、源项目(SCTMES)Menu 权限架构
+
+### 1.1 后端接口
+
+```
+GET system_settings/menu_configuration/menu/all
+```
+
+API 文件:[src/api/system_settings/menu_configuration/menu.js](file:///D:\code\company\SCTMES_MES_V5\vue-app\src\api\system_settings\menu_configuration\menu.js)
+
+返回当前用户可见的**扁平数组**,字段如下:
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `menu_id` | number | 主键,用于构建父子关系 |
+| `parent_id` | number | 父节点 ID,`0` 表示顶栏根节点 |
+| `url` | string | 前端路由路径,如 `/system_settings/user_management/user` |
+| `name` | string | 菜单显示名称 |
+| `icon` | string | 图标名(FontAwesome) |
+| `is_navi` | number | 是否作为导航菜单展示(1=是) |
+| `status` | number | 启用/禁用 |
+| `type` | string | 菜单类型 |
+| `params` | string | 额外参数 |
+| `sort` | number | 排序 |
+| `remark` | string | 备注 |
+
+### 1.2 菜单数据全链路
+
+```
+登录成功 → account.login() → dispatch('load')
+ │
+ ▼
+ account.load()
+ │
+ ...加载 user/theme/transition/page/menu/size/color...
+ │
+ ▼
+ dispatch('d2admin/menu/sourceDataLoad')
+ │
+ ┌────────────┴────────────┐
+ │ │
+ localStorage localStorage 为空
+ 有缓存 且有 token
+ │ │
+ ▼ ▼
+ 直接读缓存 GET /menu/all 后端接口
+ │
+ ▼
+ 写入 localStorage 缓存
+ │
+ └────────────┬────────────┘
+ │
+ ▼
+ menu.install(this, sourceData)
+```
+
+**Store 文件**:[src/store/modules/d2admin/modules/menu.js](file:///D:\code\company\SCTMES_MES_V5\vue-app\src\store\modules\d2admin\modules\menu.js)
+
+```js
+state: {
+ header: [],
+ aside: [],
+ asideCollapse: setting.menu.asideCollapse,
+ asideTransition: setting.menu.asideTransition,
+ authKey: {}, // ← 权限字典 { '/path': '菜单名', ... }
+ sourceData: [] // ← 菜单源数据(来自后端或本地缓存)
+}
+```
+
+### 1.3 `sourceDataLoad` action 核心逻辑
+
+```js
+async sourceDataLoad({ state, dispatch }) {
+ // 1. 优先从 localStorage 读取缓存
+ state.sourceData = await dispatch('d2admin/db/get', {
+ dbName: 'database',
+ path: '$menu.sourceData',
+ defaultValue: [],
+ user: true
+ }, { root: true })
+
+ // 2. 缓存为空且已登录 → 调后端获取
+ if (!state.sourceData.length && util.cookies.get('token')) {
+ const res = await getMenuAll(null)
+ state.sourceData = res.data || []
+ await dispatch('d2admin/db/set', {
+ dbName: 'database',
+ path: '$menu.sourceData',
+ value: state.sourceData,
+ user: true
+ }, { root: true })
+ }
+
+ // 3. 处理为 header/aside/authKey
+ menu.install(this, state.sourceData)
+}
+```
+
+### 1.4 `menu.install()` — 扁平数据 → 菜单树 + 权限字典
+
+**文件**:[src/menu/index.js](file:///D:\code\company\SCTMES_MES_V5\vue-app\src\menu\index.js)
+
+```js
+export default {
+ install(vm, source) {
+ // 1. 构建权限字典 { '/path': '菜单名' }
+ vm.commit('d2admin/menu/headerAuth', source)
+
+ // 2. 扁平数据转为 {header: [], aside: []} 树结构
+ const { header, aside } = getMenuData(source)
+
+ // 3. 写入 store → 触发菜单渲染
+ vm.commit('d2admin/menu/headerSet', header)
+ vm.commit('d2admin/menu/asideSet', aside)
+ }
+}
+```
+
+`getMenuData()` 核心流程:
+
+```
+source (扁平数组)
+ │
+ ├── 过滤: is_navi !== 1 的跳过
+ │
+ ├── parent_id === 0 → 推入 header[]
+ │
+ └── 全部节点 → 推入 aside[]
+ │
+ ▼
+ util.formatDataToTree(aside) { menu_id ↔ parent_id }
+ │
+ ▼
+ 树形结构 aside
+```
+
+**`headerAuth` mutation**:遍历 `source`,将每个有 `url` 的节点写入 `authKey[url] = name`:
+
+```js
+headerAuth(state, source) {
+ let auth = {}
+ source.forEach(value => {
+ if (value.url) {
+ auth[value.url] = value.name
+ }
+ })
+ state.authKey = auth
+}
+```
+
+### 1.5 权限控制系统
+
+**`$permission()` 方法** — 定义在 [src/plugin/d2admin/index.js](file:///D:\code\company\SCTMES_MES_V5\vue-app\src\plugin\d2admin\index.js#L50):
+
+```js
+Vue.prototype.$permission = (value, type = 'menu') => {
+ let path = ''
+ const auth = store.state.d2admin.menu.authKey
+
+ switch (type) {
+ case 'menu': // 直接用 URL 查
+ path = value
+ break
+ case 'router': // 路由 name → URL
+ path = value.name.replace(/-/g, '/')
+ path.slice(0, 1) !== '/' && (path = '/' + path)
+ break
+ }
+
+ return !!(path && Object.prototype.hasOwnProperty.call(auth, path))
+}
+```
+
+**`v-permission` 指令** — 定义在 [src/main.js](file:///D:\code\company\SCTMES_MES_V5\vue-app\src\main.js#L72-L78):
+
+```js
+Vue.directive('permission', {
+ bind: (el, binding) => {
+ if (!Vue.prototype.$permission(binding.value)) {
+ el.parentNode ? el.parentNode.removeChild(el) : el.style.display = 'none'
+ }
+ }
+})
+```
+
+使用示例:
+```html
+新增用户
+```
+
+### 1.6 菜单导航权限过滤
+
+**Menu Mixin** — [src/layout/header-aside/components/mixin/menu.js](file:///D:\code\company\SCTMES_MES_V5\vue-app\src\layout\header-aside\components\mixin\menu.js):
+
+点击顶栏一级菜单时,不直接跳转,而是查找第一个有权限的子路由:
+
+```js
+getRouterAuthPath(index, indexPath) {
+ // 子路由直接访问
+ if (index === '/index' || !indexPath || indexPath.length > 1) {
+ this.$router.push({ path: index })
+ return
+ }
+
+ // 查找一级路由下第一个有权限的子路由
+ let router = null
+ for (const value of frameInRoutes) {
+ if (value.path === index) {
+ router = value.children
+ break
+ }
+ }
+
+ if (!router) {
+ this.$router.push({ path: index })
+ return
+ }
+
+ for (const value of router) {
+ const newPath = index + '/' + value.path
+ if (this.$permission(newPath)) {
+ this.$router.push({ path: newPath })
+ break
+ }
+ }
+}
+```
+
+### 1.7 路由 — 全部静态注册
+
+路由在 [src/router/routes.js](file:///D:\code\company\SCTMES_MES_V5\vue-app\src\router\routes.js) 中**全部静态定义**,不使用 `addRoute`。
+
+路由守卫([src/router/index.js](file:///D:\code\company\SCTMES_MES_V5\vue-app\src\router\index.js))仅判断 token 是否存在,不校验具体路由权限。权限控制在**菜单渲染**和**菜单点击时**完成。
+
+### 1.8 main.js 启动流程
+
+[src/main.js](file:///D:\code\company\SCTMES_MES_V5\vue-app\src\main.js#L108-L137)
+
+```js
+created() {
+ // 仅初始化页面池,不再设置静态菜单
+ this.$store.commit('d2admin/page/init', frameInRoutes)
+ // 静态菜单设置已注释:
+ // this.$store.commit('d2admin/menu/headerSet', menuHeader)
+ // this.$store.commit('d2admin/search/init', menuHeader)
+},
+mounted() {
+ this.$store.dispatch('d2admin/account/load') // → sourceDataLoad → 获取菜单
+},
+watch: {
+ // $route.matched 切换侧边栏的 watch 已注释
+}
+```
+
+---
+
+## 二、mes-ui 当前现状 vs 目标
+
+| 模块 | mes-ui 现状 | 源项目(目标) |
+|------|-----------|---------------|
+| 菜单数据来源 | `src/menu/modules/*.js` 静态硬编码 | 后端 `GET /menu/all` + localStorage 缓存 |
+| `sourceDataLoad` | 仅 localStorage 读取,不参与菜单构建 | localStorage 兜底 + 调后端 → `menu.install()` |
+| 权限字典 | 无 | `authKey: { '/path': 'name' }` |
+| 菜单树构建 | 编译时 `supplementPath()` | 运行时 `getMenuData()` + `formatDataToTree()` |
+| 权限检查 | 无 | `$permission()` + `v-permission` 指令 |
+| 菜单点击 | 直接 `$router.push` | `getRouterAuthPath()` 查找首个有权限子路由 |
+| main.js 菜单初始化 | `created` 中 `headerSet(menuHeader)` | 注释掉静态菜单,由 `mounted` 中的 `load()` 触发 |
+| 路由注册 | 全部静态 | 全部静态(一致) |
+| 路由守卫 | 仅 token 检查 | 仅 token 检查(一致) |
+
+---
+
+## 三、迁移计划
+
+### 阶段 1️⃣:约定后端接口格式
+
+后端接口:`GET /api/menu/all`(或复用源项目的 `system_settings/menu_configuration/menu/all`)
+
+返回格式(扁平数组):
+
+```json
+{
+ "code": 0,
+ "data": [
+ { "menu_id": 1, "parent_id": 0, "url": "/index", "name": "首页", "icon": "home", "is_navi": 1 },
+ { "menu_id": 2, "parent_id": 0, "url": "/production_master_data", "name": "生产主数据", "icon": "cogs", "is_navi": 1 },
+ { "menu_id": 3, "parent_id": 2, "url": "/production_master_data/factory_model/factory_area", "name": "工厂区域", "icon": "map-marker", "is_navi": 1 }
+ ]
+}
+```
+
+### 阶段 2️⃣:新增/改造 API 层
+
+**新增** `src/api/menu.js`(参照源项目 [menu.js](file:///D:\code\company\SCTMES_MES_V5\vue-app\src\api\system_settings\menu_configuration\menu.js)):
+
+```js
+import { request } from '@/api/_service'
+
+export function getMenuAll(data) {
+ return request({
+ url: 'menu/all',
+ method: 'get',
+ params: {
+ method: 'system_settings_menu_configuration_menu_all',
+ platform: 'background',
+ ...data
+ }
+ })
+}
+```
+
+### 阶段 3️⃣:改造 `menu.js` Store
+
+**改造** [src/store/modules/d2admin/modules/menu.js](file:///d:\code\mes\mes-ui\src\store\modules\d2admin\modules\menu.js)
+
+| 改动 | 内容 |
+|------|------|
+| state | 新增 `authKey: {}` |
+| `sourceDataLoad` action | 改为:localStorage 兜底 → 调后端 → `menu.install()` |
+| mutations | 新增 `headerAuth(state, source)` → 构建 `authKey` 字典 |
+
+```js
+// 关键变更 — sourceDataLoad:
+async sourceDataLoad({ state, commit, dispatch }) {
+ // 1. 先读 localStorage 缓存
+ state.sourceData = await dispatch('d2admin/db/get', {
+ dbName: 'database',
+ path: '$menu.sourceData',
+ defaultValue: [],
+ user: true
+ }, { root: true })
+
+ // 2. 缓存为空且已登录 → 调后端
+ if (!state.sourceData.length && util.cookies.get('token')) {
+ const res = await getMenuAll()
+ state.sourceData = res || []
+ await dispatch('d2admin/db/set', {
+ dbName: 'database',
+ path: '$menu.sourceData',
+ value: state.sourceData,
+ user: true
+ }, { root: true })
+ }
+
+ // 3. 构建菜单树 + 权限字典
+ menuUtil.install(this, state.sourceData)
+}
+```
+
+### 阶段 4️⃣:改造 `src/menu/index.js` — 从静态导出变为工具模块
+
+将 [src/menu/index.js](file:///d:\code\mes\mes-ui\src\menu\index.js) 从"导出静态菜单配置"改为"菜单处理工具"(参照源项目):
+
+```js
+import util from '@/libs/util'
+
+function getMenuData(arr) {
+ let tree = { header: [], aside: [] }
+
+ arr.forEach(value => {
+ if (!value.is_navi) return // 过滤非导航菜单
+
+ const menuItem = {
+ path: value.url,
+ title: value.name,
+ icon: value.icon,
+ type: value.type,
+ params: value.params
+ }
+
+ if (value.parent_id === 0) {
+ tree.header.push({ ...menuItem })
+ }
+
+ menuItem.menu_id = value.menu_id
+ menuItem.parent_id = value.parent_id
+ tree.aside.push(menuItem)
+ })
+
+ // 扁平数组转树
+ tree.aside = util.formatDataToTree(tree.aside)
+ return tree
+}
+
+export default {
+ install(vm, source) {
+ vm.commit('d2admin/menu/headerAuth', source)
+ const { header, aside } = getMenuData(source)
+ vm.commit('d2admin/menu/headerSet', header)
+ vm.commit('d2admin/menu/asideSet', aside)
+ }
+}
+```
+
+原有的静态菜单模块(`src/menu/modules/demo-*.js`)可保留但不再被引用,后续按需清理。
+
+### 阶段 5️⃣:增加权限控制基础设施
+
+#### 5.1 `$permission` 方法
+
+**改造** `src/plugin/d2admin/index.js`,新增:
+
+```js
+Vue.prototype.$permission = (value, type = 'menu') => {
+ let path = ''
+ const auth = store.state.d2admin.menu.authKey
+
+ switch (type) {
+ case 'menu':
+ path = value
+ break
+ case 'router':
+ path = value.name.replace(/-/g, '/')
+ path.slice(0, 1) !== '/' && (path = '/' + path)
+ break
+ }
+
+ return !!(path && Object.prototype.hasOwnProperty.call(auth, path))
+}
+```
+
+#### 5.2 `v-permission` 指令
+
+**改造** `src/main.js`,新增:
+
+```js
+Vue.directive('permission', {
+ bind: (el, binding) => {
+ if (!Vue.prototype.$permission(binding.value)) {
+ el.parentNode ? el.parentNode.removeChild(el) : el.style.display = 'none'
+ }
+ }
+})
+```
+
+#### 5.3 菜单点击权限过滤
+
+**改造** [src/layout/header-aside/components/mixin/menu.js](file:///d:\code\mes\mes-ui\src\layout\header-aside\components\mixin\menu.js),增加 `getRouterAuthPath` 方法:
+
+```js
+import { frameInRoutes } from '@/router/routes'
+
+methods: {
+ handleMenuSelect(index, indexPath) {
+ if (/^d2-menu-empty-\d+$/.test(index) || index === undefined) {
+ this.$message.warning('临时菜单')
+ } else if (/^https:\/\/|http:\/\//.test(index)) {
+ util.open(index)
+ } else {
+ this.getRouterAuthPath(index, indexPath)
+ }
+ },
+
+ getRouterAuthPath(index, indexPath) {
+ if (index === '/index' || !indexPath || indexPath.length > 1) {
+ this.$router.push({ path: index })
+ return
+ }
+
+ let router = null
+ for (const value of frameInRoutes) {
+ if (value.path === index) {
+ router = value.children
+ break
+ }
+ }
+
+ if (!router) {
+ this.$router.push({ path: index })
+ return
+ }
+
+ for (const value of router) {
+ const newPath = index + '/' + value.path
+ if (this.$permission(newPath)) {
+ this.$router.push({ path: newPath })
+ break
+ }
+ }
+ }
+}
+```
+
+### 阶段 6️⃣:改造 `main.js` 启动流程
+
+**改造** [src/main.js](file:///d:\code\mes\mes-ui\src\main.js):
+
+```js
+created() {
+ this.$store.commit('d2admin/page/init', frameInRoutes)
+ // 注释掉静态菜单设置:
+ // this.$store.commit('d2admin/menu/headerSet', menuHeader)
+ // this.$store.commit('d2admin/search/init', menuHeader)
+},
+mounted() {
+ this.$store.commit('d2admin/releases/versionShow')
+ this.$store.dispatch('d2admin/account/load') // → sourceDataLoad → 获取后端菜单
+ this.$store.commit('d2admin/ua/get')
+ this.$store.dispatch('d2admin/fullscreen/listen')
+},
+watch: {
+ // 注释掉 $route.matched 侧边栏切换(由 store.aside 直接驱动)
+ // '$route.matched': { ... }
+}
+```
+
+### 阶段 7️⃣:增加 `util.formatDataToTree` 工具函数
+
+**改造** `src/libs/util.js`,新增:
+
+```js
+util.formatDataToTree = (data, key = 'menu_id', pid = 'parent_id') => {
+ if (!data || data.length <= 0) return []
+
+ let map = {}
+ data.forEach(value => { map[value[key]] = { ...value } })
+
+ let tree = []
+ data.forEach(item => {
+ const id = item[key]
+ if (map[id][pid] && map[map[id][pid]]) {
+ if (!map[map[id][pid]].children) {
+ map[map[id][pid]].children = []
+ }
+ map[map[id][pid]].children.push(map[id])
+ } else {
+ tree.push(map[id])
+ }
+ })
+ return tree
+}
+```
+
+---
+
+## 四、影响的文件清单
+
+| 文件 | 改动类型 | 说明 |
+|------|----------|------|
+| `src/api/menu.js` | **新增** | 菜单 API(`getMenuAll`) |
+| `src/store/modules/d2admin/modules/menu.js` | **改造** | `sourceDataLoad` 加后端调用 + `headerAuth` mutation + `authKey` state |
+| `src/menu/index.js` | **重写** | 从静态配置改为 `install()` 工具模块 |
+| `src/plugin/d2admin/index.js` | **改造** | 新增 `$permission` 方法 |
+| `src/main.js` | **改造** | 注释静态菜单设置;新增 `v-permission` 指令 |
+| `src/layout/header-aside/components/mixin/menu.js` | **改造** | 增加 `getRouterAuthPath` 权限过滤 |
+| `src/libs/util.js` | **改造** | 新增 `formatDataToTree` 工具函数 |
+| `src/menu/modules/demo-*.js` | **后续可删** | 静态菜单数据不再使用,单独清理 |
+
+---
+
+## 五、完整时序图
+
+```
+ 用户登录
+ │
+ ▼
+ login/index.vue → dispatch('d2admin/account/login')
+ │
+ ▼
+ account.js login action
+ ├── loginAdminUser() → 后端登录接口
+ ├── util.cookies.set() → 存 token/uuid
+ ├── dispatch('d2admin/user/set') → 存用户信息
+ └── dispatch('load')
+ │
+ ├── d2admin/user/load → 加载用户名
+ ├── d2admin/theme/load → 加载主题
+ ├── d2admin/transition/load → 加载过渡效果
+ ├── d2admin/page/openedLoad → 加载标签页
+ ├── d2admin/menu/asideLoad → 加载侧边栏收起设置
+ ├── d2admin/size/load → 加载全局尺寸
+ ├── d2admin/color/load → 加载颜色设置
+ └── d2admin/menu/sourceDataLoad
+ │
+ ├── 先读 localStorage 缓存
+ ├── 缓存空 → GET /api/menu/all 后端接口
+ ├── 写入 localStorage 缓存
+ └── menu.install(this, sourceData)
+ ├── headerAuth → 构建 authKey 权限字典
+ ├── getMenuData → 扁平 → {header, aside} 树
+ ├── headerSet → 顶栏菜单渲染
+ └── asideSet → 侧边栏菜单渲染
+ │
+ ▼
+ 跳转到首页 → 菜单已按权限渲染
+```
+
+---
+
+## 六、注意事项
+
+1. **路由仍是静态注册的**:mes-ui 不需要改造成动态 `addRoute`,路由全部在 `router/routes.js` 中静态定义即可,权限通过菜单显示/隐藏 + `getRouterAuthPath` 控制。
+2. **不要删除源项目代码**:源项目在 `D:\code\company\SCTMES_MES_V5\vue-app`,仅作为参照,不对其做任何修改。
+3. **localStorage 缓存**是离线兜底:首次登录调后端,后续从缓存读取;注销时清空缓存。
+4. **`block` cookie**:已在登录页 `mounted` 中设为 `'false'`,注销时设为 `'true'`,用于控制错误日志是否弹出提示。
diff --git a/src/api/demo.js b/src/api/demo.js
deleted file mode 100644
index ad10d27a..00000000
--- a/src/api/demo.js
+++ /dev/null
@@ -1,86 +0,0 @@
-import { find, map, random } from 'lodash'
-import faker from 'faker/locale/zh_CN'
-import { requestForMock, mock } from '@/api/_service.js'
-import * as tools from '@/api/_tools.js'
-
-const db = [
- { id: '1', name: '用户 1', address: '上海市普陀区金沙江路 1518 弄' },
- { id: '2', name: '用户 2', address: '上海市普陀区金沙江路 1517 弄' },
- { id: '3', name: '用户 3', address: '上海市普陀区金沙江路 1519 弄' },
- { id: '4', name: '用户 4', address: '上海市普陀区金沙江路 1516 弄' }
-]
-
-/**
- * @description 列表
- */
-export function DEMO_MOCK_LIST () {
- // 模拟数据
- mock
- .onAny('/demo/business/issues/142/fetch')
- .reply(...tools.responseSuccess({ list: db }))
- // 接口请求
- return requestForMock({
- url: '/demo/business/issues/142/fetch',
- method: 'get'
- })
-}
-
-/**
- * @description 详情
- * @param {String} id 项目 ID
- */
-export function DEMO_MOCK_DETAIL (id) {
- // 模拟数据
- mock
- .onAny('/demo/business/issues/142/detail')
- .reply(config => tools.responseSuccess(find(db, { id: config.params.id })))
- // 接口请求
- return requestForMock({
- url: '/demo/business/issues/142/detail',
- method: 'get',
- params: {
- id
- }
- })
-}
-
-/**
- * @description 列表
- */
-export function DEMO_MOCK_LIST2 (params = {}) {
- // 模拟数据
- mock
- .onAny('/demo/business/table/1/fetch')
- .reply(config => tools.responseSuccess({
- page: {
- total: 1000
- },
- list: map(Array(config.params.pageSize), () => ({
- key: faker.random.uuid(),
- value: [10, 100, 200, 500][random(0, 3)],
- type: faker.random.boolean(),
- admin: faker.name.firstName() + faker.name.lastName(),
- adminNote: faker.random.words(),
- dateTimeCreat: faker.date.past(),
- used: faker.random.boolean(),
- dateTimeUse: faker.date.past()
- }))
- }))
- // 接口请求
- return requestForMock({
- url: '/demo/business/table/1/fetch',
- method: 'get',
- params
- })
-}
-
-/**
- * @description 错误日志示例 请求一个不存在的地址
- */
-export function DEMO_LOG_AJAX () {
- // 接口请求
- return requestForMock({
- url: '/invalid-url',
- method: 'get'
- })
-}
diff --git a/src/api/menu.js b/src/api/menu.js
new file mode 100644
index 00000000..955c1195
--- /dev/null
+++ b/src/api/menu.js
@@ -0,0 +1,13 @@
+import { request } from '@/api/_service'
+
+const urls = 'system_settings/menu_configuration/menu/'
+
+export function getMenuAll (data) {
+ return request({
+ url: urls + 'all',
+ method: 'get',
+ params: {
+ ...data
+ }
+ })
+}
diff --git a/src/layout/header-aside/components/mixin/menu.js b/src/layout/header-aside/components/mixin/menu.js
index 7160b58f..8ed3a1d1 100644
--- a/src/layout/header-aside/components/mixin/menu.js
+++ b/src/layout/header-aside/components/mixin/menu.js
@@ -1,4 +1,5 @@
import util from '@/libs/util.js'
+import { frameInRoutes } from '@/router/routes'
export default {
methods: {
@@ -8,9 +9,43 @@ export default {
} else if (/^https:\/\/|http:\/\//.test(index)) {
util.open(index)
} else {
- this.$router.push({
- path: index
- })
+ this.getRouterAuthPath(index, indexPath)
+ }
+ },
+ /**
+ * 点击菜单时进行权限过滤,查找第一个有权限的子路由
+ * @param {String} index 选中菜单项的 index (path)
+ * @param {Array} indexPath 选中菜单项的 index path
+ */
+ getRouterAuthPath (index, indexPath) {
+ // 首页或子级路由直接访问
+ if (index === '/index' || !indexPath || indexPath.length > 1) {
+ this.$router.push({ path: index })
+ return
+ }
+
+ // 查找一级路由下是否存在子路由
+ let router = null
+ for (const value of frameInRoutes) {
+ if (value.path === index) {
+ router = value.children
+ break
+ }
+ }
+
+ // 不存在子路由则直接进入
+ if (!router) {
+ this.$router.push({ path: index })
+ return
+ }
+
+ // 存在子路由时,跳转第一个有权限的子页面
+ for (const value of router) {
+ const newPath = index + '/' + value.path
+ if (this.$permission(newPath)) {
+ this.$router.push({ path: newPath })
+ break
+ }
}
}
}
diff --git a/src/libs/util.js b/src/libs/util.js
index 9711c6a9..e7dba3fe 100644
--- a/src/libs/util.js
+++ b/src/libs/util.js
@@ -8,6 +8,35 @@ const util = {
log
}
+/**
+ * 扁平数组转树形结构
+ * @param {Array} data 扁平数组
+ * @param {String} key 主键字段名
+ * @param {String} pid 父节点字段名
+ */
+util.formatDataToTree = (data, key = 'menu_id', pid = 'parent_id') => {
+ if (!data || data.length <= 0) {
+ return []
+ }
+
+ const map = {}
+ data.forEach(value => { map[value[key]] = { ...value } })
+
+ const tree = []
+ data.forEach(item => {
+ const id = item[key]
+ if (map[id][pid] && map[map[id][pid]]) {
+ if (!map[map[id][pid]].children) {
+ map[map[id][pid]].children = []
+ }
+ map[map[id][pid]].children.push(map[id])
+ } else {
+ tree.push(map[id])
+ }
+ })
+ return tree
+}
+
/**
* @description 更新标题
* @param {String} title 标题
diff --git a/src/main.js b/src/main.js
index d6d65b41..8802faa1 100644
--- a/src/main.js
+++ b/src/main.js
@@ -9,12 +9,20 @@ import store from '@/store/index'
// 菜单和路由设置
import router from './router'
-import { menuHeader, menuAside } from '@/menu'
import { frameInRoutes } from '@/router/routes'
// 核心插件
Vue.use(d2Admin)
+// 权限控制指令
+Vue.directive('permission', {
+ bind: (el, binding) => {
+ if (!Vue.prototype.$permission(binding.value)) {
+ el.parentNode ? el.parentNode.removeChild(el) : el.style.display = 'none'
+ }
+ }
+})
+
new Vue({
router,
store,
@@ -23,31 +31,16 @@ new Vue({
created () {
// 处理路由 得到每一级的路由设置
this.$store.commit('d2admin/page/init', frameInRoutes)
- // 设置顶栏菜单
- this.$store.commit('d2admin/menu/headerSet', menuHeader)
- // 初始化菜单搜索功能
- this.$store.commit('d2admin/search/init', menuHeader)
+ // 静态菜单和搜索由 account.load → sourceDataLoad 从后端动态加载
},
mounted () {
// 展示系统信息
this.$store.commit('d2admin/releases/versionShow')
- // 用户登录后从数据库加载一系列的设置
+ // 用户登录后从数据库加载一系列的设置(含菜单)
this.$store.dispatch('d2admin/account/load')
// 获取并记录用户 UA
this.$store.commit('d2admin/ua/get')
// 初始化全屏监听
this.$store.dispatch('d2admin/fullscreen/listen')
- },
- watch: {
- // 检测路由变化切换侧边栏内容
- '$route.matched': {
- handler (matched) {
- if (matched.length > 0) {
- const _side = menuAside.filter(menu => menu.path === matched[0].path)
- this.$store.commit('d2admin/menu/asideSet', _side.length > 0 ? _side[0].children : [])
- }
- },
- immediate: true
- }
}
}).$mount('#app')
diff --git a/src/menu/index.js b/src/menu/index.js
index ccbe36e1..0cee7b17 100644
--- a/src/menu/index.js
+++ b/src/menu/index.js
@@ -1,42 +1,52 @@
-import { uniqueId } from 'lodash'
-
-// 插件
-import demoPlugins from './modules/demo-plugins'
-// 组件
-import demoComponents from './modules/demo-components'
-// 功能
-import demoPlayground from './modules/demo-playground'
+import util from '@/libs/util'
/**
- * @description 给菜单数据补充上 path 字段
- * @description https://github.com/d2-projects/d2-admin/issues/209
- * @param {Array} menu 原始的菜单数据
+ * 将后端返回的扁平菜单数组转为 { header: [], aside: [] } 树结构
+ * @param {Array} arr 后端返回的扁平菜单数据
*/
-function supplementPath (menu) {
- return menu.map(e => ({
- ...e,
- path: e.path || uniqueId('d2-menu-empty-'),
- ...e.children ? {
- children: supplementPath(e.children)
- } : {}
- }))
+function getMenuData (arr) {
+ const tree = { header: [], aside: [] }
+
+ arr.forEach(value => {
+ if (!value.is_navi) {
+ return
+ }
+
+ const menuItem = {
+ path: value.url,
+ title: value.name,
+ icon: value.icon,
+ type: value.type,
+ params: value.params
+ }
+
+ // parent_id 为 0 的节点放入顶栏
+ if (value.parent_id === 0) {
+ tree.header.push({ ...menuItem })
+ }
+
+ // 所有节点保留 menu_id / parent_id 用于构建侧栏树形结构
+ menuItem.menu_id = value.menu_id
+ menuItem.parent_id = value.parent_id
+ tree.aside.push(menuItem)
+ })
+
+ // 扁平 aside 数组转为嵌套树
+ tree.aside = util.formatDataToTree(tree.aside)
+
+ return tree
}
-// 菜单 侧边栏
-export const menuAside = supplementPath([
- demoComponents,
- demoPlugins,
- demoPlayground
-])
-
-// 菜单 顶栏
-export const menuHeader = supplementPath([
- {
- path: '/index',
- title: '首页',
- icon: 'home'
- },
- demoPlayground,
- demoComponents,
- demoPlugins
-])
+export default {
+ /**
+ * 由 sourceDataLoad 调用,将菜单源数据写入 store
+ * @param {Object} vm vuex store 实例 (this)
+ * @param {Array} source 后端返回的扁平菜单数组
+ */
+ install (vm, source) {
+ vm.commit('d2admin/menu/headerAuth', source)
+ const { header, aside } = getMenuData(source)
+ vm.commit('d2admin/menu/headerSet', header)
+ vm.commit('d2admin/menu/asideSet', aside)
+ }
+}
diff --git a/src/menu/modules/demo-components.js b/src/menu/modules/demo-components.js
deleted file mode 100644
index 2ff907dd..00000000
--- a/src/menu/modules/demo-components.js
+++ /dev/null
@@ -1,88 +0,0 @@
-export default {
- path: '/demo/components',
- title: '组件',
- icon: 'puzzle-piece',
- children: [
- { path: '/demo/components/index', title: '扩展组件', icon: 'home' },
- {
- path: '/demo/components/container',
- title: '布局容器',
- icon: 'window-restore',
- children: [
- {
- title: '填充型',
- children: [
- { path: '/demo/components/container/full', title: '基础', icon: '' },
- { path: '/demo/components/container/full-slot', title: '插槽', icon: '' },
- { path: '/demo/components/container/full-bs', title: '滚动优化', icon: '' }
- ]
- },
- {
- title: '隐形模式',
- children: [
- { path: '/demo/components/container/ghost', title: '基础', icon: '' },
- { path: '/demo/components/container/ghost-slot', title: '插槽', icon: '' },
- { path: '/demo/components/container/ghost-bs', title: '滚动优化', icon: '' }
- ]
- },
- {
- title: '卡片型',
- children: [
- { path: '/demo/components/container/card', title: '基础', icon: '' },
- { path: '/demo/components/container/card-slot', title: '插槽', icon: '' },
- { path: '/demo/components/container/card-bs', title: '滚动优化', icon: '' }
- ]
- },
- {
- title: '方法',
- children: [
- { path: '/demo/components/container/api?bs=false', title: '滚动控制', icon: '' },
- { path: '/demo/components/container/api?bs=true', title: '滚动控制 BS', icon: '' }
- ]
- }
- ]
- },
- {
- path: '/demo/components/layout/grid',
- title: '高级布局',
- icon: 'tasks',
- children: [
- { path: '/demo/components/layout/grid', title: '拖拽位置和大小' },
- { path: '/demo/components/layout/splitpane', title: '区域划分' }
- ]
- },
- {
- path: '/demo/components/editor',
- title: '编辑器',
- icon: 'pencil-square-o',
- children: [
- { path: '/demo/components/editor-ueditor', title: 'UEditor', icon: '' },
- { path: '/demo/components/editor-quill', title: 'Quill', icon: '' }
- ]
- },
- {
- path: '/demo/components/icon',
- title: '图标',
- icon: 'star',
- children: [
- { path: '/demo/components/icon/icon', title: '图标组件' },
- { path: '/demo/components/icon/icon-svg', title: 'svg 图标组件' },
- { path: '/demo/components/icon/select', title: '图标选择器' },
- { path: '/demo/components/icon/select-svg', title: 'svg 图标选择器' },
- { path: '/demo/components/icon/list', title: 'FontAwesome' }
- ]
- },
- {
- path: '/demo/components/markdown',
- title: 'markdown 解析',
- icon: 'file-text-o',
- children: [
- { path: '/demo/components/markdown/source', title: '指定资源' },
- { path: '/demo/components/markdown/url', title: '异步加载文件' }
- ]
- },
- { path: '/demo/components/countup', title: '数字动画', icon: 'motorcycle' },
- { path: '/demo/components/highlight', title: '代码高亮显示', icon: 'code' },
- { path: '/demo/components/json-tree', title: 'JSON 展示', icon: 'sitemap' }
- ]
-}
diff --git a/src/menu/modules/demo-playground.js b/src/menu/modules/demo-playground.js
deleted file mode 100644
index d002744d..00000000
--- a/src/menu/modules/demo-playground.js
+++ /dev/null
@@ -1,133 +0,0 @@
-export default {
- path: '/demo/playground',
- title: '功能',
- icon: 'flask',
- children: [
- { path: '/demo/playground/index', title: '功能', icon: 'home' },
- {
- title: 'svg 菜单图标',
- iconSvg: 'd2-admin',
- children: [
- { title: 'add', iconSvg: 'add' },
- { title: 'alarm', iconSvg: 'alarm' },
- { title: 'camera', iconSvg: 'camera' },
- { title: 'history', iconSvg: 'history' },
- { title: 'like', iconSvg: 'like' },
- { title: 'love', iconSvg: 'love' },
- { title: 'message', iconSvg: 'message' },
- { title: 'notice', iconSvg: 'notice' },
- { title: 'search', iconSvg: 'search' },
- { title: 'share', iconSvg: 'share' },
- { title: 'star', iconSvg: 'star' },
- { title: 'user', iconSvg: 'user' }
- ]
- },
- {
- title: '空菜单演示',
- icon: 'folder-o',
- children: [
- {
- title: '正在开发 1',
- children: [
- { title: '正在开发 1-1' },
- { title: '正在开发 1-2' }
- ]
- },
- { title: '正在开发 2' },
- { title: '正在开发 3' }
- ]
- },
- {
- path: '/demo/playground/frame',
- title: '内嵌网页',
- icon: 'globe',
- children: [
- { path: '/demo/playground/frame/d2-doc', title: 'D2Admin 中文文档', iconSvg: 'd2-admin' },
- { path: '/demo/playground/frame/html', title: '静态 HTML', icon: 'code' },
- { path: '/demo/playground/frame/report', title: '构建分析', icon: 'pie-chart' }
- ]
- },
- {
- title: '新窗口打开链接',
- icon: 'link',
- children: [
- { path: 'https://github.com/d2-projects/d2-admin', title: 'D2Admin Github', icon: 'github' },
- { path: 'https://juejin.im/user/57a48b632e958a006691b946/posts', title: '掘金', icon: 'globe' },
- { path: 'https://my.oschina.net/u/3871516', title: '开源中国', icon: 'globe' },
- { path: 'https://www.zhihu.com/people/fairy-ever/activities', title: '知乎', icon: 'globe' },
- { path: 'https://segmentfault.com/blog/liyang-note-book', title: 'segmentfault 专栏', icon: 'globe' },
- { path: 'http://www.fairyever.com/', title: 'www.fairyever.com', icon: 'globe' }
- ]
- },
- {
- path: '/demo/playground/store',
- title: '全局状态管理',
- icon: 'bolt',
- children: [
- { path: '/demo/playground/store/page', title: '多标签页控制', icon: 'window-restore' },
- { path: '/demo/playground/store/menu', title: '菜单控制', icon: 'bars' },
- { path: '/demo/playground/store/size', title: '全局尺寸', icon: 'font' },
- { path: '/demo/playground/store/ua', title: '浏览器信息', icon: 'info-circle' },
- { path: '/demo/playground/store/gray', title: '灰度模式', icon: 'eye' },
- { path: '/demo/playground/store/fullscreen', title: '全屏', icon: 'arrows-alt' },
- { path: '/demo/playground/store/theme', title: '主题', icon: 'diamond' },
- { path: '/demo/playground/store/transition', title: '页面过渡开关', icon: 'toggle-on' }
- ]
- },
- {
- path: '/demo/playground/page-cache',
- title: '页面缓存',
- icon: 'hdd-o',
- children: [
- { path: '/demo/playground/page-cache/on', title: '开启缓存' },
- { path: '/demo/playground/page-cache/off', title: '关闭缓存' },
- { path: '/demo/playground/page-cache/params/1', title: '带参路由缓存 1' },
- { path: '/demo/playground/page-cache/params/2', title: '带参路由缓存 2' }
- ]
- },
- {
- path: '/demo/playground/page-argu',
- title: '参数传递和留存',
- icon: 'assistive-listening-systems',
- children: [
- { path: '/demo/playground/page-argu/send', title: '发送' },
- { path: '/demo/playground/page-argu/get/username-from-menu?userid=userid-from-menu', title: '接收' }
- ]
- },
- {
- path: '/demo/playground/db',
- title: '数据持久化',
- icon: 'database',
- children: [
- { path: '/demo/playground/db/all', title: '总览', icon: 'table' },
- { path: '/demo/playground/db/public', title: '公共存储', icon: 'users' },
- { path: '/demo/playground/db/user', title: '私有数据', icon: 'user' },
- { path: '/demo/playground/db/page-public', title: '路由存储', icon: 'file-o' },
- { path: '/demo/playground/db/page-user', title: '私有路由存储', icon: 'file-o' },
- { path: '/demo/playground/db/page-snapshot-public', title: '路由快照', icon: 'file' },
- { path: '/demo/playground/db/page-snapshot-user', title: '私有路由快照', icon: 'file' }
- ]
- },
- {
- path: '/demo/playground/log',
- title: '日志',
- icon: 'bullseye',
- children: [
- { path: '/demo/playground/log/log', title: '日志记录', icon: 'dot-circle-o' },
- { path: '/demo/playground/log/error', title: '错误捕捉', icon: 'bug' },
- { path: '/demo/playground/log/ajax', title: 'Ajax 错误', icon: 'bug' },
- { path: '/demo/playground/log/console', title: '控制台日志', icon: 'lightbulb-o' }
- ]
- },
- {
- path: '/demo/playground/add-routes',
- title: '动态添加路由',
- icon: 'plus-square',
- children: [
- { path: '/demo/playground/add-routes/routes', title: '添加页面', icon: 'file-o' }
- ]
- },
- { path: '/demo/playground/env', title: '环境信息', icon: 'exclamation-circle' },
- { path: '/demo/playground/locales', title: '国际化', icon: 'language' }
- ]
-}
diff --git a/src/menu/modules/demo-plugins.js b/src/menu/modules/demo-plugins.js
deleted file mode 100644
index 1cb550db..00000000
--- a/src/menu/modules/demo-plugins.js
+++ /dev/null
@@ -1,29 +0,0 @@
-export default {
- path: '/demo/plugins',
- title: '插件',
- icon: 'plug',
- children: [
- { path: '/demo/plugins/index', title: '插件', icon: 'home' },
- {
- path: '/demo/plugins/import',
- title: '导入',
- icon: 'download',
- children: [
- { path: '/demo/plugins/import/csv', title: 'csv' },
- { path: '/demo/plugins/import/xlsx', title: 'xlsx' }
- ]
- },
- {
- path: '/demo/plugins/export',
- title: '导出',
- icon: 'upload',
- children: [
- { path: '/demo/plugins/export/table', title: '表格' },
- { path: '/demo/plugins/export/txt', title: '文本' }
- ]
- },
- { path: '/demo/plugins/clipboard-polyfill', title: '剪贴板访问', icon: 'clipboard' },
- { path: '/demo/plugins/day', title: '日期计算', icon: 'clock-o' },
- { path: '/demo/plugins/js-cookie', title: 'Cookie 读写', icon: 'asterisk' }
- ]
-}
diff --git a/src/plugin/d2admin/index.js b/src/plugin/d2admin/index.js
index 7c739e91..7f56e3c2 100644
--- a/src/plugin/d2admin/index.js
+++ b/src/plugin/d2admin/index.js
@@ -10,6 +10,8 @@ import '@/assets/svg-icons'
// 国际化
import i18n from '@/i18n.js'
+import store from '@/store'
+
// 功能插件
import pluginError from '@/plugin/error'
import pluginLog from '@/plugin/log'
@@ -28,6 +30,25 @@ export default {
Vue.prototype.$version = process.env.VUE_APP_VERSION
// 构建时间
Vue.prototype.$buildTime = process.env.VUE_APP_BUILD_TIME
+
+ // 权限检查方法
+ Vue.prototype.$permission = (value, type = 'menu') => {
+ let path = ''
+ const auth = store.state.d2admin.menu.authKey
+
+ switch (type) {
+ case 'menu':
+ path = value
+ break
+ case 'router':
+ path = value.name.replace(/-/g, '/')
+ path.slice(0, 1) !== '/' && (path = '/' + path)
+ break
+ }
+
+ return !!(path && Object.prototype.hasOwnProperty.call(auth, path))
+ }
+
// Element
Vue.use(ElementUI, {
i18n: (key, value) => i18n.t(key, value)
diff --git a/src/router/modules/components.js b/src/router/modules/components.js
deleted file mode 100644
index c1a0f402..00000000
--- a/src/router/modules/components.js
+++ /dev/null
@@ -1,41 +0,0 @@
-import layoutHeaderAside from '@/layout/header-aside'
-
-// 由于懒加载页面太多的话会造成webpack热更新太慢,所以开发环境不使用懒加载,只有生产环境使用懒加载
-const _import = require('@/libs/util.import.' + process.env.NODE_ENV)
-
-const meta = { auth: true }
-
-export default {
- path: '/demo/components',
- name: 'demo-components',
- meta,
- redirect: { name: 'demo-components-index' },
- component: layoutHeaderAside,
- children: [
- { path: 'container/full', name: 'demo-components-container-full', component: _import('demo/components/container/full.vue'), meta: { ...meta, title: '布局组件 填充' } },
- { path: 'container/full-slot', name: 'demo-components-container-full-slot', component: _import('demo/components/container/full-slot.vue'), meta: { ...meta, title: '布局组件 填充 插槽' } },
- { path: 'container/full-bs', name: 'demo-components-container-full-bs', component: _import('demo/components/container/full-bs.vue'), meta: { ...meta, title: '布局组件 填充 滚动优化' } },
- { path: 'container/ghost', name: 'demo-components-container-ghost', component: _import('demo/components/container/ghost.vue'), meta: { ...meta, title: '布局组件 隐形' } },
- { path: 'container/ghost-slot', name: 'demo-components-container-ghost-slot', component: _import('demo/components/container/ghost-slot.vue'), meta: { ...meta, title: '布局组件 隐形 插槽' } },
- { path: 'container/ghost-bs', name: 'demo-components-container-ghost-bs', component: _import('demo/components/container/ghost-bs.vue'), meta: { ...meta, title: '布局组件 隐形 滚动优化' } },
- { path: 'container/card', name: 'demo-components-container-card', component: _import('demo/components/container/card.vue'), meta: { ...meta, title: '布局组件 卡片' } },
- { path: 'container/card-slot', name: 'demo-components-container-card-slot', component: _import('demo/components/container/card-slot.vue'), meta: { ...meta, title: '布局组件 卡片 插槽' } },
- { path: 'container/card-bs', name: 'demo-components-container-card-bs', component: _import('demo/components/container/card-bs.vue'), meta: { ...meta, title: '布局组件 卡片 滚动优化' } },
- { path: 'container/api', name: 'demo-components-container-api', component: _import('demo/components/container/api.vue'), meta: { ...meta, title: '布局组件 API' } },
- { path: 'countup', name: 'demo-components-countup', component: _import('demo/components/countup'), meta: { ...meta, title: '数字动画' } },
- { path: 'editor-ueditor', name: 'demo-components-editor-ueditor', component: _import('demo/components/editor-ueditor'), meta: { ...meta, title: 'UEditor' } },
- { path: 'editor-quill', name: 'demo-components-editor-quill', component: _import('demo/components/editor-quill'), meta: { ...meta, title: '富文本编辑器' } },
- { path: 'highlight', name: 'demo-components-highlight', component: _import('demo/components/highlight'), meta: { ...meta, title: '代码高亮组件' } },
- { path: 'icon/icon', name: 'demo-components-icon-icon', component: _import('demo/components/icon/icon.vue'), meta: { ...meta, title: '图标组件' } },
- { path: 'icon/icon-svg', name: 'demo-components-icon-icon-svg', component: _import('demo/components/icon/icon-svg.vue'), meta: { ...meta, title: 'svg 图标' } },
- { path: 'icon/select', name: 'demo-components-icon-select', component: _import('demo/components/icon/select.vue'), meta: { ...meta, title: '图标选择器' } },
- { path: 'icon/select-svg', name: 'demo-components-icon-select-svg', component: _import('demo/components/icon/select-svg.vue'), meta: { ...meta, title: 'svg 图标选择器' } },
- { path: 'icon/list', name: 'demo-components-icon-list', component: _import('demo/components/icon/list.vue'), meta: { ...meta, title: '图标列表' } },
- { path: 'index', name: 'demo-components-index', component: _import('demo/components/index'), meta: { ...meta, title: '组件首页' } },
- { path: 'json-tree', name: 'demo-components-json-tree', component: _import('demo/components/json-tree'), meta: { ...meta, title: 'JSON 展示' } },
- { path: 'layout/grid', name: 'demo-components-layout-grid', component: _import('demo/components/layout/grid.vue'), meta: { ...meta, title: '拖拽网格布局' } },
- { path: 'layout/splitpane', name: 'demo-components-layout-splitpane', component: _import('demo/components/layout/splitpane.vue'), meta: { ...meta, title: '区域布局' } },
- { path: 'markdown/source', name: 'demo-components-markdown-source', component: _import('demo/components/markdown/source.vue'), meta: { ...meta, title: 'markdown指定资源渲染' } },
- { path: 'markdown/url', name: 'demo-components-markdown-url', component: _import('demo/components/markdown/url.vue'), meta: { ...meta, title: 'markdown指定url渲染' } }
- ]
-}
diff --git a/src/router/modules/playground.js b/src/router/modules/playground.js
deleted file mode 100644
index 3dcc763e..00000000
--- a/src/router/modules/playground.js
+++ /dev/null
@@ -1,47 +0,0 @@
-import layoutHeaderAside from '@/layout/header-aside'
-
-// 由于懒加载页面太多的话会造成webpack热更新太慢,所以开发环境不使用懒加载,只有生产环境使用懒加载
-const _import = require('@/libs/util.import.' + process.env.NODE_ENV)
-
-const meta = { auth: true }
-
-export default {
- path: '/demo/playground',
- name: 'demo-playground',
- meta,
- redirect: { name: 'demo-playground-index' },
- component: layoutHeaderAside,
- children: [
- { path: 'index', name: 'demo-playground-index', component: _import('demo/playground/index'), meta: { ...meta, title: '功能首页' } },
- { path: 'store/page', name: 'demo-playground-store-page', component: _import('demo/playground/store/page'), meta: { ...meta, cache: true, title: '多标签页控制' } },
- { path: 'store/menu', name: 'demo-playground-store-menu', component: _import('demo/playground/store/menu'), meta: { ...meta, title: '菜单控制' } },
- { path: 'store/size', name: 'demo-playground-store-size', component: _import('demo/playground/store/size'), meta: { ...meta, title: '全局尺寸' } },
- { path: 'store/ua', name: 'demo-playground-store-ua', component: _import('demo/playground/store/ua'), meta: { ...meta, title: '浏览器信息' } },
- { path: 'store/gray', name: 'demo-playground-store-gray', component: _import('demo/playground/store/gray'), meta: { ...meta, title: '灰度模式' } },
- { path: 'store/fullscreen', name: 'demo-playground-store-fullscreen', component: _import('demo/playground/store/fullscreen'), meta: { ...meta, title: '全屏' } },
- { path: 'store/theme', name: 'demo-playground-store-theme', component: _import('demo/playground/store/theme'), meta: { ...meta, title: '主题' } },
- { path: 'store/transition', name: 'demo-playground-store-transition', component: _import('demo/playground/store/transition'), meta: { ...meta, title: '页面过渡开关' } },
- { path: 'page-cache/on', name: 'demo-playground-page-cache-on', component: _import('demo/playground/page-cache/on.vue'), meta: { ...meta, cache: true, title: '开启缓存' } },
- { path: 'page-cache/off', name: 'demo-playground-page-cache-off', component: _import('demo/playground/page-cache/off.vue'), meta: { ...meta, title: '关闭缓存' } },
- { path: 'page-cache/params/:id', name: 'demo-playground-page-cache-params', component: _import('demo/playground/page-cache/params.vue'), meta: { ...meta, cache: true, title: '带参路由缓存' }, props: true },
- { path: 'page-argu/send', name: 'demo-playground-page-argu-send', component: _import('demo/playground/page-argu/send.vue'), meta: { ...meta, title: '参数传递 发送' } },
- { path: 'page-argu/get/:username', name: 'demo-playground-page-argu-get', component: _import('demo/playground/page-argu/get.vue'), meta: { ...meta, title: '参数传递 接收' } },
- { path: 'db/all', name: 'demo-playground-db-all', component: _import('demo/playground/db/all'), meta: { ...meta, title: '总览' } },
- { path: 'db/public', name: 'demo-playground-db-public', component: _import('demo/playground/db/public'), meta: { ...meta, title: '公共存储' } },
- { path: 'db/user', name: 'demo-playground-db-user', component: _import('demo/playground/db/user'), meta: { ...meta, title: '私有存储' } },
- { path: 'db/page-public', name: 'demo-playground-db-page-public', component: _import('demo/playground/db/page-public'), meta: { ...meta, title: '路由存储' } },
- { path: 'db/page-user', name: 'demo-playground-db-page-user', component: _import('demo/playground/db/page-user'), meta: { ...meta, title: '私有路由存储' } },
- { path: 'db/page-snapshot-public', name: 'demo-playground-db-page-snapshot-public', component: _import('demo/playground/db/page-snapshot-public'), meta: { ...meta, title: '路由快照' } },
- { path: 'db/page-snapshot-user', name: 'demo-playground-db-page-snapshot-user', component: _import('demo/playground/db/page-snapshot-user'), meta: { ...meta, title: '私有路由快照' } },
- { path: 'log/ajax', name: 'demo-playground-log-ajax', component: _import('demo/playground/log/ajax'), meta: { ...meta, title: 'Ajax 错误' } },
- { path: 'log/console', name: 'demo-playground-log-console', component: _import('demo/playground/log/console'), meta: { ...meta, title: '控制台日志' } },
- { path: 'log/error', name: 'demo-playground-log-error', component: _import('demo/playground/log/error'), meta: { ...meta, title: '错误捕捉' } },
- { path: 'log/log', name: 'demo-playground-log-log', component: _import('demo/playground/log/log'), meta: { ...meta, title: '日志记录' } },
- { path: 'add-routes/routes', name: 'demo-playground-add-routes-routes', component: _import('demo/playground/add-routes/routes'), meta: { ...meta, title: '添加页面' } },
- { path: 'env', name: 'demo-playground-env', component: _import('demo/playground/env'), meta: { ...meta, title: '环境信息' } },
- { path: 'locales', name: 'demo-playground-locales', component: _import('demo/playground/locales'), meta: { ...meta, title: '国际化' } },
- { path: 'frame/html', name: 'demo-playground-frame-html', component: _import('demo/playground/frame/html'), meta: { ...meta, title: '静态 HTML' } },
- { path: 'frame/report', name: 'demo-playground-frame-report', component: _import('demo/playground/frame/report'), meta: { ...meta, title: 'Size report' } },
- { path: 'frame/d2-doc', name: 'demo-playground-frame-d2-doc', component: _import('demo/playground/frame/d2-doc'), meta: { ...meta, title: 'D2Admin 中文文档' } }
- ]
-}
diff --git a/src/router/modules/plugins.js b/src/router/modules/plugins.js
deleted file mode 100644
index 302506e4..00000000
--- a/src/router/modules/plugins.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import layoutHeaderAside from '@/layout/header-aside'
-
-// 由于懒加载页面太多的话会造成webpack热更新太慢,所以开发环境不使用懒加载,只有生产环境使用懒加载
-const _import = require('@/libs/util.import.' + process.env.NODE_ENV)
-
-const meta = { auth: true }
-
-export default {
- path: '/demo/plugins',
- name: 'demo-plugins',
- meta,
- redirect: { name: 'demo-plugins-index' },
- component: layoutHeaderAside,
- children: [
- { path: 'clipboard-polyfill', name: 'demo-plugins-clipboard-polyfill', component: _import('demo/plugins/clipboard-polyfill'), meta: { ...meta, title: '剪贴板访问' } },
- { path: 'day', name: 'demo-plugins-day', component: _import('demo/plugins/day'), meta: { ...meta, title: '日期计算' } },
- { path: 'export/table', name: 'demo-plugins-export-table', component: _import('demo/plugins/export/table.vue'), meta: { ...meta, title: '导出表格' } },
- { path: 'export/txt', name: 'demo-plugins-export-txt', component: _import('demo/plugins/export/txt.vue'), meta: { ...meta, title: '导出文本' } },
- { path: 'import/csv', name: 'demo-plugins-import-csv', component: _import('demo/plugins/import/csv.vue'), meta: { ...meta, title: '导入 csv' } },
- { path: 'import/xlsx', name: 'demo-plugins-import-xlsx', component: _import('demo/plugins/import/xlsx.vue'), meta: { ...meta, title: '导入 xlsx' } },
- { path: 'index', name: 'demo-plugins-index', component: _import('demo/plugins/index'), meta: { ...meta, title: '插件首页' } },
- { path: 'js-cookie', name: 'demo-plugins-js-cookie', component: _import('demo/plugins/js-cookie'), meta: { ...meta, title: 'Cookie' } }
- ]
-}
diff --git a/src/router/modules/production-master-data.js b/src/router/modules/production-master-data.js
deleted file mode 100644
index e91fc9a1..00000000
--- a/src/router/modules/production-master-data.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import layoutHeaderAside from '@/layout/header-aside'
-
-const meta = { auth: true }
-
-const _import = require('@/libs/util.import.' + process.env.NODE_ENV)
-
-export default {
- path: '/production_master_data',
- component: layoutHeaderAside,
- children: (pre => [
- {
- path: 'factory_model/factory_area',
- name: `${pre}factory_model-factory_area`,
- meta: { ...meta, cache: true, title: '工厂区域' },
- component: _import('production-master-data/factory-model/factory-area')
- }
- ])('production_master_data-')
-}
diff --git a/src/router/routes.js b/src/router/routes.js
index 52a7b00f..7652ebd2 100644
--- a/src/router/routes.js
+++ b/src/router/routes.js
@@ -1,9 +1,5 @@
-import playground from './modules/playground'
-import plugins from './modules/plugins'
-import components from './modules/components'
-import productionMasterData from './modules/production-master-data'
-
import layoutHeaderAside from '@/layout/header-aside'
+import productionMasterData from './modules/production-master-data'
// 由于懒加载页面太多的话会造成webpack热更新太慢,所以开发环境不使用懒加载,只有生产环境使用懒加载
const _import = require('@/libs/util.import.' + process.env.NODE_ENV)
@@ -53,9 +49,6 @@ const frameIn = [
}
]
},
- playground,
- plugins,
- components,
productionMasterData
]
diff --git a/src/store/modules/d2admin/modules/menu.js b/src/store/modules/d2admin/modules/menu.js
index 520e2d60..8a791ec4 100644
--- a/src/store/modules/d2admin/modules/menu.js
+++ b/src/store/modules/d2admin/modules/menu.js
@@ -1,5 +1,7 @@
-// 设置文件
import setting from '@/setting.js'
+import util from '@/libs/util'
+import menu from '@/menu'
+import { getMenuAll } from '@/api/menu'
export default {
namespaced: true,
@@ -12,19 +14,14 @@ export default {
asideCollapse: setting.menu.asideCollapse,
// 侧边栏折叠动画
asideTransition: setting.menu.asideTransition,
+ // 权限字典 { '/path': '菜单名' }
+ authKey: {},
// 菜单源数据
sourceData: []
},
actions: {
- /**
- * 设置侧边栏展开或者收缩
- * @param {Object} context
- * @param {Boolean} collapse is collapse
- */
async asideCollapseSet ({ state, dispatch }, collapse) {
- // store 赋值
state.asideCollapse = collapse
- // 持久化
await dispatch('d2admin/db/set', {
dbName: 'sys',
path: 'menu.asideCollapse',
@@ -32,14 +29,8 @@ export default {
user: true
}, { root: true })
},
- /**
- * 切换侧边栏展开和收缩
- * @param {Object} context
- */
async asideCollapseToggle ({ state, dispatch }) {
- // store 赋值
state.asideCollapse = !state.asideCollapse
- // 持久化
await dispatch('d2admin/db/set', {
dbName: 'sys',
path: 'menu.asideCollapse',
@@ -47,15 +38,8 @@ export default {
user: true
}, { root: true })
},
- /**
- * 设置侧边栏折叠动画
- * @param {Object} context
- * @param {Boolean} transition is transition
- */
async asideTransitionSet ({ state, dispatch }, transition) {
- // store 赋值
state.asideTransition = transition
- // 持久化
await dispatch('d2admin/db/set', {
dbName: 'sys',
path: 'menu.asideTransition',
@@ -63,14 +47,8 @@ export default {
user: true
}, { root: true })
},
- /**
- * 切换侧边栏折叠动画
- * @param {Object} context
- */
async asideTransitionToggle ({ state, dispatch }) {
- // store 赋值
state.asideTransition = !state.asideTransition
- // 持久化
await dispatch('d2admin/db/set', {
dbName: 'sys',
path: 'menu.asideTransition',
@@ -78,52 +56,58 @@ export default {
user: true
}, { root: true })
},
- /**
- * 持久化数据加载侧边栏设置
- * @param {Object} context
- */
async asideLoad ({ state, dispatch }) {
- // store 赋值
- const menu = await dispatch('d2admin/db/get', {
+ const menuSetting = await dispatch('d2admin/db/get', {
dbName: 'sys',
path: 'menu',
defaultValue: setting.menu,
user: true
}, { root: true })
- state.asideCollapse = menu.asideCollapse !== undefined ? menu.asideCollapse : setting.menu.asideCollapse
- state.asideTransition = menu.asideTransition !== undefined ? menu.asideTransition : setting.menu.asideTransition
+ state.asideCollapse = menuSetting.asideCollapse !== undefined ? menuSetting.asideCollapse : setting.menu.asideCollapse
+ state.asideTransition = menuSetting.asideTransition !== undefined ? menuSetting.asideTransition : setting.menu.asideTransition
},
- /**
- * 持久化数据加载菜单源数据
- * @param {Object} context
- */
- async sourceDataLoad ({ state, dispatch }) {
- const sourceData = await dispatch('d2admin/db/get', {
+ async sourceDataLoad ({ state, commit, dispatch }) {
+ // 优先从 localStorage 读取上次缓存的菜单数据
+ state.sourceData = await dispatch('d2admin/db/get', {
dbName: 'database',
path: '$menu.sourceData',
defaultValue: [],
user: true
}, { root: true })
- state.sourceData = sourceData
+
+ // 缓存为空且已登录时,从后端获取菜单
+ if (!state.sourceData.length && util.cookies.get('token')) {
+ const res = await getMenuAll()
+ state.sourceData = res || []
+ await dispatch('d2admin/db/set', {
+ dbName: 'database',
+ path: '$menu.sourceData',
+ value: state.sourceData,
+ user: true
+ }, { root: true })
+ }
+
+ // 构建菜单树和权限字典
+ menu.install(this, state.sourceData)
}
},
mutations: {
- /**
- * @description 设置顶栏菜单
- * @param {Object} state state
- * @param {Array} menu menu setting
- */
+ headerAuth (state, source) {
+ if (!source || source.length <= 0) {
+ return
+ }
+ const auth = {}
+ source.forEach(value => {
+ if (value.url) {
+ auth[value.url] = value.name
+ }
+ })
+ state.authKey = auth
+ },
headerSet (state, menu) {
- // store 赋值
state.header = menu
},
- /**
- * @description 设置侧边栏菜单
- * @param {Object} state state
- * @param {Array} menu menu setting
- */
asideSet (state, menu) {
- // store 赋值
state.aside = menu
}
}
diff --git a/src/views/demo/components/container/api.vue b/src/views/demo/components/container/api.vue
deleted file mode 100644
index e021348d..00000000
--- a/src/views/demo/components/container/api.vue
+++ /dev/null
@@ -1,104 +0,0 @@
-
- { scrollTop = y }">
-
-
-
-
-
-
-
-
-
-
-
- px
-
-
-
-
-
-
-
- 回到顶部
-
-
-
-
-
-
-
-
- 相对滚动 (0, 30) 像素
-
-
- 滚动到 (0, 100) 像素位置
-
-
- 滚动到垂直位置 100
-
-
-
-
-
-
diff --git a/src/views/demo/components/container/card-bs.vue b/src/views/demo/components/container/card-bs.vue
deleted file mode 100644
index e1312736..00000000
--- a/src/views/demo/components/container/card-bs.vue
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
- Header
-
- Footer
-
-
-
-
diff --git a/src/views/demo/components/container/card-slot.vue b/src/views/demo/components/container/card-slot.vue
deleted file mode 100644
index ff8b63df..00000000
--- a/src/views/demo/components/container/card-slot.vue
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
- Header
-
- Footer
-
-
-
-
diff --git a/src/views/demo/components/container/card.vue b/src/views/demo/components/container/card.vue
deleted file mode 100644
index ec121617..00000000
--- a/src/views/demo/components/container/card.vue
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
diff --git a/src/views/demo/components/container/components/d2-demo-article.vue b/src/views/demo/components/container/components/d2-demo-article.vue
deleted file mode 100644
index 00dc1b43..00000000
--- a/src/views/demo/components/container/components/d2-demo-article.vue
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
-
-
-
-
-
diff --git a/src/views/demo/components/container/full-bs.vue b/src/views/demo/components/container/full-bs.vue
deleted file mode 100644
index 9a651025..00000000
--- a/src/views/demo/components/container/full-bs.vue
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
- Header
-
- Header
-
-
-
-
diff --git a/src/views/demo/components/container/full-slot.vue b/src/views/demo/components/container/full-slot.vue
deleted file mode 100644
index 087df2a9..00000000
--- a/src/views/demo/components/container/full-slot.vue
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
- Header
-
- Footer
-
-
-
-
diff --git a/src/views/demo/components/container/full.vue b/src/views/demo/components/container/full.vue
deleted file mode 100644
index 9d99c936..00000000
--- a/src/views/demo/components/container/full.vue
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
diff --git a/src/views/demo/components/container/ghost-bs.vue b/src/views/demo/components/container/ghost-bs.vue
deleted file mode 100644
index bb41da3b..00000000
--- a/src/views/demo/components/container/ghost-bs.vue
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
- Header
-
-
-
-
-
- Footer
-
-
-
-
diff --git a/src/views/demo/components/container/ghost-slot.vue b/src/views/demo/components/container/ghost-slot.vue
deleted file mode 100644
index 831594da..00000000
--- a/src/views/demo/components/container/ghost-slot.vue
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
- Header
-
-
-
-
-
- Footer
-
-
-
-
diff --git a/src/views/demo/components/container/ghost.vue b/src/views/demo/components/container/ghost.vue
deleted file mode 100644
index 2c9872c3..00000000
--- a/src/views/demo/components/container/ghost.vue
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/views/demo/components/container/md/long.md b/src/views/demo/components/container/md/long.md
deleted file mode 100644
index 59d2f891..00000000
--- a/src/views/demo/components/container/md/long.md
+++ /dev/null
@@ -1,53 +0,0 @@
-## vue.js
-
-**易用**
-
-已经会了 HTML、CSS、JavaScript?即刻阅读指南开始构建应用!
-
-**灵活**
-
-不断繁荣的生态系统,可以在一个库和一套完整框架之间自如伸缩。
-
-**高效**
-
-20kB min+gzip 运行大小
-
-超快虚拟 DOM
-
-最省心的优化
-
-**Vue.js 是什么**
-
-Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
-
-如果你已经是有经验的前端开发者,想知道 Vue 与其它库/框架有哪些区别,请查看对比其它框架。
-
-## Element
-
-Element,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库
-
-**一致性** Consistency
-
-- 与现实生活一致:与现实生活的流程、逻辑保持一致,遵循用户习惯的语言和概念;
-
-- 在界面中一致:所有的元素和结构需保持一致,比如:设计样式、图标和文本、元素的位置等。
-
-**反馈** Feedback
-
-- 控制反馈:通过界面样式和交互动效让用户可以清晰的感知自己的操作;
-
-- 页面反馈:操作后,通过页面元素的变化清晰地展现当前状态。
-
-**效率** Efficiency
-
-- 简化流程:设计简洁直观的操作流程;
-
-- 清晰明确:语言表达清晰且表意明确,让用户快速理解进而作出决策;
-
-- 帮助用户识别:界面简单直白,让用户快速识别而非回忆,减少用户记忆负担。
-
-**可控** Controllability
-
-- 用户决策:根据场景可给予用户操作建议或安全提示,但不能代替用户进行决策;
-
-- 结果可控:用户可以自由的进行操作,包括撤销、回退和终止当前操作等。
\ No newline at end of file
diff --git a/src/views/demo/components/container/md/short.md b/src/views/demo/components/container/md/short.md
deleted file mode 100644
index 06496563..00000000
--- a/src/views/demo/components/container/md/short.md
+++ /dev/null
@@ -1,17 +0,0 @@
-## vue.js
-
-**易用**
-
-已经会了 HTML、CSS、JavaScript?即刻阅读指南开始构建应用!
-
-**灵活**
-
-不断繁荣的生态系统,可以在一个库和一套完整框架之间自如伸缩。
-
-**高效**
-
-20kB min+gzip 运行大小
-
-超快虚拟 DOM
-
-最省心的优化
\ No newline at end of file
diff --git a/src/views/demo/components/countup/index.vue b/src/views/demo/components/countup/index.vue
deleted file mode 100644
index 9e952b8d..00000000
--- a/src/views/demo/components/countup/index.vue
+++ /dev/null
@@ -1,94 +0,0 @@
-
-
- 数字动画组件
-
-
-
- 只设置目标数字
-
-
-
-
-
-
-
- 设置起止数值
-
-
-
-
-
-
-
- 小数位数
-
-
-
-
-
-
-
- 动画时长
-
-
-
-
-
-
-
- 回调函数
-
-
-
-
-
-
-
- 结束一秒后更新数值
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/views/demo/components/editor-quill/index.vue b/src/views/demo/components/editor-quill/index.vue
deleted file mode 100644
index dc456e55..00000000
--- a/src/views/demo/components/editor-quill/index.vue
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
-
- 添加一行
-
-
-
-
-
-
-
-
diff --git a/src/views/demo/components/editor-quill/value.js b/src/views/demo/components/editor-quill/value.js
deleted file mode 100644
index 89744593..00000000
--- a/src/views/demo/components/editor-quill/value.js
+++ /dev/null
@@ -1,6 +0,0 @@
-export default `
-D2 Admin
-
-by
-vue.js
-
`
diff --git a/src/views/demo/components/editor-ueditor/index.vue b/src/views/demo/components/editor-ueditor/index.vue
deleted file mode 100644
index c2d0ab3f..00000000
--- a/src/views/demo/components/editor-ueditor/index.vue
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
-
- Result
-
-
-
-
-
-
- 当前内容 x2
-
-
- 清空
-
-
-
-
-
-
diff --git a/src/views/demo/components/highlight/code/css.js b/src/views/demo/components/highlight/code/css.js
deleted file mode 100644
index f41e0a90..00000000
--- a/src/views/demo/components/highlight/code/css.js
+++ /dev/null
@@ -1,8 +0,0 @@
-export default `body {
- background-color: aliceblue;
- height: 100%;
-}
-.my-card {
- height: 300px;
- width: 300px;
-}`
diff --git a/src/views/demo/components/highlight/code/html.js b/src/views/demo/components/highlight/code/html.js
deleted file mode 100644
index 739a2b9d..00000000
--- a/src/views/demo/components/highlight/code/html.js
+++ /dev/null
@@ -1,8 +0,0 @@
-export default `
- Hello
- -
-
- Hello
-
-
-
`
diff --git a/src/views/demo/components/highlight/code/javascript.js b/src/views/demo/components/highlight/code/javascript.js
deleted file mode 100644
index ce752335..00000000
--- a/src/views/demo/components/highlight/code/javascript.js
+++ /dev/null
@@ -1,3 +0,0 @@
-export default `[].forEach.call($$("*"), a => {
- a.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16)
-})`
diff --git a/src/views/demo/components/highlight/code/scss.js b/src/views/demo/components/highlight/code/scss.js
deleted file mode 100644
index d914909c..00000000
--- a/src/views/demo/components/highlight/code/scss.js
+++ /dev/null
@@ -1,8 +0,0 @@
-export default `body {
- background-color: aliceblue;
- height: 100%;
- .my-card {
- height: 300px;
- width: 300px;
- }
-}`
diff --git a/src/views/demo/components/highlight/index.vue b/src/views/demo/components/highlight/index.vue
deleted file mode 100644
index ea77e68a..00000000
--- a/src/views/demo/components/highlight/index.vue
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
- 代码高亮组件
-
- javascript
-
-
-
- css
-
-
-
- scss
-
-
-
- html
-
-
-
-
-
-
diff --git a/src/views/demo/components/icon/components/d2-icon-cell.vue b/src/views/demo/components/icon/components/d2-icon-cell.vue
deleted file mode 100644
index 603004f0..00000000
--- a/src/views/demo/components/icon/components/d2-icon-cell.vue
+++ /dev/null
@@ -1,82 +0,0 @@
-
-
-
-
-
-
-
-
-
- Class
-
-
-
-
- HTML
-
-
-
-
- 组件
-
-
-
-
-
-
-
-
- {{icon}}
-
-
-
-
-
-
-
diff --git a/src/views/demo/components/icon/data/index.js b/src/views/demo/components/icon/data/index.js
deleted file mode 100644
index 3283c245..00000000
--- a/src/views/demo/components/icon/data/index.js
+++ /dev/null
@@ -1,1004 +0,0 @@
-// 4.7.0
-
-export default [
- {
- title: '网页',
- icon: [
- 'address-book',
- 'address-book-o',
- 'address-card',
- 'address-card-o',
- 'adjust',
- 'american-sign-language-interpreting',
- 'anchor',
- 'archive',
- 'area-chart',
- 'arrows',
- 'arrows-h',
- 'arrows-v',
- 'asl-interpreting',
- 'assistive-listening-systems',
- 'asterisk',
- 'at',
- 'audio-description',
- 'automobile',
- 'balance-scale',
- 'ban',
- 'bank',
- 'bar-chart',
- 'bar-chart-o',
- 'barcode',
- 'bars',
- 'bath',
- 'bathtub',
- 'battery',
- 'battery-0',
- 'battery-1',
- 'battery-2',
- 'battery-3',
- 'battery-4',
- 'battery-empty',
- 'battery-full',
- 'battery-half',
- 'battery-quarter',
- 'battery-three-quarters',
- 'bed',
- 'beer',
- 'bell',
- 'bell-o',
- 'bell-slash',
- 'bell-slash-o',
- 'bicycle',
- 'binoculars',
- 'birthday-cake',
- 'blind',
- 'bluetooth',
- 'bluetooth-b',
- 'bolt',
- 'bomb',
- 'book',
- 'bookmark',
- 'bookmark-o',
- 'braille',
- 'briefcase',
- 'bug',
- 'building',
- 'building-o',
- 'bullhorn',
- 'bullseye',
- 'bus',
- 'cab',
- 'calculator',
- 'calendar',
- 'calendar-check-o',
- 'calendar-minus-o',
- 'calendar-o',
- 'calendar-plus-o',
- 'calendar-times-o',
- 'camera',
- 'camera-retro',
- 'car',
- 'caret-square-o-down',
- 'caret-square-o-left',
- 'caret-square-o-right',
- 'caret-square-o-up',
- 'cart-arrow-down',
- 'cart-plus',
- 'cc',
- 'certificate',
- 'check',
- 'check-circle',
- 'check-circle-o',
- 'check-square',
- 'check-square-o',
- 'child',
- 'circle',
- 'circle-o',
- 'circle-o-notch',
- 'circle-thin',
- 'clock-o',
- 'clone',
- 'close',
- 'cloud',
- 'cloud-download',
- 'cloud-upload',
- 'code',
- 'code-fork',
- 'coffee',
- 'cog',
- 'cogs',
- 'comment',
- 'comment-o',
- 'commenting',
- 'commenting-o',
- 'comments',
- 'comments-o',
- 'compass',
- 'copyright',
- 'creative-commons',
- 'credit-card',
- 'credit-card-alt',
- 'crop',
- 'crosshairs',
- 'cube',
- 'cubes',
- 'cutlery',
- 'index',
- 'database',
- 'deaf',
- 'deafness',
- 'desktop',
- 'diamond',
- 'dot-circle-o',
- 'download',
- 'drivers-license',
- 'drivers-license-o',
- 'edit',
- 'ellipsis-h',
- 'ellipsis-v',
- 'envelope',
- 'envelope-o',
- 'envelope-open',
- 'envelope-open-o',
- 'envelope-square',
- 'eraser',
- 'exchange',
- 'exclamation',
- 'exclamation-circle',
- 'exclamation-triangle',
- 'external-link',
- 'external-link-square',
- 'eye',
- 'eye-slash',
- 'eyedropper',
- 'fax',
- 'feed',
- 'female',
- 'fighter-jet',
- 'file-archive-o',
- 'file-audio-o',
- 'file-code-o',
- 'file-excel-o',
- 'file-image-o',
- 'file-movie-o',
- 'file-pdf-o',
- 'file-photo-o',
- 'file-picture-o',
- 'file-powerpoint-o',
- 'file-sound-o',
- 'file-video-o',
- 'file-word-o',
- 'file-zip-o',
- 'film',
- 'filter',
- 'fire',
- 'fire-extinguisher',
- 'flag',
- 'flag-checkered',
- 'flag-o',
- 'flash',
- 'flask',
- 'folder',
- 'folder-o',
- 'folder-open',
- 'folder-open-o',
- 'frown-o',
- 'futbol-o',
- 'gamepad',
- 'gavel',
- 'gear',
- 'gears',
- 'gift',
- 'glass',
- 'globe',
- 'graduation-cap',
- 'group',
- 'hand-grab-o',
- 'hand-lizard-o',
- 'hand-paper-o',
- 'hand-peace-o',
- 'hand-pointer-o',
- 'hand-rock-o',
- 'hand-scissors-o',
- 'hand-spock-o',
- 'hand-stop-o',
- 'handshake-o',
- 'hard-of-hearing',
- 'hashtag',
- 'hdd-o',
- 'headphones',
- 'heart',
- 'heart-o',
- 'heartbeat',
- 'history',
- 'home',
- 'hotel',
- 'hourglass',
- 'hourglass-1',
- 'hourglass-2',
- 'hourglass-3',
- 'hourglass-end',
- 'hourglass-half',
- 'hourglass-o',
- 'hourglass-start',
- 'i-cursor',
- 'id-badge',
- 'id-card',
- 'id-card-o',
- 'image',
- 'inbox',
- 'industry',
- 'info',
- 'info-circle',
- 'institution',
- 'key',
- 'keyboard-o',
- 'language',
- 'laptop',
- 'leaf',
- 'legal',
- 'lemon-o',
- 'level-down',
- 'level-up',
- 'life-bouy',
- 'life-buoy',
- 'life-ring',
- 'life-saver',
- 'lightbulb-o',
- 'line-chart',
- 'location-arrow',
- 'lock',
- 'low-vision',
- 'magic',
- 'magnet',
- 'mail-forward',
- 'mail-reply',
- 'mail-reply-all',
- 'male',
- 'map',
- 'map-marker',
- 'map-o',
- 'map-pin',
- 'map-signs',
- 'meh-o',
- 'microchip',
- 'microphone',
- 'microphone-slash',
- 'minus',
- 'minus-circle',
- 'minus-square',
- 'minus-square-o',
- 'mobile',
- 'mobile-phone',
- 'money',
- 'moon-o',
- 'mortar-board',
- 'motorcycle',
- 'mouse-pointer',
- 'music',
- 'navicon',
- 'newspaper-o',
- 'object-group',
- 'object-ungroup',
- 'paint-brush',
- 'paper-plane',
- 'paper-plane-o',
- 'paw',
- 'pencil',
- 'pencil-square',
- 'pencil-square-o',
- 'percent',
- 'phone',
- 'phone-square',
- 'photo',
- 'picture-o',
- 'pie-chart',
- 'plane',
- 'plug',
- 'plus',
- 'plus-circle',
- 'plus-square',
- 'plus-square-o',
- 'podcast',
- 'power-off',
- 'print',
- 'puzzle-piece',
- 'qrcode',
- 'question',
- 'question-circle',
- 'question-circle-o',
- 'quote-left',
- 'quote-right',
- 'random',
- 'recycle',
- 'refresh',
- 'registered',
- 'remove',
- 'reorder',
- 'reply',
- 'reply-all',
- 'retweet',
- 'road',
- 'rocket',
- 'rss',
- 'rss-square',
- 's15',
- 'search',
- 'search-minus',
- 'search-plus',
- 'send',
- 'send-o',
- 'server',
- 'share',
- 'share-alt',
- 'share-alt-square',
- 'share-square',
- 'share-square-o',
- 'shield',
- 'ship',
- 'shopping-bag',
- 'shopping-basket',
- 'shopping-cart',
- 'shower',
- 'sign-in',
- 'sign-language',
- 'sign-out',
- 'signal',
- 'signing',
- 'sitemap',
- 'sliders',
- 'smile-o',
- 'snowflake-o',
- 'soccer-ball-o',
- 'sort',
- 'sort-alpha-asc',
- 'sort-alpha-desc',
- 'sort-amount-asc',
- 'sort-amount-desc',
- 'sort-asc',
- 'sort-desc',
- 'sort-down',
- 'sort-numeric-asc',
- 'sort-numeric-desc',
- 'sort-up',
- 'space-shuttle',
- 'spinner',
- 'spoon',
- 'square',
- 'square-o',
- 'star',
- 'star-half',
- 'star-half-empty',
- 'star-half-full',
- 'star-half-o',
- 'star-o',
- 'sticky-note',
- 'sticky-note-o',
- 'street-view',
- 'suitcase',
- 'sun-o',
- 'support',
- 'tablet',
- 'tachometer',
- 'tag',
- 'tags',
- 'tasks',
- 'taxi',
- 'television',
- 'terminal',
- 'thermometer',
- 'thermometer-0',
- 'thermometer-1',
- 'thermometer-2',
- 'thermometer-3',
- 'thermometer-4',
- 'thermometer-empty',
- 'thermometer-full',
- 'thermometer-half',
- 'thermometer-quarter',
- 'thermometer-three-quarters',
- 'thumb-tack',
- 'thumbs-down',
- 'thumbs-o-down',
- 'thumbs-o-up',
- 'thumbs-up',
- 'ticket',
- 'times',
- 'times-circle',
- 'times-circle-o',
- 'times-rectangle',
- 'times-rectangle-o',
- 'tint',
- 'toggle-down',
- 'toggle-left',
- 'toggle-off',
- 'toggle-on',
- 'toggle-right',
- 'toggle-up',
- 'trademark',
- 'trash',
- 'trash-o',
- 'tree',
- 'trophy',
- 'truck',
- 'tty',
- 'tv',
- 'umbrella',
- 'universal-access',
- 'university',
- 'unlock',
- 'unlock-alt',
- 'unsorted',
- 'upload',
- 'user',
- 'user-circle',
- 'user-circle-o',
- 'user-o',
- 'user-plus',
- 'user-secret',
- 'user-times',
- 'users',
- 'vcard',
- 'vcard-o',
- 'video-camera',
- 'volume-control-phone',
- 'volume-down',
- 'volume-off',
- 'volume-up',
- 'warning',
- 'wheelchair',
- 'wheelchair-alt',
- 'wifi',
- 'window-close',
- 'window-close-o',
- 'window-maximize',
- 'window-minimize',
- 'window-restore',
- 'wrench'
- ]
- },
- {
- title: '辅助功能',
- icon: [
- 'american-sign-language-interpreting',
- 'asl-interpreting',
- 'assistive-listening-systems',
- 'audio-description',
- 'blind',
- 'braille',
- 'cc',
- 'deaf',
- 'deafness',
- 'hard-of-hearing',
- 'low-vision',
- 'question-circle-o',
- 'sign-language',
- 'signing',
- 'tty',
- 'universal-access',
- 'volume-control-phone',
- 'wheelchair',
- 'wheelchair-alt'
- ]
- },
- {
- title: '手势',
- icon: [
- 'hand-grab-o',
- 'hand-lizard-o',
- 'hand-o-down',
- 'hand-o-left',
- 'hand-o-right',
- 'hand-o-up',
- 'hand-paper-o',
- 'hand-peace-o',
- 'hand-pointer-o',
- 'hand-rock-o',
- 'hand-scissors-o',
- 'hand-spock-o',
- 'hand-stop-o',
- 'thumbs-down',
- 'thumbs-o-down',
- 'thumbs-o-up',
- 'thumbs-up'
- ]
- },
- {
- title: '运输',
- icon: [
- 'ambulance',
- 'automobile',
- 'bicycle',
- 'bus',
- 'cab',
- 'car',
- 'fighter-jet',
- 'motorcycle',
- 'plane',
- 'rocket',
- 'ship',
- 'space-shuttle',
- 'subway',
- 'taxi',
- 'train',
- 'truck',
- 'wheelchair',
- 'wheelchair-alt'
- ]
- },
- {
- title: '性别',
- icon: [
- 'genderless',
- 'intersex',
- 'mars',
- 'mars-double',
- 'mars-stroke',
- 'mars-stroke-h',
- 'mars-stroke-v',
- 'mercury',
- 'neuter',
- 'transgender',
- 'transgender-alt',
- 'venus',
- 'venus-double',
- 'venus-mars'
- ]
- },
- {
- title: '文件类型',
- icon: [
- 'file',
- 'file-archive-o',
- 'file-audio-o',
- 'file-code-o',
- 'file-excel-o',
- 'file-image-o',
- 'file-movie-o',
- 'file-o',
- 'file-pdf-o',
- 'file-photo-o',
- 'file-picture-o',
- 'file-powerpoint-o',
- 'file-sound-o',
- 'file-text',
- 'file-text-o',
- 'file-video-o',
- 'file-word-o',
- 'file-zip-o'
- ]
- },
- {
- title: '可旋转',
- icon: [
- 'circle-o-notch',
- 'cog',
- 'gear',
- 'refresh',
- 'spinner'
- ]
- },
- {
- title: '表单',
- icon: [
- 'check-square',
- 'check-square-o',
- 'circle',
- 'circle-o',
- 'dot-circle-o',
- 'minus-square',
- 'minus-square-o',
- 'plus-square',
- 'plus-square-o',
- 'square',
- 'square-o'
- ]
- },
- {
- title: '支付',
- icon: [
- 'cc-amex',
- 'cc-diners-club',
- 'cc-discover',
- 'cc-jcb',
- 'cc-mastercard',
- 'cc-paypal',
- 'cc-stripe',
- 'cc-visa',
- 'credit-card',
- 'credit-card-alt',
- 'google-wallet',
- 'paypal'
- ]
- },
- {
- title: '图表',
- icon: [
- 'area-chart',
- 'bar-chart',
- 'bar-chart-o',
- 'line-chart',
- 'pie-chart'
- ]
- },
- {
- title: '货币',
- icon: [
- 'bitcoin',
- 'btc',
- 'cny',
- 'dollar',
- 'eur',
- 'euro',
- 'gbp',
- 'gg',
- 'gg-circle',
- 'ils',
- 'inr',
- 'jpy',
- 'krw',
- 'money',
- 'rmb',
- 'rouble',
- 'rub',
- 'ruble',
- 'rupee',
- 'shekel',
- 'sheqel',
- 'try',
- 'turkish-lira',
- 'usd',
- 'won',
- 'yen'
- ]
- },
- {
- title: '文本编辑',
- icon: [
- 'align-center',
- 'align-justify',
- 'align-left',
- 'align-right',
- 'bold',
- 'chain',
- 'chain-broken',
- 'clipboard',
- 'columns',
- 'copy',
- 'cut',
- 'dedent',
- 'eraser',
- 'file',
- 'file-o',
- 'file-text',
- 'file-text-o',
- 'files-o',
- 'floppy-o',
- 'font',
- 'header',
- 'indent',
- 'italic',
- 'link',
- 'list',
- 'list-alt',
- 'list-ol',
- 'list-ul',
- 'outdent',
- 'paperclip',
- 'paragraph',
- 'paste',
- 'repeat',
- 'rotate-left',
- 'rotate-right',
- 'save',
- 'scissors',
- 'strikethrough',
- 'subscript',
- 'superscript',
- 'table',
- 'text-height',
- 'text-width',
- 'th',
- 'th-large',
- 'th-list',
- 'underline',
- 'undo',
- 'unlink'
- ]
- },
- {
- title: '指示方向',
- icon: [
- 'angle-double-down',
- 'angle-double-left',
- 'angle-double-right',
- 'angle-double-up',
- 'angle-down',
- 'angle-left',
- 'angle-right',
- 'angle-up',
- 'arrow-circle-down',
- 'arrow-circle-left',
- 'arrow-circle-o-down',
- 'arrow-circle-o-left',
- 'arrow-circle-o-right',
- 'arrow-circle-o-up',
- 'arrow-circle-right',
- 'arrow-circle-up',
- 'arrow-down',
- 'arrow-left',
- 'arrow-right',
- 'arrow-up',
- 'arrows',
- 'arrows-alt',
- 'arrows-h',
- 'arrows-v',
- 'caret-down',
- 'caret-left',
- 'caret-right',
- 'caret-square-o-down',
- 'caret-square-o-left',
- 'caret-square-o-right',
- 'caret-square-o-up',
- 'caret-up',
- 'chevron-circle-down',
- 'chevron-circle-left',
- 'chevron-circle-right',
- 'chevron-circle-up',
- 'chevron-down',
- 'chevron-left',
- 'chevron-right',
- 'chevron-up',
- 'exchange',
- 'hand-o-down',
- 'hand-o-left',
- 'hand-o-right',
- 'hand-o-up',
- 'long-arrow-down',
- 'long-arrow-left',
- 'long-arrow-right',
- 'long-arrow-up',
- 'toggle-down',
- 'toggle-left',
- 'toggle-right',
- 'toggle-up'
- ]
- },
- {
- title: '视频播放',
- icon: [
- 'arrows-alt',
- 'backward',
- 'compress',
- 'eject',
- 'expand',
- 'fast-backward',
- 'fast-forward',
- 'forward',
- 'pause',
- 'pause-circle',
- 'pause-circle-o',
- 'play',
- 'play-circle',
- 'play-circle-o',
- 'random',
- 'step-backward',
- 'step-forward',
- 'stop',
- 'stop-circle',
- 'stop-circle-o',
- 'youtube-play'
- ]
- },
- {
- title: '标志',
- icon: [
- '500px',
- 'adn',
- 'amazon',
- 'android',
- 'angellist',
- 'apple',
- 'bandcamp',
- 'behance',
- 'behance-square',
- 'bitbucket',
- 'bitbucket-square',
- 'bitcoin',
- 'black-tie',
- 'bluetooth',
- 'bluetooth-b',
- 'btc',
- 'buysellads',
- 'cc-amex',
- 'cc-diners-club',
- 'cc-discover',
- 'cc-jcb',
- 'cc-mastercard',
- 'cc-paypal',
- 'cc-stripe',
- 'cc-visa',
- 'chrome',
- 'codepen',
- 'codiepie',
- 'connectdevelop',
- 'contao',
- 'css3',
- 'dashcube',
- 'delicious',
- 'deviantart',
- 'digg',
- 'dribbble',
- 'dropbox',
- 'drupal',
- 'edge',
- 'eercast',
- 'empire',
- 'envira',
- 'etsy',
- 'expeditedssl',
- 'fa',
- 'facebook',
- 'facebook-f',
- 'facebook-official',
- 'facebook-square',
- 'firefox',
- 'first-order',
- 'flickr',
- 'font-awesome',
- 'fonticons',
- 'fort-awesome',
- 'forumbee',
- 'foursquare',
- 'free-code-camp',
- 'ge',
- 'get-pocket',
- 'gg',
- 'gg-circle',
- 'git',
- 'git-square',
- 'github',
- 'github-alt',
- 'github-square',
- 'gitlab',
- 'gittip',
- 'glide',
- 'glide-g',
- 'google',
- 'google-plus',
- 'google-plus-circle',
- 'google-plus-official',
- 'google-plus-square',
- 'google-wallet',
- 'gratipay',
- 'grav',
- 'hacker-news',
- 'houzz',
- 'html5',
- 'imdb',
- 'instagram',
- 'internet-explorer',
- 'ioxhost',
- 'joomla',
- 'jsfiddle',
- 'lastfm',
- 'lastfm-square',
- 'leanpub',
- 'linkedin',
- 'linkedin-square',
- 'linode',
- 'linux',
- 'maxcdn',
- 'meanpath',
- 'medium',
- 'meetup',
- 'mixcloud',
- 'modx',
- 'odnoklassniki',
- 'odnoklassniki-square',
- 'opencart',
- 'openid',
- 'opera',
- 'optin-monster',
- 'pagelines',
- 'paypal',
- 'pied-piper',
- 'pied-piper-alt',
- 'pied-piper-pp',
- 'pinterest',
- 'pinterest-p',
- 'pinterest-square',
- 'product-hunt',
- 'qq',
- 'quora',
- 'ra',
- 'ravelry',
- 'rebel',
- 'reddit',
- 'reddit-alien',
- 'reddit-square',
- 'renren',
- 'resistance',
- 'safari',
- 'scribd',
- 'sellsy',
- 'share-alt',
- 'share-alt-square',
- 'shirtsinbulk',
- 'simplybuilt',
- 'skyatlas',
- 'skype',
- 'slack',
- 'slideshare',
- 'snapchat',
- 'snapchat-ghost',
- 'snapchat-square',
- 'soundcloud',
- 'spotify',
- 'stack-exchange',
- 'stack-overflow',
- 'steam',
- 'steam-square',
- 'stumbleupon',
- 'stumbleupon-circle',
- 'superpowers',
- 'telegram',
- 'tencent-weibo',
- 'themeisle',
- 'trello',
- 'tripadvisor',
- 'tumblr',
- 'tumblr-square',
- 'twitch',
- 'twitter',
- 'twitter-square',
- 'usb',
- 'viacoin',
- 'viadeo',
- 'viadeo-square',
- 'vimeo',
- 'vimeo-square',
- 'vine',
- 'vk',
- 'wechat',
- 'weibo',
- 'weixin',
- 'whatsapp',
- 'wikipedia-w',
- 'windows',
- 'wordpress',
- 'wpbeginner',
- 'wpexplorer',
- 'wpforms',
- 'xing',
- 'xing-square',
- 'y-combinator',
- 'y-combinator-square',
- 'yahoo',
- 'yc',
- 'yc-square',
- 'yelp',
- 'yoast',
- 'youtube',
- 'youtube-play',
- 'youtube-square'
- ]
- },
- {
- title: '医疗',
- icon: [
- 'ambulance',
- 'h-square',
- 'heart',
- 'heart-o',
- 'heartbeat',
- 'hospital-o',
- 'medkit',
- 'plus-square',
- 'stethoscope',
- 'user-md',
- 'wheelchair',
- 'wheelchair-alt'
- ]
- }
-]
diff --git a/src/views/demo/components/icon/icon-svg.vue b/src/views/demo/components/icon/icon-svg.vue
deleted file mode 100644
index f55091cd..00000000
--- a/src/views/demo/components/icon/icon-svg.vue
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
- SVG图标组件
-
-
-
-
- {{icon}}
-
-
-
-
-
-
-
diff --git a/src/views/demo/components/icon/icon.vue b/src/views/demo/components/icon/icon.vue
deleted file mode 100644
index ba4eb5c7..00000000
--- a/src/views/demo/components/icon/icon.vue
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
- 图标组件
-
-
-
-
-
-
-
-
diff --git a/src/views/demo/components/icon/list.vue b/src/views/demo/components/icon/list.vue
deleted file mode 100644
index df9ed473..00000000
--- a/src/views/demo/components/icon/list.vue
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
-
-
- {{item.label}}
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/views/demo/components/icon/select-svg.vue b/src/views/demo/components/icon/select-svg.vue
deleted file mode 100644
index 6c3ecd76..00000000
--- a/src/views/demo/components/icon/select-svg.vue
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
- svg 图标选择器
-
-
一般用法 | {{icon || '未选择'}}
-
-
-
-
用户可以输入 | {{icon2 || '未选择'}}
-
-
-
-
-
-
diff --git a/src/views/demo/components/icon/select.vue b/src/views/demo/components/icon/select.vue
deleted file mode 100644
index 138c4e9d..00000000
--- a/src/views/demo/components/icon/select.vue
+++ /dev/null
@@ -1,56 +0,0 @@
-
-
- 图标选择器
-
-
一般用法
-
-
- 选择的图标 {{icon}}
-
-
- 未选择
-
-
-
-
-
用户可以输入
-
-
- 选择的图标 {{icon2}}
-
-
- 未选择
-
-
-
-
-
-
-
-
-
diff --git a/src/views/demo/components/index/index.vue b/src/views/demo/components/index/index.vue
deleted file mode 100644
index 62126807..00000000
--- a/src/views/demo/components/index/index.vue
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/src/views/demo/components/json-tree/index.vue b/src/views/demo/components/json-tree/index.vue
deleted file mode 100644
index cd9c16d8..00000000
--- a/src/views/demo/components/json-tree/index.vue
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
-
-
-
diff --git a/src/views/demo/components/layout/grid.vue b/src/views/demo/components/layout/grid.vue
deleted file mode 100644
index 875aa7bb..00000000
--- a/src/views/demo/components/layout/grid.vue
+++ /dev/null
@@ -1,122 +0,0 @@
-
-
-
-
-
- Card {{item.i}}
-
- 拖拽卡片调整位置
- 拖拽卡片右下角的手柄调整卡片大小
- 在控制台打印出数据变化
-
-
-
-
-
-
-
-
-
-
diff --git a/src/views/demo/components/layout/splitpane.vue b/src/views/demo/components/layout/splitpane.vue
deleted file mode 100644
index eb07a75c..00000000
--- a/src/views/demo/components/layout/splitpane.vue
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
- 区域划分
-
-
- 左
-
-
- 右上
- 右下
-
-
-
-
-
-
-
-
diff --git a/src/views/demo/components/markdown/md/doc.md b/src/views/demo/components/markdown/md/doc.md
deleted file mode 100644
index 189e9773..00000000
--- a/src/views/demo/components/markdown/md/doc.md
+++ /dev/null
@@ -1,38 +0,0 @@
-# 一级标题
-
-| ID | Name | Email |
-| --- | --- | --- |
-| 0001 | FairyEver | 1711467488@qq.com |
-
-```
-// 注释
-[].forEach.call($$("*"), a => {
- a.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16)
-})
-```
-
-```
-
-```
-
-```
-body {
- background-color: #333;
-}
-```
-
-一般引用
-
-> 引用文字
-
-分享一个我很早前的一副设计作品 [in Lofter](http://fairyever.lofter.com/post/16ff00_6796fe8) 借此演示百度云链接的显示优化
-
-> https://pan.baidu.com/s/1kW6uUwB
-
-设计源文件
-
-> 链接: https://pan.baidu.com/s/1ggFW21l 密码: 877y
-
-[https://github.com/d2-projects](https://github.com/d2-projects)
\ No newline at end of file
diff --git a/src/views/demo/components/markdown/source.vue b/src/views/demo/components/markdown/source.vue
deleted file mode 100644
index 0a4bda98..00000000
--- a/src/views/demo/components/markdown/source.vue
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
- 指定资源
-
-
-
-
-
diff --git a/src/views/demo/components/markdown/url.vue b/src/views/demo/components/markdown/url.vue
deleted file mode 100644
index 49461394..00000000
--- a/src/views/demo/components/markdown/url.vue
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
- 异步加载文件
-
-
-
diff --git a/src/views/demo/playground/add-routes/alternates/1.vue b/src/views/demo/playground/add-routes/alternates/1.vue
deleted file mode 100644
index f99165a0..00000000
--- a/src/views/demo/playground/add-routes/alternates/1.vue
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
- src/views/demo/playground/add-routes/alternates/1.vue
-
-
diff --git a/src/views/demo/playground/add-routes/alternates/2.vue b/src/views/demo/playground/add-routes/alternates/2.vue
deleted file mode 100644
index e03c9f47..00000000
--- a/src/views/demo/playground/add-routes/alternates/2.vue
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
- src/views/demo/playground/add-routes/alternates/2.vue
-
-
diff --git a/src/views/demo/playground/add-routes/alternates/3.vue b/src/views/demo/playground/add-routes/alternates/3.vue
deleted file mode 100644
index 47670bc1..00000000
--- a/src/views/demo/playground/add-routes/alternates/3.vue
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
- src/views/demo/playground/add-routes/alternates/3.vue
-
-
diff --git a/src/views/demo/playground/add-routes/routes.vue b/src/views/demo/playground/add-routes/routes.vue
deleted file mode 100644
index 1f18e316..00000000
--- a/src/views/demo/playground/add-routes/routes.vue
+++ /dev/null
@@ -1,109 +0,0 @@
-
-
-
-
-
-
-
-
- {{item.title}}
-
-
-
-
-
-
-
-
diff --git a/src/views/demo/playground/db/all/index.vue b/src/views/demo/playground/db/all/index.vue
deleted file mode 100644
index d5722d1d..00000000
--- a/src/views/demo/playground/db/all/index.vue
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
- 重新获取本地数据
-
-
-
-
-
diff --git a/src/views/demo/playground/db/page-public/index.vue b/src/views/demo/playground/db/page-public/index.vue
deleted file mode 100644
index 69c8f1b5..00000000
--- a/src/views/demo/playground/db/page-public/index.vue
+++ /dev/null
@@ -1,127 +0,0 @@
-
-
-
-
-
-
-
- 增加不重复字段
- 增加
- 增加自定义字段
-
-
- 增加
- 删除字段
-
-
-
-
- 清空当前用户数据
- 清空
-
-
-
-
-
-
-
-
-
diff --git a/src/views/demo/playground/db/page-snapshot-public/index.vue b/src/views/demo/playground/db/page-snapshot-public/index.vue
deleted file mode 100644
index 48a5c337..00000000
--- a/src/views/demo/playground/db/page-snapshot-public/index.vue
+++ /dev/null
@@ -1,114 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 立即创建
- 取消
-
-
-
-
- 删除当前页面快照
-
-
-
-
-
diff --git a/src/views/demo/playground/db/page-snapshot-user/index.vue b/src/views/demo/playground/db/page-snapshot-user/index.vue
deleted file mode 100644
index d59dc958..00000000
--- a/src/views/demo/playground/db/page-snapshot-user/index.vue
+++ /dev/null
@@ -1,114 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 立即创建
- 取消
-
-
-
-
- 删除当前页面快照
-
-
-
-
-
diff --git a/src/views/demo/playground/db/page-user/index.vue b/src/views/demo/playground/db/page-user/index.vue
deleted file mode 100644
index 0283872d..00000000
--- a/src/views/demo/playground/db/page-user/index.vue
+++ /dev/null
@@ -1,139 +0,0 @@
-
-
-
-
-
-
-
- 增加不重复字段
- 增加
- 增加自定义字段
-
-
- 增加
- 删除字段
-
-
-
-
- 清空当前用户数据
- 清空
-
-
-
-
-
-
-
-
-
diff --git a/src/views/demo/playground/db/public/index.vue b/src/views/demo/playground/db/public/index.vue
deleted file mode 100644
index 576b7ea5..00000000
--- a/src/views/demo/playground/db/public/index.vue
+++ /dev/null
@@ -1,123 +0,0 @@
-
-
-
-
-
-
-
- 增加不重复字段
- 增加
- 增加自定义字段
-
-
- 增加
- 删除字段
-
-
-
-
- 清空当前用户数据
- 清空
-
-
-
-
-
-
-
-
-
diff --git a/src/views/demo/playground/db/user/index.vue b/src/views/demo/playground/db/user/index.vue
deleted file mode 100644
index bd523433..00000000
--- a/src/views/demo/playground/db/user/index.vue
+++ /dev/null
@@ -1,125 +0,0 @@
-
-
-
-
-
-
-
- 增加不重复字段
- 增加
- 增加自定义字段
-
-
- 增加
- 删除字段
-
-
-
-
- 清空当前用户数据
- 清空
-
-
-
-
-
-
-
-
-
diff --git a/src/views/demo/playground/env/index.vue b/src/views/demo/playground/env/index.vue
deleted file mode 100644
index 66bb400a..00000000
--- a/src/views/demo/playground/env/index.vue
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
- process.env
-
-
-
-
-
diff --git a/src/views/demo/playground/frame/d2-doc/index.vue b/src/views/demo/playground/frame/d2-doc/index.vue
deleted file mode 100644
index 82e9b26b..00000000
--- a/src/views/demo/playground/frame/d2-doc/index.vue
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/src/views/demo/playground/frame/html/index.vue b/src/views/demo/playground/frame/html/index.vue
deleted file mode 100644
index 8c4bafc9..00000000
--- a/src/views/demo/playground/frame/html/index.vue
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/src/views/demo/playground/frame/report/index.vue b/src/views/demo/playground/frame/report/index.vue
deleted file mode 100644
index d1867ff6..00000000
--- a/src/views/demo/playground/frame/report/index.vue
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/src/views/demo/playground/index/index.vue b/src/views/demo/playground/index/index.vue
deleted file mode 100644
index 204fddf1..00000000
--- a/src/views/demo/playground/index/index.vue
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/src/views/demo/playground/locales/index.vue b/src/views/demo/playground/locales/index.vue
deleted file mode 100644
index d7da8fe5..00000000
--- a/src/views/demo/playground/locales/index.vue
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
- {{ language.label }}
-
-
-
-
-
-
-
-
diff --git a/src/views/demo/playground/log/ajax/index.vue b/src/views/demo/playground/log/ajax/index.vue
deleted file mode 100644
index 1e3fd621..00000000
--- a/src/views/demo/playground/log/ajax/index.vue
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
- Ajax 错误
- 请打开浏览器控制台,然后点击下面的按钮,尝试访问一个不存在的网络地址
- 请求错误的地址
- 此错误已经被记录在日志页面,并在页面右上"日志按钮"区域显示提示信息
-
-
-
-
diff --git a/src/views/demo/playground/log/console/image/demo.png b/src/views/demo/playground/log/console/image/demo.png
deleted file mode 100644
index 35a5c716..00000000
Binary files a/src/views/demo/playground/log/console/image/demo.png and /dev/null differ
diff --git a/src/views/demo/playground/log/console/index.vue b/src/views/demo/playground/log/console/index.vue
deleted file mode 100644
index d23b74ad..00000000
--- a/src/views/demo/playground/log/console/index.vue
+++ /dev/null
@@ -1,67 +0,0 @@
-
-
- $log.capsule
-
- $log.capsule('title', 'primary')
-
-
- $log.capsule('title', 'success', 'success')
-
-
- $log.capsule('title', 'warning', 'warning')
-
-
- $log.capsule('title', 'danger', 'danger')
-
- $log.colorful
-
- colorful
-
- $log.default | primary | success | warning | danger
-
- $log.default('default style')
-
-
- $log.primary('primary style')
-
-
- $log.success('success style')
-
-
- $log.warning('warning style')
-
-
- $log.danger('danger style')
-
- 效果 ( Chrome )
-
-
-
-
-
-
-
diff --git a/src/views/demo/playground/log/error/index.vue b/src/views/demo/playground/log/error/index.vue
deleted file mode 100644
index 383c3acb..00000000
--- a/src/views/demo/playground/log/error/index.vue
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
- 捕获错误信息
- 请打开浏览器控制台,然后点击下面的按钮
- 触发一个错误
- 此错误已经被记录在日志页面,并在页面右上"日志按钮"区域显示提示信息
-
-
-
-
diff --git a/src/views/demo/playground/log/log/index.vue b/src/views/demo/playground/log/log/index.vue
deleted file mode 100644
index 04f14e43..00000000
--- a/src/views/demo/playground/log/log/index.vue
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
- 记录日志内容
- 在下方输入你要记录的日志,然后点击记录按钮
-
- 记录
- 此信息已经被记录在日志页面,并在页面右上"日志按钮"区域显示提示信息
-
-
-
-
diff --git a/src/views/demo/playground/page-argu/get.vue b/src/views/demo/playground/page-argu/get.vue
deleted file mode 100644
index 4e49d6d5..00000000
--- a/src/views/demo/playground/page-argu/get.vue
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
- $route.params.username: {{$route.params.username}}
- $route.query.userid: {{$route.query.userid}}
- 你可以尝试返回发送数据页面修改数据重新发送,或者切换到其它页面后刷新浏览器再返回本业观察参数保留
- 返回发送数据的页面
-
-
-
-
diff --git a/src/views/demo/playground/page-argu/send.vue b/src/views/demo/playground/page-argu/send.vue
deleted file mode 100644
index 4bd55e79..00000000
--- a/src/views/demo/playground/page-argu/send.vue
+++ /dev/null
@@ -1,55 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- 跳转到接收页面
-
-
-
-
-
-
diff --git a/src/views/demo/playground/page-cache/off.vue b/src/views/demo/playground/page-cache/off.vue
deleted file mode 100644
index 03d19b81..00000000
--- a/src/views/demo/playground/page-cache/off.vue
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
- 这个页面不会被 keep-alive
- 在下面的输入框输入任意字符后,切换到其它页面,再回到此页时输入框文字消失,证明没有被缓存
-
-
-
-
-
diff --git a/src/views/demo/playground/page-cache/on.vue b/src/views/demo/playground/page-cache/on.vue
deleted file mode 100644
index 972dfe93..00000000
--- a/src/views/demo/playground/page-cache/on.vue
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
- 这个页面会被 keep-alive
- 在下面的输入框输入任意字符后,切换到其它页面,再回到此页时输入框文字保留,证明被缓存
-
-
-
-
-
diff --git a/src/views/demo/playground/page-cache/params.vue b/src/views/demo/playground/page-cache/params.vue
deleted file mode 100644
index ddd44f9f..00000000
--- a/src/views/demo/playground/page-cache/params.vue
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
-
- props.id = {{id}}
-
-
- 在下面的输入框输入任意字符后,切换到其它页面,再回到此页时输入框文字保留,证明被缓存
- 注意:此页面根据不同 params 打开后数据不会混淆
-
-
- el-input
-
-
-
- html input
-
-
-
-
-
-
-
-
-
diff --git a/src/views/demo/playground/store/fullscreen/index.vue b/src/views/demo/playground/store/fullscreen/index.vue
deleted file mode 100644
index a8b59b77..00000000
--- a/src/views/demo/playground/store/fullscreen/index.vue
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
- 全屏
-
- toggle 切换全屏
-
-
-
-
-
diff --git a/src/views/demo/playground/store/gray/index.vue b/src/views/demo/playground/store/gray/index.vue
deleted file mode 100644
index 04285eab..00000000
--- a/src/views/demo/playground/store/gray/index.vue
+++ /dev/null
@@ -1,87 +0,0 @@
-
-
-
- {{grayActive ? 'GRAY' : 'COLORFUL'}}
-
-
- 切换灰度模式
- 打开灰度模式
- 关闭灰度模式
- 模拟报错提示框
-
-
-
- Error
-
-
-
-
-
-
-
-
-
diff --git a/src/views/demo/playground/store/menu/index.vue b/src/views/demo/playground/store/menu/index.vue
deleted file mode 100644
index c447dd28..00000000
--- a/src/views/demo/playground/store/menu/index.vue
+++ /dev/null
@@ -1,148 +0,0 @@
-
-
-
-
-
- 设置顶栏空菜单
- 恢复顶栏菜单
-
-
-
-
-
- 设置侧栏空菜单
- 恢复侧栏菜单
- {{`${asideTransition ? '关闭' : '开启'}侧栏动画效果`}}
-
-
-
-
-
-
-
-
diff --git a/src/views/demo/playground/store/page/index.vue b/src/views/demo/playground/store/page/index.vue
deleted file mode 100644
index 591344cc..00000000
--- a/src/views/demo/playground/store/page/index.vue
+++ /dev/null
@@ -1,98 +0,0 @@
-
-
-
- 在下面的输入框输入任意字符后,切换到其它页面,再回到此页时输入框文字保留,证明被缓存
-
-
- 关闭标签页
-
-
- 当前
-
-
- 左侧
-
-
- 右侧
-
-
- 其它
-
-
- 全部
-
-
- 刷新
-
-
-
- 清空当前页缓存并刷新
-
-
-
- 清空所有缓存并刷新
-
-
-
-
-
-
diff --git a/src/views/demo/playground/store/size/index.vue b/src/views/demo/playground/store/size/index.vue
deleted file mode 100644
index ab853410..00000000
--- a/src/views/demo/playground/store/size/index.vue
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/views/demo/playground/store/theme/index.vue b/src/views/demo/playground/store/theme/index.vue
deleted file mode 100644
index 672513ae..00000000
--- a/src/views/demo/playground/store/theme/index.vue
+++ /dev/null
@@ -1,74 +0,0 @@
-
-
- 主题
-
-
-
-
-
-
-
-
- 已激活
- 使用
-
-
-
-
-
尝试激活一个不存在的主题(主题不存在 默认主题)
-
-
- 尝试激活主题 'err-theme'
-
-
-
- 当前激活主题 {{activeName}}
-
-
-
-
-
-
-
diff --git a/src/views/demo/playground/store/transition/index.vue b/src/views/demo/playground/store/transition/index.vue
deleted file mode 100644
index f74f3d42..00000000
--- a/src/views/demo/playground/store/transition/index.vue
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
- 当前状态 {{active ? '开启过渡动画' : '关闭过渡动画'}}
-
-
- {{active ? '关闭页面过渡动画' : '打开页面过渡动画'}}
-
-
-
-
-
diff --git a/src/views/demo/playground/store/ua/index.vue b/src/views/demo/playground/store/ua/index.vue
deleted file mode 100644
index 700f15f4..00000000
--- a/src/views/demo/playground/store/ua/index.vue
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
- useragent
-
- 格式化数据 in vuex: state.d2admin.ua.data
-
-
-
-
-
diff --git a/src/views/demo/plugins/clipboard-polyfill/index.vue b/src/views/demo/plugins/clipboard-polyfill/index.vue
deleted file mode 100644
index a9f8f662..00000000
--- a/src/views/demo/plugins/clipboard-polyfill/index.vue
+++ /dev/null
@@ -1,82 +0,0 @@
-
-
- 剪贴板访问
-
-
-
-
- 将左侧输入框内的文字复制进剪贴板
-
- 将 连带样式一起复制进剪贴板,然后去 Word 文档内粘贴
-
-
-
-
-
-
- readText( )
-
-
- read( )
-
-
-
-
-
-
-
-
-
diff --git a/src/views/demo/plugins/day/index.vue b/src/views/demo/plugins/day/index.vue
deleted file mode 100644
index 534bcc57..00000000
--- a/src/views/demo/plugins/day/index.vue
+++ /dev/null
@@ -1,73 +0,0 @@
-
-
- 日期计算
- 解析
-
- {{dayjs()}}
- {{dayjs('1995-12-25')}}
- {{dayjs(1318781876406)}}
- {{dayjs(new Date(2018, 8, 18))}}
- {{dayjs().clone()}}
- {{dayjs().isValid()}}
-
- 获取
-
- {{dayjs().year()}}
- {{dayjs().month()}}
- {{dayjs().date()}}
- {{dayjs().day()}}
- {{dayjs().hour()}}
- {{dayjs().minute()}}
- {{dayjs().second()}}
- {{dayjs().millisecond()}}
-
- 设置
-
- {{dayjs().set('month', 6).month()}}
- {{dayjs().set('second', 30).second()}}
- {{dayjs().set('hour', 4).hour()}}
-
- 操作
-
- {{dayjs().add(1, 'day').format('YYYY年M月D日 HH:mm:ss')}}
- {{dayjs().subtract(7, 'year').format('YYYY年M月D日 HH:mm:ss')}}
- {{dayjs().startOf('year').format('YYYY年M月D日 HH:mm:ss')}}
- {{dayjs().endOf('month').format('YYYY年M月D日 HH:mm:ss')}}
-
- 显示
-
- {{dayjs().format('YYYY-M-D HH:mm:ss')}}
- {{dayjs().diff(dayjs().subtract(1, 'day'), 'days')}}
- {{dayjs().valueOf()}}
- {{dayjs().unix()}}
- {{dayjs().daysInMonth()}}
- {{dayjs().toDate()}}
-
- {{dayjs().toJSON()}}
- {{dayjs().toISOString()}}
- {{dayjs().toString()}}
-
-
- 查询
-
- {{dayjs().isBefore(dayjs().add(1, 'day'))}}
- {{dayjs().isBefore(dayjs().subtract(1, 'day'))}}
- {{dayjs().isSame(dayjs())}}
- {{dayjs().isSame(dayjs().add(1, 'day'))}}
- {{dayjs().isAfter(dayjs().add(1, 'day'))}}
- {{dayjs().isAfter(dayjs().subtract(1, 'day'))}}
-
-
-
-
-
-
diff --git a/src/views/demo/plugins/export/table.vue b/src/views/demo/plugins/export/table.vue
deleted file mode 100644
index 4757fe73..00000000
--- a/src/views/demo/plugins/export/table.vue
+++ /dev/null
@@ -1,72 +0,0 @@
-
-
- 导出表格
-
-
-
- 导出 CSV
-
-
-
- 导出 Excel
-
-
-
-
-
-
-
-
-
-
diff --git a/src/views/demo/plugins/export/txt.vue b/src/views/demo/plugins/export/txt.vue
deleted file mode 100644
index a06c15cf..00000000
--- a/src/views/demo/plugins/export/txt.vue
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
- 导出文本
-
-
-
-
-
- 保存为 txt
-
-
-
-
-
-
diff --git a/src/views/demo/plugins/import/csv.vue b/src/views/demo/plugins/import/csv.vue
deleted file mode 100644
index 2e3c09f8..00000000
--- a/src/views/demo/plugins/import/csv.vue
+++ /dev/null
@@ -1,62 +0,0 @@
-
-
-
-
-
- 下载演示 .csv 表格
-
-
-
-
-
-
- 选择要导入的 .csv 表格
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/views/demo/plugins/import/xlsx.vue b/src/views/demo/plugins/import/xlsx.vue
deleted file mode 100644
index 97cbfb18..00000000
--- a/src/views/demo/plugins/import/xlsx.vue
+++ /dev/null
@@ -1,64 +0,0 @@
-
-
-
-
-
- 下载演示 .xlsx 表格
-
-
-
-
-
-
- 选择要导入的 .xlsx 表格
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/views/demo/plugins/index/index.vue b/src/views/demo/plugins/index/index.vue
deleted file mode 100644
index 97b4dba1..00000000
--- a/src/views/demo/plugins/index/index.vue
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/src/views/demo/plugins/js-cookie/index.vue b/src/views/demo/plugins/js-cookie/index.vue
deleted file mode 100644
index a1db081f..00000000
--- a/src/views/demo/plugins/js-cookie/index.vue
+++ /dev/null
@@ -1,54 +0,0 @@
-
-
-
- Cookie 读写
-
-
-
- 基本读写删
- set('demo-user-name', 'normalValue')
- get('demo-user-name')
- remove('demo-user-name')
- 设置有效期
- 设置 'demo-user-pwd' 有效期为一天
- get('demo-user-pwd')
- remove('demo-user-pwd')
- 获取所有可以获得的数据
- getAll
-
-
-
-