Compare commits
132 Commits
Author | SHA1 | Date |
---|---|---|
花裤衩 | ab97bc2259 | |
花裤衩 | fce7214967 | |
花裤衩 | 097ff8d91f | |
花裤衩 | 347791f319 | |
Kerollos Magdy | e7da4ea532 | |
dyz | 0d04d543a7 | |
crayymumu | c63755f4ca | |
花裤衩 | 3782a9f332 | |
花裤衩 | f55dd06f5a | |
Dihak | 81a14524d1 | |
花裤衩 | 0bb3b38fcf | |
花裤衩 | f321343f09 | |
qige2016 | 215ff05bd1 | |
花裤衩 | 8c89992c6c | |
花裤衩 | bee999f291 | |
花裤衩 | e9419b6277 | |
Silentdoer | 07dec8ff47 | |
MaYuanhai | 8132ad106e | |
Cat73 | e001dab7e0 | |
花裤衩 | 6831120a83 | |
花裤衩 | e773715767 | |
花裤衩 | 9975a7a938 | |
花裤衩 | 9d0bcf44cf | |
花裤衩 | 41c210e829 | |
Cat73 | 9b7e60c16b | |
花裤衩 | 11e6e065d0 | |
Edwin Betancourt | 0e194fea76 | |
Nickbing Lao | 7dc2c977a0 | |
cooper | 2ed1951355 | |
AiMe1991 | b8c934c81a | |
花裤衩 | fe72cae1e5 | |
garethx | d17cfd067a | |
花裤衩 | 4fedd2e8d8 | |
ntnyq | 5c6ddaad38 | |
Aisen | 2ffff40bfd | |
花裤衩 | c6266ea396 | |
Alex S | e29e5838bd | |
花裤衩 | 2975c4181a | |
花裤衩 | cd404bc128 | |
花裤衩 | 348e1bbafd | |
echofly | 43629c09c3 | |
Aisen60 | 4597711d9d | |
echofly | f788d681e6 | |
花裤衩 | 8ad5c90f8f | |
Shota Aratono | 11bcb43326 | |
RoBlues | 4a2401b574 | |
李小斐 | dc4832ad5b | |
MaYuanhai | 39b2b9b872 | |
花裤衩 | 255989138d | |
花裤衩 | a6bb84b763 | |
花裤衩 | 025d5e46a2 | |
花裤衩 | 95561d4977 | |
RussXD | ea27da43b7 | |
AndyLZC/AndyLZC.github.io | 93e01926e3 | |
Kaitian Xie | be18a69fa4 | |
任羽飞 | 1d707e4ab6 | |
韬 | 4339504db2 | |
花裤衩 | c656f2ed00 | |
flitrue | 230575a6fd | |
monkeycf | ded67b054a | |
xuanzai | ad444fe3ae | |
Phạm Ngọc Hòa | b2f8373a5b | |
Phạm Ngọc Hòa | b70cc183d6 | |
bbigcd | dbc41b5275 | |
Phạm Ngọc Hòa | 44f8f39465 | |
Phạm Ngọc Hòa | a4d4bc8a3e | |
Phạm Ngọc Hòa | 92a3e2da45 | |
Phạm Ngọc Hòa | 1e6aab3970 | |
Phạm Ngọc Hòa | daec48bbbe | |
花裤衩 | 1f0ac624fc | |
BradyBromley | d957bc1f4a | |
花裤衩 | 45d72a6ef5 | |
花裤衩 | fb2c852a0c | |
花裤衩 | ae92d6f95e | |
花裤衩 | f5608a7511 | |
MaYuanhai | ce667850cf | |
花裤衩 | b7c032b509 | |
花裤衩 | a3137fb6cb | |
花裤衩 | 50dcb90b53 | |
monkeycf | ed0b023767 | |
monkeycf | 137c1c3eff | |
花裤衩 | d571715c3d | |
花裤衩 | 4342032fb9 | |
MaYuanhai | 159e21c56b | |
Serge | e4f2b1e587 | |
Francis | 6c05e7ddb9 | |
MaYuanhai | 1a83a40106 | |
花裤衩 | 1602577733 | |
Baskerville* | d747879195 | |
花裤衩 | c4b9090b0b | |
why | 7be0bd5751 | |
Pan | 9ff40abd74 | |
itsccn | 6a89136805 | |
Pan | 5d12cbd75c | |
MaYuanhai | acbbc5f52d | |
TinaryTree | e216e11618 | |
MaYuanhai | cafdbf41f2 | |
肖敏 | a9e21c2ce2 | |
Jessynt | 921cdab858 | |
MaYuanhai | 440b5c6596 | |
Pan | 884587cccf | |
Pan | 00c853c54d | |
Serge | 686b1d37fd | |
花裤衩 | 6f45fd987d | |
花裤衩 | f1bc06b082 | |
bpzhang | 786d9662fb | |
Pan | e945c29a3c | |
花裤衩 | 3058cfefcb | |
花裤衩 | 4413d3383f | |
花裤衩 | caf7614ab2 | |
Pan | 52f56ee55f | |
Pan | 5b1b05b18e | |
花裤衩 | cf1f40ddad | |
Pan | bd81477202 | |
花裤衩 | a582eec089 | |
Yamel Senih | c85ce21951 | |
花裤衩 | fa23feeed4 | |
花裤衩 | cdf3ea06c7 | |
花裤衩 | 73babc4880 | |
liugq | cc7554f386 | |
Pan | 4f9efc8ea4 | |
Yamel Senih | 71ece14be1 | |
Yamel Senih | d897df5e2b | |
Pan | 5f536fdfc4 | |
Pan | b6aa00d5de | |
Pan | 3281d16131 | |
Pan | 504c06f648 | |
Pan | 63f8635538 | |
Pan | ad689e3f96 | |
花裤衩 | 6c8d7a164f | |
Pan | 6346ab3d80 | |
Pan | 818b565658 |
|
@ -3,12 +3,3 @@ ENV = 'development'
|
||||||
|
|
||||||
# base api
|
# base api
|
||||||
VUE_APP_BASE_API = '/dev-api'
|
VUE_APP_BASE_API = '/dev-api'
|
||||||
|
|
||||||
# vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable,
|
|
||||||
# to control whether the babel-plugin-dynamic-import-node plugin is enabled.
|
|
||||||
# It only does one thing by converting all import() to require().
|
|
||||||
# This configuration can significantly increase the speed of hot updates,
|
|
||||||
# when you have a large number of pages.
|
|
||||||
# Detail: https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/babel-preset-app/index.js
|
|
||||||
|
|
||||||
VUE_CLI_BABEL_TRANSPILE_MODULES = true
|
|
||||||
|
|
36
README.es.md
36
README.es.md
|
@ -51,51 +51,61 @@ Vue Element Admin es una solución práctica basada en la nueva plataforma de de
|
||||||
- Plantilla de Typescript: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (Créditos: [@Armour](https://github.com/Armour))
|
- Plantilla de Typescript: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (Créditos: [@Armour](https://github.com/Armour))
|
||||||
- [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312)
|
- [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312)
|
||||||
|
|
||||||
**Después de la versión `v4.1.0+`, la rama por defecto master no tendrá soporte para i18n. Por favor use [i18n](https://github.com/PanJiaChen/vue-element-admin/tree/i18n), los cambios serán incluidos en la rama master**
|
**Después de la versión `v4.1.0+`, la rama por defecto master no tendrá soporte para i18n. Por favor utilice la rama [i18n](https://github.com/PanJiaChen/vue-element-admin/tree/i18n), los cambios serán incluidos en la rama master**
|
||||||
|
|
||||||
**la versión actual es `v4.0+` construida con `vue-cli`. Si encuentra algún problema, por favor coloque un [issue](https://github.com/PanJiaChen/vue-element-admin/issues/new). Si desea usar la versión anterior, puede cambiar de rama a [tag/3.11.0](https://github.com/PanJiaChen/vue-element-admin/tree/tag/3.11.0), no relacionado con `vue-cli`**
|
**la versión actual es `v4.0+` construida con `vue-cli`. Si encuentra algún problema, por favor coloque un [issue](https://github.com/PanJiaChen/vue-element-admin/issues/new). Si desea usar la versión anterior, puede cambiar de rama a [tag/3.11.0](https://github.com/PanJiaChen/vue-element-admin/tree/tag/3.11.0), no relacionado con `vue-cli`**
|
||||||
|
|
||||||
**Este proyecto no está soportado para versiones muy viejas de navegadores (e.g. IE).**
|
**Este proyecto no está soportado para versiones antigüas de navegadores (ej. IE).**
|
||||||
|
|
||||||
## Preparación
|
## Preparación
|
||||||
|
|
||||||
Necesita instalar [node](https://nodejs.org/) y [git](https://git-scm.com/) localmente. El proyecto es basado en [ES2015+](https://es6.ruanyifeng.com/), [vue](https://cn.vuejs.org/index.html), [vuex](https://vuex.vuejs.org/zh-cn/), [vue-router](https://router.vuejs.org/zh-cn/), [vue-cli](https://github.com/vuejs/vue-cli) , [axios](https://github.com/axios/axios) and [element-ui](https://github.com/ElemeFE/element), toda la solicitud de datos simulada se realiza a través de [Mock.js](https://github.com/nuysoft/Mock).
|
Necesita instalar [node](https://nodejs.org/) y [git](https://git-scm.com/) localmente. El proyecto es basado en [ES2015+](https://es6.ruanyifeng.com/), [vue](https://cn.vuejs.org/index.html), [vuex](https://vuex.vuejs.org/zh-cn/), [vue-router](https://router.vuejs.org/zh-cn/), [vue-cli](https://github.com/vuejs/vue-cli) , [axios](https://github.com/axios/axios) and [element-ui](https://github.com/ElemeFE/element), toda la solicitud de datos simulada se realiza a través de [Mock.js](https://github.com/nuysoft/Mock).
|
||||||
Entendiendo y aprendiendo esto pudiera ayudarle con su proyecto.
|
Entendiendo y aprendiendo esto pudiera ayudarle con su proyecto.
|
||||||
|
|
||||||
<p align="center">
|
[![Edit on CodeSandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/PanJiaChen/vue-element-admin/tree/CodeSandbox)
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
<img width="900" src="https://wpimg.wallstcn.com/a5894c1b-f6af-456e-82df-1151da0839bf.png">
|
<img width="900" src="https://wpimg.wallstcn.com/a5894c1b-f6af-456e-82df-1151da0839bf.png">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
## Patrocinantes
|
## Patrocinantes
|
||||||
|
|
||||||
Se un patrocinante y pon tu logo en nuestro README on GitHub con un enlace directo a tu sitio web. [[Se un Patrocinante]](https://www.patreon.com/panjiachen)
|
Sea un patrocinante y coloque su logo en nuestro LEEME en GitHub con un enlace directo a su sitio web. [[Se un Patrocinante]](https://www.patreon.com/panjiachen)
|
||||||
|
|
||||||
<a href="https://flatlogic.com/admin-dashboards?from=vue-element-admin"><img width="150px" src="https://wpimg.wallstcn.com/9c0b719b-5551-4c1e-b776-63994632d94a.png" /></a><p>Plantilla de Dashboard de administración hecha con Vue, React y Angular.</p>
|
### Akveo
|
||||||
|
<a href="https://store.akveo.com/products/vue-java-admin-dashboard-spring?utm_campaign=akveo_store-Vue-Vue_demo%2Fgithub&utm_source=vue_admin&utm_medium=referral&utm_content=github_banner"><img width="500px" src="https://raw.githubusercontent.com/PanJiaChen/vue-element-admin-site/master/docs/.vuepress/public/images/vue-java-banner.png" /></a><p>Java backend integration</p>
|
||||||
|
|
||||||
|
### Flatlogic
|
||||||
|
|
||||||
|
<a href="https://flatlogic.com/admin-dashboards?from=vue-element-admin"><img width="150px" src="https://wpimg.wallstcn.com/9c0b719b-5551-4c1e-b776-63994632d94a.png" /></a><p>Admin Dashboard Templates made with Vue, React and Angular.</p>
|
||||||
|
|
||||||
## Características
|
## Características
|
||||||
|
|
||||||
```
|
```
|
||||||
- Iniciar / Cerrar Sesión
|
- Iniciar / Cerrar Sesión
|
||||||
|
|
||||||
- Permisos de Authentication
|
- Permisos de Autenticación
|
||||||
- Página de Permisos
|
- Página de Permisos
|
||||||
- Directivas de permisos
|
- Directivas de permisos
|
||||||
- Página de configuración de permisos
|
- Página de configuración de permisos
|
||||||
- Autenticación por dos pasos
|
- Autenticación por dos pasos
|
||||||
|
|
||||||
- Construcción Multi-entorno
|
- Construcción Multi-entorno
|
||||||
- dev sit stage producción
|
- Desarrollo (dev)
|
||||||
|
- sit
|
||||||
|
- Escenario de pruebas (stage),
|
||||||
|
- Producción (prod)
|
||||||
|
|
||||||
- Características Globales
|
- Características Globales
|
||||||
- I18n
|
- I18n
|
||||||
- Temas dinámicos
|
- Temas dinámicos
|
||||||
- Dynamic sidebar (soporte a rutas multi-nivel)
|
- Menu lateral dinámico (soporte a rutas multi-nivel)
|
||||||
- Barra de rutas dinámica
|
- Barra de rutas dinámica
|
||||||
- Tags-view (Tab page Support right-click operation)
|
- Tags-view (Pestañas de página, Soporta operación de clic derecho)
|
||||||
- Svg Sprite
|
- Svg Sprite
|
||||||
- Datos de simulación con Mock
|
- Datos de simulación con Mock
|
||||||
- Pantalla completa
|
- Pantalla completa
|
||||||
- Responsive Sidebar
|
- Menu lateral responsivo
|
||||||
|
|
||||||
- Editor
|
- Editor
|
||||||
- Editor de Texto Enriquecido
|
- Editor de Texto Enriquecido
|
||||||
|
@ -106,7 +116,7 @@ Se un patrocinante y pon tu logo en nuestro README on GitHub con un enlace direc
|
||||||
- Exportación a Excel
|
- Exportación a Excel
|
||||||
- Carga de Excel
|
- Carga de Excel
|
||||||
- Visualización de Excel
|
- Visualización de Excel
|
||||||
- Exportación como zip
|
- Exportación como ZIP
|
||||||
|
|
||||||
- Tabla
|
- Tabla
|
||||||
- Tabla Dinámica
|
- Tabla Dinámica
|
||||||
|
@ -135,7 +145,7 @@ Se un patrocinante y pon tu logo en nuestro README on GitHub con un enlace direc
|
||||||
- Página de Guías
|
- Página de Guías
|
||||||
- ECharts (Gráficos)
|
- ECharts (Gráficos)
|
||||||
- Portapapeles
|
- Portapapeles
|
||||||
- Convertidor de Markdown a html
|
- Convertidor de Markdown a HTML
|
||||||
```
|
```
|
||||||
|
|
||||||
## Iniciando
|
## Iniciando
|
||||||
|
@ -208,7 +218,7 @@ Navegadores modernos e Internet Explorer 10+.
|
||||||
|
|
||||||
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Safari |
|
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Safari |
|
||||||
| --------- | --------- | --------- | --------- |
|
| --------- | --------- | --------- | --------- |
|
||||||
| IE10, IE11, Edge| últimas 2 versiones| últimas 2 versiones| últimas 2 versiones
|
| IE10, IE11, Edge | últimas 2 versiones | últimas 2 versiones | últimas 2 versiones |
|
||||||
|
|
||||||
## Licencia
|
## Licencia
|
||||||
|
|
||||||
|
|
76
README.ja.md
76
README.ja.md
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
## 概要
|
## 概要
|
||||||
|
|
||||||
[vue-element-admin](https://panjiachen.github.io/vue-element-admin) は管理画面のフロントエンドのインタフェース,[vue](https://github.com/vuejs/vue) と [element-ui](https://github.com/ElemeFE/element)を使っています。i18nの多言語対応、可変ルート、権限、典型的なビジネスアプリテンプレートであり、豊富なコンポーネントを提供しています、素早くビジネス用の管理画面の現型を構築に役立ちます。
|
[vue-element-admin](https://panjiachen.github.io/vue-element-admin) は管理画面のフロントエンドのインタフェースで、[vue](https://github.com/vuejs/vue) と [element-ui](https://github.com/ElemeFE/element)を使っています。i18nの多言語対応、可変ルート、権限、典型的なビジネスアプリテンプレートであり、豊富なコンポーネントを提供しています。素早くビジネス用の管理画面の現型を構築に役立ちます。
|
||||||
|
|
||||||
- [デモページ](https://panjiachen.github.io/vue-element-admin)
|
- [デモページ](https://panjiachen.github.io/vue-element-admin)
|
||||||
|
|
||||||
|
@ -44,22 +44,24 @@
|
||||||
|
|
||||||
- おすすめシンプルテンプレート: [vue-admin-template](https://github.com/PanJiaChen/vue-admin-template)
|
- おすすめシンプルテンプレート: [vue-admin-template](https://github.com/PanJiaChen/vue-admin-template)
|
||||||
- デスクトップバージョン: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
|
- デスクトップバージョン: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
|
||||||
- Typescriptバージョン: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (鸣谢: [@Armour](https://github.com/Armour))
|
- Typescriptバージョン: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (感謝: [@Armour](https://github.com/Armour))
|
||||||
- [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312)
|
- [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312)
|
||||||
|
|
||||||
**After the `v4.1.0+` version, the default master branch will not support i18n. Please use [i18n Branch](https://github.com/PanJiaChen/vue-element-admin/tree/i18n), it will keep up with the master update**
|
**バージョン`v4.1.0+`以降について、デフォルトのmasterブランチではi18nをサポートしていません。masterブランチと共にアップデートされる[i18n Branch](https://github.com/PanJiaChen/vue-element-admin/tree/i18n)を使用してください。 **
|
||||||
|
|
||||||
**現在のバージョン `v4.0+` は `vue-cli` で構築,バグ報告は[issue](https://github.com/PanJiaChen/vue-element-admin/issues/new)のissueでお願いします。旧バージョン[tag/3.11.0](https://github.com/PanJiaChen/vue-element-admin/tree/tag/3.11.0)もあります。`vue-cli`に依存しないです。**
|
**現在のバージョン `v4.0+` は `vue-cli` で構築していて、バグ報告は[issue](https://github.com/PanJiaChen/vue-element-admin/issues/new)のissueでお願いします。旧バージョン[tag/3.11.0](https://github.com/PanJiaChen/vue-element-admin/tree/tag/3.11.0)もあります。こちらは`vue-cli`に依存しないです。**
|
||||||
|
|
||||||
**低いバージョンのブラウザはサーポートしないです(例えば ie),必要があれば polyfill を追加してください。 [詳細はこちら](https://github.com/PanJiaChen/vue-element-admin/wiki#babel-polyfill)**
|
**低いバージョンのブラウザはサーポートしないです(例えば ie),必要があれば polyfill を追加してください。 [詳細はこちら](https://github.com/PanJiaChen/vue-element-admin/wiki#babel-polyfill)**
|
||||||
|
|
||||||
## 前準備
|
## 前準備
|
||||||
|
|
||||||
ローカル環境に [node](http://nodejs.org/) と [git](https://git-scm.com/)をインストールが必要です。[ES2015+](http://es6.ruanyifeng.com/)、[vue](https://cn.vuejs.org/index.html)、[vuex](https://vuex.vuejs.org/zh-cn/)、[vue-router](https://router.vuejs.org/zh-cn/) 、[vue-cli](https://github.com/vuejs/vue-cli) 、[axios](https://github.com/axios/axios) 和 [element-ui](https://github.com/ElemeFE/element)で開発しています。Requestは[Mock.js](https://github.com/nuysoft/Mock)のモックデータを使っています。
|
ローカル環境に [node](http://nodejs.org/) と [git](https://git-scm.com/)のインストールが必要です。[ES2015+](http://es6.ruanyifeng.com/)、[vue](https://cn.vuejs.org/index.html)、[vuex](https://vuex.vuejs.org/zh-cn/)、[vue-router](https://router.vuejs.org/zh-cn/) 、[vue-cli](https://github.com/vuejs/vue-cli) 、[axios](https://github.com/axios/axios) と [element-ui](https://github.com/ElemeFE/element)で開発しています。Requestは[Mock.js](https://github.com/nuysoft/Mock)のモックデータを使っています。
|
||||||
|
|
||||||
**バグ修正や新規機能追加のissue と pull requestは大歓迎です。**
|
**バグ修正や新規機能追加のissue と pull requestは大歓迎です。**
|
||||||
|
|
||||||
<p align="center">
|
[![Edit on CodeSandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/PanJiaChen/vue-element-admin/tree/CodeSandbox)
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
<img width="900" src="https://wpimg.wallstcn.com/a5894c1b-f6af-456e-82df-1151da0839bf.png">
|
<img width="900" src="https://wpimg.wallstcn.com/a5894c1b-f6af-456e-82df-1151da0839bf.png">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -67,6 +69,11 @@
|
||||||
|
|
||||||
Become a sponsor and get your logo on our README on GitHub with a link to your site. [[Become a sponsor]](https://www.patreon.com/panjiachen)
|
Become a sponsor and get your logo on our README on GitHub with a link to your site. [[Become a sponsor]](https://www.patreon.com/panjiachen)
|
||||||
|
|
||||||
|
### Akveo
|
||||||
|
<a href="https://store.akveo.com/products/vue-java-admin-dashboard-spring?utm_campaign=akveo_store-Vue-Vue_demo%2Fgithub&utm_source=vue_admin&utm_medium=referral&utm_content=github_banner"><img width="500px" src="https://raw.githubusercontent.com/PanJiaChen/vue-element-admin-site/master/docs/.vuepress/public/images/vue-java-banner.png" /></a><p>Java backend integration</p>
|
||||||
|
|
||||||
|
### Flatlogic
|
||||||
|
|
||||||
<a href="https://flatlogic.com/admin-dashboards?from=vue-element-admin"><img width="150px" src="https://wpimg.wallstcn.com/9c0b719b-5551-4c1e-b776-63994632d94a.png" /></a><p>Admin Dashboard Templates made with Vue, React and Angular.</p>
|
<a href="https://flatlogic.com/admin-dashboards?from=vue-element-admin"><img width="150px" src="https://wpimg.wallstcn.com/9c0b719b-5551-4c1e-b776-63994632d94a.png" /></a><p>Admin Dashboard Templates made with Vue, React and Angular.</p>
|
||||||
|
|
||||||
## 機能一覧
|
## 機能一覧
|
||||||
|
@ -81,15 +88,18 @@ Become a sponsor and get your logo on our README on GitHub with a link to your s
|
||||||
- 外部IDでログイン
|
- 外部IDでログイン
|
||||||
|
|
||||||
- 複数環境デプロイ
|
- 複数環境デプロイ
|
||||||
- dev sit stage prod
|
- dev
|
||||||
|
- sit
|
||||||
|
- stage
|
||||||
|
- prod
|
||||||
|
|
||||||
- 共通機能
|
- 共通機能
|
||||||
- 多言語切替
|
- 多言語切替
|
||||||
- テーマ切替
|
- テーマ切替
|
||||||
- サイトメニュー(ルートから生成)
|
- サイトメニュー(ルートから生成)
|
||||||
- Breadcrumb Navigation
|
- パンくずリストナビゲーション
|
||||||
- Tag Navigation
|
- タブナビゲーション
|
||||||
- Svg Sprite Icon
|
- Svg Sprite アイコン
|
||||||
- ローカル/バックエンド モック データ
|
- ローカル/バックエンド モック データ
|
||||||
- Screenfull
|
- Screenfull
|
||||||
|
|
||||||
|
@ -104,33 +114,33 @@ Become a sponsor and get your logo on our README on GitHub with a link to your s
|
||||||
- リード
|
- リード
|
||||||
- Zip
|
- Zip
|
||||||
|
|
||||||
- Table
|
- テーブル
|
||||||
- Dynamic Table
|
- ダイナミックテーブル
|
||||||
- Drag And Drop Table
|
- ドラッグアンドドロップテーブル
|
||||||
- Inline Edit Table
|
- インラインエディットテーブル
|
||||||
|
|
||||||
- Error Page
|
- エラーページ
|
||||||
- 401
|
- 401
|
||||||
- 404
|
- 404
|
||||||
|
|
||||||
- コンポーネント
|
- コンポーネント
|
||||||
- Avatar Upload
|
- アバターアップロード
|
||||||
- Back To Top
|
- トップに戻る
|
||||||
- Drag Dialog
|
- ドラッグダイアログ
|
||||||
- Drag Select
|
- ドラッグ選択
|
||||||
- Drag Kanban
|
- ドラッグKanban
|
||||||
- Drag List
|
- ドラッグリスト
|
||||||
- SplitPane
|
- ペインの分割
|
||||||
- Dropzone
|
- Dropzone
|
||||||
- Sticky
|
- スティッキー
|
||||||
- CountTo
|
- CountTo
|
||||||
|
|
||||||
- Advanced Example
|
- 高度なサンプル
|
||||||
- Error Log
|
- エラーログ
|
||||||
- Dashboard
|
- ダッシュボード
|
||||||
- Guide Page
|
- ガイドページ
|
||||||
- ECharts
|
- ECharts
|
||||||
- Clipboard
|
- クリップボード
|
||||||
- Markdown to html
|
- Markdown to html
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -138,7 +148,7 @@ Become a sponsor and get your logo on our README on GitHub with a link to your s
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# clone the project
|
# clone the project
|
||||||
git clone https://github.com/PanJiaChen/vue-element-admin.git
|
git clone -b i18n git@github.com:PanJiaChen/vue-element-admin.git
|
||||||
|
|
||||||
# enter the project directory
|
# enter the project directory
|
||||||
cd vue-element-admin
|
cd vue-element-admin
|
||||||
|
@ -150,7 +160,7 @@ npm install
|
||||||
npm run dev
|
npm run dev
|
||||||
```
|
```
|
||||||
|
|
||||||
This will automatically open http://localhost:9527
|
http://localhost:9527 が自動的に開きます。
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
||||||
|
@ -178,11 +188,11 @@ npm run lint
|
||||||
npm run lint -- --fix
|
npm run lint -- --fix
|
||||||
```
|
```
|
||||||
|
|
||||||
Refer to [Documentation](https://panjiachen.github.io/vue-element-admin-site/guide/essentials/deploy.html) for more information
|
詳細は [Documentation](https://panjiachen.github.io/vue-element-admin-site/guide/essentials/deploy.html) を参照してください。
|
||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
Detailed changes for each release are documented in the [release notes](https://github.com/PanJiaChen/vue-element-admin/releases).
|
各リリースの詳細は [release notes](https://github.com/PanJiaChen/vue-element-admin/releases) にあります。
|
||||||
|
|
||||||
## Online Demo
|
## Online Demo
|
||||||
|
|
||||||
|
@ -204,7 +214,7 @@ Modern browsers and Internet Explorer 10+.
|
||||||
|
|
||||||
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Safari |
|
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Safari |
|
||||||
| --------- | --------- | --------- | --------- |
|
| --------- | --------- | --------- | --------- |
|
||||||
| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
|
| IE10, IE11, Edge | last 2 versions | last 2 versions | last 2 versions |
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|
22
README.md
22
README.md
|
@ -30,9 +30,9 @@ English | [简体中文](./README.zh-CN.md) | [日本語](./README.ja.md) | [Spa
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
[vue-element-admin](https://panjiachen.github.io/vue-element-admin) is a production-ready front-end solution for admin interfaces. It based on [vue](https://github.com/vuejs/vue) and use the UI Toolkit [element-ui](https://github.com/ElemeFE/element).
|
[vue-element-admin](https://panjiachen.github.io/vue-element-admin) is a production-ready front-end solution for admin interfaces. It is based on [vue](https://github.com/vuejs/vue) and uses the UI Toolkit [element-ui](https://github.com/ElemeFE/element).
|
||||||
|
|
||||||
It is a magical vue admin based on the newest development stack of vue, built-in i18n solution, typical templates for enterprise applications, lots of awesome features. It helps you build a large complex Single-Page Applications. I believe whatever your needs are, this project will help you.
|
[vue-element-admin](https://panjiachen.github.io/vue-element-admin) is based on the newest development stack of vue and it has a built-in i18n solution, typical templates for enterprise applications, and lots of awesome features. It helps you build large and complex Single-Page Applications. I believe whatever your needs are, this project will help you.
|
||||||
|
|
||||||
- [Preview](https://panjiachen.github.io/vue-element-admin)
|
- [Preview](https://panjiachen.github.io/vue-element-admin)
|
||||||
|
|
||||||
|
@ -62,7 +62,9 @@ It is a magical vue admin based on the newest development stack of vue, built-in
|
||||||
You need to install [node](https://nodejs.org/) and [git](https://git-scm.com/) locally. The project is based on [ES2015+](https://es6.ruanyifeng.com/), [vue](https://cn.vuejs.org/index.html), [vuex](https://vuex.vuejs.org/zh-cn/), [vue-router](https://router.vuejs.org/zh-cn/), [vue-cli](https://github.com/vuejs/vue-cli) , [axios](https://github.com/axios/axios) and [element-ui](https://github.com/ElemeFE/element), all request data is simulated using [Mock.js](https://github.com/nuysoft/Mock).
|
You need to install [node](https://nodejs.org/) and [git](https://git-scm.com/) locally. The project is based on [ES2015+](https://es6.ruanyifeng.com/), [vue](https://cn.vuejs.org/index.html), [vuex](https://vuex.vuejs.org/zh-cn/), [vue-router](https://router.vuejs.org/zh-cn/), [vue-cli](https://github.com/vuejs/vue-cli) , [axios](https://github.com/axios/axios) and [element-ui](https://github.com/ElemeFE/element), all request data is simulated using [Mock.js](https://github.com/nuysoft/Mock).
|
||||||
Understanding and learning this knowledge in advance will greatly help the use of this project.
|
Understanding and learning this knowledge in advance will greatly help the use of this project.
|
||||||
|
|
||||||
<p align="center">
|
[![Edit on CodeSandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/PanJiaChen/vue-element-admin/tree/CodeSandbox)
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
<img width="900" src="https://wpimg.wallstcn.com/a5894c1b-f6af-456e-82df-1151da0839bf.png">
|
<img width="900" src="https://wpimg.wallstcn.com/a5894c1b-f6af-456e-82df-1151da0839bf.png">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -70,6 +72,11 @@ Understanding and learning this knowledge in advance will greatly help the use o
|
||||||
|
|
||||||
Become a sponsor and get your logo on our README on GitHub with a link to your site. [[Become a sponsor]](https://www.patreon.com/panjiachen)
|
Become a sponsor and get your logo on our README on GitHub with a link to your site. [[Become a sponsor]](https://www.patreon.com/panjiachen)
|
||||||
|
|
||||||
|
### Akveo
|
||||||
|
<a href="https://store.akveo.com/products/vue-java-admin-dashboard-spring?utm_campaign=akveo_store-Vue-Vue_demo%2Fgithub&utm_source=vue_admin&utm_medium=referral&utm_content=github_banner"><img width="500px" src="https://raw.githubusercontent.com/PanJiaChen/vue-element-admin-site/master/docs/.vuepress/public/images/vue-java-banner.png" /></a><p>Java backend integration</p>
|
||||||
|
|
||||||
|
### Flatlogic
|
||||||
|
|
||||||
<a href="https://flatlogic.com/admin-dashboards?from=vue-element-admin"><img width="150px" src="https://wpimg.wallstcn.com/9c0b719b-5551-4c1e-b776-63994632d94a.png" /></a><p>Admin Dashboard Templates made with Vue, React and Angular.</p>
|
<a href="https://flatlogic.com/admin-dashboards?from=vue-element-admin"><img width="150px" src="https://wpimg.wallstcn.com/9c0b719b-5551-4c1e-b776-63994632d94a.png" /></a><p>Admin Dashboard Templates made with Vue, React and Angular.</p>
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
@ -84,7 +91,10 @@ Become a sponsor and get your logo on our README on GitHub with a link to your s
|
||||||
- Two-step login
|
- Two-step login
|
||||||
|
|
||||||
- Multi-environment build
|
- Multi-environment build
|
||||||
- dev sit stage prod
|
- Develop (dev)
|
||||||
|
- sit
|
||||||
|
- Stage Test (stage)
|
||||||
|
- Production (prod)
|
||||||
|
|
||||||
- Global Features
|
- Global Features
|
||||||
- I18n
|
- I18n
|
||||||
|
@ -142,7 +152,7 @@ Become a sponsor and get your logo on our README on GitHub with a link to your s
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# clone the project
|
# clone the project
|
||||||
git clone https://github.com/PanJiaChen/vue-element-admin.git
|
git clone -b i18n git@github.com:PanJiaChen/vue-element-admin.git
|
||||||
|
|
||||||
# enter the project directory
|
# enter the project directory
|
||||||
cd vue-element-admin
|
cd vue-element-admin
|
||||||
|
@ -208,7 +218,7 @@ Modern browsers and Internet Explorer 10+.
|
||||||
|
|
||||||
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Safari |
|
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Safari |
|
||||||
| --------- | --------- | --------- | --------- |
|
| --------- | --------- | --------- | --------- |
|
||||||
| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
|
| IE10, IE11, Edge | last 2 versions | last 2 versions | last 2 versions |
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,9 @@
|
||||||
|
|
||||||
**如有问题请先看上述使用文档和文章,若不能满足,欢迎 issue 和 pr**
|
**如有问题请先看上述使用文档和文章,若不能满足,欢迎 issue 和 pr**
|
||||||
|
|
||||||
<p align="center">
|
[![Edit on CodeSandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/PanJiaChen/vue-element-admin/tree/CodeSandbox)
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
<img width="900" src="https://wpimg.wallstcn.com/a5894c1b-f6af-456e-82df-1151da0839bf.png">
|
<img width="900" src="https://wpimg.wallstcn.com/a5894c1b-f6af-456e-82df-1151da0839bf.png">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -85,8 +87,14 @@
|
||||||
|
|
||||||
Become a sponsor and get your logo on our README on GitHub with a link to your site. [[Become a sponsor]](https://www.patreon.com/panjiachen)
|
Become a sponsor and get your logo on our README on GitHub with a link to your site. [[Become a sponsor]](https://www.patreon.com/panjiachen)
|
||||||
|
|
||||||
|
### Akveo
|
||||||
|
<a href="https://store.akveo.com/products/vue-java-admin-dashboard-spring?utm_campaign=akveo_store-Vue-Vue_demo%2Fgithub&utm_source=vue_admin&utm_medium=referral&utm_content=github_banner"><img width="500px" src="https://raw.githubusercontent.com/PanJiaChen/vue-element-admin-site/master/docs/.vuepress/public/images/vue-java-banner.png" /></a><p>Java 后端整合</p>
|
||||||
|
|
||||||
|
### Flatlogic
|
||||||
|
|
||||||
<a href="https://flatlogic.com/admin-dashboards?from=vue-element-admin"><img width="150px" src="https://wpimg.wallstcn.com/9c0b719b-5551-4c1e-b776-63994632d94a.png" /></a><p>Admin Dashboard Templates made with Vue, React and Angular.</p>
|
<a href="https://flatlogic.com/admin-dashboards?from=vue-element-admin"><img width="150px" src="https://wpimg.wallstcn.com/9c0b719b-5551-4c1e-b776-63994632d94a.png" /></a><p>Admin Dashboard Templates made with Vue, React and Angular.</p>
|
||||||
|
|
||||||
|
|
||||||
## 功能
|
## 功能
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -99,7 +107,10 @@ Become a sponsor and get your logo on our README on GitHub with a link to your s
|
||||||
- 二步登录
|
- 二步登录
|
||||||
|
|
||||||
- 多环境发布
|
- 多环境发布
|
||||||
- dev sit stage prod
|
- dev
|
||||||
|
- sit
|
||||||
|
- stage
|
||||||
|
- prod
|
||||||
|
|
||||||
- 全局功能
|
- 全局功能
|
||||||
- 国际化多语言
|
- 国际化多语言
|
||||||
|
@ -157,7 +168,7 @@ Become a sponsor and get your logo on our README on GitHub with a link to your s
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 克隆项目
|
# 克隆项目
|
||||||
git clone https://github.com/PanJiaChen/vue-element-admin.git
|
git clone -b i18n git@github.com:PanJiaChen/vue-element-admin.git
|
||||||
|
|
||||||
# 进入项目目录
|
# 进入项目目录
|
||||||
cd vue-element-admin
|
cd vue-element-admin
|
||||||
|
@ -221,13 +232,17 @@ Detailed changes for each release are documented in the [release notes](https://
|
||||||
|
|
||||||
[Buy me a coffee](https://www.buymeacoffee.com/Pan)
|
[Buy me a coffee](https://www.buymeacoffee.com/Pan)
|
||||||
|
|
||||||
|
## 购买贴纸
|
||||||
|
|
||||||
|
你也可以通过 购买[官方授权的贴纸](https://smallsticker.com/product/vue-element-admin) 的方式来支持 vue-element-admin - 每售出一张贴纸,本项目将获得 2 元的捐赠。
|
||||||
|
|
||||||
## Browsers support
|
## Browsers support
|
||||||
|
|
||||||
Modern browsers and Internet Explorer 10+.
|
Modern browsers and Internet Explorer 10+.
|
||||||
|
|
||||||
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Safari |
|
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Safari |
|
||||||
| --------- | --------- | --------- | --------- |
|
| --------- | --------- | --------- | --------- |
|
||||||
| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
|
| IE10, IE11, Edge | last 2 versions | last 2 versions | last 2 versions |
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,14 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
presets: [
|
presets: [
|
||||||
'@vue/app'
|
// https://github.com/vuejs/vue-cli/tree/master/packages/@vue/babel-preset-app
|
||||||
]
|
'@vue/cli-plugin-babel/preset'
|
||||||
|
],
|
||||||
|
'env': {
|
||||||
|
'development': {
|
||||||
|
// babel-plugin-dynamic-import-node plugin only does one thing by converting all import() to require().
|
||||||
|
// This plugin can significantly increase the speed of hot updates, when you have a large number of pages.
|
||||||
|
// https://panjiachen.github.io/vue-element-admin-site/guide/advanced/lazy-loading.html
|
||||||
|
'plugins': ['dynamic-import-node']
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import Mock from 'mockjs'
|
const Mock = require('mockjs')
|
||||||
|
|
||||||
const List = []
|
const List = []
|
||||||
const count = 100
|
const count = 100
|
||||||
|
@ -18,7 +18,7 @@ for (let i = 0; i < count; i++) {
|
||||||
forecast: '@float(0, 100, 2, 2)',
|
forecast: '@float(0, 100, 2, 2)',
|
||||||
importance: '@integer(1, 3)',
|
importance: '@integer(1, 3)',
|
||||||
'type|1': ['CN', 'US', 'JP', 'EU'],
|
'type|1': ['CN', 'US', 'JP', 'EU'],
|
||||||
'status|1': ['published', 'draft', 'deleted'],
|
'status|1': ['published', 'draft'],
|
||||||
display_time: '@datetime',
|
display_time: '@datetime',
|
||||||
comment_disabled: true,
|
comment_disabled: true,
|
||||||
pageviews: '@integer(300, 5000)',
|
pageviews: '@integer(300, 5000)',
|
||||||
|
@ -27,9 +27,9 @@ for (let i = 0; i < count; i++) {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
export default [
|
module.exports = [
|
||||||
{
|
{
|
||||||
url: '/article/list',
|
url: '/vue-element-admin/article/list',
|
||||||
type: 'get',
|
type: 'get',
|
||||||
response: config => {
|
response: config => {
|
||||||
const { importance, type, title, page = 1, limit = 20, sort } = config.query
|
const { importance, type, title, page = 1, limit = 20, sort } = config.query
|
||||||
|
@ -58,7 +58,7 @@ export default [
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
url: '/article/detail',
|
url: '/vue-element-admin/article/detail',
|
||||||
type: 'get',
|
type: 'get',
|
||||||
response: config => {
|
response: config => {
|
||||||
const { id } = config.query
|
const { id } = config.query
|
||||||
|
@ -74,7 +74,7 @@ export default [
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
url: '/article/pv',
|
url: '/vue-element-admin/article/pv',
|
||||||
type: 'get',
|
type: 'get',
|
||||||
response: _ => {
|
response: _ => {
|
||||||
return {
|
return {
|
||||||
|
@ -92,7 +92,7 @@ export default [
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
url: '/article/create',
|
url: '/vue-element-admin/article/create',
|
||||||
type: 'post',
|
type: 'post',
|
||||||
response: _ => {
|
response: _ => {
|
||||||
return {
|
return {
|
||||||
|
@ -103,7 +103,7 @@ export default [
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
url: '/article/update',
|
url: '/vue-element-admin/article/update',
|
||||||
type: 'post',
|
type: 'post',
|
||||||
response: _ => {
|
response: _ => {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import Mock from 'mockjs'
|
const Mock = require('mockjs')
|
||||||
import { param2Obj } from '../src/utils'
|
const { param2Obj } = require('./utils')
|
||||||
|
|
||||||
import user from './user'
|
const user = require('./user')
|
||||||
import role from './role'
|
const role = require('./role')
|
||||||
import article from './article'
|
const article = require('./article')
|
||||||
import search from './remote-search'
|
const search = require('./remote-search')
|
||||||
|
|
||||||
const mocks = [
|
const mocks = [
|
||||||
...user,
|
...user,
|
||||||
|
@ -16,7 +16,7 @@ const mocks = [
|
||||||
// for front mock
|
// for front mock
|
||||||
// please use it cautiously, it will redefine XMLHttpRequest,
|
// please use it cautiously, it will redefine XMLHttpRequest,
|
||||||
// which will cause many of your third-party libraries to be invalidated(like progress event).
|
// which will cause many of your third-party libraries to be invalidated(like progress event).
|
||||||
export function mockXHR() {
|
function mockXHR() {
|
||||||
// mock patch
|
// mock patch
|
||||||
// https://github.com/nuysoft/Mock/issues/300
|
// https://github.com/nuysoft/Mock/issues/300
|
||||||
Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send
|
Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send
|
||||||
|
@ -54,17 +54,7 @@ export function mockXHR() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// for mock server
|
module.exports = {
|
||||||
const responseFake = (url, type, respond) => {
|
mocks,
|
||||||
return {
|
mockXHR
|
||||||
url: new RegExp(`/mock${url}`),
|
|
||||||
type: type || 'get',
|
|
||||||
response(req, res) {
|
|
||||||
res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default mocks.map(route => {
|
|
||||||
return responseFake(route.url, route.type, route.response)
|
|
||||||
})
|
|
||||||
|
|
|
@ -2,17 +2,21 @@ const chokidar = require('chokidar')
|
||||||
const bodyParser = require('body-parser')
|
const bodyParser = require('body-parser')
|
||||||
const chalk = require('chalk')
|
const chalk = require('chalk')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
|
const Mock = require('mockjs')
|
||||||
|
|
||||||
const mockDir = path.join(process.cwd(), 'mock')
|
const mockDir = path.join(process.cwd(), 'mock')
|
||||||
|
|
||||||
function registerRoutes(app) {
|
function registerRoutes(app) {
|
||||||
let mockLastIndex
|
let mockLastIndex
|
||||||
const { default: mocks } = require('./index.js')
|
const { mocks } = require('./index.js')
|
||||||
for (const mock of mocks) {
|
const mocksForServer = mocks.map(route => {
|
||||||
|
return responseFake(route.url, route.type, route.response)
|
||||||
|
})
|
||||||
|
for (const mock of mocksForServer) {
|
||||||
app[mock.type](mock.url, mock.response)
|
app[mock.type](mock.url, mock.response)
|
||||||
mockLastIndex = app._router.stack.length
|
mockLastIndex = app._router.stack.length
|
||||||
}
|
}
|
||||||
const mockRoutesLength = Object.keys(mocks).length
|
const mockRoutesLength = Object.keys(mocksForServer).length
|
||||||
return {
|
return {
|
||||||
mockRoutesLength: mockRoutesLength,
|
mockRoutesLength: mockRoutesLength,
|
||||||
mockStartIndex: mockLastIndex - mockRoutesLength
|
mockStartIndex: mockLastIndex - mockRoutesLength
|
||||||
|
@ -27,10 +31,19 @@ function unregisterRoutes() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = app => {
|
// for mock server
|
||||||
// es6 polyfill
|
const responseFake = (url, type, respond) => {
|
||||||
require('@babel/register')
|
return {
|
||||||
|
url: new RegExp(`${process.env.VUE_APP_BASE_API}${url}`),
|
||||||
|
type: type || 'get',
|
||||||
|
response(req, res) {
|
||||||
|
console.log('request invoke:' + req.path)
|
||||||
|
res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = app => {
|
||||||
// parse app.body
|
// parse app.body
|
||||||
// https://expressjs.com/en/4x/api.html#req.body
|
// https://expressjs.com/en/4x/api.html#req.body
|
||||||
app.use(bodyParser.json())
|
app.use(bodyParser.json())
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import Mock from 'mockjs'
|
const Mock = require('mockjs')
|
||||||
|
|
||||||
const NameList = []
|
const NameList = []
|
||||||
const count = 100
|
const count = 100
|
||||||
|
@ -10,10 +10,10 @@ for (let i = 0; i < count; i++) {
|
||||||
}
|
}
|
||||||
NameList.push({ name: 'mock-Pan' })
|
NameList.push({ name: 'mock-Pan' })
|
||||||
|
|
||||||
export default [
|
module.exports = [
|
||||||
// username search
|
// username search
|
||||||
{
|
{
|
||||||
url: '/search/user',
|
url: '/vue-element-admin/search/user',
|
||||||
type: 'get',
|
type: 'get',
|
||||||
response: config => {
|
response: config => {
|
||||||
const { name } = config.query
|
const { name } = config.query
|
||||||
|
@ -30,7 +30,7 @@ export default [
|
||||||
|
|
||||||
// transaction list
|
// transaction list
|
||||||
{
|
{
|
||||||
url: '/transaction/list',
|
url: '/vue-element-admin/transaction/list',
|
||||||
type: 'get',
|
type: 'get',
|
||||||
response: _ => {
|
response: _ => {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import Mock from 'mockjs'
|
const Mock = require('mockjs')
|
||||||
import { deepClone } from '../../src/utils/index.js'
|
const { deepClone } = require('../utils')
|
||||||
import { asyncRoutes, constantRoutes } from './routes.js'
|
const { asyncRoutes, constantRoutes } = require('./routes.js')
|
||||||
|
|
||||||
const routes = deepClone([...constantRoutes, ...asyncRoutes])
|
const routes = deepClone([...constantRoutes, ...asyncRoutes])
|
||||||
|
|
||||||
|
@ -35,10 +35,10 @@ const roles = [
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
export default [
|
module.exports = [
|
||||||
// mock get all routes form server
|
// mock get all routes form server
|
||||||
{
|
{
|
||||||
url: '/routes',
|
url: '/vue-element-admin/routes',
|
||||||
type: 'get',
|
type: 'get',
|
||||||
response: _ => {
|
response: _ => {
|
||||||
return {
|
return {
|
||||||
|
@ -50,7 +50,7 @@ export default [
|
||||||
|
|
||||||
// mock get all roles form server
|
// mock get all roles form server
|
||||||
{
|
{
|
||||||
url: '/roles',
|
url: '/vue-element-admin/roles',
|
||||||
type: 'get',
|
type: 'get',
|
||||||
response: _ => {
|
response: _ => {
|
||||||
return {
|
return {
|
||||||
|
@ -62,7 +62,7 @@ export default [
|
||||||
|
|
||||||
// add role
|
// add role
|
||||||
{
|
{
|
||||||
url: '/role',
|
url: '/vue-element-admin/role',
|
||||||
type: 'post',
|
type: 'post',
|
||||||
response: {
|
response: {
|
||||||
code: 20000,
|
code: 20000,
|
||||||
|
@ -74,7 +74,7 @@ export default [
|
||||||
|
|
||||||
// update role
|
// update role
|
||||||
{
|
{
|
||||||
url: '/role/[A-Za-z0-9]',
|
url: '/vue-element-admin/role/[A-Za-z0-9]',
|
||||||
type: 'put',
|
type: 'put',
|
||||||
response: {
|
response: {
|
||||||
code: 20000,
|
code: 20000,
|
||||||
|
@ -86,7 +86,7 @@ export default [
|
||||||
|
|
||||||
// delete role
|
// delete role
|
||||||
{
|
{
|
||||||
url: '/role/[A-Za-z0-9]',
|
url: '/vue-element-admin/role/[A-Za-z0-9]',
|
||||||
type: 'delete',
|
type: 'delete',
|
||||||
response: {
|
response: {
|
||||||
code: 20000,
|
code: 20000,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Just a mock data
|
// Just a mock data
|
||||||
|
|
||||||
export const constantRoutes = [
|
const constantRoutes = [
|
||||||
{
|
{
|
||||||
path: '/redirect',
|
path: '/redirect',
|
||||||
component: 'layout/Layout',
|
component: 'layout/Layout',
|
||||||
|
@ -41,7 +41,7 @@ export const constantRoutes = [
|
||||||
path: 'dashboard',
|
path: 'dashboard',
|
||||||
component: 'views/dashboard/index',
|
component: 'views/dashboard/index',
|
||||||
name: 'Dashboard',
|
name: 'Dashboard',
|
||||||
meta: { title: 'Dashboard', icon: 'dashboard', affix: true }
|
meta: { title: 'dashboard', icon: 'dashboard', affix: true }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -53,7 +53,7 @@ export const constantRoutes = [
|
||||||
path: 'index',
|
path: 'index',
|
||||||
component: 'views/documentation/index',
|
component: 'views/documentation/index',
|
||||||
name: 'Documentation',
|
name: 'Documentation',
|
||||||
meta: { title: 'Documentation', icon: 'documentation', affix: true }
|
meta: { title: 'documentation', icon: 'documentation', affix: true }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -66,20 +66,20 @@ export const constantRoutes = [
|
||||||
path: 'index',
|
path: 'index',
|
||||||
component: 'views/guide/index',
|
component: 'views/guide/index',
|
||||||
name: 'Guide',
|
name: 'Guide',
|
||||||
meta: { title: 'Guide', icon: 'guide', noCache: true }
|
meta: { title: 'guide', icon: 'guide', noCache: true }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
export const asyncRoutes = [
|
const asyncRoutes = [
|
||||||
{
|
{
|
||||||
path: '/permission',
|
path: '/permission',
|
||||||
component: 'layout/Layout',
|
component: 'layout/Layout',
|
||||||
redirect: '/permission/index',
|
redirect: '/permission/index',
|
||||||
alwaysShow: true,
|
alwaysShow: true,
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Permission',
|
title: 'permission',
|
||||||
icon: 'lock',
|
icon: 'lock',
|
||||||
roles: ['admin', 'editor']
|
roles: ['admin', 'editor']
|
||||||
},
|
},
|
||||||
|
@ -89,7 +89,7 @@ export const asyncRoutes = [
|
||||||
component: 'views/permission/page',
|
component: 'views/permission/page',
|
||||||
name: 'PagePermission',
|
name: 'PagePermission',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Page Permission',
|
title: 'pagePermission',
|
||||||
roles: ['admin']
|
roles: ['admin']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -98,7 +98,7 @@ export const asyncRoutes = [
|
||||||
component: 'views/permission/directive',
|
component: 'views/permission/directive',
|
||||||
name: 'DirectivePermission',
|
name: 'DirectivePermission',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Directive Permission'
|
title: 'directivePermission'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -106,7 +106,7 @@ export const asyncRoutes = [
|
||||||
component: 'views/permission/role',
|
component: 'views/permission/role',
|
||||||
name: 'RolePermission',
|
name: 'RolePermission',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Role Permission',
|
title: 'rolePermission',
|
||||||
roles: ['admin']
|
roles: ['admin']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ export const asyncRoutes = [
|
||||||
path: 'index',
|
path: 'index',
|
||||||
component: 'views/icons/index',
|
component: 'views/icons/index',
|
||||||
name: 'Icons',
|
name: 'Icons',
|
||||||
meta: { title: 'Icons', icon: 'icon', noCache: true }
|
meta: { title: 'icons', icon: 'icon', noCache: true }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -132,7 +132,7 @@ export const asyncRoutes = [
|
||||||
redirect: 'noRedirect',
|
redirect: 'noRedirect',
|
||||||
name: 'ComponentDemo',
|
name: 'ComponentDemo',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Components',
|
title: 'components',
|
||||||
icon: 'component'
|
icon: 'component'
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
|
@ -140,49 +140,49 @@ export const asyncRoutes = [
|
||||||
path: 'tinymce',
|
path: 'tinymce',
|
||||||
component: 'views/components-demo/tinymce',
|
component: 'views/components-demo/tinymce',
|
||||||
name: 'TinymceDemo',
|
name: 'TinymceDemo',
|
||||||
meta: { title: 'Tinymce' }
|
meta: { title: 'tinymce' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'markdown',
|
path: 'markdown',
|
||||||
component: 'views/components-demo/markdown',
|
component: 'views/components-demo/markdown',
|
||||||
name: 'MarkdownDemo',
|
name: 'MarkdownDemo',
|
||||||
meta: { title: 'Markdown' }
|
meta: { title: 'markdown' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'json-editor',
|
path: 'json-editor',
|
||||||
component: 'views/components-demo/json-editor',
|
component: 'views/components-demo/json-editor',
|
||||||
name: 'JsonEditorDemo',
|
name: 'JsonEditorDemo',
|
||||||
meta: { title: 'Json Editor' }
|
meta: { title: 'jsonEditor' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'split-pane',
|
path: 'split-pane',
|
||||||
component: 'views/components-demo/split-pane',
|
component: 'views/components-demo/split-pane',
|
||||||
name: 'SplitpaneDemo',
|
name: 'SplitpaneDemo',
|
||||||
meta: { title: 'SplitPane' }
|
meta: { title: 'splitPane' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'avatar-upload',
|
path: 'avatar-upload',
|
||||||
component: 'views/components-demo/avatar-upload',
|
component: 'views/components-demo/avatar-upload',
|
||||||
name: 'AvatarUploadDemo',
|
name: 'AvatarUploadDemo',
|
||||||
meta: { title: 'Avatar Upload' }
|
meta: { title: 'avatarUpload' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'dropzone',
|
path: 'dropzone',
|
||||||
component: 'views/components-demo/dropzone',
|
component: 'views/components-demo/dropzone',
|
||||||
name: 'DropzoneDemo',
|
name: 'DropzoneDemo',
|
||||||
meta: { title: 'Dropzone' }
|
meta: { title: 'dropzone' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'sticky',
|
path: 'sticky',
|
||||||
component: 'views/components-demo/sticky',
|
component: 'views/components-demo/sticky',
|
||||||
name: 'StickyDemo',
|
name: 'StickyDemo',
|
||||||
meta: { title: 'Sticky' }
|
meta: { title: 'sticky' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'count-to',
|
path: 'count-to',
|
||||||
component: 'views/components-demo/count-to',
|
component: 'views/components-demo/count-to',
|
||||||
name: 'CountToDemo',
|
name: 'CountToDemo',
|
||||||
meta: { title: 'Count To' }
|
meta: { title: 'countTo' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'mixin',
|
path: 'mixin',
|
||||||
|
@ -194,31 +194,31 @@ export const asyncRoutes = [
|
||||||
path: 'back-to-top',
|
path: 'back-to-top',
|
||||||
component: 'views/components-demo/back-to-top',
|
component: 'views/components-demo/back-to-top',
|
||||||
name: 'BackToTopDemo',
|
name: 'BackToTopDemo',
|
||||||
meta: { title: 'Back To Top' }
|
meta: { title: 'backToTop' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'drag-dialog',
|
path: 'drag-dialog',
|
||||||
component: 'views/components-demo/drag-dialog',
|
component: 'views/components-demo/drag-dialog',
|
||||||
name: 'DragDialogDemo',
|
name: 'DragDialogDemo',
|
||||||
meta: { title: 'Drag Dialog' }
|
meta: { title: 'dragDialog' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'drag-select',
|
path: 'drag-select',
|
||||||
component: 'views/components-demo/drag-select',
|
component: 'views/components-demo/drag-select',
|
||||||
name: 'DragSelectDemo',
|
name: 'DragSelectDemo',
|
||||||
meta: { title: 'Drag Select' }
|
meta: { title: 'dragSelect' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'dnd-list',
|
path: 'dnd-list',
|
||||||
component: 'views/components-demo/dnd-list',
|
component: 'views/components-demo/dnd-list',
|
||||||
name: 'DndListDemo',
|
name: 'DndListDemo',
|
||||||
meta: { title: 'Dnd List' }
|
meta: { title: 'dndList' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'drag-kanban',
|
path: 'drag-kanban',
|
||||||
component: 'views/components-demo/drag-kanban',
|
component: 'views/components-demo/drag-kanban',
|
||||||
name: 'DragKanbanDemo',
|
name: 'DragKanbanDemo',
|
||||||
meta: { title: 'Drag Kanban' }
|
meta: { title: 'dragKanban' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -228,7 +228,7 @@ export const asyncRoutes = [
|
||||||
redirect: 'noRedirect',
|
redirect: 'noRedirect',
|
||||||
name: 'Charts',
|
name: 'Charts',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Charts',
|
title: 'charts',
|
||||||
icon: 'chart'
|
icon: 'chart'
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
|
@ -236,19 +236,19 @@ export const asyncRoutes = [
|
||||||
path: 'keyboard',
|
path: 'keyboard',
|
||||||
component: 'views/charts/keyboard',
|
component: 'views/charts/keyboard',
|
||||||
name: 'KeyboardChart',
|
name: 'KeyboardChart',
|
||||||
meta: { title: 'Keyboard Chart', noCache: true }
|
meta: { title: 'keyboardChart', noCache: true }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'line',
|
path: 'line',
|
||||||
component: 'views/charts/line',
|
component: 'views/charts/line',
|
||||||
name: 'LineChart',
|
name: 'LineChart',
|
||||||
meta: { title: 'Line Chart', noCache: true }
|
meta: { title: 'lineChart', noCache: true }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'mixchart',
|
path: 'mixchart',
|
||||||
component: 'views/charts/mixChart',
|
component: 'views/charts/mixChart',
|
||||||
name: 'MixChart',
|
name: 'MixChart',
|
||||||
meta: { title: 'Mix Chart', noCache: true }
|
meta: { title: 'mixChart', noCache: true }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -258,7 +258,7 @@ export const asyncRoutes = [
|
||||||
redirect: '/nested/menu1/menu1-1',
|
redirect: '/nested/menu1/menu1-1',
|
||||||
name: 'Nested',
|
name: 'Nested',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Nested',
|
title: 'nested',
|
||||||
icon: 'nested'
|
icon: 'nested'
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
|
@ -266,33 +266,33 @@ export const asyncRoutes = [
|
||||||
path: 'menu1',
|
path: 'menu1',
|
||||||
component: 'views/nested/menu1/index',
|
component: 'views/nested/menu1/index',
|
||||||
name: 'Menu1',
|
name: 'Menu1',
|
||||||
meta: { title: 'Menu1' },
|
meta: { title: 'menu1' },
|
||||||
redirect: '/nested/menu1/menu1-1',
|
redirect: '/nested/menu1/menu1-1',
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'menu1-1',
|
path: 'menu1-1',
|
||||||
component: 'views/nested/menu1/menu1-1',
|
component: 'views/nested/menu1/menu1-1',
|
||||||
name: 'Menu1-1',
|
name: 'Menu1-1',
|
||||||
meta: { title: 'Menu1-1' }
|
meta: { title: 'menu1-1' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'menu1-2',
|
path: 'menu1-2',
|
||||||
component: 'views/nested/menu1/menu1-2',
|
component: 'views/nested/menu1/menu1-2',
|
||||||
name: 'Menu1-2',
|
name: 'Menu1-2',
|
||||||
redirect: '/nested/menu1/menu1-2/menu1-2-1',
|
redirect: '/nested/menu1/menu1-2/menu1-2-1',
|
||||||
meta: { title: 'Menu1-2' },
|
meta: { title: 'menu1-2' },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'menu1-2-1',
|
path: 'menu1-2-1',
|
||||||
component: 'views/nested/menu1/menu1-2/menu1-2-1',
|
component: 'views/nested/menu1/menu1-2/menu1-2-1',
|
||||||
name: 'Menu1-2-1',
|
name: 'Menu1-2-1',
|
||||||
meta: { title: 'Menu1-2-1' }
|
meta: { title: 'menu1-2-1' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'menu1-2-2',
|
path: 'menu1-2-2',
|
||||||
component: 'views/nested/menu1/menu1-2/menu1-2-2',
|
component: 'views/nested/menu1/menu1-2/menu1-2-2',
|
||||||
name: 'Menu1-2-2',
|
name: 'Menu1-2-2',
|
||||||
meta: { title: 'Menu1-2-2' }
|
meta: { title: 'menu1-2-2' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -300,7 +300,7 @@ export const asyncRoutes = [
|
||||||
path: 'menu1-3',
|
path: 'menu1-3',
|
||||||
component: 'views/nested/menu1/menu1-3',
|
component: 'views/nested/menu1/menu1-3',
|
||||||
name: 'Menu1-3',
|
name: 'Menu1-3',
|
||||||
meta: { title: 'Menu1-3' }
|
meta: { title: 'menu1-3' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -308,7 +308,7 @@ export const asyncRoutes = [
|
||||||
path: 'menu2',
|
path: 'menu2',
|
||||||
name: 'Menu2',
|
name: 'Menu2',
|
||||||
component: 'views/nested/menu2/index',
|
component: 'views/nested/menu2/index',
|
||||||
meta: { title: 'Menu2' }
|
meta: { title: 'menu2' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -319,7 +319,7 @@ export const asyncRoutes = [
|
||||||
redirect: '/example/list',
|
redirect: '/example/list',
|
||||||
name: 'Example',
|
name: 'Example',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Example',
|
title: 'example',
|
||||||
icon: 'example'
|
icon: 'example'
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
|
@ -327,20 +327,20 @@ export const asyncRoutes = [
|
||||||
path: 'create',
|
path: 'create',
|
||||||
component: 'views/example/create',
|
component: 'views/example/create',
|
||||||
name: 'CreateArticle',
|
name: 'CreateArticle',
|
||||||
meta: { title: 'Create Article', icon: 'edit' }
|
meta: { title: 'createArticle', icon: 'edit' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'edit/:id(\\d+)',
|
path: 'edit/:id(\\d+)',
|
||||||
component: 'views/example/edit',
|
component: 'views/example/edit',
|
||||||
name: 'EditArticle',
|
name: 'EditArticle',
|
||||||
meta: { title: 'Edit Article', noCache: true },
|
meta: { title: 'editArticle', noCache: true },
|
||||||
hidden: true
|
hidden: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'list',
|
path: 'list',
|
||||||
component: 'views/example/list',
|
component: 'views/example/list',
|
||||||
name: 'ArticleList',
|
name: 'ArticleList',
|
||||||
meta: { title: 'Article List', icon: 'list' }
|
meta: { title: 'articleList', icon: 'list' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -353,7 +353,7 @@ export const asyncRoutes = [
|
||||||
path: 'index',
|
path: 'index',
|
||||||
component: 'views/tab/index',
|
component: 'views/tab/index',
|
||||||
name: 'Tab',
|
name: 'Tab',
|
||||||
meta: { title: 'Tab', icon: 'tab' }
|
meta: { title: 'tab', icon: 'tab' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -364,7 +364,7 @@ export const asyncRoutes = [
|
||||||
redirect: 'noRedirect',
|
redirect: 'noRedirect',
|
||||||
name: 'ErrorPages',
|
name: 'ErrorPages',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Error Pages',
|
title: 'errorPages',
|
||||||
icon: '404'
|
icon: '404'
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
|
@ -372,13 +372,13 @@ export const asyncRoutes = [
|
||||||
path: '401',
|
path: '401',
|
||||||
component: 'views/error-page/401',
|
component: 'views/error-page/401',
|
||||||
name: 'Page401',
|
name: 'Page401',
|
||||||
meta: { title: 'Page 401', noCache: true }
|
meta: { title: 'page401', noCache: true }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '404',
|
path: '404',
|
||||||
component: 'views/error-page/404',
|
component: 'views/error-page/404',
|
||||||
name: 'Page404',
|
name: 'Page404',
|
||||||
meta: { title: 'Page 404', noCache: true }
|
meta: { title: 'page404', noCache: true }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -392,7 +392,7 @@ export const asyncRoutes = [
|
||||||
path: 'log',
|
path: 'log',
|
||||||
component: 'views/error-log/index',
|
component: 'views/error-log/index',
|
||||||
name: 'ErrorLog',
|
name: 'ErrorLog',
|
||||||
meta: { title: 'Error Log', icon: 'bug' }
|
meta: { title: 'errorLog', icon: 'bug' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -403,7 +403,7 @@ export const asyncRoutes = [
|
||||||
redirect: '/excel/export-excel',
|
redirect: '/excel/export-excel',
|
||||||
name: 'Excel',
|
name: 'Excel',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Excel',
|
title: 'excel',
|
||||||
icon: 'excel'
|
icon: 'excel'
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
|
@ -411,25 +411,25 @@ export const asyncRoutes = [
|
||||||
path: 'export-excel',
|
path: 'export-excel',
|
||||||
component: 'views/excel/export-excel',
|
component: 'views/excel/export-excel',
|
||||||
name: 'ExportExcel',
|
name: 'ExportExcel',
|
||||||
meta: { title: 'Export Excel' }
|
meta: { title: 'exportExcel' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'export-selected-excel',
|
path: 'export-selected-excel',
|
||||||
component: 'views/excel/select-excel',
|
component: 'views/excel/select-excel',
|
||||||
name: 'SelectExcel',
|
name: 'SelectExcel',
|
||||||
meta: { title: 'Select Excel' }
|
meta: { title: 'selectExcel' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'export-merge-header',
|
path: 'export-merge-header',
|
||||||
component: 'views/excel/merge-header',
|
component: 'views/excel/merge-header',
|
||||||
name: 'MergeHeader',
|
name: 'MergeHeader',
|
||||||
meta: { title: 'Merge Header' }
|
meta: { title: 'mergeHeader' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'upload-excel',
|
path: 'upload-excel',
|
||||||
component: 'views/excel/upload-excel',
|
component: 'views/excel/upload-excel',
|
||||||
name: 'UploadExcel',
|
name: 'UploadExcel',
|
||||||
meta: { title: 'Upload Excel' }
|
meta: { title: 'uploadExcel' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -439,13 +439,13 @@ export const asyncRoutes = [
|
||||||
component: 'layout/Layout',
|
component: 'layout/Layout',
|
||||||
redirect: '/zip/download',
|
redirect: '/zip/download',
|
||||||
alwaysShow: true,
|
alwaysShow: true,
|
||||||
meta: { title: 'Zip', icon: 'zip' },
|
meta: { title: 'zip', icon: 'zip' },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'download',
|
path: 'download',
|
||||||
component: 'views/zip/index',
|
component: 'views/zip/index',
|
||||||
name: 'ExportZip',
|
name: 'ExportZip',
|
||||||
meta: { title: 'Export Zip' }
|
meta: { title: 'exportZip' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -459,7 +459,7 @@ export const asyncRoutes = [
|
||||||
path: 'index',
|
path: 'index',
|
||||||
component: 'views/pdf/index',
|
component: 'views/pdf/index',
|
||||||
name: 'PDF',
|
name: 'PDF',
|
||||||
meta: { title: 'PDF', icon: 'pdf' }
|
meta: { title: 'pdf', icon: 'pdf' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -478,7 +478,7 @@ export const asyncRoutes = [
|
||||||
path: 'index',
|
path: 'index',
|
||||||
component: 'views/theme/index',
|
component: 'views/theme/index',
|
||||||
name: 'Theme',
|
name: 'Theme',
|
||||||
meta: { title: 'Theme', icon: 'theme' }
|
meta: { title: 'theme', icon: 'theme' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -492,7 +492,7 @@ export const asyncRoutes = [
|
||||||
path: 'index',
|
path: 'index',
|
||||||
component: 'views/clipboard/index',
|
component: 'views/clipboard/index',
|
||||||
name: 'ClipboardDemo',
|
name: 'ClipboardDemo',
|
||||||
meta: { title: 'Clipboard Demo', icon: 'clipboard' }
|
meta: { title: 'clipboardDemo', icon: 'clipboard' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -505,7 +505,7 @@ export const asyncRoutes = [
|
||||||
path: 'index',
|
path: 'index',
|
||||||
component: 'views/i18n-demo/index',
|
component: 'views/i18n-demo/index',
|
||||||
name: 'I18n',
|
name: 'I18n',
|
||||||
meta: { title: 'I18n', icon: 'international' }
|
meta: { title: 'i18n', icon: 'international' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -516,10 +516,15 @@ export const asyncRoutes = [
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'https://github.com/PanJiaChen/vue-element-admin',
|
path: 'https://github.com/PanJiaChen/vue-element-admin',
|
||||||
meta: { title: 'External Link', icon: 'link' }
|
meta: { title: 'externalLink', icon: 'link' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
{ path: '*', redirect: '/404', hidden: true }
|
{ path: '*', redirect: '/404', hidden: true }
|
||||||
]
|
]
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
constantRoutes,
|
||||||
|
asyncRoutes
|
||||||
|
}
|
||||||
|
|
|
@ -23,10 +23,10 @@ const users = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default [
|
module.exports = [
|
||||||
// user login
|
// user login
|
||||||
{
|
{
|
||||||
url: '/user/login',
|
url: '/vue-element-admin/user/login',
|
||||||
type: 'post',
|
type: 'post',
|
||||||
response: config => {
|
response: config => {
|
||||||
const { username } = config.body
|
const { username } = config.body
|
||||||
|
@ -49,7 +49,7 @@ export default [
|
||||||
|
|
||||||
// get user info
|
// get user info
|
||||||
{
|
{
|
||||||
url: '/user/info\.*',
|
url: '/vue-element-admin/user/info\.*',
|
||||||
type: 'get',
|
type: 'get',
|
||||||
response: config => {
|
response: config => {
|
||||||
const { token } = config.query
|
const { token } = config.query
|
||||||
|
@ -72,7 +72,7 @@ export default [
|
||||||
|
|
||||||
// user logout
|
// user logout
|
||||||
{
|
{
|
||||||
url: '/user/logout',
|
url: '/vue-element-admin/user/logout',
|
||||||
type: 'post',
|
type: 'post',
|
||||||
response: _ => {
|
response: _ => {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
/**
|
||||||
|
* @param {string} url
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
function param2Obj(url) {
|
||||||
|
const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
|
||||||
|
if (!search) {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
const obj = {}
|
||||||
|
const searchArr = search.split('&')
|
||||||
|
searchArr.forEach(v => {
|
||||||
|
const index = v.indexOf('=')
|
||||||
|
if (index !== -1) {
|
||||||
|
const name = v.substring(0, index)
|
||||||
|
const val = v.substring(index + 1, v.length)
|
||||||
|
obj[name] = val
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is just a simple version of deep copy
|
||||||
|
* Has a lot of edge cases bug
|
||||||
|
* If you want to use a perfect deep copy, use lodash's _.cloneDeep
|
||||||
|
* @param {Object} source
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
function deepClone(source) {
|
||||||
|
if (!source && typeof source !== 'object') {
|
||||||
|
throw new Error('error arguments', 'deepClone')
|
||||||
|
}
|
||||||
|
const targetObj = source.constructor === Array ? [] : {}
|
||||||
|
Object.keys(source).forEach(keys => {
|
||||||
|
if (source[keys] && typeof source[keys] === 'object') {
|
||||||
|
targetObj[keys] = deepClone(source[keys])
|
||||||
|
} else {
|
||||||
|
targetObj[keys] = source[keys]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return targetObj
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
param2Obj,
|
||||||
|
deepClone
|
||||||
|
}
|
174
package.json
174
package.json
|
@ -1,30 +1,89 @@
|
||||||
{
|
{
|
||||||
"name": "vue-element-admin",
|
"name": "vue-element-admin",
|
||||||
"version": "4.2.1",
|
"version": "4.3.1",
|
||||||
"description": "A magical vue admin. An out-of-box UI solution for enterprise applications. Newest development stack of vue. Lots of awesome features",
|
"description": "A magical vue admin. An out-of-box UI solution for enterprise applications. Newest development stack of vue. Lots of awesome features",
|
||||||
"author": "Pan <panfree23@gmail.com>",
|
"author": "Pan <panfree23@gmail.com>",
|
||||||
"license": "MIT",
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vue-cli-service serve",
|
"dev": "vue-cli-service serve",
|
||||||
|
"lint": "eslint --ext .js,.vue src",
|
||||||
"build:prod": "vue-cli-service build",
|
"build:prod": "vue-cli-service build",
|
||||||
"build:stage": "vue-cli-service build --mode staging",
|
"build:stage": "vue-cli-service build --mode staging",
|
||||||
"preview": "node build/index.js --preview",
|
"preview": "node build/index.js --preview",
|
||||||
"lint": "eslint --ext .js,.vue src",
|
"new": "plop",
|
||||||
"test:unit": "jest --clearCache && vue-cli-service test:unit",
|
|
||||||
"test:ci": "npm run lint && npm run test:unit",
|
|
||||||
"svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml",
|
"svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml",
|
||||||
"new": "plop"
|
"test:unit": "jest --clearCache && vue-cli-service test:unit",
|
||||||
|
"test:ci": "npm run lint && npm run test:unit"
|
||||||
},
|
},
|
||||||
"husky": {
|
"dependencies": {
|
||||||
"hooks": {
|
"axios": "0.18.1",
|
||||||
"pre-commit": "lint-staged"
|
"clipboard": "2.0.4",
|
||||||
}
|
"codemirror": "5.45.0",
|
||||||
|
"core-js": "3.6.5",
|
||||||
|
"driver.js": "0.9.5",
|
||||||
|
"dropzone": "5.5.1",
|
||||||
|
"echarts": "4.2.1",
|
||||||
|
"element-ui": "2.13.2",
|
||||||
|
"file-saver": "2.0.1",
|
||||||
|
"fuse.js": "3.4.4",
|
||||||
|
"js-cookie": "2.2.0",
|
||||||
|
"jsonlint": "1.6.3",
|
||||||
|
"jszip": "3.2.1",
|
||||||
|
"normalize.css": "7.0.0",
|
||||||
|
"nprogress": "0.2.0",
|
||||||
|
"path-to-regexp": "2.4.0",
|
||||||
|
"pinyin": "2.9.0",
|
||||||
|
"screenfull": "4.2.0",
|
||||||
|
"script-loader": "0.7.2",
|
||||||
|
"sortablejs": "1.8.4",
|
||||||
|
"tui-editor": "1.3.3",
|
||||||
|
"vue": "2.6.10",
|
||||||
|
"vue-count-to": "1.0.13",
|
||||||
|
"vue-i18n": "7.3.2",
|
||||||
|
"vue-router": "3.0.2",
|
||||||
|
"vue-splitpane": "1.0.4",
|
||||||
|
"vuedraggable": "2.20.0",
|
||||||
|
"vuex": "3.1.0",
|
||||||
|
"xlsx": "0.14.1"
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
"devDependencies": {
|
||||||
"src/**/*.{js,vue}": [
|
"@vue/cli-plugin-babel": "4.4.4",
|
||||||
"eslint --fix",
|
"@vue/cli-plugin-eslint": "4.4.4",
|
||||||
"git add"
|
"@vue/cli-plugin-unit-jest": "4.4.4",
|
||||||
]
|
"@vue/cli-service": "4.4.4",
|
||||||
|
"@vue/test-utils": "1.0.0-beta.29",
|
||||||
|
"autoprefixer": "9.5.1",
|
||||||
|
"babel-eslint": "10.1.0",
|
||||||
|
"babel-jest": "23.6.0",
|
||||||
|
"babel-plugin-dynamic-import-node": "2.3.3",
|
||||||
|
"chalk": "2.4.2",
|
||||||
|
"chokidar": "2.1.5",
|
||||||
|
"connect": "3.6.6",
|
||||||
|
"eslint": "6.7.2",
|
||||||
|
"eslint-plugin-vue": "6.2.2",
|
||||||
|
"html-webpack-plugin": "3.2.0",
|
||||||
|
"husky": "1.3.1",
|
||||||
|
"lint-staged": "8.1.5",
|
||||||
|
"mockjs": "1.0.1-beta3",
|
||||||
|
"plop": "2.3.0",
|
||||||
|
"runjs": "4.3.2",
|
||||||
|
"sass": "1.26.2",
|
||||||
|
"sass-loader": "8.0.2",
|
||||||
|
"script-ext-html-webpack-plugin": "2.1.3",
|
||||||
|
"serve-static": "1.13.2",
|
||||||
|
"svg-sprite-loader": "4.1.3",
|
||||||
|
"svgo": "1.2.0",
|
||||||
|
"vue-template-compiler": "2.6.10"
|
||||||
|
},
|
||||||
|
"browserslist": [
|
||||||
|
"> 1%",
|
||||||
|
"last 2 versions"
|
||||||
|
],
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/PanJiaChen/vue-element-admin/issues"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.9",
|
||||||
|
"npm": ">= 3.0.0"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"vue",
|
"vue",
|
||||||
|
@ -35,79 +94,20 @@
|
||||||
"admin-template",
|
"admin-template",
|
||||||
"management-system"
|
"management-system"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"lint-staged": {
|
||||||
|
"src/**/*.{js,vue}": [
|
||||||
|
"eslint --fix",
|
||||||
|
"git add"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"husky": {
|
||||||
|
"hooks": {
|
||||||
|
"pre-commit": "lint-staged"
|
||||||
|
}
|
||||||
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/PanJiaChen/vue-element-admin.git"
|
"url": "git+https://github.com/PanJiaChen/vue-element-admin.git"
|
||||||
},
|
}
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/PanJiaChen/vue-element-admin/issues"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"axios": "0.18.1",
|
|
||||||
"clipboard": "2.0.4",
|
|
||||||
"codemirror": "5.45.0",
|
|
||||||
"driver.js": "0.9.5",
|
|
||||||
"dropzone": "5.5.1",
|
|
||||||
"echarts": "4.2.1",
|
|
||||||
"element-ui": "2.7.0",
|
|
||||||
"file-saver": "2.0.1",
|
|
||||||
"fuse.js": "3.4.4",
|
|
||||||
"js-cookie": "2.2.0",
|
|
||||||
"jsonlint": "1.6.3",
|
|
||||||
"jszip": "3.2.1",
|
|
||||||
"normalize.css": "7.0.0",
|
|
||||||
"nprogress": "0.2.0",
|
|
||||||
"path-to-regexp": "2.4.0",
|
|
||||||
"screenfull": "4.2.0",
|
|
||||||
"showdown": "1.9.0",
|
|
||||||
"sortablejs": "1.8.4",
|
|
||||||
"tui-editor": "1.3.3",
|
|
||||||
"vue": "2.6.10",
|
|
||||||
"vue-count-to": "1.0.13",
|
|
||||||
"vue-router": "3.0.2",
|
|
||||||
"vue-splitpane": "1.0.4",
|
|
||||||
"vuedraggable": "2.20.0",
|
|
||||||
"vuex": "3.1.0",
|
|
||||||
"xlsx": "0.14.1"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@babel/core": "7.0.0",
|
|
||||||
"@babel/register": "7.0.0",
|
|
||||||
"@vue/cli-plugin-babel": "3.5.3",
|
|
||||||
"@vue/cli-plugin-eslint": "^3.9.1",
|
|
||||||
"@vue/cli-plugin-unit-jest": "3.5.3",
|
|
||||||
"@vue/cli-service": "3.5.3",
|
|
||||||
"@vue/test-utils": "1.0.0-beta.29",
|
|
||||||
"autoprefixer": "^9.5.1",
|
|
||||||
"babel-core": "7.0.0-bridge.0",
|
|
||||||
"babel-eslint": "10.0.1",
|
|
||||||
"babel-jest": "23.6.0",
|
|
||||||
"chalk": "2.4.2",
|
|
||||||
"chokidar": "2.1.5",
|
|
||||||
"connect": "3.6.6",
|
|
||||||
"eslint": "5.15.3",
|
|
||||||
"eslint-plugin-vue": "5.2.2",
|
|
||||||
"html-webpack-plugin": "3.2.0",
|
|
||||||
"husky": "1.3.1",
|
|
||||||
"lint-staged": "8.1.5",
|
|
||||||
"mockjs": "1.0.1-beta3",
|
|
||||||
"node-sass": "^4.9.0",
|
|
||||||
"plop": "2.3.0",
|
|
||||||
"runjs": "^4.3.2",
|
|
||||||
"sass-loader": "^7.1.0",
|
|
||||||
"script-ext-html-webpack-plugin": "2.1.3",
|
|
||||||
"script-loader": "0.7.2",
|
|
||||||
"serve-static": "^1.13.2",
|
|
||||||
"svg-sprite-loader": "4.1.3",
|
|
||||||
"svgo": "1.2.0",
|
|
||||||
"vue-template-compiler": "2.6.10"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8.9",
|
|
||||||
"npm": ">= 3.0.0"
|
|
||||||
},
|
|
||||||
"browserslist": [
|
|
||||||
"> 1%",
|
|
||||||
"last 2 versions"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
{{#if state}}
|
||||||
|
const state = {}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if mutations}}
|
||||||
|
const mutations = {}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if actions}}
|
||||||
|
const actions = {}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
namespaced: true,
|
||||||
|
{{options}}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
const { notEmpty } = require('../utils.js')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
description: 'generate store',
|
||||||
|
prompts: [{
|
||||||
|
type: 'input',
|
||||||
|
name: 'name',
|
||||||
|
message: 'store name please',
|
||||||
|
validate: notEmpty('name')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'checkbox',
|
||||||
|
name: 'blocks',
|
||||||
|
message: 'Blocks:',
|
||||||
|
choices: [{
|
||||||
|
name: 'state',
|
||||||
|
value: 'state',
|
||||||
|
checked: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'mutations',
|
||||||
|
value: 'mutations',
|
||||||
|
checked: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'actions',
|
||||||
|
value: 'actions',
|
||||||
|
checked: true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
validate(value) {
|
||||||
|
if (!value.includes('state') || !value.includes('mutations')) {
|
||||||
|
return 'store require at least state and mutations'
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
actions(data) {
|
||||||
|
const name = '{{name}}'
|
||||||
|
const { blocks } = data
|
||||||
|
const options = ['state', 'mutations']
|
||||||
|
const joinFlag = `,
|
||||||
|
`
|
||||||
|
if (blocks.length === 3) {
|
||||||
|
options.push('actions')
|
||||||
|
}
|
||||||
|
|
||||||
|
const actions = [{
|
||||||
|
type: 'add',
|
||||||
|
path: `src/store/modules/${name}.js`,
|
||||||
|
templateFile: 'plop-templates/store/index.hbs',
|
||||||
|
data: {
|
||||||
|
options: options.join(joinFlag),
|
||||||
|
state: blocks.includes('state'),
|
||||||
|
mutations: blocks.includes('mutations'),
|
||||||
|
actions: blocks.includes('actions')
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
return actions
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,2 @@
|
||||||
exports.notEmpty = name => {
|
exports.notEmpty = name => v =>
|
||||||
return v => {
|
!v || v.trim() === '' ? `${name} is required` : true
|
||||||
if (!v || v.trim === '') {
|
|
||||||
return `${name} is required`
|
|
||||||
} else {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
const viewGenerator = require('./plop-templates/view/prompt')
|
const viewGenerator = require('./plop-templates/view/prompt')
|
||||||
const componentGenerator = require('./plop-templates/component/prompt')
|
const componentGenerator = require('./plop-templates/component/prompt')
|
||||||
|
const storeGenerator = require('./plop-templates/store/prompt.js')
|
||||||
|
|
||||||
module.exports = function(plop) {
|
module.exports = function(plop) {
|
||||||
plop.setGenerator('view', viewGenerator)
|
plop.setGenerator('view', viewGenerator)
|
||||||
plop.setGenerator('component', componentGenerator)
|
plop.setGenerator('component', componentGenerator)
|
||||||
|
plop.setGenerator('store', storeGenerator)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import request from '@/utils/request'
|
||||||
|
|
||||||
export function fetchList(query) {
|
export function fetchList(query) {
|
||||||
return request({
|
return request({
|
||||||
url: '/article/list',
|
url: '/vue-element-admin/article/list',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params: query
|
params: query
|
||||||
})
|
})
|
||||||
|
@ -10,7 +10,7 @@ export function fetchList(query) {
|
||||||
|
|
||||||
export function fetchArticle(id) {
|
export function fetchArticle(id) {
|
||||||
return request({
|
return request({
|
||||||
url: '/article/detail',
|
url: '/vue-element-admin/article/detail',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params: { id }
|
params: { id }
|
||||||
})
|
})
|
||||||
|
@ -18,7 +18,7 @@ export function fetchArticle(id) {
|
||||||
|
|
||||||
export function fetchPv(pv) {
|
export function fetchPv(pv) {
|
||||||
return request({
|
return request({
|
||||||
url: '/article/pv',
|
url: '/vue-element-admin/article/pv',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params: { pv }
|
params: { pv }
|
||||||
})
|
})
|
||||||
|
@ -26,7 +26,7 @@ export function fetchPv(pv) {
|
||||||
|
|
||||||
export function createArticle(data) {
|
export function createArticle(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/article/create',
|
url: '/vue-element-admin/article/create',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
|
@ -34,7 +34,7 @@ export function createArticle(data) {
|
||||||
|
|
||||||
export function updateArticle(data) {
|
export function updateArticle(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/article/update',
|
url: '/vue-element-admin/article/update',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,7 +2,7 @@ import request from '@/utils/request'
|
||||||
|
|
||||||
export function searchUser(name) {
|
export function searchUser(name) {
|
||||||
return request({
|
return request({
|
||||||
url: '/search/user',
|
url: '/vue-element-admin/search/user',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params: { name }
|
params: { name }
|
||||||
})
|
})
|
||||||
|
@ -10,7 +10,7 @@ export function searchUser(name) {
|
||||||
|
|
||||||
export function transactionList(query) {
|
export function transactionList(query) {
|
||||||
return request({
|
return request({
|
||||||
url: '/transaction/list',
|
url: '/vue-element-admin/transaction/list',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params: query
|
params: query
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,21 +2,21 @@ import request from '@/utils/request'
|
||||||
|
|
||||||
export function getRoutes() {
|
export function getRoutes() {
|
||||||
return request({
|
return request({
|
||||||
url: '/routes',
|
url: '/vue-element-admin/routes',
|
||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getRoles() {
|
export function getRoles() {
|
||||||
return request({
|
return request({
|
||||||
url: '/roles',
|
url: '/vue-element-admin/roles',
|
||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function addRole(data) {
|
export function addRole(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/role',
|
url: '/vue-element-admin/role',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
|
@ -24,7 +24,7 @@ export function addRole(data) {
|
||||||
|
|
||||||
export function updateRole(id, data) {
|
export function updateRole(id, data) {
|
||||||
return request({
|
return request({
|
||||||
url: `/role/${id}`,
|
url: `/vue-element-admin/role/${id}`,
|
||||||
method: 'put',
|
method: 'put',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
|
@ -32,7 +32,7 @@ export function updateRole(id, data) {
|
||||||
|
|
||||||
export function deleteRole(id) {
|
export function deleteRole(id) {
|
||||||
return request({
|
return request({
|
||||||
url: `/role/${id}`,
|
url: `/vue-element-admin/role/${id}`,
|
||||||
method: 'delete'
|
method: 'delete'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import request from '@/utils/request'
|
||||||
|
|
||||||
export function login(data) {
|
export function login(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/user/login',
|
url: '/vue-element-admin/user/login',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
|
@ -10,7 +10,7 @@ export function login(data) {
|
||||||
|
|
||||||
export function getInfo(token) {
|
export function getInfo(token) {
|
||||||
return request({
|
return request({
|
||||||
url: '/user/info',
|
url: '/vue-element-admin/user/info',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params: { token }
|
params: { token }
|
||||||
})
|
})
|
||||||
|
@ -18,7 +18,7 @@ export function getInfo(token) {
|
||||||
|
|
||||||
export function logout() {
|
export function logout() {
|
||||||
return request({
|
return request({
|
||||||
url: '/user/logout',
|
url: '/vue-element-admin/user/logout',
|
||||||
method: 'post'
|
method: 'post'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,17 @@
|
||||||
<el-breadcrumb class="app-breadcrumb" separator="/">
|
<el-breadcrumb class="app-breadcrumb" separator="/">
|
||||||
<transition-group name="breadcrumb">
|
<transition-group name="breadcrumb">
|
||||||
<el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
|
<el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
|
||||||
<span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect">{{ item.meta.title }}</span>
|
<span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect">
|
||||||
<a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
|
{{ generateTitle(item.meta.title) }}
|
||||||
|
</span>
|
||||||
|
<a v-else @click.prevent="handleLink(item)">{{ generateTitle(item.meta.title) }}</a>
|
||||||
</el-breadcrumb-item>
|
</el-breadcrumb-item>
|
||||||
</transition-group>
|
</transition-group>
|
||||||
</el-breadcrumb>
|
</el-breadcrumb>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { generateTitle } from '@/utils/i18n'
|
||||||
import pathToRegexp from 'path-to-regexp'
|
import pathToRegexp from 'path-to-regexp'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -31,13 +34,14 @@ export default {
|
||||||
this.getBreadcrumb()
|
this.getBreadcrumb()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
generateTitle,
|
||||||
getBreadcrumb() {
|
getBreadcrumb() {
|
||||||
// only show routes with meta.title
|
// only show routes with meta.title
|
||||||
let matched = this.$route.matched.filter(item => item.meta && item.meta.title)
|
let matched = this.$route.matched.filter(item => item.meta && item.meta.title)
|
||||||
const first = matched[0]
|
const first = matched[0]
|
||||||
|
|
||||||
if (!this.isDashboard(first)) {
|
if (!this.isDashboard(first)) {
|
||||||
matched = [{ path: '/dashboard', meta: { title: 'Dashboard' }}].concat(matched)
|
matched = [{ path: '/dashboard', meta: { title: 'dashboard' }}].concat(matched)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
|
this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
|
||||||
|
|
|
@ -3,32 +3,54 @@ import { debounce } from '@/utils'
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
$_sidebarElm: null
|
$_sidebarElm: null,
|
||||||
|
$_resizeHandler: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.__resizeHandler = debounce(() => {
|
this.initListener()
|
||||||
if (this.chart) {
|
},
|
||||||
this.chart.resize()
|
activated() {
|
||||||
}
|
if (!this.$_resizeHandler) {
|
||||||
}, 100)
|
// avoid duplication init
|
||||||
window.addEventListener('resize', this.__resizeHandler)
|
this.initListener()
|
||||||
|
}
|
||||||
|
|
||||||
this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
|
// when keep-alive chart activated, auto resize
|
||||||
this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
|
this.resize()
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
window.removeEventListener('resize', this.__resizeHandler)
|
this.destroyListener()
|
||||||
|
},
|
||||||
this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)
|
deactivated() {
|
||||||
|
this.destroyListener()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// use $_ for mixins properties
|
// use $_ for mixins properties
|
||||||
// https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
|
// https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
|
||||||
$_sidebarResizeHandler(e) {
|
$_sidebarResizeHandler(e) {
|
||||||
if (e.propertyName === 'width') {
|
if (e.propertyName === 'width') {
|
||||||
this.__resizeHandler()
|
this.$_resizeHandler()
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
initListener() {
|
||||||
|
this.$_resizeHandler = debounce(() => {
|
||||||
|
this.resize()
|
||||||
|
}, 100)
|
||||||
|
window.addEventListener('resize', this.$_resizeHandler)
|
||||||
|
|
||||||
|
this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
|
||||||
|
this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
|
||||||
|
},
|
||||||
|
destroyListener() {
|
||||||
|
window.removeEventListener('resize', this.$_resizeHandler)
|
||||||
|
this.$_resizeHandler = null
|
||||||
|
|
||||||
|
this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)
|
||||||
|
},
|
||||||
|
resize() {
|
||||||
|
const { chart } = this
|
||||||
|
chart && chart.resize()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,14 +48,18 @@ export default {
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style lang="scss" scoped>
|
||||||
.drag-select >>> .sortable-ghost {
|
.drag-select {
|
||||||
opacity: .8;
|
::v-deep {
|
||||||
color: #fff!important;
|
.sortable-ghost {
|
||||||
background: #42b983!important;
|
opacity: .8;
|
||||||
}
|
color: #fff !important;
|
||||||
|
background: #42b983 !important;
|
||||||
|
}
|
||||||
|
|
||||||
.drag-select >>> .el-tag {
|
.el-tag {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
// make search results more in line with expectations
|
// make search results more in line with expectations
|
||||||
import Fuse from 'fuse.js'
|
import Fuse from 'fuse.js'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
|
import i18n from '@/lang'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'HeaderSearch',
|
name: 'HeaderSearch',
|
||||||
|
@ -37,13 +38,26 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
routes() {
|
routes() {
|
||||||
return this.$store.getters.permission_routes
|
return this.$store.getters.permission_routes
|
||||||
|
},
|
||||||
|
lang() {
|
||||||
|
return this.$store.getters.language
|
||||||
|
},
|
||||||
|
supportPinyinSearch() {
|
||||||
|
return this.$store.state.settings.supportPinyinSearch
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
lang() {
|
||||||
|
this.searchPool = this.generateRoutes(this.routes)
|
||||||
|
},
|
||||||
routes() {
|
routes() {
|
||||||
this.searchPool = this.generateRoutes(this.routes)
|
this.searchPool = this.generateRoutes(this.routes)
|
||||||
},
|
},
|
||||||
searchPool(list) {
|
searchPool(list) {
|
||||||
|
// Support pinyin search
|
||||||
|
if (this.lang === 'zh' && this.supportPinyinSearch) {
|
||||||
|
this.addPinyinField(list)
|
||||||
|
}
|
||||||
this.initFuse(list)
|
this.initFuse(list)
|
||||||
},
|
},
|
||||||
show(value) {
|
show(value) {
|
||||||
|
@ -58,6 +72,23 @@ export default {
|
||||||
this.searchPool = this.generateRoutes(this.routes)
|
this.searchPool = this.generateRoutes(this.routes)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
async addPinyinField(list) {
|
||||||
|
const { default: pinyin } = await import('pinyin')
|
||||||
|
if (Array.isArray(list)) {
|
||||||
|
list.forEach(element => {
|
||||||
|
const title = element.title
|
||||||
|
if (Array.isArray(title)) {
|
||||||
|
title.forEach(v => {
|
||||||
|
v = pinyin(v, {
|
||||||
|
style: pinyin.STYLE_NORMAL
|
||||||
|
}).join('')
|
||||||
|
element.pinyinTitle = v
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
},
|
||||||
click() {
|
click() {
|
||||||
this.show = !this.show
|
this.show = !this.show
|
||||||
if (this.show) {
|
if (this.show) {
|
||||||
|
@ -88,6 +119,9 @@ export default {
|
||||||
keys: [{
|
keys: [{
|
||||||
name: 'title',
|
name: 'title',
|
||||||
weight: 0.7
|
weight: 0.7
|
||||||
|
}, {
|
||||||
|
name: 'pinyinTitle',
|
||||||
|
weight: 0.3
|
||||||
}, {
|
}, {
|
||||||
name: 'path',
|
name: 'path',
|
||||||
weight: 0.3
|
weight: 0.3
|
||||||
|
@ -98,26 +132,23 @@ export default {
|
||||||
// And generate the internationalized title
|
// And generate the internationalized title
|
||||||
generateRoutes(routes, basePath = '/', prefixTitle = []) {
|
generateRoutes(routes, basePath = '/', prefixTitle = []) {
|
||||||
let res = []
|
let res = []
|
||||||
|
|
||||||
for (const router of routes) {
|
for (const router of routes) {
|
||||||
// skip hidden router
|
// skip hidden router
|
||||||
if (router.hidden) { continue }
|
if (router.hidden) { continue }
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
path: path.resolve(basePath, router.path),
|
path: path.resolve(basePath, router.path),
|
||||||
title: [...prefixTitle]
|
title: [...prefixTitle]
|
||||||
}
|
}
|
||||||
|
|
||||||
if (router.meta && router.meta.title) {
|
if (router.meta && router.meta.title) {
|
||||||
data.title = [...data.title, router.meta.title]
|
// generate internationalized title
|
||||||
|
const i18ntitle = i18n.t(`route.${router.meta.title}`)
|
||||||
|
data.title = [...data.title, i18ntitle]
|
||||||
if (router.redirect !== 'noRedirect') {
|
if (router.redirect !== 'noRedirect') {
|
||||||
// only push the routes with title
|
// only push the routes with title
|
||||||
// special case: need to exclude parent router without redirect
|
// special case: need to exclude parent router without redirect
|
||||||
res.push(data)
|
res.push(data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// recursive child routes
|
// recursive child routes
|
||||||
if (router.children) {
|
if (router.children) {
|
||||||
const tempRoutes = this.generateRoutes(router.children, data.path, data.title)
|
const tempRoutes = this.generateRoutes(router.children, data.path, data.title)
|
||||||
|
@ -142,13 +173,11 @@ export default {
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.header-search {
|
.header-search {
|
||||||
font-size: 0 !important;
|
font-size: 0 !important;
|
||||||
|
|
||||||
.search-icon {
|
.search-icon {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-search-select {
|
.header-search-select {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
transition: width 0.2s;
|
transition: width 0.2s;
|
||||||
|
@ -159,7 +188,7 @@ export default {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
|
||||||
/deep/ .el-input__inner {
|
::v-deep .el-input__inner {
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
border: 0;
|
border: 0;
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
|
@ -169,7 +198,6 @@ export default {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.show {
|
&.show {
|
||||||
.header-search-select {
|
.header-search-select {
|
||||||
width: 210px;
|
width: 210px;
|
||||||
|
|
|
@ -248,6 +248,7 @@ export default {
|
||||||
// 浏览器是否支持该控件
|
// 浏览器是否支持该控件
|
||||||
isSupported,
|
isSupported,
|
||||||
// 浏览器是否支持触屏事件
|
// 浏览器是否支持触屏事件
|
||||||
|
// eslint-disable-next-line no-prototype-builtins
|
||||||
isSupportTouch: document.hasOwnProperty('ontouchstart'),
|
isSupportTouch: document.hasOwnProperty('ontouchstart'),
|
||||||
// 步骤
|
// 步骤
|
||||||
step: 1, // 1选择文件 2剪裁 3上传
|
step: 1, // 1选择文件 2剪裁 3上传
|
||||||
|
|
|
@ -54,19 +54,24 @@ export default {
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style lang="scss" scoped>
|
||||||
.json-editor{
|
.json-editor {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
|
||||||
.json-editor >>> .CodeMirror {
|
::v-deep {
|
||||||
height: auto;
|
.CodeMirror {
|
||||||
min-height: 300px;
|
height: auto;
|
||||||
}
|
min-height: 300px;
|
||||||
.json-editor >>> .CodeMirror-scroll{
|
}
|
||||||
min-height: 300px;
|
|
||||||
}
|
.CodeMirror-scroll {
|
||||||
.json-editor >>> .cm-s-rubyblue span.cm-string {
|
min-height: 300px;
|
||||||
color: #F08047;
|
}
|
||||||
|
|
||||||
|
.cm-s-rubyblue span.cm-string {
|
||||||
|
color: #F08047;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
<template>
|
||||||
|
<el-dropdown trigger="click" class="international" @command="handleSetLanguage">
|
||||||
|
<div>
|
||||||
|
<svg-icon class-name="international-icon" icon-class="language" />
|
||||||
|
</div>
|
||||||
|
<el-dropdown-menu slot="dropdown">
|
||||||
|
<el-dropdown-item :disabled="language==='zh'" command="zh">
|
||||||
|
中文
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item :disabled="language==='en'" command="en">
|
||||||
|
English
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item :disabled="language==='es'" command="es">
|
||||||
|
Español
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item :disabled="language==='ja'" command="ja">
|
||||||
|
日本語
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</el-dropdown>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
computed: {
|
||||||
|
language() {
|
||||||
|
return this.$store.getters.language
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleSetLanguage(lang) {
|
||||||
|
this.$i18n.locale = lang
|
||||||
|
this.$store.dispatch('app/setLanguage', lang)
|
||||||
|
this.$message({
|
||||||
|
message: 'Switch Language Success',
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -12,7 +12,7 @@ import Editor from 'tui-editor'
|
||||||
import defaultOptions from './default-options'
|
import defaultOptions from './default-options'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'MarddownEditor',
|
name: 'MarkdownEditor',
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: String,
|
type: String,
|
||||||
|
|
|
@ -44,6 +44,7 @@ $t: .1s;
|
||||||
width: 250px;
|
width: 250px;
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
height: auto!important;
|
||||||
&-title {
|
&-title {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: block;
|
display: block;
|
||||||
|
@ -65,10 +66,12 @@ $t: .1s;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: #e0e0e0;
|
background: #e0e0e0;
|
||||||
|
color: #000;
|
||||||
line-height: 60px;
|
line-height: 60px;
|
||||||
height: 60px;
|
height: 60px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 20px;
|
font-size: 18px;
|
||||||
|
overflow: hidden;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transition: transform 0.28s ease;
|
transition: transform 0.28s ease;
|
||||||
&:hover {
|
&:hover {
|
||||||
|
@ -90,7 +93,7 @@ $t: .1s;
|
||||||
.share-dropdown-menu-item {
|
.share-dropdown-menu-item {
|
||||||
@for $i from 1 through $n {
|
@for $i from 1 through $n {
|
||||||
&:nth-of-type(#{$i}) {
|
&:nth-of-type(#{$i}) {
|
||||||
transition-delay: ($n - $i)*$t;
|
transition-delay: ($n - $i)*$t;
|
||||||
transform: translate3d(0, ($i - 1)*60px, 0);
|
transform: translate3d(0, ($i - 1)*60px, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" />
|
<div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" />
|
||||||
<svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
|
<svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
|
||||||
<use :href="iconName" />
|
<use :xlink:href="iconName" />
|
||||||
</svg>
|
</svg>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,7 @@ export default {
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.editor-slide-upload {
|
.editor-slide-upload {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
/deep/ .el-upload--picture-card {
|
::v-deep .el-upload--picture-card {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,9 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
language() {
|
||||||
|
return this.languageTypeList[this.$store.getters.language]
|
||||||
|
},
|
||||||
containerWidth() {
|
containerWidth() {
|
||||||
const width = this.width
|
const width = this.width
|
||||||
if (/^[\d]+(\.[\d]+)?$/.test(width)) { // matches `100`, `'100'`
|
if (/^[\d]+(\.[\d]+)?$/.test(width)) { // matches `100`, `'100'`
|
||||||
|
@ -85,6 +88,10 @@ export default {
|
||||||
this.$nextTick(() =>
|
this.$nextTick(() =>
|
||||||
window.tinymce.get(this.tinymceId).setContent(val || ''))
|
window.tinymce.get(this.tinymceId).setContent(val || ''))
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
language() {
|
||||||
|
this.destroyTinymce()
|
||||||
|
this.$nextTick(() => this.initTinymce())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -115,8 +122,8 @@ export default {
|
||||||
initTinymce() {
|
initTinymce() {
|
||||||
const _this = this
|
const _this = this
|
||||||
window.tinymce.init({
|
window.tinymce.init({
|
||||||
|
language: this.language,
|
||||||
selector: `#${this.tinymceId}`,
|
selector: `#${this.tinymceId}`,
|
||||||
language: this.languageTypeList['en'],
|
|
||||||
height: this.height,
|
height: this.height,
|
||||||
body_class: 'panel-body ',
|
body_class: 'panel-body ',
|
||||||
object_resizing: false,
|
object_resizing: false,
|
||||||
|
@ -147,7 +154,11 @@ export default {
|
||||||
editor.on('FullscreenStateChanged', (e) => {
|
editor.on('FullscreenStateChanged', (e) => {
|
||||||
_this.fullscreen = e.state
|
_this.fullscreen = e.state
|
||||||
})
|
})
|
||||||
}
|
},
|
||||||
|
// it will try to keep these URLs intact
|
||||||
|
// https://www.tiny.cloud/docs-3x/reference/configuration/Configuration3x@convert_urls/
|
||||||
|
// https://stackoverflow.com/questions/5196205/disable-tinymce-absolute-to-relative-url-conversions
|
||||||
|
convert_urls: false
|
||||||
// 整合七牛上传
|
// 整合七牛上传
|
||||||
// images_dataimg_filter(img) {
|
// images_dataimg_filter(img) {
|
||||||
// setTimeout(() => {
|
// setTimeout(() => {
|
||||||
|
@ -200,37 +211,43 @@ export default {
|
||||||
window.tinymce.get(this.tinymceId).getContent()
|
window.tinymce.get(this.tinymceId).getContent()
|
||||||
},
|
},
|
||||||
imageSuccessCBK(arr) {
|
imageSuccessCBK(arr) {
|
||||||
const _this = this
|
arr.forEach(v => window.tinymce.get(this.tinymceId).insertContent(`<img class="wscnph" src="${v.url}" >`))
|
||||||
arr.forEach(v => {
|
|
||||||
window.tinymce.get(_this.tinymceId).insertContent(`<img class="wscnph" src="${v.url}" >`)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style lang="scss" scoped>
|
||||||
.tinymce-container {
|
.tinymce-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
line-height: normal;
|
line-height: normal;
|
||||||
}
|
}
|
||||||
.tinymce-container>>>.mce-fullscreen {
|
|
||||||
z-index: 10000;
|
.tinymce-container {
|
||||||
|
::v-deep {
|
||||||
|
.mce-fullscreen {
|
||||||
|
z-index: 10000;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.tinymce-textarea {
|
.tinymce-textarea {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-custom-btn-container {
|
.editor-custom-btn-container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 4px;
|
right: 4px;
|
||||||
top: 4px;
|
top: 4px;
|
||||||
/*z-index: 2005;*/
|
/*z-index: 2005;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullscreen .editor-custom-btn-container {
|
.fullscreen .editor-custom-btn-container {
|
||||||
z-index: 10000;
|
z-index: 10000;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-upload-btn {
|
.editor-upload-btn {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import store from '@/store'
|
import store from '@/store'
|
||||||
|
|
||||||
export default {
|
function checkPermission(el, binding) {
|
||||||
inserted(el, binding, vnode) {
|
const { value } = binding
|
||||||
const { value } = binding
|
const roles = store.getters && store.getters.roles
|
||||||
const roles = store.getters && store.getters.roles
|
|
||||||
|
|
||||||
if (value && value instanceof Array && value.length > 0) {
|
if (value && value instanceof Array) {
|
||||||
|
if (value.length > 0) {
|
||||||
const permissionRoles = value
|
const permissionRoles = value
|
||||||
|
|
||||||
const hasPermission = roles.some(role => {
|
const hasPermission = roles.some(role => {
|
||||||
|
@ -15,8 +15,17 @@ export default {
|
||||||
if (!hasPermission) {
|
if (!hasPermission) {
|
||||||
el.parentNode && el.parentNode.removeChild(el)
|
el.parentNode && el.parentNode.removeChild(el)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
throw new Error(`need roles! Like v-permission="['admin','editor']"`)
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
throw new Error(`need roles! Like v-permission="['admin','editor']"`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
inserted(el, binding) {
|
||||||
|
checkPermission(el, binding)
|
||||||
|
},
|
||||||
|
update(el, binding) {
|
||||||
|
checkPermission(el, binding)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,175 @@
|
||||||
|
export default {
|
||||||
|
route: {
|
||||||
|
dashboard: 'Dashboard',
|
||||||
|
documentation: 'Documentation',
|
||||||
|
guide: 'Guide',
|
||||||
|
permission: 'Permission',
|
||||||
|
pagePermission: 'Page Permission',
|
||||||
|
rolePermission: 'Role Permission',
|
||||||
|
directivePermission: 'Directive Permission',
|
||||||
|
icons: 'Icons',
|
||||||
|
components: 'Components',
|
||||||
|
tinymce: 'Tinymce',
|
||||||
|
markdown: 'Markdown',
|
||||||
|
jsonEditor: 'JSON Editor',
|
||||||
|
dndList: 'Dnd List',
|
||||||
|
splitPane: 'SplitPane',
|
||||||
|
avatarUpload: 'Avatar Upload',
|
||||||
|
dropzone: 'Dropzone',
|
||||||
|
sticky: 'Sticky',
|
||||||
|
countTo: 'Count To',
|
||||||
|
componentMixin: 'Mixin',
|
||||||
|
backToTop: 'Back To Top',
|
||||||
|
dragDialog: 'Drag Dialog',
|
||||||
|
dragSelect: 'Drag Select',
|
||||||
|
dragKanban: 'Drag Kanban',
|
||||||
|
charts: 'Charts',
|
||||||
|
keyboardChart: 'Keyboard Chart',
|
||||||
|
lineChart: 'Line Chart',
|
||||||
|
mixChart: 'Mix Chart',
|
||||||
|
example: 'Example',
|
||||||
|
nested: 'Nested Routes',
|
||||||
|
menu1: 'Menu 1',
|
||||||
|
'menu1-1': 'Menu 1-1',
|
||||||
|
'menu1-2': 'Menu 1-2',
|
||||||
|
'menu1-2-1': 'Menu 1-2-1',
|
||||||
|
'menu1-2-2': 'Menu 1-2-2',
|
||||||
|
'menu1-3': 'Menu 1-3',
|
||||||
|
menu2: 'Menu 2',
|
||||||
|
Table: 'Table',
|
||||||
|
dynamicTable: 'Dynamic Table',
|
||||||
|
dragTable: 'Drag Table',
|
||||||
|
inlineEditTable: 'Inline Edit',
|
||||||
|
complexTable: 'Complex Table',
|
||||||
|
tab: 'Tab',
|
||||||
|
form: 'Form',
|
||||||
|
createArticle: 'Create Article',
|
||||||
|
editArticle: 'Edit Article',
|
||||||
|
articleList: 'Article List',
|
||||||
|
errorPages: 'Error Pages',
|
||||||
|
page401: '401',
|
||||||
|
page404: '404',
|
||||||
|
errorLog: 'Error Log',
|
||||||
|
excel: 'Excel',
|
||||||
|
exportExcel: 'Export Excel',
|
||||||
|
selectExcel: 'Export Selected',
|
||||||
|
mergeHeader: 'Merge Header',
|
||||||
|
uploadExcel: 'Upload Excel',
|
||||||
|
zip: 'Zip',
|
||||||
|
pdf: 'PDF',
|
||||||
|
exportZip: 'Export Zip',
|
||||||
|
theme: 'Theme',
|
||||||
|
clipboardDemo: 'Clipboard',
|
||||||
|
i18n: 'I18n',
|
||||||
|
externalLink: 'External Link',
|
||||||
|
profile: 'Profile'
|
||||||
|
},
|
||||||
|
navbar: {
|
||||||
|
dashboard: 'Dashboard',
|
||||||
|
github: 'Github',
|
||||||
|
logOut: 'Log Out',
|
||||||
|
profile: 'Profile',
|
||||||
|
theme: 'Theme',
|
||||||
|
size: 'Global Size'
|
||||||
|
},
|
||||||
|
login: {
|
||||||
|
title: 'Login Form',
|
||||||
|
logIn: 'Login',
|
||||||
|
username: 'Username',
|
||||||
|
password: 'Password',
|
||||||
|
any: 'any',
|
||||||
|
thirdparty: 'Or connect with',
|
||||||
|
thirdpartyTips: 'Can not be simulated on local, so please combine you own business simulation! ! !'
|
||||||
|
},
|
||||||
|
documentation: {
|
||||||
|
documentation: 'Documentation',
|
||||||
|
github: 'Github Repository'
|
||||||
|
},
|
||||||
|
permission: {
|
||||||
|
addRole: 'New Role',
|
||||||
|
editPermission: 'Edit',
|
||||||
|
roles: 'Your roles',
|
||||||
|
switchRoles: 'Switch roles',
|
||||||
|
tips: 'In some cases, using v-permission will have no effect. For example: Element-UI el-tab or el-table-column and other scenes that dynamically render dom. You can only do this with v-if.',
|
||||||
|
delete: 'Delete',
|
||||||
|
confirm: 'Confirm',
|
||||||
|
cancel: 'Cancel'
|
||||||
|
},
|
||||||
|
guide: {
|
||||||
|
description: 'The guide page is useful for some people who entered the project for the first time. You can briefly introduce the features of the project. Demo is based on ',
|
||||||
|
button: 'Show Guide'
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
documentation: 'Documentation',
|
||||||
|
tinymceTips: 'Rich text is a core feature of the management backend, but at the same time it is a place with lots of pits. In the process of selecting rich texts, I also took a lot of detours. The common rich texts on the market have been basically used, and I finally chose Tinymce. See the more detailed rich text comparison and introduction.',
|
||||||
|
dropzoneTips: 'Because my business has special needs, and has to upload images to qiniu, so instead of a third party, I chose encapsulate it by myself. It is very simple, you can see the detail code in @/components/Dropzone.',
|
||||||
|
stickyTips: 'when the page is scrolled to the preset position will be sticky on the top.',
|
||||||
|
backToTopTips1: 'When the page is scrolled to the specified position, the Back to Top button appears in the lower right corner',
|
||||||
|
backToTopTips2: 'You can customize the style of the button, show / hide, height of appearance, height of the return. If you need a text prompt, you can use element-ui el-tooltip elements externally',
|
||||||
|
imageUploadTips: 'Since I was using only the vue@1 version, and it is not compatible with mockjs at the moment, I modified it myself, and if you are going to use it, it is better to use official version.'
|
||||||
|
},
|
||||||
|
table: {
|
||||||
|
dynamicTips1: 'Fixed header, sorted by header order',
|
||||||
|
dynamicTips2: 'Not fixed header, sorted by click order',
|
||||||
|
dragTips1: 'The default order',
|
||||||
|
dragTips2: 'The after dragging order',
|
||||||
|
title: 'Title',
|
||||||
|
importance: 'Imp',
|
||||||
|
type: 'Type',
|
||||||
|
remark: 'Remark',
|
||||||
|
search: 'Search',
|
||||||
|
add: 'Add',
|
||||||
|
export: 'Export',
|
||||||
|
reviewer: 'reviewer',
|
||||||
|
id: 'ID',
|
||||||
|
date: 'Date',
|
||||||
|
author: 'Author',
|
||||||
|
readings: 'Readings',
|
||||||
|
status: 'Status',
|
||||||
|
actions: 'Actions',
|
||||||
|
edit: 'Edit',
|
||||||
|
publish: 'Publish',
|
||||||
|
draft: 'Draft',
|
||||||
|
delete: 'Delete',
|
||||||
|
cancel: 'Cancel',
|
||||||
|
confirm: 'Confirm'
|
||||||
|
},
|
||||||
|
example: {
|
||||||
|
warning: 'Creating and editing pages cannot be cached by keep-alive because keep-alive include does not currently support caching based on routes, so it is currently cached based on component name. If you want to achieve a similar caching effect, you can use a browser caching scheme such as localStorage. Or do not use keep-alive include to cache all pages directly. See details'
|
||||||
|
},
|
||||||
|
errorLog: {
|
||||||
|
tips: 'Please click the bug icon in the upper right corner',
|
||||||
|
description: 'Now the management system are basically the form of the spa, it enhances the user experience, but it also increases the possibility of page problems, a small negligence may lead to the entire page deadlock. Fortunately Vue provides a way to catch handling exceptions, where you can handle errors or report exceptions.',
|
||||||
|
documentation: 'Document introduction'
|
||||||
|
},
|
||||||
|
excel: {
|
||||||
|
export: 'Export',
|
||||||
|
selectedExport: 'Export Selected Items',
|
||||||
|
placeholder: 'Please enter the file name (default excel-list)'
|
||||||
|
},
|
||||||
|
zip: {
|
||||||
|
export: 'Export',
|
||||||
|
placeholder: 'Please enter the file name (default file)'
|
||||||
|
},
|
||||||
|
pdf: {
|
||||||
|
tips: 'Here we use window.print() to implement the feature of downloading PDF.'
|
||||||
|
},
|
||||||
|
theme: {
|
||||||
|
change: 'Change Theme',
|
||||||
|
documentation: 'Theme documentation',
|
||||||
|
tips: 'Tips: It is different from the theme-pick on the navbar is two different skinning methods, each with different application scenarios. Refer to the documentation for details.'
|
||||||
|
},
|
||||||
|
tagsView: {
|
||||||
|
refresh: 'Refresh',
|
||||||
|
close: 'Close',
|
||||||
|
closeOthers: 'Close Others',
|
||||||
|
closeAll: 'Close All'
|
||||||
|
},
|
||||||
|
settings: {
|
||||||
|
title: 'Page style setting',
|
||||||
|
theme: 'Theme Color',
|
||||||
|
tagsView: 'Open Tags-View',
|
||||||
|
fixedHeader: 'Fixed Header',
|
||||||
|
sidebarLogo: 'Sidebar Logo'
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,175 @@
|
||||||
|
export default {
|
||||||
|
route: {
|
||||||
|
dashboard: 'Panel de control',
|
||||||
|
documentation: 'Documentación',
|
||||||
|
guide: 'Guía',
|
||||||
|
permission: 'Permisos',
|
||||||
|
rolePermission: 'Permisos de rol',
|
||||||
|
pagePermission: 'Permisos de la página',
|
||||||
|
directivePermission: 'Permisos de la directiva',
|
||||||
|
icons: 'Iconos',
|
||||||
|
components: 'Componentes',
|
||||||
|
tinymce: 'Tinymce',
|
||||||
|
markdown: 'Markdown',
|
||||||
|
jsonEditor: 'Editor JSON',
|
||||||
|
dndList: 'Lista Dnd',
|
||||||
|
splitPane: 'Panel dividido',
|
||||||
|
avatarUpload: 'Subir avatar',
|
||||||
|
dropzone: 'Subir ficheros',
|
||||||
|
sticky: 'Sticky',
|
||||||
|
countTo: 'CountTo',
|
||||||
|
componentMixin: 'Mixin',
|
||||||
|
backToTop: 'Ir arriba',
|
||||||
|
dragDialog: 'Drag Dialog',
|
||||||
|
dragSelect: 'Drag Select',
|
||||||
|
dragKanban: 'Drag Kanban',
|
||||||
|
charts: 'Gráficos',
|
||||||
|
keyboardChart: 'Keyboard Chart',
|
||||||
|
lineChart: 'Gráfico de líneas',
|
||||||
|
mixChart: 'Mix Chart',
|
||||||
|
example: 'Ejemplo',
|
||||||
|
nested: 'Rutas anidadass',
|
||||||
|
menu1: 'Menu 1',
|
||||||
|
'menu1-1': 'Menu 1-1',
|
||||||
|
'menu1-2': 'Menu 1-2',
|
||||||
|
'menu1-2-1': 'Menu 1-2-1',
|
||||||
|
'menu1-2-2': 'Menu 1-2-2',
|
||||||
|
'menu1-3': 'Menu 1-3',
|
||||||
|
menu2: 'Menu 2',
|
||||||
|
Table: 'Tabla',
|
||||||
|
dynamicTable: 'Tabla dinámica',
|
||||||
|
dragTable: 'Arrastrar tabla',
|
||||||
|
inlineEditTable: 'Editor',
|
||||||
|
complexTable: 'Complex Table',
|
||||||
|
tab: 'Pestaña',
|
||||||
|
form: 'Formulario',
|
||||||
|
createArticle: 'Crear artículo',
|
||||||
|
editArticle: 'Editar artículo',
|
||||||
|
articleList: 'Listado de artículos',
|
||||||
|
errorPages: 'Páginas de error',
|
||||||
|
page401: '401',
|
||||||
|
page404: '404',
|
||||||
|
errorLog: 'Registro de errores',
|
||||||
|
excel: 'Excel',
|
||||||
|
exportExcel: 'Exportar a Excel',
|
||||||
|
selectExcel: 'Export seleccionado',
|
||||||
|
mergeHeader: 'Merge Header',
|
||||||
|
uploadExcel: 'Subir Excel',
|
||||||
|
zip: 'Zip',
|
||||||
|
pdf: 'PDF',
|
||||||
|
exportZip: 'Exportar a Zip',
|
||||||
|
theme: 'Tema',
|
||||||
|
clipboardDemo: 'Clipboard',
|
||||||
|
i18n: 'I18n',
|
||||||
|
externalLink: 'Enlace externo',
|
||||||
|
profile: 'Profile'
|
||||||
|
},
|
||||||
|
navbar: {
|
||||||
|
logOut: 'Salir',
|
||||||
|
dashboard: 'Panel de control',
|
||||||
|
github: 'Github',
|
||||||
|
theme: 'Tema',
|
||||||
|
size: 'Tamaño global',
|
||||||
|
profile: 'Profile'
|
||||||
|
},
|
||||||
|
login: {
|
||||||
|
title: 'Formulario de acceso',
|
||||||
|
logIn: 'Acceso',
|
||||||
|
username: 'Usuario',
|
||||||
|
password: 'Contraseña',
|
||||||
|
any: 'nada',
|
||||||
|
thirdparty: 'Conectar con',
|
||||||
|
thirdpartyTips: 'No se puede simular en local, así que combine su propia simulación de negocios. ! !'
|
||||||
|
},
|
||||||
|
documentation: {
|
||||||
|
documentation: 'Documentación',
|
||||||
|
github: 'Repositorio Github'
|
||||||
|
},
|
||||||
|
permission: {
|
||||||
|
addRole: 'Nuevo rol',
|
||||||
|
editPermission: 'Permiso de edición',
|
||||||
|
roles: 'Tus permisos',
|
||||||
|
switchRoles: 'Cambiar permisos',
|
||||||
|
tips: 'In some cases it is not suitable to use v-permission, such as element Tab component or el-table-column and other asynchronous rendering dom cases which can only be achieved by manually setting the v-if.',
|
||||||
|
delete: 'Borrar',
|
||||||
|
confirm: 'Confirmar',
|
||||||
|
cancel: 'Cancelar'
|
||||||
|
},
|
||||||
|
guide: {
|
||||||
|
description: 'The guide page is useful for some people who entered the project for the first time. You can briefly introduce the features of the project. Demo is based on ',
|
||||||
|
button: 'Ver guía'
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
documentation: 'Documentación',
|
||||||
|
tinymceTips: 'Rich text editor is a core part of management system, but at the same time is a place with lots of problems. In the process of selecting rich texts, I also walked a lot of detours. The common rich text editors in the market are basically used, and the finally chose Tinymce. See documentation for more detailed rich text editor comparisons and introductions.',
|
||||||
|
dropzoneTips: 'Because my business has special needs, and has to upload images to qiniu, so instead of a third party, I chose encapsulate it by myself. It is very simple, you can see the detail code in @/components/Dropzone.',
|
||||||
|
stickyTips: 'when the page is scrolled to the preset position will be sticky on the top.',
|
||||||
|
backToTopTips1: 'When the page is scrolled to the specified position, the Back to Top button appears in the lower right corner',
|
||||||
|
backToTopTips2: 'You can customize the style of the button, show / hide, height of appearance, height of the return. If you need a text prompt, you can use element-ui el-tooltip elements externally',
|
||||||
|
imageUploadTips: 'Since I was using only the vue@1 version, and it is not compatible with mockjs at the moment, I modified it myself, and if you are going to use it, it is better to use official version.'
|
||||||
|
},
|
||||||
|
table: {
|
||||||
|
dynamicTips1: 'Fixed header, sorted by header order',
|
||||||
|
dynamicTips2: 'Not fixed header, sorted by click order',
|
||||||
|
dragTips1: 'Orden por defecto',
|
||||||
|
dragTips2: 'The after dragging order',
|
||||||
|
title: 'Título',
|
||||||
|
importance: 'Importancia',
|
||||||
|
type: 'Tipo',
|
||||||
|
remark: 'Remark',
|
||||||
|
search: 'Buscar',
|
||||||
|
add: 'Añadir',
|
||||||
|
export: 'Exportar',
|
||||||
|
reviewer: 'reviewer',
|
||||||
|
id: 'ID',
|
||||||
|
date: 'Fecha',
|
||||||
|
author: 'Autor',
|
||||||
|
readings: 'Lector',
|
||||||
|
status: 'Estado',
|
||||||
|
actions: 'Acciones',
|
||||||
|
edit: 'Editar',
|
||||||
|
publish: 'Publicar',
|
||||||
|
draft: 'Draft',
|
||||||
|
delete: 'Eliminar',
|
||||||
|
cancel: 'Cancelar',
|
||||||
|
confirm: 'Confirmar'
|
||||||
|
},
|
||||||
|
example: {
|
||||||
|
warning: 'Creating and editing pages cannot be cached by keep-alive because keep-alive include does not currently support caching based on routes, so it is currently cached based on component name. If you want to achieve a similar caching effect, you can use a browser caching scheme such as localStorage. Or do not use keep-alive include to cache all pages directly. See details'
|
||||||
|
},
|
||||||
|
errorLog: {
|
||||||
|
tips: 'Please click the bug icon in the upper right corner',
|
||||||
|
description: 'Now the management system are basically the form of the spa, it enhances the user experience, but it also increases the possibility of page problems, a small negligence may lead to the entire page deadlock. Fortunately Vue provides a way to catch handling exceptions, where you can handle errors or report exceptions.',
|
||||||
|
documentation: 'Documento de introducción'
|
||||||
|
},
|
||||||
|
excel: {
|
||||||
|
export: 'Exportar',
|
||||||
|
selectedExport: 'Exportar seleccionados',
|
||||||
|
placeholder: 'Por favor escribe un nombre de fichero'
|
||||||
|
},
|
||||||
|
zip: {
|
||||||
|
export: 'Exportar',
|
||||||
|
placeholder: 'Por favor escribe un nombre de fichero'
|
||||||
|
},
|
||||||
|
pdf: {
|
||||||
|
tips: 'Here we use window.print() to implement the feature of downloading pdf.'
|
||||||
|
},
|
||||||
|
theme: {
|
||||||
|
change: 'Cambiar tema',
|
||||||
|
documentation: 'Documentación del tema',
|
||||||
|
tips: 'Tips: It is different from the theme-pick on the navbar is two different skinning methods, each with different application scenarios. Refer to the documentation for details.'
|
||||||
|
},
|
||||||
|
tagsView: {
|
||||||
|
refresh: 'Actualizar',
|
||||||
|
close: 'Cerrar',
|
||||||
|
closeOthers: 'Cerrar otros',
|
||||||
|
closeAll: 'Cerrar todos'
|
||||||
|
},
|
||||||
|
settings: {
|
||||||
|
title: 'Page style setting',
|
||||||
|
theme: 'Theme Color',
|
||||||
|
tagsView: 'Open Tags-View',
|
||||||
|
fixedHeader: 'Fixed Header',
|
||||||
|
sidebarLogo: 'Sidebar Logo'
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
import Vue from 'vue'
|
||||||
|
import VueI18n from 'vue-i18n'
|
||||||
|
import Cookies from 'js-cookie'
|
||||||
|
import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang
|
||||||
|
import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang
|
||||||
|
import elementEsLocale from 'element-ui/lib/locale/lang/es'// element-ui lang
|
||||||
|
import elementJaLocale from 'element-ui/lib/locale/lang/ja'// element-ui lang
|
||||||
|
import enLocale from './en'
|
||||||
|
import zhLocale from './zh'
|
||||||
|
import esLocale from './es'
|
||||||
|
import jaLocale from './ja'
|
||||||
|
|
||||||
|
Vue.use(VueI18n)
|
||||||
|
|
||||||
|
const messages = {
|
||||||
|
en: {
|
||||||
|
...enLocale,
|
||||||
|
...elementEnLocale
|
||||||
|
},
|
||||||
|
zh: {
|
||||||
|
...zhLocale,
|
||||||
|
...elementZhLocale
|
||||||
|
},
|
||||||
|
es: {
|
||||||
|
...esLocale,
|
||||||
|
...elementEsLocale
|
||||||
|
},
|
||||||
|
ja: {
|
||||||
|
...jaLocale,
|
||||||
|
...elementJaLocale
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export function getLanguage() {
|
||||||
|
const chooseLanguage = Cookies.get('language')
|
||||||
|
if (chooseLanguage) return chooseLanguage
|
||||||
|
|
||||||
|
// if has not choose language
|
||||||
|
const language = (navigator.language || navigator.browserLanguage).toLowerCase()
|
||||||
|
const locales = Object.keys(messages)
|
||||||
|
for (const locale of locales) {
|
||||||
|
if (language.indexOf(locale) > -1) {
|
||||||
|
return locale
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 'en'
|
||||||
|
}
|
||||||
|
const i18n = new VueI18n({
|
||||||
|
// set locale
|
||||||
|
// options: en | zh | es
|
||||||
|
locale: getLanguage(),
|
||||||
|
// set locale messages
|
||||||
|
messages
|
||||||
|
})
|
||||||
|
|
||||||
|
export default i18n
|
|
@ -0,0 +1,175 @@
|
||||||
|
export default {
|
||||||
|
route: {
|
||||||
|
dashboard: 'トップ',
|
||||||
|
documentation: 'ドキュメント',
|
||||||
|
guide: 'ガイド',
|
||||||
|
permission: '権限',
|
||||||
|
rolePermission: '権限ロール',
|
||||||
|
pagePermission: 'ページ権限',
|
||||||
|
directivePermission: 'ディレクティブ権限',
|
||||||
|
icons: 'アイコン',
|
||||||
|
components: 'コンポーネント',
|
||||||
|
tinymce: 'TinyMCE',
|
||||||
|
markdown: 'Markdown',
|
||||||
|
jsonEditor: 'JSON Editor',
|
||||||
|
dndList: 'Drag-And-Drop',
|
||||||
|
splitPane: 'パネル',
|
||||||
|
avatarUpload: 'アバターアップロード',
|
||||||
|
dropzone: 'Dropzone',
|
||||||
|
sticky: 'Sticky',
|
||||||
|
countTo: 'Count To',
|
||||||
|
componentMixin: 'コンポーネントMixin',
|
||||||
|
backToTop: 'BackToTop',
|
||||||
|
dragDialog: 'Drag Dialog',
|
||||||
|
dragSelect: 'Drag Select',
|
||||||
|
dragKanban: 'Drag 看板',
|
||||||
|
charts: 'チャート',
|
||||||
|
keyboardChart: 'Keyboardチャート',
|
||||||
|
lineChart: 'Lineチャート',
|
||||||
|
mixChart: 'Mixチャート',
|
||||||
|
example: 'Example',
|
||||||
|
nested: 'Nested Routes',
|
||||||
|
menu1: 'メニュー1',
|
||||||
|
'menu1-1': 'メニュー 1-1',
|
||||||
|
'menu1-2': 'メニュー 1-2',
|
||||||
|
'menu1-2-1': 'メニュー 1-2-1',
|
||||||
|
'menu1-2-2': 'メニュー 1-2-2',
|
||||||
|
'menu1-3': 'メニュー 1-3',
|
||||||
|
menu2: 'メニュー 2',
|
||||||
|
Table: 'Table',
|
||||||
|
dynamicTable: '可変 Table',
|
||||||
|
dragTable: 'Drag Table',
|
||||||
|
inlineEditTable: 'Inline Edit Table',
|
||||||
|
complexTable: 'Complex Table',
|
||||||
|
tab: 'Tab',
|
||||||
|
form: 'フォーム',
|
||||||
|
createArticle: '投稿作成',
|
||||||
|
editArticle: '投稿編集',
|
||||||
|
articleList: '投稿リスト',
|
||||||
|
errorPages: 'エラーページ',
|
||||||
|
page401: '401',
|
||||||
|
page404: '404',
|
||||||
|
errorLog: 'エラーログ',
|
||||||
|
excel: 'Excel',
|
||||||
|
exportExcel: '一括エクスポート',
|
||||||
|
selectExcel: '複数選択エクスポート',
|
||||||
|
mergeHeader: 'ヘッダーマージ',
|
||||||
|
uploadExcel: 'アップロード',
|
||||||
|
zip: 'Zip',
|
||||||
|
pdf: 'PDF',
|
||||||
|
exportZip: 'Export Zip',
|
||||||
|
theme: 'テーマ変更',
|
||||||
|
clipboardDemo: 'Clipboard',
|
||||||
|
i18n: '多言語',
|
||||||
|
externalLink: '外部リンク',
|
||||||
|
profile: 'プロフィール'
|
||||||
|
},
|
||||||
|
navbar: {
|
||||||
|
dashboard: 'トップ',
|
||||||
|
github: 'GitHub',
|
||||||
|
logOut: 'ログアウト',
|
||||||
|
profile: 'プロフィール',
|
||||||
|
theme: 'テーマ変更',
|
||||||
|
size: '画面サイズ'
|
||||||
|
},
|
||||||
|
login: {
|
||||||
|
title: 'ユーザログイン',
|
||||||
|
logIn: 'ログイン',
|
||||||
|
username: 'ユーザ名',
|
||||||
|
password: 'パスワード',
|
||||||
|
any: 'password',
|
||||||
|
thirdparty: '外部IDでログイン',
|
||||||
|
thirdpartyTips: 'ローカル環境ではログインできません。実装が必要です。'
|
||||||
|
},
|
||||||
|
documentation: {
|
||||||
|
documentation: 'ドキュメント',
|
||||||
|
github: 'Github Link'
|
||||||
|
},
|
||||||
|
permission: {
|
||||||
|
addRole: 'ロール追加',
|
||||||
|
editPermission: 'ロール変更',
|
||||||
|
roles: 'ロール',
|
||||||
|
switchRoles: 'ロール切替',
|
||||||
|
tips: 'v-permissionは使えない時があります。例えば: Element-UI の el-tab、 el-table-column 及び他の dom。v-ifを使う必要があります。',
|
||||||
|
delete: '削除',
|
||||||
|
confirm: '確認',
|
||||||
|
cancel: 'キャンセル'
|
||||||
|
},
|
||||||
|
guide: {
|
||||||
|
description: 'ガイドは各機能の説明です。',
|
||||||
|
button: 'ガイドを見る'
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
documentation: 'ドキュメント',
|
||||||
|
tinymceTips: 'tinymceは管理画面に重要な機能ですが、その同時に落とし穴がありあす。tinymceを使う道のりが大変でした。Tinymceを使う時に各自のプロジェクト状況で判断が必要です。ドキュメントはこちら',
|
||||||
|
dropzoneTips: 'Third partyのパッケージを使わず、独自の実装しています。詳細は @/components/Dropzone',
|
||||||
|
stickyTips: 'ページの指定位置へスクロールした場合、表示されます。',
|
||||||
|
backToTopTips1: 'トップへスクロールが表示されます。',
|
||||||
|
backToTopTips2: 'ボタンのスタイルはカスタマイズできます。例えば、show/hide、height、position。 またはElementのel-tooltipを使って、ツールチップを実装できます。',
|
||||||
|
imageUploadTips: 'mockjsは使えないため、カスタマイズしています。公式の最新バージョンを使ってください。'
|
||||||
|
},
|
||||||
|
table: {
|
||||||
|
dynamicTips1: '先頭は固定、最後に追加',
|
||||||
|
dynamicTips2: '戦後に追加せず、指定列に追加',
|
||||||
|
dragTips1: 'デフォルト順番',
|
||||||
|
dragTips2: 'Drag後の順番',
|
||||||
|
title: 'タイトル',
|
||||||
|
importance: '重要',
|
||||||
|
type: 'タイプ',
|
||||||
|
remark: '評価',
|
||||||
|
search: '検索',
|
||||||
|
add: '追加',
|
||||||
|
export: 'エクスポート',
|
||||||
|
reviewer: 'レビュアー',
|
||||||
|
id: '番号',
|
||||||
|
date: '日時',
|
||||||
|
author: '作成者',
|
||||||
|
readings: '閲覧数',
|
||||||
|
status: 'ステータス',
|
||||||
|
actions: '操作',
|
||||||
|
edit: '編集',
|
||||||
|
publish: '公開',
|
||||||
|
draft: '下書き',
|
||||||
|
delete: 'キャンセル',
|
||||||
|
cancel: 'キャンセル',
|
||||||
|
confirm: '確認'
|
||||||
|
},
|
||||||
|
example: {
|
||||||
|
warning: '新規作成と編集画面は keep-alive を使えないです。keep-alive の include はrouteのキャッシュは使えないです。そのため、component name を使ってキャッシュさせるようにします。このようなキャッシュ機能を作りたい場合,localStorageを使う手があります。もしくは keep-alive の includeを使って、全ページキャッシュする方法はあります。'
|
||||||
|
},
|
||||||
|
errorLog: {
|
||||||
|
tips: '右上のbugアイコンをクリックしてください。',
|
||||||
|
description: '管理画面はspaを使う場合が多い、ユーザ体現向上はできますが、想定外エラーが発生する場合があります。Vueはそのエラーハンドリング機能を提供し、エラーレポートができます。',
|
||||||
|
documentation: 'ドキュメント'
|
||||||
|
},
|
||||||
|
excel: {
|
||||||
|
export: 'エクスポート',
|
||||||
|
selectedExport: 'エクスポート対象を選択してください。',
|
||||||
|
placeholder: 'ファイル名を入力してください。'
|
||||||
|
},
|
||||||
|
zip: {
|
||||||
|
export: 'エクスポート',
|
||||||
|
placeholder: 'ファイル名を入力してください。'
|
||||||
|
},
|
||||||
|
pdf: {
|
||||||
|
tips: 'window.print() を使ってPDFダウンロードしています。'
|
||||||
|
},
|
||||||
|
theme: {
|
||||||
|
change: 'テーマ切替',
|
||||||
|
documentation: 'ドキュメント',
|
||||||
|
tips: 'Tips: テーマの切り替え方法はnavbarのtheme-pickと異なります、使い方はドキュメントを確認してください。'
|
||||||
|
},
|
||||||
|
tagsView: {
|
||||||
|
refresh: '更新',
|
||||||
|
close: '閉じる',
|
||||||
|
closeOthers: 'その他閉じる',
|
||||||
|
closeAll: 'すべて閉じる'
|
||||||
|
},
|
||||||
|
settings: {
|
||||||
|
title: 'システムテーマ',
|
||||||
|
theme: 'テーマ色',
|
||||||
|
tagsView: 'Tags-View 開く',
|
||||||
|
fixedHeader: 'Fixed Header',
|
||||||
|
sidebarLogo: 'Sidebar Logo'
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,175 @@
|
||||||
|
export default {
|
||||||
|
route: {
|
||||||
|
dashboard: '首页',
|
||||||
|
documentation: '文档',
|
||||||
|
guide: '引导页',
|
||||||
|
permission: '权限测试页',
|
||||||
|
rolePermission: '角色权限',
|
||||||
|
pagePermission: '页面权限',
|
||||||
|
directivePermission: '指令权限',
|
||||||
|
icons: '图标',
|
||||||
|
components: '组件',
|
||||||
|
tinymce: '富文本编辑器',
|
||||||
|
markdown: 'Markdown',
|
||||||
|
jsonEditor: 'JSON 编辑器',
|
||||||
|
dndList: '列表拖拽',
|
||||||
|
splitPane: 'Splitpane',
|
||||||
|
avatarUpload: '头像上传',
|
||||||
|
dropzone: 'Dropzone',
|
||||||
|
sticky: 'Sticky',
|
||||||
|
countTo: 'Count To',
|
||||||
|
componentMixin: '小组件',
|
||||||
|
backToTop: '返回顶部',
|
||||||
|
dragDialog: '拖拽 Dialog',
|
||||||
|
dragSelect: '拖拽 Select',
|
||||||
|
dragKanban: '可拖拽看板',
|
||||||
|
charts: '图表',
|
||||||
|
keyboardChart: '键盘图表',
|
||||||
|
lineChart: '折线图',
|
||||||
|
mixChart: '混合图表',
|
||||||
|
example: '综合实例',
|
||||||
|
nested: '路由嵌套',
|
||||||
|
menu1: '菜单1',
|
||||||
|
'menu1-1': '菜单 1-1',
|
||||||
|
'menu1-2': '菜单 1-2',
|
||||||
|
'menu1-2-1': '菜单 1-2-1',
|
||||||
|
'menu1-2-2': '菜单 1-2-2',
|
||||||
|
'menu1-3': '菜单 1-3',
|
||||||
|
menu2: '菜单 2',
|
||||||
|
Table: 'Table',
|
||||||
|
dynamicTable: '动态 Table',
|
||||||
|
dragTable: '拖拽 Table',
|
||||||
|
inlineEditTable: 'Table 内编辑',
|
||||||
|
complexTable: '综合 Table',
|
||||||
|
tab: 'Tab',
|
||||||
|
form: '表单',
|
||||||
|
createArticle: '创建文章',
|
||||||
|
editArticle: '编辑文章',
|
||||||
|
articleList: '文章列表',
|
||||||
|
errorPages: '错误页面',
|
||||||
|
page401: '401',
|
||||||
|
page404: '404',
|
||||||
|
errorLog: '错误日志',
|
||||||
|
excel: 'Excel',
|
||||||
|
exportExcel: '导出 Excel',
|
||||||
|
selectExcel: '导出 已选择项',
|
||||||
|
mergeHeader: '导出 多级表头',
|
||||||
|
uploadExcel: '上传 Excel',
|
||||||
|
zip: 'Zip',
|
||||||
|
pdf: 'PDF',
|
||||||
|
exportZip: 'Export Zip',
|
||||||
|
theme: '换肤',
|
||||||
|
clipboardDemo: 'Clipboard',
|
||||||
|
i18n: '国际化',
|
||||||
|
externalLink: '外链',
|
||||||
|
profile: '个人中心'
|
||||||
|
},
|
||||||
|
navbar: {
|
||||||
|
dashboard: '首页',
|
||||||
|
github: '项目地址',
|
||||||
|
logOut: '退出登录',
|
||||||
|
profile: '个人中心',
|
||||||
|
theme: '换肤',
|
||||||
|
size: '布局大小'
|
||||||
|
},
|
||||||
|
login: {
|
||||||
|
title: '系统登录',
|
||||||
|
logIn: '登录',
|
||||||
|
username: '账号',
|
||||||
|
password: '密码',
|
||||||
|
any: '随便填',
|
||||||
|
thirdparty: '第三方登录',
|
||||||
|
thirdpartyTips: '本地不能模拟,请结合自己业务进行模拟!!!'
|
||||||
|
},
|
||||||
|
documentation: {
|
||||||
|
documentation: '文档',
|
||||||
|
github: 'Github 地址'
|
||||||
|
},
|
||||||
|
permission: {
|
||||||
|
addRole: '新增角色',
|
||||||
|
editPermission: '编辑权限',
|
||||||
|
roles: '你的权限',
|
||||||
|
switchRoles: '切换权限',
|
||||||
|
tips: '在某些情况下,不适合使用 v-permission。例如:Element-UI 的 el-tab 或 el-table-column 以及其它动态渲染 dom 的场景。你只能通过手动设置 v-if 来实现。',
|
||||||
|
delete: '删除',
|
||||||
|
confirm: '确定',
|
||||||
|
cancel: '取消'
|
||||||
|
},
|
||||||
|
guide: {
|
||||||
|
description: '引导页对于一些第一次进入项目的人很有用,你可以简单介绍下项目的功能。本 Demo 是基于',
|
||||||
|
button: '打开引导'
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
documentation: '文档',
|
||||||
|
tinymceTips: '富文本是管理后台一个核心的功能,但同时又是一个有很多坑的地方。在选择富文本的过程中我也走了不少的弯路,市面上常见的富文本都基本用过了,最终权衡了一下选择了Tinymce。更详细的富文本比较和介绍见',
|
||||||
|
dropzoneTips: '由于我司业务有特殊需求,而且要传七牛 所以没用第三方,选择了自己封装。代码非常的简单,具体代码你可以在这里看到 @/components/Dropzone',
|
||||||
|
stickyTips: '当页面滚动到预设的位置会吸附在顶部',
|
||||||
|
backToTopTips1: '页面滚动到指定位置会在右下角出现返回顶部按钮',
|
||||||
|
backToTopTips2: '可自定义按钮的样式、show/hide、出现的高度、返回的位置 如需文字提示,可在外部使用Element的el-tooltip元素',
|
||||||
|
imageUploadTips: '由于我在使用时它只有vue@1版本,而且和mockjs不兼容,所以自己改造了一下,如果大家要使用的话,优先还是使用官方版本。'
|
||||||
|
},
|
||||||
|
table: {
|
||||||
|
dynamicTips1: '固定表头, 按照表头顺序排序',
|
||||||
|
dynamicTips2: '不固定表头, 按照点击顺序排序',
|
||||||
|
dragTips1: '默认顺序',
|
||||||
|
dragTips2: '拖拽后顺序',
|
||||||
|
title: '标题',
|
||||||
|
importance: '重要性',
|
||||||
|
type: '类型',
|
||||||
|
remark: '点评',
|
||||||
|
search: '搜索',
|
||||||
|
add: '添加',
|
||||||
|
export: '导出',
|
||||||
|
reviewer: '审核人',
|
||||||
|
id: '序号',
|
||||||
|
date: '时间',
|
||||||
|
author: '作者',
|
||||||
|
readings: '阅读数',
|
||||||
|
status: '状态',
|
||||||
|
actions: '操作',
|
||||||
|
edit: '编辑',
|
||||||
|
publish: '发布',
|
||||||
|
draft: '草稿',
|
||||||
|
delete: '删除',
|
||||||
|
cancel: '取 消',
|
||||||
|
confirm: '确 定'
|
||||||
|
},
|
||||||
|
example: {
|
||||||
|
warning: '创建和编辑页面是不能被 keep-alive 缓存的,因为keep-alive 的 include 目前不支持根据路由来缓存,所以目前都是基于 component name 来进行缓存的。如果你想类似的实现缓存效果,可以使用 localStorage 等浏览器缓存方案。或者不要使用 keep-alive 的 include,直接缓存所有页面。详情见'
|
||||||
|
},
|
||||||
|
errorLog: {
|
||||||
|
tips: '请点击右上角bug小图标',
|
||||||
|
description: '现在的管理后台基本都是spa的形式了,它增强了用户体验,但同时也会增加页面出问题的可能性,可能一个小小的疏忽就导致整个页面的死锁。好在 Vue 官网提供了一个方法来捕获处理异常,你可以在其中进行错误处理或者异常上报。',
|
||||||
|
documentation: '文档介绍'
|
||||||
|
},
|
||||||
|
excel: {
|
||||||
|
export: '导出',
|
||||||
|
selectedExport: '导出已选择项',
|
||||||
|
placeholder: '请输入文件名(默认excel-list)'
|
||||||
|
},
|
||||||
|
zip: {
|
||||||
|
export: '导出',
|
||||||
|
placeholder: '请输入文件名(默认file)'
|
||||||
|
},
|
||||||
|
pdf: {
|
||||||
|
tips: '这里使用 window.print() 来实现下载pdf的功能'
|
||||||
|
},
|
||||||
|
theme: {
|
||||||
|
change: '换肤',
|
||||||
|
documentation: '换肤文档',
|
||||||
|
tips: 'Tips: 它区别于 navbar 上的 theme-pick, 是两种不同的换肤方法,各自有不同的应用场景,具体请参考文档。'
|
||||||
|
},
|
||||||
|
tagsView: {
|
||||||
|
refresh: '刷新',
|
||||||
|
close: '关闭',
|
||||||
|
closeOthers: '关闭其它',
|
||||||
|
closeAll: '关闭所有'
|
||||||
|
},
|
||||||
|
settings: {
|
||||||
|
title: '系统布局配置',
|
||||||
|
theme: '主题色',
|
||||||
|
tagsView: '开启 Tags-View',
|
||||||
|
fixedHeader: '固定 Header',
|
||||||
|
sidebarLogo: '侧边栏 Logo'
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,10 +12,12 @@
|
||||||
|
|
||||||
<screenfull id="screenfull" class="right-menu-item hover-effect" />
|
<screenfull id="screenfull" class="right-menu-item hover-effect" />
|
||||||
|
|
||||||
<el-tooltip content="Global Size" effect="dark" placement="bottom">
|
<el-tooltip :content="$t('navbar.size')" effect="dark" placement="bottom">
|
||||||
<size-select id="size-select" class="right-menu-item hover-effect" />
|
<size-select id="size-select" class="right-menu-item hover-effect" />
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
|
<lang-select class="right-menu-item hover-effect" />
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
|
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
|
||||||
|
@ -25,19 +27,25 @@
|
||||||
</div>
|
</div>
|
||||||
<el-dropdown-menu slot="dropdown">
|
<el-dropdown-menu slot="dropdown">
|
||||||
<router-link to="/profile/index">
|
<router-link to="/profile/index">
|
||||||
<el-dropdown-item>Profile</el-dropdown-item>
|
<el-dropdown-item>
|
||||||
|
{{ $t('navbar.profile') }}
|
||||||
|
</el-dropdown-item>
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link to="/">
|
<router-link to="/">
|
||||||
<el-dropdown-item>Dashboard</el-dropdown-item>
|
<el-dropdown-item>
|
||||||
|
{{ $t('navbar.dashboard') }}
|
||||||
|
</el-dropdown-item>
|
||||||
</router-link>
|
</router-link>
|
||||||
<a target="_blank" href="https://github.com/PanJiaChen/vue-element-admin/">
|
<a target="_blank" href="https://github.com/PanJiaChen/vue-element-admin/">
|
||||||
<el-dropdown-item>Github</el-dropdown-item>
|
<el-dropdown-item>
|
||||||
|
{{ $t('navbar.github') }}
|
||||||
|
</el-dropdown-item>
|
||||||
</a>
|
</a>
|
||||||
<a target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/#/">
|
<a target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/#/">
|
||||||
<el-dropdown-item>Docs</el-dropdown-item>
|
<el-dropdown-item>Docs</el-dropdown-item>
|
||||||
</a>
|
</a>
|
||||||
<el-dropdown-item divided>
|
<el-dropdown-item divided @click.native="logout">
|
||||||
<span style="display:block;" @click="logout">Log Out</span>
|
<span style="display:block;">{{ $t('navbar.logOut') }}</span>
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
|
@ -52,6 +60,7 @@ import Hamburger from '@/components/Hamburger'
|
||||||
import ErrorLog from '@/components/ErrorLog'
|
import ErrorLog from '@/components/ErrorLog'
|
||||||
import Screenfull from '@/components/Screenfull'
|
import Screenfull from '@/components/Screenfull'
|
||||||
import SizeSelect from '@/components/SizeSelect'
|
import SizeSelect from '@/components/SizeSelect'
|
||||||
|
import LangSelect from '@/components/LangSelect'
|
||||||
import Search from '@/components/HeaderSearch'
|
import Search from '@/components/HeaderSearch'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -61,6 +70,7 @@ export default {
|
||||||
ErrorLog,
|
ErrorLog,
|
||||||
Screenfull,
|
Screenfull,
|
||||||
SizeSelect,
|
SizeSelect,
|
||||||
|
LangSelect,
|
||||||
Search
|
Search
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
|
@ -1,27 +1,39 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="drawer-container">
|
<div class="drawer-container">
|
||||||
<div>
|
<div>
|
||||||
<h3 class="drawer-title">Page style setting</h3>
|
<h3 class="drawer-title">{{ $t('settings.title') }}</h3>
|
||||||
|
|
||||||
<div class="drawer-item">
|
<div class="drawer-item">
|
||||||
<span>Theme Color</span>
|
<span>{{ $t('settings.theme') }}</span>
|
||||||
<theme-picker style="float: right;height: 26px;margin: -3px 8px 0 0;" @change="themeChange" />
|
<theme-picker style="float: right;height: 26px;margin: -3px 8px 0 0;" @change="themeChange" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="drawer-item">
|
<div class="drawer-item">
|
||||||
<span>Open Tags-View</span>
|
<span>{{ $t('settings.tagsView') }}</span>
|
||||||
<el-switch v-model="tagsView" class="drawer-switch" />
|
<el-switch v-model="tagsView" class="drawer-switch" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="drawer-item">
|
<div class="drawer-item">
|
||||||
<span>Fixed Header</span>
|
<span>{{ $t('settings.fixedHeader') }}</span>
|
||||||
<el-switch v-model="fixedHeader" class="drawer-switch" />
|
<el-switch v-model="fixedHeader" class="drawer-switch" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="drawer-item">
|
<div class="drawer-item">
|
||||||
<span>Sidebar Logo</span>
|
<span>{{ $t('settings.sidebarLogo') }}</span>
|
||||||
<el-switch v-model="sidebarLogo" class="drawer-switch" />
|
<el-switch v-model="sidebarLogo" class="drawer-switch" />
|
||||||
</div>
|
</div>
|
||||||
|
<a v-if="isShowJob" href="https://panjiachen.github.io/vue-element-admin-site/zh/job/" target="_blank" class="job-link">
|
||||||
|
<el-alert
|
||||||
|
title="部门目前非常缺人!有兴趣的可以点击了解详情。坐标: 字节跳动"
|
||||||
|
type="success"
|
||||||
|
:closable="false"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div v-if="lang === 'zh'" class="drawer-item">
|
||||||
|
<span>菜单支持拼音搜索</span>
|
||||||
|
<el-switch v-model="supportPinyinSearch" class="drawer-switch" />
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -36,6 +48,9 @@ export default {
|
||||||
return {}
|
return {}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
isShowJob() {
|
||||||
|
return this.$store.getters.language === 'zh'
|
||||||
|
},
|
||||||
fixedHeader: {
|
fixedHeader: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.settings.fixedHeader
|
return this.$store.state.settings.fixedHeader
|
||||||
|
@ -68,6 +83,20 @@ export default {
|
||||||
value: val
|
value: val
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
supportPinyinSearch: {
|
||||||
|
get() {
|
||||||
|
return this.$store.state.settings.supportPinyinSearch
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
this.$store.dispatch('settings/changeSetting', {
|
||||||
|
key: 'supportPinyinSearch',
|
||||||
|
value: val
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
lang() {
|
||||||
|
return this.$store.getters.language
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -104,5 +133,13 @@ export default {
|
||||||
.drawer-switch {
|
.drawer-switch {
|
||||||
float: right
|
float: right
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.job-link{
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -17,7 +17,11 @@ export default {
|
||||||
const vnodes = []
|
const vnodes = []
|
||||||
|
|
||||||
if (icon) {
|
if (icon) {
|
||||||
vnodes.push(<svg-icon icon-class={icon}/>)
|
if (icon.includes('el-icon')) {
|
||||||
|
vnodes.push(<i class={[icon, 'sub-el-icon']} />)
|
||||||
|
} else {
|
||||||
|
vnodes.push(<svg-icon icon-class={icon}/>)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (title) {
|
if (title) {
|
||||||
|
@ -27,3 +31,11 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.sub-el-icon {
|
||||||
|
color: currentColor;
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<!-- eslint-disable vue/require-component-is -->
|
<component :is="type" v-bind="linkProps(to)">
|
||||||
<component v-bind="linkProps(to)">
|
|
||||||
<slot />
|
<slot />
|
||||||
</component>
|
</component>
|
||||||
</template>
|
</template>
|
||||||
|
@ -16,19 +14,28 @@ export default {
|
||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
isExternal() {
|
||||||
|
return isExternal(this.to)
|
||||||
|
},
|
||||||
|
type() {
|
||||||
|
if (this.isExternal) {
|
||||||
|
return 'a'
|
||||||
|
}
|
||||||
|
return 'router-link'
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
linkProps(url) {
|
linkProps(to) {
|
||||||
if (isExternal(url)) {
|
if (this.isExternal) {
|
||||||
return {
|
return {
|
||||||
is: 'a',
|
href: to,
|
||||||
href: url,
|
|
||||||
target: '_blank',
|
target: '_blank',
|
||||||
rel: 'noopener'
|
rel: 'noopener'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
is: 'router-link',
|
to: to
|
||||||
to: url
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-if="!item.hidden" class="menu-wrapper">
|
<div v-if="!item.hidden">
|
||||||
<template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">
|
<template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">
|
||||||
<app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)">
|
<app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)">
|
||||||
<el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}">
|
<el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}">
|
||||||
<item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="onlyOneChild.meta.title" />
|
<item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="generateTitle(onlyOneChild.meta.title)" />
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
</app-link>
|
</app-link>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body>
|
<el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body>
|
||||||
<template slot="title">
|
<template slot="title">
|
||||||
<item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" />
|
<item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="generateTitle(item.meta.title)" />
|
||||||
</template>
|
</template>
|
||||||
<sidebar-item
|
<sidebar-item
|
||||||
v-for="child in item.children"
|
v-for="child in item.children"
|
||||||
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
|
import { generateTitle } from '@/utils/i18n'
|
||||||
import { isExternal } from '@/utils/validate'
|
import { isExternal } from '@/utils/validate'
|
||||||
import Item from './Item'
|
import Item from './Item'
|
||||||
import AppLink from './Link'
|
import AppLink from './Link'
|
||||||
|
@ -89,7 +90,9 @@ export default {
|
||||||
return this.basePath
|
return this.basePath
|
||||||
}
|
}
|
||||||
return path.resolve(this.basePath, routePath)
|
return path.resolve(this.basePath, routePath)
|
||||||
}
|
},
|
||||||
|
|
||||||
|
generateTitle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -19,12 +19,21 @@ export default {
|
||||||
return this.$refs.scrollContainer.$refs.wrap
|
return this.$refs.scrollContainer.$refs.wrap
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
mounted() {
|
||||||
|
this.scrollWrapper.addEventListener('scroll', this.emitScroll, true)
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
this.scrollWrapper.removeEventListener('scroll', this.emitScroll)
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleScroll(e) {
|
handleScroll(e) {
|
||||||
const eventDelta = e.wheelDelta || -e.deltaY * 40
|
const eventDelta = e.wheelDelta || -e.deltaY * 40
|
||||||
const $scrollWrapper = this.scrollWrapper
|
const $scrollWrapper = this.scrollWrapper
|
||||||
$scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4
|
$scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4
|
||||||
},
|
},
|
||||||
|
emitScroll() {
|
||||||
|
this.$emit('scroll')
|
||||||
|
},
|
||||||
moveToTarget(currentTag) {
|
moveToTarget(currentTag) {
|
||||||
const $container = this.$refs.scrollContainer.$el
|
const $container = this.$refs.scrollContainer.$el
|
||||||
const $containerWidth = $container.offsetWidth
|
const $containerWidth = $container.offsetWidth
|
||||||
|
@ -73,7 +82,7 @@ export default {
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
/deep/ {
|
::v-deep {
|
||||||
.el-scrollbar__bar {
|
.el-scrollbar__bar {
|
||||||
bottom: 0px;
|
bottom: 0px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div id="tags-view-container" class="tags-view-container">
|
<div id="tags-view-container" class="tags-view-container">
|
||||||
<scroll-pane ref="scrollPane" class="tags-view-wrapper">
|
<scroll-pane ref="scrollPane" class="tags-view-wrapper" @scroll="handleScroll">
|
||||||
<router-link
|
<router-link
|
||||||
v-for="tag in visitedViews"
|
v-for="tag in visitedViews"
|
||||||
ref="tag"
|
ref="tag"
|
||||||
|
@ -12,21 +12,22 @@
|
||||||
@click.middle.native="!isAffix(tag)?closeSelectedTag(tag):''"
|
@click.middle.native="!isAffix(tag)?closeSelectedTag(tag):''"
|
||||||
@contextmenu.prevent.native="openMenu(tag,$event)"
|
@contextmenu.prevent.native="openMenu(tag,$event)"
|
||||||
>
|
>
|
||||||
{{ tag.title }}
|
{{ generateTitle(tag.title) }}
|
||||||
<span v-if="!isAffix(tag)" class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)" />
|
<span v-if="!isAffix(tag)" class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)" />
|
||||||
</router-link>
|
</router-link>
|
||||||
</scroll-pane>
|
</scroll-pane>
|
||||||
<ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
|
<ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
|
||||||
<li @click="refreshSelectedTag(selectedTag)">Refresh</li>
|
<li @click="refreshSelectedTag(selectedTag)">{{ $t('tagsView.refresh') }}</li>
|
||||||
<li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)">Close</li>
|
<li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)">{{ $t('tagsView.close') }}</li>
|
||||||
<li @click="closeOthersTags">Close Others</li>
|
<li @click="closeOthersTags">{{ $t('tagsView.closeOthers') }}</li>
|
||||||
<li @click="closeAllTags(selectedTag)">Close All</li>
|
<li @click="closeAllTags(selectedTag)">{{ $t('tagsView.closeAll') }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ScrollPane from './ScrollPane'
|
import ScrollPane from './ScrollPane'
|
||||||
|
import { generateTitle } from '@/utils/i18n'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -66,6 +67,7 @@ export default {
|
||||||
this.addTags()
|
this.addTags()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
generateTitle, // generateTitle by vue-i18n
|
||||||
isActive(route) {
|
isActive(route) {
|
||||||
return route.path === this.$route.path
|
return route.path === this.$route.path
|
||||||
},
|
},
|
||||||
|
@ -189,6 +191,9 @@ export default {
|
||||||
},
|
},
|
||||||
closeMenu() {
|
closeMenu() {
|
||||||
this.visible = false
|
this.visible = false
|
||||||
|
},
|
||||||
|
handleScroll() {
|
||||||
|
this.closeMenu()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import App from './App'
|
||||||
import store from './store'
|
import store from './store'
|
||||||
import router from './router'
|
import router from './router'
|
||||||
|
|
||||||
|
import i18n from './lang' // internationalization
|
||||||
import './icons' // icon
|
import './icons' // icon
|
||||||
import './permission' // permission control
|
import './permission' // permission control
|
||||||
import './utils/error-log' // error log
|
import './utils/error-log' // error log
|
||||||
|
@ -25,15 +26,16 @@ import * as filters from './filters' // global filters
|
||||||
* you can execute: mockXHR()
|
* you can execute: mockXHR()
|
||||||
*
|
*
|
||||||
* Currently MockJs will be used in the production environment,
|
* Currently MockJs will be used in the production environment,
|
||||||
* please remove it before going online! ! !
|
* please remove it before going online ! ! !
|
||||||
*/
|
*/
|
||||||
import { mockXHR } from '../mock'
|
|
||||||
if (process.env.NODE_ENV === 'production') {
|
if (process.env.NODE_ENV === 'production') {
|
||||||
|
const { mockXHR } = require('../mock')
|
||||||
mockXHR()
|
mockXHR()
|
||||||
}
|
}
|
||||||
|
|
||||||
Vue.use(Element, {
|
Vue.use(Element, {
|
||||||
size: Cookies.get('size') || 'medium' // set element-ui default size
|
size: Cookies.get('size') || 'medium', // set element-ui default size
|
||||||
|
i18n: (key, value) => i18n.t(key, value)
|
||||||
})
|
})
|
||||||
|
|
||||||
// register global utility filters
|
// register global utility filters
|
||||||
|
@ -47,5 +49,6 @@ new Vue({
|
||||||
el: '#app',
|
el: '#app',
|
||||||
router,
|
router,
|
||||||
store,
|
store,
|
||||||
|
i18n,
|
||||||
render: h => h(App)
|
render: h => h(App)
|
||||||
})
|
})
|
||||||
|
|
|
@ -24,7 +24,7 @@ router.beforeEach(async(to, from, next) => {
|
||||||
if (to.path === '/login') {
|
if (to.path === '/login') {
|
||||||
// if is logged in, redirect to the home page
|
// if is logged in, redirect to the home page
|
||||||
next({ path: '/' })
|
next({ path: '/' })
|
||||||
NProgress.done()
|
NProgress.done() // hack: https://github.com/PanJiaChen/vue-element-admin/pull/2939
|
||||||
} else {
|
} else {
|
||||||
// determine whether the user has obtained his permission roles through getInfo
|
// determine whether the user has obtained his permission roles through getInfo
|
||||||
const hasRoles = store.getters.roles && store.getters.roles.length > 0
|
const hasRoles = store.getters.roles && store.getters.roles.length > 0
|
||||||
|
|
|
@ -25,7 +25,7 @@ import nestedRouter from './modules/nested'
|
||||||
* meta : {
|
* meta : {
|
||||||
roles: ['admin','editor'] control the page roles (you can set multiple roles)
|
roles: ['admin','editor'] control the page roles (you can set multiple roles)
|
||||||
title: 'title' the name show in sidebar and breadcrumb (recommend set)
|
title: 'title' the name show in sidebar and breadcrumb (recommend set)
|
||||||
icon: 'svg-name' the icon show in the sidebar
|
icon: 'svg-name'/'el-icon-x' the icon show in the sidebar
|
||||||
noCache: true if set true, the page will no be cached(default is false)
|
noCache: true if set true, the page will no be cached(default is false)
|
||||||
affix: true if set true, the tag will affix in the tags-view
|
affix: true if set true, the tag will affix in the tags-view
|
||||||
breadcrumb: false if set false, the item will hidden in breadcrumb(default is true)
|
breadcrumb: false if set false, the item will hidden in breadcrumb(default is true)
|
||||||
|
@ -45,7 +45,7 @@ export const constantRoutes = [
|
||||||
hidden: true,
|
hidden: true,
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: '/redirect/:path*',
|
path: '/redirect/:path(.*)',
|
||||||
component: () => import('@/views/redirect/index')
|
component: () => import('@/views/redirect/index')
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -79,7 +79,7 @@ export const constantRoutes = [
|
||||||
path: 'dashboard',
|
path: 'dashboard',
|
||||||
component: () => import('@/views/dashboard/index'),
|
component: () => import('@/views/dashboard/index'),
|
||||||
name: 'Dashboard',
|
name: 'Dashboard',
|
||||||
meta: { title: 'Dashboard', icon: 'dashboard', affix: true }
|
meta: { title: 'dashboard', icon: 'dashboard', affix: true }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -91,7 +91,7 @@ export const constantRoutes = [
|
||||||
path: 'index',
|
path: 'index',
|
||||||
component: () => import('@/views/documentation/index'),
|
component: () => import('@/views/documentation/index'),
|
||||||
name: 'Documentation',
|
name: 'Documentation',
|
||||||
meta: { title: 'Documentation', icon: 'documentation', affix: true }
|
meta: { title: 'documentation', icon: 'documentation', affix: true }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -104,7 +104,7 @@ export const constantRoutes = [
|
||||||
path: 'index',
|
path: 'index',
|
||||||
component: () => import('@/views/guide/index'),
|
component: () => import('@/views/guide/index'),
|
||||||
name: 'Guide',
|
name: 'Guide',
|
||||||
meta: { title: 'Guide', icon: 'guide', noCache: true }
|
meta: { title: 'guide', icon: 'guide', noCache: true }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -118,7 +118,7 @@ export const constantRoutes = [
|
||||||
path: 'index',
|
path: 'index',
|
||||||
component: () => import('@/views/profile/index'),
|
component: () => import('@/views/profile/index'),
|
||||||
name: 'Profile',
|
name: 'Profile',
|
||||||
meta: { title: 'Profile', icon: 'user', noCache: true }
|
meta: { title: 'profile', icon: 'user', noCache: true }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -136,7 +136,7 @@ export const asyncRoutes = [
|
||||||
alwaysShow: true, // will always show the root menu
|
alwaysShow: true, // will always show the root menu
|
||||||
name: 'Permission',
|
name: 'Permission',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Permission',
|
title: 'permission',
|
||||||
icon: 'lock',
|
icon: 'lock',
|
||||||
roles: ['admin', 'editor'] // you can set roles in root nav
|
roles: ['admin', 'editor'] // you can set roles in root nav
|
||||||
},
|
},
|
||||||
|
@ -146,7 +146,7 @@ export const asyncRoutes = [
|
||||||
component: () => import('@/views/permission/page'),
|
component: () => import('@/views/permission/page'),
|
||||||
name: 'PagePermission',
|
name: 'PagePermission',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Page Permission',
|
title: 'pagePermission',
|
||||||
roles: ['admin'] // or you can only set roles in sub nav
|
roles: ['admin'] // or you can only set roles in sub nav
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -155,7 +155,7 @@ export const asyncRoutes = [
|
||||||
component: () => import('@/views/permission/directive'),
|
component: () => import('@/views/permission/directive'),
|
||||||
name: 'DirectivePermission',
|
name: 'DirectivePermission',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Directive Permission'
|
title: 'directivePermission'
|
||||||
// if do not set roles, means: this page does not require permission
|
// if do not set roles, means: this page does not require permission
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -164,7 +164,7 @@ export const asyncRoutes = [
|
||||||
component: () => import('@/views/permission/role'),
|
component: () => import('@/views/permission/role'),
|
||||||
name: 'RolePermission',
|
name: 'RolePermission',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Role Permission',
|
title: 'rolePermission',
|
||||||
roles: ['admin']
|
roles: ['admin']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,7 +179,7 @@ export const asyncRoutes = [
|
||||||
path: 'index',
|
path: 'index',
|
||||||
component: () => import('@/views/icons/index'),
|
component: () => import('@/views/icons/index'),
|
||||||
name: 'Icons',
|
name: 'Icons',
|
||||||
meta: { title: 'Icons', icon: 'icon', noCache: true }
|
meta: { title: 'icons', icon: 'icon', noCache: true }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -196,28 +196,28 @@ export const asyncRoutes = [
|
||||||
redirect: '/example/list',
|
redirect: '/example/list',
|
||||||
name: 'Example',
|
name: 'Example',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Example',
|
title: 'example',
|
||||||
icon: 'example'
|
icon: 'el-icon-s-help'
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'create',
|
path: 'create',
|
||||||
component: () => import('@/views/example/create'),
|
component: () => import('@/views/example/create'),
|
||||||
name: 'CreateArticle',
|
name: 'CreateArticle',
|
||||||
meta: { title: 'Create Article', icon: 'edit' }
|
meta: { title: 'createArticle', icon: 'edit' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'edit/:id(\\d+)',
|
path: 'edit/:id(\\d+)',
|
||||||
component: () => import('@/views/example/edit'),
|
component: () => import('@/views/example/edit'),
|
||||||
name: 'EditArticle',
|
name: 'EditArticle',
|
||||||
meta: { title: 'Edit Article', noCache: true, activeMenu: '/example/list' },
|
meta: { title: 'editArticle', noCache: true, activeMenu: '/example/list' },
|
||||||
hidden: true
|
hidden: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'list',
|
path: 'list',
|
||||||
component: () => import('@/views/example/list'),
|
component: () => import('@/views/example/list'),
|
||||||
name: 'ArticleList',
|
name: 'ArticleList',
|
||||||
meta: { title: 'Article List', icon: 'list' }
|
meta: { title: 'articleList', icon: 'list' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -230,7 +230,7 @@ export const asyncRoutes = [
|
||||||
path: 'index',
|
path: 'index',
|
||||||
component: () => import('@/views/tab/index'),
|
component: () => import('@/views/tab/index'),
|
||||||
name: 'Tab',
|
name: 'Tab',
|
||||||
meta: { title: 'Tab', icon: 'tab' }
|
meta: { title: 'tab', icon: 'tab' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -241,7 +241,7 @@ export const asyncRoutes = [
|
||||||
redirect: 'noRedirect',
|
redirect: 'noRedirect',
|
||||||
name: 'ErrorPages',
|
name: 'ErrorPages',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Error Pages',
|
title: 'errorPages',
|
||||||
icon: '404'
|
icon: '404'
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
|
@ -249,13 +249,13 @@ export const asyncRoutes = [
|
||||||
path: '401',
|
path: '401',
|
||||||
component: () => import('@/views/error-page/401'),
|
component: () => import('@/views/error-page/401'),
|
||||||
name: 'Page401',
|
name: 'Page401',
|
||||||
meta: { title: '401', noCache: true }
|
meta: { title: 'page401', noCache: true }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '404',
|
path: '404',
|
||||||
component: () => import('@/views/error-page/404'),
|
component: () => import('@/views/error-page/404'),
|
||||||
name: 'Page404',
|
name: 'Page404',
|
||||||
meta: { title: '404', noCache: true }
|
meta: { title: 'page404', noCache: true }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -268,7 +268,7 @@ export const asyncRoutes = [
|
||||||
path: 'log',
|
path: 'log',
|
||||||
component: () => import('@/views/error-log/index'),
|
component: () => import('@/views/error-log/index'),
|
||||||
name: 'ErrorLog',
|
name: 'ErrorLog',
|
||||||
meta: { title: 'Error Log', icon: 'bug' }
|
meta: { title: 'errorLog', icon: 'bug' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -279,7 +279,7 @@ export const asyncRoutes = [
|
||||||
redirect: '/excel/export-excel',
|
redirect: '/excel/export-excel',
|
||||||
name: 'Excel',
|
name: 'Excel',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Excel',
|
title: 'excel',
|
||||||
icon: 'excel'
|
icon: 'excel'
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
|
@ -287,25 +287,25 @@ export const asyncRoutes = [
|
||||||
path: 'export-excel',
|
path: 'export-excel',
|
||||||
component: () => import('@/views/excel/export-excel'),
|
component: () => import('@/views/excel/export-excel'),
|
||||||
name: 'ExportExcel',
|
name: 'ExportExcel',
|
||||||
meta: { title: 'Export Excel' }
|
meta: { title: 'exportExcel' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'export-selected-excel',
|
path: 'export-selected-excel',
|
||||||
component: () => import('@/views/excel/select-excel'),
|
component: () => import('@/views/excel/select-excel'),
|
||||||
name: 'SelectExcel',
|
name: 'SelectExcel',
|
||||||
meta: { title: 'Export Selected' }
|
meta: { title: 'selectExcel' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'export-merge-header',
|
path: 'export-merge-header',
|
||||||
component: () => import('@/views/excel/merge-header'),
|
component: () => import('@/views/excel/merge-header'),
|
||||||
name: 'MergeHeader',
|
name: 'MergeHeader',
|
||||||
meta: { title: 'Merge Header' }
|
meta: { title: 'mergeHeader' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'upload-excel',
|
path: 'upload-excel',
|
||||||
component: () => import('@/views/excel/upload-excel'),
|
component: () => import('@/views/excel/upload-excel'),
|
||||||
name: 'UploadExcel',
|
name: 'UploadExcel',
|
||||||
meta: { title: 'Upload Excel' }
|
meta: { title: 'uploadExcel' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -316,13 +316,13 @@ export const asyncRoutes = [
|
||||||
redirect: '/zip/download',
|
redirect: '/zip/download',
|
||||||
alwaysShow: true,
|
alwaysShow: true,
|
||||||
name: 'Zip',
|
name: 'Zip',
|
||||||
meta: { title: 'Zip', icon: 'zip' },
|
meta: { title: 'zip', icon: 'zip' },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'download',
|
path: 'download',
|
||||||
component: () => import('@/views/zip/index'),
|
component: () => import('@/views/zip/index'),
|
||||||
name: 'ExportZip',
|
name: 'ExportZip',
|
||||||
meta: { title: 'Export Zip' }
|
meta: { title: 'exportZip' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -336,7 +336,7 @@ export const asyncRoutes = [
|
||||||
path: 'index',
|
path: 'index',
|
||||||
component: () => import('@/views/pdf/index'),
|
component: () => import('@/views/pdf/index'),
|
||||||
name: 'PDF',
|
name: 'PDF',
|
||||||
meta: { title: 'PDF', icon: 'pdf' }
|
meta: { title: 'pdf', icon: 'pdf' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -354,7 +354,7 @@ export const asyncRoutes = [
|
||||||
path: 'index',
|
path: 'index',
|
||||||
component: () => import('@/views/theme/index'),
|
component: () => import('@/views/theme/index'),
|
||||||
name: 'Theme',
|
name: 'Theme',
|
||||||
meta: { title: 'Theme', icon: 'theme' }
|
meta: { title: 'theme', icon: 'theme' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -367,7 +367,20 @@ export const asyncRoutes = [
|
||||||
path: 'index',
|
path: 'index',
|
||||||
component: () => import('@/views/clipboard/index'),
|
component: () => import('@/views/clipboard/index'),
|
||||||
name: 'ClipboardDemo',
|
name: 'ClipboardDemo',
|
||||||
meta: { title: 'Clipboard', icon: 'clipboard' }
|
meta: { title: 'clipboardDemo', icon: 'clipboard' }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
path: '/i18n',
|
||||||
|
component: Layout,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'index',
|
||||||
|
component: () => import('@/views/i18n-demo/index'),
|
||||||
|
name: 'I18n',
|
||||||
|
meta: { title: 'i18n', icon: 'international' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -378,7 +391,7 @@ export const asyncRoutes = [
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'https://github.com/PanJiaChen/vue-element-admin',
|
path: 'https://github.com/PanJiaChen/vue-element-admin',
|
||||||
meta: { title: 'External Link', icon: 'link' }
|
meta: { title: 'externalLink', icon: 'link' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -8,7 +8,7 @@ const chartsRouter = {
|
||||||
redirect: 'noRedirect',
|
redirect: 'noRedirect',
|
||||||
name: 'Charts',
|
name: 'Charts',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Charts',
|
title: 'charts',
|
||||||
icon: 'chart'
|
icon: 'chart'
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
|
@ -16,19 +16,19 @@ const chartsRouter = {
|
||||||
path: 'keyboard',
|
path: 'keyboard',
|
||||||
component: () => import('@/views/charts/keyboard'),
|
component: () => import('@/views/charts/keyboard'),
|
||||||
name: 'KeyboardChart',
|
name: 'KeyboardChart',
|
||||||
meta: { title: 'Keyboard Chart', noCache: true }
|
meta: { title: 'keyboardChart', noCache: true }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'line',
|
path: 'line',
|
||||||
component: () => import('@/views/charts/line'),
|
component: () => import('@/views/charts/line'),
|
||||||
name: 'LineChart',
|
name: 'LineChart',
|
||||||
meta: { title: 'Line Chart', noCache: true }
|
meta: { title: 'lineChart', noCache: true }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'mix-chart',
|
path: 'mix-chart',
|
||||||
component: () => import('@/views/charts/mix-chart'),
|
component: () => import('@/views/charts/mix-chart'),
|
||||||
name: 'MixChart',
|
name: 'MixChart',
|
||||||
meta: { title: 'Mix Chart', noCache: true }
|
meta: { title: 'mixChart', noCache: true }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ const componentsRouter = {
|
||||||
redirect: 'noRedirect',
|
redirect: 'noRedirect',
|
||||||
name: 'ComponentDemo',
|
name: 'ComponentDemo',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Components',
|
title: 'components',
|
||||||
icon: 'component'
|
icon: 'component'
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
|
@ -16,85 +16,85 @@ const componentsRouter = {
|
||||||
path: 'tinymce',
|
path: 'tinymce',
|
||||||
component: () => import('@/views/components-demo/tinymce'),
|
component: () => import('@/views/components-demo/tinymce'),
|
||||||
name: 'TinymceDemo',
|
name: 'TinymceDemo',
|
||||||
meta: { title: 'Tinymce' }
|
meta: { title: 'tinymce' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'markdown',
|
path: 'markdown',
|
||||||
component: () => import('@/views/components-demo/markdown'),
|
component: () => import('@/views/components-demo/markdown'),
|
||||||
name: 'MarkdownDemo',
|
name: 'MarkdownDemo',
|
||||||
meta: { title: 'Markdown' }
|
meta: { title: 'markdown' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'json-editor',
|
path: 'json-editor',
|
||||||
component: () => import('@/views/components-demo/json-editor'),
|
component: () => import('@/views/components-demo/json-editor'),
|
||||||
name: 'JsonEditorDemo',
|
name: 'JsonEditorDemo',
|
||||||
meta: { title: 'JSON Editor' }
|
meta: { title: 'jsonEditor' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'split-pane',
|
path: 'split-pane',
|
||||||
component: () => import('@/views/components-demo/split-pane'),
|
component: () => import('@/views/components-demo/split-pane'),
|
||||||
name: 'SplitpaneDemo',
|
name: 'SplitpaneDemo',
|
||||||
meta: { title: 'SplitPane' }
|
meta: { title: 'splitPane' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'avatar-upload',
|
path: 'avatar-upload',
|
||||||
component: () => import('@/views/components-demo/avatar-upload'),
|
component: () => import('@/views/components-demo/avatar-upload'),
|
||||||
name: 'AvatarUploadDemo',
|
name: 'AvatarUploadDemo',
|
||||||
meta: { title: 'Upload' }
|
meta: { title: 'avatarUpload' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'dropzone',
|
path: 'dropzone',
|
||||||
component: () => import('@/views/components-demo/dropzone'),
|
component: () => import('@/views/components-demo/dropzone'),
|
||||||
name: 'DropzoneDemo',
|
name: 'DropzoneDemo',
|
||||||
meta: { title: 'Dropzone' }
|
meta: { title: 'dropzone' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'sticky',
|
path: 'sticky',
|
||||||
component: () => import('@/views/components-demo/sticky'),
|
component: () => import('@/views/components-demo/sticky'),
|
||||||
name: 'StickyDemo',
|
name: 'StickyDemo',
|
||||||
meta: { title: 'Sticky' }
|
meta: { title: 'sticky' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'count-to',
|
path: 'count-to',
|
||||||
component: () => import('@/views/components-demo/count-to'),
|
component: () => import('@/views/components-demo/count-to'),
|
||||||
name: 'CountToDemo',
|
name: 'CountToDemo',
|
||||||
meta: { title: 'Count To' }
|
meta: { title: 'countTo' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'mixin',
|
path: 'mixin',
|
||||||
component: () => import('@/views/components-demo/mixin'),
|
component: () => import('@/views/components-demo/mixin'),
|
||||||
name: 'ComponentMixinDemo',
|
name: 'ComponentMixinDemo',
|
||||||
meta: { title: 'Component Mixin' }
|
meta: { title: 'componentMixin' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'back-to-top',
|
path: 'back-to-top',
|
||||||
component: () => import('@/views/components-demo/back-to-top'),
|
component: () => import('@/views/components-demo/back-to-top'),
|
||||||
name: 'BackToTopDemo',
|
name: 'BackToTopDemo',
|
||||||
meta: { title: 'Back To Top' }
|
meta: { title: 'backToTop' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'drag-dialog',
|
path: 'drag-dialog',
|
||||||
component: () => import('@/views/components-demo/drag-dialog'),
|
component: () => import('@/views/components-demo/drag-dialog'),
|
||||||
name: 'DragDialogDemo',
|
name: 'DragDialogDemo',
|
||||||
meta: { title: 'Drag Dialog' }
|
meta: { title: 'dragDialog' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'drag-select',
|
path: 'drag-select',
|
||||||
component: () => import('@/views/components-demo/drag-select'),
|
component: () => import('@/views/components-demo/drag-select'),
|
||||||
name: 'DragSelectDemo',
|
name: 'DragSelectDemo',
|
||||||
meta: { title: 'Drag Select' }
|
meta: { title: 'dragSelect' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'dnd-list',
|
path: 'dnd-list',
|
||||||
component: () => import('@/views/components-demo/dnd-list'),
|
component: () => import('@/views/components-demo/dnd-list'),
|
||||||
name: 'DndListDemo',
|
name: 'DndListDemo',
|
||||||
meta: { title: 'Dnd List' }
|
meta: { title: 'dndList' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'drag-kanban',
|
path: 'drag-kanban',
|
||||||
component: () => import('@/views/components-demo/drag-kanban'),
|
component: () => import('@/views/components-demo/drag-kanban'),
|
||||||
name: 'DragKanbanDemo',
|
name: 'DragKanbanDemo',
|
||||||
meta: { title: 'Drag Kanban' }
|
meta: { title: 'dragKanban' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ const nestedRouter = {
|
||||||
redirect: '/nested/menu1/menu1-1',
|
redirect: '/nested/menu1/menu1-1',
|
||||||
name: 'Nested',
|
name: 'Nested',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Nested Routes',
|
title: 'nested',
|
||||||
icon: 'nested'
|
icon: 'nested'
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
|
@ -16,33 +16,33 @@ const nestedRouter = {
|
||||||
path: 'menu1',
|
path: 'menu1',
|
||||||
component: () => import('@/views/nested/menu1/index'), // Parent router-view
|
component: () => import('@/views/nested/menu1/index'), // Parent router-view
|
||||||
name: 'Menu1',
|
name: 'Menu1',
|
||||||
meta: { title: 'Menu 1' },
|
meta: { title: 'menu1' },
|
||||||
redirect: '/nested/menu1/menu1-1',
|
redirect: '/nested/menu1/menu1-1',
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'menu1-1',
|
path: 'menu1-1',
|
||||||
component: () => import('@/views/nested/menu1/menu1-1'),
|
component: () => import('@/views/nested/menu1/menu1-1'),
|
||||||
name: 'Menu1-1',
|
name: 'Menu1-1',
|
||||||
meta: { title: 'Menu 1-1' }
|
meta: { title: 'menu1-1' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'menu1-2',
|
path: 'menu1-2',
|
||||||
component: () => import('@/views/nested/menu1/menu1-2'),
|
component: () => import('@/views/nested/menu1/menu1-2'),
|
||||||
name: 'Menu1-2',
|
name: 'Menu1-2',
|
||||||
redirect: '/nested/menu1/menu1-2/menu1-2-1',
|
redirect: '/nested/menu1/menu1-2/menu1-2-1',
|
||||||
meta: { title: 'Menu 1-2' },
|
meta: { title: 'menu1-2' },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'menu1-2-1',
|
path: 'menu1-2-1',
|
||||||
component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'),
|
component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'),
|
||||||
name: 'Menu1-2-1',
|
name: 'Menu1-2-1',
|
||||||
meta: { title: 'Menu 1-2-1' }
|
meta: { title: 'menu1-2-1' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'menu1-2-2',
|
path: 'menu1-2-2',
|
||||||
component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'),
|
component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'),
|
||||||
name: 'Menu1-2-2',
|
name: 'Menu1-2-2',
|
||||||
meta: { title: 'Menu 1-2-2' }
|
meta: { title: 'menu1-2-2' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -50,7 +50,7 @@ const nestedRouter = {
|
||||||
path: 'menu1-3',
|
path: 'menu1-3',
|
||||||
component: () => import('@/views/nested/menu1/menu1-3'),
|
component: () => import('@/views/nested/menu1/menu1-3'),
|
||||||
name: 'Menu1-3',
|
name: 'Menu1-3',
|
||||||
meta: { title: 'Menu 1-3' }
|
meta: { title: 'menu1-3' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -58,7 +58,7 @@ const nestedRouter = {
|
||||||
path: 'menu2',
|
path: 'menu2',
|
||||||
name: 'Menu2',
|
name: 'Menu2',
|
||||||
component: () => import('@/views/nested/menu2/index'),
|
component: () => import('@/views/nested/menu2/index'),
|
||||||
meta: { title: 'Menu 2' }
|
meta: { title: 'menu2' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,25 +16,25 @@ const tableRouter = {
|
||||||
path: 'dynamic-table',
|
path: 'dynamic-table',
|
||||||
component: () => import('@/views/table/dynamic-table/index'),
|
component: () => import('@/views/table/dynamic-table/index'),
|
||||||
name: 'DynamicTable',
|
name: 'DynamicTable',
|
||||||
meta: { title: 'Dynamic Table' }
|
meta: { title: 'dynamicTable' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'drag-table',
|
path: 'drag-table',
|
||||||
component: () => import('@/views/table/drag-table'),
|
component: () => import('@/views/table/drag-table'),
|
||||||
name: 'DragTable',
|
name: 'DragTable',
|
||||||
meta: { title: 'Drag Table' }
|
meta: { title: 'dragTable' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'inline-edit-table',
|
path: 'inline-edit-table',
|
||||||
component: () => import('@/views/table/inline-edit-table'),
|
component: () => import('@/views/table/inline-edit-table'),
|
||||||
name: 'InlineEditTable',
|
name: 'InlineEditTable',
|
||||||
meta: { title: 'Inline Edit' }
|
meta: { title: 'inlineEditTable' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'complex-table',
|
path: 'complex-table',
|
||||||
component: () => import('@/views/table/complex-table'),
|
component: () => import('@/views/table/complex-table'),
|
||||||
name: 'ComplexTable',
|
name: 'ComplexTable',
|
||||||
meta: { title: 'Complex Table' }
|
meta: { title: 'complexTable' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,13 @@ module.exports = {
|
||||||
*/
|
*/
|
||||||
sidebarLogo: false,
|
sidebarLogo: false,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {boolean} true | false
|
||||||
|
* @description Whether support pinyin search in headerSearch
|
||||||
|
* Bundle size minified 47.3kb,minified + gzipped 63kb
|
||||||
|
*/
|
||||||
|
supportPinyinSearch: true,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {string | array} 'production' | ['production', 'development']
|
* @type {string | array} 'production' | ['production', 'development']
|
||||||
* @description Need show err logs component.
|
* @description Need show err logs component.
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
const getters = {
|
const getters = {
|
||||||
sidebar: state => state.app.sidebar,
|
sidebar: state => state.app.sidebar,
|
||||||
|
language: state => state.app.language,
|
||||||
size: state => state.app.size,
|
size: state => state.app.size,
|
||||||
device: state => state.app.device,
|
device: state => state.app.device,
|
||||||
visitedViews: state => state.tagsView.visitedViews,
|
visitedViews: state => state.tagsView.visitedViews,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import Cookies from 'js-cookie'
|
import Cookies from 'js-cookie'
|
||||||
|
import { getLanguage } from '@/lang/index'
|
||||||
|
|
||||||
const state = {
|
const state = {
|
||||||
sidebar: {
|
sidebar: {
|
||||||
|
@ -6,6 +7,7 @@ const state = {
|
||||||
withoutAnimation: false
|
withoutAnimation: false
|
||||||
},
|
},
|
||||||
device: 'desktop',
|
device: 'desktop',
|
||||||
|
language: getLanguage(),
|
||||||
size: Cookies.get('size') || 'medium'
|
size: Cookies.get('size') || 'medium'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +29,10 @@ const mutations = {
|
||||||
TOGGLE_DEVICE: (state, device) => {
|
TOGGLE_DEVICE: (state, device) => {
|
||||||
state.device = device
|
state.device = device
|
||||||
},
|
},
|
||||||
|
SET_LANGUAGE: (state, language) => {
|
||||||
|
state.language = language
|
||||||
|
Cookies.set('language', language)
|
||||||
|
},
|
||||||
SET_SIZE: (state, size) => {
|
SET_SIZE: (state, size) => {
|
||||||
state.size = size
|
state.size = size
|
||||||
Cookies.set('size', size)
|
Cookies.set('size', size)
|
||||||
|
@ -43,6 +49,9 @@ const actions = {
|
||||||
toggleDevice({ commit }, device) {
|
toggleDevice({ commit }, device) {
|
||||||
commit('TOGGLE_DEVICE', device)
|
commit('TOGGLE_DEVICE', device)
|
||||||
},
|
},
|
||||||
|
setLanguage({ commit }, language) {
|
||||||
|
commit('SET_LANGUAGE', language)
|
||||||
|
},
|
||||||
setSize({ commit }, size) {
|
setSize({ commit }, size) {
|
||||||
commit('SET_SIZE', size)
|
commit('SET_SIZE', size)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,20 @@
|
||||||
import variables from '@/styles/element-variables.scss'
|
import variables from '@/styles/element-variables.scss'
|
||||||
import defaultSettings from '@/settings'
|
import defaultSettings from '@/settings'
|
||||||
|
|
||||||
const { showSettings, tagsView, fixedHeader, sidebarLogo } = defaultSettings
|
const { showSettings, tagsView, fixedHeader, sidebarLogo, supportPinyinSearch } = defaultSettings
|
||||||
|
|
||||||
const state = {
|
const state = {
|
||||||
theme: variables.theme,
|
theme: variables.theme,
|
||||||
showSettings: showSettings,
|
showSettings,
|
||||||
tagsView: tagsView,
|
tagsView,
|
||||||
fixedHeader: fixedHeader,
|
fixedHeader,
|
||||||
sidebarLogo: sidebarLogo
|
sidebarLogo,
|
||||||
|
supportPinyinSearch
|
||||||
}
|
}
|
||||||
|
|
||||||
const mutations = {
|
const mutations = {
|
||||||
CHANGE_SETTING: (state, { key, value }) => {
|
CHANGE_SETTING: (state, { key, value }) => {
|
||||||
|
// eslint-disable-next-line no-prototype-builtins
|
||||||
if (state.hasOwnProperty(key)) {
|
if (state.hasOwnProperty(key)) {
|
||||||
state[key] = value
|
state[key] = value
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,28 +103,23 @@ const actions = {
|
||||||
},
|
},
|
||||||
|
|
||||||
// dynamically modify permissions
|
// dynamically modify permissions
|
||||||
changeRoles({ commit, dispatch }, role) {
|
async changeRoles({ commit, dispatch }, role) {
|
||||||
return new Promise(async resolve => {
|
const token = role + '-token'
|
||||||
const token = role + '-token'
|
|
||||||
|
|
||||||
commit('SET_TOKEN', token)
|
commit('SET_TOKEN', token)
|
||||||
setToken(token)
|
setToken(token)
|
||||||
|
|
||||||
const { roles } = await dispatch('getInfo')
|
const { roles } = await dispatch('getInfo')
|
||||||
|
|
||||||
resetRouter()
|
resetRouter()
|
||||||
|
|
||||||
// generate accessible routes map based on roles
|
// generate accessible routes map based on roles
|
||||||
const accessRoutes = await dispatch('permission/generateRoutes', roles, { root: true })
|
const accessRoutes = await dispatch('permission/generateRoutes', roles, { root: true })
|
||||||
|
// dynamically add accessible routes
|
||||||
|
router.addRoutes(accessRoutes)
|
||||||
|
|
||||||
// dynamically add accessible routes
|
// reset visited views and cached views
|
||||||
router.addRoutes(accessRoutes)
|
dispatch('tagsView/delAllViews', null, { root: true })
|
||||||
|
|
||||||
// reset visited views and cached views
|
|
||||||
dispatch('tagsView/delAllViews', null, { root: true })
|
|
||||||
|
|
||||||
resolve()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
.fixed-width {
|
.fixed-width {
|
||||||
.el-button--mini {
|
.el-button--mini {
|
||||||
padding: 7px 10px;
|
padding: 7px 10px;
|
||||||
width: 60px;
|
min-width: 60px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,3 +77,8 @@
|
||||||
.el-range-editor.el-input__inner {
|
.el-range-editor.el-input__inner {
|
||||||
display: inline-flex !important;
|
display: inline-flex !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// to fix el-date-picker css style
|
||||||
|
.el-range-separator {
|
||||||
|
box-sizing: content-box;
|
||||||
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
/* theme color */
|
/* theme color */
|
||||||
$--color-primary: #1890ff;
|
$--color-primary: #1890ff;
|
||||||
$--color-success: #13ce66;
|
$--color-success: #13ce66;
|
||||||
$--color-warning: #FFBA00;
|
$--color-warning: #ffba00;
|
||||||
$--color-danger: #ff4949;
|
$--color-danger: #ff4949;
|
||||||
// $--color-info: #1E1E1E;
|
// $--color-info: #1E1E1E;
|
||||||
|
|
||||||
|
@ -17,10 +17,10 @@ $--button-font-weight: 400;
|
||||||
$--border-color-light: #dfe4ed;
|
$--border-color-light: #dfe4ed;
|
||||||
$--border-color-lighter: #e6ebf5;
|
$--border-color-lighter: #e6ebf5;
|
||||||
|
|
||||||
$--table-border:1px solid#dfe6ec;
|
$--table-border: 1px solid #dfe6ec;
|
||||||
|
|
||||||
/* icon font path, required */
|
/* icon font path, required */
|
||||||
$--font-path: '~element-ui/lib/theme-chalk/fonts';
|
$--font-path: "~element-ui/lib/theme-chalk/fonts";
|
||||||
|
|
||||||
@import "~element-ui/packages/theme-chalk/src/index";
|
@import "~element-ui/packages/theme-chalk/src/index";
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,11 @@
|
||||||
margin-right: 16px;
|
margin-right: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sub-el-icon {
|
||||||
|
margin-right: 12px;
|
||||||
|
margin-left: -2px;
|
||||||
|
}
|
||||||
|
|
||||||
.el-menu {
|
.el-menu {
|
||||||
border: none;
|
border: none;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -105,6 +110,10 @@
|
||||||
.svg-icon {
|
.svg-icon {
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sub-el-icon {
|
||||||
|
margin-left: 19px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,6 +127,10 @@
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sub-el-icon {
|
||||||
|
margin-left: 19px;
|
||||||
|
}
|
||||||
|
|
||||||
.el-submenu__icon-arrow {
|
.el-submenu__icon-arrow {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
@ -178,6 +191,10 @@
|
||||||
.svg-icon {
|
.svg-icon {
|
||||||
margin-right: 16px;
|
margin-right: 16px;
|
||||||
}
|
}
|
||||||
|
.sub-el-icon {
|
||||||
|
margin-right: 12px;
|
||||||
|
margin-left: -2px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.nest-menu .el-submenu>.el-submenu__title,
|
.nest-menu .el-submenu>.el-submenu__title,
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
import defaultSettings from '@/settings'
|
import defaultSettings from '@/settings'
|
||||||
|
import i18n from '@/lang'
|
||||||
|
|
||||||
const title = defaultSettings.title || 'Vue Element Admin'
|
const title = defaultSettings.title || 'Vue Element Admin'
|
||||||
|
|
||||||
export default function getPageTitle(pageTitle) {
|
export default function getPageTitle(key) {
|
||||||
if (pageTitle) {
|
const hasKey = i18n.te(`route.${key}`)
|
||||||
return `${pageTitle} - ${title}`
|
if (hasKey) {
|
||||||
|
const pageName = i18n.t(`route.${key}`)
|
||||||
|
return `${pageName} - ${title}`
|
||||||
}
|
}
|
||||||
return `${title}`
|
return `${title}`
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
// translate router.meta.title, be used in breadcrumb sidebar tagsview
|
||||||
|
export function generateTitle(title) {
|
||||||
|
const hasKey = this.$te('route.' + title)
|
||||||
|
|
||||||
|
if (hasKey) {
|
||||||
|
// $t :this method from vue-i18n, inject in @/lang/index.js
|
||||||
|
const translatedTitle = this.$t('route.' + title)
|
||||||
|
|
||||||
|
return translatedTitle
|
||||||
|
}
|
||||||
|
return title
|
||||||
|
}
|
|
@ -9,7 +9,7 @@
|
||||||
* @returns {string | null}
|
* @returns {string | null}
|
||||||
*/
|
*/
|
||||||
export function parseTime(time, cFormat) {
|
export function parseTime(time, cFormat) {
|
||||||
if (arguments.length === 0) {
|
if (arguments.length === 0 || !time) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
|
const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
|
||||||
|
@ -17,9 +17,17 @@ export function parseTime(time, cFormat) {
|
||||||
if (typeof time === 'object') {
|
if (typeof time === 'object') {
|
||||||
date = time
|
date = time
|
||||||
} else {
|
} else {
|
||||||
if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
|
if ((typeof time === 'string')) {
|
||||||
time = parseInt(time)
|
if ((/^[0-9]+$/.test(time))) {
|
||||||
|
// support "1548221490638"
|
||||||
|
time = parseInt(time)
|
||||||
|
} else {
|
||||||
|
// support safari
|
||||||
|
// https://stackoverflow.com/questions/4310953/invalid-date-in-safari
|
||||||
|
time = time.replace(new RegExp(/-/gm), '/')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((typeof time === 'number') && (time.toString().length === 10)) {
|
if ((typeof time === 'number') && (time.toString().length === 10)) {
|
||||||
time = time * 1000
|
time = time * 1000
|
||||||
}
|
}
|
||||||
|
@ -154,19 +162,21 @@ export function param(json) {
|
||||||
* @returns {Object}
|
* @returns {Object}
|
||||||
*/
|
*/
|
||||||
export function param2Obj(url) {
|
export function param2Obj(url) {
|
||||||
const search = url.split('?')[1]
|
const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
|
||||||
if (!search) {
|
if (!search) {
|
||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
return JSON.parse(
|
const obj = {}
|
||||||
'{"' +
|
const searchArr = search.split('&')
|
||||||
decodeURIComponent(search)
|
searchArr.forEach(v => {
|
||||||
.replace(/"/g, '\\"')
|
const index = v.indexOf('=')
|
||||||
.replace(/&/g, '","')
|
if (index !== -1) {
|
||||||
.replace(/=/g, '":"')
|
const name = v.substring(0, index)
|
||||||
.replace(/\+/g, ' ') +
|
const val = v.substring(index + 1, v.length)
|
||||||
'"}'
|
obj[name] = val
|
||||||
)
|
}
|
||||||
|
})
|
||||||
|
return obj
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -13,11 +13,7 @@ export default function checkPermission(value) {
|
||||||
const hasPermission = roles.some(role => {
|
const hasPermission = roles.some(role => {
|
||||||
return permissionRoles.includes(role)
|
return permissionRoles.includes(role)
|
||||||
})
|
})
|
||||||
|
return hasPermission
|
||||||
if (!hasPermission) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
} else {
|
} else {
|
||||||
console.error(`need roles! Like v-permission="['admin','editor']"`)
|
console.error(`need roles! Like v-permission="['admin','editor']"`)
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<div class="components-container">
|
<div class="components-container">
|
||||||
<aside>This is based on
|
<aside>This is based on
|
||||||
<a class="link-type" href="//github.com/dai-siki/vue-image-crop-upload"> vue-image-crop-upload</a>.
|
<a class="link-type" href="//github.com/dai-siki/vue-image-crop-upload"> vue-image-crop-upload</a>.
|
||||||
Since I was using only the vue@1 version, and it is not compatible with mockjs at the moment, I modified it myself, and if you are going to use it, it is better to use official version.
|
{{ $t('components.imageUploadTips') }}
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
<pan-thumb :image="image" />
|
<pan-thumb :image="image" />
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="components-container">
|
<div class="components-container">
|
||||||
<aside>
|
<aside>{{ $t('components.backToTopTips1') }}</aside>
|
||||||
When the page is scrolled to the specified position, the Back to Top button appears in the lower right corner
|
<aside>{{ $t('components.backToTopTips2') }}</aside>
|
||||||
</aside>
|
|
||||||
<aside>
|
|
||||||
You can customize the style of the button, show / hide, height of appearance, height of the return. If you need a text prompt, you can use element-ui el-tooltip elements externally
|
|
||||||
</aside>
|
|
||||||
<div class="placeholder-container">
|
<div class="placeholder-container">
|
||||||
<div>placeholder</div>
|
<div>placeholder</div>
|
||||||
<div>placeholder</div>
|
<div>placeholder</div>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<div class="components-container">
|
<div class="components-container">
|
||||||
<aside>
|
<aside>
|
||||||
Based on <a class="link-type" href="https://github.com/rowanwins/vue-dropzone"> dropzone </a>.
|
Based on <a class="link-type" href="https://github.com/rowanwins/vue-dropzone"> dropzone </a>.
|
||||||
Because my business has special needs, and has to upload images to qiniu, so instead of a third party, I chose encapsulate it by myself. It is very simple, you can see the detail code in @/components/Dropzone.
|
{{ $t('components.dropzoneTips') }}
|
||||||
</aside>
|
</aside>
|
||||||
<div class="editor-container">
|
<div class="editor-container">
|
||||||
<dropzone id="myVueDropzone" url="https://httpbin.org/post" @dropzone-removedFile="dropzoneR" @dropzone-success="dropzoneS" />
|
<dropzone id="myVueDropzone" url="https://httpbin.org/post" @dropzone-removedFile="dropzoneR" @dropzone-success="dropzoneS" />
|
||||||
|
|
|
@ -79,7 +79,7 @@ export default {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
language() {
|
language() {
|
||||||
return this.languageTypeList['en']
|
return this.languageTypeList[this.$store.getters.language]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
@ -37,9 +37,7 @@
|
||||||
</sticky>
|
</sticky>
|
||||||
|
|
||||||
<div class="components-container">
|
<div class="components-container">
|
||||||
<aside>
|
<aside>Sticky header, {{ $t('components.stickyTips') }}</aside>
|
||||||
Sticky header, When the page is scrolled to the preset position will be sticky on the top.
|
|
||||||
</aside>
|
|
||||||
<div>placeholder</div>
|
<div>placeholder</div>
|
||||||
<div>placeholder</div>
|
<div>placeholder</div>
|
||||||
<div>placeholder</div>
|
<div>placeholder</div>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="components-container">
|
<div class="components-container">
|
||||||
<aside>
|
<aside>
|
||||||
Rich text is a core feature of the management backend, but at the same time it is a place with lots of pits. In the process of selecting rich texts, I also took a lot of detours. The common rich texts on the market have been basically used, and I finally chose Tinymce. See the more detailed rich text comparison and introduction.
|
{{ $t('components.tinymceTips') }}
|
||||||
<a target="_blank" class="link-type" href="https://panjiachen.github.io/vue-element-admin-site/component/rich-editor.html">Documentation</a>
|
<a target="_blank" class="link-type" href="https://panjiachen.github.io/vue-element-admin-site/feature/component/rich-editor.html"> {{ $t('components.documentation') }}</a>
|
||||||
</aside>
|
</aside>
|
||||||
<div>
|
<div>
|
||||||
<tinymce v-model="content" :height="300" />
|
<tinymce v-model="content" :height="300" />
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<el-progress :percentage="18" />
|
<el-progress :percentage="18" />
|
||||||
</div>
|
</div>
|
||||||
<div class="progress-item">
|
<div class="progress-item">
|
||||||
<span>Css</span>
|
<span>CSS</span>
|
||||||
<el-progress :percentage="12" />
|
<el-progress :percentage="12" />
|
||||||
</div>
|
</div>
|
||||||
<div class="progress-item">
|
<div class="progress-item">
|
||||||
|
@ -101,7 +101,7 @@ export default {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
box-shadow: none!important;
|
box-shadow: none!important;
|
||||||
/deep/ .pan-info {
|
::v-deep .pan-info {
|
||||||
box-shadow: none!important;
|
box-shadow: none!important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ export default {
|
||||||
indicator: [
|
indicator: [
|
||||||
{ name: 'Sales', max: 10000 },
|
{ name: 'Sales', max: 10000 },
|
||||||
{ name: 'Administration', max: 20000 },
|
{ name: 'Administration', max: 20000 },
|
||||||
{ name: 'Information Techology', max: 20000 },
|
{ name: 'Information Technology', max: 20000 },
|
||||||
{ name: 'Customer Support', max: 20000 },
|
{ name: 'Customer Support', max: 20000 },
|
||||||
{ name: 'Development', max: 20000 },
|
{ name: 'Development', max: 20000 },
|
||||||
{ name: 'Marketing', max: 20000 }
|
{ name: 'Marketing', max: 20000 }
|
||||||
|
|
|
@ -1,26 +1,11 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="app-container documentation-container">
|
<div class="app-container documentation-container">
|
||||||
<a
|
<a class="document-btn" target="_blank" href="https://store.akveo.com/products/vue-java-admin-dashboard-spring?utm_campaign=akveo_store-Vue-Vue_demo%2Fgithub&utm_source=vue_admin&utm_medium=referral&utm_content=demo_English_button">Java backend integration</a>
|
||||||
class="document-btn"
|
<a class="document-btn" target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/">Documentation</a>
|
||||||
target="_blank"
|
<a class="document-btn" target="_blank" href="https://github.com/PanJiaChen/vue-element-admin/">Github Repository</a>
|
||||||
href="https://panjiachen.github.io/vue-element-admin-site/"
|
<a class="document-btn" target="_blank" href="https://panjiachen.gitee.io/vue-element-admin-site/zh/">国内文档</a>
|
||||||
>Documentation</a>
|
<dropdown-menu class="document-btn" :items="articleList" title="系列文章" />
|
||||||
<a
|
<a class="document-btn" target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/zh/job/">内推招聘</a>
|
||||||
class="document-btn"
|
|
||||||
target="_blank"
|
|
||||||
href="https://github.com/PanJiaChen/vue-element-admin/"
|
|
||||||
>Github Repository</a>
|
|
||||||
<a
|
|
||||||
class="document-btn"
|
|
||||||
target="_blank"
|
|
||||||
href="https://panjiachen.gitee.io/vue-element-admin-site/zh/"
|
|
||||||
>国内文档</a>
|
|
||||||
<dropdown-menu :items="articleList" style="float:left;margin-left:50px;" title="系列文章" />
|
|
||||||
<a
|
|
||||||
class="document-btn"
|
|
||||||
target="_blank"
|
|
||||||
href="https://panjiachen.github.io/vue-element-admin-site/zh/job/"
|
|
||||||
>内推招聘</a>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -53,15 +38,17 @@ export default {
|
||||||
margin: 50px;
|
margin: 50px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
justify-content: flex-start;
|
||||||
|
|
||||||
.document-btn {
|
.document-btn {
|
||||||
margin-left: 50px;
|
flex-shrink: 0;
|
||||||
display: block;
|
display: block;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background: black;
|
background: black;
|
||||||
color: white;
|
color: white;
|
||||||
height: 60px;
|
height: 60px;
|
||||||
width: 200px;
|
padding: 0 16px;
|
||||||
margin-bottom: 16px;
|
margin: 16px;
|
||||||
line-height: 60px;
|
line-height: 60px;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
|
@ -2,11 +2,12 @@
|
||||||
<div class="errPage-container">
|
<div class="errPage-container">
|
||||||
<ErrorA />
|
<ErrorA />
|
||||||
<ErrorB />
|
<ErrorB />
|
||||||
<h3>Please click the bug icon in the upper right corner</h3>
|
<!-- $t is vue-i18n global function to translate lang -->
|
||||||
|
<h3>{{ $t('errorLog.tips') }}</h3>
|
||||||
<aside>
|
<aside>
|
||||||
Now the management system are basically the form of the spa, it enhances the user experience, but it also increases the possibility of page problems, a small negligence may lead to the entire page deadlock. Fortunately Vue provides a way to catch handling exceptions, where you can handle errors or report exceptions.
|
{{ $t('errorLog.description') }}
|
||||||
<a target="_blank" class="link-type" href="https://panjiachen.github.io/vue-element-admin-site/guide/advanced/error.html">
|
<a target="_blank" class="link-type" href="https://panjiachen.github.io/vue-element-admin-site/guide/advanced/error.html">
|
||||||
Document introduction
|
{{ $t('errorLog.documentation') }}
|
||||||
</a>
|
</a>
|
||||||
</aside>
|
</aside>
|
||||||
<a href="#">
|
<a href="#">
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="createPost-container">
|
<div class="createPost-container">
|
||||||
<el-form ref="postForm" :model="postForm" :rules="rules" class="form-container">
|
<el-form ref="postForm" :model="postForm" :rules="rules" class="form-container">
|
||||||
|
|
||||||
<sticky :z-index="10" :class-name="'sub-navbar '+postForm.status">
|
<sticky :z-index="10" :class-name="'sub-navbar '+postForm.status">
|
||||||
<CommentDropdown v-model="postForm.comment_disabled" />
|
<CommentDropdown v-model="postForm.comment_disabled" />
|
||||||
<PlatformDropdown v-model="postForm.platforms" />
|
<PlatformDropdown v-model="postForm.platforms" />
|
||||||
|
@ -153,6 +152,9 @@ export default {
|
||||||
contentShortLength() {
|
contentShortLength() {
|
||||||
return this.postForm.content_short.length
|
return this.postForm.content_short.length
|
||||||
},
|
},
|
||||||
|
lang() {
|
||||||
|
return this.$store.getters.language
|
||||||
|
},
|
||||||
displayTime: {
|
displayTime: {
|
||||||
// set and get is useful when the data
|
// set and get is useful when the data
|
||||||
// returned by the back end api is different from the front end
|
// returned by the back end api is different from the front end
|
||||||
|
@ -196,7 +198,7 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
setTagsViewTitle() {
|
setTagsViewTitle() {
|
||||||
const title = 'Edit Article'
|
const title = this.lang === 'zh' ? '编辑文章' : 'Edit Article'
|
||||||
const route = Object.assign({}, this.tempRoute, { title: `${title}-${this.postForm.id}` })
|
const route = Object.assign({}, this.tempRoute, { title: `${title}-${this.postForm.id}` })
|
||||||
this.$store.dispatch('tagsView/updateVisitedView', route)
|
this.$store.dispatch('tagsView/updateVisitedView', route)
|
||||||
},
|
},
|
||||||
|
@ -277,7 +279,7 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.article-textarea /deep/ {
|
.article-textarea ::v-deep {
|
||||||
textarea {
|
textarea {
|
||||||
padding-right: 40px;
|
padding-right: 40px;
|
||||||
resize: none;
|
resize: none;
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<aside>
|
<aside>
|
||||||
Creating and editing pages cannot be cached by keep-alive because keep-alive include does not currently support
|
{{ $t('example.warning') }}
|
||||||
caching based on routes, so it is currently cached based on component name. If you want to achieve a similar caching
|
|
||||||
effect, you can use a browser caching scheme such as localStorage. Or do not use keep-alive include to cache all
|
|
||||||
pages directly. See details
|
|
||||||
<a
|
<a
|
||||||
href="https://panjiachen.github.io/vue-element-admin-site/guide/essentials/tags-view.html"
|
href="https://panjiachen.github.io/vue-element-admin-site/guide/essentials/tags-view.html"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<div style="display:inline-block;">
|
<div style="display:inline-block;">
|
||||||
|
<!-- $t is vue-i18n global function to translate lang -->
|
||||||
<label class="radio-label" style="padding-left:0;">Filename: </label>
|
<label class="radio-label" style="padding-left:0;">Filename: </label>
|
||||||
<el-input v-model="filename" placeholder="Please enter the file name (default excel-list)" style="width:345px;" prefix-icon="el-icon-document" />
|
<el-input v-model="filename" :placeholder="$t('excel.placeholder')" style="width:350px;" prefix-icon="el-icon-document" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
<template>
|
<template>
|
||||||
|
<!-- $t is vue-i18n global function to translate lang -->
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<FilenameOption v-model="filename" />
|
<FilenameOption v-model="filename" />
|
||||||
<AutoWidthOption v-model="autoWidth" />
|
<AutoWidthOption v-model="autoWidth" />
|
||||||
<BookTypeOption v-model="bookType" />
|
<BookTypeOption v-model="bookType" />
|
||||||
<el-button :loading="downloadLoading" style="margin:0 0 20px 20px;" type="primary" icon="el-icon-document" @click="handleDownload">
|
<el-button :loading="downloadLoading" style="margin:0 0 20px 20px;" type="primary" icon="el-icon-document" @click="handleDownload">
|
||||||
Export Excel
|
{{ $t('excel.export') }} Excel
|
||||||
</el-button>
|
</el-button>
|
||||||
<a href="https://panjiachen.github.io/vue-element-admin-site/feature/component/excel.html" target="_blank" style="margin-left:15px;">
|
<a href="https://panjiachen.github.io/vue-element-admin-site/feature/component/excel.html" target="_blank" style="margin-left:15px;">
|
||||||
<el-tag type="info">Documentation</el-tag>
|
<el-tag type="info">Documentation</el-tag>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-table v-loading="listLoading" :data="list" element-loading-text="拼命加载中" border fit highlight-current-row>
|
<el-table v-loading="listLoading" :data="list" element-loading-text="Loading..." border fit highlight-current-row>
|
||||||
<el-table-column align="center" label="Id" width="95">
|
<el-table-column align="center" label="Id" width="95">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
{{ scope.$index }}
|
{{ scope.$index }}
|
||||||
|
@ -51,7 +51,6 @@ import { parseTime } from '@/utils'
|
||||||
import FilenameOption from './components/FilenameOption'
|
import FilenameOption from './components/FilenameOption'
|
||||||
import AutoWidthOption from './components/AutoWidthOption'
|
import AutoWidthOption from './components/AutoWidthOption'
|
||||||
import BookTypeOption from './components/BookTypeOption'
|
import BookTypeOption from './components/BookTypeOption'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ExportExcel',
|
name: 'ExportExcel',
|
||||||
components: { FilenameOption, AutoWidthOption, BookTypeOption },
|
components: { FilenameOption, AutoWidthOption, BookTypeOption },
|
||||||
|
|
|
@ -71,21 +71,21 @@ export default {
|
||||||
},
|
},
|
||||||
handleDownload() {
|
handleDownload() {
|
||||||
this.downloadLoading = true
|
this.downloadLoading = true
|
||||||
import('@/vendor/Export2Excel').then(excel => {
|
import('@/vendor/Export2Excel').then(excel => {
|
||||||
const multiHeader = [['Id', 'Main Information', '', '', 'Date']]
|
const multiHeader = [['Id', 'Main Information', '', '', 'Date']]
|
||||||
const header = ['', 'Title', 'Author', 'Readings', '']
|
const header = ['', 'Title', 'Author', 'Readings', '']
|
||||||
const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time']
|
const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time']
|
||||||
const list = this.list
|
const list = this.list
|
||||||
const data = this.formatJson(filterVal, list)
|
const data = this.formatJson(filterVal, list)
|
||||||
const merges = ['A1:A2', 'B1:D1', 'E1:E2']
|
const merges = ['A1:A2', 'B1:D1', 'E1:E2']
|
||||||
excel.export_json_to_excel({
|
excel.export_json_to_excel({
|
||||||
multiHeader,
|
multiHeader,
|
||||||
header,
|
header,
|
||||||
merges,
|
merges,
|
||||||
data
|
data
|
||||||
})
|
|
||||||
this.downloadLoading = false
|
|
||||||
})
|
})
|
||||||
|
this.downloadLoading = false
|
||||||
|
})
|
||||||
},
|
},
|
||||||
formatJson(filterVal, jsonData) {
|
formatJson(filterVal, jsonData) {
|
||||||
return jsonData.map(v => filterVal.map(j => {
|
return jsonData.map(v => filterVal.map(j => {
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<el-input v-model="filename" placeholder="Please enter the file name (default excel-list)" style="width:350px;" prefix-icon="el-icon-document" />
|
<!-- $t is vue-i18n global function to translate lang -->
|
||||||
|
<el-input v-model="filename" :placeholder="$t('excel.placeholder')" style="width:350px;" prefix-icon="el-icon-document" />
|
||||||
<el-button :loading="downloadLoading" style="margin-bottom:20px" type="primary" icon="el-icon-document" @click="handleDownload">
|
<el-button :loading="downloadLoading" style="margin-bottom:20px" type="primary" icon="el-icon-document" @click="handleDownload">
|
||||||
Export Selected Items
|
{{ $t('excel.selectedExport') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<a href="https://panjiachen.github.io/vue-element-admin-site/feature/component/excel.html" target="_blank" style="margin-left:15px;">
|
<a href="https://panjiachen.github.io/vue-element-admin-site/feature/component/excel.html" target="_blank" style="margin-left:15px;">
|
||||||
<el-tag type="info">Documentation</el-tag>
|
<el-tag type="info">Documentation</el-tag>
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<aside>
|
<aside>
|
||||||
The guide page is useful for some people who entered the project for the first time. You can briefly introduce the
|
{{ $t('guide.description') }}
|
||||||
features of the project. Demo is based on
|
|
||||||
<a href="https://github.com/kamranahmedse/driver.js" target="_blank">driver.js.</a>
|
<a href="https://github.com/kamranahmedse/driver.js" target="_blank">driver.js.</a>
|
||||||
</aside>
|
</aside>
|
||||||
<el-button icon="el-icon-question" type="primary" @click.prevent.stop="guide">
|
<el-button icon="el-icon-question" type="primary" @click.prevent.stop="guide">
|
||||||
Show Guide
|
{{ $t('guide.button') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -0,0 +1,168 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-card class="box-card" style="margin-top:40px;">
|
||||||
|
<div slot="header" class="clearfix">
|
||||||
|
<svg-icon icon-class="international" />
|
||||||
|
<span style="margin-left:10px;">{{ $t('i18nView.title') }}</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-radio-group v-model="lang" size="small">
|
||||||
|
<el-radio label="zh" border>
|
||||||
|
简体中文
|
||||||
|
</el-radio>
|
||||||
|
<el-radio label="en" border>
|
||||||
|
English
|
||||||
|
</el-radio>
|
||||||
|
<el-radio label="es" border>
|
||||||
|
Español
|
||||||
|
</el-radio>
|
||||||
|
<el-radio label="ja" border>
|
||||||
|
日本語
|
||||||
|
</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
<el-tag style="margin-top:15px;display:block;" type="info">
|
||||||
|
{{ $t('i18nView.note') }}
|
||||||
|
</el-tag>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<el-row :gutter="20" style="margin:100px 15px 50px;">
|
||||||
|
<el-col :span="12" :xs="24">
|
||||||
|
<div class="block">
|
||||||
|
<el-date-picker v-model="date" :placeholder="$t('i18nView.datePlaceholder')" type="date" />
|
||||||
|
</div>
|
||||||
|
<div class="block">
|
||||||
|
<el-select v-model="value" :placeholder="$t('i18nView.selectPlaceholder')">
|
||||||
|
<el-option
|
||||||
|
v-for="item in options"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div class="block">
|
||||||
|
<el-button class="item-btn" size="small">
|
||||||
|
{{ $t('i18nView.default') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button class="item-btn" size="small" type="primary">
|
||||||
|
{{ $t('i18nView.primary') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button class="item-btn" size="small" type="success">
|
||||||
|
{{ $t('i18nView.success') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button class="item-btn" size="small" type="info">
|
||||||
|
{{ $t('i18nView.info') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button class="item-btn" size="small" type="warning">
|
||||||
|
{{ $t('i18nView.warning') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button class="item-btn" size="small" type="danger">
|
||||||
|
{{ $t('i18nView.danger') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12" :xs="24">
|
||||||
|
<el-table :data="tableData" fit highlight-current-row border style="width: 100%">
|
||||||
|
<el-table-column :label="$t('i18nView.tableName')" prop="name" width="100" align="center" />
|
||||||
|
<el-table-column :label="$t('i18nView.tableDate')" prop="date" width="120" align="center" />
|
||||||
|
<el-table-column :label="$t('i18nView.tableAddress')" prop="address" />
|
||||||
|
</el-table>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import local from './local'
|
||||||
|
const viewName = 'i18nView'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'I18n',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
date: '',
|
||||||
|
tableData: [{
|
||||||
|
date: '2016-05-03',
|
||||||
|
name: 'Tom',
|
||||||
|
address: 'No. 189, Grove St, Los Angeles'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: '2016-05-02',
|
||||||
|
name: 'Tom',
|
||||||
|
address: 'No. 189, Grove St, Los Angeles'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: '2016-05-04',
|
||||||
|
name: 'Tom',
|
||||||
|
address: 'No. 189, Grove St, Los Angeles'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: '2016-05-01',
|
||||||
|
name: 'Tom',
|
||||||
|
address: 'No. 189, Grove St, Los Angeles'
|
||||||
|
}],
|
||||||
|
options: [],
|
||||||
|
value: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
lang: {
|
||||||
|
get() {
|
||||||
|
return this.$store.state.app.language
|
||||||
|
},
|
||||||
|
set(lang) {
|
||||||
|
this.$i18n.locale = lang
|
||||||
|
this.$store.dispatch('app/setLanguage', lang)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
lang() {
|
||||||
|
this.setOptions()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
if (!this.$i18n.getLocaleMessage('en')[viewName]) {
|
||||||
|
this.$i18n.mergeLocaleMessage('en', local.en)
|
||||||
|
this.$i18n.mergeLocaleMessage('zh', local.zh)
|
||||||
|
this.$i18n.mergeLocaleMessage('es', local.es)
|
||||||
|
this.$i18n.mergeLocaleMessage('ja', local.ja)
|
||||||
|
}
|
||||||
|
this.setOptions() // set default select options
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
setOptions() {
|
||||||
|
this.options = [
|
||||||
|
{
|
||||||
|
value: '1',
|
||||||
|
label: this.$t('i18nView.one')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: '2',
|
||||||
|
label: this.$t('i18nView.two')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: '3',
|
||||||
|
label: this.$t('i18nView.three')
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.box-card {
|
||||||
|
width: 600px;
|
||||||
|
max-width: 100%;
|
||||||
|
margin: 20px auto;
|
||||||
|
}
|
||||||
|
.item-btn{
|
||||||
|
margin-bottom: 15px;
|
||||||
|
margin-left: 0px;
|
||||||
|
}
|
||||||
|
.block {
|
||||||
|
padding: 25px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,83 @@
|
||||||
|
|
||||||
|
export default {
|
||||||
|
zh: {
|
||||||
|
i18nView: {
|
||||||
|
title: '切换语言',
|
||||||
|
note: '本项目国际化基于 vue-i18n',
|
||||||
|
datePlaceholder: '请选择日期',
|
||||||
|
selectPlaceholder: '请选择',
|
||||||
|
tableDate: '日期',
|
||||||
|
tableName: '姓名',
|
||||||
|
tableAddress: '地址',
|
||||||
|
default: '默认按钮',
|
||||||
|
primary: '主要按钮',
|
||||||
|
success: '成功按钮',
|
||||||
|
info: '信息按钮',
|
||||||
|
warning: '警告按钮',
|
||||||
|
danger: '危险按钮',
|
||||||
|
one: '一',
|
||||||
|
two: '二',
|
||||||
|
three: '三'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
en: {
|
||||||
|
i18nView: {
|
||||||
|
title: 'Switch Language',
|
||||||
|
note: 'The internationalization of this project is based on vue-i18n',
|
||||||
|
datePlaceholder: 'Pick a day',
|
||||||
|
selectPlaceholder: 'Select',
|
||||||
|
tableDate: 'tableDate',
|
||||||
|
tableName: 'tableName',
|
||||||
|
tableAddress: 'tableAddress',
|
||||||
|
default: 'default:',
|
||||||
|
primary: 'primary',
|
||||||
|
success: 'success',
|
||||||
|
info: 'info',
|
||||||
|
warning: 'warning',
|
||||||
|
danger: 'danger',
|
||||||
|
one: 'One',
|
||||||
|
two: 'Two',
|
||||||
|
three: 'Three'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
es: {
|
||||||
|
i18nView: {
|
||||||
|
title: 'Switch Language',
|
||||||
|
note: 'The internationalization of this project is based on vue-i18n',
|
||||||
|
datePlaceholder: 'Pick a day',
|
||||||
|
selectPlaceholder: 'Select',
|
||||||
|
tableDate: 'tableDate',
|
||||||
|
tableName: 'tableName',
|
||||||
|
tableAddress: 'tableAddress',
|
||||||
|
default: 'default:',
|
||||||
|
primary: 'primary',
|
||||||
|
success: 'success',
|
||||||
|
info: 'info',
|
||||||
|
warning: 'warning',
|
||||||
|
danger: 'danger',
|
||||||
|
one: 'One',
|
||||||
|
two: 'Two',
|
||||||
|
three: 'Three'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ja: {
|
||||||
|
i18nView: {
|
||||||
|
title: '言語切替',
|
||||||
|
note: 'vue-i18nを使っています',
|
||||||
|
datePlaceholder: '日時選択',
|
||||||
|
selectPlaceholder: '選択してください',
|
||||||
|
tableDate: '日時',
|
||||||
|
tableName: '姓名',
|
||||||
|
tableAddress: '住所',
|
||||||
|
default: 'default',
|
||||||
|
primary: 'primary',
|
||||||
|
success: 'success',
|
||||||
|
info: 'info',
|
||||||
|
warning: 'warning',
|
||||||
|
danger: 'danger',
|
||||||
|
one: '1',
|
||||||
|
two: '2',
|
||||||
|
three: '3'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,74 +1,3 @@
|
||||||
const elementIcons = [
|
const elementIcons = ['platform-eleme', 'eleme', 'delete-solid', 'delete', 's-tools', 'setting', 'user-solid', 'user', 'phone', 'phone-outline', 'more', 'more-outline', 'star-on', 'star-off', 's-goods', 'goods', 'warning', 'warning-outline', 'question', 'info', 'remove', 'circle-plus', 'success', 'error', 'zoom-in', 'zoom-out', 'remove-outline', 'circle-plus-outline', 'circle-check', 'circle-close', 's-help', 'help', 'minus', 'plus', 'check', 'close', 'picture', 'picture-outline', 'picture-outline-round', 'upload', 'upload2', 'download', 'camera-solid', 'camera', 'video-camera-solid', 'video-camera', 'message-solid', 'bell', 's-cooperation', 's-order', 's-platform', 's-fold', 's-unfold', 's-operation', 's-promotion', 's-home', 's-release', 's-ticket', 's-management', 's-open', 's-shop', 's-marketing', 's-flag', 's-comment', 's-finance', 's-claim', 's-custom', 's-opportunity', 's-data', 's-check', 's-grid', 'menu', 'share', 'd-caret', 'caret-left', 'caret-right', 'caret-bottom', 'caret-top', 'bottom-left', 'bottom-right', 'back', 'right', 'bottom', 'top', 'top-left', 'top-right', 'arrow-left', 'arrow-right', 'arrow-down', 'arrow-up', 'd-arrow-left', 'd-arrow-right', 'video-pause', 'video-play', 'refresh', 'refresh-right', 'refresh-left', 'finished', 'sort', 'sort-up', 'sort-down', 'rank', 'loading', 'view', 'c-scale-to-original', 'date', 'edit', 'edit-outline', 'folder', 'folder-opened', 'folder-add', 'folder-remove', 'folder-delete', 'folder-checked', 'tickets', 'document-remove', 'document-delete', 'document-copy', 'document-checked', 'document', 'document-add', 'printer', 'paperclip', 'takeaway-box', 'search', 'monitor', 'attract', 'mobile', 'scissors', 'umbrella', 'headset', 'brush', 'mouse', 'coordinate', 'magic-stick', 'reading', 'data-line', 'data-board', 'pie-chart', 'data-analysis', 'collection-tag', 'film', 'suitcase', 'suitcase-1', 'receiving', 'collection', 'files', 'notebook-1', 'notebook-2', 'toilet-paper', 'office-building', 'school', 'table-lamp', 'house', 'no-smoking', 'smoking', 'shopping-cart-full', 'shopping-cart-1', 'shopping-cart-2', 'shopping-bag-1', 'shopping-bag-2', 'sold-out', 'sell', 'present', 'box', 'bank-card', 'money', 'coin', 'wallet', 'discount', 'price-tag', 'news', 'guide', 'male', 'female', 'thumb', 'cpu', 'link', 'connection', 'open', 'turn-off', 'set-up', 'chat-round', 'chat-line-round', 'chat-square', 'chat-dot-round', 'chat-dot-square', 'chat-line-square', 'message', 'postcard', 'position', 'turn-off-microphone', 'microphone', 'close-notification', 'bangzhu', 'time', 'odometer', 'crop', 'aim', 'switch-button', 'full-screen', 'copy-document', 'mic', 'stopwatch', 'medal-1', 'medal', 'trophy', 'trophy-1', 'first-aid-kit', 'discover', 'place', 'location', 'location-outline', 'location-information', 'add-location', 'delete-location', 'map-location', 'alarm-clock', 'timer', 'watch-1', 'watch', 'lock', 'unlock', 'key', 'service', 'mobile-phone', 'bicycle', 'truck', 'ship', 'basketball', 'football', 'soccer', 'baseball', 'wind-power', 'light-rain', 'lightning', 'heavy-rain', 'sunrise', 'sunrise-1', 'sunset', 'sunny', 'cloudy', 'partly-cloudy', 'cloudy-and-sunny', 'moon', 'moon-night', 'dish', 'dish-1', 'food', 'chicken', 'fork-spoon', 'knife-fork', 'burger', 'tableware', 'sugar', 'dessert', 'ice-cream', 'hot-water', 'water-cup', 'coffee-cup', 'cold-drink', 'goblet', 'goblet-full', 'goblet-square', 'goblet-square-full', 'refrigerator', 'grape', 'watermelon', 'cherry', 'apple', 'pear', 'orange', 'coffee', 'ice-tea', 'ice-drink', 'milk-tea', 'potato-strips', 'lollipop', 'ice-cream-square', 'ice-cream-round']
|
||||||
'info',
|
|
||||||
'error',
|
|
||||||
'success',
|
|
||||||
'warning',
|
|
||||||
'question',
|
|
||||||
'back',
|
|
||||||
'arrow-left',
|
|
||||||
'arrow-down',
|
|
||||||
'arrow-right',
|
|
||||||
'arrow-up',
|
|
||||||
'caret-left',
|
|
||||||
'caret-bottom',
|
|
||||||
'caret-top',
|
|
||||||
'caret-right',
|
|
||||||
'd-arrow-left',
|
|
||||||
'd-arrow-right',
|
|
||||||
'minus',
|
|
||||||
'plus',
|
|
||||||
'remove',
|
|
||||||
'circle-plus',
|
|
||||||
'remove-outline',
|
|
||||||
'circle-plus-outline',
|
|
||||||
'close',
|
|
||||||
'check',
|
|
||||||
'circle-close',
|
|
||||||
'circle-check',
|
|
||||||
'circle-close-outline',
|
|
||||||
'circle-check-outline',
|
|
||||||
'zoom-out',
|
|
||||||
'zoom-in',
|
|
||||||
'd-caret',
|
|
||||||
'sort',
|
|
||||||
'sort-down',
|
|
||||||
'sort-up',
|
|
||||||
'tickets',
|
|
||||||
'document',
|
|
||||||
'goods',
|
|
||||||
'sold-out',
|
|
||||||
'news',
|
|
||||||
'message',
|
|
||||||
'date',
|
|
||||||
'printer',
|
|
||||||
'time',
|
|
||||||
'bell',
|
|
||||||
'mobile-phone',
|
|
||||||
'service',
|
|
||||||
'view',
|
|
||||||
'menu',
|
|
||||||
'more',
|
|
||||||
'more-outline',
|
|
||||||
'star-on',
|
|
||||||
'star-off',
|
|
||||||
'location',
|
|
||||||
'location-outline',
|
|
||||||
'phone',
|
|
||||||
'phone-outline',
|
|
||||||
'picture',
|
|
||||||
'picture-outline',
|
|
||||||
'delete',
|
|
||||||
'search',
|
|
||||||
'edit',
|
|
||||||
'edit-outline',
|
|
||||||
'rank',
|
|
||||||
'refresh',
|
|
||||||
'share',
|
|
||||||
'setting',
|
|
||||||
'upload',
|
|
||||||
'upload2',
|
|
||||||
'download',
|
|
||||||
'loading'
|
|
||||||
]
|
|
||||||
|
|
||||||
export default elementIcons
|
export default elementIcons
|
||||||
|
|
|
@ -6,29 +6,33 @@
|
||||||
</aside>
|
</aside>
|
||||||
<el-tabs type="border-card">
|
<el-tabs type="border-card">
|
||||||
<el-tab-pane label="Icons">
|
<el-tab-pane label="Icons">
|
||||||
<div v-for="item of svgIcons" :key="item" @click="handleClipboard(generateIconCode(item),$event)">
|
<div class="grid">
|
||||||
<el-tooltip placement="top">
|
<div v-for="item of svgIcons" :key="item" @click="handleClipboard(generateIconCode(item),$event)">
|
||||||
<div slot="content">
|
<el-tooltip placement="top">
|
||||||
{{ generateIconCode(item) }}
|
<div slot="content">
|
||||||
</div>
|
{{ generateIconCode(item) }}
|
||||||
<div class="icon-item">
|
</div>
|
||||||
<svg-icon :icon-class="item" class-name="disabled" />
|
<div class="icon-item">
|
||||||
<span>{{ item }}</span>
|
<svg-icon :icon-class="item" class-name="disabled" />
|
||||||
</div>
|
<span>{{ item }}</span>
|
||||||
</el-tooltip>
|
</div>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="Element-UI Icons">
|
<el-tab-pane label="Element-UI Icons">
|
||||||
<div v-for="item of elementIcons" :key="item" @click="handleClipboard(generateElementIconCode(item),$event)">
|
<div class="grid">
|
||||||
<el-tooltip placement="top">
|
<div v-for="item of elementIcons" :key="item" @click="handleClipboard(generateElementIconCode(item),$event)">
|
||||||
<div slot="content">
|
<el-tooltip placement="top">
|
||||||
{{ generateElementIconCode(item) }}
|
<div slot="content">
|
||||||
</div>
|
{{ generateElementIconCode(item) }}
|
||||||
<div class="icon-item">
|
</div>
|
||||||
<i :class="'el-icon-' + item" />
|
<div class="icon-item">
|
||||||
<span>{{ item }}</span>
|
<i :class="'el-icon-' + item" />
|
||||||
</div>
|
<span>{{ item }}</span>
|
||||||
</el-tooltip>
|
</div>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
|
@ -67,6 +71,12 @@ export default {
|
||||||
margin: 10px 20px 0;
|
margin: 10px 20px 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
position: relative;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
.icon-item {
|
.icon-item {
|
||||||
margin: 20px;
|
margin: 20px;
|
||||||
height: 85px;
|
height: 85px;
|
||||||
|
|
|
@ -3,7 +3,10 @@
|
||||||
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" autocomplete="on" label-position="left">
|
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" autocomplete="on" label-position="left">
|
||||||
|
|
||||||
<div class="title-container">
|
<div class="title-container">
|
||||||
<h3 class="title">Login Form</h3>
|
<h3 class="title">
|
||||||
|
{{ $t('login.title') }}
|
||||||
|
</h3>
|
||||||
|
<lang-select class="set-language" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-form-item prop="username">
|
<el-form-item prop="username">
|
||||||
|
@ -13,7 +16,7 @@
|
||||||
<el-input
|
<el-input
|
||||||
ref="username"
|
ref="username"
|
||||||
v-model="loginForm.username"
|
v-model="loginForm.username"
|
||||||
placeholder="Username"
|
:placeholder="$t('login.username')"
|
||||||
name="username"
|
name="username"
|
||||||
type="text"
|
type="text"
|
||||||
tabindex="1"
|
tabindex="1"
|
||||||
|
@ -31,7 +34,7 @@
|
||||||
ref="password"
|
ref="password"
|
||||||
v-model="loginForm.password"
|
v-model="loginForm.password"
|
||||||
:type="passwordType"
|
:type="passwordType"
|
||||||
placeholder="Password"
|
:placeholder="$t('login.password')"
|
||||||
name="password"
|
name="password"
|
||||||
tabindex="2"
|
tabindex="2"
|
||||||
autocomplete="on"
|
autocomplete="on"
|
||||||
|
@ -45,26 +48,30 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
<el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">Login</el-button>
|
<el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">
|
||||||
|
{{ $t('login.logIn') }}
|
||||||
|
</el-button>
|
||||||
|
|
||||||
<div style="position:relative">
|
<div style="position:relative">
|
||||||
<div class="tips">
|
<div class="tips">
|
||||||
<span>Username : admin</span>
|
<span>{{ $t('login.username') }} : admin</span>
|
||||||
<span>Password : any</span>
|
<span>{{ $t('login.password') }} : {{ $t('login.any') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="tips">
|
<div class="tips">
|
||||||
<span style="margin-right:18px;">Username : editor</span>
|
<span style="margin-right:18px;">
|
||||||
<span>Password : any</span>
|
{{ $t('login.username') }} : editor
|
||||||
|
</span>
|
||||||
|
<span>{{ $t('login.password') }} : {{ $t('login.any') }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-button class="thirdparty-button" type="primary" @click="showDialog=true">
|
<el-button class="thirdparty-button" type="primary" @click="showDialog=true">
|
||||||
Or connect with
|
{{ $t('login.thirdparty') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<el-dialog title="Or connect with" :visible.sync="showDialog">
|
<el-dialog :title="$t('login.thirdparty')" :visible.sync="showDialog">
|
||||||
Can not be simulated on local, so please combine you own business simulation! ! !
|
{{ $t('login.thirdpartyTips') }}
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
|
@ -75,11 +82,12 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { validUsername } from '@/utils/validate'
|
import { validUsername } from '@/utils/validate'
|
||||||
|
import LangSelect from '@/components/LangSelect'
|
||||||
import SocialSign from './components/SocialSignin'
|
import SocialSign from './components/SocialSignin'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Login',
|
name: 'Login',
|
||||||
components: { SocialSign },
|
components: { LangSelect, SocialSign },
|
||||||
data() {
|
data() {
|
||||||
const validateUsername = (rule, value, callback) => {
|
const validateUsername = (rule, value, callback) => {
|
||||||
if (!validUsername(value)) {
|
if (!validUsername(value)) {
|
||||||
|
@ -138,17 +146,9 @@ export default {
|
||||||
// window.removeEventListener('storage', this.afterQRScan)
|
// window.removeEventListener('storage', this.afterQRScan)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
checkCapslock({ shiftKey, key } = {}) {
|
checkCapslock(e) {
|
||||||
if (key && key.length === 1) {
|
const { key } = e
|
||||||
if (shiftKey && (key >= 'a' && key <= 'z') || !shiftKey && (key >= 'A' && key <= 'Z')) {
|
this.capsTooltip = key && key.length === 1 && (key >= 'A' && key <= 'Z')
|
||||||
this.capsTooltip = true
|
|
||||||
} else {
|
|
||||||
this.capsTooltip = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (key === 'CapsLock' && this.capsTooltip === true) {
|
|
||||||
this.capsTooltip = false
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
showPwd() {
|
showPwd() {
|
||||||
if (this.passwordType === 'password') {
|
if (this.passwordType === 'password') {
|
||||||
|
@ -305,6 +305,15 @@ $light_gray:#eee;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.set-language {
|
||||||
|
color: #fff;
|
||||||
|
position: absolute;
|
||||||
|
top: 3px;
|
||||||
|
font-size: 18px;
|
||||||
|
right: 0px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.show-pwd {
|
.show-pwd {
|
||||||
|
|
|
@ -26,17 +26,17 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
fetchData() {
|
fetchData() {
|
||||||
import('./content.js').then(data => {
|
import('./content.js').then(data => {
|
||||||
const { title } = data.default
|
const { title } = data.default
|
||||||
document.title = title
|
document.title = title
|
||||||
this.article = data.default
|
this.article = data.default
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.fullscreenLoading = false
|
this.fullscreenLoading = false
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
window.print()
|
window.print()
|
||||||
})
|
})
|
||||||
}, 3000)
|
}, 3000)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<aside style="margin-top:15px;">
|
<aside style="margin-top:15px;">{{ $t('pdf.tips') }}</aside>
|
||||||
Here we use window.print() to implement the feature of downloading PDF.
|
|
||||||
</aside>
|
|
||||||
<router-link target="_blank" to="/pdf/download">
|
<router-link target="_blank" to="/pdf/download">
|
||||||
<el-button type="primary">
|
<el-button type="primary">
|
||||||
Click to download PDF
|
Click to download PDF
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div style="margin-bottom:15px;">
|
<div style="margin-bottom:15px;">
|
||||||
Your roles: {{ roles }}
|
{{ $t('permission.roles') }}: {{ roles }}
|
||||||
</div>
|
</div>
|
||||||
Switch roles:
|
{{ $t('permission.switchRoles') }}:
|
||||||
<el-radio-group v-model="switchRoles">
|
<el-radio-group v-model="switchRoles">
|
||||||
<el-radio-button label="editor" />
|
<el-radio-button label="editor" />
|
||||||
<el-radio-button label="admin" />
|
<el-radio-button label="admin" />
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
<div :key="'checkPermission'+key" style="margin-top:60px;">
|
<div :key="'checkPermission'+key" style="margin-top:60px;">
|
||||||
<aside>
|
<aside>
|
||||||
In some cases, using v-permission will have no effect. For example: Element-UI's Tab component or el-table-column and other scenes that dynamically render dom. You can only do this with v-if.
|
{{ $t('permission.tips') }}
|
||||||
<br> e.g.
|
<br> e.g.
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ export default {
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.app-container {
|
.app-container {
|
||||||
/deep/ .permission-alert {
|
::v-deep .permission-alert {
|
||||||
width: 320px;
|
width: 320px;
|
||||||
margin-top: 15px;
|
margin-top: 15px;
|
||||||
background-color: #f0f9eb;
|
background-color: #f0f9eb;
|
||||||
|
@ -100,10 +100,10 @@ export default {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
/deep/ .permission-sourceCode {
|
::v-deep .permission-sourceCode {
|
||||||
margin-left: 15px;
|
margin-left: 15px;
|
||||||
}
|
}
|
||||||
/deep/ .permission-tag {
|
::v-deep .permission-tag {
|
||||||
background-color: #ecf5ff;
|
background-color: #ecf5ff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<el-button type="primary" @click="handleAddRole">New Role</el-button>
|
<el-button type="primary" @click="handleAddRole">
|
||||||
|
{{ $t('permission.addRole') }}
|
||||||
|
</el-button>
|
||||||
|
|
||||||
<el-table :data="rolesList" style="width: 100%;margin-top:30px;" border>
|
<el-table :data="rolesList" style="width: 100%;margin-top:30px;" border>
|
||||||
<el-table-column align="center" label="Role Key" width="220">
|
<el-table-column align="center" label="Role Key" width="220">
|
||||||
|
@ -20,8 +22,12 @@
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column align="center" label="Operations">
|
<el-table-column align="center" label="Operations">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button type="primary" size="small" @click="handleEdit(scope)">Edit</el-button>
|
<el-button type="primary" size="small" @click="handleEdit(scope)">
|
||||||
<el-button type="danger" size="small" @click="handleDelete(scope)">Delete</el-button>
|
{{ $t('permission.editPermission') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button type="danger" size="small" @click="handleDelete(scope)">
|
||||||
|
{{ $t('permission.delete') }}
|
||||||
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
@ -40,20 +46,16 @@
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="Menus">
|
<el-form-item label="Menus">
|
||||||
<el-tree
|
<el-tree ref="tree" :check-strictly="checkStrictly" :data="routesData" :props="defaultProps" show-checkbox node-key="path" class="permission-tree" />
|
||||||
ref="tree"
|
|
||||||
:check-strictly="checkStrictly"
|
|
||||||
:data="routesData"
|
|
||||||
:props="defaultProps"
|
|
||||||
show-checkbox
|
|
||||||
node-key="path"
|
|
||||||
class="permission-tree"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div style="text-align:right;">
|
<div style="text-align:right;">
|
||||||
<el-button type="danger" @click="dialogVisible=false">Cancel</el-button>
|
<el-button type="danger" @click="dialogVisible=false">
|
||||||
<el-button type="primary" @click="confirmRole">Confirm</el-button>
|
{{ $t('permission.cancel') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button type="primary" @click="confirmRole">
|
||||||
|
{{ $t('permission.confirm') }}
|
||||||
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
|
@ -63,6 +65,7 @@
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import { deepClone } from '@/utils'
|
import { deepClone } from '@/utils'
|
||||||
import { getRoutes, getRoles, addRole, deleteRole, updateRole } from '@/api/role'
|
import { getRoutes, getRoles, addRole, deleteRole, updateRole } from '@/api/role'
|
||||||
|
import i18n from '@/lang'
|
||||||
|
|
||||||
const defaultRole = {
|
const defaultRole = {
|
||||||
key: '',
|
key: '',
|
||||||
|
@ -100,13 +103,23 @@ export default {
|
||||||
async getRoutes() {
|
async getRoutes() {
|
||||||
const res = await getRoutes()
|
const res = await getRoutes()
|
||||||
this.serviceRoutes = res.data
|
this.serviceRoutes = res.data
|
||||||
this.routes = this.generateRoutes(res.data)
|
const routes = this.generateRoutes(res.data)
|
||||||
|
this.routes = this.i18n(routes)
|
||||||
},
|
},
|
||||||
async getRoles() {
|
async getRoles() {
|
||||||
const res = await getRoles()
|
const res = await getRoles()
|
||||||
this.rolesList = res.data
|
this.rolesList = res.data
|
||||||
},
|
},
|
||||||
|
i18n(routes) {
|
||||||
|
const app = routes.map(route => {
|
||||||
|
route.title = i18n.t(`route.${route.title}`)
|
||||||
|
if (route.children) {
|
||||||
|
route.children = this.i18n(route.children)
|
||||||
|
}
|
||||||
|
return route
|
||||||
|
})
|
||||||
|
return app
|
||||||
|
},
|
||||||
// Reshape the routes structure so that it looks the same as the sidebar
|
// Reshape the routes structure so that it looks the same as the sidebar
|
||||||
generateRoutes(routes, basePath = '/') {
|
generateRoutes(routes, basePath = '/') {
|
||||||
const res = []
|
const res = []
|
||||||
|
|
|
@ -65,7 +65,7 @@ export default {
|
||||||
name: '',
|
name: '',
|
||||||
email: '',
|
email: '',
|
||||||
avatar: '',
|
avatar: '',
|
||||||
roles: ''
|
role: ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,61 +74,61 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.box-center {
|
.box-center {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
display: table;
|
display: table;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-muted {
|
.text-muted {
|
||||||
color: #777;
|
color: #777;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-profile {
|
.user-profile {
|
||||||
.user-name {
|
.user-name {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.box-center {
|
.box-center {
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-role {
|
.user-role {
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.box-social {
|
.box-social {
|
||||||
padding-top: 30px;
|
padding-top: 30px;
|
||||||
|
|
||||||
.el-table {
|
.el-table {
|
||||||
border-top: 1px solid #dfe6ec;
|
border-top: 1px solid #dfe6ec;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-follow {
|
.user-follow {
|
||||||
padding-top: 20px;
|
padding-top: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-bio {
|
.user-bio {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
color: #606266;
|
color: #606266;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
padding-left: 4px;
|
padding-left: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-bio-section {
|
.user-bio-section {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
padding: 15px 0;
|
padding: 15px 0;
|
||||||
|
|
||||||
.user-bio-section-header {
|
.user-bio-section-header {
|
||||||
border-bottom: 1px solid #dfe6ec;
|
border-bottom: 1px solid #dfe6ec;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -13,11 +13,11 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import tabPane from './components/TabPane'
|
import TabPane from './components/TabPane'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Tab',
|
name: 'Tab',
|
||||||
components: { tabPane },
|
components: { TabPane },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
tabMapOptions: [
|
tabMapOptions: [
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<div class="filter-container">
|
<div class="filter-container">
|
||||||
<el-input v-model="listQuery.title" placeholder="Title" style="width: 200px;" class="filter-item" @keyup.enter.native="handleFilter" />
|
<el-input v-model="listQuery.title" :placeholder="$t('table.title')" style="width: 200px;" class="filter-item" @keyup.enter.native="handleFilter" />
|
||||||
<el-select v-model="listQuery.importance" placeholder="Imp" clearable style="width: 90px" class="filter-item">
|
<el-select v-model="listQuery.importance" :placeholder="$t('table.importance')" clearable style="width: 90px" class="filter-item">
|
||||||
<el-option v-for="item in importanceOptions" :key="item" :label="item" :value="item" />
|
<el-option v-for="item in importanceOptions" :key="item" :label="item" :value="item" />
|
||||||
</el-select>
|
</el-select>
|
||||||
<el-select v-model="listQuery.type" placeholder="Type" clearable class="filter-item" style="width: 130px">
|
<el-select v-model="listQuery.type" :placeholder="$t('table.type')" clearable class="filter-item" style="width: 130px">
|
||||||
<el-option v-for="item in calendarTypeOptions" :key="item.key" :label="item.display_name+'('+item.key+')'" :value="item.key" />
|
<el-option v-for="item in calendarTypeOptions" :key="item.key" :label="item.display_name+'('+item.key+')'" :value="item.key" />
|
||||||
</el-select>
|
</el-select>
|
||||||
<el-select v-model="listQuery.sort" style="width: 140px" class="filter-item" @change="handleFilter">
|
<el-select v-model="listQuery.sort" style="width: 140px" class="filter-item" @change="handleFilter">
|
||||||
<el-option v-for="item in sortOptions" :key="item.key" :label="item.label" :value="item.key" />
|
<el-option v-for="item in sortOptions" :key="item.key" :label="item.label" :value="item.key" />
|
||||||
</el-select>
|
</el-select>
|
||||||
<el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">
|
<el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">
|
||||||
Search
|
{{ $t('table.search') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-edit" @click="handleCreate">
|
<el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-edit" @click="handleCreate">
|
||||||
Add
|
{{ $t('table.add') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button v-waves :loading="downloadLoading" class="filter-item" type="primary" icon="el-icon-download" @click="handleDownload">
|
<el-button v-waves :loading="downloadLoading" class="filter-item" type="primary" icon="el-icon-download" @click="handleDownload">
|
||||||
Export
|
{{ $t('table.export') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-checkbox v-model="showReviewer" class="filter-item" style="margin-left:15px;" @change="tableKey=tableKey+1">
|
<el-checkbox v-model="showReviewer" class="filter-item" style="margin-left:15px;" @change="tableKey=tableKey+1">
|
||||||
reviewer
|
{{ $t('table.reviewer') }}
|
||||||
</el-checkbox>
|
</el-checkbox>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -35,63 +35,63 @@
|
||||||
style="width: 100%;"
|
style="width: 100%;"
|
||||||
@sort-change="sortChange"
|
@sort-change="sortChange"
|
||||||
>
|
>
|
||||||
<el-table-column label="ID" prop="id" sortable="custom" align="center" width="80" :class-name="getSortClass('id')">
|
<el-table-column :label="$t('table.id')" prop="id" sortable="custom" align="center" width="80" :class-name="getSortClass('id')">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="{row}">
|
||||||
<span>{{ scope.row.id }}</span>
|
<span>{{ row.id }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="Date" width="150px" align="center">
|
<el-table-column :label="$t('table.date')" width="150px" align="center">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="{row}">
|
||||||
<span>{{ scope.row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
|
<span>{{ row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="Title" min-width="150px">
|
<el-table-column :label="$t('table.title')" min-width="150px">
|
||||||
<template slot-scope="{row}">
|
<template slot-scope="{row}">
|
||||||
<span class="link-type" @click="handleUpdate(row)">{{ row.title }}</span>
|
<span class="link-type" @click="handleUpdate(row)">{{ row.title }}</span>
|
||||||
<el-tag>{{ row.type | typeFilter }}</el-tag>
|
<el-tag>{{ row.type | typeFilter }}</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="Author" width="110px" align="center">
|
<el-table-column :label="$t('table.author')" width="110px" align="center">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="{row}">
|
||||||
<span>{{ scope.row.author }}</span>
|
<span>{{ row.author }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column v-if="showReviewer" label="Reviewer" width="110px" align="center">
|
<el-table-column v-if="showReviewer" :label="$t('table.reviewer')" width="110px" align="center">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="{row}">
|
||||||
<span style="color:red;">{{ scope.row.reviewer }}</span>
|
<span style="color:red;">{{ row.reviewer }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="Imp" width="80px">
|
<el-table-column :label="$t('table.importance')" width="80px">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="{row}">
|
||||||
<svg-icon v-for="n in +scope.row.importance" :key="n" icon-class="star" class="meta-item__icon" />
|
<svg-icon v-for="n in +row.importance" :key="n" icon-class="star" class="meta-item__icon" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="Readings" align="center" width="95">
|
<el-table-column :label="$t('table.readings')" align="center" width="95">
|
||||||
<template slot-scope="{row}">
|
<template slot-scope="{row}">
|
||||||
<span v-if="row.pageviews" class="link-type" @click="handleFetchPv(row.pageviews)">{{ row.pageviews }}</span>
|
<span v-if="row.pageviews" class="link-type" @click="handleFetchPv(row.pageviews)">{{ row.pageviews }}</span>
|
||||||
<span v-else>0</span>
|
<span v-else>0</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="Status" class-name="status-col" width="100">
|
<el-table-column :label="$t('table.status')" class-name="status-col" width="100">
|
||||||
<template slot-scope="{row}">
|
<template slot-scope="{row}">
|
||||||
<el-tag :type="row.status | statusFilter">
|
<el-tag :type="row.status | statusFilter">
|
||||||
{{ row.status }}
|
{{ row.status }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="Actions" align="center" width="230" class-name="small-padding fixed-width">
|
<el-table-column :label="$t('table.actions')" align="center" width="230" class-name="small-padding fixed-width">
|
||||||
<template slot-scope="{row}">
|
<template slot-scope="{row,$index}">
|
||||||
<el-button type="primary" size="mini" @click="handleUpdate(row)">
|
<el-button type="primary" size="mini" @click="handleUpdate(row)">
|
||||||
Edit
|
{{ $t('table.edit') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button v-if="row.status!='published'" size="mini" type="success" @click="handleModifyStatus(row,'published')">
|
<el-button v-if="row.status!='published'" size="mini" type="success" @click="handleModifyStatus(row,'published')">
|
||||||
Publish
|
{{ $t('table.publish') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button v-if="row.status!='draft'" size="mini" @click="handleModifyStatus(row,'draft')">
|
<el-button v-if="row.status!='draft'" size="mini" @click="handleModifyStatus(row,'draft')">
|
||||||
Draft
|
{{ $t('table.draft') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button v-if="row.status!='deleted'" size="mini" type="danger" @click="handleModifyStatus(row,'deleted')">
|
<el-button v-if="row.status!='deleted'" size="mini" type="danger" @click="handleDelete(row,$index)">
|
||||||
Delete
|
{{ $t('table.delete') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
@ -101,35 +101,35 @@
|
||||||
|
|
||||||
<el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
|
<el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
|
||||||
<el-form ref="dataForm" :rules="rules" :model="temp" label-position="left" label-width="70px" style="width: 400px; margin-left:50px;">
|
<el-form ref="dataForm" :rules="rules" :model="temp" label-position="left" label-width="70px" style="width: 400px; margin-left:50px;">
|
||||||
<el-form-item label="Type" prop="type">
|
<el-form-item :label="$t('table.type')" prop="type">
|
||||||
<el-select v-model="temp.type" class="filter-item" placeholder="Please select">
|
<el-select v-model="temp.type" class="filter-item" placeholder="Please select">
|
||||||
<el-option v-for="item in calendarTypeOptions" :key="item.key" :label="item.display_name" :value="item.key" />
|
<el-option v-for="item in calendarTypeOptions" :key="item.key" :label="item.display_name" :value="item.key" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="Date" prop="timestamp">
|
<el-form-item :label="$t('table.date')" prop="timestamp">
|
||||||
<el-date-picker v-model="temp.timestamp" type="datetime" placeholder="Please pick a date" />
|
<el-date-picker v-model="temp.timestamp" type="datetime" placeholder="Please pick a date" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="Title" prop="title">
|
<el-form-item :label="$t('table.title')" prop="title">
|
||||||
<el-input v-model="temp.title" />
|
<el-input v-model="temp.title" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="Status">
|
<el-form-item :label="$t('table.status')">
|
||||||
<el-select v-model="temp.status" class="filter-item" placeholder="Please select">
|
<el-select v-model="temp.status" class="filter-item" placeholder="Please select">
|
||||||
<el-option v-for="item in statusOptions" :key="item" :label="item" :value="item" />
|
<el-option v-for="item in statusOptions" :key="item" :label="item" :value="item" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="Imp">
|
<el-form-item :label="$t('table.importance')">
|
||||||
<el-rate v-model="temp.importance" :colors="['#99A9BF', '#F7BA2A', '#FF9900']" :max="3" style="margin-top:8px;" />
|
<el-rate v-model="temp.importance" :colors="['#99A9BF', '#F7BA2A', '#FF9900']" :max="3" style="margin-top:8px;" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="Remark">
|
<el-form-item :label="$t('table.remark')">
|
||||||
<el-input v-model="temp.remark" :autosize="{ minRows: 2, maxRows: 4}" type="textarea" placeholder="Please input" />
|
<el-input v-model="temp.remark" :autosize="{ minRows: 2, maxRows: 4}" type="textarea" placeholder="Please input" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div slot="footer" class="dialog-footer">
|
<div slot="footer" class="dialog-footer">
|
||||||
<el-button @click="dialogFormVisible = false">
|
<el-button @click="dialogFormVisible = false">
|
||||||
Cancel
|
{{ $t('table.cancel') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button type="primary" @click="dialogStatus==='create'?createData():updateData()">
|
<el-button type="primary" @click="dialogStatus==='create'?createData():updateData()">
|
||||||
Confirm
|
{{ $t('table.confirm') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
@ -140,7 +140,7 @@
|
||||||
<el-table-column prop="pv" label="Pv" />
|
<el-table-column prop="pv" label="Pv" />
|
||||||
</el-table>
|
</el-table>
|
||||||
<span slot="footer" class="dialog-footer">
|
<span slot="footer" class="dialog-footer">
|
||||||
<el-button type="primary" @click="dialogPvVisible = false">Confirm</el-button>
|
<el-button type="primary" @click="dialogPvVisible = false">{{ $t('table.confirm') }}</el-button>
|
||||||
</span>
|
</span>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
|
@ -248,7 +248,7 @@ export default {
|
||||||
},
|
},
|
||||||
handleModifyStatus(row, status) {
|
handleModifyStatus(row, status) {
|
||||||
this.$message({
|
this.$message({
|
||||||
message: '操作Success',
|
message: '操作成功',
|
||||||
type: 'success'
|
type: 'success'
|
||||||
})
|
})
|
||||||
row.status = status
|
row.status = status
|
||||||
|
@ -295,8 +295,8 @@ export default {
|
||||||
this.list.unshift(this.temp)
|
this.list.unshift(this.temp)
|
||||||
this.dialogFormVisible = false
|
this.dialogFormVisible = false
|
||||||
this.$notify({
|
this.$notify({
|
||||||
title: 'Success',
|
title: '成功',
|
||||||
message: 'Created Successfully',
|
message: '创建成功',
|
||||||
type: 'success',
|
type: 'success',
|
||||||
duration: 2000
|
duration: 2000
|
||||||
})
|
})
|
||||||
|
@ -319,17 +319,12 @@ export default {
|
||||||
const tempData = Object.assign({}, this.temp)
|
const tempData = Object.assign({}, this.temp)
|
||||||
tempData.timestamp = +new Date(tempData.timestamp) // change Thu Nov 30 2017 16:41:05 GMT+0800 (CST) to 1512031311464
|
tempData.timestamp = +new Date(tempData.timestamp) // change Thu Nov 30 2017 16:41:05 GMT+0800 (CST) to 1512031311464
|
||||||
updateArticle(tempData).then(() => {
|
updateArticle(tempData).then(() => {
|
||||||
for (const v of this.list) {
|
const index = this.list.findIndex(v => v.id === this.temp.id)
|
||||||
if (v.id === this.temp.id) {
|
this.list.splice(index, 1, this.temp)
|
||||||
const index = this.list.indexOf(v)
|
|
||||||
this.list.splice(index, 1, this.temp)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.dialogFormVisible = false
|
this.dialogFormVisible = false
|
||||||
this.$notify({
|
this.$notify({
|
||||||
title: 'Success',
|
title: '成功',
|
||||||
message: 'Update Successfully',
|
message: '更新成功',
|
||||||
type: 'success',
|
type: 'success',
|
||||||
duration: 2000
|
duration: 2000
|
||||||
})
|
})
|
||||||
|
@ -337,14 +332,13 @@ export default {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
handleDelete(row) {
|
handleDelete(row, index) {
|
||||||
this.$notify({
|
this.$notify({
|
||||||
title: 'Success',
|
title: '成功',
|
||||||
message: 'Delete Successfully',
|
message: '删除成功',
|
||||||
type: 'success',
|
type: 'success',
|
||||||
duration: 2000
|
duration: 2000
|
||||||
})
|
})
|
||||||
const index = this.list.indexOf(row)
|
|
||||||
this.list.splice(index, 1)
|
this.list.splice(index, 1)
|
||||||
},
|
},
|
||||||
handleFetchPv(pv) {
|
handleFetchPv(pv) {
|
||||||
|
@ -358,7 +352,7 @@ export default {
|
||||||
import('@/vendor/Export2Excel').then(excel => {
|
import('@/vendor/Export2Excel').then(excel => {
|
||||||
const tHeader = ['timestamp', 'title', 'type', 'importance', 'status']
|
const tHeader = ['timestamp', 'title', 'type', 'importance', 'status']
|
||||||
const filterVal = ['timestamp', 'title', 'type', 'importance', 'status']
|
const filterVal = ['timestamp', 'title', 'type', 'importance', 'status']
|
||||||
const data = this.formatJson(filterVal, this.list)
|
const data = this.formatJson(filterVal)
|
||||||
excel.export_json_to_excel({
|
excel.export_json_to_excel({
|
||||||
header: tHeader,
|
header: tHeader,
|
||||||
data,
|
data,
|
||||||
|
@ -367,8 +361,8 @@ export default {
|
||||||
this.downloadLoading = false
|
this.downloadLoading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
formatJson(filterVal, jsonData) {
|
formatJson(filterVal) {
|
||||||
return jsonData.map(v => filterVal.map(j => {
|
return this.list.map(v => filterVal.map(j => {
|
||||||
if (j === 'timestamp') {
|
if (j === 'timestamp') {
|
||||||
return parseTime(v[j])
|
return parseTime(v[j])
|
||||||
} else {
|
} else {
|
||||||
|
@ -378,11 +372,7 @@ export default {
|
||||||
},
|
},
|
||||||
getSortClass: function(key) {
|
getSortClass: function(key) {
|
||||||
const sort = this.listQuery.sort
|
const sort = this.listQuery.sort
|
||||||
return sort === `+${key}`
|
return sort === `+${key}` ? 'ascending' : 'descending'
|
||||||
? 'ascending'
|
|
||||||
: sort === `-${key}`
|
|
||||||
? 'descending'
|
|
||||||
: ''
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,38 +3,38 @@
|
||||||
<!-- Note that row-key is necessary to get a correct row order. -->
|
<!-- Note that row-key is necessary to get a correct row order. -->
|
||||||
<el-table ref="dragTable" v-loading="listLoading" :data="list" row-key="id" border fit highlight-current-row style="width: 100%">
|
<el-table ref="dragTable" v-loading="listLoading" :data="list" row-key="id" border fit highlight-current-row style="width: 100%">
|
||||||
<el-table-column align="center" label="ID" width="65">
|
<el-table-column align="center" label="ID" width="65">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="{row}">
|
||||||
<span>{{ scope.row.id }}</span>
|
<span>{{ row.id }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column width="180px" align="center" label="Date">
|
<el-table-column width="180px" align="center" label="Date">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="{row}">
|
||||||
<span>{{ scope.row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
|
<span>{{ row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column min-width="300px" label="Title">
|
<el-table-column min-width="300px" label="Title">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="{row}">
|
||||||
<span>{{ scope.row.title }}</span>
|
<span>{{ row.title }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column width="110px" align="center" label="Author">
|
<el-table-column width="110px" align="center" label="Author">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="{row}">
|
||||||
<span>{{ scope.row.author }}</span>
|
<span>{{ row.author }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column width="100px" label="Importance">
|
<el-table-column width="100px" label="Importance">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="{row}">
|
||||||
<svg-icon v-for="n in +scope.row.importance" :key="n" icon-class="star" class="icon-star" />
|
<svg-icon v-for="n in + row.importance" :key="n" icon-class="star" class="icon-star" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column align="center" label="Readings" width="95">
|
<el-table-column align="center" label="Readings" width="95">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="{row}">
|
||||||
<span>{{ scope.row.pageviews }}</span>
|
<span>{{ row.pageviews }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
|
@ -52,11 +52,12 @@
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
<!-- $t is vue-i18n global function to translate lang (lang in @/lang) -->
|
||||||
<div class="show-d">
|
<div class="show-d">
|
||||||
<el-tag>The default order :</el-tag> {{ oldList }}
|
<el-tag style="margin-right:12px;">{{ $t('table.dragTips1') }} :</el-tag> {{ oldList }}
|
||||||
</div>
|
</div>
|
||||||
<div class="show-d">
|
<div class="show-d">
|
||||||
<el-tag>The after dragging order :</el-tag> {{ newList }}
|
<el-tag>{{ $t('table.dragTips2') }} :</el-tag> {{ newList }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<div style="margin:0 0 5px 20px">
|
<div style="margin:0 0 5px 20px">
|
||||||
Fixed header, sorted by header order,
|
{{ $t('table.dynamicTips1') }}
|
||||||
</div>
|
</div>
|
||||||
<fixed-thead />
|
<fixed-thead />
|
||||||
|
|
||||||
<div style="margin:30px 0 5px 20px">
|
<div style="margin:30px 0 5px 20px">
|
||||||
Not fixed header, sorted by click order
|
{{ $t('table.dynamicTips2') }}
|
||||||
</div>
|
</div>
|
||||||
<unfixed-thead />
|
<unfixed-thead />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,26 +2,26 @@
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<el-table v-loading="listLoading" :data="list" border fit highlight-current-row style="width: 100%">
|
<el-table v-loading="listLoading" :data="list" border fit highlight-current-row style="width: 100%">
|
||||||
<el-table-column align="center" label="ID" width="80">
|
<el-table-column align="center" label="ID" width="80">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="{row}">
|
||||||
<span>{{ scope.row.id }}</span>
|
<span>{{ row.id }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column width="180px" align="center" label="Date">
|
<el-table-column width="180px" align="center" label="Date">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="{row}">
|
||||||
<span>{{ scope.row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
|
<span>{{ row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column width="120px" align="center" label="Author">
|
<el-table-column width="120px" align="center" label="Author">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="{row}">
|
||||||
<span>{{ scope.row.author }}</span>
|
<span>{{ row.author }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column width="100px" label="Importance">
|
<el-table-column width="100px" label="Importance">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="{row}">
|
||||||
<svg-icon v-for="n in +scope.row.importance" :key="n" icon-class="star" class="meta-item__icon" />
|
<svg-icon v-for="n in + row.importance" :key="n" icon-class="star" class="meta-item__icon" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue