Commit d7d9c38c22e75021e7944d0e3f5f67b68dccb23d
1 parent
feb3d4f57f
Exists in
master
auto commit the code by alias command
Showing
314 changed files
with
20034 additions
and
2674 deletions
Show diff stats
1 | MIT License | 1 | MIT License |
2 | 2 | ||
3 | Copyright (c) 2017-present PanJiaChen | 3 | Copyright (c) 2017-present PanJiaChen |
4 | 4 | ||
5 | Permission is hereby granted, free of charge, to any person obtaining a copy | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy |
6 | of this software and associated documentation files (the "Software"), to deal | 6 | of this software and associated documentation files (the "Software"), to deal |
7 | in the Software without restriction, including without limitation the rights | 7 | in the Software without restriction, including without limitation the rights |
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
9 | copies of the Software, and to permit persons to whom the Software is | 9 | copies of the Software, and to permit persons to whom the Software is |
10 | furnished to do so, subject to the following conditions: | 10 | furnished to do so, subject to the following conditions: |
11 | 11 | ||
12 | The above copyright notice and this permission notice shall be included in all | 12 | The above copyright notice and this permission notice shall be included in all |
13 | copies or substantial portions of the Software. | 13 | copies or substantial portions of the Software. |
14 | 14 | ||
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
21 | SOFTWARE. | 21 | SOFTWARE. |
22 | 22 |
README.es.md
File was created | 1 | <p align="center"> | |
2 | <img width="320" src="https://wpimg.wallstcn.com/ecc53a42-d79b-42e2-8852-5126b810a4c8.svg"> | ||
3 | </p> | ||
4 | |||
5 | <p align="center"> | ||
6 | <a href="https://github.com/vuejs/vue"> | ||
7 | <img src="https://img.shields.io/badge/vue-2.6.10-brightgreen.svg" alt="vue"> | ||
8 | </a> | ||
9 | <a href="https://github.com/ElemeFE/element"> | ||
10 | <img src="https://img.shields.io/badge/element--ui-2.7.0-brightgreen.svg" alt="element-ui"> | ||
11 | </a> | ||
12 | <a href="https://travis-ci.org/PanJiaChen/vue-element-admin" rel="nofollow"> | ||
13 | <img src="https://travis-ci.org/PanJiaChen/vue-element-admin.svg?branch=master" alt="Estado de Construcción"> | ||
14 | </a> | ||
15 | <a href="https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE"> | ||
16 | <img src="https://img.shields.io/github/license/mashape/apistatus.svg" alt="Licencia"> | ||
17 | </a> | ||
18 | <a href="https://github.com/PanJiaChen/vue-element-admin/releases"> | ||
19 | <img src="https://img.shields.io/github/release/PanJiaChen/vue-element-admin.svg" alt="Liberación Github"> | ||
20 | </a> | ||
21 | <a href="https://gitter.im/vue-element-admin/discuss"> | ||
22 | <img src="https://badges.gitter.im/Join%20Chat.svg" alt="Gitter"> | ||
23 | </a> | ||
24 | <a href="https://panjiachen.github.io/vue-element-admin-site/donate"> | ||
25 | <img src="https://img.shields.io/badge/%24-donate-ff69b4.svg" alt="Donación"> | ||
26 | </a> | ||
27 | </p> | ||
28 | |||
29 | Español | [English](./README.md) | [简体中文](./README.zh-CN.md) | [日本語](./README.ja.md) | ||
30 | |||
31 | ## Introducción | ||
32 | |||
33 | [vue-element-admin](https://panjiachen.github.io/vue-element-admin) es una interfáz de administración preparada para producción. Está basada en [vue](https://github.com/vuejs/vue) y usa [element-ui](https://github.com/ElemeFE/element) como conjunto de herramientas de interfáz de usuario. | ||
34 | |||
35 | Vue Element Admin es una solución práctica basada en la nueva plataforma de desarrollo de vue, construida con soporte a i18 para el manejo de múltiples lenguajes, plantillas estándares para aplicaciones de negocio y un conjunto de asombrosas características. Esta herramienta ayuda a construir largas y complejas Aplicacones de una sola página (SPA). Creo que lo que necesites hacer, este proyecto te ayudará. | ||
36 | |||
37 | - [Vista Prévia de la Aplicación](https://panjiachen.github.io/vue-element-admin) | ||
38 | |||
39 | - [Documentación](https://panjiachen.github.io/vue-element-admin-site/) | ||
40 | |||
41 | - [Canal de Gitter](https://gitter.im/vue-element-admin/discuss) | ||
42 | |||
43 | - [Para Donaciones](https://panjiachen.github.io/vue-element-admin-site/donate/) | ||
44 | |||
45 | - [Enlace de Wiki](https://github.com/PanJiaChen/vue-element-admin/wiki) | ||
46 | |||
47 | - [Canal de Gitee](https://panjiachen.gitee.io/vue-element-admin/) | ||
48 | |||
49 | - Plantilla base recomendada para usar: [vue-admin-template](https://github.com/PanJiaChen/vue-admin-template) | ||
50 | - Aplicación de Escritorio: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin) | ||
51 | - Plantilla de Typescript: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (Créditos: [@Armour](https://github.com/Armour)) | ||
52 | - [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312) | ||
53 | |||
54 | **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** | ||
55 | |||
56 | **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`** | ||
57 | |||
58 | **Este proyecto no está soportado para versiones muy viejas de navegadores (e.g. IE).** | ||
59 | |||
60 | ## Preparación | ||
61 | |||
62 | 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). | ||
63 | Entendiendo y aprendiendo esto pudiera ayudarle con su proyecto. | ||
64 | |||
65 | <p align="center"> | ||
66 | <img width="900" src="https://wpimg.wallstcn.com/a5894c1b-f6af-456e-82df-1151da0839bf.png"> | ||
67 | </p> | ||
68 | |||
69 | ## Patrocinantes | ||
70 | |||
71 | 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) | ||
72 | |||
73 | <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> | ||
74 | |||
75 | ## Características | ||
76 | |||
77 | ``` | ||
78 | - Iniciar / Cerrar Sesión | ||
79 | |||
80 | - Permisos de Authentication | ||
81 | - Página de Permisos | ||
82 | - Directivas de permisos | ||
83 | - Página de configuración de permisos | ||
84 | - Autenticación por dos pasos | ||
85 | |||
86 | - Construcción Multi-entorno | ||
87 | - dev sit stage producción | ||
88 | |||
89 | - Características Globales | ||
90 | - I18n | ||
91 | - Temas dinámicos | ||
92 | - Dynamic sidebar (soporte a rutas multi-nivel) | ||
93 | - Barra de rutas dinámica | ||
94 | - Tags-view (Tab page Support right-click operation) | ||
95 | - Svg Sprite | ||
96 | - Datos de simulación con Mock | ||
97 | - Pantalla completa | ||
98 | - Responsive Sidebar | ||
99 | |||
100 | - Editor | ||
101 | - Editor de Texto Enriquecido | ||
102 | - Editor Markdown | ||
103 | - Editor JSON | ||
104 | |||
105 | - Excel | ||
106 | - Exportación a Excel | ||
107 | - Carga de Excel | ||
108 | - Visualización de Excel | ||
109 | - Exportación como zip | ||
110 | |||
111 | - Tabla | ||
112 | - Tabla Dinámica | ||
113 | - Tabla con Arrastrar y Soltar | ||
114 | - Tabla de edición en línea | ||
115 | |||
116 | - Páginas de Error | ||
117 | - 401 | ||
118 | - 404 | ||
119 | |||
120 | - Componentes | ||
121 | - Carga de Avatar | ||
122 | - Botón para subir al inicio | ||
123 | - Arrastrar y Soltar (Diaglogo) | ||
124 | - Arrastrar y Soltar (Seleccionar) | ||
125 | - Arrastrar y Soltar (Kanban) | ||
126 | - Arrastrar y Soltar (Lista) | ||
127 | - Panel de división | ||
128 | - Componente para soltar archivos | ||
129 | - Adhesión de objetos | ||
130 | - Contador hasta | ||
131 | |||
132 | - Ejemplo Avanzado | ||
133 | - Registro de Errores | ||
134 | - Tablero de indicadores | ||
135 | - Página de Guías | ||
136 | - ECharts (Gráficos) | ||
137 | - Portapapeles | ||
138 | - Convertidor de Markdown a html | ||
139 | ``` | ||
140 | |||
141 | ## Iniciando | ||
142 | |||
143 | ```bash | ||
144 | # clone el proyecto | ||
145 | git clone https://github.com/PanJiaChen/vue-element-admin.git | ||
146 | |||
147 | # vaya al directorio clonado | ||
148 | cd vue-element-admin | ||
149 | |||
150 | # instale las dependencias | ||
151 | npm install | ||
152 | |||
153 | # corra el proyecto como desarrollador | ||
154 | npm run dev | ||
155 | ``` | ||
156 | |||
157 | Automáticamente se abrirá el siguiente enlace en su navegador http://localhost:9527 | ||
158 | |||
159 | ## Construcción | ||
160 | |||
161 | ```bash | ||
162 | # Construcción para entornos de prueba | ||
163 | npm run build:stage | ||
164 | |||
165 | # Construcción para entornos de producción | ||
166 | npm run build:prod | ||
167 | ``` | ||
168 | |||
169 | ## Avanzado | ||
170 | |||
171 | ```bash | ||
172 | # Vista previa con efectos de entorno | ||
173 | npm run preview | ||
174 | |||
175 | # Vista previa con efectos + análisis de recursos estáticos | ||
176 | npm run preview -- --report | ||
177 | |||
178 | # Chequeo de formato de código | ||
179 | npm run lint | ||
180 | |||
181 | # Chequeo de formato de código y auto-corrección | ||
182 | npm run lint -- --fix | ||
183 | ``` | ||
184 | |||
185 | Vaya a [Documentación](https://panjiachen.github.io/vue-element-admin-site/guide/essentials/deploy.html) para mayor información | ||
186 | |||
187 | ## Registro de Cambios | ||
188 | |||
189 | Los cambios detallados por cada liberación se encuentran en [notas de liberación](https://github.com/PanJiaChen/vue-element-admin/releases). | ||
190 | |||
191 | ## Demostración en línea | ||
192 | |||
193 | [Vista Prévia de la Aplicación](https://panjiachen.github.io/vue-element-admin) | ||
194 | |||
195 | ## Donación | ||
196 | |||
197 | Si este proyecto es de mucha ayuda para ti, puedes comprarle al autor un vaso de jugo :tropical_drink: | ||
198 | |||
199 |  | ||
200 | |||
201 | [dona por Paypal](https://www.paypal.me/panfree23) | ||
202 | |||
203 | [Comprame un Café](https://www.buymeacoffee.com/Pan) | ||
204 | |||
205 | ## Navegadores Soportados | ||
206 | |||
207 | Navegadores modernos e Internet Explorer 10+. | ||
208 | |||
209 | | [<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 | | ||
210 | | --------- | --------- | --------- | --------- | | ||
211 | | IE10, IE11, Edge| últimas 2 versiones| últimas 2 versiones| últimas 2 versiones | ||
212 | |||
213 | ## Licencia | ||
214 | |||
215 | [MIT](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE) | ||
216 | |||
217 | Copyright (c) 2017-presente PanJiaChen | ||
218 |
README.ja.md
File was created | 1 | <p align="center"> | |
2 | <img width="320" src="https://wpimg.wallstcn.com/ecc53a42-d79b-42e2-8852-5126b810a4c8.svg"> | ||
3 | </p> | ||
4 | |||
5 | <p align="center"> | ||
6 | <a href="https://github.com/vuejs/vue"> | ||
7 | <img src="https://img.shields.io/badge/vue-2.6.10-brightgreen.svg" alt="vue"> | ||
8 | </a> | ||
9 | <a href="https://github.com/ElemeFE/element"> | ||
10 | <img src="https://img.shields.io/badge/element--ui-2.7.0-brightgreen.svg" alt="element-ui"> | ||
11 | </a> | ||
12 | <a href="https://travis-ci.org/PanJiaChen/vue-element-admin" rel="nofollow"> | ||
13 | <img src="https://travis-ci.org/PanJiaChen/vue-element-admin.svg?branch=master" alt="Build Status"> | ||
14 | </a> | ||
15 | <a href="https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE"> | ||
16 | <img src="https://img.shields.io/github/license/mashape/apistatus.svg" alt="license"> | ||
17 | </a> | ||
18 | <a href="https://github.com/PanJiaChen/vue-element-admin/releases"> | ||
19 | <img src="https://img.shields.io/github/release/PanJiaChen/vue-element-admin.svg" alt="GitHub release"> | ||
20 | </a> | ||
21 | <a href="https://gitter.im/vue-element-admin/discuss"> | ||
22 | <img src="https://badges.gitter.im/Join%20Chat.svg" alt="gitter"> | ||
23 | </a> | ||
24 | <a href="https://panjiachen.gitee.io/vue-element-admin-site/zh/donate"> | ||
25 | <img src="https://img.shields.io/badge/%24-donate-ff69b4.svg" alt="donate"> | ||
26 | </a> | ||
27 | </p> | ||
28 | |||
29 | 日本語 | [English](./README.md) | [简体中文](./README.zh-CN.md) | [Spanish](./README.es.md) | ||
30 | |||
31 | ## 概要 | ||
32 | |||
33 | [vue-element-admin](https://panjiachen.github.io/vue-element-admin) は管理画面のフロントエンドのインタフェース,[vue](https://github.com/vuejs/vue) と [element-ui](https://github.com/ElemeFE/element)を使っています。i18nの多言語対応、可変ルート、権限、典型的なビジネスアプリテンプレートであり、豊富なコンポーネントを提供しています、素早くビジネス用の管理画面の現型を構築に役立ちます。 | ||
34 | |||
35 | - [デモページ](https://panjiachen.github.io/vue-element-admin) | ||
36 | |||
37 | - [ドキュメント](https://panjiachen.github.io/vue-element-admin-site/) | ||
38 | |||
39 | - [Gitter](https://gitter.im/vue-element-admin/discuss) | ||
40 | |||
41 | - [Donate](https://panjiachen.gitee.io/vue-element-admin-site/zh/donate) | ||
42 | |||
43 | - [Wiki](https://github.com/PanJiaChen/vue-element-admin/wiki) | ||
44 | |||
45 | - おすすめシンプルテンプレート: [vue-admin-template](https://github.com/PanJiaChen/vue-admin-template) | ||
46 | - デスクトップバージョン: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin) | ||
47 | - Typescriptバージョン: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (鸣谢: [@Armour](https://github.com/Armour)) | ||
48 | - [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312) | ||
49 | |||
50 | **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** | ||
51 | |||
52 | **現在のバージョン `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`に依存しないです。** | ||
53 | |||
54 | **低いバージョンのブラウザはサーポートしないです(例えば ie),必要があれば polyfill を追加してください。 [詳細はこちら](https://github.com/PanJiaChen/vue-element-admin/wiki#babel-polyfill)** | ||
55 | |||
56 | ## 前準備 | ||
57 | |||
58 | ローカル環境に [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)のモックデータを使っています。 | ||
59 | |||
60 | **バグ修正や新規機能追加のissue と pull requestは大歓迎です。** | ||
61 | |||
62 | <p align="center"> | ||
63 | <img width="900" src="https://wpimg.wallstcn.com/a5894c1b-f6af-456e-82df-1151da0839bf.png"> | ||
64 | </p> | ||
65 | |||
66 | ## Sponsors | ||
67 | |||
68 | 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) | ||
69 | |||
70 | <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> | ||
71 | |||
72 | ## 機能一覧 | ||
73 | |||
74 | ``` | ||
75 | - ログイン / ログアウト | ||
76 | |||
77 | - Auth認証 | ||
78 | - ページ権限 | ||
79 | - 権限パーミッション | ||
80 | - 権限設定 | ||
81 | - 外部IDでログイン | ||
82 | |||
83 | - 複数環境デプロイ | ||
84 | - dev sit stage prod | ||
85 | |||
86 | - 共通機能 | ||
87 | - 多言語切替 | ||
88 | - テーマ切替 | ||
89 | - サイトメニュー(ルートから生成) | ||
90 | - Breadcrumb Navigation | ||
91 | - Tag Navigation | ||
92 | - Svg Sprite Icon | ||
93 | - ローカル/バックエンド モック データ | ||
94 | - Screenfull | ||
95 | |||
96 | - WYSIWYG | ||
97 | - TinyMCE | ||
98 | - Markdown | ||
99 | - JSON | ||
100 | |||
101 | - Excel | ||
102 | - エクスポート | ||
103 | - インポート | ||
104 | - リード | ||
105 | - Zip | ||
106 | |||
107 | - Table | ||
108 | - Dynamic Table | ||
109 | - Drag And Drop Table | ||
110 | - Inline Edit Table | ||
111 | |||
112 | - Error Page | ||
113 | - 401 | ||
114 | - 404 | ||
115 | |||
116 | - コンポーネント | ||
117 | - Avatar Upload | ||
118 | - Back To Top | ||
119 | - Drag Dialog | ||
120 | - Drag Select | ||
121 | - Drag Kanban | ||
122 | - Drag List | ||
123 | - SplitPane | ||
124 | - Dropzone | ||
125 | - Sticky | ||
126 | - CountTo | ||
127 | |||
128 | - Advanced Example | ||
129 | - Error Log | ||
130 | - Dashboard | ||
131 | - Guide Page | ||
132 | - ECharts | ||
133 | - Clipboard | ||
134 | - Markdown to html | ||
135 | ``` | ||
136 | |||
137 | ## Getting started | ||
138 | |||
139 | ```bash | ||
140 | # clone the project | ||
141 | git clone -b i18n git@github.com:PanJiaChen/vue-element-admin.git | ||
142 | |||
143 | # enter the project directory | ||
144 | cd vue-element-admin | ||
145 | |||
146 | # install dependency | ||
147 | npm install | ||
148 | |||
149 | # develop | ||
150 | npm run dev | ||
151 | ``` | ||
152 | |||
153 | This will automatically open http://localhost:9527 | ||
154 | |||
155 | ## Build | ||
156 | |||
157 | ```bash | ||
158 | # build for test environment | ||
159 | npm run build:stage | ||
160 | |||
161 | # build for production environment | ||
162 | npm run build:prod | ||
163 | ``` | ||
164 | |||
165 | ## Advanced | ||
166 | |||
167 | ```bash | ||
168 | # preview the release environment effect | ||
169 | npm run preview | ||
170 | |||
171 | # preview the release environment effect + static resource analysis | ||
172 | npm run preview -- --report | ||
173 | |||
174 | # code format check | ||
175 | npm run lint | ||
176 | |||
177 | # code format check and auto fix | ||
178 | npm run lint -- --fix | ||
179 | ``` | ||
180 | |||
181 | Refer to [Documentation](https://panjiachen.github.io/vue-element-admin-site/guide/essentials/deploy.html) for more information | ||
182 | |||
183 | ## Changelog | ||
184 | |||
185 | Detailed changes for each release are documented in the [release notes](https://github.com/PanJiaChen/vue-element-admin/releases). | ||
186 | |||
187 | ## Online Demo | ||
188 | |||
189 | [Preview](https://panjiachen.github.io/vue-element-admin) | ||
190 | |||
191 | ## Donate | ||
192 | |||
193 | If you find this project useful, you can buy author a glass of juice :tropical_drink: | ||
194 | |||
195 |  | ||
196 | |||
197 | [Paypal Me](https://www.paypal.me/panfree23) | ||
198 | |||
199 | [Buy me a coffee](https://www.buymeacoffee.com/Pan) | ||
200 | |||
201 | ## Browsers support | ||
202 | |||
203 | Modern browsers and Internet Explorer 10+. | ||
204 | |||
205 | | [<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 | | ||
206 | | --------- | --------- | --------- | --------- | | ||
207 | | IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions | ||
208 | |||
209 | ## License | ||
210 | |||
211 | [MIT](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE) | ||
212 | |||
213 | Copyright (c) 2017-present PanJiaChen | ||
214 |
README.md
1 | <p align="center"> | ||
2 | <img width="320" src="https://wpimg.wallstcn.com/ecc53a42-d79b-42e2-8852-5126b810a4c8.svg"> | ||
3 | </p> | ||
1 | 4 | ||
5 | <p align="center"> | ||
6 | <a href="https://github.com/vuejs/vue"> | ||
7 | <img src="https://img.shields.io/badge/vue-2.6.10-brightgreen.svg" alt="vue"> | ||
8 | </a> | ||
9 | <a href="https://github.com/ElemeFE/element"> | ||
10 | <img src="https://img.shields.io/badge/element--ui-2.7.0-brightgreen.svg" alt="element-ui"> | ||
11 | </a> | ||
12 | <a href="https://travis-ci.org/PanJiaChen/vue-element-admin" rel="nofollow"> | ||
13 | <img src="https://travis-ci.org/PanJiaChen/vue-element-admin.svg?branch=master" alt="Build Status"> | ||
14 | </a> | ||
15 | <a href="https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE"> | ||
16 | <img src="https://img.shields.io/github/license/mashape/apistatus.svg" alt="license"> | ||
17 | </a> | ||
18 | <a href="https://github.com/PanJiaChen/vue-element-admin/releases"> | ||
19 | <img src="https://img.shields.io/github/release/PanJiaChen/vue-element-admin.svg" alt="GitHub release"> | ||
20 | </a> | ||
21 | <a href="https://gitter.im/vue-element-admin/discuss"> | ||
22 | <img src="https://badges.gitter.im/Join%20Chat.svg" alt="gitter"> | ||
23 | </a> | ||
24 | <a href="https://panjiachen.github.io/vue-element-admin-site/donate"> | ||
25 | <img src="https://img.shields.io/badge/%24-donate-ff69b4.svg" alt="donate"> | ||
26 | </a> | ||
27 | </p> | ||
2 | 28 | ||
3 | ## Build Setup | 29 | English | [简体中文](./README.zh-CN.md) | [日本語](./README.ja.md) | [Spanish](./README.es.md) |
4 | 30 | ||
31 | ## Introduction | ||
32 | |||
33 | [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). | ||
34 | |||
35 | [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. | ||
36 | |||
37 | - [Preview](https://panjiachen.github.io/vue-element-admin) | ||
38 | |||
39 | - [Documentation](https://panjiachen.github.io/vue-element-admin-site/) | ||
40 | |||
41 | - [Gitter](https://gitter.im/vue-element-admin/discuss) | ||
42 | |||
43 | - [Donate](https://panjiachen.github.io/vue-element-admin-site/donate/) | ||
44 | |||
45 | - [Wiki](https://github.com/PanJiaChen/vue-element-admin/wiki) | ||
46 | |||
47 | - [Gitee](https://panjiachen.gitee.io/vue-element-admin/) 国内用户可访问该地址在线预览 | ||
48 | |||
49 | - Base template recommends using: [vue-admin-template](https://github.com/PanJiaChen/vue-admin-template) | ||
50 | - Desktop: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin) | ||
51 | - Typescript: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (Credits: [@Armour](https://github.com/Armour)) | ||
52 | - [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312) | ||
53 | |||
54 | **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** | ||
55 | |||
56 | **The current version is `v4.0+` build on `vue-cli`. If you find a problem, please put [issue](https://github.com/PanJiaChen/vue-element-admin/issues/new). If you want to use the old version , you can switch branch to [tag/3.11.0](https://github.com/PanJiaChen/vue-element-admin/tree/tag/3.11.0), it does not rely on `vue-cli`** | ||
57 | |||
58 | **This project does not support low version browsers (e.g. IE). Please add polyfill by yourself.** | ||
59 | |||
60 | ## Preparation | ||
61 | |||
62 | 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). | ||
63 | Understanding and learning this knowledge in advance will greatly help the use of this project. | ||
64 | |||
65 | <p align="center"> | ||
66 | <img width="900" src="https://wpimg.wallstcn.com/a5894c1b-f6af-456e-82df-1151da0839bf.png"> | ||
67 | </p> | ||
68 | |||
69 | ## Sponsors | ||
70 | |||
71 | 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) | ||
72 | |||
73 | <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> | ||
74 | |||
75 | ## Features | ||
76 | |||
77 | ``` | ||
78 | - Login / Logout | ||
79 | |||
80 | - Permission Authentication | ||
81 | - Page permission | ||
82 | - Directive permission | ||
83 | - Permission configuration page | ||
84 | - Two-step login | ||
85 | |||
86 | - Multi-environment build | ||
87 | - dev sit stage prod | ||
88 | |||
89 | - Global Features | ||
90 | - I18n | ||
91 | - Multiple dynamic themes | ||
92 | - Dynamic sidebar (supports multi-level routing) | ||
93 | - Dynamic breadcrumb | ||
94 | - Tags-view (Tab page Support right-click operation) | ||
95 | - Svg Sprite | ||
96 | - Mock data | ||
97 | - Screenfull | ||
98 | - Responsive Sidebar | ||
99 | |||
100 | - Editor | ||
101 | - Rich Text Editor | ||
102 | - Markdown Editor | ||
103 | - JSON Editor | ||
104 | |||
105 | - Excel | ||
106 | - Export Excel | ||
107 | - Upload Excel | ||
108 | - Visualization Excel | ||
109 | - Export zip | ||
110 | |||
111 | - Table | ||
112 | - Dynamic Table | ||
113 | - Drag And Drop Table | ||
114 | - Inline Edit Table | ||
115 | |||
116 | - Error Page | ||
117 | - 401 | ||
118 | - 404 | ||
119 | |||
120 | - Components | ||
121 | - Avatar Upload | ||
122 | - Back To Top | ||
123 | - Drag Dialog | ||
124 | - Drag Select | ||
125 | - Drag Kanban | ||
126 | - Drag List | ||
127 | - SplitPane | ||
128 | - Dropzone | ||
129 | - Sticky | ||
130 | - CountTo | ||
131 | |||
132 | - Advanced Example | ||
133 | - Error Log | ||
134 | - Dashboard | ||
135 | - Guide Page | ||
136 | - ECharts | ||
137 | - Clipboard | ||
138 | - Markdown to html | ||
139 | ``` | ||
140 | |||
141 | ## Getting started | ||
5 | 142 | ||
6 | ```bash | 143 | ```bash |
144 | # clone the project | ||
145 | git clone -b i18n git@github.com:PanJiaChen/vue-element-admin.git | ||
7 | 146 | ||
8 | # enter the project directory | 147 | # enter the project directory |
9 | cd gulu-admin | 148 | cd vue-element-admin |
10 | 149 | ||
11 | # install dependency | 150 | # install dependency |
12 | npm install | 151 | npm install |
13 | 152 | ||
14 | # develop | 153 | # develop |
15 | npm run dev | 154 | npm run dev |
16 | ``` | 155 | ``` |
17 | 156 | ||
18 | This will automatically open http://localhost:9528 | 157 | This will automatically open http://localhost:9527 |
19 | 158 | ||
20 | ## Build | 159 | ## Build |
21 | 160 | ||
22 | ```bash | 161 | ```bash |
23 | # build for test environment | 162 | # build for test environment |
24 | npm run build:stage | 163 | npm run build:stage |
25 | 164 | ||
26 | # build for production environment | 165 | # build for production environment |
27 | npm run build:prod | 166 | npm run build:prod |
28 | ``` | 167 | ``` |
29 | 168 | ||
30 | ## Advanced | 169 | ## Advanced |
31 | 170 | ||
32 | ```bash | 171 | ```bash |
33 | # preview the release environment effect | 172 | # preview the release environment effect |
34 | npm run preview | 173 | npm run preview |
35 | 174 | ||
36 | # preview the release environment effect + static resource analysis | 175 | # preview the release environment effect + static resource analysis |
37 | npm run preview -- --report | 176 | npm run preview -- --report |
38 | 177 | ||
39 | # code format check | 178 | # code format check |
40 | npm run lint | 179 | npm run lint |
41 | 180 | ||
42 | # code format check and auto fix | 181 | # code format check and auto fix |
43 | npm run lint -- --fix | 182 | npm run lint -- --fix |
44 | ``` | 183 | ``` |
45 | 184 | ||
46 | Refer to [Documentation](https://panjiachen.github.io/vue-element-admin-site/guide/essentials/deploy.html) for more information | 185 | Refer to [Documentation](https://panjiachen.github.io/vue-element-admin-site/guide/essentials/deploy.html) for more information |
47 | 186 | ||
48 | ## Demo | 187 | ## Changelog |
49 | 188 | ||
50 |  | 189 | Detailed changes for each release are documented in the [release notes](https://github.com/PanJiaChen/vue-element-admin/releases). |
51 | 190 | ||
52 | ## Extra | 191 | ## Online Demo |
53 | 192 | ||
54 | If you want router permission && generate menu by user roles , you can use this branch [permission-control](https://github.com/PanJiaChen/vue-admin-template/tree/permission-control) | 193 | [Preview](https://panjiachen.github.io/vue-element-admin) |
55 | 194 | ||
56 | For `typescript` version, you can use [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (Credits: [@Armour](https://github.com/Armour)) | 195 | ## Donate |
57 | 196 | ||
58 | ## Related Project | 197 | If you find this project useful, you can buy author a glass of juice :tropical_drink: |
59 | 198 | ||
60 | - [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin) | 199 |  |
61 | 200 | ||
62 | - [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin) | 201 | [Paypal Me](https://www.paypal.me/panfree23) |
63 | 202 | ||
64 | - [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) | 203 | [Buy me a coffee](https://www.buymeacoffee.com/Pan) |
65 | 204 | ||
66 | - [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312) | 205 | ## Browsers support |
206 | |||
207 | Modern browsers and Internet Explorer 10+. | ||
208 | |||
209 | | [<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 | | ||
210 | | --------- | --------- | --------- | --------- | | ||
211 | | IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions | ||
212 | |||
213 | ## License | ||
67 | 214 | ||
215 | [MIT](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE) | ||
68 | 216 | ||
217 | Copyright (c) 2017-present PanJiaChen | ||
69 | 218 |
README.zh-CN.md
File was created | 1 | <p align="center"> | |
2 | <img width="320" src="https://wpimg.wallstcn.com/ecc53a42-d79b-42e2-8852-5126b810a4c8.svg"> | ||
3 | </p> | ||
4 | |||
5 | <p align="center"> | ||
6 | <a href="https://github.com/vuejs/vue"> | ||
7 | <img src="https://img.shields.io/badge/vue-2.6.10-brightgreen.svg" alt="vue"> | ||
8 | </a> | ||
9 | <a href="https://github.com/ElemeFE/element"> | ||
10 | <img src="https://img.shields.io/badge/element--ui-2.7.0-brightgreen.svg" alt="element-ui"> | ||
11 | </a> | ||
12 | <a href="https://travis-ci.org/PanJiaChen/vue-element-admin" rel="nofollow"> | ||
13 | <img src="https://travis-ci.org/PanJiaChen/vue-element-admin.svg?branch=master" alt="Build Status"> | ||
14 | </a> | ||
15 | <a href="https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE"> | ||
16 | <img src="https://img.shields.io/github/license/mashape/apistatus.svg" alt="license"> | ||
17 | </a> | ||
18 | <a href="https://github.com/PanJiaChen/vue-element-admin/releases"> | ||
19 | <img src="https://img.shields.io/github/release/PanJiaChen/vue-element-admin.svg" alt="GitHub release"> | ||
20 | </a> | ||
21 | <a href="https://gitter.im/vue-element-admin/discuss"> | ||
22 | <img src="https://badges.gitter.im/Join%20Chat.svg" alt="gitter"> | ||
23 | </a> | ||
24 | <a href="https://panjiachen.gitee.io/vue-element-admin-site/zh/donate"> | ||
25 | <img src="https://img.shields.io/badge/%24-donate-ff69b4.svg" alt="donate"> | ||
26 | </a> | ||
27 | </p> | ||
28 | |||
29 | 简体中文 | [English](./README.md) | [日本語](./README.ja.md) | [Spanish](./README.es.md) | ||
30 | |||
31 | ## 简介 | ||
32 | |||
33 | [vue-element-admin](https://panjiachen.github.io/vue-element-admin) 是一个后台前端解决方案,它基于 [vue](https://github.com/vuejs/vue) 和 [element-ui](https://github.com/ElemeFE/element)实现。它使用了最新的前端技术栈,内置了 i18n 国际化解决方案,动态路由,权限验证,提炼了典型的业务模型,提供了丰富的功能组件,它可以帮助你快速搭建企业级中后台产品原型。相信不管你的需求是什么,本项目都能帮助到你。 | ||
34 | |||
35 | - [在线预览](https://panjiachen.github.io/vue-element-admin) | ||
36 | |||
37 | - [使用文档](https://panjiachen.github.io/vue-element-admin-site/zh/) | ||
38 | |||
39 | - [Gitter 讨论组](https://gitter.im/vue-element-admin/discuss) | ||
40 | |||
41 | - [Donate](https://panjiachen.gitee.io/vue-element-admin-site/zh/donate) | ||
42 | |||
43 | - [Wiki](https://github.com/PanJiaChen/vue-element-admin/wiki) | ||
44 | |||
45 | - [Gitee](https://panjiachen.gitee.io/vue-element-admin/) 在线预览(国内用户可访问该地址) | ||
46 | |||
47 | - [国内访问文档](https://panjiachen.gitee.io/vue-element-admin-site/zh/) 文档(方便没翻墙的用户查看) | ||
48 | |||
49 | - 基础模板建议使用: [vue-admin-template](https://github.com/PanJiaChen/vue-admin-template) | ||
50 | - 桌面端: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin) | ||
51 | - Typescript 版: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (鸣谢: [@Armour](https://github.com/Armour)) | ||
52 | - [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312) | ||
53 | |||
54 | **`v4.1.0+`版本之后默认 master 分支将不支持国际化,有需要的请使用[i18n](https://github.com/PanJiaChen/vue-element-admin/tree/i18n)分支,它会和 master 保持同步更新** | ||
55 | |||
56 | **该项目不支持低版本浏览器(如 ie),有需求请自行添加 polyfill [详情](https://github.com/PanJiaChen/vue-element-admin/wiki#babel-polyfill)** | ||
57 | |||
58 | **目前版本为 `v4.0+` 基于 `vue-cli` 进行构建,若发现问题,欢迎提[issue](https://github.com/PanJiaChen/vue-element-admin/issues/new)。若你想使用旧版本,可以切换分支到[tag/3.11.0](https://github.com/PanJiaChen/vue-element-admin/tree/tag/3.11.0),它不依赖 `vue-cli`** | ||
59 | |||
60 | 群主 **[圈子](https://jianshiapp.com/circles/1209)** 群主会经常分享一些技术相关的东西,或者加入 [qq 群](https://github.com/PanJiaChen/vue-element-admin/issues/602) 或者关注 [微博](https://weibo.com/u/3423485724?is_all=1) | ||
61 | |||
62 | ## 前序准备 | ||
63 | |||
64 | 你需要在本地安装 [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),所有的请求数据都使用[Mock.js](https://github.com/nuysoft/Mock)进行模拟,提前了解和学习这些知识会对使用本项目有很大的帮助。 | ||
65 | |||
66 | 同时配套了系列教程文章,如何从零构建后一个完整的后台项目,建议大家先看完这些文章再来实践本项目 | ||
67 | |||
68 | - [手摸手,带你用 vue 撸后台 系列一(基础篇)](https://juejin.im/post/59097cd7a22b9d0065fb61d2) | ||
69 | - [手摸手,带你用 vue 撸后台 系列二(登录权限篇)](https://juejin.im/post/591aa14f570c35006961acac) | ||
70 | - [手摸手,带你用 vue 撸后台 系列三 (实战篇)](https://juejin.im/post/593121aa0ce4630057f70d35) | ||
71 | - [手摸手,带你用 vue 撸后台 系列四(vueAdmin 一个极简的后台基础模板)](https://juejin.im/post/595b4d776fb9a06bbe7dba56) | ||
72 | - [手摸手,带你用vue撸后台 系列五(v4.0新版本)](https://juejin.im/post/5c92ff94f265da6128275a85) | ||
73 | - [手摸手,带你封装一个 vue component](https://segmentfault.com/a/1190000009090836) | ||
74 | - [手摸手,带你优雅的使用 icon](https://juejin.im/post/59bb864b5188257e7a427c09) | ||
75 | - [手摸手,带你用合理的姿势使用 webpack4(上)](https://juejin.im/post/5b56909a518825195f499806) | ||
76 | - [手摸手,带你用合理的姿势使用 webpack4(下)](https://juejin.im/post/5b5d6d6f6fb9a04fea58aabc) | ||
77 | |||
78 | **如有问题请先看上述使用文档和文章,若不能满足,欢迎 issue 和 pr** | ||
79 | |||
80 | <p align="center"> | ||
81 | <img width="900" src="https://wpimg.wallstcn.com/a5894c1b-f6af-456e-82df-1151da0839bf.png"> | ||
82 | </p> | ||
83 | |||
84 | ## Sponsors | ||
85 | |||
86 | 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) | ||
87 | |||
88 | <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> | ||
89 | |||
90 | ## 功能 | ||
91 | |||
92 | ``` | ||
93 | - 登录 / 注销 | ||
94 | |||
95 | - 权限验证 | ||
96 | - 页面权限 | ||
97 | - 指令权限 | ||
98 | - 权限配置 | ||
99 | - 二步登录 | ||
100 | |||
101 | - 多环境发布 | ||
102 | - dev sit stage prod | ||
103 | |||
104 | - 全局功能 | ||
105 | - 国际化多语言 | ||
106 | - 多种动态换肤 | ||
107 | - 动态侧边栏(支持多级路由嵌套) | ||
108 | - 动态面包屑 | ||
109 | - 快捷导航(标签页) | ||
110 | - Svg Sprite 图标 | ||
111 | - 本地/后端 mock 数据 | ||
112 | - Screenfull全屏 | ||
113 | - 自适应收缩侧边栏 | ||
114 | |||
115 | - 编辑器 | ||
116 | - 富文本 | ||
117 | - Markdown | ||
118 | - JSON 等多格式 | ||
119 | |||
120 | - Excel | ||
121 | - 导出excel | ||
122 | - 导入excel | ||
123 | - 前端可视化excel | ||
124 | - 导出zip | ||
125 | |||
126 | - 表格 | ||
127 | - 动态表格 | ||
128 | - 拖拽表格 | ||
129 | - 内联编辑 | ||
130 | |||
131 | - 错误页面 | ||
132 | - 401 | ||
133 | - 404 | ||
134 | |||
135 | - 組件 | ||
136 | - 头像上传 | ||
137 | - 返回顶部 | ||
138 | - 拖拽Dialog | ||
139 | - 拖拽Select | ||
140 | - 拖拽看板 | ||
141 | - 列表拖拽 | ||
142 | - SplitPane | ||
143 | - Dropzone | ||
144 | - Sticky | ||
145 | - CountTo | ||
146 | |||
147 | - 综合实例 | ||
148 | - 错误日志 | ||
149 | - Dashboard | ||
150 | - 引导页 | ||
151 | - ECharts 图表 | ||
152 | - Clipboard(剪贴复制) | ||
153 | - Markdown2html | ||
154 | ``` | ||
155 | |||
156 | ## 开发 | ||
157 | |||
158 | ```bash | ||
159 | # 克隆项目 | ||
160 | git clone -b i18n git@github.com:PanJiaChen/vue-element-admin.git | ||
161 | |||
162 | # 进入项目目录 | ||
163 | cd vue-element-admin | ||
164 | |||
165 | # 安装依赖 | ||
166 | npm install | ||
167 | |||
168 | # 建议不要直接使用 cnpm 安装依赖,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题 | ||
169 | npm install --registry=https://registry.npm.taobao.org | ||
170 | |||
171 | # 启动服务 | ||
172 | npm run dev | ||
173 | ``` | ||
174 | |||
175 | 浏览器访问 http://localhost:9527 | ||
176 | |||
177 | ## 发布 | ||
178 | |||
179 | ```bash | ||
180 | # 构建测试环境 | ||
181 | npm run build:stage | ||
182 | |||
183 | # 构建生产环境 | ||
184 | npm run build:prod | ||
185 | ``` | ||
186 | |||
187 | ## 其它 | ||
188 | |||
189 | ```bash | ||
190 | # 预览发布环境效果 | ||
191 | npm run preview | ||
192 | |||
193 | # 预览发布环境效果 + 静态资源分析 | ||
194 | npm run preview -- --report | ||
195 | |||
196 | # 代码格式检查 | ||
197 | npm run lint | ||
198 | |||
199 | # 代码格式检查并自动修复 | ||
200 | npm run lint -- --fix | ||
201 | ``` | ||
202 | |||
203 | 更多信息请参考 [使用文档](https://panjiachen.github.io/vue-element-admin-site/zh/) | ||
204 | |||
205 | ## Changelog | ||
206 | |||
207 | Detailed changes for each release are documented in the [release notes](https://github.com/PanJiaChen/vue-element-admin/releases). | ||
208 | |||
209 | ## Online Demo | ||
210 | |||
211 | [在线 Demo](https://panjiachen.github.io/vue-element-admin) | ||
212 | |||
213 | ## Donate | ||
214 | |||
215 | 如果你觉得这个项目帮助到了你,你可以帮作者买一杯果汁表示鼓励 :tropical_drink: | ||
216 |  | ||
217 | |||
218 | [更多捐赠方式](https://panjiachen.gitee.io/vue-element-admin-site/zh/donate) | ||
219 | |||
220 | [Paypal Me](https://www.paypal.me/panfree23) | ||
221 | |||
222 | [Buy me a coffee](https://www.buymeacoffee.com/Pan) | ||
223 | |||
224 | ## Browsers support | ||
225 | |||
226 | Modern browsers and Internet Explorer 10+. | ||
227 | |||
228 | | [<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 | | ||
229 | | --------- | --------- | --------- | --------- | | ||
230 | | IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions | ||
231 | |||
232 | ## License | ||
233 | |||
234 | [MIT](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE) | ||
235 | |||
236 | Copyright (c) 2017-present PanJiaChen | ||
237 |
babel.config.js
1 | // module.exports = { | ||
2 | // presets: [ | ||
3 | // '@vue/app' | ||
4 | // ] | ||
5 | // } | ||
6 | // "@babel/preset-env", | ||
7 | // { | ||
8 | // "modules": false | ||
9 | // }, | ||
10 | module.exports = { | 1 | module.exports = { |
11 | "presets": [ | 2 | presets: [ |
12 | [ | 3 | '@vue/app' |
13 | '@vue/app', | ||
14 | // '@babel/preset-env', | ||
15 | { | ||
16 | // "modules": false, | ||
17 | // "targets": { // 配置代码的运行环境 | ||
18 | // "chrome": 64 | ||
19 | // }, | ||
20 | // "useBuiltIns": true // 开启对 babel-polyfill 的优化 | ||
21 | } | ||
22 | ] | ||
23 | ], | ||
24 | "plugins": [ | ||
25 | [ | ||
26 | "component", | ||
27 | { | ||
28 | "libraryName": "element-ui", | ||
29 | "styleLibraryName": "theme-chalk" | ||
30 | } | ||
31 | ] | ||
32 | ] | 4 | ] |
33 | } | 5 | } |
34 | 6 |
1 | const { run } = require('runjs') | 1 | const { run } = require('runjs') |
2 | const chalk = require('chalk') | 2 | const chalk = require('chalk') |
3 | const config = require('../vue.config.js') | 3 | const config = require('../vue.config.js') |
4 | const rawArgv = process.argv.slice(2) | 4 | const rawArgv = process.argv.slice(2) |
5 | const args = rawArgv.join(' ') | 5 | const args = rawArgv.join(' ') |
6 | 6 | ||
7 | if (process.env.npm_config_preview || rawArgv.includes('--preview')) { | 7 | if (process.env.npm_config_preview || rawArgv.includes('--preview')) { |
8 | const report = rawArgv.includes('--report') | 8 | const report = rawArgv.includes('--report') |
9 | 9 | ||
10 | run(`vue-cli-service build ${args}`) | 10 | run(`vue-cli-service build ${args}`) |
11 | 11 | ||
12 | const port = 9526 | 12 | const port = 9526 |
13 | const publicPath = config.publicPath | 13 | const publicPath = config.publicPath |
14 | 14 | ||
15 | var connect = require('connect') | 15 | var connect = require('connect') |
16 | var serveStatic = require('serve-static') | 16 | var serveStatic = require('serve-static') |
17 | const app = connect() | 17 | const app = connect() |
18 | 18 | ||
19 | app.use( | 19 | app.use( |
20 | publicPath, | 20 | publicPath, |
21 | serveStatic('./dist', { | 21 | serveStatic('./dist', { |
22 | index: ['index.html', '/'] | 22 | index: ['index.html', '/'] |
23 | }) | 23 | }) |
24 | ) | 24 | ) |
25 | 25 | ||
26 | app.listen(port, function () { | 26 | app.listen(port, function () { |
27 | console.log(chalk.green(`> Preview at http://localhost:${port}${publicPath}`)) | 27 | console.log(chalk.green(`> Preview at http://localhost:${port}${publicPath}`)) |
28 | if (report) { | 28 | if (report) { |
29 | console.log(chalk.green(`> Report at http://localhost:${port}${publicPath}report.html`)) | 29 | console.log(chalk.green(`> Report at http://localhost:${port}${publicPath}report.html`)) |
30 | } | 30 | } |
31 | 31 | ||
32 | }) | 32 | }) |
33 | } else { | 33 | } else { |
34 | run(`vue-cli-service build ${args}`) | 34 | run(`vue-cli-service build ${args}`) |
35 | } | 35 | } |
36 | 36 |
1 | module.exports = { | 1 | module.exports = { |
2 | moduleFileExtensions: ['js', 'jsx', 'json', 'vue'], | 2 | moduleFileExtensions: ['js', 'jsx', 'json', 'vue'], |
3 | transform: { | 3 | transform: { |
4 | '^.+\\.vue$': 'vue-jest', | 4 | '^.+\\.vue$': 'vue-jest', |
5 | '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': | 5 | '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': |
6 | 'jest-transform-stub', | 6 | 'jest-transform-stub', |
7 | '^.+\\.jsx?$': 'babel-jest' | 7 | '^.+\\.jsx?$': 'babel-jest' |
8 | }, | 8 | }, |
9 | moduleNameMapper: { | 9 | moduleNameMapper: { |
10 | '^@/(.*)$': '<rootDir>/src/$1' | 10 | '^@/(.*)$': '<rootDir>/src/$1' |
11 | }, | 11 | }, |
12 | snapshotSerializers: ['jest-serializer-vue'], | 12 | snapshotSerializers: ['jest-serializer-vue'], |
13 | testMatch: [ | 13 | testMatch: [ |
14 | '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)' | 14 | '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)' |
15 | ], | 15 | ], |
16 | collectCoverageFrom: ['src/utils/**/*.{js,vue}', '!src/utils/auth.js', '!src/utils/request.js', 'src/components/**/*.{js,vue}'], | 16 | collectCoverageFrom: ['src/utils/**/*.{js,vue}', '!src/utils/auth.js', '!src/utils/request.js', 'src/components/**/*.{js,vue}'], |
17 | coverageDirectory: '<rootDir>/tests/unit/coverage', | 17 | coverageDirectory: '<rootDir>/tests/unit/coverage', |
18 | // 'collectCoverage': true, | 18 | // 'collectCoverage': true, |
19 | 'coverageReporters': [ | 19 | 'coverageReporters': [ |
20 | 'lcov', | 20 | 'lcov', |
21 | 'text-summary' | 21 | 'text-summary' |
22 | ], | 22 | ], |
23 | testURL: 'http://localhost/' | 23 | testURL: 'http://localhost/' |
24 | } | 24 | } |
25 | 25 |
jsconfig.json
1 | { | 1 | { |
2 | "compilerOptions": { | 2 | "compilerOptions": { |
3 | "baseUrl": "./", | 3 | "baseUrl": "./", |
4 | "paths": { | 4 | "paths": { |
5 | "@/*": ["src/*"] | 5 | "@/*": ["src/*"] |
6 | } | 6 | } |
7 | }, | 7 | }, |
8 | "exclude": ["node_modules", "dist"] | 8 | "exclude": ["node_modules", "dist"] |
9 | } | 9 | } |
10 |
mock/article.js
File was created | 1 | import Mock from 'mockjs' | |
2 | |||
3 | const List = [] | ||
4 | const count = 100 | ||
5 | |||
6 | const baseContent = '<p>I am testing data, I am testing data.</p><p><img src="https://wpimg.wallstcn.com/4c69009c-0fd4-4153-b112-6cb53d1cf943"></p>' | ||
7 | const image_uri = 'https://wpimg.wallstcn.com/e4558086-631c-425c-9430-56ffb46e70b3' | ||
8 | |||
9 | for (let i = 0; i < count; i++) { | ||
10 | List.push(Mock.mock({ | ||
11 | id: '@increment', | ||
12 | timestamp: +Mock.Random.date('T'), | ||
13 | author: '@first', | ||
14 | reviewer: '@first', | ||
15 | title: '@title(5, 10)', | ||
16 | content_short: 'mock data', | ||
17 | content: baseContent, | ||
18 | forecast: '@float(0, 100, 2, 2)', | ||
19 | importance: '@integer(1, 3)', | ||
20 | 'type|1': ['CN', 'US', 'JP', 'EU'], | ||
21 | 'status|1': ['published', 'draft'], | ||
22 | display_time: '@datetime', | ||
23 | comment_disabled: true, | ||
24 | pageviews: '@integer(300, 5000)', | ||
25 | image_uri, | ||
26 | platforms: ['a-platform'] | ||
27 | })) | ||
28 | } | ||
29 | |||
30 | export default [ | ||
31 | { | ||
32 | url: '/vue-element-admin/article/list', | ||
33 | type: 'get', | ||
34 | response: config => { | ||
35 | const { importance, type, title, page = 1, limit = 20, sort } = config.query | ||
36 | |||
37 | let mockList = List.filter(item => { | ||
38 | if (importance && item.importance !== +importance) return false | ||
39 | if (type && item.type !== type) return false | ||
40 | if (title && item.title.indexOf(title) < 0) return false | ||
41 | return true | ||
42 | }) | ||
43 | |||
44 | if (sort === '-id') { | ||
45 | mockList = mockList.reverse() | ||
46 | } | ||
47 | |||
48 | const pageList = mockList.filter((item, index) => index < limit * page && index >= limit * (page - 1)) | ||
49 | |||
50 | return { | ||
51 | code: 20000, | ||
52 | data: { | ||
53 | total: mockList.length, | ||
54 | items: pageList | ||
55 | } | ||
56 | } | ||
57 | } | ||
58 | }, | ||
59 | |||
60 | { | ||
61 | url: '/vue-element-admin/article/detail', | ||
62 | type: 'get', | ||
63 | response: config => { | ||
64 | const { id } = config.query | ||
65 | for (const article of List) { | ||
66 | if (article.id === +id) { | ||
67 | return { | ||
68 | code: 20000, | ||
69 | data: article | ||
70 | } | ||
71 | } | ||
72 | } | ||
73 | } | ||
74 | }, | ||
75 | |||
76 | { | ||
77 | url: '/vue-element-admin/article/pv', | ||
78 | type: 'get', | ||
79 | response: _ => { | ||
80 | return { | ||
81 | code: 20000, | ||
82 | data: { | ||
83 | pvData: [ | ||
84 | { key: 'PC', pv: 1024 }, | ||
85 | { key: 'mobile', pv: 1024 }, | ||
86 | { key: 'ios', pv: 1024 }, | ||
87 | { key: 'android', pv: 1024 } | ||
88 | ] | ||
89 | } | ||
90 | } | ||
91 | } | ||
92 | }, | ||
93 | |||
94 | { | ||
95 | url: '/vue-element-admin/article/create', | ||
96 | type: 'post', | ||
97 | response: _ => { | ||
98 | return { | ||
99 | code: 20000, | ||
100 | data: 'success' | ||
101 | } | ||
102 | } | ||
103 | }, | ||
104 | |||
105 | { | ||
106 | url: '/vue-element-admin/article/update', | ||
107 | type: 'post', | ||
108 | response: _ => { | ||
109 | return { | ||
110 | code: 20000, | ||
111 | data: 'success' | ||
112 | } | ||
113 | } | ||
114 | } | ||
115 | ] | ||
116 | |||
117 |
mock/index.js
1 | import Mock from 'mockjs' | 1 | import Mock from 'mockjs' |
2 | import { | 2 | import { param2Obj } from '../src/utils' |
3 | param2Obj | ||
4 | } from '../src/utils' | ||
5 | 3 | ||
6 | import user from './user' | 4 | import user from './user' |
7 | import table from './table' | 5 | import role from './role' |
6 | import article from './article' | ||
7 | import search from './remote-search' | ||
8 | 8 | ||
9 | const mocks = [ | 9 | const mocks = [ |
10 | ...user, | 10 | ...user, |
11 | ...table | 11 | ...role, |
12 | ...article, | ||
13 | ...search | ||
12 | ] | 14 | ] |
13 | 15 | ||
14 | // for front mock | 16 | // for front mock |
15 | // please use it cautiously, it will redefine XMLHttpRequest, | 17 | // please use it cautiously, it will redefine XMLHttpRequest, |
16 | // which will cause many of your third-party libraries to be invalidated(like progress event). | 18 | // which will cause many of your third-party libraries to be invalidated(like progress event). |
17 | export function mockXHR() { | 19 | export function mockXHR() { |
18 | // mock patch | 20 | // mock patch |
19 | // https://github.com/nuysoft/Mock/issues/300 | 21 | // https://github.com/nuysoft/Mock/issues/300 |
20 | Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send | 22 | Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send |
21 | Mock.XHR.prototype.send = function () { | 23 | Mock.XHR.prototype.send = function() { |
22 | if (this.custom.xhr) { | 24 | if (this.custom.xhr) { |
23 | this.custom.xhr.withCredentials = this.withCredentials || false | 25 | this.custom.xhr.withCredentials = this.withCredentials || false |
24 | 26 | ||
25 | if (this.responseType) { | 27 | if (this.responseType) { |
26 | this.custom.xhr.responseType = this.responseType | 28 | this.custom.xhr.responseType = this.responseType |
27 | } | 29 | } |
28 | } | 30 | } |
29 | this.proxy_send(...arguments) | 31 | this.proxy_send(...arguments) |
30 | } | 32 | } |
31 | 33 | ||
32 | function XHR2ExpressReqWrap(respond) { | 34 | function XHR2ExpressReqWrap(respond) { |
33 | return function (options) { | 35 | return function(options) { |
34 | let result = null | 36 | let result = null |
35 | if (respond instanceof Function) { | 37 | if (respond instanceof Function) { |
36 | const { | 38 | const { body, type, url } = options |
37 | body, | ||
38 | type, | ||
39 | url | ||
40 | } = options | ||
41 | // https://expressjs.com/en/4x/api.html#req | 39 | // https://expressjs.com/en/4x/api.html#req |
42 | result = respond({ | 40 | result = respond({ |
43 | method: type, | 41 | method: type, |
44 | body: JSON.parse(body), | 42 | body: JSON.parse(body), |
45 | query: param2Obj(url) | 43 | query: param2Obj(url) |
46 | }) | 44 | }) |
47 | } else { | 45 | } else { |
48 | result = respond | 46 | result = respond |
49 | } | 47 | } |
50 | return Mock.mock(result) | 48 | return Mock.mock(result) |
51 | } | 49 | } |
52 | } | 50 | } |
53 | 51 | ||
54 | for (const i of mocks) { | 52 | for (const i of mocks) { |
55 | Mock.mock(new RegExp(i.url), i.type || 'get', XHR2ExpressReqWrap(i.response)) | 53 | Mock.mock(new RegExp(i.url), i.type || 'get', XHR2ExpressReqWrap(i.response)) |
56 | } | 54 | } |
57 | } | 55 | } |
58 | 56 | ||
59 | // for mock server | 57 | // for mock server |
60 | const responseFake = (url, type, respond) => { | 58 | const responseFake = (url, type, respond) => { |
61 | return { | 59 | return { |
62 | url: new RegExp(`${process.env.VUE_APP_BASE_API}${url}`), | 60 | url: new RegExp(`${process.env.VUE_APP_BASE_API}${url}`), |
63 | type: type || 'get', | 61 | type: type || 'get', |
64 | response(req, res) { | 62 | response(req, res) { |
65 | console.log('request invoke:' + req.path) | 63 | console.log('request invoke:' + req.path) |
66 | res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond)) | 64 | res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond)) |
67 | } | 65 | } |
68 | } | 66 | } |
69 | } | 67 | } |
70 | 68 |
mock/mock-server.js
1 | const chokidar = require('chokidar') | 1 | const chokidar = require('chokidar') |
2 | const bodyParser = require('body-parser') | 2 | const bodyParser = require('body-parser') |
3 | const chalk = require('chalk') | 3 | const chalk = require('chalk') |
4 | const path = require('path') | 4 | const path = require('path') |
5 | 5 | ||
6 | const mockDir = path.join(process.cwd(), 'mock') | 6 | const mockDir = path.join(process.cwd(), 'mock') |
7 | 7 | ||
8 | function registerRoutes(app) { | 8 | function registerRoutes(app) { |
9 | let mockLastIndex | 9 | let mockLastIndex |
10 | const { default: mocks } = require('./index.js') | 10 | const { default: mocks } = require('./index.js') |
11 | for (const mock of mocks) { | 11 | for (const mock of mocks) { |
12 | app[mock.type](mock.url, mock.response) | 12 | app[mock.type](mock.url, mock.response) |
13 | mockLastIndex = app._router.stack.length | 13 | mockLastIndex = app._router.stack.length |
14 | } | 14 | } |
15 | const mockRoutesLength = Object.keys(mocks).length | 15 | const mockRoutesLength = Object.keys(mocks).length |
16 | return { | 16 | return { |
17 | mockRoutesLength: mockRoutesLength, | 17 | mockRoutesLength: mockRoutesLength, |
18 | mockStartIndex: mockLastIndex - mockRoutesLength | 18 | mockStartIndex: mockLastIndex - mockRoutesLength |
19 | } | 19 | } |
20 | } | 20 | } |
21 | 21 | ||
22 | function unregisterRoutes() { | 22 | function unregisterRoutes() { |
23 | Object.keys(require.cache).forEach(i => { | 23 | Object.keys(require.cache).forEach(i => { |
24 | if (i.includes(mockDir)) { | 24 | if (i.includes(mockDir)) { |
25 | delete require.cache[require.resolve(i)] | 25 | delete require.cache[require.resolve(i)] |
26 | } | 26 | } |
27 | }) | 27 | }) |
28 | } | 28 | } |
29 | 29 | ||
30 | module.exports = app => { | 30 | module.exports = app => { |
31 | // es6 polyfill | 31 | // es6 polyfill |
32 | require('@babel/register') | 32 | require('@babel/register') |
33 | 33 | ||
34 | // parse app.body | 34 | // parse app.body |
35 | // https://expressjs.com/en/4x/api.html#req.body | 35 | // https://expressjs.com/en/4x/api.html#req.body |
36 | app.use(bodyParser.json()) | 36 | app.use(bodyParser.json()) |
37 | app.use(bodyParser.urlencoded({ | 37 | app.use(bodyParser.urlencoded({ |
38 | extended: true | 38 | extended: true |
39 | })) | 39 | })) |
40 | 40 | ||
41 | const mockRoutes = registerRoutes(app) | 41 | const mockRoutes = registerRoutes(app) |
42 | var mockRoutesLength = mockRoutes.mockRoutesLength | 42 | var mockRoutesLength = mockRoutes.mockRoutesLength |
43 | var mockStartIndex = mockRoutes.mockStartIndex | 43 | var mockStartIndex = mockRoutes.mockStartIndex |
44 | 44 | ||
45 | // watch files, hot reload mock server | 45 | // watch files, hot reload mock server |
46 | chokidar.watch(mockDir, { | 46 | chokidar.watch(mockDir, { |
47 | ignored: /mock-server/, | 47 | ignored: /mock-server/, |
48 | ignoreInitial: true | 48 | ignoreInitial: true |
49 | }).on('all', (event, path) => { | 49 | }).on('all', (event, path) => { |
50 | if (event === 'change' || event === 'add') { | 50 | if (event === 'change' || event === 'add') { |
51 | try { | 51 | try { |
52 | // remove mock routes stack | 52 | // remove mock routes stack |
53 | app._router.stack.splice(mockStartIndex, mockRoutesLength) | 53 | app._router.stack.splice(mockStartIndex, mockRoutesLength) |
54 | 54 | ||
55 | // clear routes cache | 55 | // clear routes cache |
56 | unregisterRoutes() | 56 | unregisterRoutes() |
57 | 57 | ||
58 | const mockRoutes = registerRoutes(app) | 58 | const mockRoutes = registerRoutes(app) |
59 | mockRoutesLength = mockRoutes.mockRoutesLength | 59 | mockRoutesLength = mockRoutes.mockRoutesLength |
60 | mockStartIndex = mockRoutes.mockStartIndex | 60 | mockStartIndex = mockRoutes.mockStartIndex |
61 | 61 | ||
62 | console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed ${path}`)) | 62 | console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed ${path}`)) |
63 | } catch (error) { | 63 | } catch (error) { |
64 | console.error(chalk.redBright(error)) | 64 | console.log(chalk.redBright(error)) |
65 | } | 65 | } |
66 | } | 66 | } |
67 | }) | 67 | }) |
68 | } | 68 | } |
69 | 69 |
mock/remote-search.js
File was created | 1 | import Mock from 'mockjs' | |
2 | |||
3 | const NameList = [] | ||
4 | const count = 100 | ||
5 | |||
6 | for (let i = 0; i < count; i++) { | ||
7 | NameList.push(Mock.mock({ | ||
8 | name: '@first' | ||
9 | })) | ||
10 | } | ||
11 | NameList.push({ name: 'mock-Pan' }) | ||
12 | |||
13 | export default [ | ||
14 | // username search | ||
15 | { | ||
16 | url: '/vue-element-admin/search/user', | ||
17 | type: 'get', | ||
18 | response: config => { | ||
19 | const { name } = config.query | ||
20 | const mockNameList = NameList.filter(item => { | ||
21 | const lowerCaseName = item.name.toLowerCase() | ||
22 | return !(name && lowerCaseName.indexOf(name.toLowerCase()) < 0) | ||
23 | }) | ||
24 | return { | ||
25 | code: 20000, | ||
26 | data: { items: mockNameList } | ||
27 | } | ||
28 | } | ||
29 | }, | ||
30 | |||
31 | // transaction list | ||
32 | { | ||
33 | url: '/vue-element-admin/transaction/list', | ||
34 | type: 'get', | ||
35 | response: _ => { | ||
36 | return { | ||
37 | code: 20000, | ||
38 | data: { | ||
39 | total: 20, | ||
40 | 'items|20': [{ | ||
41 | order_no: '@guid()', | ||
42 | timestamp: +Mock.Random.date('T'), | ||
43 | username: '@name()', | ||
44 | price: '@float(1000, 15000, 0, 2)', | ||
45 | 'status|1': ['success', 'pending'] | ||
46 | }] | ||
47 | } | ||
48 | } | ||
49 | } | ||
50 | } | ||
51 | ] | ||
52 |
mock/role/index.js
File was created | 1 | import Mock from 'mockjs' | |
2 | import { deepClone } from '../../src/utils/index.js' | ||
3 | import { asyncRoutes, constantRoutes } from './routes.js' | ||
4 | |||
5 | const routes = deepClone([...constantRoutes, ...asyncRoutes]) | ||
6 | |||
7 | const roles = [ | ||
8 | { | ||
9 | key: 'admin', | ||
10 | name: 'admin', | ||
11 | description: 'Super Administrator. Have access to view all pages.', | ||
12 | routes: routes | ||
13 | }, | ||
14 | { | ||
15 | key: 'editor', | ||
16 | name: 'editor', | ||
17 | description: 'Normal Editor. Can see all pages except permission page', | ||
18 | routes: routes.filter(i => i.path !== '/permission')// just a mock | ||
19 | }, | ||
20 | { | ||
21 | key: 'visitor', | ||
22 | name: 'visitor', | ||
23 | description: 'Just a visitor. Can only see the home page and the document page', | ||
24 | routes: [{ | ||
25 | path: '', | ||
26 | redirect: 'dashboard', | ||
27 | children: [ | ||
28 | { | ||
29 | path: 'dashboard', | ||
30 | name: 'Dashboard', | ||
31 | meta: { title: 'dashboard', icon: 'dashboard' } | ||
32 | } | ||
33 | ] | ||
34 | }] | ||
35 | } | ||
36 | ] | ||
37 | |||
38 | export default [ | ||
39 | // mock get all routes form server | ||
40 | { | ||
41 | url: '/vue-element-admin/routes', | ||
42 | type: 'get', | ||
43 | response: _ => { | ||
44 | return { | ||
45 | code: 20000, | ||
46 | data: routes | ||
47 | } | ||
48 | } | ||
49 | }, | ||
50 | |||
51 | // mock get all roles form server | ||
52 | { | ||
53 | url: '/vue-element-admin/roles', | ||
54 | type: 'get', | ||
55 | response: _ => { | ||
56 | return { | ||
57 | code: 20000, | ||
58 | data: roles | ||
59 | } | ||
60 | } | ||
61 | }, | ||
62 | |||
63 | // add role | ||
64 | { | ||
65 | url: '/vue-element-admin/role', | ||
66 | type: 'post', | ||
67 | response: { | ||
68 | code: 20000, | ||
69 | data: { | ||
70 | key: Mock.mock('@integer(300, 5000)') | ||
71 | } | ||
72 | } | ||
73 | }, | ||
74 | |||
75 | // update role | ||
76 | { | ||
77 | url: '/vue-element-admin/role/[A-Za-z0-9]', | ||
78 | type: 'put', | ||
79 | response: { | ||
80 | code: 20000, | ||
81 | data: { | ||
82 | status: 'success' | ||
83 | } | ||
84 | } | ||
85 | }, | ||
86 | |||
87 | // delete role | ||
88 | { | ||
89 | url: '/vue-element-admin/role/[A-Za-z0-9]', | ||
90 | type: 'delete', | ||
91 | response: { | ||
92 | code: 20000, | ||
93 | data: { | ||
94 | status: 'success' | ||
95 | } | ||
96 | } | ||
97 | } | ||
98 | ] | ||
99 |
mock/role/routes.js
File was created | 1 | // Just a mock data | |
2 | |||
3 | export const constantRoutes = [ | ||
4 | { | ||
5 | path: '/redirect', | ||
6 | component: 'layout/Layout', | ||
7 | hidden: true, | ||
8 | children: [ | ||
9 | { | ||
10 | path: '/redirect/:path*', | ||
11 | component: 'views/redirect/index' | ||
12 | } | ||
13 | ] | ||
14 | }, | ||
15 | { | ||
16 | path: '/login', | ||
17 | component: 'views/login/index', | ||
18 | hidden: true | ||
19 | }, | ||
20 | { | ||
21 | path: '/auth-redirect', | ||
22 | component: 'views/login/auth-redirect', | ||
23 | hidden: true | ||
24 | }, | ||
25 | { | ||
26 | path: '/404', | ||
27 | component: 'views/error-page/404', | ||
28 | hidden: true | ||
29 | }, | ||
30 | { | ||
31 | path: '/401', | ||
32 | component: 'views/error-page/401', | ||
33 | hidden: true | ||
34 | }, | ||
35 | { | ||
36 | path: '', | ||
37 | component: 'layout/Layout', | ||
38 | redirect: 'dashboard', | ||
39 | children: [ | ||
40 | { | ||
41 | path: 'dashboard', | ||
42 | component: 'views/dashboard/index', | ||
43 | name: 'Dashboard', | ||
44 | meta: { title: 'dashboard', icon: 'dashboard', affix: true } | ||
45 | } | ||
46 | ] | ||
47 | }, | ||
48 | { | ||
49 | path: '/documentation', | ||
50 | component: 'layout/Layout', | ||
51 | children: [ | ||
52 | { | ||
53 | path: 'index', | ||
54 | component: 'views/documentation/index', | ||
55 | name: 'Documentation', | ||
56 | meta: { title: 'documentation', icon: 'documentation', affix: true } | ||
57 | } | ||
58 | ] | ||
59 | }, | ||
60 | { | ||
61 | path: '/guide', | ||
62 | component: 'layout/Layout', | ||
63 | redirect: '/guide/index', | ||
64 | children: [ | ||
65 | { | ||
66 | path: 'index', | ||
67 | component: 'views/guide/index', | ||
68 | name: 'Guide', | ||
69 | meta: { title: 'guide', icon: 'guide', noCache: true } | ||
70 | } | ||
71 | ] | ||
72 | } | ||
73 | ] | ||
74 | |||
75 | export const asyncRoutes = [ | ||
76 | { | ||
77 | path: '/permission', | ||
78 | component: 'layout/Layout', | ||
79 | redirect: '/permission/index', | ||
80 | alwaysShow: true, | ||
81 | meta: { | ||
82 | title: 'permission', | ||
83 | icon: 'lock', | ||
84 | roles: ['admin', 'editor'] | ||
85 | }, | ||
86 | children: [ | ||
87 | { | ||
88 | path: 'page', | ||
89 | component: 'views/permission/page', | ||
90 | name: 'PagePermission', | ||
91 | meta: { | ||
92 | title: 'pagePermission', | ||
93 | roles: ['admin'] | ||
94 | } | ||
95 | }, | ||
96 | { | ||
97 | path: 'directive', | ||
98 | component: 'views/permission/directive', | ||
99 | name: 'DirectivePermission', | ||
100 | meta: { | ||
101 | title: 'directivePermission' | ||
102 | } | ||
103 | }, | ||
104 | { | ||
105 | path: 'role', | ||
106 | component: 'views/permission/role', | ||
107 | name: 'RolePermission', | ||
108 | meta: { | ||
109 | title: 'rolePermission', | ||
110 | roles: ['admin'] | ||
111 | } | ||
112 | } | ||
113 | ] | ||
114 | }, | ||
115 | |||
116 | { | ||
117 | path: '/icon', | ||
118 | component: 'layout/Layout', | ||
119 | children: [ | ||
120 | { | ||
121 | path: 'index', | ||
122 | component: 'views/icons/index', | ||
123 | name: 'Icons', | ||
124 | meta: { title: 'icons', icon: 'icon', noCache: true } | ||
125 | } | ||
126 | ] | ||
127 | }, | ||
128 | |||
129 | { | ||
130 | path: '/components', | ||
131 | component: 'layout/Layout', | ||
132 | redirect: 'noRedirect', | ||
133 | name: 'ComponentDemo', | ||
134 | meta: { | ||
135 | title: 'components', | ||
136 | icon: 'component' | ||
137 | }, | ||
138 | children: [ | ||
139 | { | ||
140 | path: 'tinymce', | ||
141 | component: 'views/components-demo/tinymce', | ||
142 | name: 'TinymceDemo', | ||
143 | meta: { title: 'tinymce' } | ||
144 | }, | ||
145 | { | ||
146 | path: 'markdown', | ||
147 | component: 'views/components-demo/markdown', | ||
148 | name: 'MarkdownDemo', | ||
149 | meta: { title: 'markdown' } | ||
150 | }, | ||
151 | { | ||
152 | path: 'json-editor', | ||
153 | component: 'views/components-demo/json-editor', | ||
154 | name: 'JsonEditorDemo', | ||
155 | meta: { title: 'jsonEditor' } | ||
156 | }, | ||
157 | { | ||
158 | path: 'split-pane', | ||
159 | component: 'views/components-demo/split-pane', | ||
160 | name: 'SplitpaneDemo', | ||
161 | meta: { title: 'splitPane' } | ||
162 | }, | ||
163 | { | ||
164 | path: 'avatar-upload', | ||
165 | component: 'views/components-demo/avatar-upload', | ||
166 | name: 'AvatarUploadDemo', | ||
167 | meta: { title: 'avatarUpload' } | ||
168 | }, | ||
169 | { | ||
170 | path: 'dropzone', | ||
171 | component: 'views/components-demo/dropzone', | ||
172 | name: 'DropzoneDemo', | ||
173 | meta: { title: 'dropzone' } | ||
174 | }, | ||
175 | { | ||
176 | path: 'sticky', | ||
177 | component: 'views/components-demo/sticky', | ||
178 | name: 'StickyDemo', | ||
179 | meta: { title: 'sticky' } | ||
180 | }, | ||
181 | { | ||
182 | path: 'count-to', | ||
183 | component: 'views/components-demo/count-to', | ||
184 | name: 'CountToDemo', | ||
185 | meta: { title: 'countTo' } | ||
186 | }, | ||
187 | { | ||
188 | path: 'mixin', | ||
189 | component: 'views/components-demo/mixin', | ||
190 | name: 'ComponentMixinDemo', | ||
191 | meta: { title: 'componentMixin' } | ||
192 | }, | ||
193 | { | ||
194 | path: 'back-to-top', | ||
195 | component: 'views/components-demo/back-to-top', | ||
196 | name: 'BackToTopDemo', | ||
197 | meta: { title: 'backToTop' } | ||
198 | }, | ||
199 | { | ||
200 | path: 'drag-dialog', | ||
201 | component: 'views/components-demo/drag-dialog', | ||
202 | name: 'DragDialogDemo', | ||
203 | meta: { title: 'dragDialog' } | ||
204 | }, | ||
205 | { | ||
206 | path: 'drag-select', | ||
207 | component: 'views/components-demo/drag-select', | ||
208 | name: 'DragSelectDemo', | ||
209 | meta: { title: 'dragSelect' } | ||
210 | }, | ||
211 | { | ||
212 | path: 'dnd-list', | ||
213 | component: 'views/components-demo/dnd-list', | ||
214 | name: 'DndListDemo', | ||
215 | meta: { title: 'dndList' } | ||
216 | }, | ||
217 | { | ||
218 | path: 'drag-kanban', | ||
219 | component: 'views/components-demo/drag-kanban', | ||
220 | name: 'DragKanbanDemo', | ||
221 | meta: { title: 'dragKanban' } | ||
222 | } | ||
223 | ] | ||
224 | }, | ||
225 | { | ||
226 | path: '/charts', | ||
227 | component: 'layout/Layout', | ||
228 | redirect: 'noRedirect', | ||
229 | name: 'Charts', | ||
230 | meta: { | ||
231 | title: 'charts', | ||
232 | icon: 'chart' | ||
233 | }, | ||
234 | children: [ | ||
235 | { | ||
236 | path: 'keyboard', | ||
237 | component: 'views/charts/keyboard', | ||
238 | name: 'KeyboardChart', | ||
239 | meta: { title: 'keyboardChart', noCache: true } | ||
240 | }, | ||
241 | { | ||
242 | path: 'line', | ||
243 | component: 'views/charts/line', | ||
244 | name: 'LineChart', | ||
245 | meta: { title: 'lineChart', noCache: true } | ||
246 | }, | ||
247 | { | ||
248 | path: 'mixchart', | ||
249 | component: 'views/charts/mixChart', | ||
250 | name: 'MixChart', | ||
251 | meta: { title: 'mixChart', noCache: true } | ||
252 | } | ||
253 | ] | ||
254 | }, | ||
255 | { | ||
256 | path: '/nested', | ||
257 | component: 'layout/Layout', | ||
258 | redirect: '/nested/menu1/menu1-1', | ||
259 | name: 'Nested', | ||
260 | meta: { | ||
261 | title: 'nested', | ||
262 | icon: 'nested' | ||
263 | }, | ||
264 | children: [ | ||
265 | { | ||
266 | path: 'menu1', | ||
267 | component: 'views/nested/menu1/index', | ||
268 | name: 'Menu1', | ||
269 | meta: { title: 'menu1' }, | ||
270 | redirect: '/nested/menu1/menu1-1', | ||
271 | children: [ | ||
272 | { | ||
273 | path: 'menu1-1', | ||
274 | component: 'views/nested/menu1/menu1-1', | ||
275 | name: 'Menu1-1', | ||
276 | meta: { title: 'menu1-1' } | ||
277 | }, | ||
278 | { | ||
279 | path: 'menu1-2', | ||
280 | component: 'views/nested/menu1/menu1-2', | ||
281 | name: 'Menu1-2', | ||
282 | redirect: '/nested/menu1/menu1-2/menu1-2-1', | ||
283 | meta: { title: 'menu1-2' }, | ||
284 | children: [ | ||
285 | { | ||
286 | path: 'menu1-2-1', | ||
287 | component: 'views/nested/menu1/menu1-2/menu1-2-1', | ||
288 | name: 'Menu1-2-1', | ||
289 | meta: { title: 'menu1-2-1' } | ||
290 | }, | ||
291 | { | ||
292 | path: 'menu1-2-2', | ||
293 | component: 'views/nested/menu1/menu1-2/menu1-2-2', | ||
294 | name: 'Menu1-2-2', | ||
295 | meta: { title: 'menu1-2-2' } | ||
296 | } | ||
297 | ] | ||
298 | }, | ||
299 | { | ||
300 | path: 'menu1-3', | ||
301 | component: 'views/nested/menu1/menu1-3', | ||
302 | name: 'Menu1-3', | ||
303 | meta: { title: 'menu1-3' } | ||
304 | } | ||
305 | ] | ||
306 | }, | ||
307 | { | ||
308 | path: 'menu2', | ||
309 | name: 'Menu2', | ||
310 | component: 'views/nested/menu2/index', | ||
311 | meta: { title: 'menu2' } | ||
312 | } | ||
313 | ] | ||
314 | }, | ||
315 | |||
316 | { | ||
317 | path: '/example', | ||
318 | component: 'layout/Layout', | ||
319 | redirect: '/example/list', | ||
320 | name: 'Example', | ||
321 | meta: { | ||
322 | title: 'example', | ||
323 | icon: 'example' | ||
324 | }, | ||
325 | children: [ | ||
326 | { | ||
327 | path: 'create', | ||
328 | component: 'views/example/create', | ||
329 | name: 'CreateArticle', | ||
330 | meta: { title: 'createArticle', icon: 'edit' } | ||
331 | }, | ||
332 | { | ||
333 | path: 'edit/:id(\\d+)', | ||
334 | component: 'views/example/edit', | ||
335 | name: 'EditArticle', | ||
336 | meta: { title: 'editArticle', noCache: true }, | ||
337 | hidden: true | ||
338 | }, | ||
339 | { | ||
340 | path: 'list', | ||
341 | component: 'views/example/list', | ||
342 | name: 'ArticleList', | ||
343 | meta: { title: 'articleList', icon: 'list' } | ||
344 | } | ||
345 | ] | ||
346 | }, | ||
347 | |||
348 | { | ||
349 | path: '/tab', | ||
350 | component: 'layout/Layout', | ||
351 | children: [ | ||
352 | { | ||
353 | path: 'index', | ||
354 | component: 'views/tab/index', | ||
355 | name: 'Tab', | ||
356 | meta: { title: 'tab', icon: 'tab' } | ||
357 | } | ||
358 | ] | ||
359 | }, | ||
360 | |||
361 | { | ||
362 | path: '/error', | ||
363 | component: 'layout/Layout', | ||
364 | redirect: 'noRedirect', | ||
365 | name: 'ErrorPages', | ||
366 | meta: { | ||
367 | title: 'errorPages', | ||
368 | icon: '404' | ||
369 | }, | ||
370 | children: [ | ||
371 | { | ||
372 | path: '401', | ||
373 | component: 'views/error-page/401', | ||
374 | name: 'Page401', | ||
375 | meta: { title: 'page401', noCache: true } | ||
376 | }, | ||
377 | { | ||
378 | path: '404', | ||
379 | component: 'views/error-page/404', | ||
380 | name: 'Page404', | ||
381 | meta: { title: 'page404', noCache: true } | ||
382 | } | ||
383 | ] | ||
384 | }, | ||
385 | |||
386 | { | ||
387 | path: '/error-log', | ||
388 | component: 'layout/Layout', | ||
389 | redirect: 'noRedirect', | ||
390 | children: [ | ||
391 | { | ||
392 | path: 'log', | ||
393 | component: 'views/error-log/index', | ||
394 | name: 'ErrorLog', | ||
395 | meta: { title: 'errorLog', icon: 'bug' } | ||
396 | } | ||
397 | ] | ||
398 | }, | ||
399 | |||
400 | { | ||
401 | path: '/excel', | ||
402 | component: 'layout/Layout', | ||
403 | redirect: '/excel/export-excel', | ||
404 | name: 'Excel', | ||
405 | meta: { | ||
406 | title: 'excel', | ||
407 | icon: 'excel' | ||
408 | }, | ||
409 | children: [ | ||
410 | { | ||
411 | path: 'export-excel', | ||
412 | component: 'views/excel/export-excel', | ||
413 | name: 'ExportExcel', | ||
414 | meta: { title: 'exportExcel' } | ||
415 | }, | ||
416 | { | ||
417 | path: 'export-selected-excel', | ||
418 | component: 'views/excel/select-excel', | ||
419 | name: 'SelectExcel', | ||
420 | meta: { title: 'selectExcel' } | ||
421 | }, | ||
422 | { | ||
423 | path: 'export-merge-header', | ||
424 | component: 'views/excel/merge-header', | ||
425 | name: 'MergeHeader', | ||
426 | meta: { title: 'mergeHeader' } | ||
427 | }, | ||
428 | { | ||
429 | path: 'upload-excel', | ||
430 | component: 'views/excel/upload-excel', | ||
431 | name: 'UploadExcel', | ||
432 | meta: { title: 'uploadExcel' } | ||
433 | } | ||
434 | ] | ||
435 | }, | ||
436 | |||
437 | { | ||
438 | path: '/zip', | ||
439 | component: 'layout/Layout', | ||
440 | redirect: '/zip/download', | ||
441 | alwaysShow: true, | ||
442 | meta: { title: 'zip', icon: 'zip' }, | ||
443 | children: [ | ||
444 | { | ||
445 | path: 'download', | ||
446 | component: 'views/zip/index', | ||
447 | name: 'ExportZip', | ||
448 | meta: { title: 'exportZip' } | ||
449 | } | ||
450 | ] | ||
451 | }, | ||
452 | |||
453 | { | ||
454 | path: '/pdf', | ||
455 | component: 'layout/Layout', | ||
456 | redirect: '/pdf/index', | ||
457 | children: [ | ||
458 | { | ||
459 | path: 'index', | ||
460 | component: 'views/pdf/index', | ||
461 | name: 'PDF', | ||
462 | meta: { title: 'pdf', icon: 'pdf' } | ||
463 | } | ||
464 | ] | ||
465 | }, | ||
466 | { | ||
467 | path: '/pdf/download', | ||
468 | component: 'views/pdf/download', | ||
469 | hidden: true | ||
470 | }, | ||
471 | |||
472 | { | ||
473 | path: '/theme', | ||
474 | component: 'layout/Layout', | ||
475 | redirect: 'noRedirect', | ||
476 | children: [ | ||
477 | { | ||
478 | path: 'index', | ||
479 | component: 'views/theme/index', | ||
480 | name: 'Theme', | ||
481 | meta: { title: 'theme', icon: 'theme' } | ||
482 | } | ||
483 | ] | ||
484 | }, | ||
485 | |||
486 | { | ||
487 | path: '/clipboard', | ||
488 | component: 'layout/Layout', | ||
489 | redirect: 'noRedirect', | ||
490 | children: [ | ||
491 | { | ||
492 | path: 'index', | ||
493 | component: 'views/clipboard/index', | ||
494 | name: 'ClipboardDemo', | ||
495 | meta: { title: 'clipboardDemo', icon: 'clipboard' } | ||
496 | } | ||
497 | ] | ||
498 | }, | ||
499 | |||
500 | { | ||
501 | path: '/i18n', | ||
502 | component: 'layout/Layout', | ||
503 | children: [ | ||
504 | { | ||
505 | path: 'index', | ||
506 | component: 'views/i18n-demo/index', | ||
507 | name: 'I18n', | ||
508 | meta: { title: 'i18n', icon: 'international' } | ||
509 | } | ||
510 | ] | ||
511 | }, | ||
512 | |||
513 | { | ||
514 | path: 'external-link', | ||
515 | component: 'layout/Layout', | ||
516 | children: [ | ||
517 | { | ||
518 | path: 'https://github.com/PanJiaChen/vue-element-admin', | ||
519 | meta: { title: 'externalLink', icon: 'link' } | ||
520 | } | ||
521 | ] | ||
522 | }, | ||
523 | |||
524 | { path: '*', redirect: '/404', hidden: true } | ||
525 | ] | ||
526 |
mock/user.js
1 | |||
1 | const tokens = { | 2 | const tokens = { |
2 | admin: { | 3 | admin: { |
3 | token: 'admin-token' | 4 | token: 'admin-token' |
4 | }, | 5 | }, |
5 | assistant: { | 6 | editor: { |
6 | token: 'assistant-token' | 7 | token: 'editor-token' |
7 | }, | ||
8 | runner: { | ||
9 | token: 'runner-token' | ||
10 | }, | ||
11 | shoper: { | ||
12 | token: 'shoper-token' | ||
13 | } | 8 | } |
14 | } | 9 | } |
15 | 10 | ||
16 | const users = { | 11 | const users = { |
17 | 'admin-token': { //管理员 | 12 | 'admin-token': { |
18 | roles: ['admin'], | 13 | roles: ['admin'], |
19 | introduction: 'I am a super administrator', | 14 | introduction: 'I am a super administrator', |
20 | avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif', | 15 | avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif', |
21 | name: 'Super Admin' | 16 | name: 'Super Admin' |
22 | }, | 17 | }, |
23 | 'assistant-token': { //管理员助理 | 18 | 'editor-token': { |
24 | roles: ['assistant'], | 19 | roles: ['editor'], |
25 | introduction: 'I am a assistant of administrator', | 20 | introduction: 'I am an editor', |
26 | avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif', | ||
27 | name: 'assistant Admin' | ||
28 | }, | ||
29 | 'runner-token': { //运营人员 | ||
30 | roles: ['runner'], | ||
31 | introduction: 'I am an runner', | ||
32 | avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif', | ||
33 | name: 'Normal runner' | ||
34 | }, | ||
35 | 'shoper-token': { //供应商 | ||
36 | roles: ['shoper'], | ||
37 | introduction: 'I am an shoper', | ||
38 | avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif', | 21 | avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif', |
39 | name: 'Normal shoper' | 22 | name: 'Normal Editor' |
40 | } | 23 | } |
41 | } | 24 | } |
42 | 25 | ||
43 | export default [{ // user login | 26 | export default [ |
44 | url: '/yp/user/login', | 27 | // user login |
28 | { | ||
29 | url: '/vue-element-admin/user/login', | ||
45 | type: 'post', | 30 | type: 'post', |
46 | response: config => { | 31 | response: config => { |
47 | console.log('config-----111--->', config.body); | 32 | const { username } = config.body |
48 | const { | 33 | const token = tokens[username] |
49 | username, | 34 | |
50 | password | 35 | // mock error |
51 | } = config.body; | 36 | if (!token) { |
52 | if (username == 'admin' && password == '111111') { | ||
53 | const token = tokens[username]; | ||
54 | if (!token) { | ||
55 | return { | ||
56 | code: 60204, | ||
57 | message: 'Account and password are incorrect.' | ||
58 | } | ||
59 | } else { | ||
60 | return { | ||
61 | code: 20000, | ||
62 | data: token | ||
63 | } | ||
64 | } | ||
65 | } else { | ||
66 | console.log('passwordpasswordpassword', username, password); | ||
67 | return { | 37 | return { |
68 | code: 60204, | 38 | code: 60204, |
69 | message: 'Account and password are incorrect///.' | 39 | message: 'Account and password are incorrect.' |
70 | } | 40 | } |
71 | } | 41 | } |
42 | |||
43 | return { | ||
44 | code: 20000, | ||
45 | data: token | ||
46 | } | ||
72 | } | 47 | } |
73 | }, | 48 | }, |
74 | 49 | ||
75 | // get user info | 50 | // get user info |
76 | { | 51 | { |
77 | url: '/yp/user/info\.*', | 52 | url: '/vue-element-admin/user/info\.*', |
78 | type: 'get', | 53 | type: 'get', |
79 | response: config => { | 54 | response: config => { |
80 | const { | 55 | const { token } = config.query |
81 | token | ||
82 | } = config.query | ||
83 | const info = users[token] | 56 | const info = users[token] |
84 | 57 | ||
85 | // mock error | 58 | // mock error |
86 | if (!info) { | 59 | if (!info) { |
87 | return { | 60 | return { |
88 | code: 50008, | 61 | code: 50008, |
89 | message: 'Login failed, unable to get user details.' | 62 | message: 'Login failed, unable to get user details.' |
90 | } | 63 | } |
91 | } | 64 | } |
92 | 65 | ||
93 | return { | 66 | return { |
94 | code: 20000, | 67 | code: 20000, |
95 | data: info | 68 | data: info |
96 | } | 69 | } |
97 | } | 70 | } |
98 | }, | 71 | }, |
99 | 72 | ||
100 | // user logout | 73 | // user logout |
101 | { | 74 | { |
102 | url: '/yp/user/logout', | 75 | url: '/vue-element-admin/user/logout', |
103 | type: 'post', | 76 | type: 'post', |
104 | response: _ => { | 77 | response: _ => { |
package.json
1 | { | 1 | { |
2 | "name": "yp-plan", | 2 | "name": "vue-element-admin", |
3 | "version": "4.2.1", | 3 | "version": "4.2.1", |
4 | "description": "A vue admin template with Element UI & axios & iconfont & permission control & lint", | 4 | "description": "A magical vue admin. An out-of-box UI solution for enterprise applications. Newest development stack of vue. Lots of awesome features", |
5 | "author": "XYT==admin@xiuyetang.com", | 5 | "author": "Pan <panfree23@gmail.com>", |
6 | "license": "MIT", | 6 | "license": "MIT", |
7 | "scripts": { | 7 | "scripts": { |
8 | "dev": "vue-cli-service serve", | 8 | "dev": "vue-cli-service serve", |
9 | "build:prod": "vue-cli-service build", | 9 | "build:prod": "vue-cli-service build", |
10 | "build:stage": "vue-cli-service build --mode staging", | 10 | "build:stage": "vue-cli-service build --mode staging", |
11 | "preview": "node build/index.js --preview", | 11 | "preview": "node build/index.js --preview", |
12 | "lint": "eslint --ext .js,.vue src", | 12 | "lint": "eslint --ext .js,.vue src", |
13 | "test:unit": "jest --clearCache && vue-cli-service test:unit", | 13 | "test:unit": "jest --clearCache && vue-cli-service test:unit", |
14 | "test:ci": "npm run lint && npm run test:unit", | 14 | "test:ci": "npm run lint && npm run test:unit", |
15 | "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml" | 15 | "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml", |
16 | "new": "plop" | ||
17 | }, | ||
18 | "husky": { | ||
19 | "hooks": { | ||
20 | "pre-commit": "lint-staged" | ||
21 | } | ||
22 | }, | ||
23 | "lint-staged": { | ||
24 | "src/**/*.{js,vue}": [ | ||
25 | "eslint --fix", | ||
26 | "git add" | ||
27 | ] | ||
28 | }, | ||
29 | "keywords": [ | ||
30 | "vue", | ||
31 | "admin", | ||
32 | "dashboard", | ||
33 | "element-ui", | ||
34 | "boilerplate", | ||
35 | "admin-template", | ||
36 | "management-system" | ||
37 | ], | ||
38 | "repository": { | ||
39 | "type": "git", | ||
40 | "url": "git+https://github.com/PanJiaChen/vue-element-admin.git" | ||
41 | }, | ||
42 | "bugs": { | ||
43 | "url": "https://github.com/PanJiaChen/vue-element-admin/issues" | ||
16 | }, | 44 | }, |
17 | "dependencies": { | 45 | "dependencies": { |
18 | "axios": "0.18.1", | 46 | "axios": "0.18.1", |
19 | "babel-polyfill": "^6.26.0", | 47 | "clipboard": "2.0.4", |
20 | "echarts": "^4.7.0", | 48 | "codemirror": "5.45.0", |
49 | "driver.js": "0.9.5", | ||
50 | "dropzone": "5.5.1", | ||
51 | "echarts": "4.2.1", | ||
21 | "element-ui": "2.13.0", | 52 | "element-ui": "2.13.0", |
53 | "file-saver": "2.0.1", | ||
54 | "fuse.js": "3.4.4", | ||
22 | "js-cookie": "2.2.0", | 55 | "js-cookie": "2.2.0", |
56 | "jsonlint": "1.6.3", | ||
57 | "jszip": "3.2.1", | ||
23 | "normalize.css": "7.0.0", | 58 | "normalize.css": "7.0.0", |
24 | "nprogress": "0.2.0", | 59 | "nprogress": "0.2.0", |
25 | "path-to-regexp": "2.4.0", | 60 | "path-to-regexp": "2.4.0", |
26 | "plop": "^2.6.0", | 61 | "pinyin": "2.9.0", |
62 | "screenfull": "4.2.0", | ||
63 | "showdown": "1.9.0", | ||
64 | "sortablejs": "1.8.4", | ||
65 | "tui-editor": "1.3.3", | ||
27 | "vue": "2.6.10", | 66 | "vue": "2.6.10", |
28 | "vue-router": "3.0.6", | 67 | "vue-count-to": "1.0.13", |
29 | "vuex": "3.1.0" | 68 | "vue-i18n": "7.3.2", |
69 | "vue-router": "3.0.2", | ||
70 | "vue-splitpane": "1.0.4", | ||
71 | "vuedraggable": "2.20.0", | ||
72 | "vuex": "3.1.0", | ||
73 | "xlsx": "0.14.1" | ||
30 | }, | 74 | }, |
31 | "devDependencies": { | 75 | "devDependencies": { |
32 | "@babel/core": "7.0.0", | 76 | "@babel/core": "7.0.0", |
33 | "@babel/preset-env": "^7.9.6", | ||
34 | "@babel/register": "7.0.0", | 77 | "@babel/register": "7.0.0", |
35 | "@vue/cli-plugin-babel": "3.6.0", | 78 | "@vue/cli-plugin-babel": "3.5.3", |
36 | "@vue/cli-plugin-eslint": "^3.9.1", | 79 | "@vue/cli-plugin-eslint": "^3.9.1", |
37 | "@vue/cli-plugin-unit-jest": "3.6.3", | 80 | "@vue/cli-plugin-unit-jest": "3.5.3", |
38 | "@vue/cli-service": "3.6.0", | 81 | "@vue/cli-service": "3.5.3", |
39 | "@vue/test-utils": "1.0.0-beta.29", | 82 | "@vue/test-utils": "1.0.0-beta.29", |
40 | "autoprefixer": "^9.5.1", | 83 | "autoprefixer": "^9.5.1", |
41 | "babel-cli": "^6.26.0", | ||
42 | "babel-core": "7.0.0-bridge.0", | 84 | "babel-core": "7.0.0-bridge.0", |
43 | "babel-eslint": "10.0.1", | 85 | "babel-eslint": "10.0.1", |
44 | "babel-jest": "23.6.0", | 86 | "babel-jest": "23.6.0", |
45 | "babel-plugin-component": "^1.1.1", | ||
46 | "babel-preset-env": "^1.7.0", | ||
47 | "chalk": "2.4.2", | 87 | "chalk": "2.4.2", |
88 | "chokidar": "2.1.5", | ||
48 | "connect": "3.6.6", | 89 | "connect": "3.6.6", |
49 | "eslint": "5.15.3", | 90 | "eslint": "5.15.3", |
50 | "eslint-plugin-vue": "5.2.2", | 91 | "eslint-plugin-vue": "5.2.2", |
51 | "html-webpack-plugin": "3.2.0", | 92 | "html-webpack-plugin": "3.2.0", |
93 | "husky": "1.3.1", | ||
94 | "lint-staged": "8.1.5", | ||
52 | "mockjs": "1.0.1-beta3", | 95 | "mockjs": "1.0.1-beta3", |
53 | "node-sass": "^4.9.0", | 96 | "node-sass": "^4.9.0", |
97 | "plop": "2.3.0", | ||
54 | "runjs": "^4.3.2", | 98 | "runjs": "^4.3.2", |
55 | "sass-loader": "^7.1.0", | 99 | "sass-loader": "^7.1.0", |
56 | "script-ext-html-webpack-plugin": "2.1.3", | 100 | "script-ext-html-webpack-plugin": "2.1.3", |
57 | "script-loader": "0.7.2", | 101 | "script-loader": "0.7.2", |
58 | "serve-static": "^1.13.2", | 102 | "serve-static": "^1.13.2", |
59 | "svg-sprite-loader": "4.1.3", | 103 | "svg-sprite-loader": "4.1.3", |
60 | "svgo": "1.2.2", | 104 | "svgo": "1.2.0", |
61 | "vue-schart": "^2.0.0", | ||
62 | "vue-template-compiler": "2.6.10" | 105 | "vue-template-compiler": "2.6.10" |
63 | }, | 106 | }, |
64 | "engines": { | 107 | "engines": { |
65 | "node": ">=8.9", | 108 | "node": ">=8.9", |
66 | "npm": ">= 3.0.0" | 109 | "npm": ">= 3.0.0" |
67 | }, | 110 | }, |
68 | "browserslist": [ | 111 | "browserslist": [ |
plop-templates/component/index.hbs
File was created | 1 | {{#if template}} | |
2 | <template> | ||
3 | <div /> | ||
4 | </template> | ||
5 | {{/if}} | ||
6 | |||
7 | {{#if script}} | ||
8 | <script> | ||
9 | export default { | ||
10 | name: '{{ properCase name }}', | ||
11 | props: {}, | ||
12 | data() { | ||
13 | return {} | ||
14 | }, | ||
15 | created() {}, | ||
16 | mounted() {}, | ||
17 | methods: {} | ||
18 | } | ||
19 | </script> | ||
20 | {{/if}} | ||
21 | |||
22 | {{#if style}} | ||
23 | <style lang="scss" scoped> | ||
24 | |||
25 | </style> | ||
26 | {{/if}} | ||
27 |
plop-templates/component/prompt.js
File was created | 1 | const { notEmpty } = require('../utils.js') | |
2 | |||
3 | module.exports = { | ||
4 | description: 'generate vue component', | ||
5 | prompts: [{ | ||
6 | type: 'input', | ||
7 | name: 'name', | ||
8 | message: 'component name please', | ||
9 | validate: notEmpty('name') | ||
10 | }, | ||
11 | { | ||
12 | type: 'checkbox', | ||
13 | name: 'blocks', | ||
14 | message: 'Blocks:', | ||
15 | choices: [{ | ||
16 | name: '<template>', | ||
17 | value: 'template', | ||
18 | checked: true | ||
19 | }, | ||
20 | { | ||
21 | name: '<script>', | ||
22 | value: 'script', | ||
23 | checked: true | ||
24 | }, | ||
25 | { | ||
26 | name: 'style', | ||
27 | value: 'style', | ||
28 | checked: true | ||
29 | } | ||
30 | ], | ||
31 | validate(value) { | ||
32 | if (value.indexOf('script') === -1 && value.indexOf('template') === -1) { | ||
33 | return 'Components require at least a <script> or <template> tag.' | ||
34 | } | ||
35 | return true | ||
36 | } | ||
37 | } | ||
38 | ], | ||
39 | actions: data => { | ||
40 | const name = '{{properCase name}}' | ||
41 | const actions = [{ | ||
42 | type: 'add', | ||
43 | path: `src/components/${name}/index.vue`, | ||
44 | templateFile: 'plop-templates/component/index.hbs', | ||
45 | data: { | ||
46 | name: name, | ||
47 | template: data.blocks.includes('template'), | ||
48 | script: data.blocks.includes('script'), | ||
49 | style: data.blocks.includes('style') | ||
50 | } | ||
51 | }] | ||
52 | |||
53 | return actions | ||
54 | } | ||
55 | } | ||
56 |
plop-templates/store/index.hbs
File was created | 1 | {{#if state}} | |
2 | const state = {} | ||
3 | {{/if}} | ||
4 | |||
5 | {{#if mutations}} | ||
6 | const mutations = {} | ||
7 | {{/if}} | ||
8 | |||
9 | {{#if actions}} | ||
10 | const actions = {} | ||
11 | {{/if}} | ||
12 | |||
13 | export default { | ||
14 | namespaced: true, | ||
15 | {{options}} | ||
16 | } | ||
17 |
plop-templates/store/prompt.js
File was created | 1 | const { notEmpty } = require('../utils.js') | |
2 | |||
3 | module.exports = { | ||
4 | description: 'generate store', | ||
5 | prompts: [{ | ||
6 | type: 'input', | ||
7 | name: 'name', | ||
8 | message: 'store name please', | ||
9 | validate: notEmpty('name') | ||
10 | }, | ||
11 | { | ||
12 | type: 'checkbox', | ||
13 | name: 'blocks', | ||
14 | message: 'Blocks:', | ||
15 | choices: [{ | ||
16 | name: 'state', | ||
17 | value: 'state', | ||
18 | checked: true | ||
19 | }, | ||
20 | { | ||
21 | name: 'mutations', | ||
22 | value: 'mutations', | ||
23 | checked: true | ||
24 | }, | ||
25 | { | ||
26 | name: 'actions', | ||
27 | value: 'actions', | ||
28 | checked: true | ||
29 | } | ||
30 | ], | ||
31 | validate(value) { | ||
32 | if (!value.includes('state') || !value.includes('mutations')) { | ||
33 | return 'store require at least state and mutations' | ||
34 | } | ||
35 | return true | ||
36 | } | ||
37 | } | ||
38 | ], | ||
39 | actions(data) { | ||
40 | const name = '{{name}}' | ||
41 | const { blocks } = data | ||
42 | const options = ['state', 'mutations'] | ||
43 | const joinFlag = `, | ||
44 | ` | ||
45 | if (blocks.length === 3) { | ||
46 | options.push('actions') | ||
47 | } | ||
48 | |||
49 | const actions = [{ | ||
50 | type: 'add', | ||
51 | path: `src/store/modules/${name}.js`, | ||
52 | templateFile: 'plop-templates/store/index.hbs', | ||
53 | data: { | ||
54 | options: options.join(joinFlag), | ||
55 | state: blocks.includes('state'), | ||
56 | mutations: blocks.includes('mutations'), | ||
57 | actions: blocks.includes('actions') | ||
58 | } | ||
59 | }] | ||
60 | return actions | ||
61 | } | ||
62 | } | ||
63 |
plop-templates/utils.js
File was created | 1 | exports.notEmpty = name => { | |
2 | return v => { | ||
3 | if (!v || v.trim === '') { | ||
4 | return `${name} is required` | ||
5 | } else { | ||
6 | return true | ||
7 | } | ||
8 | } | ||
9 | } | ||
10 |
plop-templates/view/index.hbs
File was created | 1 | {{#if template}} | |
2 | <template> | ||
3 | <div /> | ||
4 | </template> | ||
5 | {{/if}} | ||
6 | |||
7 | {{#if script}} | ||
8 | <script> | ||
9 | export default { | ||
10 | name: '{{ properCase name }}', | ||
11 | props: {}, | ||
12 | data() { | ||
13 | return {} | ||
14 | }, | ||
15 | created() {}, | ||
16 | mounted() {}, | ||
17 | methods: {} | ||
18 | } | ||
19 | </script> | ||
20 | {{/if}} | ||
21 | |||
22 | {{#if style}} | ||
23 | <style lang="scss" scoped> | ||
24 | |||
25 | </style> | ||
26 | {{/if}} | ||
27 |
plop-templates/view/prompt.js
File was created | 1 | const { notEmpty } = require('../utils.js') | |
2 | |||
3 | module.exports = { | ||
4 | description: 'generate a view', | ||
5 | prompts: [{ | ||
6 | type: 'input', | ||
7 | name: 'name', | ||
8 | message: 'view name please', | ||
9 | validate: notEmpty('name') | ||
10 | }, | ||
11 | { | ||
12 | type: 'checkbox', | ||
13 | name: 'blocks', | ||
14 | message: 'Blocks:', | ||
15 | choices: [{ | ||
16 | name: '<template>', | ||
17 | value: 'template', | ||
18 | checked: true | ||
19 | }, | ||
20 | { | ||
21 | name: '<script>', | ||
22 | value: 'script', | ||
23 | checked: true | ||
24 | }, | ||
25 | { | ||
26 | name: 'style', | ||
27 | value: 'style', | ||
28 | checked: true | ||
29 | } | ||
30 | ], | ||
31 | validate(value) { | ||
32 | if (value.indexOf('script') === -1 && value.indexOf('template') === -1) { | ||
33 | return 'View require at least a <script> or <template> tag.' | ||
34 | } | ||
35 | return true | ||
36 | } | ||
37 | } | ||
38 | ], | ||
39 | actions: data => { | ||
40 | const name = '{{name}}' | ||
41 | const actions = [{ | ||
42 | type: 'add', | ||
43 | path: `src/views/${name}/index.vue`, | ||
44 | templateFile: 'plop-templates/view/index.hbs', | ||
45 | data: { | ||
46 | name: name, | ||
47 | template: data.blocks.includes('template'), | ||
48 | script: data.blocks.includes('script'), | ||
49 | style: data.blocks.includes('style') | ||
50 | } | ||
51 | }] | ||
52 | |||
53 | return actions | ||
54 | } | ||
55 | } | ||
56 |
plopfile.js
File was created | 1 | const viewGenerator = require('./plop-templates/view/prompt') | |
2 | const componentGenerator = require('./plop-templates/component/prompt') | ||
3 | const storeGenerator = require('./plop-templates/store/prompt.js') | ||
4 | |||
5 | module.exports = function(plop) { | ||
6 | plop.setGenerator('view', viewGenerator) | ||
7 | plop.setGenerator('component', componentGenerator) | ||
8 | plop.setGenerator('store', storeGenerator) | ||
9 | } | ||
10 |
postcss.config.js
1 | // https://github.com/michael-ciniawsky/postcss-load-config | ||
2 | |||
3 | module.exports = { | 1 | module.exports = { |
4 | 'plugins': { | 2 | plugins: { |
5 | // to edit target browsers: use "browserslist" field in package.json | 3 | autoprefixer: {} |
6 | 'autoprefixer': {} | ||
7 | } | 4 | } |
8 | } | 5 | } |
9 | 6 |
No preview for this file type
public/index.html
1 | <!DOCTYPE html> | 1 | <!DOCTYPE html> |
2 | <html> | 2 | <html> |
3 | <head> | 3 | <head> |
4 | <meta charset="utf-8"> | 4 | <meta charset="utf-8"> |
5 | <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> | 5 | <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> |
6 | <meta name="renderer" content="webkit"> | ||
6 | <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> | 7 | <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> |
7 | <link rel="icon" href="<%= BASE_URL %>favicon.ico"> | 8 | <link rel="icon" href="<%= BASE_URL %>favicon.ico"> |
8 | <title><%= webpackConfig.name %></title> | 9 | <title><%= webpackConfig.name %></title> |
9 | </head> | 10 | </head> |
10 | <body> | 11 | <body> |
11 | <noscript> | ||
12 | <strong>We're sorry but <%= webpackConfig.name %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> | ||
13 | </noscript> | ||
14 | <div id="app"></div> | 12 | <div id="app"></div> |
15 | <!-- built files will be auto injected --> | 13 | <!-- built files will be auto injected --> |
16 | </body> | 14 | </body> |
17 | </html> | 15 | </html> |
src/App.vue
1 | <template> | 1 | <template> |
2 | <div id="app"> | 2 | <div id="app"> |
3 | <router-view /> | 3 | <router-view /> |
4 | </div> | 4 | </div> |
5 | </template> | 5 | </template> |
6 | 6 | ||
7 | |||
8 | <script> | 7 | <script> |
9 | export default { | 8 | export default { |
10 | name: "App" | 9 | name: 'App' |
11 | }; | ||
12 | </script> | ||
13 | |||
14 | |||
15 | <style> | ||
16 | @import "//at.alicdn.com/t/font_1075796_5kpx2vwkmq3.css"; | ||
17 | |||
18 | [class^="el-icon-mo"], | ||
19 | [class^=" el-icon-mo"] { | ||
20 | font-family: "iconfont", serif !important; | ||
21 | font-size: 16px; | ||
22 | font-style: normal; | ||
23 | -webkit-font-smoothing: antialiased; | ||
24 | -moz-osx-font-smoothing: grayscale; | ||
25 | } | 10 | } |
26 | </style> |
src/api/article.js
File was created | 1 | import request from '@/utils/request' | |
2 | |||
3 | export function fetchList(query) { | ||
4 | return request({ | ||
5 | url: '/vue-element-admin/article/list', | ||
6 | method: 'get', | ||
7 | params: query | ||
8 | }) | ||
9 | } | ||
10 | |||
11 | export function fetchArticle(id) { | ||
12 | return request({ | ||
13 | url: '/vue-element-admin/article/detail', | ||
14 | method: 'get', | ||
15 | params: { id } | ||
16 | }) | ||
17 | } | ||
18 | |||
19 | export function fetchPv(pv) { | ||
20 | return request({ | ||
21 | url: '/vue-element-admin/article/pv', | ||
22 | method: 'get', | ||
23 | params: { pv } | ||
24 | }) | ||
25 | } | ||
26 | |||
27 | export function createArticle(data) { | ||
28 | return request({ | ||
29 | url: '/vue-element-admin/article/create', | ||
30 | method: 'post', | ||
31 | data | ||
32 | }) | ||
33 | } | ||
34 | |||
35 | export function updateArticle(data) { | ||
36 | return request({ | ||
37 | url: '/vue-element-admin/article/update', | ||
38 | method: 'post', | ||
39 | data | ||
40 | }) | ||
41 | } | ||
42 |
src/api/qiniu.js
File was created | 1 | import request from '@/utils/request' | |
2 | |||
3 | export function getToken() { | ||
4 | return request({ | ||
5 | url: '/qiniu/upload/token', // 假地址 自行替换 | ||
6 | method: 'get' | ||
7 | }) | ||
8 | } | ||
9 |
src/api/remote-search.js
File was created | 1 | import request from '@/utils/request' | |
2 | |||
3 | export function searchUser(name) { | ||
4 | return request({ | ||
5 | url: '/vue-element-admin/search/user', | ||
6 | method: 'get', | ||
7 | params: { name } | ||
8 | }) | ||
9 | } | ||
10 | |||
11 | export function transactionList(query) { | ||
12 | return request({ | ||
13 | url: '/vue-element-admin/transaction/list', | ||
14 | method: 'get', | ||
15 | params: query | ||
16 | }) | ||
17 | } | ||
18 |
src/api/role.js
File was created | 1 | import request from '@/utils/request' | |
2 | |||
3 | export function getRoutes() { | ||
4 | return request({ | ||
5 | url: '/vue-element-admin/routes', | ||
6 | method: 'get' | ||
7 | }) | ||
8 | } | ||
9 | |||
10 | export function getRoles() { | ||
11 | return request({ | ||
12 | url: '/vue-element-admin/roles', | ||
13 | method: 'get' | ||
14 | }) | ||
15 | } | ||
16 | |||
17 | export function addRole(data) { | ||
18 | return request({ | ||
19 | url: '/vue-element-admin/role', | ||
20 | method: 'post', | ||
21 | data | ||
22 | }) | ||
23 | } | ||
24 | |||
25 | export function updateRole(id, data) { | ||
26 | return request({ | ||
27 | url: `/vue-element-admin/role/${id}`, | ||
28 | method: 'put', | ||
29 | data | ||
30 | }) | ||
31 | } | ||
32 | |||
33 | export function deleteRole(id) { | ||
34 | return request({ | ||
35 | url: `/vue-element-admin/role/${id}`, | ||
36 | method: 'delete' | ||
37 | }) | ||
38 | } | ||
39 |
src/api/user.js
1 | import request from '@/utils/request' | 1 | import request from '@/utils/request' |
2 | // var qs = require('Qs'); | ||
3 | 2 | ||
4 | export function login(data) { | 3 | export function login(data) { |
5 | console.log('login.1111...', data) | ||
6 | return request({ | 4 | return request({ |
7 | url: '/yp/user/login', | 5 | url: '/vue-element-admin/user/login', |
8 | // url: '/yp.user.login.php', | ||
9 | method: 'post', | 6 | method: 'post', |
10 | // headers: { | 7 | data |
11 | // 'Content-type': 'application/x-www-form-urlencoded' | ||
12 | // }, | ||
13 | data, | ||
14 | // responseType: 'text/plain', | ||
15 | // onDownloadProgress: false, | ||
16 | // onUploadProgress: true, | ||
17 | // proxy: {} | ||
18 | }); | ||
19 | } | ||
20 | |||
21 | export function getInfo(token) { | ||
22 | console.log('getInfo....', token) | ||
23 | return request({ | ||
24 | url: '/yp/user/info', | ||
25 | // url: '/yp.user.info.php', | ||
26 | method: 'get', | ||
27 | params: { | ||
28 | token | ||
29 | } | ||
30 | // , | ||
31 | // headers: { | ||
32 | // 'Content-type': 'application/x-www-form-urlencoded' | ||
33 | // }, | ||
34 | }) | 8 | }) |
35 | } | 9 | } |
36 | 10 | ||
37 | export function list(token) { | 11 | export function getInfo(token) { |
38 | console.log('listUser....', token) | ||
39 | return request({ | 12 | return request({ |
40 | url: '/yp/user/list', | 13 | url: '/vue-element-admin/user/info', |
41 | method: 'get', | 14 | method: 'get', |
42 | params: { | 15 | params: { token } |
43 | token | ||
44 | } | ||
45 | }) | 16 | }) |
46 | } | 17 | } |
47 | 18 | ||
48 | export function add(token) { | 19 | export function logout() { |
49 | console.log('addUser....', token) | ||
50 | return request({ | 20 | return request({ |
51 | url: '/yp/user/add', | 21 | url: '/vue-element-admin/user/logout', |
52 | method: 'post', | 22 | method: 'post' |
53 | params: { | ||
54 | token | ||
55 | } | ||
56 | }) | ||
57 | } | ||
58 | |||
59 | export function modi(token) { | ||
60 | console.log('modiUser....', token) | ||
61 | return request({ | ||
62 | url: '/yp/user/modi', | ||
63 | method: 'post', | ||
64 | params: { | ||
65 | token | ||
66 | } | ||
67 | }) | ||
68 | } | ||
69 | |||
70 | export function logout(token) { | ||
71 | console.log('logout....', token) | ||
72 | return request({ | ||
73 | url: '/yp/user/logout', | ||
74 | // url: '/yp.user.logout.php', | ||
75 | method: 'post', | ||
76 | }) | 23 | }) |
77 | } | 24 | } |
78 | 25 |
src/assets/401_images/401.gif
160 KB
src/assets/custom-theme/fonts/element-icons.ttf
No preview for this file type
src/assets/custom-theme/fonts/element-icons.woff
No preview for this file type
src/assets/custom-theme/index.css
File was created | 1 | @charset "UTF-8";.custom-theme .fade-in-linear-enter-active,.custom-theme .fade-in-linear-leave-active{-webkit-transition:opacity .2s linear;transition:opacity .2s linear}.custom-theme .fade-in-linear-enter,.custom-theme .fade-in-linear-leave,.custom-theme .fade-in-linear-leave-active{opacity:0}.custom-theme .el-fade-in-linear-enter-active,.custom-theme .el-fade-in-linear-leave-active{-webkit-transition:opacity .2s linear;transition:opacity .2s linear}.custom-theme .el-fade-in-linear-enter,.custom-theme .el-fade-in-linear-leave,.custom-theme .el-fade-in-linear-leave-active{opacity:0}.custom-theme .el-fade-in-enter-active,.custom-theme .el-fade-in-leave-active{-webkit-transition:all .3s cubic-bezier(.55,0,.1,1);transition:all .3s cubic-bezier(.55,0,.1,1)}.custom-theme .el-fade-in-enter,.custom-theme .el-fade-in-leave-active{opacity:0}.custom-theme .el-zoom-in-center-enter-active,.custom-theme .el-zoom-in-center-leave-active{-webkit-transition:all .3s cubic-bezier(.55,0,.1,1);transition:all .3s cubic-bezier(.55,0,.1,1)}.custom-theme .el-zoom-in-center-enter,.custom-theme .el-zoom-in-center-leave-active{opacity:0;-webkit-transform:scaleX(0);transform:scaleX(0)}.custom-theme .el-zoom-in-top-enter-active,.custom-theme .el-zoom-in-top-leave-active{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;transition:opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;transition:transform .3s cubic-bezier(.23,1,.32,1) .1s,opacity .3s cubic-bezier(.23,1,.32,1) .1s;transition:transform .3s cubic-bezier(.23,1,.32,1) .1s,opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;-webkit-transform-origin:center top;transform-origin:center top}.custom-theme .el-zoom-in-top-enter,.custom-theme .el-zoom-in-top-leave-active{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.custom-theme .el-zoom-in-bottom-enter-active,.custom-theme .el-zoom-in-bottom-leave-active{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;transition:opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;transition:transform .3s cubic-bezier(.23,1,.32,1) .1s,opacity .3s cubic-bezier(.23,1,.32,1) .1s;transition:transform .3s cubic-bezier(.23,1,.32,1) .1s,opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;-webkit-transform-origin:center bottom;transform-origin:center bottom}.custom-theme .el-zoom-in-bottom-enter,.custom-theme .el-zoom-in-bottom-leave-active{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.custom-theme .el-zoom-in-left-enter-active,.custom-theme .el-zoom-in-left-leave-active{opacity:1;-webkit-transform:scale(1,1);transform:scale(1,1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;transition:opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;transition:transform .3s cubic-bezier(.23,1,.32,1) .1s,opacity .3s cubic-bezier(.23,1,.32,1) .1s;transition:transform .3s cubic-bezier(.23,1,.32,1) .1s,opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;-webkit-transform-origin:top left;transform-origin:top left}.custom-theme .el-zoom-in-left-enter,.custom-theme .el-zoom-in-left-leave-active{opacity:0;-webkit-transform:scale(.45,.45);transform:scale(.45,.45)}.custom-theme .collapse-transition{-webkit-transition:.3s height ease-in-out,.3s padding-top ease-in-out,.3s padding-bottom ease-in-out;transition:.3s height ease-in-out,.3s padding-top ease-in-out,.3s padding-bottom ease-in-out}.custom-theme .horizontal-collapse-transition{-webkit-transition:.3s width ease-in-out,.3s padding-left ease-in-out,.3s padding-right ease-in-out;transition:.3s width ease-in-out,.3s padding-left ease-in-out,.3s padding-right ease-in-out}.custom-theme .el-list-enter-active,.custom-theme .el-list-leave-active{-webkit-transition:all 1s;transition:all 1s}.custom-theme .el-list-enter,.custom-theme .el-list-leave-active{opacity:0;-webkit-transform:translateY(-30px);transform:translateY(-30px)}.custom-theme .el-opacity-transition{-webkit-transition:opacity .3s cubic-bezier(.55,0,.1,1);transition:opacity .3s cubic-bezier(.55,0,.1,1)}@font-face{font-family:element-icons;src:url(fonts/element-icons.woff?t=1508751886602) format("woff"),url(fonts/element-icons.ttf?t=1508751886602) format("truetype");font-weight:400;font-style:normal}.custom-theme [class*=" el-icon-"],.custom-theme [class^=el-icon-]{font-family:element-icons!important;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;vertical-align:baseline;display:inline-block;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.custom-theme .el-icon-upload:before{content:"\e60d"}.custom-theme .el-icon-error:before{content:"\e62c"}.custom-theme .el-icon-success:before{content:"\e62d"}.custom-theme .el-icon-warning:before{content:"\e62e"}.custom-theme .el-icon-sort-down:before{content:"\e630"}.custom-theme .el-icon-sort-up:before{content:"\e631"}.custom-theme .el-icon-arrow-left:before{content:"\e600"}.custom-theme .el-icon-circle-plus:before{content:"\e601"}.custom-theme .el-icon-circle-plus-outline:before{content:"\e602"}.custom-theme .el-icon-arrow-down:before{content:"\e603"}.custom-theme .el-icon-arrow-right:before{content:"\e604"}.custom-theme .el-icon-arrow-up:before{content:"\e605"}.custom-theme .el-icon-back:before{content:"\e606"}.custom-theme .el-icon-circle-close:before{content:"\e607"}.custom-theme .el-icon-date:before{content:"\e608"}.custom-theme .el-icon-circle-close-outline:before{content:"\e609"}.custom-theme .el-icon-caret-left:before{content:"\e60a"}.custom-theme .el-icon-caret-bottom:before{content:"\e60b"}.custom-theme .el-icon-caret-top:before{content:"\e60c"}.custom-theme .el-icon-caret-right:before{content:"\e60e"}.custom-theme .el-icon-close:before{content:"\e60f"}.custom-theme .el-icon-d-arrow-left:before{content:"\e610"}.custom-theme .el-icon-check:before{content:"\e611"}.custom-theme .el-icon-delete:before{content:"\e612"}.custom-theme .el-icon-d-arrow-right:before{content:"\e613"}.custom-theme .el-icon-document:before{content:"\e614"}.custom-theme .el-icon-d-caret:before{content:"\e615"}.custom-theme .el-icon-edit-outline:before{content:"\e616"}.custom-theme .el-icon-download:before{content:"\e617"}.custom-theme .el-icon-goods:before{content:"\e618"}.custom-theme .el-icon-search:before{content:"\e619"}.custom-theme .el-icon-info:before{content:"\e61a"}.custom-theme .el-icon-message:before{content:"\e61b"}.custom-theme .el-icon-edit:before{content:"\e61c"}.custom-theme .el-icon-location:before{content:"\e61d"}.custom-theme .el-icon-loading:before{content:"\e61e"}.custom-theme .el-icon-location-outline:before{content:"\e61f"}.custom-theme .el-icon-menu:before{content:"\e620"}.custom-theme .el-icon-minus:before{content:"\e621"}.custom-theme .el-icon-bell:before{content:"\e622"}.custom-theme .el-icon-mobile-phone:before{content:"\e624"}.custom-theme .el-icon-news:before{content:"\e625"}.custom-theme .el-icon-more:before{content:"\e646"}.custom-theme .el-icon-more-outline:before{content:"\e626"}.custom-theme .el-icon-phone:before{content:"\e627"}.custom-theme .el-icon-phone-outline:before{content:"\e628"}.custom-theme .el-icon-picture:before{content:"\e629"}.custom-theme .el-icon-picture-outline:before{content:"\e62a"}.custom-theme .el-icon-plus:before{content:"\e62b"}.custom-theme .el-icon-printer:before{content:"\e62f"}.custom-theme .el-icon-rank:before{content:"\e632"}.custom-theme .el-icon-refresh:before{content:"\e633"}.custom-theme .el-icon-question:before{content:"\e634"}.custom-theme .el-icon-remove:before{content:"\e635"}.custom-theme .el-icon-share:before{content:"\e636"}.custom-theme .el-icon-star-on:before{content:"\e637"}.custom-theme .el-icon-setting:before{content:"\e638"}.custom-theme .el-icon-circle-check:before{content:"\e639"}.custom-theme .el-icon-service:before{content:"\e63a"}.custom-theme .el-icon-sold-out:before{content:"\e63b"}.custom-theme .el-icon-remove-outline:before{content:"\e63c"}.custom-theme .el-icon-star-off:before{content:"\e63d"}.custom-theme .el-icon-circle-check-outline:before{content:"\e63e"}.custom-theme .el-icon-tickets:before{content:"\e63f"}.custom-theme .el-icon-sort:before{content:"\e640"}.custom-theme .el-icon-zoom-in:before{content:"\e641"}.custom-theme .el-icon-time:before{content:"\e642"}.custom-theme .el-icon-view:before{content:"\e643"}.custom-theme .el-icon-upload2:before{content:"\e644"}.custom-theme .el-icon-zoom-out:before{content:"\e645"}.custom-theme .el-icon-loading{-webkit-animation:rotating 2s linear infinite;animation:rotating 2s linear infinite}.custom-theme .el-icon--right{margin-left:5px}.custom-theme .el-icon--left{margin-right:5px}@-webkit-keyframes rotating{0%{-webkit-transform:rotateZ(0);transform:rotateZ(0)}100%{-webkit-transform:rotateZ(360deg);transform:rotateZ(360deg)}}@keyframes rotating{0%{-webkit-transform:rotateZ(0);transform:rotateZ(0)}100%{-webkit-transform:rotateZ(360deg);transform:rotateZ(360deg)}}.custom-theme .el-popper .popper__arrow,.custom-theme .el-popper .popper__arrow::after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.custom-theme .el-popper .popper__arrow{border-width:6px;-webkit-filter:drop-shadow(0 2px 12px rgba(0, 0, 0, .03));filter:drop-shadow(0 2px 12px rgba(0, 0, 0, .03))}.custom-theme .el-popper .popper__arrow::after{content:" ";border-width:6px}.custom-theme .el-popper[x-placement^=top]{margin-bottom:12px}.custom-theme .el-popper[x-placement^=top] .popper__arrow{bottom:-6px;left:50%;margin-right:3px;border-top-color:#e6ebf5;border-bottom-width:0}.custom-theme .el-popper[x-placement^=top] .popper__arrow::after{bottom:1px;margin-left:-6px;border-top-color:#fff;border-bottom-width:0}.custom-theme .el-popper[x-placement^=bottom]{margin-top:12px}.custom-theme .el-popper[x-placement^=bottom] .popper__arrow{top:-6px;left:50%;margin-right:3px;border-top-width:0;border-bottom-color:#e6ebf5}.custom-theme .el-popper[x-placement^=bottom] .popper__arrow::after{top:1px;margin-left:-6px;border-top-width:0;border-bottom-color:#fff}.custom-theme .el-popper[x-placement^=right]{margin-left:12px}.custom-theme .el-popper[x-placement^=right] .popper__arrow{top:50%;left:-6px;margin-bottom:3px;border-right-color:#e6ebf5;border-left-width:0}.custom-theme .el-popper[x-placement^=right] .popper__arrow::after{bottom:-6px;left:1px;border-right-color:#fff;border-left-width:0}.custom-theme .el-popper[x-placement^=left]{margin-right:12px}.custom-theme .el-popper[x-placement^=left] .popper__arrow{top:50%;right:-6px;margin-bottom:3px;border-right-width:0;border-left-color:#e6ebf5}.custom-theme .el-popper[x-placement^=left] .popper__arrow::after{right:1px;bottom:-6px;margin-left:-6px;border-right-width:0;border-left-color:#fff}.custom-theme .el-select-dropdown{position:absolute;z-index:1001;border:solid 1px #dfe4ed;border-radius:4px;background-color:#fff;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);-webkit-box-sizing:border-box;box-sizing:border-box;margin:5px 0}.custom-theme .el-select-dropdown.is-multiple .el-select-dropdown__item.selected{color:#262729;background-color:#fff}.custom-theme .el-select-dropdown.is-multiple .el-select-dropdown__item.selected.hover{background-color:#f5f7fa}.custom-theme .el-select-dropdown.is-multiple .el-select-dropdown__item.selected::after{position:absolute;right:20px;font-family:element-icons;content:"\E611";font-size:12px;font-weight:700;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.custom-theme .el-select-dropdown .el-scrollbar.is-empty .el-select-dropdown__list{padding:0}.custom-theme .el-select-dropdown .popper__arrow{-webkit-transform:translateX(-400%);transform:translateX(-400%)}.custom-theme .el-select-dropdown.is-arrow-fixed .popper__arrow{-webkit-transform:translateX(-200%);transform:translateX(-200%)}.custom-theme .el-select-dropdown__empty{padding:10px 0;margin:0;text-align:center;color:#999;font-size:14px}.custom-theme .el-select-dropdown__wrap{max-height:274px}.custom-theme .el-select-dropdown__list{list-style:none;padding:6px 0;margin:0;-webkit-box-sizing:border-box;box-sizing:border-box}.custom-theme .el-input{position:relative;font-size:14px;display:inline-block;width:100%}.custom-theme .el-input::-webkit-scrollbar{z-index:11;width:6px}.custom-theme .el-input::-webkit-scrollbar:horizontal{height:6px}.custom-theme .el-input::-webkit-scrollbar-thumb{border-radius:5px;width:6px;background:#b4bccc}.custom-theme .el-input::-webkit-scrollbar-corner{background:#fff}.custom-theme .el-input::-webkit-scrollbar-track{background:#fff}.custom-theme .el-input::-webkit-scrollbar-track-piece{background:#fff;width:6px}.custom-theme .el-input__inner{-webkit-appearance:none;background-color:#fff;background-image:none;border-radius:4px;border:1px solid #d8dce5;-webkit-box-sizing:border-box;box-sizing:border-box;color:#5a5e66;display:inline-block;font-size:inherit;height:40px;line-height:1;outline:0;padding:0 15px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1);width:100%}.custom-theme .el-input__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner::placeholder{color:#b4bccc}.custom-theme .el-input__inner:hover{border-color:#b4bccc}.custom-theme .el-input__inner:focus{outline:0;border-color:#262729}.custom-theme .el-input__suffix{position:absolute;height:100%;right:5px;top:0;text-align:center;color:#b4bccc;-webkit-transition:all .3s;transition:all .3s;pointer-events:none}.custom-theme .el-input__suffix-inner{pointer-events:all}.custom-theme .el-input__prefix{position:absolute;height:100%;left:5px;top:0;text-align:center;color:#b4bccc;-webkit-transition:all .3s;transition:all .3s}.custom-theme .el-input__icon{height:100%;width:25px;text-align:center;-webkit-transition:all .3s;transition:all .3s;line-height:40px}.custom-theme .el-input__icon:after{content:'';height:100%;width:0;display:inline-block;vertical-align:middle}.custom-theme .el-input__validateIcon{pointer-events:none}.custom-theme .el-input.is-active .el-input__inner{outline:0;border-color:#262729}.custom-theme .el-input.is-disabled .el-input__inner{background-color:#f5f7fa;border-color:#dfe4ed;color:#b4bccc;cursor:not-allowed}.custom-theme .el-input.is-disabled .el-input__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner::placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__icon{cursor:not-allowed}.custom-theme .el-input--suffix .el-input__inner{padding-right:30px}.custom-theme .el-input--prefix .el-input__inner{padding-left:30px}.custom-theme .el-input--medium{font-size:14px}.custom-theme .el-input--medium .el-input__inner{height:36px}.custom-theme .el-input--medium .el-input__icon{line-height:36px}.custom-theme .el-input--small{font-size:13px}.custom-theme .el-input--small .el-input__inner{height:32px}.custom-theme .el-input--small .el-input__icon{line-height:32px}.custom-theme .el-input--mini{font-size:12px}.custom-theme .el-input--mini .el-input__inner{height:28px}.custom-theme .el-input--mini .el-input__icon{line-height:28px}.custom-theme .el-input-group{line-height:normal;display:inline-table;width:100%;border-collapse:separate}.custom-theme .el-input-group>.el-input__inner{vertical-align:middle;display:table-cell}.custom-theme .el-input-group__append,.custom-theme .el-input-group__prepend{background-color:#f5f7fa;color:#0a76a4;vertical-align:middle;display:table-cell;position:relative;border:1px solid #d8dce5;border-radius:4px;padding:0 20px;width:1px;white-space:nowrap}.custom-theme .el-input-group__append:focus,.custom-theme .el-input-group__prepend:focus{outline:0}.custom-theme .el-input-group__append .el-button,.custom-theme .el-input-group__append .el-select,.custom-theme .el-input-group__prepend .el-button,.custom-theme .el-input-group__prepend .el-select{display:inline-block;margin:-20px}.custom-theme .el-input-group__append button.el-button,.custom-theme .el-input-group__append div.el-select .el-input__inner,.custom-theme .el-input-group__append div.el-select:hover .el-input__inner,.custom-theme .el-input-group__prepend button.el-button,.custom-theme .el-input-group__prepend div.el-select .el-input__inner,.custom-theme .el-input-group__prepend div.el-select:hover .el-input__inner{border-color:transparent;background-color:transparent;color:inherit;border-top:0;border-bottom:0}.custom-theme .el-input-group__append .el-button,.custom-theme .el-input-group__append .el-input,.custom-theme .el-input-group__prepend .el-button,.custom-theme .el-input-group__prepend .el-input{font-size:inherit}.custom-theme .el-input-group__prepend{border-right:0;border-top-right-radius:0;border-bottom-right-radius:0}.custom-theme .el-input-group__append{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.custom-theme .el-input-group--prepend .el-input__inner{border-top-left-radius:0;border-bottom-left-radius:0}.custom-theme .el-input-group--append .el-input__inner{border-top-right-radius:0;border-bottom-right-radius:0}.custom-theme .el-textarea{display:inline-block;width:100%;vertical-align:bottom}.custom-theme .el-textarea__inner{display:block;resize:vertical;padding:5px 15px;line-height:1.5;-webkit-box-sizing:border-box;box-sizing:border-box;width:100%;font-size:14px;color:#5a5e66;background-color:#fff;background-image:none;border:1px solid #d8dce5;border-radius:4px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1)}.custom-theme .el-textarea__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner::placeholder{color:#b4bccc}.custom-theme .el-textarea__inner:hover{border-color:#b4bccc}.custom-theme .el-textarea__inner:focus{outline:0;border-color:#262729}.custom-theme .el-textarea.is-disabled .el-textarea__inner{background-color:#f5f7fa;border-color:#dfe4ed;color:#b4bccc;cursor:not-allowed}.custom-theme .el-textarea.is-disabled .el-textarea__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner::placeholder{color:#b4bccc}.custom-theme .el-tag{background-color:rgba(38,39,41,.1);display:inline-block;padding:0 10px;height:32px;line-height:30px;font-size:12px;color:#262729;border-radius:4px;-webkit-box-sizing:border-box;box-sizing:border-box;border:1px solid rgba(38,39,41,.2);white-space:nowrap}.custom-theme .el-tag .el-icon-close{border-radius:50%;text-align:center;position:relative;cursor:pointer;font-size:12px;height:18px;width:18px;line-height:18px;vertical-align:middle;top:-1px;right:-5px;color:#262729}.custom-theme .el-tag .el-icon-close::before{display:block}.custom-theme .el-tag .el-icon-close:hover{background-color:#262729;color:#fff}.custom-theme .el-tag--info{background-color:rgba(10,118,164,.1);border-color:rgba(10,118,164,.2);color:#0a76a4}.custom-theme .el-tag--info.is-hit{border-color:#0a76a4}.custom-theme .el-tag--info .el-tag__close{color:#0a76a4}.custom-theme .el-tag--info .el-tag__close:hover{background-color:#0a76a4;color:#fff}.custom-theme .el-tag--success{background-color:rgba(64,145,103,.1);border-color:rgba(64,145,103,.2);color:#409167}.custom-theme .el-tag--success.is-hit{border-color:#409167}.custom-theme .el-tag--success .el-tag__close{color:#409167}.custom-theme .el-tag--success .el-tag__close:hover{background-color:#409167;color:#fff}.custom-theme .el-tag--warning{background-color:rgba(157,164,8,.1);border-color:rgba(157,164,8,.2);color:#9da408}.custom-theme .el-tag--warning.is-hit{border-color:#9da408}.custom-theme .el-tag--warning .el-tag__close{color:#9da408}.custom-theme .el-tag--warning .el-tag__close:hover{background-color:#9da408;color:#fff}.custom-theme .el-tag--danger{background-color:rgba(179,69,14,.1);border-color:rgba(179,69,14,.2);color:#b3450e}.custom-theme .el-tag--danger.is-hit{border-color:#b3450e}.custom-theme .el-tag--danger .el-tag__close{color:#b3450e}.custom-theme .el-tag--danger .el-tag__close:hover{background-color:#b3450e;color:#fff}.custom-theme .el-tag--medium{height:28px;line-height:26px}.custom-theme .el-tag--medium .el-icon-close{-webkit-transform:scale(.8);transform:scale(.8)}.custom-theme .el-tag--small{height:24px;padding:0 8px;line-height:22px}.custom-theme .el-tag--small .el-icon-close{-webkit-transform:scale(.8);transform:scale(.8)}.custom-theme .el-tag--mini{height:20px;padding:0 5px;line-height:19px}.custom-theme .el-tag--mini .el-icon-close{margin-left:-3px;-webkit-transform:scale(.7);transform:scale(.7)}.custom-theme .el-select-dropdown__item{font-size:14px;padding:0 20px;position:relative;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#5a5e66;height:34px;line-height:34px;-webkit-box-sizing:border-box;box-sizing:border-box;cursor:pointer}.custom-theme .el-select-dropdown__item.is-disabled{color:#b4bccc;cursor:not-allowed}.custom-theme .el-select-dropdown__item.is-disabled:hover{background-color:#fff}.custom-theme .el-select-dropdown__item.hover,.custom-theme .el-select-dropdown__item:hover{background-color:#f5f7fa}.custom-theme .el-select-dropdown__item.selected{color:#262729;font-weight:700}.custom-theme .el-select-dropdown__item span{line-height:34px!important}.custom-theme .el-select-group{margin:0;padding:0}.custom-theme .el-select-group__wrap{position:relative;list-style:none;margin:0;padding:0}.custom-theme .el-select-group__wrap:not(:last-of-type){padding-bottom:24px}.custom-theme .el-select-group__wrap:not(:last-of-type)::after{content:'';position:absolute;display:block;left:20px;right:20px;bottom:12px;height:1px;background:#dfe4ed}.custom-theme .el-select-group__title{padding-left:20px;font-size:12px;color:#0a76a4;line-height:30px}.custom-theme .el-select-group .el-select-dropdown__item{padding-left:20px}.custom-theme .el-scrollbar{overflow:hidden;position:relative}.custom-theme .el-scrollbar:active>.el-scrollbar__bar,.custom-theme .el-scrollbar:focus>.el-scrollbar__bar,.custom-theme .el-scrollbar:hover>.el-scrollbar__bar{opacity:1;-webkit-transition:opacity 340ms ease-out;transition:opacity 340ms ease-out}.custom-theme .el-scrollbar__wrap{overflow:scroll;height:100%}.custom-theme .el-scrollbar__wrap--hidden-default::-webkit-scrollbar{width:0;height:0}.custom-theme .el-scrollbar__thumb{position:relative;display:block;width:0;height:0;cursor:pointer;border-radius:inherit;background-color:rgba(135,141,153,.3);-webkit-transition:.3s background-color;transition:.3s background-color}.custom-theme .el-scrollbar__thumb:hover{background-color:rgba(135,141,153,.5)}.custom-theme .el-scrollbar__bar{position:absolute;right:2px;bottom:2px;z-index:1;border-radius:4px;opacity:0;-webkit-transition:opacity 120ms ease-out;transition:opacity 120ms ease-out}.custom-theme .el-scrollbar__bar.is-vertical{width:6px;top:2px}.custom-theme .el-scrollbar__bar.is-vertical>div{width:100%}.custom-theme .el-scrollbar__bar.is-horizontal{height:6px;left:2px}.custom-theme .el-scrollbar__bar.is-horizontal>div{height:100%}.custom-theme .el-select{display:inline-block;position:relative}.custom-theme .el-select:hover .el-input__inner{border-color:#b4bccc}.custom-theme .el-select .el-input__inner{cursor:pointer;padding-right:35px}.custom-theme .el-select .el-input__inner:focus{border-color:#262729}.custom-theme .el-select .el-input .el-select__caret{color:#b4bccc;font-size:14px;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;-webkit-transform:rotateZ(180deg);transform:rotateZ(180deg);line-height:16px;cursor:pointer}.custom-theme .el-select .el-input .el-select__caret.is-reverse{-webkit-transform:rotateZ(0);transform:rotateZ(0)}.custom-theme .el-select .el-input .el-select__caret.is-show-close{font-size:14px;text-align:center;-webkit-transform:rotateZ(180deg);transform:rotateZ(180deg);border-radius:100%;color:#b4bccc;-webkit-transition:color .2s cubic-bezier(.645,.045,.355,1);transition:color .2s cubic-bezier(.645,.045,.355,1)}.custom-theme .el-select .el-input .el-select__caret.is-show-close:hover{color:#878d99}.custom-theme .el-select .el-input.is-disabled .el-input__inner{cursor:not-allowed}.custom-theme .el-select .el-input.is-disabled .el-input__inner:hover{border-color:#dfe4ed}.custom-theme .el-select>.el-input{display:block}.custom-theme .el-select__input{border:none;outline:0;padding:0;margin-left:15px;color:#666;font-size:14px;vertical-align:baseline;-webkit-appearance:none;-moz-appearance:none;appearance:none;height:28px;background-color:transparent}.custom-theme .el-select__input.is-mini{height:14px}.custom-theme .el-select__close{cursor:pointer;position:absolute;top:8px;z-index:1000;right:25px;color:#b4bccc;line-height:18px;font-size:14px}.custom-theme .el-select__close:hover{color:#878d99}.custom-theme .el-select__tags{position:absolute;line-height:normal;white-space:normal;z-index:1;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.custom-theme .el-select .el-tag__close{margin-top:-2px}.custom-theme .el-select .el-tag{-webkit-box-sizing:border-box;box-sizing:border-box;border-color:transparent;margin:3px 0 3px 6px;background-color:#f0f2f5}.custom-theme .el-select .el-tag__close.el-icon-close{background-color:#b4bccc;right:-7px;color:#fff}.custom-theme .el-select .el-tag__close.el-icon-close:hover{background-color:#878d99}.custom-theme .el-select .el-tag__close.el-icon-close::before{display:block;-webkit-transform:translate(0,.5px);transform:translate(0,.5px)}.custom-theme .el-select__tag{display:inline-block;height:24px;line-height:24px;font-size:14px;border-radius:4px;color:#fff;background-color:#262729}.custom-theme .el-select__tag .el-icon-close{font-size:14px}.custom-theme .el-pagination{white-space:nowrap;padding:2px 5px;color:#2d2f33;font-weight:700}.custom-theme .el-pagination::after,.custom-theme .el-pagination::before{display:table;content:""}.custom-theme .el-pagination::after{clear:both}.custom-theme .el-pagination button,.custom-theme .el-pagination span:not([class*=suffix]){display:inline-block;font-size:13px;min-width:35.5px;height:28px;line-height:28px;vertical-align:top;-webkit-box-sizing:border-box;box-sizing:border-box}.custom-theme .el-pagination .el-input__inner{text-align:center}.custom-theme .el-pagination .el-input__suffix{right:0;-webkit-transform:scale(.8);transform:scale(.8)}.custom-theme .el-pagination .el-select .el-input{width:100px;margin:0 5px}.custom-theme .el-pagination .el-select .el-input .el-input__inner{padding-right:25px;border-radius:3px;height:28px}.custom-theme .el-pagination button{border:none;padding:0 6px;background:0 0}.custom-theme .el-pagination button:focus{outline:0}.custom-theme .el-pagination button:hover{color:#262729}.custom-theme .el-pagination button.disabled{color:#b4bccc;background-color:#fff;cursor:not-allowed}.custom-theme .el-pagination .btn-next,.custom-theme .el-pagination .btn-prev{background:center center no-repeat;background-size:16px;background-color:#fff;cursor:pointer;margin:0;color:#2d2f33}.custom-theme .el-pagination .btn-next .el-icon,.custom-theme .el-pagination .btn-prev .el-icon{display:block;font-size:12px}.custom-theme .el-pagination .btn-prev{padding-right:12px}.custom-theme .el-pagination .btn-next{padding-left:12px}.custom-theme .el-pagination--small .btn-next,.custom-theme .el-pagination--small .btn-prev,.custom-theme .el-pagination--small .el-pager li,.custom-theme .el-pagination--small .el-pager li:last-child{border-color:transparent;font-size:12px;line-height:22px;height:22px;min-width:22px}.custom-theme .el-pagination--small .arrow.disabled{visibility:hidden}.custom-theme .el-pagination__sizes{margin:0 10px 0 0;font-weight:400;color:#5a5e66}.custom-theme .el-pagination__sizes .el-input .el-input__inner{font-size:13px;padding-left:8px}.custom-theme .el-pagination__sizes .el-input .el-input__inner:hover{border-color:#262729}.custom-theme .el-pagination__total{margin-right:10px;font-weight:400;color:#5a5e66}.custom-theme .el-pagination__jump{margin-left:24px;font-weight:400;color:#5a5e66}.custom-theme .el-pagination__jump .el-input__inner{padding:0 3px}.custom-theme .el-pagination__rightwrapper{float:right}.custom-theme .el-pagination__editor{line-height:18px;padding:0 2px;height:28px;text-align:center;margin:0 2px;-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:3px;-moz-appearance:textfield}.custom-theme .el-pagination__editor.el-input{width:50px}.custom-theme .el-pagination__editor.el-input .el-input__inner{height:28px}.custom-theme .el-pagination__editor .el-input__inner::-webkit-inner-spin-button,.custom-theme .el-pagination__editor .el-input__inner::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.custom-theme .el-pager{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;list-style:none;display:inline-block;vertical-align:top;font-size:0;padding:0;margin:0}.custom-theme .el-pager .el-icon-more::before{vertical-align:-4px}.custom-theme .el-pager li{padding:0 4px;background:#fff;vertical-align:top;display:inline-block;font-size:13px;min-width:35.5px;height:28px;line-height:28px;cursor:pointer;-webkit-box-sizing:border-box;box-sizing:border-box;text-align:center;margin:0}.custom-theme .el-pager li.btn-quicknext,.custom-theme .el-pager li.btn-quickprev{line-height:28px;color:#2d2f33}.custom-theme .el-pager li.btn-quickprev:hover{cursor:pointer}.custom-theme .el-pager li.btn-quicknext:hover{cursor:pointer}.custom-theme .el-pager li.active+li{border-left:0}.custom-theme .el-pager li:hover{color:#262729}.custom-theme .el-pager li.active{color:#262729;cursor:default}.custom-theme .v-modal-enter{-webkit-animation:v-modal-in .2s ease;animation:v-modal-in .2s ease}.custom-theme .v-modal-leave{-webkit-animation:v-modal-out .2s ease forwards;animation:v-modal-out .2s ease forwards}@-webkit-keyframes v-modal-in{0%{opacity:0}}@keyframes v-modal-in{0%{opacity:0}}@-webkit-keyframes v-modal-out{100%{opacity:0}}@keyframes v-modal-out{100%{opacity:0}}.custom-theme .v-modal{position:fixed;left:0;top:0;width:100%;height:100%;opacity:.5;background:#000}.custom-theme .el-dialog{position:relative;margin:0 auto 50px;background:#fff;border-radius:2px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,.3);box-shadow:0 1px 3px rgba(0,0,0,.3);-webkit-box-sizing:border-box;box-sizing:border-box;width:50%}.custom-theme .el-dialog.is-fullscreen{width:100%;margin-top:0;margin-bottom:0;height:100%;overflow:auto}.custom-theme .el-dialog__wrapper{position:fixed;top:0;right:0;bottom:0;left:0;overflow:auto;margin:0}.custom-theme .el-dialog__header{padding:15px;padding-bottom:10px}.custom-theme .el-dialog__headerbtn{position:absolute;top:15px;right:15px;padding:0;background:0 0;border:none;outline:0;cursor:pointer;font-size:16px}.custom-theme .el-dialog__headerbtn .el-dialog__close{color:#0a76a4}.custom-theme .el-dialog__headerbtn:focus .el-dialog__close,.custom-theme .el-dialog__headerbtn:hover .el-dialog__close{color:#262729}.custom-theme .el-dialog__title{line-height:24px;font-size:18px;color:#2d2f33}.custom-theme .el-dialog__body{padding:30px 20px;color:#5a5e66;line-height:24px;font-size:14px}.custom-theme .el-dialog__footer{padding:15px;padding-top:10px;text-align:right;-webkit-box-sizing:border-box;box-sizing:border-box}.custom-theme .el-dialog--center{text-align:center}.custom-theme .el-dialog--center .el-dialog__header{padding-top:30px}.custom-theme .el-dialog--center .el-dialog__body{text-align:initial;padding:25px 27px 30px}.custom-theme .el-dialog--center .el-dialog__footer{text-align:inherit;padding-bottom:30px}.custom-theme .dialog-fade-enter-active{-webkit-animation:dialog-fade-in .3s;animation:dialog-fade-in .3s}.custom-theme .dialog-fade-leave-active{-webkit-animation:dialog-fade-out .3s;animation:dialog-fade-out .3s}@-webkit-keyframes dialog-fade-in{0%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}}@keyframes dialog-fade-in{0%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}}@-webkit-keyframes dialog-fade-out{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}100%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}}@keyframes dialog-fade-out{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}100%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}}.custom-theme .el-input{position:relative;font-size:14px;display:inline-block;width:100%}.custom-theme .el-input::-webkit-scrollbar{z-index:11;width:6px}.custom-theme .el-input::-webkit-scrollbar:horizontal{height:6px}.custom-theme .el-input::-webkit-scrollbar-thumb{border-radius:5px;width:6px;background:#b4bccc}.custom-theme .el-input::-webkit-scrollbar-corner{background:#fff}.custom-theme .el-input::-webkit-scrollbar-track{background:#fff}.custom-theme .el-input::-webkit-scrollbar-track-piece{background:#fff;width:6px}.custom-theme .el-input__inner{-webkit-appearance:none;background-color:#fff;background-image:none;border-radius:4px;border:1px solid #d8dce5;-webkit-box-sizing:border-box;box-sizing:border-box;color:#5a5e66;display:inline-block;font-size:inherit;height:40px;line-height:1;outline:0;padding:0 15px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1);width:100%}.custom-theme .el-input__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner::placeholder{color:#b4bccc}.custom-theme .el-input__inner:hover{border-color:#b4bccc}.custom-theme .el-input__inner:focus{outline:0;border-color:#262729}.custom-theme .el-input__suffix{position:absolute;height:100%;right:5px;top:0;text-align:center;color:#b4bccc;-webkit-transition:all .3s;transition:all .3s;pointer-events:none}.custom-theme .el-input__suffix-inner{pointer-events:all}.custom-theme .el-input__prefix{position:absolute;height:100%;left:5px;top:0;text-align:center;color:#b4bccc;-webkit-transition:all .3s;transition:all .3s}.custom-theme .el-input__icon{height:100%;width:25px;text-align:center;-webkit-transition:all .3s;transition:all .3s;line-height:40px}.custom-theme .el-input__icon:after{content:'';height:100%;width:0;display:inline-block;vertical-align:middle}.custom-theme .el-input__validateIcon{pointer-events:none}.custom-theme .el-input.is-active .el-input__inner{outline:0;border-color:#262729}.custom-theme .el-input.is-disabled .el-input__inner{background-color:#f5f7fa;border-color:#dfe4ed;color:#b4bccc;cursor:not-allowed}.custom-theme .el-input.is-disabled .el-input__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner::placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__icon{cursor:not-allowed}.custom-theme .el-input--suffix .el-input__inner{padding-right:30px}.custom-theme .el-input--prefix .el-input__inner{padding-left:30px}.custom-theme .el-input--medium{font-size:14px}.custom-theme .el-input--medium .el-input__inner{height:36px}.custom-theme .el-input--medium .el-input__icon{line-height:36px}.custom-theme .el-input--small{font-size:13px}.custom-theme .el-input--small .el-input__inner{height:32px}.custom-theme .el-input--small .el-input__icon{line-height:32px}.custom-theme .el-input--mini{font-size:12px}.custom-theme .el-input--mini .el-input__inner{height:28px}.custom-theme .el-input--mini .el-input__icon{line-height:28px}.custom-theme .el-input-group{line-height:normal;display:inline-table;width:100%;border-collapse:separate}.custom-theme .el-input-group>.el-input__inner{vertical-align:middle;display:table-cell}.custom-theme .el-input-group__append,.custom-theme .el-input-group__prepend{background-color:#f5f7fa;color:#0a76a4;vertical-align:middle;display:table-cell;position:relative;border:1px solid #d8dce5;border-radius:4px;padding:0 20px;width:1px;white-space:nowrap}.custom-theme .el-input-group__append:focus,.custom-theme .el-input-group__prepend:focus{outline:0}.custom-theme .el-input-group__append .el-button,.custom-theme .el-input-group__append .el-select,.custom-theme .el-input-group__prepend .el-button,.custom-theme .el-input-group__prepend .el-select{display:inline-block;margin:-20px}.custom-theme .el-input-group__append button.el-button,.custom-theme .el-input-group__append div.el-select .el-input__inner,.custom-theme .el-input-group__append div.el-select:hover .el-input__inner,.custom-theme .el-input-group__prepend button.el-button,.custom-theme .el-input-group__prepend div.el-select .el-input__inner,.custom-theme .el-input-group__prepend div.el-select:hover .el-input__inner{border-color:transparent;background-color:transparent;color:inherit;border-top:0;border-bottom:0}.custom-theme .el-input-group__append .el-button,.custom-theme .el-input-group__append .el-input,.custom-theme .el-input-group__prepend .el-button,.custom-theme .el-input-group__prepend .el-input{font-size:inherit}.custom-theme .el-input-group__prepend{border-right:0;border-top-right-radius:0;border-bottom-right-radius:0}.custom-theme .el-input-group__append{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.custom-theme .el-input-group--prepend .el-input__inner{border-top-left-radius:0;border-bottom-left-radius:0}.custom-theme .el-input-group--append .el-input__inner{border-top-right-radius:0;border-bottom-right-radius:0}.custom-theme .el-textarea{display:inline-block;width:100%;vertical-align:bottom}.custom-theme .el-textarea__inner{display:block;resize:vertical;padding:5px 15px;line-height:1.5;-webkit-box-sizing:border-box;box-sizing:border-box;width:100%;font-size:14px;color:#5a5e66;background-color:#fff;background-image:none;border:1px solid #d8dce5;border-radius:4px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1)}.custom-theme .el-textarea__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner::placeholder{color:#b4bccc}.custom-theme .el-textarea__inner:hover{border-color:#b4bccc}.custom-theme .el-textarea__inner:focus{outline:0;border-color:#262729}.custom-theme .el-textarea.is-disabled .el-textarea__inner{background-color:#f5f7fa;border-color:#dfe4ed;color:#b4bccc;cursor:not-allowed}.custom-theme .el-textarea.is-disabled .el-textarea__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner::placeholder{color:#b4bccc}.custom-theme .el-scrollbar{overflow:hidden;position:relative}.custom-theme .el-scrollbar:active>.el-scrollbar__bar,.custom-theme .el-scrollbar:focus>.el-scrollbar__bar,.custom-theme .el-scrollbar:hover>.el-scrollbar__bar{opacity:1;-webkit-transition:opacity 340ms ease-out;transition:opacity 340ms ease-out}.custom-theme .el-scrollbar__wrap{overflow:scroll;height:100%}.custom-theme .el-scrollbar__wrap--hidden-default::-webkit-scrollbar{width:0;height:0}.custom-theme .el-scrollbar__thumb{position:relative;display:block;width:0;height:0;cursor:pointer;border-radius:inherit;background-color:rgba(135,141,153,.3);-webkit-transition:.3s background-color;transition:.3s background-color}.custom-theme .el-scrollbar__thumb:hover{background-color:rgba(135,141,153,.5)}.custom-theme .el-scrollbar__bar{position:absolute;right:2px;bottom:2px;z-index:1;border-radius:4px;opacity:0;-webkit-transition:opacity 120ms ease-out;transition:opacity 120ms ease-out}.custom-theme .el-scrollbar__bar.is-vertical{width:6px;top:2px}.custom-theme .el-scrollbar__bar.is-vertical>div{width:100%}.custom-theme .el-scrollbar__bar.is-horizontal{height:6px;left:2px}.custom-theme .el-scrollbar__bar.is-horizontal>div{height:100%}.custom-theme .el-popper .popper__arrow,.custom-theme .el-popper .popper__arrow::after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.custom-theme .el-popper .popper__arrow{border-width:6px;-webkit-filter:drop-shadow(0 2px 12px rgba(0, 0, 0, .03));filter:drop-shadow(0 2px 12px rgba(0, 0, 0, .03))}.custom-theme .el-popper .popper__arrow::after{content:" ";border-width:6px}.custom-theme .el-popper[x-placement^=top]{margin-bottom:12px}.custom-theme .el-popper[x-placement^=top] .popper__arrow{bottom:-6px;left:50%;margin-right:3px;border-top-color:#e6ebf5;border-bottom-width:0}.custom-theme .el-popper[x-placement^=top] .popper__arrow::after{bottom:1px;margin-left:-6px;border-top-color:#fff;border-bottom-width:0}.custom-theme .el-popper[x-placement^=bottom]{margin-top:12px}.custom-theme .el-popper[x-placement^=bottom] .popper__arrow{top:-6px;left:50%;margin-right:3px;border-top-width:0;border-bottom-color:#e6ebf5}.custom-theme .el-popper[x-placement^=bottom] .popper__arrow::after{top:1px;margin-left:-6px;border-top-width:0;border-bottom-color:#fff}.custom-theme .el-popper[x-placement^=right]{margin-left:12px}.custom-theme .el-popper[x-placement^=right] .popper__arrow{top:50%;left:-6px;margin-bottom:3px;border-right-color:#e6ebf5;border-left-width:0}.custom-theme .el-popper[x-placement^=right] .popper__arrow::after{bottom:-6px;left:1px;border-right-color:#fff;border-left-width:0}.custom-theme .el-popper[x-placement^=left]{margin-right:12px}.custom-theme .el-popper[x-placement^=left] .popper__arrow{top:50%;right:-6px;margin-bottom:3px;border-right-width:0;border-left-color:#e6ebf5}.custom-theme .el-popper[x-placement^=left] .popper__arrow::after{right:1px;bottom:-6px;margin-left:-6px;border-right-width:0;border-left-color:#fff}.custom-theme .el-autocomplete{position:relative;display:inline-block}.custom-theme .el-autocomplete-suggestion{margin:5px 0;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);border-radius:4px}.custom-theme .el-autocomplete-suggestion.el-popper .popper__arrow{left:24px!important}.custom-theme .el-autocomplete-suggestion__wrap{max-height:280px;padding:10px 0;-webkit-box-sizing:border-box;box-sizing:border-box;overflow:auto;background-color:#fff;border:1px solid #dfe4ed;border-radius:4px}.custom-theme .el-autocomplete-suggestion__list{margin:0;padding:0}.custom-theme .el-autocomplete-suggestion li{padding:0 20px;margin:0;line-height:34px;cursor:pointer;color:#5a5e66;font-size:14px;list-style:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.custom-theme .el-autocomplete-suggestion li:hover{background-color:#f5f7fa}.custom-theme .el-autocomplete-suggestion li.highlighted{background-color:#f5f7fa}.custom-theme .el-autocomplete-suggestion li.divider{margin-top:6px;border-top:1px solid #000}.custom-theme .el-autocomplete-suggestion li.divider:last-child{margin-bottom:-6px}.custom-theme .el-autocomplete-suggestion.is-loading li{text-align:center;height:100px;line-height:100px;font-size:20px;color:#999}.custom-theme .el-autocomplete-suggestion.is-loading li::after{display:inline-block;content:"";height:100%;vertical-align:middle}.custom-theme .el-autocomplete-suggestion.is-loading li:hover{background-color:#fff}.custom-theme .el-autocomplete-suggestion.is-loading .el-icon-loading{vertical-align:middle}.custom-theme .el-button{display:inline-block;line-height:1;white-space:nowrap;cursor:pointer;background:#fff;border:1px solid #d8dce5;border-color:#d8dce5;color:#5a5e66;-webkit-appearance:none;text-align:center;-webkit-box-sizing:border-box;box-sizing:border-box;outline:0;margin:0;-webkit-transition:.1s;transition:.1s;font-weight:500;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;padding:12px 20px;font-size:14px;border-radius:4px}.custom-theme .el-button+.el-button{margin-left:10px}.custom-theme .el-button.is-round{padding:12px 20px}.custom-theme .el-button:focus,.custom-theme .el-button:hover{color:#262729;border-color:#bebebf;background-color:#e9e9ea}.custom-theme .el-button:active{color:#222325;border-color:#222325;outline:0}.custom-theme .el-button::-moz-focus-inner{border:0}.custom-theme .el-button [class*=el-icon-]+span{margin-left:5px}.custom-theme .el-button.is-plain:focus,.custom-theme .el-button.is-plain:hover{background:#fff;border-color:#262729;color:#262729}.custom-theme .el-button.is-plain:active{background:#fff;border-color:#222325;color:#222325;outline:0}.custom-theme .el-button.is-active{color:#222325;border-color:#222325}.custom-theme .el-button.is-disabled,.custom-theme .el-button.is-disabled:focus,.custom-theme .el-button.is-disabled:hover{color:#b4bccc;cursor:not-allowed;background-image:none;background-color:#fff;border-color:#e6ebf5}.custom-theme .el-button.is-disabled.el-button--text{background-color:transparent}.custom-theme .el-button.is-disabled.is-plain,.custom-theme .el-button.is-disabled.is-plain:focus,.custom-theme .el-button.is-disabled.is-plain:hover{background-color:#fff;border-color:#e6ebf5;color:#b4bccc}.custom-theme .el-button.is-loading{position:relative;pointer-events:none}.custom-theme .el-button.is-loading:before{pointer-events:none;content:'';position:absolute;left:-1px;top:-1px;right:-1px;bottom:-1px;border-radius:inherit;background-color:rgba(255,255,255,.35)}.custom-theme .el-button.is-round{border-radius:20px;padding:12px 23px}.custom-theme .el-button--primary{color:#fff;background-color:#262729;border-color:#262729}.custom-theme .el-button--primary:focus,.custom-theme .el-button--primary:hover{background:#515254;border-color:#515254;color:#fff}.custom-theme .el-button--primary:active{background:#222325;border-color:#222325;color:#fff;outline:0}.custom-theme .el-button--primary.is-active{background:#222325;border-color:#222325;color:#fff}.custom-theme .el-button--primary.is-disabled,.custom-theme .el-button--primary.is-disabled:active,.custom-theme .el-button--primary.is-disabled:focus,.custom-theme .el-button--primary.is-disabled:hover{color:#fff;background-color:#939394;border-color:#939394}.custom-theme .el-button--primary.is-plain{color:#262729;background:#e9e9ea;border-color:#a8a9a9}.custom-theme .el-button--primary.is-plain:focus,.custom-theme .el-button--primary.is-plain:hover{background:#262729;border-color:#262729;color:#fff}.custom-theme .el-button--primary.is-plain:active{background:#222325;border-color:#222325;color:#fff;outline:0}.custom-theme .el-button--primary.is-plain.is-disabled,.custom-theme .el-button--primary.is-plain.is-disabled:active,.custom-theme .el-button--primary.is-plain.is-disabled:focus,.custom-theme .el-button--primary.is-plain.is-disabled:hover{color:#7d7d7f;background-color:#e9e9ea;border-color:#d4d4d4}.custom-theme .el-button--success{color:#fff;background-color:#409167;border-color:#409167}.custom-theme .el-button--success:focus,.custom-theme .el-button--success:hover{background:#66a785;border-color:#66a785;color:#fff}.custom-theme .el-button--success:active{background:#3a835d;border-color:#3a835d;color:#fff;outline:0}.custom-theme .el-button--success.is-active{background:#3a835d;border-color:#3a835d;color:#fff}.custom-theme .el-button--success.is-disabled,.custom-theme .el-button--success.is-disabled:active,.custom-theme .el-button--success.is-disabled:focus,.custom-theme .el-button--success.is-disabled:hover{color:#fff;background-color:#a0c8b3;border-color:#a0c8b3}.custom-theme .el-button--success.is-plain{color:#409167;background:#ecf4f0;border-color:#b3d3c2}.custom-theme .el-button--success.is-plain:focus,.custom-theme .el-button--success.is-plain:hover{background:#409167;border-color:#409167;color:#fff}.custom-theme .el-button--success.is-plain:active{background:#3a835d;border-color:#3a835d;color:#fff;outline:0}.custom-theme .el-button--success.is-plain.is-disabled,.custom-theme .el-button--success.is-plain.is-disabled:active,.custom-theme .el-button--success.is-plain.is-disabled:focus,.custom-theme .el-button--success.is-plain.is-disabled:hover{color:#8cbda4;background-color:#ecf4f0;border-color:#d9e9e1}.custom-theme .el-button--warning{color:#fff;background-color:#9da408;border-color:#9da408}.custom-theme .el-button--warning:focus,.custom-theme .el-button--warning:hover{background:#b1b639;border-color:#b1b639;color:#fff}.custom-theme .el-button--warning:active{background:#8d9407;border-color:#8d9407;color:#fff;outline:0}.custom-theme .el-button--warning.is-active{background:#8d9407;border-color:#8d9407;color:#fff}.custom-theme .el-button--warning.is-disabled,.custom-theme .el-button--warning.is-disabled:active,.custom-theme .el-button--warning.is-disabled:focus,.custom-theme .el-button--warning.is-disabled:hover{color:#fff;background-color:#ced284;border-color:#ced284}.custom-theme .el-button--warning.is-plain{color:#9da408;background:#f5f6e6;border-color:#d8db9c}.custom-theme .el-button--warning.is-plain:focus,.custom-theme .el-button--warning.is-plain:hover{background:#9da408;border-color:#9da408;color:#fff}.custom-theme .el-button--warning.is-plain:active{background:#8d9407;border-color:#8d9407;color:#fff;outline:0}.custom-theme .el-button--warning.is-plain.is-disabled,.custom-theme .el-button--warning.is-plain.is-disabled:active,.custom-theme .el-button--warning.is-plain.is-disabled:focus,.custom-theme .el-button--warning.is-plain.is-disabled:hover{color:#c4c86b;background-color:#f5f6e6;border-color:#ebedce}.custom-theme .el-button--danger{color:#fff;background-color:#b3450e;border-color:#b3450e}.custom-theme .el-button--danger:focus,.custom-theme .el-button--danger:hover{background:#c26a3e;border-color:#c26a3e;color:#fff}.custom-theme .el-button--danger:active{background:#a13e0d;border-color:#a13e0d;color:#fff;outline:0}.custom-theme .el-button--danger.is-active{background:#a13e0d;border-color:#a13e0d;color:#fff}.custom-theme .el-button--danger.is-disabled,.custom-theme .el-button--danger.is-disabled:active,.custom-theme .el-button--danger.is-disabled:focus,.custom-theme .el-button--danger.is-disabled:hover{color:#fff;background-color:#d9a287;border-color:#d9a287}.custom-theme .el-button--danger.is-plain{color:#b3450e;background:#f7ece7;border-color:#e1b59f}.custom-theme .el-button--danger.is-plain:focus,.custom-theme .el-button--danger.is-plain:hover{background:#b3450e;border-color:#b3450e;color:#fff}.custom-theme .el-button--danger.is-plain:active{background:#a13e0d;border-color:#a13e0d;color:#fff;outline:0}.custom-theme .el-button--danger.is-plain.is-disabled,.custom-theme .el-button--danger.is-plain.is-disabled:active,.custom-theme .el-button--danger.is-plain.is-disabled:focus,.custom-theme .el-button--danger.is-plain.is-disabled:hover{color:#d18f6e;background-color:#f7ece7;border-color:#f0dacf}.custom-theme .el-button--info{color:#fff;background-color:#0a76a4;border-color:#0a76a4}.custom-theme .el-button--info:focus,.custom-theme .el-button--info:hover{background:#3b91b6;border-color:#3b91b6;color:#fff}.custom-theme .el-button--info:active{background:#096a94;border-color:#096a94;color:#fff;outline:0}.custom-theme .el-button--info.is-active{background:#096a94;border-color:#096a94;color:#fff}.custom-theme .el-button--info.is-disabled,.custom-theme .el-button--info.is-disabled:active,.custom-theme .el-button--info.is-disabled:focus,.custom-theme .el-button--info.is-disabled:hover{color:#fff;background-color:#85bbd2;border-color:#85bbd2}.custom-theme .el-button--info.is-plain{color:#0a76a4;background:#e7f1f6;border-color:#9dc8db}.custom-theme .el-button--info.is-plain:focus,.custom-theme .el-button--info.is-plain:hover{background:#0a76a4;border-color:#0a76a4;color:#fff}.custom-theme .el-button--info.is-plain:active{background:#096a94;border-color:#096a94;color:#fff;outline:0}.custom-theme .el-button--info.is-plain.is-disabled,.custom-theme .el-button--info.is-plain.is-disabled:active,.custom-theme .el-button--info.is-plain.is-disabled:focus,.custom-theme .el-button--info.is-plain.is-disabled:hover{color:#6cadc8;background-color:#e7f1f6;border-color:#cee4ed}.custom-theme .el-button--medium{padding:10px 20px;font-size:14px;border-radius:4px}.custom-theme .el-button--medium.is-round{padding:10px 20px}.custom-theme .el-button--small{padding:9px 15px;font-size:12px;border-radius:3px}.custom-theme .el-button--small.is-round{padding:9px 15px}.custom-theme .el-button--mini{padding:7px 15px;font-size:12px;border-radius:3px}.custom-theme .el-button--mini.is-round{padding:7px 15px}.custom-theme .el-button--text{border:none;color:#262729;background:0 0;padding-left:0;padding-right:0}.custom-theme .el-button--text:focus,.custom-theme .el-button--text:hover{color:#515254;border-color:transparent;background-color:transparent}.custom-theme .el-button--text:active{color:#222325;border-color:transparent;background-color:transparent}.custom-theme .el-button-group{display:inline-block;vertical-align:middle}.custom-theme .el-button-group::after,.custom-theme .el-button-group::before{display:table;content:""}.custom-theme .el-button-group::after{clear:both}.custom-theme .el-button-group .el-button{float:left;position:relative}.custom-theme .el-button-group .el-button+.el-button{margin-left:0}.custom-theme .el-button-group .el-button:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.custom-theme .el-button-group .el-button:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.custom-theme .el-button-group .el-button:not(:first-child):not(:last-child){border-radius:0}.custom-theme .el-button-group .el-button:not(:last-child){margin-right:-1px}.custom-theme .el-button-group .el-button:active,.custom-theme .el-button-group .el-button:focus,.custom-theme .el-button-group .el-button:hover{z-index:1}.custom-theme .el-button-group .el-button.is-active{z-index:1}.custom-theme .el-button-group .el-button--primary:first-child{border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--primary:last-child{border-left-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--primary:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--success:first-child{border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--success:last-child{border-left-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--success:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--warning:first-child{border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--warning:last-child{border-left-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--warning:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--danger:first-child{border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--danger:last-child{border-left-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--danger:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--info:first-child{border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--info:last-child{border-left-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--info:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.custom-theme .el-popper .popper__arrow,.custom-theme .el-popper .popper__arrow::after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.custom-theme .el-popper .popper__arrow{border-width:6px;-webkit-filter:drop-shadow(0 2px 12px rgba(0, 0, 0, .03));filter:drop-shadow(0 2px 12px rgba(0, 0, 0, .03))}.custom-theme .el-popper .popper__arrow::after{content:" ";border-width:6px}.custom-theme .el-popper[x-placement^=top]{margin-bottom:12px}.custom-theme .el-popper[x-placement^=top] .popper__arrow{bottom:-6px;left:50%;margin-right:3px;border-top-color:#e6ebf5;border-bottom-width:0}.custom-theme .el-popper[x-placement^=top] .popper__arrow::after{bottom:1px;margin-left:-6px;border-top-color:#fff;border-bottom-width:0}.custom-theme .el-popper[x-placement^=bottom]{margin-top:12px}.custom-theme .el-popper[x-placement^=bottom] .popper__arrow{top:-6px;left:50%;margin-right:3px;border-top-width:0;border-bottom-color:#e6ebf5}.custom-theme .el-popper[x-placement^=bottom] .popper__arrow::after{top:1px;margin-left:-6px;border-top-width:0;border-bottom-color:#fff}.custom-theme .el-popper[x-placement^=right]{margin-left:12px}.custom-theme .el-popper[x-placement^=right] .popper__arrow{top:50%;left:-6px;margin-bottom:3px;border-right-color:#e6ebf5;border-left-width:0}.custom-theme .el-popper[x-placement^=right] .popper__arrow::after{bottom:-6px;left:1px;border-right-color:#fff;border-left-width:0}.custom-theme .el-popper[x-placement^=left]{margin-right:12px}.custom-theme .el-popper[x-placement^=left] .popper__arrow{top:50%;right:-6px;margin-bottom:3px;border-right-width:0;border-left-color:#e6ebf5}.custom-theme .el-popper[x-placement^=left] .popper__arrow::after{right:1px;bottom:-6px;margin-left:-6px;border-right-width:0;border-left-color:#fff}.custom-theme .el-dropdown{display:inline-block;position:relative;color:#5a5e66;font-size:14px}.custom-theme .el-dropdown .el-button-group{display:block}.custom-theme .el-dropdown .el-button-group .el-button{float:none}.custom-theme .el-dropdown .el-dropdown__caret-button{padding-left:5px;padding-right:5px;position:relative;border-left:none}.custom-theme .el-dropdown .el-dropdown__caret-button::before{content:'';position:absolute;display:block;width:1px;top:5px;bottom:5px;left:0;background:rgba(255,255,255,.5)}.custom-theme .el-dropdown .el-dropdown__caret-button:hover::before{top:0;bottom:0}.custom-theme .el-dropdown .el-dropdown__caret-button .el-dropdown__icon{padding-left:0}.custom-theme .el-dropdown__icon{font-size:12px;margin:0 3px}.custom-theme .el-dropdown-menu{position:absolute;top:0;left:0;z-index:10;padding:10px 0;margin:5px 0;background-color:#fff;border:1px solid #e6ebf5;border-radius:4px;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.custom-theme .el-dropdown-menu__item{list-style:none;line-height:36px;padding:0 20px;margin:0;font-size:14px;color:#5a5e66;cursor:pointer}.custom-theme .el-dropdown-menu__item:not(.is-disabled):hover{background-color:#e9e9ea;color:#515254}.custom-theme .el-dropdown-menu__item--divided{position:relative;margin-top:6px;border-top:1px solid #e6ebf5}.custom-theme .el-dropdown-menu__item--divided:before{content:'';height:6px;display:block;margin:0 -20px;background-color:#fff}.custom-theme .el-dropdown-menu__item.is-disabled{cursor:default;color:#bbb;pointer-events:none}.custom-theme .el-dropdown-menu--medium{padding:6px 0}.custom-theme .el-dropdown-menu--medium .el-dropdown-menu__item{line-height:30px;padding:0 17px;font-size:14px}.custom-theme .el-dropdown-menu--medium .el-dropdown-menu__item.el-dropdown-menu__item--divided{margin-top:6px}.custom-theme .el-dropdown-menu--medium .el-dropdown-menu__item.el-dropdown-menu__item--divided:before{height:6px;margin:0 -17px}.custom-theme .el-dropdown-menu--small{padding:6px 0}.custom-theme .el-dropdown-menu--small .el-dropdown-menu__item{line-height:27px;padding:0 15px;font-size:13px}.custom-theme .el-dropdown-menu--small .el-dropdown-menu__item.el-dropdown-menu__item--divided{margin-top:4px}.custom-theme .el-dropdown-menu--small .el-dropdown-menu__item.el-dropdown-menu__item--divided:before{height:4px;margin:0 -15px}.custom-theme .el-dropdown-menu--mini{padding:3px 0}.custom-theme .el-dropdown-menu--mini .el-dropdown-menu__item{line-height:24px;padding:0 10px;font-size:12px}.custom-theme .el-dropdown-menu--mini .el-dropdown-menu__item.el-dropdown-menu__item--divided{margin-top:3px}.custom-theme .el-dropdown-menu--mini .el-dropdown-menu__item.el-dropdown-menu__item--divided:before{height:3px;margin:0 -10px}.custom-theme .el-menu{border-right:solid 1px #e6e6e6;list-style:none;position:relative;margin:0;padding-left:0;background-color:#fff}.custom-theme .el-menu::after,.custom-theme .el-menu::before{display:table;content:""}.custom-theme .el-menu::after{clear:both}.custom-theme .el-menu li{list-style:none}.custom-theme .el-menu--horizontal{border-right:none;border-bottom:solid 1px #e6e6e6}.custom-theme .el-menu--horizontal .el-menu-item{float:left;height:60px;line-height:60px;margin:0;cursor:pointer;position:relative;-webkit-box-sizing:border-box;box-sizing:border-box;border-bottom:2px solid transparent;color:#878d99}.custom-theme .el-menu--horizontal .el-menu-item a,.custom-theme .el-menu--horizontal .el-menu-item a:hover{color:inherit}.custom-theme .el-menu--horizontal .el-menu-item:focus,.custom-theme .el-menu--horizontal .el-menu-item:hover{background-color:#fff}.custom-theme .el-menu--horizontal .el-submenu{float:left;position:relative}.custom-theme .el-menu--horizontal .el-submenu:focus{outline:0}.custom-theme .el-menu--horizontal .el-submenu:focus>.el-submenu__title{color:#2d2f33}.custom-theme .el-menu--horizontal .el-submenu>.el-menu{position:absolute;top:65px;left:0;border:none;padding:5px 0;background-color:#fff;z-index:100;min-width:100%;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);border-radius:2px}.custom-theme .el-menu--horizontal .el-submenu .el-submenu__title{height:60px;line-height:60px;border-bottom:2px solid transparent;color:#878d99}.custom-theme .el-menu--horizontal .el-submenu .el-submenu__title:hover{background-color:#fff}.custom-theme .el-menu--horizontal .el-submenu .el-menu-item{background-color:#fff;float:none;height:36px;line-height:36px;padding:0 10px}.custom-theme .el-menu--horizontal .el-submenu .el-submenu__icon-arrow{position:static;vertical-align:middle;margin-left:8px;margin-top:-3px}.custom-theme .el-menu--horizontal .el-menu-item:focus,.custom-theme .el-menu--horizontal .el-menu-item:hover,.custom-theme .el-menu--horizontal .el-submenu__title:hover{outline:0;color:#2d2f33}.custom-theme .el-menu--horizontal>.el-menu-item.is-active,.custom-theme .el-menu--horizontal>.el-submenu.is-active .el-submenu__title{border-bottom:2px solid #262729;color:#2d2f33}.custom-theme .el-menu--collapse{width:64px}.custom-theme .el-menu--collapse>.el-menu-item [class^=el-icon-],.custom-theme .el-menu--collapse>.el-submenu>.el-submenu__title [class^=el-icon-]{margin:0;vertical-align:middle;width:24px;text-align:center}.custom-theme .el-menu--collapse>.el-menu-item .el-submenu__icon-arrow,.custom-theme .el-menu--collapse>.el-submenu>.el-submenu__title .el-submenu__icon-arrow{display:none}.custom-theme .el-menu--collapse>.el-menu-item span,.custom-theme .el-menu--collapse>.el-submenu>.el-submenu__title span{height:0;width:0;overflow:hidden;visibility:hidden;display:inline-block}.custom-theme .el-menu--collapse>.el-menu-item.is-active i{color:inherit}.custom-theme .el-menu--collapse .el-menu .el-submenu{min-width:200px}.custom-theme .el-menu--collapse .el-submenu{position:relative}.custom-theme .el-menu--collapse .el-submenu .el-menu{position:absolute;margin-left:5px;top:0;left:100%;z-index:10;border:1px solid #dfe4ed;border-radius:2px;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.custom-theme .el-menu--collapse .el-submenu.is-opened>.el-submenu__title .el-submenu__icon-arrow{-webkit-transform:none;transform:none}.custom-theme .el-menu-item{height:56px;line-height:56px;font-size:14px;color:#2d2f33;padding:0 20px;cursor:pointer;position:relative;-webkit-transition:border-color .3s,background-color .3s,color .3s;transition:border-color .3s,background-color .3s,color .3s;-webkit-box-sizing:border-box;box-sizing:border-box;white-space:nowrap}.custom-theme .el-menu-item [class^=el-icon-]{margin-right:5px;width:24px;text-align:center;font-size:18px}.custom-theme .el-menu-item *{vertical-align:middle}.custom-theme .el-menu-item:first-child{margin-left:0}.custom-theme .el-menu-item:last-child{margin-right:0}.custom-theme .el-menu-item:focus,.custom-theme .el-menu-item:hover{outline:0;background-color:#e9e9ea}.custom-theme .el-menu-item i{color:#878d99}.custom-theme .el-menu-item.is-active{color:#262729}.custom-theme .el-menu-item.is-active i{color:inherit}.custom-theme .el-submenu__title{position:relative;height:56px;line-height:56px;font-size:14px;color:#2d2f33;padding:0 20px;cursor:pointer;position:relative;-webkit-transition:border-color .3s,background-color .3s,color .3s;transition:border-color .3s,background-color .3s,color .3s;-webkit-box-sizing:border-box;box-sizing:border-box;white-space:nowrap}.custom-theme .el-submenu__title *{vertical-align:middle}.custom-theme .el-submenu__title i{color:#878d99}.custom-theme .el-submenu__title:hover{background-color:#e9e9ea}.custom-theme .el-submenu .el-menu{border:none}.custom-theme .el-submenu .el-menu-item{height:50px;line-height:50px;padding:0 45px;min-width:200px}.custom-theme .el-submenu__icon-arrow{position:absolute;top:50%;right:20px;margin-top:-7px;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;font-size:12px}.custom-theme .el-submenu.is-active .el-submenu__title{border-bottom-color:#262729}.custom-theme .el-submenu.is-opened>.el-submenu__title .el-submenu__icon-arrow{-webkit-transform:rotateZ(180deg);transform:rotateZ(180deg)}.custom-theme .el-submenu [class^=el-icon-]{vertical-align:middle;margin-right:5px;width:24px;text-align:center;font-size:18px}.custom-theme .el-menu-item-group>ul{padding:0}.custom-theme .el-menu-item-group__title{padding:7px 0 7px 20px;line-height:normal;font-size:12px;color:#878d99}.custom-theme .horizontal-collapse-transition .el-submenu__title .el-submenu__icon-arrow{-webkit-transition:.2s;transition:.2s;opacity:0}.custom-theme .el-input{position:relative;font-size:14px;display:inline-block;width:100%}.custom-theme .el-input::-webkit-scrollbar{z-index:11;width:6px}.custom-theme .el-input::-webkit-scrollbar:horizontal{height:6px}.custom-theme .el-input::-webkit-scrollbar-thumb{border-radius:5px;width:6px;background:#b4bccc}.custom-theme .el-input::-webkit-scrollbar-corner{background:#fff}.custom-theme .el-input::-webkit-scrollbar-track{background:#fff}.custom-theme .el-input::-webkit-scrollbar-track-piece{background:#fff;width:6px}.custom-theme .el-input__inner{-webkit-appearance:none;background-color:#fff;background-image:none;border-radius:4px;border:1px solid #d8dce5;-webkit-box-sizing:border-box;box-sizing:border-box;color:#5a5e66;display:inline-block;font-size:inherit;height:40px;line-height:1;outline:0;padding:0 15px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1);width:100%}.custom-theme .el-input__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner::placeholder{color:#b4bccc}.custom-theme .el-input__inner:hover{border-color:#b4bccc}.custom-theme .el-input__inner:focus{outline:0;border-color:#262729}.custom-theme .el-input__suffix{position:absolute;height:100%;right:5px;top:0;text-align:center;color:#b4bccc;-webkit-transition:all .3s;transition:all .3s;pointer-events:none}.custom-theme .el-input__suffix-inner{pointer-events:all}.custom-theme .el-input__prefix{position:absolute;height:100%;left:5px;top:0;text-align:center;color:#b4bccc;-webkit-transition:all .3s;transition:all .3s}.custom-theme .el-input__icon{height:100%;width:25px;text-align:center;-webkit-transition:all .3s;transition:all .3s;line-height:40px}.custom-theme .el-input__icon:after{content:'';height:100%;width:0;display:inline-block;vertical-align:middle}.custom-theme .el-input__validateIcon{pointer-events:none}.custom-theme .el-input.is-active .el-input__inner{outline:0;border-color:#262729}.custom-theme .el-input.is-disabled .el-input__inner{background-color:#f5f7fa;border-color:#dfe4ed;color:#b4bccc;cursor:not-allowed}.custom-theme .el-input.is-disabled .el-input__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner::placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__icon{cursor:not-allowed}.custom-theme .el-input--suffix .el-input__inner{padding-right:30px}.custom-theme .el-input--prefix .el-input__inner{padding-left:30px}.custom-theme .el-input--medium{font-size:14px}.custom-theme .el-input--medium .el-input__inner{height:36px}.custom-theme .el-input--medium .el-input__icon{line-height:36px}.custom-theme .el-input--small{font-size:13px}.custom-theme .el-input--small .el-input__inner{height:32px}.custom-theme .el-input--small .el-input__icon{line-height:32px}.custom-theme .el-input--mini{font-size:12px}.custom-theme .el-input--mini .el-input__inner{height:28px}.custom-theme .el-input--mini .el-input__icon{line-height:28px}.custom-theme .el-input-group{line-height:normal;display:inline-table;width:100%;border-collapse:separate}.custom-theme .el-input-group>.el-input__inner{vertical-align:middle;display:table-cell}.custom-theme .el-input-group__append,.custom-theme .el-input-group__prepend{background-color:#f5f7fa;color:#0a76a4;vertical-align:middle;display:table-cell;position:relative;border:1px solid #d8dce5;border-radius:4px;padding:0 20px;width:1px;white-space:nowrap}.custom-theme .el-input-group__append:focus,.custom-theme .el-input-group__prepend:focus{outline:0}.custom-theme .el-input-group__append .el-button,.custom-theme .el-input-group__append .el-select,.custom-theme .el-input-group__prepend .el-button,.custom-theme .el-input-group__prepend .el-select{display:inline-block;margin:-20px}.custom-theme .el-input-group__append button.el-button,.custom-theme .el-input-group__append div.el-select .el-input__inner,.custom-theme .el-input-group__append div.el-select:hover .el-input__inner,.custom-theme .el-input-group__prepend button.el-button,.custom-theme .el-input-group__prepend div.el-select .el-input__inner,.custom-theme .el-input-group__prepend div.el-select:hover .el-input__inner{border-color:transparent;background-color:transparent;color:inherit;border-top:0;border-bottom:0}.custom-theme .el-input-group__append .el-button,.custom-theme .el-input-group__append .el-input,.custom-theme .el-input-group__prepend .el-button,.custom-theme .el-input-group__prepend .el-input{font-size:inherit}.custom-theme .el-input-group__prepend{border-right:0;border-top-right-radius:0;border-bottom-right-radius:0}.custom-theme .el-input-group__append{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.custom-theme .el-input-group--prepend .el-input__inner{border-top-left-radius:0;border-bottom-left-radius:0}.custom-theme .el-input-group--append .el-input__inner{border-top-right-radius:0;border-bottom-right-radius:0}.custom-theme .el-textarea{display:inline-block;width:100%;vertical-align:bottom}.custom-theme .el-textarea__inner{display:block;resize:vertical;padding:5px 15px;line-height:1.5;-webkit-box-sizing:border-box;box-sizing:border-box;width:100%;font-size:14px;color:#5a5e66;background-color:#fff;background-image:none;border:1px solid #d8dce5;border-radius:4px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1)}.custom-theme .el-textarea__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner::placeholder{color:#b4bccc}.custom-theme .el-textarea__inner:hover{border-color:#b4bccc}.custom-theme .el-textarea__inner:focus{outline:0;border-color:#262729}.custom-theme .el-textarea.is-disabled .el-textarea__inner{background-color:#f5f7fa;border-color:#dfe4ed;color:#b4bccc;cursor:not-allowed}.custom-theme .el-textarea.is-disabled .el-textarea__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner::placeholder{color:#b4bccc}.custom-theme .el-input{position:relative;font-size:14px;display:inline-block;width:100%}.custom-theme .el-input::-webkit-scrollbar{z-index:11;width:6px}.custom-theme .el-input::-webkit-scrollbar:horizontal{height:6px}.custom-theme .el-input::-webkit-scrollbar-thumb{border-radius:5px;width:6px;background:#b4bccc}.custom-theme .el-input::-webkit-scrollbar-corner{background:#fff}.custom-theme .el-input::-webkit-scrollbar-track{background:#fff}.custom-theme .el-input::-webkit-scrollbar-track-piece{background:#fff;width:6px}.custom-theme .el-input__inner{-webkit-appearance:none;background-color:#fff;background-image:none;border-radius:4px;border:1px solid #d8dce5;-webkit-box-sizing:border-box;box-sizing:border-box;color:#5a5e66;display:inline-block;font-size:inherit;height:40px;line-height:1;outline:0;padding:0 15px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1);width:100%}.custom-theme .el-input__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner::placeholder{color:#b4bccc}.custom-theme .el-input__inner:hover{border-color:#b4bccc}.custom-theme .el-input__inner:focus{outline:0;border-color:#262729}.custom-theme .el-input__suffix{position:absolute;height:100%;right:5px;top:0;text-align:center;color:#b4bccc;-webkit-transition:all .3s;transition:all .3s;pointer-events:none}.custom-theme .el-input__suffix-inner{pointer-events:all}.custom-theme .el-input__prefix{position:absolute;height:100%;left:5px;top:0;text-align:center;color:#b4bccc;-webkit-transition:all .3s;transition:all .3s}.custom-theme .el-input__icon{height:100%;width:25px;text-align:center;-webkit-transition:all .3s;transition:all .3s;line-height:40px}.custom-theme .el-input__icon:after{content:'';height:100%;width:0;display:inline-block;vertical-align:middle}.custom-theme .el-input__validateIcon{pointer-events:none}.custom-theme .el-input.is-active .el-input__inner{outline:0;border-color:#262729}.custom-theme .el-input.is-disabled .el-input__inner{background-color:#f5f7fa;border-color:#dfe4ed;color:#b4bccc;cursor:not-allowed}.custom-theme .el-input.is-disabled .el-input__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner::placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__icon{cursor:not-allowed}.custom-theme .el-input--suffix .el-input__inner{padding-right:30px}.custom-theme .el-input--prefix .el-input__inner{padding-left:30px}.custom-theme .el-input--medium{font-size:14px}.custom-theme .el-input--medium .el-input__inner{height:36px}.custom-theme .el-input--medium .el-input__icon{line-height:36px}.custom-theme .el-input--small{font-size:13px}.custom-theme .el-input--small .el-input__inner{height:32px}.custom-theme .el-input--small .el-input__icon{line-height:32px}.custom-theme .el-input--mini{font-size:12px}.custom-theme .el-input--mini .el-input__inner{height:28px}.custom-theme .el-input--mini .el-input__icon{line-height:28px}.custom-theme .el-input-group{line-height:normal;display:inline-table;width:100%;border-collapse:separate}.custom-theme .el-input-group>.el-input__inner{vertical-align:middle;display:table-cell}.custom-theme .el-input-group__append,.custom-theme .el-input-group__prepend{background-color:#f5f7fa;color:#0a76a4;vertical-align:middle;display:table-cell;position:relative;border:1px solid #d8dce5;border-radius:4px;padding:0 20px;width:1px;white-space:nowrap}.custom-theme .el-input-group__append:focus,.custom-theme .el-input-group__prepend:focus{outline:0}.custom-theme .el-input-group__append .el-button,.custom-theme .el-input-group__append .el-select,.custom-theme .el-input-group__prepend .el-button,.custom-theme .el-input-group__prepend .el-select{display:inline-block;margin:-20px}.custom-theme .el-input-group__append button.el-button,.custom-theme .el-input-group__append div.el-select .el-input__inner,.custom-theme .el-input-group__append div.el-select:hover .el-input__inner,.custom-theme .el-input-group__prepend button.el-button,.custom-theme .el-input-group__prepend div.el-select .el-input__inner,.custom-theme .el-input-group__prepend div.el-select:hover .el-input__inner{border-color:transparent;background-color:transparent;color:inherit;border-top:0;border-bottom:0}.custom-theme .el-input-group__append .el-button,.custom-theme .el-input-group__append .el-input,.custom-theme .el-input-group__prepend .el-button,.custom-theme .el-input-group__prepend .el-input{font-size:inherit}.custom-theme .el-input-group__prepend{border-right:0;border-top-right-radius:0;border-bottom-right-radius:0}.custom-theme .el-input-group__append{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.custom-theme .el-input-group--prepend .el-input__inner{border-top-left-radius:0;border-bottom-left-radius:0}.custom-theme .el-input-group--append .el-input__inner{border-top-right-radius:0;border-bottom-right-radius:0}.custom-theme .el-textarea{display:inline-block;width:100%;vertical-align:bottom}.custom-theme .el-textarea__inner{display:block;resize:vertical;padding:5px 15px;line-height:1.5;-webkit-box-sizing:border-box;box-sizing:border-box;width:100%;font-size:14px;color:#5a5e66;background-color:#fff;background-image:none;border:1px solid #d8dce5;border-radius:4px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1)}.custom-theme .el-textarea__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner::placeholder{color:#b4bccc}.custom-theme .el-textarea__inner:hover{border-color:#b4bccc}.custom-theme .el-textarea__inner:focus{outline:0;border-color:#262729}.custom-theme .el-textarea.is-disabled .el-textarea__inner{background-color:#f5f7fa;border-color:#dfe4ed;color:#b4bccc;cursor:not-allowed}.custom-theme .el-textarea.is-disabled .el-textarea__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner::placeholder{color:#b4bccc}.custom-theme .el-input-number{position:relative;display:inline-block;width:180px;line-height:38px}.custom-theme .el-input-number .el-input{display:block}.custom-theme .el-input-number .el-input__inner{-webkit-appearance:none;padding-left:50px;padding-right:50px;text-align:center}.custom-theme .el-input-number__decrease,.custom-theme .el-input-number__increase{position:absolute;z-index:1;top:1px;width:40px;height:auto;text-align:center;background:#f5f7fa;color:#5a5e66;cursor:pointer;font-size:13px}.custom-theme .el-input-number__decrease:hover,.custom-theme .el-input-number__increase:hover{color:#262729}.custom-theme .el-input-number__decrease:hover:not(.is-disabled)~.el-input .el-input__inner:not(.is-disabled),.custom-theme .el-input-number__increase:hover:not(.is-disabled)~.el-input .el-input__inner:not(.is-disabled){border-color:#262729}.custom-theme .el-input-number__decrease.is-disabled,.custom-theme .el-input-number__increase.is-disabled{color:#b4bccc;cursor:not-allowed}.custom-theme .el-input-number__increase{right:1px;border-radius:0 4px 4px 0;border-left:1px solid #d8dce5}.custom-theme .el-input-number__decrease{left:1px;border-radius:4px 0 0 4px;border-right:1px solid #d8dce5}.custom-theme .el-input-number.is-disabled .el-input-number__decrease,.custom-theme .el-input-number.is-disabled .el-input-number__increase{border-color:#dfe4ed;color:#dfe4ed}.custom-theme .el-input-number.is-disabled .el-input-number__decrease:hover,.custom-theme .el-input-number.is-disabled .el-input-number__increase:hover{color:#dfe4ed;cursor:not-allowed}.custom-theme .el-input-number--medium{width:200px;line-height:34px}.custom-theme .el-input-number--medium .el-input-number__decrease,.custom-theme .el-input-number--medium .el-input-number__increase{width:36px;font-size:14px}.custom-theme .el-input-number--medium .el-input__inner{padding-left:43px;padding-right:43px}.custom-theme .el-input-number--small{width:130px;line-height:30px}.custom-theme .el-input-number--small .el-input-number__decrease,.custom-theme .el-input-number--small .el-input-number__increase{width:32px;font-size:13px}.custom-theme .el-input-number--small .el-input-number__decrease [class*=el-icon],.custom-theme .el-input-number--small .el-input-number__increase [class*=el-icon]{-webkit-transform:scale(.9);transform:scale(.9)}.custom-theme .el-input-number--small .el-input__inner{padding-left:39px;padding-right:39px}.custom-theme .el-input-number--mini{width:130px;line-height:26px}.custom-theme .el-input-number--mini .el-input-number__decrease,.custom-theme .el-input-number--mini .el-input-number__increase{width:28px;font-size:12px}.custom-theme .el-input-number--mini .el-input-number__decrease [class*=el-icon],.custom-theme .el-input-number--mini .el-input-number__increase [class*=el-icon]{-webkit-transform:scale(.8);transform:scale(.8)}.custom-theme .el-input-number--mini .el-input__inner{padding-left:35px;padding-right:35px}.custom-theme .el-input-number.is-without-controls .el-input__inner{padding-left:15px;padding-right:15px}.custom-theme .el-input-number.is-controls-right .el-input__inner{padding-left:15px;padding-right:50px}.custom-theme .el-input-number.is-controls-right .el-input-number__decrease,.custom-theme .el-input-number.is-controls-right .el-input-number__increase{height:auto;line-height:19px}.custom-theme .el-input-number.is-controls-right .el-input-number__decrease [class*=el-icon],.custom-theme .el-input-number.is-controls-right .el-input-number__increase [class*=el-icon]{-webkit-transform:scale(.8);transform:scale(.8)}.custom-theme .el-input-number.is-controls-right .el-input-number__increase{border-radius:0 4px 0 0;border-bottom:1px solid #d8dce5}.custom-theme .el-input-number.is-controls-right .el-input-number__decrease{right:1px;bottom:1px;top:auto;left:auto;border-right:none;border-left:1px solid #d8dce5;border-radius:0 0 4px 0}.custom-theme .el-input-number.is-controls-right[class*=medium] [class*=decrease],.custom-theme .el-input-number.is-controls-right[class*=medium] [class*=increase]{line-height:17px}.custom-theme .el-input-number.is-controls-right[class*=small] [class*=decrease],.custom-theme .el-input-number.is-controls-right[class*=small] [class*=increase]{line-height:15px}.custom-theme .el-input-number.is-controls-right[class*=mini] [class*=decrease],.custom-theme .el-input-number.is-controls-right[class*=mini] [class*=increase]{line-height:13px}.custom-theme .el-radio{color:#5a5e66;font-weight:500;line-height:1;position:relative;cursor:pointer;display:inline-block;white-space:nowrap;outline:0;font-size:14px;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}.custom-theme .el-radio.is-bordered{padding:10px 20px 10px 10px;border-radius:4px;border:1px solid #d8dce5}.custom-theme .el-radio.is-bordered.is-checked{border-color:#262729}.custom-theme .el-radio.is-bordered.is-disabled{cursor:not-allowed;border-color:#e6ebf5}.custom-theme .el-radio.is-bordered+.el-radio.is-bordered{margin-left:10px}.custom-theme .el-radio--medium.is-bordered{padding:8px 20px 8px 10px;border-radius:4px}.custom-theme .el-radio--medium.is-bordered .el-radio__label{font-size:14px}.custom-theme .el-radio--medium.is-bordered .el-radio__inner{height:14px;width:14px}.custom-theme .el-radio--small.is-bordered{padding:6px 15px 6px 10px;border-radius:3px}.custom-theme .el-radio--small.is-bordered .el-radio__label{font-size:12px}.custom-theme .el-radio--small.is-bordered .el-radio__inner{height:12px;width:12px}.custom-theme .el-radio--mini.is-bordered{padding:4px 15px 4px 10px;border-radius:3px}.custom-theme .el-radio--mini.is-bordered .el-radio__label{font-size:12px}.custom-theme .el-radio--mini.is-bordered .el-radio__inner{height:12px;width:12px}.custom-theme .el-radio+.el-radio{margin-left:30px}.custom-theme .el-radio__input{white-space:nowrap;cursor:pointer;outline:0;display:inline-block;line-height:1;position:relative;vertical-align:middle}.custom-theme .el-radio__input.is-disabled .el-radio__inner{background-color:#f5f7fa;border-color:#dfe4ed;cursor:not-allowed}.custom-theme .el-radio__input.is-disabled .el-radio__inner::after{cursor:not-allowed;background-color:#f5f7fa}.custom-theme .el-radio__input.is-disabled .el-radio__inner+.el-radio__label{cursor:not-allowed}.custom-theme .el-radio__input.is-disabled.is-checked .el-radio__inner{background-color:#f5f7fa;border-color:#dfe4ed}.custom-theme .el-radio__input.is-disabled.is-checked .el-radio__inner::after{background-color:#b4bccc}.custom-theme .el-radio__input.is-disabled+span.el-radio__label{color:#b4bccc;cursor:not-allowed}.custom-theme .el-radio__input.is-checked .el-radio__inner{border-color:#262729;background:#262729}.custom-theme .el-radio__input.is-checked .el-radio__inner::after{-webkit-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}.custom-theme .el-radio__input.is-checked+.el-radio__label{color:#262729}.custom-theme .el-radio__input.is-focus .el-radio__inner{border-color:#262729}.custom-theme .el-radio__inner{border:1px solid #d8dce5;border-radius:100%;width:14px;height:14px;background-color:#fff;position:relative;cursor:pointer;display:inline-block;-webkit-box-sizing:border-box;box-sizing:border-box}.custom-theme .el-radio__inner:hover{border-color:#262729}.custom-theme .el-radio__inner::after{width:4px;height:4px;border-radius:100%;background-color:#fff;content:"";position:absolute;left:50%;top:50%;-webkit-transform:translate(-50%,-50%) scale(0);transform:translate(-50%,-50%) scale(0);-webkit-transition:-webkit-transform .15s cubic-bezier(.71,-.46,.88,.6);transition:-webkit-transform .15s cubic-bezier(.71,-.46,.88,.6);transition:transform .15s cubic-bezier(.71,-.46,.88,.6);transition:transform .15s cubic-bezier(.71,-.46,.88,.6),-webkit-transform .15s cubic-bezier(.71,-.46,.88,.6)}.custom-theme .el-radio__original{opacity:0;outline:0;position:absolute;z-index:-1;top:0;left:0;right:0;bottom:0;margin:0}.custom-theme .el-radio:focus:not(.is-focus):not(:active) .el-radio__inner{-webkit-box-shadow:0 0 2px 2px #262729;box-shadow:0 0 2px 2px #262729}.custom-theme .el-radio__label{font-size:14px;padding-left:10px}.custom-theme .el-radio-group{display:inline-block;line-height:1;vertical-align:middle;font-size:0}.custom-theme .el-radio-button{position:relative;display:inline-block;outline:0}.custom-theme .el-radio-button__inner{display:inline-block;line-height:1;white-space:nowrap;vertical-align:middle;background:#fff;border:1px solid #d8dce5;font-weight:500;border-left:0;color:#5a5e66;-webkit-appearance:none;text-align:center;-webkit-box-sizing:border-box;box-sizing:border-box;outline:0;margin:0;position:relative;cursor:pointer;-webkit-transition:all .3s cubic-bezier(.645,.045,.355,1);transition:all .3s cubic-bezier(.645,.045,.355,1);padding:12px 20px;font-size:14px;border-radius:0}.custom-theme .el-radio-button__inner.is-round{padding:12px 20px}.custom-theme .el-radio-button__inner:hover{color:#262729}.custom-theme .el-radio-button__inner [class*=el-icon-]{line-height:.9}.custom-theme .el-radio-button__inner [class*=el-icon-]+span{margin-left:5px}.custom-theme .el-radio-button__orig-radio{opacity:0;outline:0;position:absolute;z-index:-1;left:-999px}.custom-theme .el-radio-button__orig-radio:checked+.el-radio-button__inner{color:#fff;background-color:#262729;border-color:#262729;-webkit-box-shadow:-1px 0 0 0 #262729;box-shadow:-1px 0 0 0 #262729}.custom-theme .el-radio-button__orig-radio:disabled+.el-radio-button__inner{color:#b4bccc;cursor:not-allowed;background-image:none;background-color:#fff;border-color:#e6ebf5;-webkit-box-shadow:none;box-shadow:none}.custom-theme .el-radio-button__orig-radio:disabled:checked+.el-radio-button__inner{background-color:#edf2fc}.custom-theme .el-radio-button:first-child .el-radio-button__inner{border-left:1px solid #d8dce5;border-radius:4px 0 0 4px;-webkit-box-shadow:none!important;box-shadow:none!important}.custom-theme .el-radio-button:last-child .el-radio-button__inner{border-radius:0 4px 4px 0}.custom-theme .el-radio-button:first-child:last-child .el-radio-button__inner{border-radius:4px}.custom-theme .el-radio-button--medium .el-radio-button__inner{padding:10px 20px;font-size:14px;border-radius:0}.custom-theme .el-radio-button--medium .el-radio-button__inner.is-round{padding:10px 20px}.custom-theme .el-radio-button--small .el-radio-button__inner{padding:9px 15px;font-size:12px;border-radius:0}.custom-theme .el-radio-button--small .el-radio-button__inner.is-round{padding:9px 15px}.custom-theme .el-radio-button--mini .el-radio-button__inner{padding:7px 15px;font-size:12px;border-radius:0}.custom-theme .el-radio-button--mini .el-radio-button__inner.is-round{padding:7px 15px}.custom-theme .el-radio-button:focus:not(.is-focus):not(:active){-webkit-box-shadow:0 0 2px 2px #262729;box-shadow:0 0 2px 2px #262729}.custom-theme .el-checkbox{color:#5a5e66;font-weight:500;font-size:14px;position:relative;cursor:pointer;display:inline-block;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.custom-theme .el-checkbox.is-bordered{padding:9px 20px 9px 10px;border-radius:4px;border:1px solid #d8dce5}.custom-theme .el-checkbox.is-bordered.is-checked{border-color:#262729}.custom-theme .el-checkbox.is-bordered.is-disabled{border-color:#e6ebf5;cursor:not-allowed}.custom-theme .el-checkbox.is-bordered+.el-checkbox.is-bordered{margin-left:10px}.custom-theme .el-checkbox.is-bordered.el-checkbox--medium{padding:7px 20px 7px 10px;border-radius:4px}.custom-theme .el-checkbox.is-bordered.el-checkbox--medium .el-checkbox__label{line-height:17px;font-size:14px}.custom-theme .el-checkbox.is-bordered.el-checkbox--medium .el-checkbox__inner{height:14px;width:14px}.custom-theme .el-checkbox.is-bordered.el-checkbox--small{padding:3px 15px 7px 10px;border-radius:3px}.custom-theme .el-checkbox.is-bordered.el-checkbox--small .el-checkbox__label{line-height:15px;font-size:12px}.custom-theme .el-checkbox.is-bordered.el-checkbox--small .el-checkbox__inner{height:12px;width:12px}.custom-theme .el-checkbox.is-bordered.el-checkbox--small .el-checkbox__inner::after{height:6px;width:2px}.custom-theme .el-checkbox.is-bordered.el-checkbox--mini{padding:1px 15px 5px 10px;border-radius:3px}.custom-theme .el-checkbox.is-bordered.el-checkbox--mini .el-checkbox__label{line-height:12px;font-size:12px}.custom-theme .el-checkbox.is-bordered.el-checkbox--mini .el-checkbox__inner{height:12px;width:12px}.custom-theme .el-checkbox.is-bordered.el-checkbox--mini .el-checkbox__inner::after{height:6px;width:2px}.custom-theme .el-checkbox__input{white-space:nowrap;cursor:pointer;outline:0;display:inline-block;line-height:1;position:relative;vertical-align:middle}.custom-theme .el-checkbox__input.is-disabled .el-checkbox__inner{background-color:#edf2fc;border-color:#d8dce5;cursor:not-allowed}.custom-theme .el-checkbox__input.is-disabled .el-checkbox__inner::after{cursor:not-allowed;border-color:#b4bccc}.custom-theme .el-checkbox__input.is-disabled .el-checkbox__inner+.el-checkbox__label{cursor:not-allowed}.custom-theme .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner{background-color:#edf2fc;border-color:#d8dce5}.custom-theme .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner::after{border-color:#b4bccc}.custom-theme .el-checkbox__input.is-disabled.is-indeterminate .el-checkbox__inner{background-color:#edf2fc;border-color:#d8dce5}.custom-theme .el-checkbox__input.is-disabled.is-indeterminate .el-checkbox__inner::before{background-color:#b4bccc;border-color:#b4bccc}.custom-theme .el-checkbox__input.is-disabled+span.el-checkbox__label{color:#b4bccc;cursor:not-allowed}.custom-theme .el-checkbox__input.is-checked .el-checkbox__inner{background-color:#262729;border-color:#262729}.custom-theme .el-checkbox__input.is-checked .el-checkbox__inner::after{-webkit-transform:rotate(45deg) scaleY(1);transform:rotate(45deg) scaleY(1)}.custom-theme .el-checkbox__input.is-checked+.el-checkbox__label{color:#262729}.custom-theme .el-checkbox__input.is-focus .el-checkbox__inner{border-color:#262729}.custom-theme .el-checkbox__input.is-indeterminate .el-checkbox__inner{background-color:#262729;border-color:#262729}.custom-theme .el-checkbox__input.is-indeterminate .el-checkbox__inner::before{content:'';position:absolute;display:block;background-color:#fff;height:2px;-webkit-transform:scale(.5);transform:scale(.5);left:0;right:0;top:5px}.custom-theme .el-checkbox__input.is-indeterminate .el-checkbox__inner::after{display:none}.custom-theme .el-checkbox__inner{display:inline-block;position:relative;border:1px solid #d8dce5;border-radius:2px;-webkit-box-sizing:border-box;box-sizing:border-box;width:14px;height:14px;background-color:#fff;z-index:1;-webkit-transition:border-color .25s cubic-bezier(.71,-.46,.29,1.46),background-color .25s cubic-bezier(.71,-.46,.29,1.46);transition:border-color .25s cubic-bezier(.71,-.46,.29,1.46),background-color .25s cubic-bezier(.71,-.46,.29,1.46)}.custom-theme .el-checkbox__inner:hover{border-color:#262729}.custom-theme .el-checkbox__inner::after{-webkit-box-sizing:content-box;box-sizing:content-box;content:"";border:1px solid #fff;border-left:0;border-top:0;height:7px;left:4px;position:absolute;top:1px;-webkit-transform:rotate(45deg) scaleY(0);transform:rotate(45deg) scaleY(0);width:3px;-webkit-transition:-webkit-transform .15s cubic-bezier(.71,-.46,.88,.6) 50ms;transition:-webkit-transform .15s cubic-bezier(.71,-.46,.88,.6) 50ms;transition:transform .15s cubic-bezier(.71,-.46,.88,.6) 50ms;transition:transform .15s cubic-bezier(.71,-.46,.88,.6) 50ms,-webkit-transform .15s cubic-bezier(.71,-.46,.88,.6) 50ms;-webkit-transform-origin:center;transform-origin:center}.custom-theme .el-checkbox__original{opacity:0;outline:0;position:absolute;margin:0;width:0;height:0;left:-999px}.custom-theme .el-checkbox__label{display:inline-block;padding-left:10px;line-height:19px;font-size:14px}.custom-theme .el-checkbox+.el-checkbox{margin-left:30px}.custom-theme .el-checkbox-button{position:relative;display:inline-block}.custom-theme .el-checkbox-button__inner{display:inline-block;line-height:1;font-weight:500;white-space:nowrap;vertical-align:middle;cursor:pointer;background:#fff;border:1px solid #d8dce5;border-left:0;color:#5a5e66;-webkit-appearance:none;text-align:center;-webkit-box-sizing:border-box;box-sizing:border-box;outline:0;margin:0;position:relative;-webkit-transition:all .3s cubic-bezier(.645,.045,.355,1);transition:all .3s cubic-bezier(.645,.045,.355,1);-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;padding:12px 20px;font-size:14px;border-radius:0}.custom-theme .el-checkbox-button__inner.is-round{padding:12px 20px}.custom-theme .el-checkbox-button__inner:hover{color:#262729}.custom-theme .el-checkbox-button__inner [class*=el-icon-]{line-height:.9}.custom-theme .el-checkbox-button__inner [class*=el-icon-]+span{margin-left:5px}.custom-theme .el-checkbox-button__original{opacity:0;outline:0;position:absolute;margin:0;left:-999px}.custom-theme .el-checkbox-button.is-checked .el-checkbox-button__inner{color:#fff;background-color:#262729;border-color:#262729;-webkit-box-shadow:-1px 0 0 0 #7d7d7f;box-shadow:-1px 0 0 0 #7d7d7f}.custom-theme .el-checkbox-button.is-disabled .el-checkbox-button__inner{color:#b4bccc;cursor:not-allowed;background-image:none;background-color:#fff;border-color:#e6ebf5;-webkit-box-shadow:none;box-shadow:none}.custom-theme .el-checkbox-button:first-child .el-checkbox-button__inner{border-left:1px solid #d8dce5;border-radius:4px 0 0 4px;-webkit-box-shadow:none!important;box-shadow:none!important}.custom-theme .el-checkbox-button.is-focus .el-checkbox-button__inner{border-color:#262729}.custom-theme .el-checkbox-button:last-child .el-checkbox-button__inner{border-radius:0 4px 4px 0}.custom-theme .el-checkbox-button--medium .el-checkbox-button__inner{padding:10px 20px;font-size:14px;border-radius:0}.custom-theme .el-checkbox-button--medium .el-checkbox-button__inner.is-round{padding:10px 20px}.custom-theme .el-checkbox-button--small .el-checkbox-button__inner{padding:9px 15px;font-size:12px;border-radius:0}.custom-theme .el-checkbox-button--small .el-checkbox-button__inner.is-round{padding:9px 15px}.custom-theme .el-checkbox-button--mini .el-checkbox-button__inner{padding:7px 15px;font-size:12px;border-radius:0}.custom-theme .el-checkbox-button--mini .el-checkbox-button__inner.is-round{padding:7px 15px}.custom-theme .el-checkbox-group{font-size:0}.custom-theme .el-switch{display:inline-block;position:relative;font-size:14px;line-height:20px;height:20px;vertical-align:middle}.custom-theme .el-switch.is-disabled .el-switch__core,.custom-theme .el-switch.is-disabled .el-switch__label{cursor:not-allowed}.custom-theme .el-switch__label{-webkit-transition:.2s;transition:.2s;height:20px;display:inline-block;font-size:14px;font-weight:500;cursor:pointer;vertical-align:middle;color:#2d2f33}.custom-theme .el-switch__label.is-active{color:#262729}.custom-theme .el-switch__label--left{margin-right:10px}.custom-theme .el-switch__label--right{margin-left:10px}.custom-theme .el-switch__label *{line-height:1;font-size:14px;display:inline-block}.custom-theme .el-switch__input{position:absolute;width:0;height:0;opacity:0;margin:0}.custom-theme .el-switch__input:focus~.el-switch__core{outline:1px solid #262729}.custom-theme .el-switch__core{margin:0;display:inline-block;position:relative;width:40px;height:20px;border:1px solid #d8dce5;outline:0;border-radius:10px;-webkit-box-sizing:border-box;box-sizing:border-box;background:#d8dce5;cursor:pointer;-webkit-transition:border-color .3s,background-color .3s;transition:border-color .3s,background-color .3s;vertical-align:middle}.custom-theme .el-switch__core .el-switch__button{position:absolute;top:1px;left:1px;border-radius:100%;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;width:16px;height:16px;background-color:#fff}.custom-theme .el-switch.is-checked .el-switch__core{border-color:#262729;background-color:#262729}.custom-theme .el-switch.is-disabled{opacity:.6}.custom-theme .el-switch--wide .el-switch__label.el-switch__label--left span{left:10px}.custom-theme .el-switch--wide .el-switch__label.el-switch__label--right span{right:10px}.custom-theme .el-switch .label-fade-enter,.custom-theme .el-switch .label-fade-leave-active{opacity:0}.custom-theme .el-popper .popper__arrow,.custom-theme .el-popper .popper__arrow::after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.custom-theme .el-popper .popper__arrow{border-width:6px;-webkit-filter:drop-shadow(0 2px 12px rgba(0, 0, 0, .03));filter:drop-shadow(0 2px 12px rgba(0, 0, 0, .03))}.custom-theme .el-popper .popper__arrow::after{content:" ";border-width:6px}.custom-theme .el-popper[x-placement^=top]{margin-bottom:12px}.custom-theme .el-popper[x-placement^=top] .popper__arrow{bottom:-6px;left:50%;margin-right:3px;border-top-color:#e6ebf5;border-bottom-width:0}.custom-theme .el-popper[x-placement^=top] .popper__arrow::after{bottom:1px;margin-left:-6px;border-top-color:#fff;border-bottom-width:0}.custom-theme .el-popper[x-placement^=bottom]{margin-top:12px}.custom-theme .el-popper[x-placement^=bottom] .popper__arrow{top:-6px;left:50%;margin-right:3px;border-top-width:0;border-bottom-color:#e6ebf5}.custom-theme .el-popper[x-placement^=bottom] .popper__arrow::after{top:1px;margin-left:-6px;border-top-width:0;border-bottom-color:#fff}.custom-theme .el-popper[x-placement^=right]{margin-left:12px}.custom-theme .el-popper[x-placement^=right] .popper__arrow{top:50%;left:-6px;margin-bottom:3px;border-right-color:#e6ebf5;border-left-width:0}.custom-theme .el-popper[x-placement^=right] .popper__arrow::after{bottom:-6px;left:1px;border-right-color:#fff;border-left-width:0}.custom-theme .el-popper[x-placement^=left]{margin-right:12px}.custom-theme .el-popper[x-placement^=left] .popper__arrow{top:50%;right:-6px;margin-bottom:3px;border-right-width:0;border-left-color:#e6ebf5}.custom-theme .el-popper[x-placement^=left] .popper__arrow::after{right:1px;bottom:-6px;margin-left:-6px;border-right-width:0;border-left-color:#fff}.custom-theme .el-select-dropdown{position:absolute;z-index:1001;border:solid 1px #dfe4ed;border-radius:4px;background-color:#fff;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);-webkit-box-sizing:border-box;box-sizing:border-box;margin:5px 0}.custom-theme .el-select-dropdown.is-multiple .el-select-dropdown__item.selected{color:#262729;background-color:#fff}.custom-theme .el-select-dropdown.is-multiple .el-select-dropdown__item.selected.hover{background-color:#f5f7fa}.custom-theme .el-select-dropdown.is-multiple .el-select-dropdown__item.selected::after{position:absolute;right:20px;font-family:element-icons;content:"\E611";font-size:12px;font-weight:700;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.custom-theme .el-select-dropdown .el-scrollbar.is-empty .el-select-dropdown__list{padding:0}.custom-theme .el-select-dropdown .popper__arrow{-webkit-transform:translateX(-400%);transform:translateX(-400%)}.custom-theme .el-select-dropdown.is-arrow-fixed .popper__arrow{-webkit-transform:translateX(-200%);transform:translateX(-200%)}.custom-theme .el-select-dropdown__empty{padding:10px 0;margin:0;text-align:center;color:#999;font-size:14px}.custom-theme .el-select-dropdown__wrap{max-height:274px}.custom-theme .el-select-dropdown__list{list-style:none;padding:6px 0;margin:0;-webkit-box-sizing:border-box;box-sizing:border-box}.custom-theme .el-input{position:relative;font-size:14px;display:inline-block;width:100%}.custom-theme .el-input::-webkit-scrollbar{z-index:11;width:6px}.custom-theme .el-input::-webkit-scrollbar:horizontal{height:6px}.custom-theme .el-input::-webkit-scrollbar-thumb{border-radius:5px;width:6px;background:#b4bccc}.custom-theme .el-input::-webkit-scrollbar-corner{background:#fff}.custom-theme .el-input::-webkit-scrollbar-track{background:#fff}.custom-theme .el-input::-webkit-scrollbar-track-piece{background:#fff;width:6px}.custom-theme .el-input__inner{-webkit-appearance:none;background-color:#fff;background-image:none;border-radius:4px;border:1px solid #d8dce5;-webkit-box-sizing:border-box;box-sizing:border-box;color:#5a5e66;display:inline-block;font-size:inherit;height:40px;line-height:1;outline:0;padding:0 15px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1);width:100%}.custom-theme .el-input__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner::placeholder{color:#b4bccc}.custom-theme .el-input__inner:hover{border-color:#b4bccc}.custom-theme .el-input__inner:focus{outline:0;border-color:#262729}.custom-theme .el-input__suffix{position:absolute;height:100%;right:5px;top:0;text-align:center;color:#b4bccc;-webkit-transition:all .3s;transition:all .3s;pointer-events:none}.custom-theme .el-input__suffix-inner{pointer-events:all}.custom-theme .el-input__prefix{position:absolute;height:100%;left:5px;top:0;text-align:center;color:#b4bccc;-webkit-transition:all .3s;transition:all .3s}.custom-theme .el-input__icon{height:100%;width:25px;text-align:center;-webkit-transition:all .3s;transition:all .3s;line-height:40px}.custom-theme .el-input__icon:after{content:'';height:100%;width:0;display:inline-block;vertical-align:middle}.custom-theme .el-input__validateIcon{pointer-events:none}.custom-theme .el-input.is-active .el-input__inner{outline:0;border-color:#262729}.custom-theme .el-input.is-disabled .el-input__inner{background-color:#f5f7fa;border-color:#dfe4ed;color:#b4bccc;cursor:not-allowed}.custom-theme .el-input.is-disabled .el-input__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner::placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__icon{cursor:not-allowed}.custom-theme .el-input--suffix .el-input__inner{padding-right:30px}.custom-theme .el-input--prefix .el-input__inner{padding-left:30px}.custom-theme .el-input--medium{font-size:14px}.custom-theme .el-input--medium .el-input__inner{height:36px}.custom-theme .el-input--medium .el-input__icon{line-height:36px}.custom-theme .el-input--small{font-size:13px}.custom-theme .el-input--small .el-input__inner{height:32px}.custom-theme .el-input--small .el-input__icon{line-height:32px}.custom-theme .el-input--mini{font-size:12px}.custom-theme .el-input--mini .el-input__inner{height:28px}.custom-theme .el-input--mini .el-input__icon{line-height:28px}.custom-theme .el-input-group{line-height:normal;display:inline-table;width:100%;border-collapse:separate}.custom-theme .el-input-group>.el-input__inner{vertical-align:middle;display:table-cell}.custom-theme .el-input-group__append,.custom-theme .el-input-group__prepend{background-color:#f5f7fa;color:#0a76a4;vertical-align:middle;display:table-cell;position:relative;border:1px solid #d8dce5;border-radius:4px;padding:0 20px;width:1px;white-space:nowrap}.custom-theme .el-input-group__append:focus,.custom-theme .el-input-group__prepend:focus{outline:0}.custom-theme .el-input-group__append .el-button,.custom-theme .el-input-group__append .el-select,.custom-theme .el-input-group__prepend .el-button,.custom-theme .el-input-group__prepend .el-select{display:inline-block;margin:-20px}.custom-theme .el-input-group__append button.el-button,.custom-theme .el-input-group__append div.el-select .el-input__inner,.custom-theme .el-input-group__append div.el-select:hover .el-input__inner,.custom-theme .el-input-group__prepend button.el-button,.custom-theme .el-input-group__prepend div.el-select .el-input__inner,.custom-theme .el-input-group__prepend div.el-select:hover .el-input__inner{border-color:transparent;background-color:transparent;color:inherit;border-top:0;border-bottom:0}.custom-theme .el-input-group__append .el-button,.custom-theme .el-input-group__append .el-input,.custom-theme .el-input-group__prepend .el-button,.custom-theme .el-input-group__prepend .el-input{font-size:inherit}.custom-theme .el-input-group__prepend{border-right:0;border-top-right-radius:0;border-bottom-right-radius:0}.custom-theme .el-input-group__append{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.custom-theme .el-input-group--prepend .el-input__inner{border-top-left-radius:0;border-bottom-left-radius:0}.custom-theme .el-input-group--append .el-input__inner{border-top-right-radius:0;border-bottom-right-radius:0}.custom-theme .el-textarea{display:inline-block;width:100%;vertical-align:bottom}.custom-theme .el-textarea__inner{display:block;resize:vertical;padding:5px 15px;line-height:1.5;-webkit-box-sizing:border-box;box-sizing:border-box;width:100%;font-size:14px;color:#5a5e66;background-color:#fff;background-image:none;border:1px solid #d8dce5;border-radius:4px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1)}.custom-theme .el-textarea__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner::placeholder{color:#b4bccc}.custom-theme .el-textarea__inner:hover{border-color:#b4bccc}.custom-theme .el-textarea__inner:focus{outline:0;border-color:#262729}.custom-theme .el-textarea.is-disabled .el-textarea__inner{background-color:#f5f7fa;border-color:#dfe4ed;color:#b4bccc;cursor:not-allowed}.custom-theme .el-textarea.is-disabled .el-textarea__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner::placeholder{color:#b4bccc}.custom-theme .el-tag{background-color:rgba(38,39,41,.1);display:inline-block;padding:0 10px;height:32px;line-height:30px;font-size:12px;color:#262729;border-radius:4px;-webkit-box-sizing:border-box;box-sizing:border-box;border:1px solid rgba(38,39,41,.2);white-space:nowrap}.custom-theme .el-tag .el-icon-close{border-radius:50%;text-align:center;position:relative;cursor:pointer;font-size:12px;height:18px;width:18px;line-height:18px;vertical-align:middle;top:-1px;right:-5px;color:#262729}.custom-theme .el-tag .el-icon-close::before{display:block}.custom-theme .el-tag .el-icon-close:hover{background-color:#262729;color:#fff}.custom-theme .el-tag--info{background-color:rgba(10,118,164,.1);border-color:rgba(10,118,164,.2);color:#0a76a4}.custom-theme .el-tag--info.is-hit{border-color:#0a76a4}.custom-theme .el-tag--info .el-tag__close{color:#0a76a4}.custom-theme .el-tag--info .el-tag__close:hover{background-color:#0a76a4;color:#fff}.custom-theme .el-tag--success{background-color:rgba(64,145,103,.1);border-color:rgba(64,145,103,.2);color:#409167}.custom-theme .el-tag--success.is-hit{border-color:#409167}.custom-theme .el-tag--success .el-tag__close{color:#409167}.custom-theme .el-tag--success .el-tag__close:hover{background-color:#409167;color:#fff}.custom-theme .el-tag--warning{background-color:rgba(157,164,8,.1);border-color:rgba(157,164,8,.2);color:#9da408}.custom-theme .el-tag--warning.is-hit{border-color:#9da408}.custom-theme .el-tag--warning .el-tag__close{color:#9da408}.custom-theme .el-tag--warning .el-tag__close:hover{background-color:#9da408;color:#fff}.custom-theme .el-tag--danger{background-color:rgba(179,69,14,.1);border-color:rgba(179,69,14,.2);color:#b3450e}.custom-theme .el-tag--danger.is-hit{border-color:#b3450e}.custom-theme .el-tag--danger .el-tag__close{color:#b3450e}.custom-theme .el-tag--danger .el-tag__close:hover{background-color:#b3450e;color:#fff}.custom-theme .el-tag--medium{height:28px;line-height:26px}.custom-theme .el-tag--medium .el-icon-close{-webkit-transform:scale(.8);transform:scale(.8)}.custom-theme .el-tag--small{height:24px;padding:0 8px;line-height:22px}.custom-theme .el-tag--small .el-icon-close{-webkit-transform:scale(.8);transform:scale(.8)}.custom-theme .el-tag--mini{height:20px;padding:0 5px;line-height:19px}.custom-theme .el-tag--mini .el-icon-close{margin-left:-3px;-webkit-transform:scale(.7);transform:scale(.7)}.custom-theme .el-select-dropdown__item{font-size:14px;padding:0 20px;position:relative;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#5a5e66;height:34px;line-height:34px;-webkit-box-sizing:border-box;box-sizing:border-box;cursor:pointer}.custom-theme .el-select-dropdown__item.is-disabled{color:#b4bccc;cursor:not-allowed}.custom-theme .el-select-dropdown__item.is-disabled:hover{background-color:#fff}.custom-theme .el-select-dropdown__item.hover,.custom-theme .el-select-dropdown__item:hover{background-color:#f5f7fa}.custom-theme .el-select-dropdown__item.selected{color:#262729;font-weight:700}.custom-theme .el-select-dropdown__item span{line-height:34px!important}.custom-theme .el-select-group{margin:0;padding:0}.custom-theme .el-select-group__wrap{position:relative;list-style:none;margin:0;padding:0}.custom-theme .el-select-group__wrap:not(:last-of-type){padding-bottom:24px}.custom-theme .el-select-group__wrap:not(:last-of-type)::after{content:'';position:absolute;display:block;left:20px;right:20px;bottom:12px;height:1px;background:#dfe4ed}.custom-theme .el-select-group__title{padding-left:20px;font-size:12px;color:#0a76a4;line-height:30px}.custom-theme .el-select-group .el-select-dropdown__item{padding-left:20px}.custom-theme .el-scrollbar{overflow:hidden;position:relative}.custom-theme .el-scrollbar:active>.el-scrollbar__bar,.custom-theme .el-scrollbar:focus>.el-scrollbar__bar,.custom-theme .el-scrollbar:hover>.el-scrollbar__bar{opacity:1;-webkit-transition:opacity 340ms ease-out;transition:opacity 340ms ease-out}.custom-theme .el-scrollbar__wrap{overflow:scroll;height:100%}.custom-theme .el-scrollbar__wrap--hidden-default::-webkit-scrollbar{width:0;height:0}.custom-theme .el-scrollbar__thumb{position:relative;display:block;width:0;height:0;cursor:pointer;border-radius:inherit;background-color:rgba(135,141,153,.3);-webkit-transition:.3s background-color;transition:.3s background-color}.custom-theme .el-scrollbar__thumb:hover{background-color:rgba(135,141,153,.5)}.custom-theme .el-scrollbar__bar{position:absolute;right:2px;bottom:2px;z-index:1;border-radius:4px;opacity:0;-webkit-transition:opacity 120ms ease-out;transition:opacity 120ms ease-out}.custom-theme .el-scrollbar__bar.is-vertical{width:6px;top:2px}.custom-theme .el-scrollbar__bar.is-vertical>div{width:100%}.custom-theme .el-scrollbar__bar.is-horizontal{height:6px;left:2px}.custom-theme .el-scrollbar__bar.is-horizontal>div{height:100%}.custom-theme .el-select{display:inline-block;position:relative}.custom-theme .el-select:hover .el-input__inner{border-color:#b4bccc}.custom-theme .el-select .el-input__inner{cursor:pointer;padding-right:35px}.custom-theme .el-select .el-input__inner:focus{border-color:#262729}.custom-theme .el-select .el-input .el-select__caret{color:#b4bccc;font-size:14px;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;-webkit-transform:rotateZ(180deg);transform:rotateZ(180deg);line-height:16px;cursor:pointer}.custom-theme .el-select .el-input .el-select__caret.is-reverse{-webkit-transform:rotateZ(0);transform:rotateZ(0)}.custom-theme .el-select .el-input .el-select__caret.is-show-close{font-size:14px;text-align:center;-webkit-transform:rotateZ(180deg);transform:rotateZ(180deg);border-radius:100%;color:#b4bccc;-webkit-transition:color .2s cubic-bezier(.645,.045,.355,1);transition:color .2s cubic-bezier(.645,.045,.355,1)}.custom-theme .el-select .el-input .el-select__caret.is-show-close:hover{color:#878d99}.custom-theme .el-select .el-input.is-disabled .el-input__inner{cursor:not-allowed}.custom-theme .el-select .el-input.is-disabled .el-input__inner:hover{border-color:#dfe4ed}.custom-theme .el-select>.el-input{display:block}.custom-theme .el-select__input{border:none;outline:0;padding:0;margin-left:15px;color:#666;font-size:14px;vertical-align:baseline;-webkit-appearance:none;-moz-appearance:none;appearance:none;height:28px;background-color:transparent}.custom-theme .el-select__input.is-mini{height:14px}.custom-theme .el-select__close{cursor:pointer;position:absolute;top:8px;z-index:1000;right:25px;color:#b4bccc;line-height:18px;font-size:14px}.custom-theme .el-select__close:hover{color:#878d99}.custom-theme .el-select__tags{position:absolute;line-height:normal;white-space:normal;z-index:1;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.custom-theme .el-select .el-tag__close{margin-top:-2px}.custom-theme .el-select .el-tag{-webkit-box-sizing:border-box;box-sizing:border-box;border-color:transparent;margin:3px 0 3px 6px;background-color:#f0f2f5}.custom-theme .el-select .el-tag__close.el-icon-close{background-color:#b4bccc;right:-7px;color:#fff}.custom-theme .el-select .el-tag__close.el-icon-close:hover{background-color:#878d99}.custom-theme .el-select .el-tag__close.el-icon-close::before{display:block;-webkit-transform:translate(0,.5px);transform:translate(0,.5px)}.custom-theme .el-select__tag{display:inline-block;height:24px;line-height:24px;font-size:14px;border-radius:4px;color:#fff;background-color:#262729}.custom-theme .el-select__tag .el-icon-close{font-size:14px}.custom-theme .el-button{display:inline-block;line-height:1;white-space:nowrap;cursor:pointer;background:#fff;border:1px solid #d8dce5;border-color:#d8dce5;color:#5a5e66;-webkit-appearance:none;text-align:center;-webkit-box-sizing:border-box;box-sizing:border-box;outline:0;margin:0;-webkit-transition:.1s;transition:.1s;font-weight:500;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;padding:12px 20px;font-size:14px;border-radius:4px}.custom-theme .el-button+.el-button{margin-left:10px}.custom-theme .el-button.is-round{padding:12px 20px}.custom-theme .el-button:focus,.custom-theme .el-button:hover{color:#262729;border-color:#bebebf;background-color:#e9e9ea}.custom-theme .el-button:active{color:#222325;border-color:#222325;outline:0}.custom-theme .el-button::-moz-focus-inner{border:0}.custom-theme .el-button [class*=el-icon-]+span{margin-left:5px}.custom-theme .el-button.is-plain:focus,.custom-theme .el-button.is-plain:hover{background:#fff;border-color:#262729;color:#262729}.custom-theme .el-button.is-plain:active{background:#fff;border-color:#222325;color:#222325;outline:0}.custom-theme .el-button.is-active{color:#222325;border-color:#222325}.custom-theme .el-button.is-disabled,.custom-theme .el-button.is-disabled:focus,.custom-theme .el-button.is-disabled:hover{color:#b4bccc;cursor:not-allowed;background-image:none;background-color:#fff;border-color:#e6ebf5}.custom-theme .el-button.is-disabled.el-button--text{background-color:transparent}.custom-theme .el-button.is-disabled.is-plain,.custom-theme .el-button.is-disabled.is-plain:focus,.custom-theme .el-button.is-disabled.is-plain:hover{background-color:#fff;border-color:#e6ebf5;color:#b4bccc}.custom-theme .el-button.is-loading{position:relative;pointer-events:none}.custom-theme .el-button.is-loading:before{pointer-events:none;content:'';position:absolute;left:-1px;top:-1px;right:-1px;bottom:-1px;border-radius:inherit;background-color:rgba(255,255,255,.35)}.custom-theme .el-button.is-round{border-radius:20px;padding:12px 23px}.custom-theme .el-button--primary{color:#fff;background-color:#262729;border-color:#262729}.custom-theme .el-button--primary:focus,.custom-theme .el-button--primary:hover{background:#515254;border-color:#515254;color:#fff}.custom-theme .el-button--primary:active{background:#222325;border-color:#222325;color:#fff;outline:0}.custom-theme .el-button--primary.is-active{background:#222325;border-color:#222325;color:#fff}.custom-theme .el-button--primary.is-disabled,.custom-theme .el-button--primary.is-disabled:active,.custom-theme .el-button--primary.is-disabled:focus,.custom-theme .el-button--primary.is-disabled:hover{color:#fff;background-color:#939394;border-color:#939394}.custom-theme .el-button--primary.is-plain{color:#262729;background:#e9e9ea;border-color:#a8a9a9}.custom-theme .el-button--primary.is-plain:focus,.custom-theme .el-button--primary.is-plain:hover{background:#262729;border-color:#262729;color:#fff}.custom-theme .el-button--primary.is-plain:active{background:#222325;border-color:#222325;color:#fff;outline:0}.custom-theme .el-button--primary.is-plain.is-disabled,.custom-theme .el-button--primary.is-plain.is-disabled:active,.custom-theme .el-button--primary.is-plain.is-disabled:focus,.custom-theme .el-button--primary.is-plain.is-disabled:hover{color:#7d7d7f;background-color:#e9e9ea;border-color:#d4d4d4}.custom-theme .el-button--success{color:#fff;background-color:#409167;border-color:#409167}.custom-theme .el-button--success:focus,.custom-theme .el-button--success:hover{background:#66a785;border-color:#66a785;color:#fff}.custom-theme .el-button--success:active{background:#3a835d;border-color:#3a835d;color:#fff;outline:0}.custom-theme .el-button--success.is-active{background:#3a835d;border-color:#3a835d;color:#fff}.custom-theme .el-button--success.is-disabled,.custom-theme .el-button--success.is-disabled:active,.custom-theme .el-button--success.is-disabled:focus,.custom-theme .el-button--success.is-disabled:hover{color:#fff;background-color:#a0c8b3;border-color:#a0c8b3}.custom-theme .el-button--success.is-plain{color:#409167;background:#ecf4f0;border-color:#b3d3c2}.custom-theme .el-button--success.is-plain:focus,.custom-theme .el-button--success.is-plain:hover{background:#409167;border-color:#409167;color:#fff}.custom-theme .el-button--success.is-plain:active{background:#3a835d;border-color:#3a835d;color:#fff;outline:0}.custom-theme .el-button--success.is-plain.is-disabled,.custom-theme .el-button--success.is-plain.is-disabled:active,.custom-theme .el-button--success.is-plain.is-disabled:focus,.custom-theme .el-button--success.is-plain.is-disabled:hover{color:#8cbda4;background-color:#ecf4f0;border-color:#d9e9e1}.custom-theme .el-button--warning{color:#fff;background-color:#9da408;border-color:#9da408}.custom-theme .el-button--warning:focus,.custom-theme .el-button--warning:hover{background:#b1b639;border-color:#b1b639;color:#fff}.custom-theme .el-button--warning:active{background:#8d9407;border-color:#8d9407;color:#fff;outline:0}.custom-theme .el-button--warning.is-active{background:#8d9407;border-color:#8d9407;color:#fff}.custom-theme .el-button--warning.is-disabled,.custom-theme .el-button--warning.is-disabled:active,.custom-theme .el-button--warning.is-disabled:focus,.custom-theme .el-button--warning.is-disabled:hover{color:#fff;background-color:#ced284;border-color:#ced284}.custom-theme .el-button--warning.is-plain{color:#9da408;background:#f5f6e6;border-color:#d8db9c}.custom-theme .el-button--warning.is-plain:focus,.custom-theme .el-button--warning.is-plain:hover{background:#9da408;border-color:#9da408;color:#fff}.custom-theme .el-button--warning.is-plain:active{background:#8d9407;border-color:#8d9407;color:#fff;outline:0}.custom-theme .el-button--warning.is-plain.is-disabled,.custom-theme .el-button--warning.is-plain.is-disabled:active,.custom-theme .el-button--warning.is-plain.is-disabled:focus,.custom-theme .el-button--warning.is-plain.is-disabled:hover{color:#c4c86b;background-color:#f5f6e6;border-color:#ebedce}.custom-theme .el-button--danger{color:#fff;background-color:#b3450e;border-color:#b3450e}.custom-theme .el-button--danger:focus,.custom-theme .el-button--danger:hover{background:#c26a3e;border-color:#c26a3e;color:#fff}.custom-theme .el-button--danger:active{background:#a13e0d;border-color:#a13e0d;color:#fff;outline:0}.custom-theme .el-button--danger.is-active{background:#a13e0d;border-color:#a13e0d;color:#fff}.custom-theme .el-button--danger.is-disabled,.custom-theme .el-button--danger.is-disabled:active,.custom-theme .el-button--danger.is-disabled:focus,.custom-theme .el-button--danger.is-disabled:hover{color:#fff;background-color:#d9a287;border-color:#d9a287}.custom-theme .el-button--danger.is-plain{color:#b3450e;background:#f7ece7;border-color:#e1b59f}.custom-theme .el-button--danger.is-plain:focus,.custom-theme .el-button--danger.is-plain:hover{background:#b3450e;border-color:#b3450e;color:#fff}.custom-theme .el-button--danger.is-plain:active{background:#a13e0d;border-color:#a13e0d;color:#fff;outline:0}.custom-theme .el-button--danger.is-plain.is-disabled,.custom-theme .el-button--danger.is-plain.is-disabled:active,.custom-theme .el-button--danger.is-plain.is-disabled:focus,.custom-theme .el-button--danger.is-plain.is-disabled:hover{color:#d18f6e;background-color:#f7ece7;border-color:#f0dacf}.custom-theme .el-button--info{color:#fff;background-color:#0a76a4;border-color:#0a76a4}.custom-theme .el-button--info:focus,.custom-theme .el-button--info:hover{background:#3b91b6;border-color:#3b91b6;color:#fff}.custom-theme .el-button--info:active{background:#096a94;border-color:#096a94;color:#fff;outline:0}.custom-theme .el-button--info.is-active{background:#096a94;border-color:#096a94;color:#fff}.custom-theme .el-button--info.is-disabled,.custom-theme .el-button--info.is-disabled:active,.custom-theme .el-button--info.is-disabled:focus,.custom-theme .el-button--info.is-disabled:hover{color:#fff;background-color:#85bbd2;border-color:#85bbd2}.custom-theme .el-button--info.is-plain{color:#0a76a4;background:#e7f1f6;border-color:#9dc8db}.custom-theme .el-button--info.is-plain:focus,.custom-theme .el-button--info.is-plain:hover{background:#0a76a4;border-color:#0a76a4;color:#fff}.custom-theme .el-button--info.is-plain:active{background:#096a94;border-color:#096a94;color:#fff;outline:0}.custom-theme .el-button--info.is-plain.is-disabled,.custom-theme .el-button--info.is-plain.is-disabled:active,.custom-theme .el-button--info.is-plain.is-disabled:focus,.custom-theme .el-button--info.is-plain.is-disabled:hover{color:#6cadc8;background-color:#e7f1f6;border-color:#cee4ed}.custom-theme .el-button--medium{padding:10px 20px;font-size:14px;border-radius:4px}.custom-theme .el-button--medium.is-round{padding:10px 20px}.custom-theme .el-button--small{padding:9px 15px;font-size:12px;border-radius:3px}.custom-theme .el-button--small.is-round{padding:9px 15px}.custom-theme .el-button--mini{padding:7px 15px;font-size:12px;border-radius:3px}.custom-theme .el-button--mini.is-round{padding:7px 15px}.custom-theme .el-button--text{border:none;color:#262729;background:0 0;padding-left:0;padding-right:0}.custom-theme .el-button--text:focus,.custom-theme .el-button--text:hover{color:#515254;border-color:transparent;background-color:transparent}.custom-theme .el-button--text:active{color:#222325;border-color:transparent;background-color:transparent}.custom-theme .el-button-group{display:inline-block;vertical-align:middle}.custom-theme .el-button-group::after,.custom-theme .el-button-group::before{display:table;content:""}.custom-theme .el-button-group::after{clear:both}.custom-theme .el-button-group .el-button{float:left;position:relative}.custom-theme .el-button-group .el-button+.el-button{margin-left:0}.custom-theme .el-button-group .el-button:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.custom-theme .el-button-group .el-button:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.custom-theme .el-button-group .el-button:not(:first-child):not(:last-child){border-radius:0}.custom-theme .el-button-group .el-button:not(:last-child){margin-right:-1px}.custom-theme .el-button-group .el-button:active,.custom-theme .el-button-group .el-button:focus,.custom-theme .el-button-group .el-button:hover{z-index:1}.custom-theme .el-button-group .el-button.is-active{z-index:1}.custom-theme .el-button-group .el-button--primary:first-child{border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--primary:last-child{border-left-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--primary:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--success:first-child{border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--success:last-child{border-left-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--success:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--warning:first-child{border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--warning:last-child{border-left-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--warning:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--danger:first-child{border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--danger:last-child{border-left-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--danger:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--info:first-child{border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--info:last-child{border-left-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--info:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.custom-theme .el-checkbox{color:#5a5e66;font-weight:500;font-size:14px;position:relative;cursor:pointer;display:inline-block;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.custom-theme .el-checkbox.is-bordered{padding:9px 20px 9px 10px;border-radius:4px;border:1px solid #d8dce5}.custom-theme .el-checkbox.is-bordered.is-checked{border-color:#262729}.custom-theme .el-checkbox.is-bordered.is-disabled{border-color:#e6ebf5;cursor:not-allowed}.custom-theme .el-checkbox.is-bordered+.el-checkbox.is-bordered{margin-left:10px}.custom-theme .el-checkbox.is-bordered.el-checkbox--medium{padding:7px 20px 7px 10px;border-radius:4px}.custom-theme .el-checkbox.is-bordered.el-checkbox--medium .el-checkbox__label{line-height:17px;font-size:14px}.custom-theme .el-checkbox.is-bordered.el-checkbox--medium .el-checkbox__inner{height:14px;width:14px}.custom-theme .el-checkbox.is-bordered.el-checkbox--small{padding:3px 15px 7px 10px;border-radius:3px}.custom-theme .el-checkbox.is-bordered.el-checkbox--small .el-checkbox__label{line-height:15px;font-size:12px}.custom-theme .el-checkbox.is-bordered.el-checkbox--small .el-checkbox__inner{height:12px;width:12px}.custom-theme .el-checkbox.is-bordered.el-checkbox--small .el-checkbox__inner::after{height:6px;width:2px}.custom-theme .el-checkbox.is-bordered.el-checkbox--mini{padding:1px 15px 5px 10px;border-radius:3px}.custom-theme .el-checkbox.is-bordered.el-checkbox--mini .el-checkbox__label{line-height:12px;font-size:12px}.custom-theme .el-checkbox.is-bordered.el-checkbox--mini .el-checkbox__inner{height:12px;width:12px}.custom-theme .el-checkbox.is-bordered.el-checkbox--mini .el-checkbox__inner::after{height:6px;width:2px}.custom-theme .el-checkbox__input{white-space:nowrap;cursor:pointer;outline:0;display:inline-block;line-height:1;position:relative;vertical-align:middle}.custom-theme .el-checkbox__input.is-disabled .el-checkbox__inner{background-color:#edf2fc;border-color:#d8dce5;cursor:not-allowed}.custom-theme .el-checkbox__input.is-disabled .el-checkbox__inner::after{cursor:not-allowed;border-color:#b4bccc}.custom-theme .el-checkbox__input.is-disabled .el-checkbox__inner+.el-checkbox__label{cursor:not-allowed}.custom-theme .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner{background-color:#edf2fc;border-color:#d8dce5}.custom-theme .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner::after{border-color:#b4bccc}.custom-theme .el-checkbox__input.is-disabled.is-indeterminate .el-checkbox__inner{background-color:#edf2fc;border-color:#d8dce5}.custom-theme .el-checkbox__input.is-disabled.is-indeterminate .el-checkbox__inner::before{background-color:#b4bccc;border-color:#b4bccc}.custom-theme .el-checkbox__input.is-disabled+span.el-checkbox__label{color:#b4bccc;cursor:not-allowed}.custom-theme .el-checkbox__input.is-checked .el-checkbox__inner{background-color:#262729;border-color:#262729}.custom-theme .el-checkbox__input.is-checked .el-checkbox__inner::after{-webkit-transform:rotate(45deg) scaleY(1);transform:rotate(45deg) scaleY(1)}.custom-theme .el-checkbox__input.is-checked+.el-checkbox__label{color:#262729}.custom-theme .el-checkbox__input.is-focus .el-checkbox__inner{border-color:#262729}.custom-theme .el-checkbox__input.is-indeterminate .el-checkbox__inner{background-color:#262729;border-color:#262729}.custom-theme .el-checkbox__input.is-indeterminate .el-checkbox__inner::before{content:'';position:absolute;display:block;background-color:#fff;height:2px;-webkit-transform:scale(.5);transform:scale(.5);left:0;right:0;top:5px}.custom-theme .el-checkbox__input.is-indeterminate .el-checkbox__inner::after{display:none}.custom-theme .el-checkbox__inner{display:inline-block;position:relative;border:1px solid #d8dce5;border-radius:2px;-webkit-box-sizing:border-box;box-sizing:border-box;width:14px;height:14px;background-color:#fff;z-index:1;-webkit-transition:border-color .25s cubic-bezier(.71,-.46,.29,1.46),background-color .25s cubic-bezier(.71,-.46,.29,1.46);transition:border-color .25s cubic-bezier(.71,-.46,.29,1.46),background-color .25s cubic-bezier(.71,-.46,.29,1.46)}.custom-theme .el-checkbox__inner:hover{border-color:#262729}.custom-theme .el-checkbox__inner::after{-webkit-box-sizing:content-box;box-sizing:content-box;content:"";border:1px solid #fff;border-left:0;border-top:0;height:7px;left:4px;position:absolute;top:1px;-webkit-transform:rotate(45deg) scaleY(0);transform:rotate(45deg) scaleY(0);width:3px;-webkit-transition:-webkit-transform .15s cubic-bezier(.71,-.46,.88,.6) 50ms;transition:-webkit-transform .15s cubic-bezier(.71,-.46,.88,.6) 50ms;transition:transform .15s cubic-bezier(.71,-.46,.88,.6) 50ms;transition:transform .15s cubic-bezier(.71,-.46,.88,.6) 50ms,-webkit-transform .15s cubic-bezier(.71,-.46,.88,.6) 50ms;-webkit-transform-origin:center;transform-origin:center}.custom-theme .el-checkbox__original{opacity:0;outline:0;position:absolute;margin:0;width:0;height:0;left:-999px}.custom-theme .el-checkbox__label{display:inline-block;padding-left:10px;line-height:19px;font-size:14px}.custom-theme .el-checkbox+.el-checkbox{margin-left:30px}.custom-theme .el-checkbox-button{position:relative;display:inline-block}.custom-theme .el-checkbox-button__inner{display:inline-block;line-height:1;font-weight:500;white-space:nowrap;vertical-align:middle;cursor:pointer;background:#fff;border:1px solid #d8dce5;border-left:0;color:#5a5e66;-webkit-appearance:none;text-align:center;-webkit-box-sizing:border-box;box-sizing:border-box;outline:0;margin:0;position:relative;-webkit-transition:all .3s cubic-bezier(.645,.045,.355,1);transition:all .3s cubic-bezier(.645,.045,.355,1);-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;padding:12px 20px;font-size:14px;border-radius:0}.custom-theme .el-checkbox-button__inner.is-round{padding:12px 20px}.custom-theme .el-checkbox-button__inner:hover{color:#262729}.custom-theme .el-checkbox-button__inner [class*=el-icon-]{line-height:.9}.custom-theme .el-checkbox-button__inner [class*=el-icon-]+span{margin-left:5px}.custom-theme .el-checkbox-button__original{opacity:0;outline:0;position:absolute;margin:0;left:-999px}.custom-theme .el-checkbox-button.is-checked .el-checkbox-button__inner{color:#fff;background-color:#262729;border-color:#262729;-webkit-box-shadow:-1px 0 0 0 #7d7d7f;box-shadow:-1px 0 0 0 #7d7d7f}.custom-theme .el-checkbox-button.is-disabled .el-checkbox-button__inner{color:#b4bccc;cursor:not-allowed;background-image:none;background-color:#fff;border-color:#e6ebf5;-webkit-box-shadow:none;box-shadow:none}.custom-theme .el-checkbox-button:first-child .el-checkbox-button__inner{border-left:1px solid #d8dce5;border-radius:4px 0 0 4px;-webkit-box-shadow:none!important;box-shadow:none!important}.custom-theme .el-checkbox-button.is-focus .el-checkbox-button__inner{border-color:#262729}.custom-theme .el-checkbox-button:last-child .el-checkbox-button__inner{border-radius:0 4px 4px 0}.custom-theme .el-checkbox-button--medium .el-checkbox-button__inner{padding:10px 20px;font-size:14px;border-radius:0}.custom-theme .el-checkbox-button--medium .el-checkbox-button__inner.is-round{padding:10px 20px}.custom-theme .el-checkbox-button--small .el-checkbox-button__inner{padding:9px 15px;font-size:12px;border-radius:0}.custom-theme .el-checkbox-button--small .el-checkbox-button__inner.is-round{padding:9px 15px}.custom-theme .el-checkbox-button--mini .el-checkbox-button__inner{padding:7px 15px;font-size:12px;border-radius:0}.custom-theme .el-checkbox-button--mini .el-checkbox-button__inner.is-round{padding:7px 15px}.custom-theme .el-checkbox-group{font-size:0}.custom-theme .el-tag{background-color:rgba(38,39,41,.1);display:inline-block;padding:0 10px;height:32px;line-height:30px;font-size:12px;color:#262729;border-radius:4px;-webkit-box-sizing:border-box;box-sizing:border-box;border:1px solid rgba(38,39,41,.2);white-space:nowrap}.custom-theme .el-tag .el-icon-close{border-radius:50%;text-align:center;position:relative;cursor:pointer;font-size:12px;height:18px;width:18px;line-height:18px;vertical-align:middle;top:-1px;right:-5px;color:#262729}.custom-theme .el-tag .el-icon-close::before{display:block}.custom-theme .el-tag .el-icon-close:hover{background-color:#262729;color:#fff}.custom-theme .el-tag--info{background-color:rgba(10,118,164,.1);border-color:rgba(10,118,164,.2);color:#0a76a4}.custom-theme .el-tag--info.is-hit{border-color:#0a76a4}.custom-theme .el-tag--info .el-tag__close{color:#0a76a4}.custom-theme .el-tag--info .el-tag__close:hover{background-color:#0a76a4;color:#fff}.custom-theme .el-tag--success{background-color:rgba(64,145,103,.1);border-color:rgba(64,145,103,.2);color:#409167}.custom-theme .el-tag--success.is-hit{border-color:#409167}.custom-theme .el-tag--success .el-tag__close{color:#409167}.custom-theme .el-tag--success .el-tag__close:hover{background-color:#409167;color:#fff}.custom-theme .el-tag--warning{background-color:rgba(157,164,8,.1);border-color:rgba(157,164,8,.2);color:#9da408}.custom-theme .el-tag--warning.is-hit{border-color:#9da408}.custom-theme .el-tag--warning .el-tag__close{color:#9da408}.custom-theme .el-tag--warning .el-tag__close:hover{background-color:#9da408;color:#fff}.custom-theme .el-tag--danger{background-color:rgba(179,69,14,.1);border-color:rgba(179,69,14,.2);color:#b3450e}.custom-theme .el-tag--danger.is-hit{border-color:#b3450e}.custom-theme .el-tag--danger .el-tag__close{color:#b3450e}.custom-theme .el-tag--danger .el-tag__close:hover{background-color:#b3450e;color:#fff}.custom-theme .el-tag--medium{height:28px;line-height:26px}.custom-theme .el-tag--medium .el-icon-close{-webkit-transform:scale(.8);transform:scale(.8)}.custom-theme .el-tag--small{height:24px;padding:0 8px;line-height:22px}.custom-theme .el-tag--small .el-icon-close{-webkit-transform:scale(.8);transform:scale(.8)}.custom-theme .el-tag--mini{height:20px;padding:0 5px;line-height:19px}.custom-theme .el-tag--mini .el-icon-close{margin-left:-3px;-webkit-transform:scale(.7);transform:scale(.7)}.custom-theme .el-table{position:relative;overflow:hidden;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-box-flex:1;-ms-flex:1;flex:1;width:100%;max-width:100%;background-color:#fff;font-size:14px;color:#5a5e66}.custom-theme .el-table__empty-block{position:relative;min-height:60px;text-align:center;width:100%;height:100%}.custom-theme .el-table__empty-text{position:absolute;left:50%;top:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);color:color(#262729 s(16%) l(44%))}.custom-theme .el-table__expand-column .cell{padding:0;text-align:center}.custom-theme .el-table__expand-icon{position:relative;cursor:pointer;color:#666;font-size:12px;-webkit-transition:-webkit-transform .2s ease-in-out;transition:-webkit-transform .2s ease-in-out;transition:transform .2s ease-in-out;transition:transform .2s ease-in-out,-webkit-transform .2s ease-in-out;height:20px}.custom-theme .el-table__expand-icon--expanded{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.custom-theme .el-table__expand-icon>.el-icon{position:absolute;left:50%;top:50%;margin-left:-5px;margin-top:-5px}.custom-theme .el-table__expanded-cell{background-color:#fff}.custom-theme .el-table__expanded-cell[class*=cell]{padding:20px 50px}.custom-theme .el-table__expanded-cell:hover{background-color:#f5f7fa!important}.custom-theme .el-table--fit{border-right:0;border-bottom:0}.custom-theme .el-table--fit td.gutter,.custom-theme .el-table--fit th.gutter{border-right-width:1px}.custom-theme .el-table thead{color:#878d99;font-weight:500}.custom-theme .el-table thead.is-group th{background:#f5f7fa}.custom-theme .el-table td,.custom-theme .el-table th{padding:12px 0;min-width:0;-webkit-box-sizing:border-box;box-sizing:border-box;text-overflow:ellipsis;vertical-align:middle;position:relative}.custom-theme .el-table td.is-center,.custom-theme .el-table th.is-center{text-align:center}.custom-theme .el-table td.is-left,.custom-theme .el-table th.is-left{text-align:left}.custom-theme .el-table td.is-right,.custom-theme .el-table th.is-right{text-align:right}.custom-theme .el-table td.gutter,.custom-theme .el-table th.gutter{width:15px;border-right-width:0;border-bottom-width:0;padding:0}.custom-theme .el-table td.is-hidden>*,.custom-theme .el-table th.is-hidden>*{visibility:hidden}.custom-theme .el-table--medium td,.custom-theme .el-table--medium th{padding:10px 0}.custom-theme .el-table--small{font-size:12px}.custom-theme .el-table--small td,.custom-theme .el-table--small th{padding:8px 0}.custom-theme .el-table--mini{font-size:12px}.custom-theme .el-table--mini td,.custom-theme .el-table--mini th{padding:6px 0}.custom-theme .el-table tr{background-color:#fff}.custom-theme .el-table tr input[type=checkbox]{margin:0}.custom-theme .el-table td,.custom-theme .el-table th.is-leaf{border-bottom:1px solid #e6ebf5}.custom-theme .el-table th.is-sortable{cursor:pointer}.custom-theme .el-table th{white-space:nowrap;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-align:left}.custom-theme .el-table th div{display:inline-block;padding-left:10px;padding-right:10px;line-height:40px;-webkit-box-sizing:border-box;box-sizing:border-box;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.custom-theme .el-table th>.cell{position:relative;word-wrap:normal;text-overflow:ellipsis;display:inline-block;vertical-align:middle;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}.custom-theme .el-table th>.cell.highlight{color:#262729}.custom-theme .el-table th.required>div::before{display:inline-block;content:"";width:8px;height:8px;border-radius:50%;background:#ff4d51;margin-right:5px;vertical-align:middle}.custom-theme .el-table td div{-webkit-box-sizing:border-box;box-sizing:border-box}.custom-theme .el-table td.gutter{width:0}.custom-theme .el-table .cell{-webkit-box-sizing:border-box;box-sizing:border-box;overflow:hidden;text-overflow:ellipsis;white-space:normal;word-break:break-all;line-height:23px;padding-left:10px;padding-right:10px}.custom-theme .el-table .cell.el-tooltip{white-space:nowrap;min-width:50px}.custom-theme .el-table td:first-child .cell,.custom-theme .el-table th:first-child .cell{padding-left:0}.custom-theme .el-table--border,.custom-theme .el-table--group{border:1px solid #e6ebf5}.custom-theme .el-table--border::after,.custom-theme .el-table--group::after,.custom-theme .el-table::before{content:'';position:absolute;background-color:#e6ebf5;z-index:1}.custom-theme .el-table--border::after,.custom-theme .el-table--group::after{top:0;right:0;width:1px;height:100%}.custom-theme .el-table::before{left:0;bottom:0;width:100%;height:1px}.custom-theme .el-table--border{border-right:none;border-bottom:none}.custom-theme .el-table--border td,.custom-theme .el-table--border th{border-right:1px solid #e6ebf5}.custom-theme .el-table--border td:first-child .cell,.custom-theme .el-table--border th:first-child .cell{padding-left:10px}.custom-theme .el-table--border .has-gutter td:nth-last-of-type(2),.custom-theme .el-table--border .has-gutter th:nth-last-of-type(2){border-right:none}.custom-theme .el-table--border th.gutter:last-of-type{border-bottom:1px solid #e6ebf5;border-bottom-width:1px}.custom-theme .el-table--border th{border-bottom:1px solid #e6ebf5}.custom-theme .el-table--hidden{visibility:hidden}.custom-theme .el-table__fixed,.custom-theme .el-table__fixed-right{position:absolute;top:0;left:0;overflow-x:hidden;-webkit-box-shadow:0 0 10px rgba(0,0,0,.12);box-shadow:0 0 10px rgba(0,0,0,.12)}.custom-theme .el-table__fixed-right::before,.custom-theme .el-table__fixed::before{content:'';position:absolute;left:0;bottom:0;width:100%;height:1px;background-color:#e6ebf5;z-index:4}.custom-theme .el-table__fixed-right-patch{position:absolute;top:-1px;right:0;background-color:#fff;border-bottom:1px solid #e6ebf5}.custom-theme .el-table__fixed-right{top:0;left:auto;right:0}.custom-theme .el-table__fixed-right .el-table__fixed-body-wrapper,.custom-theme .el-table__fixed-right .el-table__fixed-footer-wrapper,.custom-theme .el-table__fixed-right .el-table__fixed-header-wrapper{left:auto;right:0}.custom-theme .el-table__fixed-header-wrapper{position:absolute;left:0;top:0;z-index:3}.custom-theme .el-table__fixed-footer-wrapper{position:absolute;left:0;bottom:0;z-index:3}.custom-theme .el-table__fixed-footer-wrapper tbody td{border-top:1px solid #e6ebf5;background-color:#f5f7fa;color:#5a5e66}.custom-theme .el-table__fixed-body-wrapper{position:absolute;left:0;top:37px;overflow:hidden;z-index:3}.custom-theme .el-table__body-wrapper,.custom-theme .el-table__footer-wrapper,.custom-theme .el-table__header-wrapper{width:100%}.custom-theme .el-table__footer-wrapper{margin-top:-1px}.custom-theme .el-table__footer-wrapper td{border-top:1px solid #e6ebf5}.custom-theme .el-table__body,.custom-theme .el-table__footer,.custom-theme .el-table__header{table-layout:fixed}.custom-theme .el-table__footer-wrapper,.custom-theme .el-table__header-wrapper{overflow:hidden}.custom-theme .el-table__footer-wrapper tbody td,.custom-theme .el-table__header-wrapper tbody td{background-color:#f5f7fa;color:#5a5e66}.custom-theme .el-table__body-wrapper{overflow:auto;position:relative}.custom-theme .el-table__body-wrapper.is-scroll-none~.el-table__fixed,.custom-theme .el-table__body-wrapper.is-scroll-none~.el-table__fixed-right{-webkit-box-shadow:none;box-shadow:none}.custom-theme .el-table__body-wrapper.is-scroll-left~.el-table__fixed{-webkit-box-shadow:none;box-shadow:none}.custom-theme .el-table__body-wrapper.is-scroll-right~.el-table__fixed-right{-webkit-box-shadow:none;box-shadow:none}.custom-theme .el-table__body-wrapper .el-table--border.is-scroll-right~.el-table__fixed-right{border-left:1px solid #e6ebf5}.custom-theme .el-table__body-wrapper .el-table--border.is-scroll-left~.el-table__fixed{border-right:1px solid #e6ebf5}.custom-theme .el-table .caret-wrapper{position:relative;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:13px;width:24px;cursor:pointer;overflow:initial}.custom-theme .el-table .sort-caret{color:#0a76a4;width:14px;overflow:hidden;font-size:13px}.custom-theme .el-table .ascending .sort-caret.ascending{color:#262729}.custom-theme .el-table .descending .sort-caret.descending{color:#262729}.custom-theme .el-table .hidden-columns{visibility:hidden;position:absolute;z-index:-1}.custom-theme .el-table--striped .el-table__body tr.el-table__row--striped td{background:#fafafa}.custom-theme .el-table--striped .el-table__body tr.el-table__row--striped.current-row td{background-color:#e9e9ea}.custom-theme .el-table__body tr.hover-row.current-row>td,.custom-theme .el-table__body tr.hover-row.el-table__row--striped.current-row>td,.custom-theme .el-table__body tr.hover-row.el-table__row--striped>td,.custom-theme .el-table__body tr.hover-row>td{background-color:#e9e9ea}.custom-theme .el-table__body tr.current-row>td{background-color:#e9e9ea}.custom-theme .el-table__column-resize-proxy{position:absolute;left:200px;top:0;bottom:0;width:0;border-left:1px solid #e6ebf5;z-index:10}.custom-theme .el-table__column-filter-trigger{display:inline-block;line-height:34px;cursor:pointer}.custom-theme .el-table__column-filter-trigger i{color:#0a76a4;font-size:12px;-webkit-transform:scale(.75);transform:scale(.75)}.custom-theme .el-table--enable-row-transition .el-table__body td{-webkit-transition:background-color .25s ease;transition:background-color .25s ease}.custom-theme .el-table--enable-row-hover .el-table__body tr:hover>td{background-color:#f5f7fa}.custom-theme .el-table--fluid-height .el-table__fixed,.custom-theme .el-table--fluid-height .el-table__fixed-right{bottom:0;overflow:hidden}.custom-theme .el-checkbox{color:#5a5e66;font-weight:500;font-size:14px;position:relative;cursor:pointer;display:inline-block;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.custom-theme .el-checkbox.is-bordered{padding:9px 20px 9px 10px;border-radius:4px;border:1px solid #d8dce5}.custom-theme .el-checkbox.is-bordered.is-checked{border-color:#262729}.custom-theme .el-checkbox.is-bordered.is-disabled{border-color:#e6ebf5;cursor:not-allowed}.custom-theme .el-checkbox.is-bordered+.el-checkbox.is-bordered{margin-left:10px}.custom-theme .el-checkbox.is-bordered.el-checkbox--medium{padding:7px 20px 7px 10px;border-radius:4px}.custom-theme .el-checkbox.is-bordered.el-checkbox--medium .el-checkbox__label{line-height:17px;font-size:14px}.custom-theme .el-checkbox.is-bordered.el-checkbox--medium .el-checkbox__inner{height:14px;width:14px}.custom-theme .el-checkbox.is-bordered.el-checkbox--small{padding:3px 15px 7px 10px;border-radius:3px}.custom-theme .el-checkbox.is-bordered.el-checkbox--small .el-checkbox__label{line-height:15px;font-size:12px}.custom-theme .el-checkbox.is-bordered.el-checkbox--small .el-checkbox__inner{height:12px;width:12px}.custom-theme .el-checkbox.is-bordered.el-checkbox--small .el-checkbox__inner::after{height:6px;width:2px}.custom-theme .el-checkbox.is-bordered.el-checkbox--mini{padding:1px 15px 5px 10px;border-radius:3px}.custom-theme .el-checkbox.is-bordered.el-checkbox--mini .el-checkbox__label{line-height:12px;font-size:12px}.custom-theme .el-checkbox.is-bordered.el-checkbox--mini .el-checkbox__inner{height:12px;width:12px}.custom-theme .el-checkbox.is-bordered.el-checkbox--mini .el-checkbox__inner::after{height:6px;width:2px}.custom-theme .el-checkbox__input{white-space:nowrap;cursor:pointer;outline:0;display:inline-block;line-height:1;position:relative;vertical-align:middle}.custom-theme .el-checkbox__input.is-disabled .el-checkbox__inner{background-color:#edf2fc;border-color:#d8dce5;cursor:not-allowed}.custom-theme .el-checkbox__input.is-disabled .el-checkbox__inner::after{cursor:not-allowed;border-color:#b4bccc}.custom-theme .el-checkbox__input.is-disabled .el-checkbox__inner+.el-checkbox__label{cursor:not-allowed}.custom-theme .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner{background-color:#edf2fc;border-color:#d8dce5}.custom-theme .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner::after{border-color:#b4bccc}.custom-theme .el-checkbox__input.is-disabled.is-indeterminate .el-checkbox__inner{background-color:#edf2fc;border-color:#d8dce5}.custom-theme .el-checkbox__input.is-disabled.is-indeterminate .el-checkbox__inner::before{background-color:#b4bccc;border-color:#b4bccc}.custom-theme .el-checkbox__input.is-disabled+span.el-checkbox__label{color:#b4bccc;cursor:not-allowed}.custom-theme .el-checkbox__input.is-checked .el-checkbox__inner{background-color:#262729;border-color:#262729}.custom-theme .el-checkbox__input.is-checked .el-checkbox__inner::after{-webkit-transform:rotate(45deg) scaleY(1);transform:rotate(45deg) scaleY(1)}.custom-theme .el-checkbox__input.is-checked+.el-checkbox__label{color:#262729}.custom-theme .el-checkbox__input.is-focus .el-checkbox__inner{border-color:#262729}.custom-theme .el-checkbox__input.is-indeterminate .el-checkbox__inner{background-color:#262729;border-color:#262729}.custom-theme .el-checkbox__input.is-indeterminate .el-checkbox__inner::before{content:'';position:absolute;display:block;background-color:#fff;height:2px;-webkit-transform:scale(.5);transform:scale(.5);left:0;right:0;top:5px}.custom-theme .el-checkbox__input.is-indeterminate .el-checkbox__inner::after{display:none}.custom-theme .el-checkbox__inner{display:inline-block;position:relative;border:1px solid #d8dce5;border-radius:2px;-webkit-box-sizing:border-box;box-sizing:border-box;width:14px;height:14px;background-color:#fff;z-index:1;-webkit-transition:border-color .25s cubic-bezier(.71,-.46,.29,1.46),background-color .25s cubic-bezier(.71,-.46,.29,1.46);transition:border-color .25s cubic-bezier(.71,-.46,.29,1.46),background-color .25s cubic-bezier(.71,-.46,.29,1.46)}.custom-theme .el-checkbox__inner:hover{border-color:#262729}.custom-theme .el-checkbox__inner::after{-webkit-box-sizing:content-box;box-sizing:content-box;content:"";border:1px solid #fff;border-left:0;border-top:0;height:7px;left:4px;position:absolute;top:1px;-webkit-transform:rotate(45deg) scaleY(0);transform:rotate(45deg) scaleY(0);width:3px;-webkit-transition:-webkit-transform .15s cubic-bezier(.71,-.46,.88,.6) 50ms;transition:-webkit-transform .15s cubic-bezier(.71,-.46,.88,.6) 50ms;transition:transform .15s cubic-bezier(.71,-.46,.88,.6) 50ms;transition:transform .15s cubic-bezier(.71,-.46,.88,.6) 50ms,-webkit-transform .15s cubic-bezier(.71,-.46,.88,.6) 50ms;-webkit-transform-origin:center;transform-origin:center}.custom-theme .el-checkbox__original{opacity:0;outline:0;position:absolute;margin:0;width:0;height:0;left:-999px}.custom-theme .el-checkbox__label{display:inline-block;padding-left:10px;line-height:19px;font-size:14px}.custom-theme .el-checkbox+.el-checkbox{margin-left:30px}.custom-theme .el-checkbox-button{position:relative;display:inline-block}.custom-theme .el-checkbox-button__inner{display:inline-block;line-height:1;font-weight:500;white-space:nowrap;vertical-align:middle;cursor:pointer;background:#fff;border:1px solid #d8dce5;border-left:0;color:#5a5e66;-webkit-appearance:none;text-align:center;-webkit-box-sizing:border-box;box-sizing:border-box;outline:0;margin:0;position:relative;-webkit-transition:all .3s cubic-bezier(.645,.045,.355,1);transition:all .3s cubic-bezier(.645,.045,.355,1);-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;padding:12px 20px;font-size:14px;border-radius:0}.custom-theme .el-checkbox-button__inner.is-round{padding:12px 20px}.custom-theme .el-checkbox-button__inner:hover{color:#262729}.custom-theme .el-checkbox-button__inner [class*=el-icon-]{line-height:.9}.custom-theme .el-checkbox-button__inner [class*=el-icon-]+span{margin-left:5px}.custom-theme .el-checkbox-button__original{opacity:0;outline:0;position:absolute;margin:0;left:-999px}.custom-theme .el-checkbox-button.is-checked .el-checkbox-button__inner{color:#fff;background-color:#262729;border-color:#262729;-webkit-box-shadow:-1px 0 0 0 #7d7d7f;box-shadow:-1px 0 0 0 #7d7d7f}.custom-theme .el-checkbox-button.is-disabled .el-checkbox-button__inner{color:#b4bccc;cursor:not-allowed;background-image:none;background-color:#fff;border-color:#e6ebf5;-webkit-box-shadow:none;box-shadow:none}.custom-theme .el-checkbox-button:first-child .el-checkbox-button__inner{border-left:1px solid #d8dce5;border-radius:4px 0 0 4px;-webkit-box-shadow:none!important;box-shadow:none!important}.custom-theme .el-checkbox-button.is-focus .el-checkbox-button__inner{border-color:#262729}.custom-theme .el-checkbox-button:last-child .el-checkbox-button__inner{border-radius:0 4px 4px 0}.custom-theme .el-checkbox-button--medium .el-checkbox-button__inner{padding:10px 20px;font-size:14px;border-radius:0}.custom-theme .el-checkbox-button--medium .el-checkbox-button__inner.is-round{padding:10px 20px}.custom-theme .el-checkbox-button--small .el-checkbox-button__inner{padding:9px 15px;font-size:12px;border-radius:0}.custom-theme .el-checkbox-button--small .el-checkbox-button__inner.is-round{padding:9px 15px}.custom-theme .el-checkbox-button--mini .el-checkbox-button__inner{padding:7px 15px;font-size:12px;border-radius:0}.custom-theme .el-checkbox-button--mini .el-checkbox-button__inner.is-round{padding:7px 15px}.custom-theme .el-checkbox-group{font-size:0}.custom-theme .el-tag{background-color:rgba(38,39,41,.1);display:inline-block;padding:0 10px;height:32px;line-height:30px;font-size:12px;color:#262729;border-radius:4px;-webkit-box-sizing:border-box;box-sizing:border-box;border:1px solid rgba(38,39,41,.2);white-space:nowrap}.custom-theme .el-tag .el-icon-close{border-radius:50%;text-align:center;position:relative;cursor:pointer;font-size:12px;height:18px;width:18px;line-height:18px;vertical-align:middle;top:-1px;right:-5px;color:#262729}.custom-theme .el-tag .el-icon-close::before{display:block}.custom-theme .el-tag .el-icon-close:hover{background-color:#262729;color:#fff}.custom-theme .el-tag--info{background-color:rgba(10,118,164,.1);border-color:rgba(10,118,164,.2);color:#0a76a4}.custom-theme .el-tag--info.is-hit{border-color:#0a76a4}.custom-theme .el-tag--info .el-tag__close{color:#0a76a4}.custom-theme .el-tag--info .el-tag__close:hover{background-color:#0a76a4;color:#fff}.custom-theme .el-tag--success{background-color:rgba(64,145,103,.1);border-color:rgba(64,145,103,.2);color:#409167}.custom-theme .el-tag--success.is-hit{border-color:#409167}.custom-theme .el-tag--success .el-tag__close{color:#409167}.custom-theme .el-tag--success .el-tag__close:hover{background-color:#409167;color:#fff}.custom-theme .el-tag--warning{background-color:rgba(157,164,8,.1);border-color:rgba(157,164,8,.2);color:#9da408}.custom-theme .el-tag--warning.is-hit{border-color:#9da408}.custom-theme .el-tag--warning .el-tag__close{color:#9da408}.custom-theme .el-tag--warning .el-tag__close:hover{background-color:#9da408;color:#fff}.custom-theme .el-tag--danger{background-color:rgba(179,69,14,.1);border-color:rgba(179,69,14,.2);color:#b3450e}.custom-theme .el-tag--danger.is-hit{border-color:#b3450e}.custom-theme .el-tag--danger .el-tag__close{color:#b3450e}.custom-theme .el-tag--danger .el-tag__close:hover{background-color:#b3450e;color:#fff}.custom-theme .el-tag--medium{height:28px;line-height:26px}.custom-theme .el-tag--medium .el-icon-close{-webkit-transform:scale(.8);transform:scale(.8)}.custom-theme .el-tag--small{height:24px;padding:0 8px;line-height:22px}.custom-theme .el-tag--small .el-icon-close{-webkit-transform:scale(.8);transform:scale(.8)}.custom-theme .el-tag--mini{height:20px;padding:0 5px;line-height:19px}.custom-theme .el-tag--mini .el-icon-close{margin-left:-3px;-webkit-transform:scale(.7);transform:scale(.7)}.custom-theme .el-table-column--selection .cell{padding-left:14px;padding-right:14px}.custom-theme .el-table-filter{border:solid 1px #e6ebf5;border-radius:2px;background-color:#fff;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);-webkit-box-sizing:border-box;box-sizing:border-box;margin:2px 0}.custom-theme .el-table-filter__list{padding:5px 0;margin:0;list-style:none;min-width:100px}.custom-theme .el-table-filter__list-item{line-height:36px;padding:0 10px;cursor:pointer;font-size:14px}.custom-theme .el-table-filter__list-item:hover{background-color:#e9e9ea;color:#515254}.custom-theme .el-table-filter__list-item.is-active{background-color:#262729;color:#fff}.custom-theme .el-table-filter__content{min-width:100px}.custom-theme .el-table-filter__bottom{border-top:1px solid #e6ebf5;padding:8px}.custom-theme .el-table-filter__bottom button{background:0 0;border:none;color:#5a5e66;cursor:pointer;font-size:13px;padding:0 3px}.custom-theme .el-table-filter__bottom button:hover{color:#262729}.custom-theme .el-table-filter__bottom button:focus{outline:0}.custom-theme .el-table-filter__bottom button.is-disabled{color:#b4bccc;cursor:not-allowed}.custom-theme .el-table-filter__checkbox-group{padding:10px}.custom-theme .el-table-filter__checkbox-group label.el-checkbox{display:block;margin-bottom:8px;margin-left:5px}.custom-theme .el-table-filter__checkbox-group .el-checkbox:last-child{margin-bottom:0}.custom-theme .el-date-table{font-size:12px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.custom-theme .el-date-table.is-week-mode .el-date-table__row:hover div{background-color:#edf2fc}.custom-theme .el-date-table.is-week-mode .el-date-table__row:hover td.available:hover{color:#5a5e66}.custom-theme .el-date-table.is-week-mode .el-date-table__row:hover td:first-child div{margin-left:5px;border-top-left-radius:15px;border-bottom-left-radius:15px}.custom-theme .el-date-table.is-week-mode .el-date-table__row:hover td:last-child div{margin-right:5px;border-top-right-radius:15px;border-bottom-right-radius:15px}.custom-theme .el-date-table.is-week-mode .el-date-table__row.current div{background-color:#edf2fc}.custom-theme .el-date-table td{width:32px;height:30px;padding:4px 0;-webkit-box-sizing:border-box;box-sizing:border-box;text-align:center;cursor:pointer;position:relative}.custom-theme .el-date-table td div{height:30px;padding:3px 0;-webkit-box-sizing:border-box;box-sizing:border-box}.custom-theme .el-date-table td span{width:24px;height:24px;display:block;margin:0 auto;line-height:24px;position:absolute;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%);border-radius:50%}.custom-theme .el-date-table td.next-month,.custom-theme .el-date-table td.prev-month{color:#b4bccc}.custom-theme .el-date-table td.today{position:relative}.custom-theme .el-date-table td.today span{color:#262729}.custom-theme .el-date-table td.today.end-date span,.custom-theme .el-date-table td.today.start-date span{color:#fff}.custom-theme .el-date-table td.available:hover{color:#262729}.custom-theme .el-date-table td.in-range div{background-color:#edf2fc}.custom-theme .el-date-table td.in-range div:hover{background-color:#edf2fc}.custom-theme .el-date-table td.current:not(.disabled) span{color:#fff;background-color:#262729}.custom-theme .el-date-table td.end-date div,.custom-theme .el-date-table td.start-date div{color:#fff}.custom-theme .el-date-table td.end-date span,.custom-theme .el-date-table td.start-date span{background-color:#262729}.custom-theme .el-date-table td.start-date div{margin-left:5px;border-top-left-radius:15px;border-bottom-left-radius:15px}.custom-theme .el-date-table td.end-date div{margin-right:5px;border-top-right-radius:15px;border-bottom-right-radius:15px}.custom-theme .el-date-table td.disabled div{background-color:#f5f7fa;opacity:1;cursor:not-allowed;color:#b4bccc}.custom-theme .el-date-table td.week{font-size:80%;color:#5a5e66}.custom-theme .el-date-table th{padding:5px;color:#5a5e66;font-weight:400;border-bottom:solid 1px #e6ebf5}.custom-theme .el-month-table{font-size:12px;margin:-1px;border-collapse:collapse}.custom-theme .el-month-table td{text-align:center;padding:20px 3px;cursor:pointer}.custom-theme .el-month-table td.disabled .cell{background-color:#f5f7fa;cursor:not-allowed;color:#b4bccc}.custom-theme .el-month-table td.disabled .cell:hover{color:#b4bccc}.custom-theme .el-month-table td .cell{width:48px;height:32px;display:block;line-height:32px;color:#5a5e66;margin:0 auto}.custom-theme .el-month-table td .cell:hover{color:#262729}.custom-theme .el-month-table td.current:not(.disabled) .cell{color:#262729}.custom-theme .el-year-table{font-size:12px;margin:-1px;border-collapse:collapse}.custom-theme .el-year-table .el-icon{color:#2d2f33}.custom-theme .el-year-table td{text-align:center;padding:20px 3px;cursor:pointer}.custom-theme .el-year-table td.disabled .cell{background-color:#f5f7fa;cursor:not-allowed;color:#b4bccc}.custom-theme .el-year-table td.disabled .cell:hover{color:#b4bccc}.custom-theme .el-year-table td .cell{width:48px;height:32px;display:block;line-height:32px;color:#5a5e66;margin:0 auto}.custom-theme .el-year-table td .cell:hover{color:#262729}.custom-theme .el-year-table td.current:not(.disabled) .cell{color:#262729}.custom-theme .el-time-spinner.has-seconds .el-time-spinner__wrapper{width:33.3%}.custom-theme .el-time-spinner.has-seconds .el-time-spinner__wrapper:nth-child(2){margin-left:1%}.custom-theme .el-time-spinner__wrapper{max-height:190px;overflow:auto;display:inline-block;width:50%;vertical-align:top;position:relative}.custom-theme .el-time-spinner__wrapper .el-scrollbar__wrap:not(.el-scrollbar__wrap--hidden-default){padding-bottom:15px}.custom-theme .el-time-spinner__wrapper.is-arrow{-webkit-box-sizing:border-box;box-sizing:border-box;text-align:center;overflow:hidden}.custom-theme .el-time-spinner__wrapper.is-arrow .el-time-spinner__list{-webkit-transform:translateY(-32px);transform:translateY(-32px)}.custom-theme .el-time-spinner__wrapper.is-arrow .el-time-spinner__item:hover:not(.disabled):not(.active){background:#fff;cursor:default}.custom-theme .el-time-spinner__arrow{font-size:12px;color:#878d99;position:absolute;left:0;width:100%;z-index:1;text-align:center;height:30px;line-height:30px;cursor:pointer}.custom-theme .el-time-spinner__arrow:hover{color:#262729}.custom-theme .el-time-spinner__arrow.el-icon-arrow-up{top:10px}.custom-theme .el-time-spinner__arrow.el-icon-arrow-down{bottom:10px}.custom-theme .el-time-spinner__input.el-input{width:70%}.custom-theme .el-time-spinner__input.el-input .el-input__inner{padding:0;text-align:center}.custom-theme .el-time-spinner__list{padding:0;margin:0;list-style:none;text-align:center}.custom-theme .el-time-spinner__list::after,.custom-theme .el-time-spinner__list::before{content:'';display:block;width:100%;height:80px}.custom-theme .el-time-spinner__item{height:32px;line-height:32px;font-size:12px;color:#5a5e66}.custom-theme .el-time-spinner__item:hover:not(.disabled):not(.active){background:#f5f7fa;cursor:pointer}.custom-theme .el-time-spinner__item.active:not(.disabled){color:#2d2f33;font-weight:700}.custom-theme .el-time-spinner__item.disabled{color:#b4bccc;cursor:not-allowed}.custom-theme .fade-in-linear-enter-active,.custom-theme .fade-in-linear-leave-active{-webkit-transition:opacity .2s linear;transition:opacity .2s linear}.custom-theme .fade-in-linear-enter,.custom-theme .fade-in-linear-leave,.custom-theme .fade-in-linear-leave-active{opacity:0}.custom-theme .el-fade-in-linear-enter-active,.custom-theme .el-fade-in-linear-leave-active{-webkit-transition:opacity .2s linear;transition:opacity .2s linear}.custom-theme .el-fade-in-linear-enter,.custom-theme .el-fade-in-linear-leave,.custom-theme .el-fade-in-linear-leave-active{opacity:0}.custom-theme .el-fade-in-enter-active,.custom-theme .el-fade-in-leave-active{-webkit-transition:all .3s cubic-bezier(.55,0,.1,1);transition:all .3s cubic-bezier(.55,0,.1,1)}.custom-theme .el-fade-in-enter,.custom-theme .el-fade-in-leave-active{opacity:0}.custom-theme .el-zoom-in-center-enter-active,.custom-theme .el-zoom-in-center-leave-active{-webkit-transition:all .3s cubic-bezier(.55,0,.1,1);transition:all .3s cubic-bezier(.55,0,.1,1)}.custom-theme .el-zoom-in-center-enter,.custom-theme .el-zoom-in-center-leave-active{opacity:0;-webkit-transform:scaleX(0);transform:scaleX(0)}.custom-theme .el-zoom-in-top-enter-active,.custom-theme .el-zoom-in-top-leave-active{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;transition:opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;transition:transform .3s cubic-bezier(.23,1,.32,1) .1s,opacity .3s cubic-bezier(.23,1,.32,1) .1s;transition:transform .3s cubic-bezier(.23,1,.32,1) .1s,opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;-webkit-transform-origin:center top;transform-origin:center top}.custom-theme .el-zoom-in-top-enter,.custom-theme .el-zoom-in-top-leave-active{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.custom-theme .el-zoom-in-bottom-enter-active,.custom-theme .el-zoom-in-bottom-leave-active{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;transition:opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;transition:transform .3s cubic-bezier(.23,1,.32,1) .1s,opacity .3s cubic-bezier(.23,1,.32,1) .1s;transition:transform .3s cubic-bezier(.23,1,.32,1) .1s,opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;-webkit-transform-origin:center bottom;transform-origin:center bottom}.custom-theme .el-zoom-in-bottom-enter,.custom-theme .el-zoom-in-bottom-leave-active{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.custom-theme .el-zoom-in-left-enter-active,.custom-theme .el-zoom-in-left-leave-active{opacity:1;-webkit-transform:scale(1,1);transform:scale(1,1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;transition:opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;transition:transform .3s cubic-bezier(.23,1,.32,1) .1s,opacity .3s cubic-bezier(.23,1,.32,1) .1s;transition:transform .3s cubic-bezier(.23,1,.32,1) .1s,opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;-webkit-transform-origin:top left;transform-origin:top left}.custom-theme .el-zoom-in-left-enter,.custom-theme .el-zoom-in-left-leave-active{opacity:0;-webkit-transform:scale(.45,.45);transform:scale(.45,.45)}.custom-theme .collapse-transition{-webkit-transition:.3s height ease-in-out,.3s padding-top ease-in-out,.3s padding-bottom ease-in-out;transition:.3s height ease-in-out,.3s padding-top ease-in-out,.3s padding-bottom ease-in-out}.custom-theme .horizontal-collapse-transition{-webkit-transition:.3s width ease-in-out,.3s padding-left ease-in-out,.3s padding-right ease-in-out;transition:.3s width ease-in-out,.3s padding-left ease-in-out,.3s padding-right ease-in-out}.custom-theme .el-list-enter-active,.custom-theme .el-list-leave-active{-webkit-transition:all 1s;transition:all 1s}.custom-theme .el-list-enter,.custom-theme .el-list-leave-active{opacity:0;-webkit-transform:translateY(-30px);transform:translateY(-30px)}.custom-theme .el-opacity-transition{-webkit-transition:opacity .3s cubic-bezier(.55,0,.1,1);transition:opacity .3s cubic-bezier(.55,0,.1,1)}.custom-theme .el-date-editor{position:relative;display:inline-block;text-align:left}.custom-theme .el-date-editor.el-input,.custom-theme .el-date-editor.el-input__inner{width:220px}.custom-theme .el-date-editor--daterange.el-input,.custom-theme .el-date-editor--daterange.el-input__inner,.custom-theme .el-date-editor--timerange.el-input,.custom-theme .el-date-editor--timerange.el-input__inner{width:350px}.custom-theme .el-date-editor--datetimerange.el-input,.custom-theme .el-date-editor--datetimerange.el-input__inner{width:400px}.custom-theme .el-date-editor .el-range__icon{font-size:14px;margin-left:-5px;color:#b4bccc;float:left;line-height:32px}.custom-theme .el-date-editor .el-range-input{-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;outline:0;display:inline-block;height:100%;margin:0;padding:0;width:39%;text-align:center;font-size:14px;color:#5a5e66}.custom-theme .el-date-editor .el-range-input::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-date-editor .el-range-input:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-date-editor .el-range-input::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-date-editor .el-range-input::placeholder{color:#b4bccc}.custom-theme .el-date-editor .el-range-separator{display:inline-block;height:100%;padding:0 5px;margin:0;text-align:center;line-height:32px;font-size:14px;width:5%;color:#2d2f33}.custom-theme .el-date-editor .el-range__close-icon{font-size:14px;color:#b4bccc;width:25px;display:inline-block;float:right;line-height:32px}.custom-theme .el-range-editor.el-input__inner{padding:3px 10px}.custom-theme .el-range-editor.is-active{border-color:#262729}.custom-theme .el-range-editor.is-active:hover{border-color:#262729}.custom-theme .el-range-editor--medium.el-input__inner{height:36px}.custom-theme .el-range-editor--medium .el-range-separator{line-height:28px;font-size:14px}.custom-theme .el-range-editor--medium .el-range-input{font-size:14px}.custom-theme .el-range-editor--medium .el-range__close-icon,.custom-theme .el-range-editor--medium .el-range__icon{line-height:28px}.custom-theme .el-range-editor--small.el-input__inner{height:32px}.custom-theme .el-range-editor--small .el-range-separator{line-height:24px;font-size:13px}.custom-theme .el-range-editor--small .el-range-input{font-size:13px}.custom-theme .el-range-editor--small .el-range__close-icon,.custom-theme .el-range-editor--small .el-range__icon{line-height:24px}.custom-theme .el-range-editor--mini.el-input__inner{height:28px}.custom-theme .el-range-editor--mini .el-range-separator{line-height:20px;font-size:12px}.custom-theme .el-range-editor--mini .el-range-input{font-size:12px}.custom-theme .el-range-editor--mini .el-range__close-icon,.custom-theme .el-range-editor--mini .el-range__icon{line-height:20px}.custom-theme .el-range-editor.is-disabled{background-color:#f5f7fa;border-color:#dfe4ed;color:#b4bccc;cursor:not-allowed}.custom-theme .el-range-editor.is-disabled:focus,.custom-theme .el-range-editor.is-disabled:hover{border-color:#dfe4ed}.custom-theme .el-range-editor.is-disabled input{background-color:#f5f7fa;color:#b4bccc;cursor:not-allowed}.custom-theme .el-range-editor.is-disabled input::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-range-editor.is-disabled input:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-range-editor.is-disabled input::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-range-editor.is-disabled input::placeholder{color:#b4bccc}.custom-theme .el-range-editor.is-disabled .el-range-separator{color:#b4bccc}.custom-theme .el-picker-panel{color:#5a5e66;border:1px solid #dfe4ed;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);background:#fff;border-radius:4px;line-height:30px;margin:5px 0}.custom-theme .el-picker-panel__body-wrapper::after,.custom-theme .el-picker-panel__body::after{content:"";display:table;clear:both}.custom-theme .el-picker-panel__content{position:relative;margin:15px}.custom-theme .el-picker-panel__footer{border-top:1px solid #e4e4e4;padding:4px;text-align:right;background-color:#fff;position:relative;font-size:0}.custom-theme .el-picker-panel__shortcut{display:block;width:100%;border:0;background-color:transparent;line-height:28px;font-size:14px;color:#5a5e66;padding-left:12px;text-align:left;outline:0;cursor:pointer}.custom-theme .el-picker-panel__shortcut:hover{color:#262729}.custom-theme .el-picker-panel__shortcut.active{background-color:#e6f1fe;color:#262729}.custom-theme .el-picker-panel__btn{border:1px solid #dcdcdc;color:#333;line-height:24px;border-radius:2px;padding:0 20px;cursor:pointer;background-color:transparent;outline:0;font-size:12px}.custom-theme .el-picker-panel__btn[disabled]{color:#ccc;cursor:not-allowed}.custom-theme .el-picker-panel__icon-btn{font-size:12px;color:#2d2f33;border:0;background:0 0;cursor:pointer;outline:0;margin-top:8px}.custom-theme .el-picker-panel__icon-btn:hover{color:#262729}.custom-theme .el-picker-panel__icon-btn.is-disabled{color:#bbb}.custom-theme .el-picker-panel__icon-btn.is-disabled:hover{cursor:not-allowed}.custom-theme .el-picker-panel__link-btn{vertical-align:middle}.custom-theme .el-picker-panel .popper__arrow{-webkit-transform:translateX(-400%);transform:translateX(-400%)}.custom-theme .el-picker-panel [slot=sidebar],.custom-theme .el-picker-panel__sidebar{position:absolute;top:0;bottom:0;width:110px;border-right:1px solid #e4e4e4;-webkit-box-sizing:border-box;box-sizing:border-box;padding-top:6px;background-color:#fff;overflow:auto}.custom-theme .el-picker-panel [slot=sidebar]+.el-picker-panel__body,.custom-theme .el-picker-panel__sidebar+.el-picker-panel__body{margin-left:110px}.custom-theme .el-date-picker{width:322px}.custom-theme .el-date-picker.has-sidebar.has-time{width:434px}.custom-theme .el-date-picker.has-sidebar{width:438px}.custom-theme .el-date-picker.has-time .el-picker-panel__body-wrapper{position:relative}.custom-theme .el-date-picker .el-picker-panel__content{width:292px}.custom-theme .el-date-picker table{table-layout:fixed;width:100%}.custom-theme .el-date-picker__editor-wrap{position:relative;display:table-cell;padding:0 5px}.custom-theme .el-date-picker__time-header{position:relative;border-bottom:1px solid #e4e4e4;font-size:12px;padding:8px 5px 5px 5px;display:table;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}.custom-theme .el-date-picker__header{margin:12px;text-align:center}.custom-theme .el-date-picker__header--bordered{margin-bottom:0;padding-bottom:12px;border-bottom:solid 1px #e6ebf5}.custom-theme .el-date-picker__header--bordered+.el-picker-panel__content{margin-top:0}.custom-theme .el-date-picker__header-label{font-size:16px;font-weight:500;padding:0 5px;line-height:22px;text-align:center;cursor:pointer;color:#5a5e66}.custom-theme .el-date-picker__header-label:hover{color:#262729}.custom-theme .el-date-picker__header-label.active{color:#262729}.custom-theme .el-date-picker__prev-btn{float:left}.custom-theme .el-date-picker__next-btn{float:right}.custom-theme .el-date-picker__time-wrap{padding:10px;text-align:center}.custom-theme .el-date-picker__time-label{float:left;cursor:pointer;line-height:30px;margin-left:10px}.custom-theme .el-date-range-picker{width:646px}.custom-theme .el-date-range-picker.has-sidebar{width:756px}.custom-theme .el-date-range-picker table{table-layout:fixed;width:100%}.custom-theme .el-date-range-picker .el-picker-panel__body{min-width:513px}.custom-theme .el-date-range-picker .el-picker-panel__content{margin:0}.custom-theme .el-date-range-picker__header{position:relative;text-align:center;height:28px}.custom-theme .el-date-range-picker__header [class*=arrow-left]{float:left}.custom-theme .el-date-range-picker__header [class*=arrow-right]{float:right}.custom-theme .el-date-range-picker__header div{font-size:16px;font-weight:500;margin-right:50px}.custom-theme .el-date-range-picker__content{float:left;width:50%;-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;padding:16px}.custom-theme .el-date-range-picker__content.is-left{border-right:1px solid #e4e4e4}.custom-theme .el-date-range-picker__content.is-right .el-date-range-picker__header div{margin-left:50px;margin-right:50px}.custom-theme .el-date-range-picker__editors-wrap{-webkit-box-sizing:border-box;box-sizing:border-box;display:table-cell}.custom-theme .el-date-range-picker__editors-wrap.is-right{text-align:right}.custom-theme .el-date-range-picker__time-header{position:relative;border-bottom:1px solid #e4e4e4;font-size:12px;padding:8px 5px 5px 5px;display:table;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}.custom-theme .el-date-range-picker__time-header>.el-icon-arrow-right{font-size:20px;vertical-align:middle;display:table-cell;color:#2d2f33}.custom-theme .el-date-range-picker__time-picker-wrap{position:relative;display:table-cell;padding:0 5px}.custom-theme .el-date-range-picker__time-picker-wrap .el-picker-panel{position:absolute;top:13px;right:0;z-index:1;background:#fff}.custom-theme .el-time-range-picker{width:354px;overflow:visible}.custom-theme .el-time-range-picker__content{position:relative;text-align:center;padding:10px}.custom-theme .el-time-range-picker__cell{-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;padding:4px 7px 7px;width:50%;display:inline-block}.custom-theme .el-time-range-picker__header{margin-bottom:5px;text-align:center;font-size:14px}.custom-theme .el-time-range-picker__body{border-radius:2px;border:1px solid #dfe4ed}.custom-theme .el-time-panel{margin:5px 0;border:solid 1px #dfe4ed;background-color:#fff;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);border-radius:2px;position:absolute;width:180px;left:0;z-index:1000;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.custom-theme .el-time-panel__content{font-size:0;position:relative;overflow:hidden}.custom-theme .el-time-panel__content::after,.custom-theme .el-time-panel__content::before{content:"";top:50%;position:absolute;margin-top:-15px;height:32px;z-index:-1;left:0;right:0;-webkit-box-sizing:border-box;box-sizing:border-box;padding-top:6px;text-align:left;border-top:1px solid #dfe4ed;border-bottom:1px solid #dfe4ed}.custom-theme .el-time-panel__content::after{left:50%;margin-left:12%;margin-right:12%}.custom-theme .el-time-panel__content::before{padding-left:50%;margin-right:12%;margin-left:12%}.custom-theme .el-time-panel__content.has-seconds::after{left:calc(100% / 3 * 2)}.custom-theme .el-time-panel__content.has-seconds::before{padding-left:calc(100% / 3)}.custom-theme .el-time-panel__footer{border-top:1px solid #e4e4e4;padding:4px;height:36px;line-height:25px;text-align:right;-webkit-box-sizing:border-box;box-sizing:border-box}.custom-theme .el-time-panel__btn{border:none;line-height:28px;padding:0 5px;margin:0 5px;cursor:pointer;background-color:transparent;outline:0;font-size:12px;color:#2d2f33}.custom-theme .el-time-panel__btn.confirm{font-weight:800;color:#262729}.custom-theme .el-time-panel .popper__arrow{-webkit-transform:translateX(-400%);transform:translateX(-400%)}.custom-theme .el-input{position:relative;font-size:14px;display:inline-block;width:100%}.custom-theme .el-input::-webkit-scrollbar{z-index:11;width:6px}.custom-theme .el-input::-webkit-scrollbar:horizontal{height:6px}.custom-theme .el-input::-webkit-scrollbar-thumb{border-radius:5px;width:6px;background:#b4bccc}.custom-theme .el-input::-webkit-scrollbar-corner{background:#fff}.custom-theme .el-input::-webkit-scrollbar-track{background:#fff}.custom-theme .el-input::-webkit-scrollbar-track-piece{background:#fff;width:6px}.custom-theme .el-input__inner{-webkit-appearance:none;background-color:#fff;background-image:none;border-radius:4px;border:1px solid #d8dce5;-webkit-box-sizing:border-box;box-sizing:border-box;color:#5a5e66;display:inline-block;font-size:inherit;height:40px;line-height:1;outline:0;padding:0 15px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1);width:100%}.custom-theme .el-input__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner::placeholder{color:#b4bccc}.custom-theme .el-input__inner:hover{border-color:#b4bccc}.custom-theme .el-input__inner:focus{outline:0;border-color:#262729}.custom-theme .el-input__suffix{position:absolute;height:100%;right:5px;top:0;text-align:center;color:#b4bccc;-webkit-transition:all .3s;transition:all .3s;pointer-events:none}.custom-theme .el-input__suffix-inner{pointer-events:all}.custom-theme .el-input__prefix{position:absolute;height:100%;left:5px;top:0;text-align:center;color:#b4bccc;-webkit-transition:all .3s;transition:all .3s}.custom-theme .el-input__icon{height:100%;width:25px;text-align:center;-webkit-transition:all .3s;transition:all .3s;line-height:40px}.custom-theme .el-input__icon:after{content:'';height:100%;width:0;display:inline-block;vertical-align:middle}.custom-theme .el-input__validateIcon{pointer-events:none}.custom-theme .el-input.is-active .el-input__inner{outline:0;border-color:#262729}.custom-theme .el-input.is-disabled .el-input__inner{background-color:#f5f7fa;border-color:#dfe4ed;color:#b4bccc;cursor:not-allowed}.custom-theme .el-input.is-disabled .el-input__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner::placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__icon{cursor:not-allowed}.custom-theme .el-input--suffix .el-input__inner{padding-right:30px}.custom-theme .el-input--prefix .el-input__inner{padding-left:30px}.custom-theme .el-input--medium{font-size:14px}.custom-theme .el-input--medium .el-input__inner{height:36px}.custom-theme .el-input--medium .el-input__icon{line-height:36px}.custom-theme .el-input--small{font-size:13px}.custom-theme .el-input--small .el-input__inner{height:32px}.custom-theme .el-input--small .el-input__icon{line-height:32px}.custom-theme .el-input--mini{font-size:12px}.custom-theme .el-input--mini .el-input__inner{height:28px}.custom-theme .el-input--mini .el-input__icon{line-height:28px}.custom-theme .el-input-group{line-height:normal;display:inline-table;width:100%;border-collapse:separate}.custom-theme .el-input-group>.el-input__inner{vertical-align:middle;display:table-cell}.custom-theme .el-input-group__append,.custom-theme .el-input-group__prepend{background-color:#f5f7fa;color:#0a76a4;vertical-align:middle;display:table-cell;position:relative;border:1px solid #d8dce5;border-radius:4px;padding:0 20px;width:1px;white-space:nowrap}.custom-theme .el-input-group__append:focus,.custom-theme .el-input-group__prepend:focus{outline:0}.custom-theme .el-input-group__append .el-button,.custom-theme .el-input-group__append .el-select,.custom-theme .el-input-group__prepend .el-button,.custom-theme .el-input-group__prepend .el-select{display:inline-block;margin:-20px}.custom-theme .el-input-group__append button.el-button,.custom-theme .el-input-group__append div.el-select .el-input__inner,.custom-theme .el-input-group__append div.el-select:hover .el-input__inner,.custom-theme .el-input-group__prepend button.el-button,.custom-theme .el-input-group__prepend div.el-select .el-input__inner,.custom-theme .el-input-group__prepend div.el-select:hover .el-input__inner{border-color:transparent;background-color:transparent;color:inherit;border-top:0;border-bottom:0}.custom-theme .el-input-group__append .el-button,.custom-theme .el-input-group__append .el-input,.custom-theme .el-input-group__prepend .el-button,.custom-theme .el-input-group__prepend .el-input{font-size:inherit}.custom-theme .el-input-group__prepend{border-right:0;border-top-right-radius:0;border-bottom-right-radius:0}.custom-theme .el-input-group__append{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.custom-theme .el-input-group--prepend .el-input__inner{border-top-left-radius:0;border-bottom-left-radius:0}.custom-theme .el-input-group--append .el-input__inner{border-top-right-radius:0;border-bottom-right-radius:0}.custom-theme .el-textarea{display:inline-block;width:100%;vertical-align:bottom}.custom-theme .el-textarea__inner{display:block;resize:vertical;padding:5px 15px;line-height:1.5;-webkit-box-sizing:border-box;box-sizing:border-box;width:100%;font-size:14px;color:#5a5e66;background-color:#fff;background-image:none;border:1px solid #d8dce5;border-radius:4px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1)}.custom-theme .el-textarea__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner::placeholder{color:#b4bccc}.custom-theme .el-textarea__inner:hover{border-color:#b4bccc}.custom-theme .el-textarea__inner:focus{outline:0;border-color:#262729}.custom-theme .el-textarea.is-disabled .el-textarea__inner{background-color:#f5f7fa;border-color:#dfe4ed;color:#b4bccc;cursor:not-allowed}.custom-theme .el-textarea.is-disabled .el-textarea__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner::placeholder{color:#b4bccc}.custom-theme .el-scrollbar{overflow:hidden;position:relative}.custom-theme .el-scrollbar:active>.el-scrollbar__bar,.custom-theme .el-scrollbar:focus>.el-scrollbar__bar,.custom-theme .el-scrollbar:hover>.el-scrollbar__bar{opacity:1;-webkit-transition:opacity 340ms ease-out;transition:opacity 340ms ease-out}.custom-theme .el-scrollbar__wrap{overflow:scroll;height:100%}.custom-theme .el-scrollbar__wrap--hidden-default::-webkit-scrollbar{width:0;height:0}.custom-theme .el-scrollbar__thumb{position:relative;display:block;width:0;height:0;cursor:pointer;border-radius:inherit;background-color:rgba(135,141,153,.3);-webkit-transition:.3s background-color;transition:.3s background-color}.custom-theme .el-scrollbar__thumb:hover{background-color:rgba(135,141,153,.5)}.custom-theme .el-scrollbar__bar{position:absolute;right:2px;bottom:2px;z-index:1;border-radius:4px;opacity:0;-webkit-transition:opacity 120ms ease-out;transition:opacity 120ms ease-out}.custom-theme .el-scrollbar__bar.is-vertical{width:6px;top:2px}.custom-theme .el-scrollbar__bar.is-vertical>div{width:100%}.custom-theme .el-scrollbar__bar.is-horizontal{height:6px;left:2px}.custom-theme .el-scrollbar__bar.is-horizontal>div{height:100%}.custom-theme .el-popper .popper__arrow,.custom-theme .el-popper .popper__arrow::after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.custom-theme .el-popper .popper__arrow{border-width:6px;-webkit-filter:drop-shadow(0 2px 12px rgba(0, 0, 0, .03));filter:drop-shadow(0 2px 12px rgba(0, 0, 0, .03))}.custom-theme .el-popper .popper__arrow::after{content:" ";border-width:6px}.custom-theme .el-popper[x-placement^=top]{margin-bottom:12px}.custom-theme .el-popper[x-placement^=top] .popper__arrow{bottom:-6px;left:50%;margin-right:3px;border-top-color:#e6ebf5;border-bottom-width:0}.custom-theme .el-popper[x-placement^=top] .popper__arrow::after{bottom:1px;margin-left:-6px;border-top-color:#fff;border-bottom-width:0}.custom-theme .el-popper[x-placement^=bottom]{margin-top:12px}.custom-theme .el-popper[x-placement^=bottom] .popper__arrow{top:-6px;left:50%;margin-right:3px;border-top-width:0;border-bottom-color:#e6ebf5}.custom-theme .el-popper[x-placement^=bottom] .popper__arrow::after{top:1px;margin-left:-6px;border-top-width:0;border-bottom-color:#fff}.custom-theme .el-popper[x-placement^=right]{margin-left:12px}.custom-theme .el-popper[x-placement^=right] .popper__arrow{top:50%;left:-6px;margin-bottom:3px;border-right-color:#e6ebf5;border-left-width:0}.custom-theme .el-popper[x-placement^=right] .popper__arrow::after{bottom:-6px;left:1px;border-right-color:#fff;border-left-width:0}.custom-theme .el-popper[x-placement^=left]{margin-right:12px}.custom-theme .el-popper[x-placement^=left] .popper__arrow{top:50%;right:-6px;margin-bottom:3px;border-right-width:0;border-left-color:#e6ebf5}.custom-theme .el-popper[x-placement^=left] .popper__arrow::after{right:1px;bottom:-6px;margin-left:-6px;border-right-width:0;border-left-color:#fff}.custom-theme .fade-in-linear-enter-active,.custom-theme .fade-in-linear-leave-active{-webkit-transition:opacity .2s linear;transition:opacity .2s linear}.custom-theme .fade-in-linear-enter,.custom-theme .fade-in-linear-leave,.custom-theme .fade-in-linear-leave-active{opacity:0}.custom-theme .el-fade-in-linear-enter-active,.custom-theme .el-fade-in-linear-leave-active{-webkit-transition:opacity .2s linear;transition:opacity .2s linear}.custom-theme .el-fade-in-linear-enter,.custom-theme .el-fade-in-linear-leave,.custom-theme .el-fade-in-linear-leave-active{opacity:0}.custom-theme .el-fade-in-enter-active,.custom-theme .el-fade-in-leave-active{-webkit-transition:all .3s cubic-bezier(.55,0,.1,1);transition:all .3s cubic-bezier(.55,0,.1,1)}.custom-theme .el-fade-in-enter,.custom-theme .el-fade-in-leave-active{opacity:0}.custom-theme .el-zoom-in-center-enter-active,.custom-theme .el-zoom-in-center-leave-active{-webkit-transition:all .3s cubic-bezier(.55,0,.1,1);transition:all .3s cubic-bezier(.55,0,.1,1)}.custom-theme .el-zoom-in-center-enter,.custom-theme .el-zoom-in-center-leave-active{opacity:0;-webkit-transform:scaleX(0);transform:scaleX(0)}.custom-theme .el-zoom-in-top-enter-active,.custom-theme .el-zoom-in-top-leave-active{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;transition:opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;transition:transform .3s cubic-bezier(.23,1,.32,1) .1s,opacity .3s cubic-bezier(.23,1,.32,1) .1s;transition:transform .3s cubic-bezier(.23,1,.32,1) .1s,opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;-webkit-transform-origin:center top;transform-origin:center top}.custom-theme .el-zoom-in-top-enter,.custom-theme .el-zoom-in-top-leave-active{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.custom-theme .el-zoom-in-bottom-enter-active,.custom-theme .el-zoom-in-bottom-leave-active{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;transition:opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;transition:transform .3s cubic-bezier(.23,1,.32,1) .1s,opacity .3s cubic-bezier(.23,1,.32,1) .1s;transition:transform .3s cubic-bezier(.23,1,.32,1) .1s,opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;-webkit-transform-origin:center bottom;transform-origin:center bottom}.custom-theme .el-zoom-in-bottom-enter,.custom-theme .el-zoom-in-bottom-leave-active{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.custom-theme .el-zoom-in-left-enter-active,.custom-theme .el-zoom-in-left-leave-active{opacity:1;-webkit-transform:scale(1,1);transform:scale(1,1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;transition:opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;transition:transform .3s cubic-bezier(.23,1,.32,1) .1s,opacity .3s cubic-bezier(.23,1,.32,1) .1s;transition:transform .3s cubic-bezier(.23,1,.32,1) .1s,opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;-webkit-transform-origin:top left;transform-origin:top left}.custom-theme .el-zoom-in-left-enter,.custom-theme .el-zoom-in-left-leave-active{opacity:0;-webkit-transform:scale(.45,.45);transform:scale(.45,.45)}.custom-theme .collapse-transition{-webkit-transition:.3s height ease-in-out,.3s padding-top ease-in-out,.3s padding-bottom ease-in-out;transition:.3s height ease-in-out,.3s padding-top ease-in-out,.3s padding-bottom ease-in-out}.custom-theme .horizontal-collapse-transition{-webkit-transition:.3s width ease-in-out,.3s padding-left ease-in-out,.3s padding-right ease-in-out;transition:.3s width ease-in-out,.3s padding-left ease-in-out,.3s padding-right ease-in-out}.custom-theme .el-list-enter-active,.custom-theme .el-list-leave-active{-webkit-transition:all 1s;transition:all 1s}.custom-theme .el-list-enter,.custom-theme .el-list-leave-active{opacity:0;-webkit-transform:translateY(-30px);transform:translateY(-30px)}.custom-theme .el-opacity-transition{-webkit-transition:opacity .3s cubic-bezier(.55,0,.1,1);transition:opacity .3s cubic-bezier(.55,0,.1,1)}.custom-theme .el-date-editor{position:relative;display:inline-block;text-align:left}.custom-theme .el-date-editor.el-input,.custom-theme .el-date-editor.el-input__inner{width:220px}.custom-theme .el-date-editor--daterange.el-input,.custom-theme .el-date-editor--daterange.el-input__inner,.custom-theme .el-date-editor--timerange.el-input,.custom-theme .el-date-editor--timerange.el-input__inner{width:350px}.custom-theme .el-date-editor--datetimerange.el-input,.custom-theme .el-date-editor--datetimerange.el-input__inner{width:400px}.custom-theme .el-date-editor .el-range__icon{font-size:14px;margin-left:-5px;color:#b4bccc;float:left;line-height:32px}.custom-theme .el-date-editor .el-range-input{-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;outline:0;display:inline-block;height:100%;margin:0;padding:0;width:39%;text-align:center;font-size:14px;color:#5a5e66}.custom-theme .el-date-editor .el-range-input::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-date-editor .el-range-input:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-date-editor .el-range-input::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-date-editor .el-range-input::placeholder{color:#b4bccc}.custom-theme .el-date-editor .el-range-separator{display:inline-block;height:100%;padding:0 5px;margin:0;text-align:center;line-height:32px;font-size:14px;width:5%;color:#2d2f33}.custom-theme .el-date-editor .el-range__close-icon{font-size:14px;color:#b4bccc;width:25px;display:inline-block;float:right;line-height:32px}.custom-theme .el-range-editor.el-input__inner{padding:3px 10px}.custom-theme .el-range-editor.is-active{border-color:#262729}.custom-theme .el-range-editor.is-active:hover{border-color:#262729}.custom-theme .el-range-editor--medium.el-input__inner{height:36px}.custom-theme .el-range-editor--medium .el-range-separator{line-height:28px;font-size:14px}.custom-theme .el-range-editor--medium .el-range-input{font-size:14px}.custom-theme .el-range-editor--medium .el-range__close-icon,.custom-theme .el-range-editor--medium .el-range__icon{line-height:28px}.custom-theme .el-range-editor--small.el-input__inner{height:32px}.custom-theme .el-range-editor--small .el-range-separator{line-height:24px;font-size:13px}.custom-theme .el-range-editor--small .el-range-input{font-size:13px}.custom-theme .el-range-editor--small .el-range__close-icon,.custom-theme .el-range-editor--small .el-range__icon{line-height:24px}.custom-theme .el-range-editor--mini.el-input__inner{height:28px}.custom-theme .el-range-editor--mini .el-range-separator{line-height:20px;font-size:12px}.custom-theme .el-range-editor--mini .el-range-input{font-size:12px}.custom-theme .el-range-editor--mini .el-range__close-icon,.custom-theme .el-range-editor--mini .el-range__icon{line-height:20px}.custom-theme .el-range-editor.is-disabled{background-color:#f5f7fa;border-color:#dfe4ed;color:#b4bccc;cursor:not-allowed}.custom-theme .el-range-editor.is-disabled:focus,.custom-theme .el-range-editor.is-disabled:hover{border-color:#dfe4ed}.custom-theme .el-range-editor.is-disabled input{background-color:#f5f7fa;color:#b4bccc;cursor:not-allowed}.custom-theme .el-range-editor.is-disabled input::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-range-editor.is-disabled input:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-range-editor.is-disabled input::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-range-editor.is-disabled input::placeholder{color:#b4bccc}.custom-theme .el-range-editor.is-disabled .el-range-separator{color:#b4bccc}.custom-theme .el-picker-panel{color:#5a5e66;border:1px solid #dfe4ed;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);background:#fff;border-radius:4px;line-height:30px;margin:5px 0}.custom-theme .el-picker-panel__body-wrapper::after,.custom-theme .el-picker-panel__body::after{content:"";display:table;clear:both}.custom-theme .el-picker-panel__content{position:relative;margin:15px}.custom-theme .el-picker-panel__footer{border-top:1px solid #e4e4e4;padding:4px;text-align:right;background-color:#fff;position:relative;font-size:0}.custom-theme .el-picker-panel__shortcut{display:block;width:100%;border:0;background-color:transparent;line-height:28px;font-size:14px;color:#5a5e66;padding-left:12px;text-align:left;outline:0;cursor:pointer}.custom-theme .el-picker-panel__shortcut:hover{color:#262729}.custom-theme .el-picker-panel__shortcut.active{background-color:#e6f1fe;color:#262729}.custom-theme .el-picker-panel__btn{border:1px solid #dcdcdc;color:#333;line-height:24px;border-radius:2px;padding:0 20px;cursor:pointer;background-color:transparent;outline:0;font-size:12px}.custom-theme .el-picker-panel__btn[disabled]{color:#ccc;cursor:not-allowed}.custom-theme .el-picker-panel__icon-btn{font-size:12px;color:#2d2f33;border:0;background:0 0;cursor:pointer;outline:0;margin-top:8px}.custom-theme .el-picker-panel__icon-btn:hover{color:#262729}.custom-theme .el-picker-panel__icon-btn.is-disabled{color:#bbb}.custom-theme .el-picker-panel__icon-btn.is-disabled:hover{cursor:not-allowed}.custom-theme .el-picker-panel__link-btn{vertical-align:middle}.custom-theme .el-picker-panel .popper__arrow{-webkit-transform:translateX(-400%);transform:translateX(-400%)}.custom-theme .el-picker-panel [slot=sidebar],.custom-theme .el-picker-panel__sidebar{position:absolute;top:0;bottom:0;width:110px;border-right:1px solid #e4e4e4;-webkit-box-sizing:border-box;box-sizing:border-box;padding-top:6px;background-color:#fff;overflow:auto}.custom-theme .el-picker-panel [slot=sidebar]+.el-picker-panel__body,.custom-theme .el-picker-panel__sidebar+.el-picker-panel__body{margin-left:110px}.custom-theme .el-date-picker{width:322px}.custom-theme .el-date-picker.has-sidebar.has-time{width:434px}.custom-theme .el-date-picker.has-sidebar{width:438px}.custom-theme .el-date-picker.has-time .el-picker-panel__body-wrapper{position:relative}.custom-theme .el-date-picker .el-picker-panel__content{width:292px}.custom-theme .el-date-picker table{table-layout:fixed;width:100%}.custom-theme .el-date-picker__editor-wrap{position:relative;display:table-cell;padding:0 5px}.custom-theme .el-date-picker__time-header{position:relative;border-bottom:1px solid #e4e4e4;font-size:12px;padding:8px 5px 5px 5px;display:table;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}.custom-theme .el-date-picker__header{margin:12px;text-align:center}.custom-theme .el-date-picker__header--bordered{margin-bottom:0;padding-bottom:12px;border-bottom:solid 1px #e6ebf5}.custom-theme .el-date-picker__header--bordered+.el-picker-panel__content{margin-top:0}.custom-theme .el-date-picker__header-label{font-size:16px;font-weight:500;padding:0 5px;line-height:22px;text-align:center;cursor:pointer;color:#5a5e66}.custom-theme .el-date-picker__header-label:hover{color:#262729}.custom-theme .el-date-picker__header-label.active{color:#262729}.custom-theme .el-date-picker__prev-btn{float:left}.custom-theme .el-date-picker__next-btn{float:right}.custom-theme .el-date-picker__time-wrap{padding:10px;text-align:center}.custom-theme .el-date-picker__time-label{float:left;cursor:pointer;line-height:30px;margin-left:10px}.custom-theme .el-scrollbar{overflow:hidden;position:relative}.custom-theme .el-scrollbar:active>.el-scrollbar__bar,.custom-theme .el-scrollbar:focus>.el-scrollbar__bar,.custom-theme .el-scrollbar:hover>.el-scrollbar__bar{opacity:1;-webkit-transition:opacity 340ms ease-out;transition:opacity 340ms ease-out}.custom-theme .el-scrollbar__wrap{overflow:scroll;height:100%}.custom-theme .el-scrollbar__wrap--hidden-default::-webkit-scrollbar{width:0;height:0}.custom-theme .el-scrollbar__thumb{position:relative;display:block;width:0;height:0;cursor:pointer;border-radius:inherit;background-color:rgba(135,141,153,.3);-webkit-transition:.3s background-color;transition:.3s background-color}.custom-theme .el-scrollbar__thumb:hover{background-color:rgba(135,141,153,.5)}.custom-theme .el-scrollbar__bar{position:absolute;right:2px;bottom:2px;z-index:1;border-radius:4px;opacity:0;-webkit-transition:opacity 120ms ease-out;transition:opacity 120ms ease-out}.custom-theme .el-scrollbar__bar.is-vertical{width:6px;top:2px}.custom-theme .el-scrollbar__bar.is-vertical>div{width:100%}.custom-theme .el-scrollbar__bar.is-horizontal{height:6px;left:2px}.custom-theme .el-scrollbar__bar.is-horizontal>div{height:100%}.custom-theme .el-popper .popper__arrow,.custom-theme .el-popper .popper__arrow::after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.custom-theme .el-popper .popper__arrow{border-width:6px;-webkit-filter:drop-shadow(0 2px 12px rgba(0, 0, 0, .03));filter:drop-shadow(0 2px 12px rgba(0, 0, 0, .03))}.custom-theme .el-popper .popper__arrow::after{content:" ";border-width:6px}.custom-theme .el-popper[x-placement^=top]{margin-bottom:12px}.custom-theme .el-popper[x-placement^=top] .popper__arrow{bottom:-6px;left:50%;margin-right:3px;border-top-color:#e6ebf5;border-bottom-width:0}.custom-theme .el-popper[x-placement^=top] .popper__arrow::after{bottom:1px;margin-left:-6px;border-top-color:#fff;border-bottom-width:0}.custom-theme .el-popper[x-placement^=bottom]{margin-top:12px}.custom-theme .el-popper[x-placement^=bottom] .popper__arrow{top:-6px;left:50%;margin-right:3px;border-top-width:0;border-bottom-color:#e6ebf5}.custom-theme .el-popper[x-placement^=bottom] .popper__arrow::after{top:1px;margin-left:-6px;border-top-width:0;border-bottom-color:#fff}.custom-theme .el-popper[x-placement^=right]{margin-left:12px}.custom-theme .el-popper[x-placement^=right] .popper__arrow{top:50%;left:-6px;margin-bottom:3px;border-right-color:#e6ebf5;border-left-width:0}.custom-theme .el-popper[x-placement^=right] .popper__arrow::after{bottom:-6px;left:1px;border-right-color:#fff;border-left-width:0}.custom-theme .el-popper[x-placement^=left]{margin-right:12px}.custom-theme .el-popper[x-placement^=left] .popper__arrow{top:50%;right:-6px;margin-bottom:3px;border-right-width:0;border-left-color:#e6ebf5}.custom-theme .el-popper[x-placement^=left] .popper__arrow::after{right:1px;bottom:-6px;margin-left:-6px;border-right-width:0;border-left-color:#fff}.custom-theme .time-select{margin:5px 0;min-width:0}.custom-theme .time-select .el-picker-panel__content{max-height:200px;margin:0}.custom-theme .time-select-item{padding:8px 10px;font-size:14px;line-height:20px}.custom-theme .time-select-item.selected:not(.disabled){color:#262729;font-weight:700}.custom-theme .time-select-item.disabled{color:#dfe4ed;cursor:not-allowed}.custom-theme .time-select-item:hover{background-color:#f5f7fa;font-weight:700;cursor:pointer}.custom-theme .fade-in-linear-enter-active,.custom-theme .fade-in-linear-leave-active{-webkit-transition:opacity .2s linear;transition:opacity .2s linear}.custom-theme .fade-in-linear-enter,.custom-theme .fade-in-linear-leave,.custom-theme .fade-in-linear-leave-active{opacity:0}.custom-theme .el-fade-in-linear-enter-active,.custom-theme .el-fade-in-linear-leave-active{-webkit-transition:opacity .2s linear;transition:opacity .2s linear}.custom-theme .el-fade-in-linear-enter,.custom-theme .el-fade-in-linear-leave,.custom-theme .el-fade-in-linear-leave-active{opacity:0}.custom-theme .el-fade-in-enter-active,.custom-theme .el-fade-in-leave-active{-webkit-transition:all .3s cubic-bezier(.55,0,.1,1);transition:all .3s cubic-bezier(.55,0,.1,1)}.custom-theme .el-fade-in-enter,.custom-theme .el-fade-in-leave-active{opacity:0}.custom-theme .el-zoom-in-center-enter-active,.custom-theme .el-zoom-in-center-leave-active{-webkit-transition:all .3s cubic-bezier(.55,0,.1,1);transition:all .3s cubic-bezier(.55,0,.1,1)}.custom-theme .el-zoom-in-center-enter,.custom-theme .el-zoom-in-center-leave-active{opacity:0;-webkit-transform:scaleX(0);transform:scaleX(0)}.custom-theme .el-zoom-in-top-enter-active,.custom-theme .el-zoom-in-top-leave-active{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;transition:opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;transition:transform .3s cubic-bezier(.23,1,.32,1) .1s,opacity .3s cubic-bezier(.23,1,.32,1) .1s;transition:transform .3s cubic-bezier(.23,1,.32,1) .1s,opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;-webkit-transform-origin:center top;transform-origin:center top}.custom-theme .el-zoom-in-top-enter,.custom-theme .el-zoom-in-top-leave-active{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.custom-theme .el-zoom-in-bottom-enter-active,.custom-theme .el-zoom-in-bottom-leave-active{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;transition:opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;transition:transform .3s cubic-bezier(.23,1,.32,1) .1s,opacity .3s cubic-bezier(.23,1,.32,1) .1s;transition:transform .3s cubic-bezier(.23,1,.32,1) .1s,opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;-webkit-transform-origin:center bottom;transform-origin:center bottom}.custom-theme .el-zoom-in-bottom-enter,.custom-theme .el-zoom-in-bottom-leave-active{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.custom-theme .el-zoom-in-left-enter-active,.custom-theme .el-zoom-in-left-leave-active{opacity:1;-webkit-transform:scale(1,1);transform:scale(1,1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;transition:opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;transition:transform .3s cubic-bezier(.23,1,.32,1) .1s,opacity .3s cubic-bezier(.23,1,.32,1) .1s;transition:transform .3s cubic-bezier(.23,1,.32,1) .1s,opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;-webkit-transform-origin:top left;transform-origin:top left}.custom-theme .el-zoom-in-left-enter,.custom-theme .el-zoom-in-left-leave-active{opacity:0;-webkit-transform:scale(.45,.45);transform:scale(.45,.45)}.custom-theme .collapse-transition{-webkit-transition:.3s height ease-in-out,.3s padding-top ease-in-out,.3s padding-bottom ease-in-out;transition:.3s height ease-in-out,.3s padding-top ease-in-out,.3s padding-bottom ease-in-out}.custom-theme .horizontal-collapse-transition{-webkit-transition:.3s width ease-in-out,.3s padding-left ease-in-out,.3s padding-right ease-in-out;transition:.3s width ease-in-out,.3s padding-left ease-in-out,.3s padding-right ease-in-out}.custom-theme .el-list-enter-active,.custom-theme .el-list-leave-active{-webkit-transition:all 1s;transition:all 1s}.custom-theme .el-list-enter,.custom-theme .el-list-leave-active{opacity:0;-webkit-transform:translateY(-30px);transform:translateY(-30px)}.custom-theme .el-opacity-transition{-webkit-transition:opacity .3s cubic-bezier(.55,0,.1,1);transition:opacity .3s cubic-bezier(.55,0,.1,1)}.custom-theme .el-date-editor{position:relative;display:inline-block;text-align:left}.custom-theme .el-date-editor.el-input,.custom-theme .el-date-editor.el-input__inner{width:220px}.custom-theme .el-date-editor--daterange.el-input,.custom-theme .el-date-editor--daterange.el-input__inner,.custom-theme .el-date-editor--timerange.el-input,.custom-theme .el-date-editor--timerange.el-input__inner{width:350px}.custom-theme .el-date-editor--datetimerange.el-input,.custom-theme .el-date-editor--datetimerange.el-input__inner{width:400px}.custom-theme .el-date-editor .el-range__icon{font-size:14px;margin-left:-5px;color:#b4bccc;float:left;line-height:32px}.custom-theme .el-date-editor .el-range-input{-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;outline:0;display:inline-block;height:100%;margin:0;padding:0;width:39%;text-align:center;font-size:14px;color:#5a5e66}.custom-theme .el-date-editor .el-range-input::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-date-editor .el-range-input:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-date-editor .el-range-input::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-date-editor .el-range-input::placeholder{color:#b4bccc}.custom-theme .el-date-editor .el-range-separator{display:inline-block;height:100%;padding:0 5px;margin:0;text-align:center;line-height:32px;font-size:14px;width:5%;color:#2d2f33}.custom-theme .el-date-editor .el-range__close-icon{font-size:14px;color:#b4bccc;width:25px;display:inline-block;float:right;line-height:32px}.custom-theme .el-range-editor.el-input__inner{padding:3px 10px}.custom-theme .el-range-editor.is-active{border-color:#262729}.custom-theme .el-range-editor.is-active:hover{border-color:#262729}.custom-theme .el-range-editor--medium.el-input__inner{height:36px}.custom-theme .el-range-editor--medium .el-range-separator{line-height:28px;font-size:14px}.custom-theme .el-range-editor--medium .el-range-input{font-size:14px}.custom-theme .el-range-editor--medium .el-range__close-icon,.custom-theme .el-range-editor--medium .el-range__icon{line-height:28px}.custom-theme .el-range-editor--small.el-input__inner{height:32px}.custom-theme .el-range-editor--small .el-range-separator{line-height:24px;font-size:13px}.custom-theme .el-range-editor--small .el-range-input{font-size:13px}.custom-theme .el-range-editor--small .el-range__close-icon,.custom-theme .el-range-editor--small .el-range__icon{line-height:24px}.custom-theme .el-range-editor--mini.el-input__inner{height:28px}.custom-theme .el-range-editor--mini .el-range-separator{line-height:20px;font-size:12px}.custom-theme .el-range-editor--mini .el-range-input{font-size:12px}.custom-theme .el-range-editor--mini .el-range__close-icon,.custom-theme .el-range-editor--mini .el-range__icon{line-height:20px}.custom-theme .el-range-editor.is-disabled{background-color:#f5f7fa;border-color:#dfe4ed;color:#b4bccc;cursor:not-allowed}.custom-theme .el-range-editor.is-disabled:focus,.custom-theme .el-range-editor.is-disabled:hover{border-color:#dfe4ed}.custom-theme .el-range-editor.is-disabled input{background-color:#f5f7fa;color:#b4bccc;cursor:not-allowed}.custom-theme .el-range-editor.is-disabled input::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-range-editor.is-disabled input:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-range-editor.is-disabled input::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-range-editor.is-disabled input::placeholder{color:#b4bccc}.custom-theme .el-range-editor.is-disabled .el-range-separator{color:#b4bccc}.custom-theme .el-time-spinner.has-seconds .el-time-spinner__wrapper{width:33.3%}.custom-theme .el-time-spinner.has-seconds .el-time-spinner__wrapper:nth-child(2){margin-left:1%}.custom-theme .el-time-spinner__wrapper{max-height:190px;overflow:auto;display:inline-block;width:50%;vertical-align:top;position:relative}.custom-theme .el-time-spinner__wrapper .el-scrollbar__wrap:not(.el-scrollbar__wrap--hidden-default){padding-bottom:15px}.custom-theme .el-time-spinner__wrapper.is-arrow{-webkit-box-sizing:border-box;box-sizing:border-box;text-align:center;overflow:hidden}.custom-theme .el-time-spinner__wrapper.is-arrow .el-time-spinner__list{-webkit-transform:translateY(-32px);transform:translateY(-32px)}.custom-theme .el-time-spinner__wrapper.is-arrow .el-time-spinner__item:hover:not(.disabled):not(.active){background:#fff;cursor:default}.custom-theme .el-time-spinner__arrow{font-size:12px;color:#878d99;position:absolute;left:0;width:100%;z-index:1;text-align:center;height:30px;line-height:30px;cursor:pointer}.custom-theme .el-time-spinner__arrow:hover{color:#262729}.custom-theme .el-time-spinner__arrow.el-icon-arrow-up{top:10px}.custom-theme .el-time-spinner__arrow.el-icon-arrow-down{bottom:10px}.custom-theme .el-time-spinner__input.el-input{width:70%}.custom-theme .el-time-spinner__input.el-input .el-input__inner{padding:0;text-align:center}.custom-theme .el-time-spinner__list{padding:0;margin:0;list-style:none;text-align:center}.custom-theme .el-time-spinner__list::after,.custom-theme .el-time-spinner__list::before{content:'';display:block;width:100%;height:80px}.custom-theme .el-time-spinner__item{height:32px;line-height:32px;font-size:12px;color:#5a5e66}.custom-theme .el-time-spinner__item:hover:not(.disabled):not(.active){background:#f5f7fa;cursor:pointer}.custom-theme .el-time-spinner__item.active:not(.disabled){color:#2d2f33;font-weight:700}.custom-theme .el-time-spinner__item.disabled{color:#b4bccc;cursor:not-allowed}.custom-theme .el-time-panel{margin:5px 0;border:solid 1px #dfe4ed;background-color:#fff;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);border-radius:2px;position:absolute;width:180px;left:0;z-index:1000;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.custom-theme .el-time-panel__content{font-size:0;position:relative;overflow:hidden}.custom-theme .el-time-panel__content::after,.custom-theme .el-time-panel__content::before{content:"";top:50%;position:absolute;margin-top:-15px;height:32px;z-index:-1;left:0;right:0;-webkit-box-sizing:border-box;box-sizing:border-box;padding-top:6px;text-align:left;border-top:1px solid #dfe4ed;border-bottom:1px solid #dfe4ed}.custom-theme .el-time-panel__content::after{left:50%;margin-left:12%;margin-right:12%}.custom-theme .el-time-panel__content::before{padding-left:50%;margin-right:12%;margin-left:12%}.custom-theme .el-time-panel__content.has-seconds::after{left:calc(100% / 3 * 2)}.custom-theme .el-time-panel__content.has-seconds::before{padding-left:calc(100% / 3)}.custom-theme .el-time-panel__footer{border-top:1px solid #e4e4e4;padding:4px;height:36px;line-height:25px;text-align:right;-webkit-box-sizing:border-box;box-sizing:border-box}.custom-theme .el-time-panel__btn{border:none;line-height:28px;padding:0 5px;margin:0 5px;cursor:pointer;background-color:transparent;outline:0;font-size:12px;color:#2d2f33}.custom-theme .el-time-panel__btn.confirm{font-weight:800;color:#262729}.custom-theme .el-time-panel .popper__arrow{-webkit-transform:translateX(-400%);transform:translateX(-400%)}.custom-theme .el-input{position:relative;font-size:14px;display:inline-block;width:100%}.custom-theme .el-input::-webkit-scrollbar{z-index:11;width:6px}.custom-theme .el-input::-webkit-scrollbar:horizontal{height:6px}.custom-theme .el-input::-webkit-scrollbar-thumb{border-radius:5px;width:6px;background:#b4bccc}.custom-theme .el-input::-webkit-scrollbar-corner{background:#fff}.custom-theme .el-input::-webkit-scrollbar-track{background:#fff}.custom-theme .el-input::-webkit-scrollbar-track-piece{background:#fff;width:6px}.custom-theme .el-input__inner{-webkit-appearance:none;background-color:#fff;background-image:none;border-radius:4px;border:1px solid #d8dce5;-webkit-box-sizing:border-box;box-sizing:border-box;color:#5a5e66;display:inline-block;font-size:inherit;height:40px;line-height:1;outline:0;padding:0 15px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1);width:100%}.custom-theme .el-input__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner::placeholder{color:#b4bccc}.custom-theme .el-input__inner:hover{border-color:#b4bccc}.custom-theme .el-input__inner:focus{outline:0;border-color:#262729}.custom-theme .el-input__suffix{position:absolute;height:100%;right:5px;top:0;text-align:center;color:#b4bccc;-webkit-transition:all .3s;transition:all .3s;pointer-events:none}.custom-theme .el-input__suffix-inner{pointer-events:all}.custom-theme .el-input__prefix{position:absolute;height:100%;left:5px;top:0;text-align:center;color:#b4bccc;-webkit-transition:all .3s;transition:all .3s}.custom-theme .el-input__icon{height:100%;width:25px;text-align:center;-webkit-transition:all .3s;transition:all .3s;line-height:40px}.custom-theme .el-input__icon:after{content:'';height:100%;width:0;display:inline-block;vertical-align:middle}.custom-theme .el-input__validateIcon{pointer-events:none}.custom-theme .el-input.is-active .el-input__inner{outline:0;border-color:#262729}.custom-theme .el-input.is-disabled .el-input__inner{background-color:#f5f7fa;border-color:#dfe4ed;color:#b4bccc;cursor:not-allowed}.custom-theme .el-input.is-disabled .el-input__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner::placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__icon{cursor:not-allowed}.custom-theme .el-input--suffix .el-input__inner{padding-right:30px}.custom-theme .el-input--prefix .el-input__inner{padding-left:30px}.custom-theme .el-input--medium{font-size:14px}.custom-theme .el-input--medium .el-input__inner{height:36px}.custom-theme .el-input--medium .el-input__icon{line-height:36px}.custom-theme .el-input--small{font-size:13px}.custom-theme .el-input--small .el-input__inner{height:32px}.custom-theme .el-input--small .el-input__icon{line-height:32px}.custom-theme .el-input--mini{font-size:12px}.custom-theme .el-input--mini .el-input__inner{height:28px}.custom-theme .el-input--mini .el-input__icon{line-height:28px}.custom-theme .el-input-group{line-height:normal;display:inline-table;width:100%;border-collapse:separate}.custom-theme .el-input-group>.el-input__inner{vertical-align:middle;display:table-cell}.custom-theme .el-input-group__append,.custom-theme .el-input-group__prepend{background-color:#f5f7fa;color:#0a76a4;vertical-align:middle;display:table-cell;position:relative;border:1px solid #d8dce5;border-radius:4px;padding:0 20px;width:1px;white-space:nowrap}.custom-theme .el-input-group__append:focus,.custom-theme .el-input-group__prepend:focus{outline:0}.custom-theme .el-input-group__append .el-button,.custom-theme .el-input-group__append .el-select,.custom-theme .el-input-group__prepend .el-button,.custom-theme .el-input-group__prepend .el-select{display:inline-block;margin:-20px}.custom-theme .el-input-group__append button.el-button,.custom-theme .el-input-group__append div.el-select .el-input__inner,.custom-theme .el-input-group__append div.el-select:hover .el-input__inner,.custom-theme .el-input-group__prepend button.el-button,.custom-theme .el-input-group__prepend div.el-select .el-input__inner,.custom-theme .el-input-group__prepend div.el-select:hover .el-input__inner{border-color:transparent;background-color:transparent;color:inherit;border-top:0;border-bottom:0}.custom-theme .el-input-group__append .el-button,.custom-theme .el-input-group__append .el-input,.custom-theme .el-input-group__prepend .el-button,.custom-theme .el-input-group__prepend .el-input{font-size:inherit}.custom-theme .el-input-group__prepend{border-right:0;border-top-right-radius:0;border-bottom-right-radius:0}.custom-theme .el-input-group__append{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.custom-theme .el-input-group--prepend .el-input__inner{border-top-left-radius:0;border-bottom-left-radius:0}.custom-theme .el-input-group--append .el-input__inner{border-top-right-radius:0;border-bottom-right-radius:0}.custom-theme .el-textarea{display:inline-block;width:100%;vertical-align:bottom}.custom-theme .el-textarea__inner{display:block;resize:vertical;padding:5px 15px;line-height:1.5;-webkit-box-sizing:border-box;box-sizing:border-box;width:100%;font-size:14px;color:#5a5e66;background-color:#fff;background-image:none;border:1px solid #d8dce5;border-radius:4px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1)}.custom-theme .el-textarea__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner::placeholder{color:#b4bccc}.custom-theme .el-textarea__inner:hover{border-color:#b4bccc}.custom-theme .el-textarea__inner:focus{outline:0;border-color:#262729}.custom-theme .el-textarea.is-disabled .el-textarea__inner{background-color:#f5f7fa;border-color:#dfe4ed;color:#b4bccc;cursor:not-allowed}.custom-theme .el-textarea.is-disabled .el-textarea__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner::placeholder{color:#b4bccc}.custom-theme .el-scrollbar{overflow:hidden;position:relative}.custom-theme .el-scrollbar:active>.el-scrollbar__bar,.custom-theme .el-scrollbar:focus>.el-scrollbar__bar,.custom-theme .el-scrollbar:hover>.el-scrollbar__bar{opacity:1;-webkit-transition:opacity 340ms ease-out;transition:opacity 340ms ease-out}.custom-theme .el-scrollbar__wrap{overflow:scroll;height:100%}.custom-theme .el-scrollbar__wrap--hidden-default::-webkit-scrollbar{width:0;height:0}.custom-theme .el-scrollbar__thumb{position:relative;display:block;width:0;height:0;cursor:pointer;border-radius:inherit;background-color:rgba(135,141,153,.3);-webkit-transition:.3s background-color;transition:.3s background-color}.custom-theme .el-scrollbar__thumb:hover{background-color:rgba(135,141,153,.5)}.custom-theme .el-scrollbar__bar{position:absolute;right:2px;bottom:2px;z-index:1;border-radius:4px;opacity:0;-webkit-transition:opacity 120ms ease-out;transition:opacity 120ms ease-out}.custom-theme .el-scrollbar__bar.is-vertical{width:6px;top:2px}.custom-theme .el-scrollbar__bar.is-vertical>div{width:100%}.custom-theme .el-scrollbar__bar.is-horizontal{height:6px;left:2px}.custom-theme .el-scrollbar__bar.is-horizontal>div{height:100%}.custom-theme .el-popper .popper__arrow,.custom-theme .el-popper .popper__arrow::after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.custom-theme .el-popper .popper__arrow{border-width:6px;-webkit-filter:drop-shadow(0 2px 12px rgba(0, 0, 0, .03));filter:drop-shadow(0 2px 12px rgba(0, 0, 0, .03))}.custom-theme .el-popper .popper__arrow::after{content:" ";border-width:6px}.custom-theme .el-popper[x-placement^=top]{margin-bottom:12px}.custom-theme .el-popper[x-placement^=top] .popper__arrow{bottom:-6px;left:50%;margin-right:3px;border-top-color:#e6ebf5;border-bottom-width:0}.custom-theme .el-popper[x-placement^=top] .popper__arrow::after{bottom:1px;margin-left:-6px;border-top-color:#fff;border-bottom-width:0}.custom-theme .el-popper[x-placement^=bottom]{margin-top:12px}.custom-theme .el-popper[x-placement^=bottom] .popper__arrow{top:-6px;left:50%;margin-right:3px;border-top-width:0;border-bottom-color:#e6ebf5}.custom-theme .el-popper[x-placement^=bottom] .popper__arrow::after{top:1px;margin-left:-6px;border-top-width:0;border-bottom-color:#fff}.custom-theme .el-popper[x-placement^=right]{margin-left:12px}.custom-theme .el-popper[x-placement^=right] .popper__arrow{top:50%;left:-6px;margin-bottom:3px;border-right-color:#e6ebf5;border-left-width:0}.custom-theme .el-popper[x-placement^=right] .popper__arrow::after{bottom:-6px;left:1px;border-right-color:#fff;border-left-width:0}.custom-theme .el-popper[x-placement^=left]{margin-right:12px}.custom-theme .el-popper[x-placement^=left] .popper__arrow{top:50%;right:-6px;margin-bottom:3px;border-right-width:0;border-left-color:#e6ebf5}.custom-theme .el-popper[x-placement^=left] .popper__arrow::after{right:1px;bottom:-6px;margin-left:-6px;border-right-width:0;border-left-color:#fff}.custom-theme .el-popper .popper__arrow,.custom-theme .el-popper .popper__arrow::after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.custom-theme .el-popper .popper__arrow{border-width:6px;-webkit-filter:drop-shadow(0 2px 12px rgba(0, 0, 0, .03));filter:drop-shadow(0 2px 12px rgba(0, 0, 0, .03))}.custom-theme .el-popper .popper__arrow::after{content:" ";border-width:6px}.custom-theme .el-popper[x-placement^=top]{margin-bottom:12px}.custom-theme .el-popper[x-placement^=top] .popper__arrow{bottom:-6px;left:50%;margin-right:3px;border-top-color:#e6ebf5;border-bottom-width:0}.custom-theme .el-popper[x-placement^=top] .popper__arrow::after{bottom:1px;margin-left:-6px;border-top-color:#fff;border-bottom-width:0}.custom-theme .el-popper[x-placement^=bottom]{margin-top:12px}.custom-theme .el-popper[x-placement^=bottom] .popper__arrow{top:-6px;left:50%;margin-right:3px;border-top-width:0;border-bottom-color:#e6ebf5}.custom-theme .el-popper[x-placement^=bottom] .popper__arrow::after{top:1px;margin-left:-6px;border-top-width:0;border-bottom-color:#fff}.custom-theme .el-popper[x-placement^=right]{margin-left:12px}.custom-theme .el-popper[x-placement^=right] .popper__arrow{top:50%;left:-6px;margin-bottom:3px;border-right-color:#e6ebf5;border-left-width:0}.custom-theme .el-popper[x-placement^=right] .popper__arrow::after{bottom:-6px;left:1px;border-right-color:#fff;border-left-width:0}.custom-theme .el-popper[x-placement^=left]{margin-right:12px}.custom-theme .el-popper[x-placement^=left] .popper__arrow{top:50%;right:-6px;margin-bottom:3px;border-right-width:0;border-left-color:#e6ebf5}.custom-theme .el-popper[x-placement^=left] .popper__arrow::after{right:1px;bottom:-6px;margin-left:-6px;border-right-width:0;border-left-color:#fff}.custom-theme .el-popover{position:absolute;background:#fff;min-width:150px;border-radius:4px;border:1px solid #e6ebf5;padding:12px;z-index:2000;color:#5a5e66;line-height:1.4;text-align:justify;word-break:break-all;font-size:14px;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.custom-theme .el-popover--plain{padding:18px 20px}.custom-theme .el-popover__title{color:#2d2f33;font-size:16px;line-height:1;margin-bottom:12px}.custom-theme .el-tooltip__popper{position:absolute;border-radius:4px;padding:10px;z-index:2000;font-size:12px;line-height:1.2}.custom-theme .el-tooltip__popper .popper__arrow,.custom-theme .el-tooltip__popper .popper__arrow::after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.custom-theme .el-tooltip__popper .popper__arrow{border-width:6px}.custom-theme .el-tooltip__popper .popper__arrow::after{content:" ";border-width:5px}.custom-theme .el-tooltip__popper[x-placement^=top]{margin-bottom:12px}.custom-theme .el-tooltip__popper[x-placement^=top] .popper__arrow{bottom:-6px;border-top-color:#2d2f33;border-bottom-width:0}.custom-theme .el-tooltip__popper[x-placement^=top] .popper__arrow::after{bottom:1px;margin-left:-5px;border-top-color:#2d2f33;border-bottom-width:0}.custom-theme .el-tooltip__popper[x-placement^=bottom]{margin-top:12px}.custom-theme .el-tooltip__popper[x-placement^=bottom] .popper__arrow{top:-6px;border-top-width:0;border-bottom-color:#2d2f33}.custom-theme .el-tooltip__popper[x-placement^=bottom] .popper__arrow::after{top:1px;margin-left:-5px;border-top-width:0;border-bottom-color:#2d2f33}.custom-theme .el-tooltip__popper[x-placement^=right]{margin-left:12px}.custom-theme .el-tooltip__popper[x-placement^=right] .popper__arrow{left:-6px;border-right-color:#2d2f33;border-left-width:0}.custom-theme .el-tooltip__popper[x-placement^=right] .popper__arrow::after{bottom:-5px;left:1px;border-right-color:#2d2f33;border-left-width:0}.custom-theme .el-tooltip__popper[x-placement^=left]{margin-right:12px}.custom-theme .el-tooltip__popper[x-placement^=left] .popper__arrow{right:-6px;border-right-width:0;border-left-color:#2d2f33}.custom-theme .el-tooltip__popper[x-placement^=left] .popper__arrow::after{right:1px;bottom:-5px;margin-left:-5px;border-right-width:0;border-left-color:#2d2f33}.custom-theme .el-tooltip__popper.is-dark{background:#2d2f33;color:#fff}.custom-theme .el-tooltip__popper.is-light{background:#fff;border:1px solid #2d2f33}.custom-theme .el-tooltip__popper.is-light[x-placement^=top] .popper__arrow{border-top-color:#2d2f33}.custom-theme .el-tooltip__popper.is-light[x-placement^=top] .popper__arrow::after{border-top-color:#fff}.custom-theme .el-tooltip__popper.is-light[x-placement^=bottom] .popper__arrow{border-bottom-color:#2d2f33}.custom-theme .el-tooltip__popper.is-light[x-placement^=bottom] .popper__arrow::after{border-bottom-color:#fff}.custom-theme .el-tooltip__popper.is-light[x-placement^=left] .popper__arrow{border-left-color:#2d2f33}.custom-theme .el-tooltip__popper.is-light[x-placement^=left] .popper__arrow::after{border-left-color:#fff}.custom-theme .el-tooltip__popper.is-light[x-placement^=right] .popper__arrow{border-right-color:#2d2f33}.custom-theme .el-tooltip__popper.is-light[x-placement^=right] .popper__arrow::after{border-right-color:#fff}.custom-theme .v-modal-enter{-webkit-animation:v-modal-in .2s ease;animation:v-modal-in .2s ease}.custom-theme .v-modal-leave{-webkit-animation:v-modal-out .2s ease forwards;animation:v-modal-out .2s ease forwards}@keyframes v-modal-in{0%{opacity:0}}@keyframes v-modal-out{100%{opacity:0}}.custom-theme .v-modal{position:fixed;left:0;top:0;width:100%;height:100%;opacity:.5;background:#000}.custom-theme .el-button{display:inline-block;line-height:1;white-space:nowrap;cursor:pointer;background:#fff;border:1px solid #d8dce5;border-color:#d8dce5;color:#5a5e66;-webkit-appearance:none;text-align:center;-webkit-box-sizing:border-box;box-sizing:border-box;outline:0;margin:0;-webkit-transition:.1s;transition:.1s;font-weight:500;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;padding:12px 20px;font-size:14px;border-radius:4px}.custom-theme .el-button+.el-button{margin-left:10px}.custom-theme .el-button.is-round{padding:12px 20px}.custom-theme .el-button:focus,.custom-theme .el-button:hover{color:#262729;border-color:#bebebf;background-color:#e9e9ea}.custom-theme .el-button:active{color:#222325;border-color:#222325;outline:0}.custom-theme .el-button::-moz-focus-inner{border:0}.custom-theme .el-button [class*=el-icon-]+span{margin-left:5px}.custom-theme .el-button.is-plain:focus,.custom-theme .el-button.is-plain:hover{background:#fff;border-color:#262729;color:#262729}.custom-theme .el-button.is-plain:active{background:#fff;border-color:#222325;color:#222325;outline:0}.custom-theme .el-button.is-active{color:#222325;border-color:#222325}.custom-theme .el-button.is-disabled,.custom-theme .el-button.is-disabled:focus,.custom-theme .el-button.is-disabled:hover{color:#b4bccc;cursor:not-allowed;background-image:none;background-color:#fff;border-color:#e6ebf5}.custom-theme .el-button.is-disabled.el-button--text{background-color:transparent}.custom-theme .el-button.is-disabled.is-plain,.custom-theme .el-button.is-disabled.is-plain:focus,.custom-theme .el-button.is-disabled.is-plain:hover{background-color:#fff;border-color:#e6ebf5;color:#b4bccc}.custom-theme .el-button.is-loading{position:relative;pointer-events:none}.custom-theme .el-button.is-loading:before{pointer-events:none;content:'';position:absolute;left:-1px;top:-1px;right:-1px;bottom:-1px;border-radius:inherit;background-color:rgba(255,255,255,.35)}.custom-theme .el-button.is-round{border-radius:20px;padding:12px 23px}.custom-theme .el-button--primary{color:#fff;background-color:#262729;border-color:#262729}.custom-theme .el-button--primary:focus,.custom-theme .el-button--primary:hover{background:#515254;border-color:#515254;color:#fff}.custom-theme .el-button--primary:active{background:#222325;border-color:#222325;color:#fff;outline:0}.custom-theme .el-button--primary.is-active{background:#222325;border-color:#222325;color:#fff}.custom-theme .el-button--primary.is-disabled,.custom-theme .el-button--primary.is-disabled:active,.custom-theme .el-button--primary.is-disabled:focus,.custom-theme .el-button--primary.is-disabled:hover{color:#fff;background-color:#939394;border-color:#939394}.custom-theme .el-button--primary.is-plain{color:#262729;background:#e9e9ea;border-color:#a8a9a9}.custom-theme .el-button--primary.is-plain:focus,.custom-theme .el-button--primary.is-plain:hover{background:#262729;border-color:#262729;color:#fff}.custom-theme .el-button--primary.is-plain:active{background:#222325;border-color:#222325;color:#fff;outline:0}.custom-theme .el-button--primary.is-plain.is-disabled,.custom-theme .el-button--primary.is-plain.is-disabled:active,.custom-theme .el-button--primary.is-plain.is-disabled:focus,.custom-theme .el-button--primary.is-plain.is-disabled:hover{color:#7d7d7f;background-color:#e9e9ea;border-color:#d4d4d4}.custom-theme .el-button--success{color:#fff;background-color:#409167;border-color:#409167}.custom-theme .el-button--success:focus,.custom-theme .el-button--success:hover{background:#66a785;border-color:#66a785;color:#fff}.custom-theme .el-button--success:active{background:#3a835d;border-color:#3a835d;color:#fff;outline:0}.custom-theme .el-button--success.is-active{background:#3a835d;border-color:#3a835d;color:#fff}.custom-theme .el-button--success.is-disabled,.custom-theme .el-button--success.is-disabled:active,.custom-theme .el-button--success.is-disabled:focus,.custom-theme .el-button--success.is-disabled:hover{color:#fff;background-color:#a0c8b3;border-color:#a0c8b3}.custom-theme .el-button--success.is-plain{color:#409167;background:#ecf4f0;border-color:#b3d3c2}.custom-theme .el-button--success.is-plain:focus,.custom-theme .el-button--success.is-plain:hover{background:#409167;border-color:#409167;color:#fff}.custom-theme .el-button--success.is-plain:active{background:#3a835d;border-color:#3a835d;color:#fff;outline:0}.custom-theme .el-button--success.is-plain.is-disabled,.custom-theme .el-button--success.is-plain.is-disabled:active,.custom-theme .el-button--success.is-plain.is-disabled:focus,.custom-theme .el-button--success.is-plain.is-disabled:hover{color:#8cbda4;background-color:#ecf4f0;border-color:#d9e9e1}.custom-theme .el-button--warning{color:#fff;background-color:#9da408;border-color:#9da408}.custom-theme .el-button--warning:focus,.custom-theme .el-button--warning:hover{background:#b1b639;border-color:#b1b639;color:#fff}.custom-theme .el-button--warning:active{background:#8d9407;border-color:#8d9407;color:#fff;outline:0}.custom-theme .el-button--warning.is-active{background:#8d9407;border-color:#8d9407;color:#fff}.custom-theme .el-button--warning.is-disabled,.custom-theme .el-button--warning.is-disabled:active,.custom-theme .el-button--warning.is-disabled:focus,.custom-theme .el-button--warning.is-disabled:hover{color:#fff;background-color:#ced284;border-color:#ced284}.custom-theme .el-button--warning.is-plain{color:#9da408;background:#f5f6e6;border-color:#d8db9c}.custom-theme .el-button--warning.is-plain:focus,.custom-theme .el-button--warning.is-plain:hover{background:#9da408;border-color:#9da408;color:#fff}.custom-theme .el-button--warning.is-plain:active{background:#8d9407;border-color:#8d9407;color:#fff;outline:0}.custom-theme .el-button--warning.is-plain.is-disabled,.custom-theme .el-button--warning.is-plain.is-disabled:active,.custom-theme .el-button--warning.is-plain.is-disabled:focus,.custom-theme .el-button--warning.is-plain.is-disabled:hover{color:#c4c86b;background-color:#f5f6e6;border-color:#ebedce}.custom-theme .el-button--danger{color:#fff;background-color:#b3450e;border-color:#b3450e}.custom-theme .el-button--danger:focus,.custom-theme .el-button--danger:hover{background:#c26a3e;border-color:#c26a3e;color:#fff}.custom-theme .el-button--danger:active{background:#a13e0d;border-color:#a13e0d;color:#fff;outline:0}.custom-theme .el-button--danger.is-active{background:#a13e0d;border-color:#a13e0d;color:#fff}.custom-theme .el-button--danger.is-disabled,.custom-theme .el-button--danger.is-disabled:active,.custom-theme .el-button--danger.is-disabled:focus,.custom-theme .el-button--danger.is-disabled:hover{color:#fff;background-color:#d9a287;border-color:#d9a287}.custom-theme .el-button--danger.is-plain{color:#b3450e;background:#f7ece7;border-color:#e1b59f}.custom-theme .el-button--danger.is-plain:focus,.custom-theme .el-button--danger.is-plain:hover{background:#b3450e;border-color:#b3450e;color:#fff}.custom-theme .el-button--danger.is-plain:active{background:#a13e0d;border-color:#a13e0d;color:#fff;outline:0}.custom-theme .el-button--danger.is-plain.is-disabled,.custom-theme .el-button--danger.is-plain.is-disabled:active,.custom-theme .el-button--danger.is-plain.is-disabled:focus,.custom-theme .el-button--danger.is-plain.is-disabled:hover{color:#d18f6e;background-color:#f7ece7;border-color:#f0dacf}.custom-theme .el-button--info{color:#fff;background-color:#0a76a4;border-color:#0a76a4}.custom-theme .el-button--info:focus,.custom-theme .el-button--info:hover{background:#3b91b6;border-color:#3b91b6;color:#fff}.custom-theme .el-button--info:active{background:#096a94;border-color:#096a94;color:#fff;outline:0}.custom-theme .el-button--info.is-active{background:#096a94;border-color:#096a94;color:#fff}.custom-theme .el-button--info.is-disabled,.custom-theme .el-button--info.is-disabled:active,.custom-theme .el-button--info.is-disabled:focus,.custom-theme .el-button--info.is-disabled:hover{color:#fff;background-color:#85bbd2;border-color:#85bbd2}.custom-theme .el-button--info.is-plain{color:#0a76a4;background:#e7f1f6;border-color:#9dc8db}.custom-theme .el-button--info.is-plain:focus,.custom-theme .el-button--info.is-plain:hover{background:#0a76a4;border-color:#0a76a4;color:#fff}.custom-theme .el-button--info.is-plain:active{background:#096a94;border-color:#096a94;color:#fff;outline:0}.custom-theme .el-button--info.is-plain.is-disabled,.custom-theme .el-button--info.is-plain.is-disabled:active,.custom-theme .el-button--info.is-plain.is-disabled:focus,.custom-theme .el-button--info.is-plain.is-disabled:hover{color:#6cadc8;background-color:#e7f1f6;border-color:#cee4ed}.custom-theme .el-button--medium{padding:10px 20px;font-size:14px;border-radius:4px}.custom-theme .el-button--medium.is-round{padding:10px 20px}.custom-theme .el-button--small{padding:9px 15px;font-size:12px;border-radius:3px}.custom-theme .el-button--small.is-round{padding:9px 15px}.custom-theme .el-button--mini{padding:7px 15px;font-size:12px;border-radius:3px}.custom-theme .el-button--mini.is-round{padding:7px 15px}.custom-theme .el-button--text{border:none;color:#262729;background:0 0;padding-left:0;padding-right:0}.custom-theme .el-button--text:focus,.custom-theme .el-button--text:hover{color:#515254;border-color:transparent;background-color:transparent}.custom-theme .el-button--text:active{color:#222325;border-color:transparent;background-color:transparent}.custom-theme .el-button-group{display:inline-block;vertical-align:middle}.custom-theme .el-button-group::after,.custom-theme .el-button-group::before{display:table;content:""}.custom-theme .el-button-group::after{clear:both}.custom-theme .el-button-group .el-button{float:left;position:relative}.custom-theme .el-button-group .el-button+.el-button{margin-left:0}.custom-theme .el-button-group .el-button:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.custom-theme .el-button-group .el-button:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.custom-theme .el-button-group .el-button:not(:first-child):not(:last-child){border-radius:0}.custom-theme .el-button-group .el-button:not(:last-child){margin-right:-1px}.custom-theme .el-button-group .el-button:active,.custom-theme .el-button-group .el-button:focus,.custom-theme .el-button-group .el-button:hover{z-index:1}.custom-theme .el-button-group .el-button.is-active{z-index:1}.custom-theme .el-button-group .el-button--primary:first-child{border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--primary:last-child{border-left-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--primary:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--success:first-child{border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--success:last-child{border-left-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--success:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--warning:first-child{border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--warning:last-child{border-left-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--warning:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--danger:first-child{border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--danger:last-child{border-left-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--danger:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--info:first-child{border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--info:last-child{border-left-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--info:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.custom-theme .el-input{position:relative;font-size:14px;display:inline-block;width:100%}.custom-theme .el-input::-webkit-scrollbar{z-index:11;width:6px}.custom-theme .el-input::-webkit-scrollbar:horizontal{height:6px}.custom-theme .el-input::-webkit-scrollbar-thumb{border-radius:5px;width:6px;background:#b4bccc}.custom-theme .el-input::-webkit-scrollbar-corner{background:#fff}.custom-theme .el-input::-webkit-scrollbar-track{background:#fff}.custom-theme .el-input::-webkit-scrollbar-track-piece{background:#fff;width:6px}.custom-theme .el-input__inner{-webkit-appearance:none;background-color:#fff;background-image:none;border-radius:4px;border:1px solid #d8dce5;-webkit-box-sizing:border-box;box-sizing:border-box;color:#5a5e66;display:inline-block;font-size:inherit;height:40px;line-height:1;outline:0;padding:0 15px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1);width:100%}.custom-theme .el-input__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner::placeholder{color:#b4bccc}.custom-theme .el-input__inner:hover{border-color:#b4bccc}.custom-theme .el-input__inner:focus{outline:0;border-color:#262729}.custom-theme .el-input__suffix{position:absolute;height:100%;right:5px;top:0;text-align:center;color:#b4bccc;-webkit-transition:all .3s;transition:all .3s;pointer-events:none}.custom-theme .el-input__suffix-inner{pointer-events:all}.custom-theme .el-input__prefix{position:absolute;height:100%;left:5px;top:0;text-align:center;color:#b4bccc;-webkit-transition:all .3s;transition:all .3s}.custom-theme .el-input__icon{height:100%;width:25px;text-align:center;-webkit-transition:all .3s;transition:all .3s;line-height:40px}.custom-theme .el-input__icon:after{content:'';height:100%;width:0;display:inline-block;vertical-align:middle}.custom-theme .el-input__validateIcon{pointer-events:none}.custom-theme .el-input.is-active .el-input__inner{outline:0;border-color:#262729}.custom-theme .el-input.is-disabled .el-input__inner{background-color:#f5f7fa;border-color:#dfe4ed;color:#b4bccc;cursor:not-allowed}.custom-theme .el-input.is-disabled .el-input__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner::placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__icon{cursor:not-allowed}.custom-theme .el-input--suffix .el-input__inner{padding-right:30px}.custom-theme .el-input--prefix .el-input__inner{padding-left:30px}.custom-theme .el-input--medium{font-size:14px}.custom-theme .el-input--medium .el-input__inner{height:36px}.custom-theme .el-input--medium .el-input__icon{line-height:36px}.custom-theme .el-input--small{font-size:13px}.custom-theme .el-input--small .el-input__inner{height:32px}.custom-theme .el-input--small .el-input__icon{line-height:32px}.custom-theme .el-input--mini{font-size:12px}.custom-theme .el-input--mini .el-input__inner{height:28px}.custom-theme .el-input--mini .el-input__icon{line-height:28px}.custom-theme .el-input-group{line-height:normal;display:inline-table;width:100%;border-collapse:separate}.custom-theme .el-input-group>.el-input__inner{vertical-align:middle;display:table-cell}.custom-theme .el-input-group__append,.custom-theme .el-input-group__prepend{background-color:#f5f7fa;color:#0a76a4;vertical-align:middle;display:table-cell;position:relative;border:1px solid #d8dce5;border-radius:4px;padding:0 20px;width:1px;white-space:nowrap}.custom-theme .el-input-group__append:focus,.custom-theme .el-input-group__prepend:focus{outline:0}.custom-theme .el-input-group__append .el-button,.custom-theme .el-input-group__append .el-select,.custom-theme .el-input-group__prepend .el-button,.custom-theme .el-input-group__prepend .el-select{display:inline-block;margin:-20px}.custom-theme .el-input-group__append button.el-button,.custom-theme .el-input-group__append div.el-select .el-input__inner,.custom-theme .el-input-group__append div.el-select:hover .el-input__inner,.custom-theme .el-input-group__prepend button.el-button,.custom-theme .el-input-group__prepend div.el-select .el-input__inner,.custom-theme .el-input-group__prepend div.el-select:hover .el-input__inner{border-color:transparent;background-color:transparent;color:inherit;border-top:0;border-bottom:0}.custom-theme .el-input-group__append .el-button,.custom-theme .el-input-group__append .el-input,.custom-theme .el-input-group__prepend .el-button,.custom-theme .el-input-group__prepend .el-input{font-size:inherit}.custom-theme .el-input-group__prepend{border-right:0;border-top-right-radius:0;border-bottom-right-radius:0}.custom-theme .el-input-group__append{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.custom-theme .el-input-group--prepend .el-input__inner{border-top-left-radius:0;border-bottom-left-radius:0}.custom-theme .el-input-group--append .el-input__inner{border-top-right-radius:0;border-bottom-right-radius:0}.custom-theme .el-textarea{display:inline-block;width:100%;vertical-align:bottom}.custom-theme .el-textarea__inner{display:block;resize:vertical;padding:5px 15px;line-height:1.5;-webkit-box-sizing:border-box;box-sizing:border-box;width:100%;font-size:14px;color:#5a5e66;background-color:#fff;background-image:none;border:1px solid #d8dce5;border-radius:4px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1)}.custom-theme .el-textarea__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner::placeholder{color:#b4bccc}.custom-theme .el-textarea__inner:hover{border-color:#b4bccc}.custom-theme .el-textarea__inner:focus{outline:0;border-color:#262729}.custom-theme .el-textarea.is-disabled .el-textarea__inner{background-color:#f5f7fa;border-color:#dfe4ed;color:#b4bccc;cursor:not-allowed}.custom-theme .el-textarea.is-disabled .el-textarea__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner::placeholder{color:#b4bccc}.custom-theme .el-message-box{display:inline-block;width:420px;padding-bottom:10px;vertical-align:middle;background-color:#fff;border-radius:4px;border:1px solid #e6ebf5;font-size:18px;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);text-align:left;overflow:hidden;-webkit-backface-visibility:hidden;backface-visibility:hidden}.custom-theme .el-message-box__wrapper{position:fixed;top:0;bottom:0;left:0;right:0;text-align:center}.custom-theme .el-message-box__wrapper::after{content:"";display:inline-block;height:100%;width:0;vertical-align:middle}.custom-theme .el-message-box__header{position:relative;padding:15px;padding-bottom:10px}.custom-theme .el-message-box__title{padding-left:0;margin-bottom:0;font-size:18px;line-height:1;color:#2d2f33}.custom-theme .el-message-box__headerbtn{position:absolute;top:15px;right:15px;padding:0;border:none;outline:0;background:0 0;font-size:16px;cursor:pointer}.custom-theme .el-message-box__headerbtn .el-message-box__close{color:#0a76a4}.custom-theme .el-message-box__headerbtn:focus .el-message-box__close,.custom-theme .el-message-box__headerbtn:hover .el-message-box__close{color:#262729}.custom-theme .el-message-box__content{position:relative;padding:10px 15px;color:#5a5e66;font-size:14px}.custom-theme .el-message-box__input{padding-top:15px}.custom-theme .el-message-box__input input.invalid{border-color:#b3450e}.custom-theme .el-message-box__input input.invalid:focus{border-color:#b3450e}.custom-theme .el-message-box__status{position:absolute;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);font-size:24px!important}.custom-theme .el-message-box__status::before{padding-left:1px}.custom-theme .el-message-box__status+.el-message-box__message{padding-left:36px;padding-right:12px}.custom-theme .el-message-box__status.el-icon-success{color:#409167}.custom-theme .el-message-box__status.el-icon-info{color:#0a76a4}.custom-theme .el-message-box__status.el-icon-warning{color:#9da408}.custom-theme .el-message-box__status.el-icon-error{color:#b3450e}.custom-theme .el-message-box__message{margin:0}.custom-theme .el-message-box__message p{margin:0;line-height:24px}.custom-theme .el-message-box__errormsg{color:#b3450e;font-size:12px;min-height:18px;margin-top:2px}.custom-theme .el-message-box__btns{padding:5px 15px 0;text-align:right}.custom-theme .el-message-box__btns button:nth-child(2){margin-left:10px}.custom-theme .el-message-box__btns-reverse{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.custom-theme .el-message-box--center{padding-bottom:30px}.custom-theme .el-message-box--center .el-message-box__header{padding-top:30px}.custom-theme .el-message-box--center .el-message-box__title{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.custom-theme .el-message-box--center .el-message-box__status{position:relative;top:auto;padding-right:5px;text-align:center;-webkit-transform:translateY(-1px);transform:translateY(-1px)}.custom-theme .el-message-box--center .el-message-box__message{margin-left:0}.custom-theme .el-message-box--center .el-message-box__btns,.custom-theme .el-message-box--center .el-message-box__content{text-align:center}.custom-theme .el-message-box--center .el-message-box__content{padding-left:27px;padding-right:27px}.custom-theme .msgbox-fade-enter-active{-webkit-animation:msgbox-fade-in .3s;animation:msgbox-fade-in .3s}.custom-theme .msgbox-fade-leave-active{-webkit-animation:msgbox-fade-out .3s;animation:msgbox-fade-out .3s}@-webkit-keyframes msgbox-fade-in{0%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}}@keyframes msgbox-fade-in{0%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}}@-webkit-keyframes msgbox-fade-out{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}100%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}}@keyframes msgbox-fade-out{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}100%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}}.custom-theme .el-breadcrumb{font-size:14px;line-height:1}.custom-theme .el-breadcrumb::after,.custom-theme .el-breadcrumb::before{display:table;content:""}.custom-theme .el-breadcrumb::after{clear:both}.custom-theme .el-breadcrumb__separator{margin:0 9px;font-weight:700;color:#b4bccc}.custom-theme .el-breadcrumb__separator[class*=icon]{margin:0 6px;font-weight:400}.custom-theme .el-breadcrumb__item{float:left}.custom-theme .el-breadcrumb__inner,.custom-theme .el-breadcrumb__inner a{font-weight:700;-webkit-transition:color .2s cubic-bezier(.645,.045,.355,1);transition:color .2s cubic-bezier(.645,.045,.355,1);color:#2d2f33}.custom-theme .el-breadcrumb__inner a:hover,.custom-theme .el-breadcrumb__inner:hover{color:#262729;cursor:pointer}.custom-theme .el-breadcrumb__item:last-child .el-breadcrumb__inner,.custom-theme .el-breadcrumb__item:last-child .el-breadcrumb__inner a,.custom-theme .el-breadcrumb__item:last-child .el-breadcrumb__inner a:hover,.custom-theme .el-breadcrumb__item:last-child .el-breadcrumb__inner:hover{font-weight:400;color:#5a5e66;cursor:text}.custom-theme .el-breadcrumb__item:last-child .el-breadcrumb__separator{display:none}.custom-theme .el-form--label-left .el-form-item__label{text-align:left}.custom-theme .el-form--label-top .el-form-item__label{float:none;display:inline-block;text-align:left;padding:0 0 10px 0}.custom-theme .el-form--inline .el-form-item{display:inline-block;margin-right:10px;vertical-align:top}.custom-theme .el-form--inline .el-form-item__label{float:none;display:inline-block}.custom-theme .el-form--inline .el-form-item__content{display:inline-block;vertical-align:top}.custom-theme .el-form--inline.el-form--label-top .el-form-item__content{display:block}.custom-theme .el-form-item{margin-bottom:22px}.custom-theme .el-form-item::after,.custom-theme .el-form-item::before{display:table;content:""}.custom-theme .el-form-item::after{clear:both}.custom-theme .el-form-item .el-form-item{margin-bottom:0}.custom-theme .el-form-item .el-input__validateIcon{display:none}.custom-theme .el-form-item--medium .el-form-item__label{line-height:36px}.custom-theme .el-form-item--medium .el-form-item__content{line-height:36px}.custom-theme .el-form-item--small .el-form-item__label{line-height:32px}.custom-theme .el-form-item--small .el-form-item__content{line-height:32px}.custom-theme .el-form-item--small.el-form-item{margin-bottom:18px}.custom-theme .el-form-item--small .el-form-item__error{padding-top:2px}.custom-theme .el-form-item--mini .el-form-item__label{line-height:28px}.custom-theme .el-form-item--mini .el-form-item__content{line-height:28px}.custom-theme .el-form-item--mini.el-form-item{margin-bottom:18px}.custom-theme .el-form-item--mini .el-form-item__error{padding-top:1px}.custom-theme .el-form-item__label{text-align:right;vertical-align:middle;float:left;font-size:14px;color:#5a5e66;line-height:40px;padding:0 12px 0 0;-webkit-box-sizing:border-box;box-sizing:border-box}.custom-theme .el-form-item__content{line-height:40px;position:relative;font-size:14px}.custom-theme .el-form-item__content::after,.custom-theme .el-form-item__content::before{display:table;content:""}.custom-theme .el-form-item__content::after{clear:both}.custom-theme .el-form-item__error{color:#b3450e;font-size:12px;line-height:1;padding-top:4px;position:absolute;top:100%;left:0}.custom-theme .el-form-item__error--inline{position:relative;top:auto;left:auto;display:inline-block;margin-left:10px}.custom-theme .el-form-item.is-required .el-form-item__label:before{content:'*';color:#b3450e;margin-right:4px}.custom-theme .el-form-item.is-error .el-input__inner,.custom-theme .el-form-item.is-error .el-input__inner:focus,.custom-theme .el-form-item.is-error .el-textarea__inner,.custom-theme .el-form-item.is-error .el-textarea__inner:focus{border-color:#b3450e}.custom-theme .el-form-item.is-error .el-input-group__append .el-input__inner,.custom-theme .el-form-item.is-error .el-input-group__prepend .el-input__inner{border-color:transparent}.custom-theme .el-form-item.is-error .el-input__validateIcon{color:#b3450e}.custom-theme .el-form-item.is-success .el-input__inner,.custom-theme .el-form-item.is-success .el-input__inner:focus,.custom-theme .el-form-item.is-success .el-textarea__inner,.custom-theme .el-form-item.is-success .el-textarea__inner:focus{border-color:#409167}.custom-theme .el-form-item.is-success .el-input-group__append .el-input__inner,.custom-theme .el-form-item.is-success .el-input-group__prepend .el-input__inner{border-color:transparent}.custom-theme .el-form-item.is-success .el-input__validateIcon{color:#409167}.custom-theme .el-form-item--feedback .el-input__validateIcon{display:inline-block}.custom-theme .el-tabs__header{padding:0;position:relative;margin:0 0 15px}.custom-theme .el-tabs__active-bar{position:absolute;bottom:0;left:0;height:2px;background-color:#262729;z-index:1;-webkit-transition:-webkit-transform .3s cubic-bezier(.645,.045,.355,1);transition:-webkit-transform .3s cubic-bezier(.645,.045,.355,1);transition:transform .3s cubic-bezier(.645,.045,.355,1);transition:transform .3s cubic-bezier(.645,.045,.355,1),-webkit-transform .3s cubic-bezier(.645,.045,.355,1);list-style:none}.custom-theme .el-tabs__new-tab{float:right;border:1px solid #d3dce6;height:18px;width:18px;line-height:18px;margin:12px 0 9px 10px;border-radius:3px;text-align:center;font-size:12px;color:#d3dce6;cursor:pointer;-webkit-transition:all .15s;transition:all .15s}.custom-theme .el-tabs__new-tab .el-icon-plus{-webkit-transform:scale(.8,.8);transform:scale(.8,.8)}.custom-theme .el-tabs__new-tab:hover{color:#262729}.custom-theme .el-tabs__nav-wrap{overflow:hidden;margin-bottom:-1px;position:relative}.custom-theme .el-tabs__nav-wrap::after{content:"";position:absolute;left:0;bottom:0;width:100%;height:2px;background-color:#dfe4ed;z-index:1}.custom-theme .el-tabs__nav-wrap.is-scrollable{padding:0 20px;-webkit-box-sizing:border-box;box-sizing:border-box}.custom-theme .el-tabs__nav-scroll{overflow:hidden}.custom-theme .el-tabs__nav-next,.custom-theme .el-tabs__nav-prev{position:absolute;cursor:pointer;line-height:44px;font-size:12px;color:#878d99}.custom-theme .el-tabs__nav-next{right:0}.custom-theme .el-tabs__nav-prev{left:0}.custom-theme .el-tabs__nav{white-space:nowrap;position:relative;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;float:left;z-index:2}.custom-theme .el-tabs__item{padding:0 20px;height:40px;-webkit-box-sizing:border-box;box-sizing:border-box;line-height:40px;display:inline-block;list-style:none;font-size:14px;font-weight:500;color:#2d2f33;position:relative}.custom-theme .el-tabs__item:focus,.custom-theme .el-tabs__item:focus:active{outline:0}.custom-theme .el-tabs__item .el-icon-close{border-radius:50%;text-align:center;-webkit-transition:all .3s cubic-bezier(.645,.045,.355,1);transition:all .3s cubic-bezier(.645,.045,.355,1);margin-left:5px}.custom-theme .el-tabs__item .el-icon-close:before{-webkit-transform:scale(.9);transform:scale(.9);display:inline-block}.custom-theme .el-tabs__item .el-icon-close:hover{background-color:#b4bccc;color:#fff}.custom-theme .el-tabs__item.is-active{color:#262729}.custom-theme .el-tabs__item:hover{color:#262729;cursor:pointer}.custom-theme .el-tabs__item.is-disabled{color:#b4bccc;cursor:default}.custom-theme .el-tabs__content{overflow:hidden;position:relative}.custom-theme .el-tabs--card>.el-tabs__header{border-bottom:1px solid #dfe4ed}.custom-theme .el-tabs--card>.el-tabs__header .el-tabs__nav-wrap::after{content:none}.custom-theme .el-tabs--card>.el-tabs__header .el-tabs__nav{border:1px solid #dfe4ed;border-bottom:none;border-radius:4px 4px 0 0}.custom-theme .el-tabs--card>.el-tabs__header .el-tabs__active-bar{display:none}.custom-theme .el-tabs--card>.el-tabs__header .el-tabs__item .el-icon-close{position:relative;font-size:12px;width:0;height:14px;vertical-align:middle;line-height:15px;overflow:hidden;top:-1px;right:-2px;-webkit-transform-origin:100% 50%;transform-origin:100% 50%}.custom-theme .el-tabs--card>.el-tabs__header .el-tabs__item{border-bottom:1px solid transparent;border-left:1px solid #dfe4ed;-webkit-transition:color .3s cubic-bezier(.645,.045,.355,1),padding .3s cubic-bezier(.645,.045,.355,1);transition:color .3s cubic-bezier(.645,.045,.355,1),padding .3s cubic-bezier(.645,.045,.355,1)}.custom-theme .el-tabs--card>.el-tabs__header .el-tabs__item:first-child{border-left:none}.custom-theme .el-tabs--card>.el-tabs__header .el-tabs__item.is-closable:hover{padding-left:13px;padding-right:13px}.custom-theme .el-tabs--card>.el-tabs__header .el-tabs__item.is-closable:hover .el-icon-close{width:14px}.custom-theme .el-tabs--card>.el-tabs__header .el-tabs__item.is-active{border-bottom-color:#fff}.custom-theme .el-tabs--card>.el-tabs__header .el-tabs__item.is-active.is-closable{padding-left:20px;padding-right:20px}.custom-theme .el-tabs--card>.el-tabs__header .el-tabs__item.is-active.is-closable .el-icon-close{width:14px}.custom-theme .el-tabs--border-card{background:#fff;border:1px solid #d8dce5;-webkit-box-shadow:0 2px 4px 0 rgba(0,0,0,.12),0 0 6px 0 rgba(0,0,0,.04);box-shadow:0 2px 4px 0 rgba(0,0,0,.12),0 0 6px 0 rgba(0,0,0,.04)}.custom-theme .el-tabs--border-card>.el-tabs__content{padding:15px}.custom-theme .el-tabs--border-card>.el-tabs__header{background-color:#f5f7fa;border-bottom:1px solid #dfe4ed;margin:0}.custom-theme .el-tabs--border-card>.el-tabs__header .el-tabs__nav-wrap::after{content:none}.custom-theme .el-tabs--border-card>.el-tabs__header .el-tabs__item{-webkit-transition:all .3s cubic-bezier(.645,.045,.355,1);transition:all .3s cubic-bezier(.645,.045,.355,1);border:1px solid transparent;margin:-1px -1px 0;color:#878d99}.custom-theme .el-tabs--border-card>.el-tabs__header .el-tabs__item.is-active{color:#262729;background-color:#fff;border-right-color:#d8dce5;border-left-color:#d8dce5}.custom-theme .el-tabs--border-card>.el-tabs__header .el-tabs__item:hover{color:#262729}.custom-theme .el-tabs--bottom:not(.el-tabs--border-card):not(.el-tabs--card) .el-tabs__item:nth-child(2),.custom-theme .el-tabs--top:not(.el-tabs--border-card):not(.el-tabs--card) .el-tabs__item:nth-child(2){padding-left:0}.custom-theme .el-tabs--bottom .el-tabs__header{margin-bottom:0;margin-top:10px}.custom-theme .el-tabs--bottom.el-tabs--border-card .el-tabs__header{border-bottom:0;border-top:1px solid #d8dce5}.custom-theme .el-tabs--bottom.el-tabs--border-card .el-tabs__nav-wrap{margin-top:-1px;margin-bottom:0}.custom-theme .el-tabs--bottom.el-tabs--border-card .el-tabs__item{border:1px solid transparent;margin:0 -1px -1px -1px}.custom-theme .el-tabs--left,.custom-theme .el-tabs--right{overflow:hidden}.custom-theme .el-tabs--left .el-tabs__header,.custom-theme .el-tabs--left .el-tabs__nav-scroll,.custom-theme .el-tabs--left .el-tabs__nav-wrap,.custom-theme .el-tabs--right .el-tabs__header,.custom-theme .el-tabs--right .el-tabs__nav-scroll,.custom-theme .el-tabs--right .el-tabs__nav-wrap{height:100%}.custom-theme .el-tabs--left .el-tabs__active-bar,.custom-theme .el-tabs--right .el-tabs__active-bar{top:0;bottom:auto;width:2px;height:auto}.custom-theme .el-tabs--left .el-tabs__nav-wrap,.custom-theme .el-tabs--right .el-tabs__nav-wrap{margin-bottom:0}.custom-theme .el-tabs--left .el-tabs__nav-wrap.is-scrollable,.custom-theme .el-tabs--right .el-tabs__nav-wrap.is-scrollable{padding:30px 0}.custom-theme .el-tabs--left .el-tabs__nav-wrap::after,.custom-theme .el-tabs--right .el-tabs__nav-wrap::after{height:100%;width:2px;bottom:auto;top:0}.custom-theme .el-tabs--left .el-tabs__nav,.custom-theme .el-tabs--right .el-tabs__nav{float:none}.custom-theme .el-tabs--left .el-tabs__item,.custom-theme .el-tabs--right .el-tabs__item{display:block}.custom-theme .el-tabs--left .el-tabs__nav-next,.custom-theme .el-tabs--left .el-tabs__nav-prev,.custom-theme .el-tabs--right .el-tabs__nav-next,.custom-theme .el-tabs--right .el-tabs__nav-prev{height:30px;line-height:30px;width:100%;text-align:center;cursor:pointer}.custom-theme .el-tabs--left .el-tabs__nav-next i,.custom-theme .el-tabs--left .el-tabs__nav-prev i,.custom-theme .el-tabs--right .el-tabs__nav-next i,.custom-theme .el-tabs--right .el-tabs__nav-prev i{-webkit-transform:rotateZ(90deg);transform:rotateZ(90deg)}.custom-theme .el-tabs--left .el-tabs__nav-prev,.custom-theme .el-tabs--right .el-tabs__nav-prev{left:auto;top:0}.custom-theme .el-tabs--left .el-tabs__nav-next,.custom-theme .el-tabs--right .el-tabs__nav-next{right:auto;bottom:0}.custom-theme .el-tabs--left .el-tabs__header{float:left;margin-bottom:0;margin-right:10px}.custom-theme .el-tabs--left .el-tabs__nav-wrap{margin-right:-1px}.custom-theme .el-tabs--left .el-tabs__nav-wrap::after{left:auto;right:0}.custom-theme .el-tabs--left .el-tabs__active-bar{right:0;left:auto}.custom-theme .el-tabs--left .el-tabs__item{text-align:right}.custom-theme .el-tabs--left.el-tabs--card .el-tabs__active-bar{display:none}.custom-theme .el-tabs--left.el-tabs--card .el-tabs__item{border-left:none;border-right:1px solid #dfe4ed;border-bottom:none;border-top:1px solid #dfe4ed}.custom-theme .el-tabs--left.el-tabs--card .el-tabs__item:first-child{border-right:1px solid #dfe4ed;border-top:none}.custom-theme .el-tabs--left.el-tabs--card .el-tabs__item.is-active{border:1px solid #dfe4ed;border-right-color:#fff;border-left:none;border-bottom:none}.custom-theme .el-tabs--left.el-tabs--card .el-tabs__item.is-active:first-child{border-top:none}.custom-theme .el-tabs--left.el-tabs--card .el-tabs__item.is-active:last-child{border-bottom:none}.custom-theme .el-tabs--left.el-tabs--card .el-tabs__nav{border-radius:4px 0 0 4px;border-bottom:1px solid #dfe4ed;border-right:none}.custom-theme .el-tabs--left.el-tabs--card .el-tabs__new-tab{float:none}.custom-theme .el-tabs--left.el-tabs--border-card .el-tabs__header{border-right:1px solid #dfe4ed}.custom-theme .el-tabs--left.el-tabs--border-card .el-tabs__item{border:1px solid transparent;margin:-1px 0 -1px -1px}.custom-theme .el-tabs--left.el-tabs--border-card .el-tabs__item.is-active{border-color:transparent;border-top-color:#d1dbe5;border-bottom-color:#d1dbe5}.custom-theme .el-tabs--right .el-tabs__header{float:right;margin-bottom:0;margin-left:10px}.custom-theme .el-tabs--right .el-tabs__nav-wrap{margin-left:-1px}.custom-theme .el-tabs--right .el-tabs__nav-wrap::after{left:0;right:auto}.custom-theme .el-tabs--right .el-tabs__active-bar{left:0}.custom-theme .el-tabs--right.el-tabs--card .el-tabs__active-bar{display:none}.custom-theme .el-tabs--right.el-tabs--card .el-tabs__item{border-bottom:none;border-top:1px solid #dfe4ed}.custom-theme .el-tabs--right.el-tabs--card .el-tabs__item:first-child{border-left:1px solid #dfe4ed;border-top:none}.custom-theme .el-tabs--right.el-tabs--card .el-tabs__item.is-active{border:1px solid #dfe4ed;border-left-color:#fff;border-right:none;border-bottom:none}.custom-theme .el-tabs--right.el-tabs--card .el-tabs__item.is-active:first-child{border-top:none}.custom-theme .el-tabs--right.el-tabs--card .el-tabs__item.is-active:last-child{border-bottom:none}.custom-theme .el-tabs--right.el-tabs--card .el-tabs__nav{border-radius:0 4px 4px 0;border-bottom:1px solid #dfe4ed;border-left:none}.custom-theme .el-tabs--right.el-tabs--border-card .el-tabs__header{border-left:1px solid #dfe4ed}.custom-theme .el-tabs--right.el-tabs--border-card .el-tabs__item{border:1px solid transparent;margin:-1px -1px -1px 0}.custom-theme .el-tabs--right.el-tabs--border-card .el-tabs__item.is-active{border-color:transparent;border-top-color:#d1dbe5;border-bottom-color:#d1dbe5}.custom-theme .slideInLeft-transition,.custom-theme .slideInRight-transition{display:inline-block}.custom-theme .slideInRight-enter{-webkit-animation:slideInRight-enter .3s;animation:slideInRight-enter .3s}.custom-theme .slideInRight-leave{position:absolute;left:0;right:0;-webkit-animation:slideInRight-leave .3s;animation:slideInRight-leave .3s}.custom-theme .slideInLeft-enter{-webkit-animation:slideInLeft-enter .3s;animation:slideInLeft-enter .3s}.custom-theme .slideInLeft-leave{position:absolute;left:0;right:0;-webkit-animation:slideInLeft-leave .3s;animation:slideInLeft-leave .3s}@-webkit-keyframes slideInRight-enter{0%{opacity:0;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(100%);transform:translateX(100%)}to{opacity:1;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes slideInRight-enter{0%{opacity:0;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(100%);transform:translateX(100%)}to{opacity:1;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0)}}@-webkit-keyframes slideInRight-leave{0%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0);opacity:1}100%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(100%);transform:translateX(100%);opacity:0}}@keyframes slideInRight-leave{0%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0);opacity:1}100%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(100%);transform:translateX(100%);opacity:0}}@-webkit-keyframes slideInLeft-enter{0%{opacity:0;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(-100%);transform:translateX(-100%)}to{opacity:1;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes slideInLeft-enter{0%{opacity:0;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(-100%);transform:translateX(-100%)}to{opacity:1;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0)}}@-webkit-keyframes slideInLeft-leave{0%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0);opacity:1}100%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(-100%);transform:translateX(-100%);opacity:0}}@keyframes slideInLeft-leave{0%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0);opacity:1}100%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(-100%);transform:translateX(-100%);opacity:0}}.custom-theme .el-tag{background-color:rgba(38,39,41,.1);display:inline-block;padding:0 10px;height:32px;line-height:30px;font-size:12px;color:#262729;border-radius:4px;-webkit-box-sizing:border-box;box-sizing:border-box;border:1px solid rgba(38,39,41,.2);white-space:nowrap}.custom-theme .el-tag .el-icon-close{border-radius:50%;text-align:center;position:relative;cursor:pointer;font-size:12px;height:18px;width:18px;line-height:18px;vertical-align:middle;top:-1px;right:-5px;color:#262729}.custom-theme .el-tag .el-icon-close::before{display:block}.custom-theme .el-tag .el-icon-close:hover{background-color:#262729;color:#fff}.custom-theme .el-tag--info{background-color:rgba(10,118,164,.1);border-color:rgba(10,118,164,.2);color:#0a76a4}.custom-theme .el-tag--info.is-hit{border-color:#0a76a4}.custom-theme .el-tag--info .el-tag__close{color:#0a76a4}.custom-theme .el-tag--info .el-tag__close:hover{background-color:#0a76a4;color:#fff}.custom-theme .el-tag--success{background-color:rgba(64,145,103,.1);border-color:rgba(64,145,103,.2);color:#409167}.custom-theme .el-tag--success.is-hit{border-color:#409167}.custom-theme .el-tag--success .el-tag__close{color:#409167}.custom-theme .el-tag--success .el-tag__close:hover{background-color:#409167;color:#fff}.custom-theme .el-tag--warning{background-color:rgba(157,164,8,.1);border-color:rgba(157,164,8,.2);color:#9da408}.custom-theme .el-tag--warning.is-hit{border-color:#9da408}.custom-theme .el-tag--warning .el-tag__close{color:#9da408}.custom-theme .el-tag--warning .el-tag__close:hover{background-color:#9da408;color:#fff}.custom-theme .el-tag--danger{background-color:rgba(179,69,14,.1);border-color:rgba(179,69,14,.2);color:#b3450e}.custom-theme .el-tag--danger.is-hit{border-color:#b3450e}.custom-theme .el-tag--danger .el-tag__close{color:#b3450e}.custom-theme .el-tag--danger .el-tag__close:hover{background-color:#b3450e;color:#fff}.custom-theme .el-tag--medium{height:28px;line-height:26px}.custom-theme .el-tag--medium .el-icon-close{-webkit-transform:scale(.8);transform:scale(.8)}.custom-theme .el-tag--small{height:24px;padding:0 8px;line-height:22px}.custom-theme .el-tag--small .el-icon-close{-webkit-transform:scale(.8);transform:scale(.8)}.custom-theme .el-tag--mini{height:20px;padding:0 5px;line-height:19px}.custom-theme .el-tag--mini .el-icon-close{margin-left:-3px;-webkit-transform:scale(.7);transform:scale(.7)}.custom-theme .el-tree{cursor:default;background:#fff;color:#5a5e66}.custom-theme .el-tree__empty-block{position:relative;min-height:60px;text-align:center;width:100%;height:100%}.custom-theme .el-tree__empty-text{position:absolute;left:50%;top:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);color:#623615}.custom-theme .el-tree-node{white-space:nowrap}.custom-theme .el-tree-node__content{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:26px;cursor:pointer}.custom-theme .el-tree-node__content>.el-tree-node__expand-icon{padding:6px}.custom-theme .el-tree-node__content>.el-checkbox{margin-right:8px}.custom-theme .el-tree-node__content:hover{background-color:#f5f7fa}.custom-theme .el-tree-node__expand-icon{cursor:pointer;color:#b4bccc;font-size:12px;-webkit-transform:rotate(0);transform:rotate(0);-webkit-transition:-webkit-transform .3s ease-in-out;transition:-webkit-transform .3s ease-in-out;transition:transform .3s ease-in-out;transition:transform .3s ease-in-out,-webkit-transform .3s ease-in-out}.custom-theme .el-tree-node__expand-icon.expanded{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.custom-theme .el-tree-node__expand-icon.is-leaf{color:transparent;cursor:default}.custom-theme .el-tree-node__label{font-size:14px}.custom-theme .el-tree-node__loading-icon{margin-right:8px;font-size:14px;color:#b4bccc}.custom-theme .el-tree-node>.el-tree-node__children{overflow:hidden;background-color:transparent}.custom-theme .el-tree-node.is-expanded>.el-tree-node__children{display:block}.custom-theme .el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content{background-color:#eee}.custom-theme .el-alert{width:100%;padding:8px 16px;margin:0;-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:4px;position:relative;background-color:#fff;overflow:hidden;opacity:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-transition:opacity .2s;transition:opacity .2s}.custom-theme .el-alert.is-center{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.custom-theme .el-alert--success{background-color:#ecf4f0;color:#409167}.custom-theme .el-alert--success .el-alert__description{color:#409167}.custom-theme .el-alert--info{background-color:#e7f1f6;color:#0a76a4}.custom-theme .el-alert--info .el-alert__description{color:#0a76a4}.custom-theme .el-alert--warning{background-color:#f5f6e6;color:#9da408}.custom-theme .el-alert--warning .el-alert__description{color:#9da408}.custom-theme .el-alert--error{background-color:#f7ece7;color:#b3450e}.custom-theme .el-alert--error .el-alert__description{color:#b3450e}.custom-theme .el-alert__content{display:table-cell;padding:0 8px}.custom-theme .el-alert__icon{font-size:16px;width:16px}.custom-theme .el-alert__icon.is-big{font-size:28px;width:28px}.custom-theme .el-alert__title{font-size:13px;line-height:18px}.custom-theme .el-alert__title.is-bold{font-weight:700}.custom-theme .el-alert .el-alert__description{font-size:12px;margin:5px 0 0 0}.custom-theme .el-alert__closebtn{font-size:12px;color:#b4bccc;opacity:1;position:absolute;top:12px;right:15px;cursor:pointer}.custom-theme .el-alert__closebtn.is-customed{font-style:normal;font-size:13px;top:9px}.custom-theme .el-alert-fade-enter,.custom-theme .el-alert-fade-leave-active{opacity:0}.custom-theme .el-notification{display:-webkit-box;display:-ms-flexbox;display:flex;width:330px;padding:14px 26px 14px 13px;border-radius:8px;-webkit-box-sizing:border-box;box-sizing:border-box;border:1px solid #e6ebf5;position:fixed;background-color:#fff;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);-webkit-transition:opacity .3s,left .3s,right .3s,top .4s,bottom .3s,-webkit-transform .3s;transition:opacity .3s,left .3s,right .3s,top .4s,bottom .3s,-webkit-transform .3s;transition:opacity .3s,transform .3s,left .3s,right .3s,top .4s,bottom .3s;transition:opacity .3s,transform .3s,left .3s,right .3s,top .4s,bottom .3s,-webkit-transform .3s;overflow:hidden}.custom-theme .el-notification.right{right:16px}.custom-theme .el-notification.left{left:16px}.custom-theme .el-notification__group{margin-left:13px}.custom-theme .el-notification__title{font-weight:700;font-size:16px;color:#2d2f33;margin:0}.custom-theme .el-notification__content{font-size:14px;line-height:21px;margin:6px 0 0 0;color:#5a5e66;text-align:justify}.custom-theme .el-notification__content p{margin:0}.custom-theme .el-notification__icon{height:24px;width:24px;font-size:24px;-webkit-transform:translateY(4px);transform:translateY(4px)}.custom-theme .el-notification__closeBtn{position:absolute;top:15px;right:15px;cursor:pointer;color:#878d99;font-size:16px}.custom-theme .el-notification__closeBtn:hover{color:#5a5e66}.custom-theme .el-notification .el-icon-success{color:#409167}.custom-theme .el-notification .el-icon-error{color:#b3450e}.custom-theme .el-notification .el-icon-info{color:#0a76a4}.custom-theme .el-notification .el-icon-warning{color:#9da408}.custom-theme .el-notification-fade-enter.right{right:0;-webkit-transform:translateX(100%);transform:translateX(100%)}.custom-theme .el-notification-fade-enter.left{left:0;-webkit-transform:translateX(-100%);transform:translateX(-100%)}.custom-theme .el-notification-fade-leave-active{opacity:0}.custom-theme .el-input{position:relative;font-size:14px;display:inline-block;width:100%}.custom-theme .el-input::-webkit-scrollbar{z-index:11;width:6px}.custom-theme .el-input::-webkit-scrollbar:horizontal{height:6px}.custom-theme .el-input::-webkit-scrollbar-thumb{border-radius:5px;width:6px;background:#b4bccc}.custom-theme .el-input::-webkit-scrollbar-corner{background:#fff}.custom-theme .el-input::-webkit-scrollbar-track{background:#fff}.custom-theme .el-input::-webkit-scrollbar-track-piece{background:#fff;width:6px}.custom-theme .el-input__inner{-webkit-appearance:none;background-color:#fff;background-image:none;border-radius:4px;border:1px solid #d8dce5;-webkit-box-sizing:border-box;box-sizing:border-box;color:#5a5e66;display:inline-block;font-size:inherit;height:40px;line-height:1;outline:0;padding:0 15px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1);width:100%}.custom-theme .el-input__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner::placeholder{color:#b4bccc}.custom-theme .el-input__inner:hover{border-color:#b4bccc}.custom-theme .el-input__inner:focus{outline:0;border-color:#262729}.custom-theme .el-input__suffix{position:absolute;height:100%;right:5px;top:0;text-align:center;color:#b4bccc;-webkit-transition:all .3s;transition:all .3s;pointer-events:none}.custom-theme .el-input__suffix-inner{pointer-events:all}.custom-theme .el-input__prefix{position:absolute;height:100%;left:5px;top:0;text-align:center;color:#b4bccc;-webkit-transition:all .3s;transition:all .3s}.custom-theme .el-input__icon{height:100%;width:25px;text-align:center;-webkit-transition:all .3s;transition:all .3s;line-height:40px}.custom-theme .el-input__icon:after{content:'';height:100%;width:0;display:inline-block;vertical-align:middle}.custom-theme .el-input__validateIcon{pointer-events:none}.custom-theme .el-input.is-active .el-input__inner{outline:0;border-color:#262729}.custom-theme .el-input.is-disabled .el-input__inner{background-color:#f5f7fa;border-color:#dfe4ed;color:#b4bccc;cursor:not-allowed}.custom-theme .el-input.is-disabled .el-input__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner::placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__icon{cursor:not-allowed}.custom-theme .el-input--suffix .el-input__inner{padding-right:30px}.custom-theme .el-input--prefix .el-input__inner{padding-left:30px}.custom-theme .el-input--medium{font-size:14px}.custom-theme .el-input--medium .el-input__inner{height:36px}.custom-theme .el-input--medium .el-input__icon{line-height:36px}.custom-theme .el-input--small{font-size:13px}.custom-theme .el-input--small .el-input__inner{height:32px}.custom-theme .el-input--small .el-input__icon{line-height:32px}.custom-theme .el-input--mini{font-size:12px}.custom-theme .el-input--mini .el-input__inner{height:28px}.custom-theme .el-input--mini .el-input__icon{line-height:28px}.custom-theme .el-input-group{line-height:normal;display:inline-table;width:100%;border-collapse:separate}.custom-theme .el-input-group>.el-input__inner{vertical-align:middle;display:table-cell}.custom-theme .el-input-group__append,.custom-theme .el-input-group__prepend{background-color:#f5f7fa;color:#0a76a4;vertical-align:middle;display:table-cell;position:relative;border:1px solid #d8dce5;border-radius:4px;padding:0 20px;width:1px;white-space:nowrap}.custom-theme .el-input-group__append:focus,.custom-theme .el-input-group__prepend:focus{outline:0}.custom-theme .el-input-group__append .el-button,.custom-theme .el-input-group__append .el-select,.custom-theme .el-input-group__prepend .el-button,.custom-theme .el-input-group__prepend .el-select{display:inline-block;margin:-20px}.custom-theme .el-input-group__append button.el-button,.custom-theme .el-input-group__append div.el-select .el-input__inner,.custom-theme .el-input-group__append div.el-select:hover .el-input__inner,.custom-theme .el-input-group__prepend button.el-button,.custom-theme .el-input-group__prepend div.el-select .el-input__inner,.custom-theme .el-input-group__prepend div.el-select:hover .el-input__inner{border-color:transparent;background-color:transparent;color:inherit;border-top:0;border-bottom:0}.custom-theme .el-input-group__append .el-button,.custom-theme .el-input-group__append .el-input,.custom-theme .el-input-group__prepend .el-button,.custom-theme .el-input-group__prepend .el-input{font-size:inherit}.custom-theme .el-input-group__prepend{border-right:0;border-top-right-radius:0;border-bottom-right-radius:0}.custom-theme .el-input-group__append{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.custom-theme .el-input-group--prepend .el-input__inner{border-top-left-radius:0;border-bottom-left-radius:0}.custom-theme .el-input-group--append .el-input__inner{border-top-right-radius:0;border-bottom-right-radius:0}.custom-theme .el-textarea{display:inline-block;width:100%;vertical-align:bottom}.custom-theme .el-textarea__inner{display:block;resize:vertical;padding:5px 15px;line-height:1.5;-webkit-box-sizing:border-box;box-sizing:border-box;width:100%;font-size:14px;color:#5a5e66;background-color:#fff;background-image:none;border:1px solid #d8dce5;border-radius:4px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1)}.custom-theme .el-textarea__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner::placeholder{color:#b4bccc}.custom-theme .el-textarea__inner:hover{border-color:#b4bccc}.custom-theme .el-textarea__inner:focus{outline:0;border-color:#262729}.custom-theme .el-textarea.is-disabled .el-textarea__inner{background-color:#f5f7fa;border-color:#dfe4ed;color:#b4bccc;cursor:not-allowed}.custom-theme .el-textarea.is-disabled .el-textarea__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner::placeholder{color:#b4bccc}.custom-theme .el-input-number{position:relative;display:inline-block;width:180px;line-height:38px}.custom-theme .el-input-number .el-input{display:block}.custom-theme .el-input-number .el-input__inner{-webkit-appearance:none;padding-left:50px;padding-right:50px;text-align:center}.custom-theme .el-input-number__decrease,.custom-theme .el-input-number__increase{position:absolute;z-index:1;top:1px;width:40px;height:auto;text-align:center;background:#f5f7fa;color:#5a5e66;cursor:pointer;font-size:13px}.custom-theme .el-input-number__decrease:hover,.custom-theme .el-input-number__increase:hover{color:#262729}.custom-theme .el-input-number__decrease:hover:not(.is-disabled)~.el-input .el-input__inner:not(.is-disabled),.custom-theme .el-input-number__increase:hover:not(.is-disabled)~.el-input .el-input__inner:not(.is-disabled){border-color:#262729}.custom-theme .el-input-number__decrease.is-disabled,.custom-theme .el-input-number__increase.is-disabled{color:#b4bccc;cursor:not-allowed}.custom-theme .el-input-number__increase{right:1px;border-radius:0 4px 4px 0;border-left:1px solid #d8dce5}.custom-theme .el-input-number__decrease{left:1px;border-radius:4px 0 0 4px;border-right:1px solid #d8dce5}.custom-theme .el-input-number.is-disabled .el-input-number__decrease,.custom-theme .el-input-number.is-disabled .el-input-number__increase{border-color:#dfe4ed;color:#dfe4ed}.custom-theme .el-input-number.is-disabled .el-input-number__decrease:hover,.custom-theme .el-input-number.is-disabled .el-input-number__increase:hover{color:#dfe4ed;cursor:not-allowed}.custom-theme .el-input-number--medium{width:200px;line-height:34px}.custom-theme .el-input-number--medium .el-input-number__decrease,.custom-theme .el-input-number--medium .el-input-number__increase{width:36px;font-size:14px}.custom-theme .el-input-number--medium .el-input__inner{padding-left:43px;padding-right:43px}.custom-theme .el-input-number--small{width:130px;line-height:30px}.custom-theme .el-input-number--small .el-input-number__decrease,.custom-theme .el-input-number--small .el-input-number__increase{width:32px;font-size:13px}.custom-theme .el-input-number--small .el-input-number__decrease [class*=el-icon],.custom-theme .el-input-number--small .el-input-number__increase [class*=el-icon]{-webkit-transform:scale(.9);transform:scale(.9)}.custom-theme .el-input-number--small .el-input__inner{padding-left:39px;padding-right:39px}.custom-theme .el-input-number--mini{width:130px;line-height:26px}.custom-theme .el-input-number--mini .el-input-number__decrease,.custom-theme .el-input-number--mini .el-input-number__increase{width:28px;font-size:12px}.custom-theme .el-input-number--mini .el-input-number__decrease [class*=el-icon],.custom-theme .el-input-number--mini .el-input-number__increase [class*=el-icon]{-webkit-transform:scale(.8);transform:scale(.8)}.custom-theme .el-input-number--mini .el-input__inner{padding-left:35px;padding-right:35px}.custom-theme .el-input-number.is-without-controls .el-input__inner{padding-left:15px;padding-right:15px}.custom-theme .el-input-number.is-controls-right .el-input__inner{padding-left:15px;padding-right:50px}.custom-theme .el-input-number.is-controls-right .el-input-number__decrease,.custom-theme .el-input-number.is-controls-right .el-input-number__increase{height:auto;line-height:19px}.custom-theme .el-input-number.is-controls-right .el-input-number__decrease [class*=el-icon],.custom-theme .el-input-number.is-controls-right .el-input-number__increase [class*=el-icon]{-webkit-transform:scale(.8);transform:scale(.8)}.custom-theme .el-input-number.is-controls-right .el-input-number__increase{border-radius:0 4px 0 0;border-bottom:1px solid #d8dce5}.custom-theme .el-input-number.is-controls-right .el-input-number__decrease{right:1px;bottom:1px;top:auto;left:auto;border-right:none;border-left:1px solid #d8dce5;border-radius:0 0 4px 0}.custom-theme .el-input-number.is-controls-right[class*=medium] [class*=decrease],.custom-theme .el-input-number.is-controls-right[class*=medium] [class*=increase]{line-height:17px}.custom-theme .el-input-number.is-controls-right[class*=small] [class*=decrease],.custom-theme .el-input-number.is-controls-right[class*=small] [class*=increase]{line-height:15px}.custom-theme .el-input-number.is-controls-right[class*=mini] [class*=decrease],.custom-theme .el-input-number.is-controls-right[class*=mini] [class*=increase]{line-height:13px}.custom-theme .el-tooltip__popper{position:absolute;border-radius:4px;padding:10px;z-index:2000;font-size:12px;line-height:1.2}.custom-theme .el-tooltip__popper .popper__arrow,.custom-theme .el-tooltip__popper .popper__arrow::after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.custom-theme .el-tooltip__popper .popper__arrow{border-width:6px}.custom-theme .el-tooltip__popper .popper__arrow::after{content:" ";border-width:5px}.custom-theme .el-tooltip__popper[x-placement^=top]{margin-bottom:12px}.custom-theme .el-tooltip__popper[x-placement^=top] .popper__arrow{bottom:-6px;border-top-color:#2d2f33;border-bottom-width:0}.custom-theme .el-tooltip__popper[x-placement^=top] .popper__arrow::after{bottom:1px;margin-left:-5px;border-top-color:#2d2f33;border-bottom-width:0}.custom-theme .el-tooltip__popper[x-placement^=bottom]{margin-top:12px}.custom-theme .el-tooltip__popper[x-placement^=bottom] .popper__arrow{top:-6px;border-top-width:0;border-bottom-color:#2d2f33}.custom-theme .el-tooltip__popper[x-placement^=bottom] .popper__arrow::after{top:1px;margin-left:-5px;border-top-width:0;border-bottom-color:#2d2f33}.custom-theme .el-tooltip__popper[x-placement^=right]{margin-left:12px}.custom-theme .el-tooltip__popper[x-placement^=right] .popper__arrow{left:-6px;border-right-color:#2d2f33;border-left-width:0}.custom-theme .el-tooltip__popper[x-placement^=right] .popper__arrow::after{bottom:-5px;left:1px;border-right-color:#2d2f33;border-left-width:0}.custom-theme .el-tooltip__popper[x-placement^=left]{margin-right:12px}.custom-theme .el-tooltip__popper[x-placement^=left] .popper__arrow{right:-6px;border-right-width:0;border-left-color:#2d2f33}.custom-theme .el-tooltip__popper[x-placement^=left] .popper__arrow::after{right:1px;bottom:-5px;margin-left:-5px;border-right-width:0;border-left-color:#2d2f33}.custom-theme .el-tooltip__popper.is-dark{background:#2d2f33;color:#fff}.custom-theme .el-tooltip__popper.is-light{background:#fff;border:1px solid #2d2f33}.custom-theme .el-tooltip__popper.is-light[x-placement^=top] .popper__arrow{border-top-color:#2d2f33}.custom-theme .el-tooltip__popper.is-light[x-placement^=top] .popper__arrow::after{border-top-color:#fff}.custom-theme .el-tooltip__popper.is-light[x-placement^=bottom] .popper__arrow{border-bottom-color:#2d2f33}.custom-theme .el-tooltip__popper.is-light[x-placement^=bottom] .popper__arrow::after{border-bottom-color:#fff}.custom-theme .el-tooltip__popper.is-light[x-placement^=left] .popper__arrow{border-left-color:#2d2f33}.custom-theme .el-tooltip__popper.is-light[x-placement^=left] .popper__arrow::after{border-left-color:#fff}.custom-theme .el-tooltip__popper.is-light[x-placement^=right] .popper__arrow{border-right-color:#2d2f33}.custom-theme .el-tooltip__popper.is-light[x-placement^=right] .popper__arrow::after{border-right-color:#fff}.custom-theme .el-slider::after,.custom-theme .el-slider::before{display:table;content:""}.custom-theme .el-slider::after{clear:both}.custom-theme .el-slider__runway{width:100%;height:6px;margin:16px 0;background-color:#dfe4ed;border-radius:3px;position:relative;cursor:pointer;vertical-align:middle}.custom-theme .el-slider__runway.show-input{margin-right:160px;width:auto}.custom-theme .el-slider__runway.disabled{cursor:default}.custom-theme .el-slider__runway.disabled .el-slider__bar{background-color:#b4bccc}.custom-theme .el-slider__runway.disabled .el-slider__button{border-color:#b4bccc}.custom-theme .el-slider__runway.disabled .el-slider__button-wrapper.hover,.custom-theme .el-slider__runway.disabled .el-slider__button-wrapper:hover{cursor:not-allowed}.custom-theme .el-slider__runway.disabled .el-slider__button-wrapper.dragging{cursor:not-allowed}.custom-theme .el-slider__runway.disabled .el-slider__button.dragging,.custom-theme .el-slider__runway.disabled .el-slider__button.hover,.custom-theme .el-slider__runway.disabled .el-slider__button:hover{-webkit-transform:scale(1);transform:scale(1)}.custom-theme .el-slider__runway.disabled .el-slider__button.hover,.custom-theme .el-slider__runway.disabled .el-slider__button:hover{cursor:not-allowed}.custom-theme .el-slider__runway.disabled .el-slider__button.dragging{cursor:not-allowed}.custom-theme .el-slider__input{float:right;margin-top:3px}.custom-theme .el-slider__bar{height:6px;background-color:#262729;border-top-left-radius:3px;border-bottom-left-radius:3px;position:absolute}.custom-theme .el-slider__button-wrapper{height:36px;width:36px;position:absolute;z-index:1001;top:-15px;-webkit-transform:translateX(-50%);transform:translateX(-50%);background-color:transparent;text-align:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.custom-theme .el-slider__button-wrapper::after{display:inline-block;content:"";height:100%;vertical-align:middle}.custom-theme .el-slider__button-wrapper .el-tooltip{vertical-align:middle;display:inline-block}.custom-theme .el-slider__button-wrapper.hover,.custom-theme .el-slider__button-wrapper:hover{cursor:-webkit-grab;cursor:grab}.custom-theme .el-slider__button-wrapper.dragging{cursor:-webkit-grabbing;cursor:grabbing}.custom-theme .el-slider__button{width:16px;height:16px;border:solid 2px #262729;background-color:#fff;border-radius:50%;-webkit-transition:.2s;transition:.2s;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.custom-theme .el-slider__button.dragging,.custom-theme .el-slider__button.hover,.custom-theme .el-slider__button:hover{-webkit-transform:scale(1.2);transform:scale(1.2)}.custom-theme .el-slider__button.hover,.custom-theme .el-slider__button:hover{cursor:-webkit-grab;cursor:grab}.custom-theme .el-slider__button.dragging{cursor:-webkit-grabbing;cursor:grabbing}.custom-theme .el-slider__stop{position:absolute;height:6px;width:6px;border-radius:100%;background-color:#fff;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.custom-theme .el-slider.is-vertical{position:relative}.custom-theme .el-slider.is-vertical .el-slider__runway{width:4px;height:100%;margin:0 16px}.custom-theme .el-slider.is-vertical .el-slider__bar{width:4px;height:auto;border-radius:0 0 3px 3px}.custom-theme .el-slider.is-vertical .el-slider__button-wrapper{top:auto;left:-15px;-webkit-transform:translateY(50%);transform:translateY(50%)}.custom-theme .el-slider.is-vertical .el-slider__stop{-webkit-transform:translateY(50%);transform:translateY(50%)}.custom-theme .el-slider.is-vertical.el-slider--with-input{padding-bottom:58px}.custom-theme .el-slider.is-vertical.el-slider--with-input .el-slider__input{overflow:visible;float:none;position:absolute;bottom:22px;width:36px;margin-top:15px}.custom-theme .el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input__inner{text-align:center;padding-left:5px;padding-right:5px}.custom-theme .el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input-number__decrease,.custom-theme .el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input-number__increase{top:32px;margin-top:-1px;border:1px solid #d8dce5;line-height:20px;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1)}.custom-theme .el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input-number__decrease{width:18px;right:18px;border-bottom-left-radius:4px}.custom-theme .el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input-number__increase{width:19px;border-bottom-right-radius:4px}.custom-theme .el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input-number__increase~.el-input .el-input__inner{border-bottom-left-radius:0;border-bottom-right-radius:0}.custom-theme .el-slider.is-vertical.el-slider--with-input .el-slider__input:hover .el-input-number__decrease,.custom-theme .el-slider.is-vertical.el-slider--with-input .el-slider__input:hover .el-input-number__increase{border-color:#b4bccc}.custom-theme .el-slider.is-vertical.el-slider--with-input .el-slider__input:active .el-input-number__decrease,.custom-theme .el-slider.is-vertical.el-slider--with-input .el-slider__input:active .el-input-number__increase{border-color:#262729}.custom-theme .el-loading-parent--relative{position:relative!important}.custom-theme .el-loading-parent--hidden{overflow:hidden!important}.custom-theme .el-loading-mask{position:absolute;z-index:10000;background-color:rgba(255,255,255,.9);margin:0;top:0;right:0;bottom:0;left:0;-webkit-transition:opacity .3s;transition:opacity .3s}.custom-theme .el-loading-mask.is-fullscreen{position:fixed}.custom-theme .el-loading-mask.is-fullscreen .el-loading-spinner{margin-top:-25px}.custom-theme .el-loading-mask.is-fullscreen .el-loading-spinner .circular{height:50px;width:50px}.custom-theme .el-loading-spinner{top:50%;margin-top:-21px;width:100%;text-align:center;position:absolute}.custom-theme .el-loading-spinner .el-loading-text{color:#262729;margin:3px 0;font-size:14px}.custom-theme .el-loading-spinner .circular{height:42px;width:42px;-webkit-animation:loading-rotate 2s linear infinite;animation:loading-rotate 2s linear infinite}.custom-theme .el-loading-spinner .path{-webkit-animation:loading-dash 1.5s ease-in-out infinite;animation:loading-dash 1.5s ease-in-out infinite;stroke-dasharray:90,150;stroke-dashoffset:0;stroke-width:2;stroke:#262729;stroke-linecap:round}.custom-theme .el-loading-spinner i{color:#262729}.custom-theme .el-loading-fade-enter,.custom-theme .el-loading-fade-leave-active{opacity:0}@-webkit-keyframes loading-rotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes loading-rotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes loading-dash{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-40px}100%{stroke-dasharray:90,150;stroke-dashoffset:-120px}}@keyframes loading-dash{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-40px}100%{stroke-dasharray:90,150;stroke-dashoffset:-120px}}.custom-theme .el-row{position:relative;-webkit-box-sizing:border-box;box-sizing:border-box}.custom-theme .el-row::after,.custom-theme .el-row::before{display:table;content:""}.custom-theme .el-row::after{clear:both}.custom-theme .el-row--flex{display:-webkit-box;display:-ms-flexbox;display:flex}.custom-theme .el-row--flex:after,.custom-theme .el-row--flex:before{display:none}.custom-theme .el-row--flex.is-justify-center{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.custom-theme .el-row--flex.is-justify-end{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.custom-theme .el-row--flex.is-justify-space-between{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.custom-theme .el-row--flex.is-justify-space-around{-ms-flex-pack:distribute;justify-content:space-around}.custom-theme .el-row--flex.is-align-middle{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.custom-theme .el-row--flex.is-align-bottom{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.custom-theme [class*=el-col-]{float:left;-webkit-box-sizing:border-box;box-sizing:border-box}.custom-theme .el-col-0{display:none}.custom-theme .el-col-1{width:4.16667%}.custom-theme .el-col-offset-1{margin-left:4.16667%}.custom-theme .el-col-pull-1{position:relative;right:4.16667%}.custom-theme .el-col-push-1{position:relative;left:4.16667%}.custom-theme .el-col-2{width:8.33333%}.custom-theme .el-col-offset-2{margin-left:8.33333%}.custom-theme .el-col-pull-2{position:relative;right:8.33333%}.custom-theme .el-col-push-2{position:relative;left:8.33333%}.custom-theme .el-col-3{width:12.5%}.custom-theme .el-col-offset-3{margin-left:12.5%}.custom-theme .el-col-pull-3{position:relative;right:12.5%}.custom-theme .el-col-push-3{position:relative;left:12.5%}.custom-theme .el-col-4{width:16.66667%}.custom-theme .el-col-offset-4{margin-left:16.66667%}.custom-theme .el-col-pull-4{position:relative;right:16.66667%}.custom-theme .el-col-push-4{position:relative;left:16.66667%}.custom-theme .el-col-5{width:20.83333%}.custom-theme .el-col-offset-5{margin-left:20.83333%}.custom-theme .el-col-pull-5{position:relative;right:20.83333%}.custom-theme .el-col-push-5{position:relative;left:20.83333%}.custom-theme .el-col-6{width:25%}.custom-theme .el-col-offset-6{margin-left:25%}.custom-theme .el-col-pull-6{position:relative;right:25%}.custom-theme .el-col-push-6{position:relative;left:25%}.custom-theme .el-col-7{width:29.16667%}.custom-theme .el-col-offset-7{margin-left:29.16667%}.custom-theme .el-col-pull-7{position:relative;right:29.16667%}.custom-theme .el-col-push-7{position:relative;left:29.16667%}.custom-theme .el-col-8{width:33.33333%}.custom-theme .el-col-offset-8{margin-left:33.33333%}.custom-theme .el-col-pull-8{position:relative;right:33.33333%}.custom-theme .el-col-push-8{position:relative;left:33.33333%}.custom-theme .el-col-9{width:37.5%}.custom-theme .el-col-offset-9{margin-left:37.5%}.custom-theme .el-col-pull-9{position:relative;right:37.5%}.custom-theme .el-col-push-9{position:relative;left:37.5%}.custom-theme .el-col-10{width:41.66667%}.custom-theme .el-col-offset-10{margin-left:41.66667%}.custom-theme .el-col-pull-10{position:relative;right:41.66667%}.custom-theme .el-col-push-10{position:relative;left:41.66667%}.custom-theme .el-col-11{width:45.83333%}.custom-theme .el-col-offset-11{margin-left:45.83333%}.custom-theme .el-col-pull-11{position:relative;right:45.83333%}.custom-theme .el-col-push-11{position:relative;left:45.83333%}.custom-theme .el-col-12{width:50%}.custom-theme .el-col-offset-12{margin-left:50%}.custom-theme .el-col-pull-12{position:relative;right:50%}.custom-theme .el-col-push-12{position:relative;left:50%}.custom-theme .el-col-13{width:54.16667%}.custom-theme .el-col-offset-13{margin-left:54.16667%}.custom-theme .el-col-pull-13{position:relative;right:54.16667%}.custom-theme .el-col-push-13{position:relative;left:54.16667%}.custom-theme .el-col-14{width:58.33333%}.custom-theme .el-col-offset-14{margin-left:58.33333%}.custom-theme .el-col-pull-14{position:relative;right:58.33333%}.custom-theme .el-col-push-14{position:relative;left:58.33333%}.custom-theme .el-col-15{width:62.5%}.custom-theme .el-col-offset-15{margin-left:62.5%}.custom-theme .el-col-pull-15{position:relative;right:62.5%}.custom-theme .el-col-push-15{position:relative;left:62.5%}.custom-theme .el-col-16{width:66.66667%}.custom-theme .el-col-offset-16{margin-left:66.66667%}.custom-theme .el-col-pull-16{position:relative;right:66.66667%}.custom-theme .el-col-push-16{position:relative;left:66.66667%}.custom-theme .el-col-17{width:70.83333%}.custom-theme .el-col-offset-17{margin-left:70.83333%}.custom-theme .el-col-pull-17{position:relative;right:70.83333%}.custom-theme .el-col-push-17{position:relative;left:70.83333%}.custom-theme .el-col-18{width:75%}.custom-theme .el-col-offset-18{margin-left:75%}.custom-theme .el-col-pull-18{position:relative;right:75%}.custom-theme .el-col-push-18{position:relative;left:75%}.custom-theme .el-col-19{width:79.16667%}.custom-theme .el-col-offset-19{margin-left:79.16667%}.custom-theme .el-col-pull-19{position:relative;right:79.16667%}.custom-theme .el-col-push-19{position:relative;left:79.16667%}.custom-theme .el-col-20{width:83.33333%}.custom-theme .el-col-offset-20{margin-left:83.33333%}.custom-theme .el-col-pull-20{position:relative;right:83.33333%}.custom-theme .el-col-push-20{position:relative;left:83.33333%}.custom-theme .el-col-21{width:87.5%}.custom-theme .el-col-offset-21{margin-left:87.5%}.custom-theme .el-col-pull-21{position:relative;right:87.5%}.custom-theme .el-col-push-21{position:relative;left:87.5%}.custom-theme .el-col-22{width:91.66667%}.custom-theme .el-col-offset-22{margin-left:91.66667%}.custom-theme .el-col-pull-22{position:relative;right:91.66667%}.custom-theme .el-col-push-22{position:relative;left:91.66667%}.custom-theme .el-col-23{width:95.83333%}.custom-theme .el-col-offset-23{margin-left:95.83333%}.custom-theme .el-col-pull-23{position:relative;right:95.83333%}.custom-theme .el-col-push-23{position:relative;left:95.83333%}.custom-theme .el-col-24{width:100%}.custom-theme .el-col-offset-24{margin-left:100%}.custom-theme .el-col-pull-24{position:relative;right:100%}.custom-theme .el-col-push-24{position:relative;left:100%}@media only screen and (max-width:768px){.custom-theme .el-col-xs-0{display:none}.custom-theme .el-col-xs-1{width:4.16667%}.custom-theme .el-col-xs-offset-1{margin-left:4.16667%}.custom-theme .el-col-xs-pull-1{position:relative;right:4.16667%}.custom-theme .el-col-xs-push-1{position:relative;left:4.16667%}.custom-theme .el-col-xs-2{width:8.33333%}.custom-theme .el-col-xs-offset-2{margin-left:8.33333%}.custom-theme .el-col-xs-pull-2{position:relative;right:8.33333%}.custom-theme .el-col-xs-push-2{position:relative;left:8.33333%}.custom-theme .el-col-xs-3{width:12.5%}.custom-theme .el-col-xs-offset-3{margin-left:12.5%}.custom-theme .el-col-xs-pull-3{position:relative;right:12.5%}.custom-theme .el-col-xs-push-3{position:relative;left:12.5%}.custom-theme .el-col-xs-4{width:16.66667%}.custom-theme .el-col-xs-offset-4{margin-left:16.66667%}.custom-theme .el-col-xs-pull-4{position:relative;right:16.66667%}.custom-theme .el-col-xs-push-4{position:relative;left:16.66667%}.custom-theme .el-col-xs-5{width:20.83333%}.custom-theme .el-col-xs-offset-5{margin-left:20.83333%}.custom-theme .el-col-xs-pull-5{position:relative;right:20.83333%}.custom-theme .el-col-xs-push-5{position:relative;left:20.83333%}.custom-theme .el-col-xs-6{width:25%}.custom-theme .el-col-xs-offset-6{margin-left:25%}.custom-theme .el-col-xs-pull-6{position:relative;right:25%}.custom-theme .el-col-xs-push-6{position:relative;left:25%}.custom-theme .el-col-xs-7{width:29.16667%}.custom-theme .el-col-xs-offset-7{margin-left:29.16667%}.custom-theme .el-col-xs-pull-7{position:relative;right:29.16667%}.custom-theme .el-col-xs-push-7{position:relative;left:29.16667%}.custom-theme .el-col-xs-8{width:33.33333%}.custom-theme .el-col-xs-offset-8{margin-left:33.33333%}.custom-theme .el-col-xs-pull-8{position:relative;right:33.33333%}.custom-theme .el-col-xs-push-8{position:relative;left:33.33333%}.custom-theme .el-col-xs-9{width:37.5%}.custom-theme .el-col-xs-offset-9{margin-left:37.5%}.custom-theme .el-col-xs-pull-9{position:relative;right:37.5%}.custom-theme .el-col-xs-push-9{position:relative;left:37.5%}.custom-theme .el-col-xs-10{width:41.66667%}.custom-theme .el-col-xs-offset-10{margin-left:41.66667%}.custom-theme .el-col-xs-pull-10{position:relative;right:41.66667%}.custom-theme .el-col-xs-push-10{position:relative;left:41.66667%}.custom-theme .el-col-xs-11{width:45.83333%}.custom-theme .el-col-xs-offset-11{margin-left:45.83333%}.custom-theme .el-col-xs-pull-11{position:relative;right:45.83333%}.custom-theme .el-col-xs-push-11{position:relative;left:45.83333%}.custom-theme .el-col-xs-12{width:50%}.custom-theme .el-col-xs-offset-12{margin-left:50%}.custom-theme .el-col-xs-pull-12{position:relative;right:50%}.custom-theme .el-col-xs-push-12{position:relative;left:50%}.custom-theme .el-col-xs-13{width:54.16667%}.custom-theme .el-col-xs-offset-13{margin-left:54.16667%}.custom-theme .el-col-xs-pull-13{position:relative;right:54.16667%}.custom-theme .el-col-xs-push-13{position:relative;left:54.16667%}.custom-theme .el-col-xs-14{width:58.33333%}.custom-theme .el-col-xs-offset-14{margin-left:58.33333%}.custom-theme .el-col-xs-pull-14{position:relative;right:58.33333%}.custom-theme .el-col-xs-push-14{position:relative;left:58.33333%}.custom-theme .el-col-xs-15{width:62.5%}.custom-theme .el-col-xs-offset-15{margin-left:62.5%}.custom-theme .el-col-xs-pull-15{position:relative;right:62.5%}.custom-theme .el-col-xs-push-15{position:relative;left:62.5%}.custom-theme .el-col-xs-16{width:66.66667%}.custom-theme .el-col-xs-offset-16{margin-left:66.66667%}.custom-theme .el-col-xs-pull-16{position:relative;right:66.66667%}.custom-theme .el-col-xs-push-16{position:relative;left:66.66667%}.custom-theme .el-col-xs-17{width:70.83333%}.custom-theme .el-col-xs-offset-17{margin-left:70.83333%}.custom-theme .el-col-xs-pull-17{position:relative;right:70.83333%}.custom-theme .el-col-xs-push-17{position:relative;left:70.83333%}.custom-theme .el-col-xs-18{width:75%}.custom-theme .el-col-xs-offset-18{margin-left:75%}.custom-theme .el-col-xs-pull-18{position:relative;right:75%}.custom-theme .el-col-xs-push-18{position:relative;left:75%}.custom-theme .el-col-xs-19{width:79.16667%}.custom-theme .el-col-xs-offset-19{margin-left:79.16667%}.custom-theme .el-col-xs-pull-19{position:relative;right:79.16667%}.custom-theme .el-col-xs-push-19{position:relative;left:79.16667%}.custom-theme .el-col-xs-20{width:83.33333%}.custom-theme .el-col-xs-offset-20{margin-left:83.33333%}.custom-theme .el-col-xs-pull-20{position:relative;right:83.33333%}.custom-theme .el-col-xs-push-20{position:relative;left:83.33333%}.custom-theme .el-col-xs-21{width:87.5%}.custom-theme .el-col-xs-offset-21{margin-left:87.5%}.custom-theme .el-col-xs-pull-21{position:relative;right:87.5%}.custom-theme .el-col-xs-push-21{position:relative;left:87.5%}.custom-theme .el-col-xs-22{width:91.66667%}.custom-theme .el-col-xs-offset-22{margin-left:91.66667%}.custom-theme .el-col-xs-pull-22{position:relative;right:91.66667%}.custom-theme .el-col-xs-push-22{position:relative;left:91.66667%}.custom-theme .el-col-xs-23{width:95.83333%}.custom-theme .el-col-xs-offset-23{margin-left:95.83333%}.custom-theme .el-col-xs-pull-23{position:relative;right:95.83333%}.custom-theme .el-col-xs-push-23{position:relative;left:95.83333%}.custom-theme .el-col-xs-24{width:100%}.custom-theme .el-col-xs-offset-24{margin-left:100%}.custom-theme .el-col-xs-pull-24{position:relative;right:100%}.custom-theme .el-col-xs-push-24{position:relative;left:100%}}@media only screen and (min-width:768px){.custom-theme .el-col-sm-0{display:none}.custom-theme .el-col-sm-1{width:4.16667%}.custom-theme .el-col-sm-offset-1{margin-left:4.16667%}.custom-theme .el-col-sm-pull-1{position:relative;right:4.16667%}.custom-theme .el-col-sm-push-1{position:relative;left:4.16667%}.custom-theme .el-col-sm-2{width:8.33333%}.custom-theme .el-col-sm-offset-2{margin-left:8.33333%}.custom-theme .el-col-sm-pull-2{position:relative;right:8.33333%}.custom-theme .el-col-sm-push-2{position:relative;left:8.33333%}.custom-theme .el-col-sm-3{width:12.5%}.custom-theme .el-col-sm-offset-3{margin-left:12.5%}.custom-theme .el-col-sm-pull-3{position:relative;right:12.5%}.custom-theme .el-col-sm-push-3{position:relative;left:12.5%}.custom-theme .el-col-sm-4{width:16.66667%}.custom-theme .el-col-sm-offset-4{margin-left:16.66667%}.custom-theme .el-col-sm-pull-4{position:relative;right:16.66667%}.custom-theme .el-col-sm-push-4{position:relative;left:16.66667%}.custom-theme .el-col-sm-5{width:20.83333%}.custom-theme .el-col-sm-offset-5{margin-left:20.83333%}.custom-theme .el-col-sm-pull-5{position:relative;right:20.83333%}.custom-theme .el-col-sm-push-5{position:relative;left:20.83333%}.custom-theme .el-col-sm-6{width:25%}.custom-theme .el-col-sm-offset-6{margin-left:25%}.custom-theme .el-col-sm-pull-6{position:relative;right:25%}.custom-theme .el-col-sm-push-6{position:relative;left:25%}.custom-theme .el-col-sm-7{width:29.16667%}.custom-theme .el-col-sm-offset-7{margin-left:29.16667%}.custom-theme .el-col-sm-pull-7{position:relative;right:29.16667%}.custom-theme .el-col-sm-push-7{position:relative;left:29.16667%}.custom-theme .el-col-sm-8{width:33.33333%}.custom-theme .el-col-sm-offset-8{margin-left:33.33333%}.custom-theme .el-col-sm-pull-8{position:relative;right:33.33333%}.custom-theme .el-col-sm-push-8{position:relative;left:33.33333%}.custom-theme .el-col-sm-9{width:37.5%}.custom-theme .el-col-sm-offset-9{margin-left:37.5%}.custom-theme .el-col-sm-pull-9{position:relative;right:37.5%}.custom-theme .el-col-sm-push-9{position:relative;left:37.5%}.custom-theme .el-col-sm-10{width:41.66667%}.custom-theme .el-col-sm-offset-10{margin-left:41.66667%}.custom-theme .el-col-sm-pull-10{position:relative;right:41.66667%}.custom-theme .el-col-sm-push-10{position:relative;left:41.66667%}.custom-theme .el-col-sm-11{width:45.83333%}.custom-theme .el-col-sm-offset-11{margin-left:45.83333%}.custom-theme .el-col-sm-pull-11{position:relative;right:45.83333%}.custom-theme .el-col-sm-push-11{position:relative;left:45.83333%}.custom-theme .el-col-sm-12{width:50%}.custom-theme .el-col-sm-offset-12{margin-left:50%}.custom-theme .el-col-sm-pull-12{position:relative;right:50%}.custom-theme .el-col-sm-push-12{position:relative;left:50%}.custom-theme .el-col-sm-13{width:54.16667%}.custom-theme .el-col-sm-offset-13{margin-left:54.16667%}.custom-theme .el-col-sm-pull-13{position:relative;right:54.16667%}.custom-theme .el-col-sm-push-13{position:relative;left:54.16667%}.custom-theme .el-col-sm-14{width:58.33333%}.custom-theme .el-col-sm-offset-14{margin-left:58.33333%}.custom-theme .el-col-sm-pull-14{position:relative;right:58.33333%}.custom-theme .el-col-sm-push-14{position:relative;left:58.33333%}.custom-theme .el-col-sm-15{width:62.5%}.custom-theme .el-col-sm-offset-15{margin-left:62.5%}.custom-theme .el-col-sm-pull-15{position:relative;right:62.5%}.custom-theme .el-col-sm-push-15{position:relative;left:62.5%}.custom-theme .el-col-sm-16{width:66.66667%}.custom-theme .el-col-sm-offset-16{margin-left:66.66667%}.custom-theme .el-col-sm-pull-16{position:relative;right:66.66667%}.custom-theme .el-col-sm-push-16{position:relative;left:66.66667%}.custom-theme .el-col-sm-17{width:70.83333%}.custom-theme .el-col-sm-offset-17{margin-left:70.83333%}.custom-theme .el-col-sm-pull-17{position:relative;right:70.83333%}.custom-theme .el-col-sm-push-17{position:relative;left:70.83333%}.custom-theme .el-col-sm-18{width:75%}.custom-theme .el-col-sm-offset-18{margin-left:75%}.custom-theme .el-col-sm-pull-18{position:relative;right:75%}.custom-theme .el-col-sm-push-18{position:relative;left:75%}.custom-theme .el-col-sm-19{width:79.16667%}.custom-theme .el-col-sm-offset-19{margin-left:79.16667%}.custom-theme .el-col-sm-pull-19{position:relative;right:79.16667%}.custom-theme .el-col-sm-push-19{position:relative;left:79.16667%}.custom-theme .el-col-sm-20{width:83.33333%}.custom-theme .el-col-sm-offset-20{margin-left:83.33333%}.custom-theme .el-col-sm-pull-20{position:relative;right:83.33333%}.custom-theme .el-col-sm-push-20{position:relative;left:83.33333%}.custom-theme .el-col-sm-21{width:87.5%}.custom-theme .el-col-sm-offset-21{margin-left:87.5%}.custom-theme .el-col-sm-pull-21{position:relative;right:87.5%}.custom-theme .el-col-sm-push-21{position:relative;left:87.5%}.custom-theme .el-col-sm-22{width:91.66667%}.custom-theme .el-col-sm-offset-22{margin-left:91.66667%}.custom-theme .el-col-sm-pull-22{position:relative;right:91.66667%}.custom-theme .el-col-sm-push-22{position:relative;left:91.66667%}.custom-theme .el-col-sm-23{width:95.83333%}.custom-theme .el-col-sm-offset-23{margin-left:95.83333%}.custom-theme .el-col-sm-pull-23{position:relative;right:95.83333%}.custom-theme .el-col-sm-push-23{position:relative;left:95.83333%}.custom-theme .el-col-sm-24{width:100%}.custom-theme .el-col-sm-offset-24{margin-left:100%}.custom-theme .el-col-sm-pull-24{position:relative;right:100%}.custom-theme .el-col-sm-push-24{position:relative;left:100%}}@media only screen and (min-width:992px){.custom-theme .el-col-md-0{display:none}.custom-theme .el-col-md-1{width:4.16667%}.custom-theme .el-col-md-offset-1{margin-left:4.16667%}.custom-theme .el-col-md-pull-1{position:relative;right:4.16667%}.custom-theme .el-col-md-push-1{position:relative;left:4.16667%}.custom-theme .el-col-md-2{width:8.33333%}.custom-theme .el-col-md-offset-2{margin-left:8.33333%}.custom-theme .el-col-md-pull-2{position:relative;right:8.33333%}.custom-theme .el-col-md-push-2{position:relative;left:8.33333%}.custom-theme .el-col-md-3{width:12.5%}.custom-theme .el-col-md-offset-3{margin-left:12.5%}.custom-theme .el-col-md-pull-3{position:relative;right:12.5%}.custom-theme .el-col-md-push-3{position:relative;left:12.5%}.custom-theme .el-col-md-4{width:16.66667%}.custom-theme .el-col-md-offset-4{margin-left:16.66667%}.custom-theme .el-col-md-pull-4{position:relative;right:16.66667%}.custom-theme .el-col-md-push-4{position:relative;left:16.66667%}.custom-theme .el-col-md-5{width:20.83333%}.custom-theme .el-col-md-offset-5{margin-left:20.83333%}.custom-theme .el-col-md-pull-5{position:relative;right:20.83333%}.custom-theme .el-col-md-push-5{position:relative;left:20.83333%}.custom-theme .el-col-md-6{width:25%}.custom-theme .el-col-md-offset-6{margin-left:25%}.custom-theme .el-col-md-pull-6{position:relative;right:25%}.custom-theme .el-col-md-push-6{position:relative;left:25%}.custom-theme .el-col-md-7{width:29.16667%}.custom-theme .el-col-md-offset-7{margin-left:29.16667%}.custom-theme .el-col-md-pull-7{position:relative;right:29.16667%}.custom-theme .el-col-md-push-7{position:relative;left:29.16667%}.custom-theme .el-col-md-8{width:33.33333%}.custom-theme .el-col-md-offset-8{margin-left:33.33333%}.custom-theme .el-col-md-pull-8{position:relative;right:33.33333%}.custom-theme .el-col-md-push-8{position:relative;left:33.33333%}.custom-theme .el-col-md-9{width:37.5%}.custom-theme .el-col-md-offset-9{margin-left:37.5%}.custom-theme .el-col-md-pull-9{position:relative;right:37.5%}.custom-theme .el-col-md-push-9{position:relative;left:37.5%}.custom-theme .el-col-md-10{width:41.66667%}.custom-theme .el-col-md-offset-10{margin-left:41.66667%}.custom-theme .el-col-md-pull-10{position:relative;right:41.66667%}.custom-theme .el-col-md-push-10{position:relative;left:41.66667%}.custom-theme .el-col-md-11{width:45.83333%}.custom-theme .el-col-md-offset-11{margin-left:45.83333%}.custom-theme .el-col-md-pull-11{position:relative;right:45.83333%}.custom-theme .el-col-md-push-11{position:relative;left:45.83333%}.custom-theme .el-col-md-12{width:50%}.custom-theme .el-col-md-offset-12{margin-left:50%}.custom-theme .el-col-md-pull-12{position:relative;right:50%}.custom-theme .el-col-md-push-12{position:relative;left:50%}.custom-theme .el-col-md-13{width:54.16667%}.custom-theme .el-col-md-offset-13{margin-left:54.16667%}.custom-theme .el-col-md-pull-13{position:relative;right:54.16667%}.custom-theme .el-col-md-push-13{position:relative;left:54.16667%}.custom-theme .el-col-md-14{width:58.33333%}.custom-theme .el-col-md-offset-14{margin-left:58.33333%}.custom-theme .el-col-md-pull-14{position:relative;right:58.33333%}.custom-theme .el-col-md-push-14{position:relative;left:58.33333%}.custom-theme .el-col-md-15{width:62.5%}.custom-theme .el-col-md-offset-15{margin-left:62.5%}.custom-theme .el-col-md-pull-15{position:relative;right:62.5%}.custom-theme .el-col-md-push-15{position:relative;left:62.5%}.custom-theme .el-col-md-16{width:66.66667%}.custom-theme .el-col-md-offset-16{margin-left:66.66667%}.custom-theme .el-col-md-pull-16{position:relative;right:66.66667%}.custom-theme .el-col-md-push-16{position:relative;left:66.66667%}.custom-theme .el-col-md-17{width:70.83333%}.custom-theme .el-col-md-offset-17{margin-left:70.83333%}.custom-theme .el-col-md-pull-17{position:relative;right:70.83333%}.custom-theme .el-col-md-push-17{position:relative;left:70.83333%}.custom-theme .el-col-md-18{width:75%}.custom-theme .el-col-md-offset-18{margin-left:75%}.custom-theme .el-col-md-pull-18{position:relative;right:75%}.custom-theme .el-col-md-push-18{position:relative;left:75%}.custom-theme .el-col-md-19{width:79.16667%}.custom-theme .el-col-md-offset-19{margin-left:79.16667%}.custom-theme .el-col-md-pull-19{position:relative;right:79.16667%}.custom-theme .el-col-md-push-19{position:relative;left:79.16667%}.custom-theme .el-col-md-20{width:83.33333%}.custom-theme .el-col-md-offset-20{margin-left:83.33333%}.custom-theme .el-col-md-pull-20{position:relative;right:83.33333%}.custom-theme .el-col-md-push-20{position:relative;left:83.33333%}.custom-theme .el-col-md-21{width:87.5%}.custom-theme .el-col-md-offset-21{margin-left:87.5%}.custom-theme .el-col-md-pull-21{position:relative;right:87.5%}.custom-theme .el-col-md-push-21{position:relative;left:87.5%}.custom-theme .el-col-md-22{width:91.66667%}.custom-theme .el-col-md-offset-22{margin-left:91.66667%}.custom-theme .el-col-md-pull-22{position:relative;right:91.66667%}.custom-theme .el-col-md-push-22{position:relative;left:91.66667%}.custom-theme .el-col-md-23{width:95.83333%}.custom-theme .el-col-md-offset-23{margin-left:95.83333%}.custom-theme .el-col-md-pull-23{position:relative;right:95.83333%}.custom-theme .el-col-md-push-23{position:relative;left:95.83333%}.custom-theme .el-col-md-24{width:100%}.custom-theme .el-col-md-offset-24{margin-left:100%}.custom-theme .el-col-md-pull-24{position:relative;right:100%}.custom-theme .el-col-md-push-24{position:relative;left:100%}}@media only screen and (min-width:1200px){.custom-theme .el-col-lg-0{display:none}.custom-theme .el-col-lg-1{width:4.16667%}.custom-theme .el-col-lg-offset-1{margin-left:4.16667%}.custom-theme .el-col-lg-pull-1{position:relative;right:4.16667%}.custom-theme .el-col-lg-push-1{position:relative;left:4.16667%}.custom-theme .el-col-lg-2{width:8.33333%}.custom-theme .el-col-lg-offset-2{margin-left:8.33333%}.custom-theme .el-col-lg-pull-2{position:relative;right:8.33333%}.custom-theme .el-col-lg-push-2{position:relative;left:8.33333%}.custom-theme .el-col-lg-3{width:12.5%}.custom-theme .el-col-lg-offset-3{margin-left:12.5%}.custom-theme .el-col-lg-pull-3{position:relative;right:12.5%}.custom-theme .el-col-lg-push-3{position:relative;left:12.5%}.custom-theme .el-col-lg-4{width:16.66667%}.custom-theme .el-col-lg-offset-4{margin-left:16.66667%}.custom-theme .el-col-lg-pull-4{position:relative;right:16.66667%}.custom-theme .el-col-lg-push-4{position:relative;left:16.66667%}.custom-theme .el-col-lg-5{width:20.83333%}.custom-theme .el-col-lg-offset-5{margin-left:20.83333%}.custom-theme .el-col-lg-pull-5{position:relative;right:20.83333%}.custom-theme .el-col-lg-push-5{position:relative;left:20.83333%}.custom-theme .el-col-lg-6{width:25%}.custom-theme .el-col-lg-offset-6{margin-left:25%}.custom-theme .el-col-lg-pull-6{position:relative;right:25%}.custom-theme .el-col-lg-push-6{position:relative;left:25%}.custom-theme .el-col-lg-7{width:29.16667%}.custom-theme .el-col-lg-offset-7{margin-left:29.16667%}.custom-theme .el-col-lg-pull-7{position:relative;right:29.16667%}.custom-theme .el-col-lg-push-7{position:relative;left:29.16667%}.custom-theme .el-col-lg-8{width:33.33333%}.custom-theme .el-col-lg-offset-8{margin-left:33.33333%}.custom-theme .el-col-lg-pull-8{position:relative;right:33.33333%}.custom-theme .el-col-lg-push-8{position:relative;left:33.33333%}.custom-theme .el-col-lg-9{width:37.5%}.custom-theme .el-col-lg-offset-9{margin-left:37.5%}.custom-theme .el-col-lg-pull-9{position:relative;right:37.5%}.custom-theme .el-col-lg-push-9{position:relative;left:37.5%}.custom-theme .el-col-lg-10{width:41.66667%}.custom-theme .el-col-lg-offset-10{margin-left:41.66667%}.custom-theme .el-col-lg-pull-10{position:relative;right:41.66667%}.custom-theme .el-col-lg-push-10{position:relative;left:41.66667%}.custom-theme .el-col-lg-11{width:45.83333%}.custom-theme .el-col-lg-offset-11{margin-left:45.83333%}.custom-theme .el-col-lg-pull-11{position:relative;right:45.83333%}.custom-theme .el-col-lg-push-11{position:relative;left:45.83333%}.custom-theme .el-col-lg-12{width:50%}.custom-theme .el-col-lg-offset-12{margin-left:50%}.custom-theme .el-col-lg-pull-12{position:relative;right:50%}.custom-theme .el-col-lg-push-12{position:relative;left:50%}.custom-theme .el-col-lg-13{width:54.16667%}.custom-theme .el-col-lg-offset-13{margin-left:54.16667%}.custom-theme .el-col-lg-pull-13{position:relative;right:54.16667%}.custom-theme .el-col-lg-push-13{position:relative;left:54.16667%}.custom-theme .el-col-lg-14{width:58.33333%}.custom-theme .el-col-lg-offset-14{margin-left:58.33333%}.custom-theme .el-col-lg-pull-14{position:relative;right:58.33333%}.custom-theme .el-col-lg-push-14{position:relative;left:58.33333%}.custom-theme .el-col-lg-15{width:62.5%}.custom-theme .el-col-lg-offset-15{margin-left:62.5%}.custom-theme .el-col-lg-pull-15{position:relative;right:62.5%}.custom-theme .el-col-lg-push-15{position:relative;left:62.5%}.custom-theme .el-col-lg-16{width:66.66667%}.custom-theme .el-col-lg-offset-16{margin-left:66.66667%}.custom-theme .el-col-lg-pull-16{position:relative;right:66.66667%}.custom-theme .el-col-lg-push-16{position:relative;left:66.66667%}.custom-theme .el-col-lg-17{width:70.83333%}.custom-theme .el-col-lg-offset-17{margin-left:70.83333%}.custom-theme .el-col-lg-pull-17{position:relative;right:70.83333%}.custom-theme .el-col-lg-push-17{position:relative;left:70.83333%}.custom-theme .el-col-lg-18{width:75%}.custom-theme .el-col-lg-offset-18{margin-left:75%}.custom-theme .el-col-lg-pull-18{position:relative;right:75%}.custom-theme .el-col-lg-push-18{position:relative;left:75%}.custom-theme .el-col-lg-19{width:79.16667%}.custom-theme .el-col-lg-offset-19{margin-left:79.16667%}.custom-theme .el-col-lg-pull-19{position:relative;right:79.16667%}.custom-theme .el-col-lg-push-19{position:relative;left:79.16667%}.custom-theme .el-col-lg-20{width:83.33333%}.custom-theme .el-col-lg-offset-20{margin-left:83.33333%}.custom-theme .el-col-lg-pull-20{position:relative;right:83.33333%}.custom-theme .el-col-lg-push-20{position:relative;left:83.33333%}.custom-theme .el-col-lg-21{width:87.5%}.custom-theme .el-col-lg-offset-21{margin-left:87.5%}.custom-theme .el-col-lg-pull-21{position:relative;right:87.5%}.custom-theme .el-col-lg-push-21{position:relative;left:87.5%}.custom-theme .el-col-lg-22{width:91.66667%}.custom-theme .el-col-lg-offset-22{margin-left:91.66667%}.custom-theme .el-col-lg-pull-22{position:relative;right:91.66667%}.custom-theme .el-col-lg-push-22{position:relative;left:91.66667%}.custom-theme .el-col-lg-23{width:95.83333%}.custom-theme .el-col-lg-offset-23{margin-left:95.83333%}.custom-theme .el-col-lg-pull-23{position:relative;right:95.83333%}.custom-theme .el-col-lg-push-23{position:relative;left:95.83333%}.custom-theme .el-col-lg-24{width:100%}.custom-theme .el-col-lg-offset-24{margin-left:100%}.custom-theme .el-col-lg-pull-24{position:relative;right:100%}.custom-theme .el-col-lg-push-24{position:relative;left:100%}}@media only screen and (min-width:1920px){.custom-theme .el-col-xl-0{display:none}.custom-theme .el-col-xl-1{width:4.16667%}.custom-theme .el-col-xl-offset-1{margin-left:4.16667%}.custom-theme .el-col-xl-pull-1{position:relative;right:4.16667%}.custom-theme .el-col-xl-push-1{position:relative;left:4.16667%}.custom-theme .el-col-xl-2{width:8.33333%}.custom-theme .el-col-xl-offset-2{margin-left:8.33333%}.custom-theme .el-col-xl-pull-2{position:relative;right:8.33333%}.custom-theme .el-col-xl-push-2{position:relative;left:8.33333%}.custom-theme .el-col-xl-3{width:12.5%}.custom-theme .el-col-xl-offset-3{margin-left:12.5%}.custom-theme .el-col-xl-pull-3{position:relative;right:12.5%}.custom-theme .el-col-xl-push-3{position:relative;left:12.5%}.custom-theme .el-col-xl-4{width:16.66667%}.custom-theme .el-col-xl-offset-4{margin-left:16.66667%}.custom-theme .el-col-xl-pull-4{position:relative;right:16.66667%}.custom-theme .el-col-xl-push-4{position:relative;left:16.66667%}.custom-theme .el-col-xl-5{width:20.83333%}.custom-theme .el-col-xl-offset-5{margin-left:20.83333%}.custom-theme .el-col-xl-pull-5{position:relative;right:20.83333%}.custom-theme .el-col-xl-push-5{position:relative;left:20.83333%}.custom-theme .el-col-xl-6{width:25%}.custom-theme .el-col-xl-offset-6{margin-left:25%}.custom-theme .el-col-xl-pull-6{position:relative;right:25%}.custom-theme .el-col-xl-push-6{position:relative;left:25%}.custom-theme .el-col-xl-7{width:29.16667%}.custom-theme .el-col-xl-offset-7{margin-left:29.16667%}.custom-theme .el-col-xl-pull-7{position:relative;right:29.16667%}.custom-theme .el-col-xl-push-7{position:relative;left:29.16667%}.custom-theme .el-col-xl-8{width:33.33333%}.custom-theme .el-col-xl-offset-8{margin-left:33.33333%}.custom-theme .el-col-xl-pull-8{position:relative;right:33.33333%}.custom-theme .el-col-xl-push-8{position:relative;left:33.33333%}.custom-theme .el-col-xl-9{width:37.5%}.custom-theme .el-col-xl-offset-9{margin-left:37.5%}.custom-theme .el-col-xl-pull-9{position:relative;right:37.5%}.custom-theme .el-col-xl-push-9{position:relative;left:37.5%}.custom-theme .el-col-xl-10{width:41.66667%}.custom-theme .el-col-xl-offset-10{margin-left:41.66667%}.custom-theme .el-col-xl-pull-10{position:relative;right:41.66667%}.custom-theme .el-col-xl-push-10{position:relative;left:41.66667%}.custom-theme .el-col-xl-11{width:45.83333%}.custom-theme .el-col-xl-offset-11{margin-left:45.83333%}.custom-theme .el-col-xl-pull-11{position:relative;right:45.83333%}.custom-theme .el-col-xl-push-11{position:relative;left:45.83333%}.custom-theme .el-col-xl-12{width:50%}.custom-theme .el-col-xl-offset-12{margin-left:50%}.custom-theme .el-col-xl-pull-12{position:relative;right:50%}.custom-theme .el-col-xl-push-12{position:relative;left:50%}.custom-theme .el-col-xl-13{width:54.16667%}.custom-theme .el-col-xl-offset-13{margin-left:54.16667%}.custom-theme .el-col-xl-pull-13{position:relative;right:54.16667%}.custom-theme .el-col-xl-push-13{position:relative;left:54.16667%}.custom-theme .el-col-xl-14{width:58.33333%}.custom-theme .el-col-xl-offset-14{margin-left:58.33333%}.custom-theme .el-col-xl-pull-14{position:relative;right:58.33333%}.custom-theme .el-col-xl-push-14{position:relative;left:58.33333%}.custom-theme .el-col-xl-15{width:62.5%}.custom-theme .el-col-xl-offset-15{margin-left:62.5%}.custom-theme .el-col-xl-pull-15{position:relative;right:62.5%}.custom-theme .el-col-xl-push-15{position:relative;left:62.5%}.custom-theme .el-col-xl-16{width:66.66667%}.custom-theme .el-col-xl-offset-16{margin-left:66.66667%}.custom-theme .el-col-xl-pull-16{position:relative;right:66.66667%}.custom-theme .el-col-xl-push-16{position:relative;left:66.66667%}.custom-theme .el-col-xl-17{width:70.83333%}.custom-theme .el-col-xl-offset-17{margin-left:70.83333%}.custom-theme .el-col-xl-pull-17{position:relative;right:70.83333%}.custom-theme .el-col-xl-push-17{position:relative;left:70.83333%}.custom-theme .el-col-xl-18{width:75%}.custom-theme .el-col-xl-offset-18{margin-left:75%}.custom-theme .el-col-xl-pull-18{position:relative;right:75%}.custom-theme .el-col-xl-push-18{position:relative;left:75%}.custom-theme .el-col-xl-19{width:79.16667%}.custom-theme .el-col-xl-offset-19{margin-left:79.16667%}.custom-theme .el-col-xl-pull-19{position:relative;right:79.16667%}.custom-theme .el-col-xl-push-19{position:relative;left:79.16667%}.custom-theme .el-col-xl-20{width:83.33333%}.custom-theme .el-col-xl-offset-20{margin-left:83.33333%}.custom-theme .el-col-xl-pull-20{position:relative;right:83.33333%}.custom-theme .el-col-xl-push-20{position:relative;left:83.33333%}.custom-theme .el-col-xl-21{width:87.5%}.custom-theme .el-col-xl-offset-21{margin-left:87.5%}.custom-theme .el-col-xl-pull-21{position:relative;right:87.5%}.custom-theme .el-col-xl-push-21{position:relative;left:87.5%}.custom-theme .el-col-xl-22{width:91.66667%}.custom-theme .el-col-xl-offset-22{margin-left:91.66667%}.custom-theme .el-col-xl-pull-22{position:relative;right:91.66667%}.custom-theme .el-col-xl-push-22{position:relative;left:91.66667%}.custom-theme .el-col-xl-23{width:95.83333%}.custom-theme .el-col-xl-offset-23{margin-left:95.83333%}.custom-theme .el-col-xl-pull-23{position:relative;right:95.83333%}.custom-theme .el-col-xl-push-23{position:relative;left:95.83333%}.custom-theme .el-col-xl-24{width:100%}.custom-theme .el-col-xl-offset-24{margin-left:100%}.custom-theme .el-col-xl-pull-24{position:relative;right:100%}.custom-theme .el-col-xl-push-24{position:relative;left:100%}}.custom-theme .el-progress{position:relative;line-height:1}.custom-theme .el-progress__text{font-size:14px;color:#5a5e66;display:inline-block;vertical-align:middle;margin-left:10px;line-height:1}.custom-theme .el-progress__text i{vertical-align:middle;display:block}.custom-theme .el-progress--circle{display:inline-block}.custom-theme .el-progress--circle .el-progress__text{position:absolute;top:50%;left:0;width:100%;text-align:center;margin:0;-webkit-transform:translate(0,-50%);transform:translate(0,-50%)}.custom-theme .el-progress--circle .el-progress__text i{vertical-align:middle;display:inline-block}.custom-theme .el-progress--without-text .el-progress__text{display:none}.custom-theme .el-progress--without-text .el-progress-bar{padding-right:0;margin-right:0;display:block}.custom-theme .el-progress--text-inside .el-progress-bar{padding-right:0;margin-right:0}.custom-theme .el-progress.is-success .el-progress-bar__inner{background-color:#409167}.custom-theme .el-progress.is-success .el-progress__text{color:#409167}.custom-theme .el-progress.is-exception .el-progress-bar__inner{background-color:#b3450e}.custom-theme .el-progress.is-exception .el-progress__text{color:#b3450e}.custom-theme .el-progress-bar{padding-right:50px;display:inline-block;vertical-align:middle;width:100%;margin-right:-55px;-webkit-box-sizing:border-box;box-sizing:border-box}.custom-theme .el-progress-bar__outer{height:6px;border-radius:100px;background-color:#e6ebf5;overflow:hidden;position:relative;vertical-align:middle}.custom-theme .el-progress-bar__inner{position:absolute;left:0;top:0;height:100%;background-color:#262729;text-align:right;border-radius:100px;line-height:1;white-space:nowrap}.custom-theme .el-progress-bar__inner::after{display:inline-block;content:"";height:100%;vertical-align:middle}.custom-theme .el-progress-bar__innerText{display:inline-block;vertical-align:middle;color:#fff;font-size:12px;margin:0 5px}@-webkit-keyframes progress{0%{background-position:0 0}100%{background-position:32px 0}}@keyframes progress{0%{background-position:0 0}100%{background-position:32px 0}}.custom-theme .el-upload{display:inline-block;text-align:center;cursor:pointer}.custom-theme .el-upload__input{display:none}.custom-theme .el-upload__tip{font-size:12px;color:#5a5e66;margin-top:7px}.custom-theme .el-upload iframe{position:absolute;z-index:-1;top:0;left:0;opacity:0}.custom-theme .el-upload--picture-card{background-color:#fbfdff;border:1px dashed #c0ccda;border-radius:6px;-webkit-box-sizing:border-box;box-sizing:border-box;width:148px;height:148px;cursor:pointer;line-height:146px;vertical-align:top}.custom-theme .el-upload--picture-card i{font-size:28px;color:#8c939d}.custom-theme .el-upload--picture-card:hover{border-color:#262729;color:#262729}.custom-theme .el-upload-dragger{background-color:#fff;border:1px dashed #d9d9d9;border-radius:6px;-webkit-box-sizing:border-box;box-sizing:border-box;width:360px;height:180px;text-align:center;cursor:pointer;position:relative;overflow:hidden}.custom-theme .el-upload-dragger .el-icon-upload{font-size:67px;color:#b4bccc;margin:40px 0 16px;line-height:50px}.custom-theme .el-upload-dragger+.el-upload__tip{text-align:center}.custom-theme .el-upload-dragger~.el-upload__files{border-top:1px solid #d8dce5;margin-top:7px;padding-top:5px}.custom-theme .el-upload-dragger .el-upload__text{color:#5a5e66;font-size:14px;text-align:center}.custom-theme .el-upload-dragger .el-upload__text em{color:#262729;font-style:normal}.custom-theme .el-upload-dragger:hover{border-color:#262729}.custom-theme .el-upload-dragger.is-dragover{background-color:rgba(32,159,255,.06);border:2px dashed #262729}.custom-theme .el-upload-list{margin:0;padding:0;list-style:none}.custom-theme .el-upload-list__item{-webkit-transition:all .5s cubic-bezier(.55,0,.1,1);transition:all .5s cubic-bezier(.55,0,.1,1);font-size:14px;color:#5a5e66;line-height:1.8;margin-top:5px;position:relative;-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:4px;width:100%}.custom-theme .el-upload-list__item .el-progress{position:absolute;top:20px;width:100%}.custom-theme .el-upload-list__item .el-progress__text{position:absolute;right:0;top:-13px}.custom-theme .el-upload-list__item .el-progress-bar{margin-right:0;padding-right:0}.custom-theme .el-upload-list__item:first-child{margin-top:10px}.custom-theme .el-upload-list__item .el-icon-upload-success{color:#409167}.custom-theme .el-upload-list__item .el-icon-close{display:none;position:absolute;top:5px;right:5px;cursor:pointer;opacity:.75;color:#5a5e66}.custom-theme .el-upload-list__item .el-icon-close:hover{opacity:1}.custom-theme .el-upload-list__item .el-icon-close-tip{display:none;position:absolute;top:5px;right:0;cursor:pointer;opacity:1;color:#262729;-webkit-transform:translate(15%,0);transform:translate(15%,0)}.custom-theme .el-upload-list__item:hover{background-color:#f5f7fa}.custom-theme .el-upload-list__item:hover .el-icon-close{display:inline-block}.custom-theme .el-upload-list__item:hover .el-progress__text{display:none}.custom-theme .el-upload-list__item.is-success .el-upload-list__item-status-label{display:block}.custom-theme .el-upload-list__item.is-success .el-upload-list__item-name:focus,.custom-theme .el-upload-list__item.is-success .el-upload-list__item-name:hover{color:#262729;cursor:pointer}.custom-theme .el-upload-list__item.is-success:focus .el-icon-close-tip{display:inline-block}.custom-theme .el-upload-list__item.is-success:active,.custom-theme .el-upload-list__item.is-success:focus:not(.focusing){outline-width:0}.custom-theme .el-upload-list__item.is-success:active .el-icon-close-tip,.custom-theme .el-upload-list__item.is-success:focus:not(.focusing) .el-icon-close-tip{display:none}.custom-theme .el-upload-list__item.is-success:focus .el-upload-list__item-status-label,.custom-theme .el-upload-list__item.is-success:hover .el-upload-list__item-status-label{display:none}.custom-theme .el-upload-list.is-disabled .el-upload-list__item:hover .el-upload-list__item-status-label{display:block}.custom-theme .el-upload-list__item-name{color:#5a5e66;display:block;margin-right:40px;overflow:hidden;padding-left:4px;text-overflow:ellipsis;-webkit-transition:color .3s;transition:color .3s;white-space:nowrap}.custom-theme .el-upload-list__item-name [class^=el-icon]{height:100%;margin-right:7px;color:#878d99;line-height:inherit}.custom-theme .el-upload-list__item-status-label{position:absolute;right:5px;top:0;line-height:inherit;display:none}.custom-theme .el-upload-list__item-delete{position:absolute;right:10px;top:0;font-size:12px;color:#5a5e66;display:none}.custom-theme .el-upload-list__item-delete:hover{color:#262729}.custom-theme .el-upload-list--picture-card{margin:0;display:inline;vertical-align:top}.custom-theme .el-upload-list--picture-card .el-upload-list__item{overflow:hidden;background-color:#fff;border:1px solid #c0ccda;border-radius:6px;-webkit-box-sizing:border-box;box-sizing:border-box;width:148px;height:148px;margin:0 8px 8px 0;display:inline-block}.custom-theme .el-upload-list--picture-card .el-upload-list__item .el-icon-check,.custom-theme .el-upload-list--picture-card .el-upload-list__item .el-icon-circle-check{color:#fff}.custom-theme .el-upload-list--picture-card .el-upload-list__item .el-icon-close{display:none}.custom-theme .el-upload-list--picture-card .el-upload-list__item:hover .el-upload-list__item-status-label{display:none}.custom-theme .el-upload-list--picture-card .el-upload-list__item:hover .el-progress__text{display:block}.custom-theme .el-upload-list--picture-card .el-upload-list__item-name{display:none}.custom-theme .el-upload-list--picture-card .el-upload-list__item-thumbnail{width:100%;height:100%}.custom-theme .el-upload-list--picture-card .el-upload-list__item-status-label{position:absolute;right:-15px;top:-6px;width:40px;height:24px;background:#13ce66;text-align:center;-webkit-transform:rotate(45deg);transform:rotate(45deg);-webkit-box-shadow:0 0 1pc 1px rgba(0,0,0,.2);box-shadow:0 0 1pc 1px rgba(0,0,0,.2)}.custom-theme .el-upload-list--picture-card .el-upload-list__item-status-label i{font-size:12px;margin-top:11px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.custom-theme .el-upload-list--picture-card .el-upload-list__item-actions{position:absolute;width:100%;height:100%;left:0;top:0;cursor:default;text-align:center;color:#fff;opacity:0;font-size:20px;background-color:rgba(0,0,0,.5);-webkit-transition:opacity .3s;transition:opacity .3s}.custom-theme .el-upload-list--picture-card .el-upload-list__item-actions::after{display:inline-block;content:"";height:100%;vertical-align:middle}.custom-theme .el-upload-list--picture-card .el-upload-list__item-actions span{display:none;cursor:pointer}.custom-theme .el-upload-list--picture-card .el-upload-list__item-actions span+span{margin-left:15px}.custom-theme .el-upload-list--picture-card .el-upload-list__item-actions .el-upload-list__item-delete{position:static;font-size:inherit;color:inherit}.custom-theme .el-upload-list--picture-card .el-upload-list__item-actions:hover{opacity:1}.custom-theme .el-upload-list--picture-card .el-upload-list__item-actions:hover span{display:inline-block}.custom-theme .el-upload-list--picture-card .el-progress{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);bottom:auto;width:126px}.custom-theme .el-upload-list--picture-card .el-progress .el-progress__text{top:50%}.custom-theme .el-upload-list--picture .el-upload-list__item{overflow:hidden;background-color:#fff;border:1px solid #c0ccda;border-radius:6px;-webkit-box-sizing:border-box;box-sizing:border-box;margin-top:10px;padding:10px 10px 10px 90px;height:92px}.custom-theme .el-upload-list--picture .el-upload-list__item .el-icon-check,.custom-theme .el-upload-list--picture .el-upload-list__item .el-icon-circle-check{color:#fff}.custom-theme .el-upload-list--picture .el-upload-list__item:hover .el-upload-list__item-status-label{background:0 0;-webkit-box-shadow:none;box-shadow:none;top:-2px;right:-12px}.custom-theme .el-upload-list--picture .el-upload-list__item:hover .el-progress__text{display:block}.custom-theme .el-upload-list--picture .el-upload-list__item.is-success .el-upload-list__item-name{line-height:70px;margin-top:0}.custom-theme .el-upload-list--picture .el-upload-list__item.is-success .el-upload-list__item-name i{display:none}.custom-theme .el-upload-list--picture .el-upload-list__item-thumbnail{vertical-align:middle;display:inline-block;width:70px;height:70px;float:left;position:relative;z-index:1;margin-left:-80px}.custom-theme .el-upload-list--picture .el-upload-list__item-name{display:block;margin-top:20px}.custom-theme .el-upload-list--picture .el-upload-list__item-name i{font-size:70px;line-height:1;position:absolute;left:9px;top:10px}.custom-theme .el-upload-list--picture .el-upload-list__item-status-label{position:absolute;right:-17px;top:-7px;width:46px;height:26px;background:#13ce66;text-align:center;-webkit-transform:rotate(45deg);transform:rotate(45deg);-webkit-box-shadow:0 1px 1px #ccc;box-shadow:0 1px 1px #ccc}.custom-theme .el-upload-list--picture .el-upload-list__item-status-label i{font-size:12px;margin-top:12px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.custom-theme .el-upload-list--picture .el-progress{position:relative;top:-7px}.custom-theme .el-upload-cover{position:absolute;left:0;top:0;width:100%;height:100%;overflow:hidden;z-index:10;cursor:default}.custom-theme .el-upload-cover::after{display:inline-block;content:"";height:100%;vertical-align:middle}.custom-theme .el-upload-cover img{display:block;width:100%;height:100%}.custom-theme .el-upload-cover__label{position:absolute;right:-15px;top:-6px;width:40px;height:24px;background:#13ce66;text-align:center;-webkit-transform:rotate(45deg);transform:rotate(45deg);-webkit-box-shadow:0 0 1pc 1px rgba(0,0,0,.2);box-shadow:0 0 1pc 1px rgba(0,0,0,.2)}.custom-theme .el-upload-cover__label i{font-size:12px;margin-top:11px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);color:#fff}.custom-theme .el-upload-cover__progress{display:inline-block;vertical-align:middle;position:static;width:243px}.custom-theme .el-upload-cover__progress+.el-upload__inner{opacity:0}.custom-theme .el-upload-cover__content{position:absolute;top:0;left:0;width:100%;height:100%}.custom-theme .el-upload-cover__interact{position:absolute;bottom:0;left:0;width:100%;height:100%;background-color:rgba(0,0,0,.72);text-align:center}.custom-theme .el-upload-cover__interact .btn{display:inline-block;color:#fff;font-size:14px;cursor:pointer;vertical-align:middle;-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;transition:opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;transition:transform .3s cubic-bezier(.23,1,.32,1) .1s,opacity .3s cubic-bezier(.23,1,.32,1) .1s;transition:transform .3s cubic-bezier(.23,1,.32,1) .1s,opacity .3s cubic-bezier(.23,1,.32,1) .1s,-webkit-transform .3s cubic-bezier(.23,1,.32,1) .1s;margin-top:60px}.custom-theme .el-upload-cover__interact .btn i{margin-top:0}.custom-theme .el-upload-cover__interact .btn span{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.custom-theme .el-upload-cover__interact .btn:not(:first-child){margin-left:35px}.custom-theme .el-upload-cover__interact .btn:hover{-webkit-transform:translateY(-13px);transform:translateY(-13px)}.custom-theme .el-upload-cover__interact .btn:hover span{opacity:1}.custom-theme .el-upload-cover__interact .btn i{color:#fff;display:block;font-size:24px;line-height:inherit;margin:0 auto 5px}.custom-theme .el-upload-cover__title{position:absolute;bottom:0;left:0;background-color:#fff;height:36px;width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:400;text-align:left;padding:0 10px;margin:0;line-height:36px;font-size:14px;color:#2d2f33}.custom-theme .el-upload-cover+.el-upload__inner{opacity:0;position:relative;z-index:1}.custom-theme .el-progress{position:relative;line-height:1}.custom-theme .el-progress__text{font-size:14px;color:#5a5e66;display:inline-block;vertical-align:middle;margin-left:10px;line-height:1}.custom-theme .el-progress__text i{vertical-align:middle;display:block}.custom-theme .el-progress--circle{display:inline-block}.custom-theme .el-progress--circle .el-progress__text{position:absolute;top:50%;left:0;width:100%;text-align:center;margin:0;-webkit-transform:translate(0,-50%);transform:translate(0,-50%)}.custom-theme .el-progress--circle .el-progress__text i{vertical-align:middle;display:inline-block}.custom-theme .el-progress--without-text .el-progress__text{display:none}.custom-theme .el-progress--without-text .el-progress-bar{padding-right:0;margin-right:0;display:block}.custom-theme .el-progress--text-inside .el-progress-bar{padding-right:0;margin-right:0}.custom-theme .el-progress.is-success .el-progress-bar__inner{background-color:#409167}.custom-theme .el-progress.is-success .el-progress__text{color:#409167}.custom-theme .el-progress.is-exception .el-progress-bar__inner{background-color:#b3450e}.custom-theme .el-progress.is-exception .el-progress__text{color:#b3450e}.custom-theme .el-progress-bar{padding-right:50px;display:inline-block;vertical-align:middle;width:100%;margin-right:-55px;-webkit-box-sizing:border-box;box-sizing:border-box}.custom-theme .el-progress-bar__outer{height:6px;border-radius:100px;background-color:#e6ebf5;overflow:hidden;position:relative;vertical-align:middle}.custom-theme .el-progress-bar__inner{position:absolute;left:0;top:0;height:100%;background-color:#262729;text-align:right;border-radius:100px;line-height:1;white-space:nowrap}.custom-theme .el-progress-bar__inner::after{display:inline-block;content:"";height:100%;vertical-align:middle}.custom-theme .el-progress-bar__innerText{display:inline-block;vertical-align:middle;color:#fff;font-size:12px;margin:0 5px}@keyframes progress{0%{background-position:0 0}100%{background-position:32px 0}}.custom-theme .el-time-spinner{width:100%;white-space:nowrap}.custom-theme .el-spinner{display:inline-block;vertical-align:middle}.custom-theme .el-spinner-inner{-webkit-animation:rotate 2s linear infinite;animation:rotate 2s linear infinite;width:50px;height:50px}.custom-theme .el-spinner-inner .path{stroke:#ececec;stroke-linecap:round;-webkit-animation:dash 1.5s ease-in-out infinite;animation:dash 1.5s ease-in-out infinite}@-webkit-keyframes rotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes rotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes dash{0%{stroke-dasharray:1,150;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-35}100%{stroke-dasharray:90,150;stroke-dashoffset:-124}}@keyframes dash{0%{stroke-dasharray:1,150;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-35}100%{stroke-dasharray:90,150;stroke-dashoffset:-124}}.custom-theme .el-message{min-width:380px;-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:4px;border-width:1px;border-style:solid;border-color:#e6ebf5;position:fixed;left:50%;top:20px;-webkit-transform:translateX(-50%);transform:translateX(-50%);background-color:#edf2fc;-webkit-transition:opacity .3s,-webkit-transform .4s;transition:opacity .3s,-webkit-transform .4s;transition:opacity .3s,transform .4s;transition:opacity .3s,transform .4s,-webkit-transform .4s;overflow:hidden;padding:15px 15px 15px 20px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.custom-theme .el-message.is-center{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.custom-theme .el-message p{margin:0}.custom-theme .el-message--info .el-message__content{color:#0a76a4}.custom-theme .el-message--success{background-color:#ecf4f0;border-color:#d9e9e1}.custom-theme .el-message--success .el-message__content{color:#409167}.custom-theme .el-message--warning{background-color:#f5f6e6;border-color:#ebedce}.custom-theme .el-message--warning .el-message__content{color:#9da408}.custom-theme .el-message--error{background-color:#f7ece7;border-color:#f0dacf}.custom-theme .el-message--error .el-message__content{color:#b3450e}.custom-theme .el-message__icon{margin-right:10px}.custom-theme .el-message__content{padding:0;font-size:14px;line-height:1}.custom-theme .el-message__content:focus{outline-width:0}.custom-theme .el-message__closeBtn{position:absolute;top:50%;right:15px;-webkit-transform:translateY(-50%);transform:translateY(-50%);cursor:pointer;color:#b4bccc;font-size:16px}.custom-theme .el-message__closeBtn:focus{outline-width:0}.custom-theme .el-message__closeBtn:hover{color:#878d99}.custom-theme .el-message .el-icon-success{color:#409167}.custom-theme .el-message .el-icon-error{color:#b3450e}.custom-theme .el-message .el-icon-info{color:#0a76a4}.custom-theme .el-message .el-icon-warning{color:#9da408}.custom-theme .el-message-fade-enter,.custom-theme .el-message-fade-leave-active{opacity:0;-webkit-transform:translate(-50%,-100%);transform:translate(-50%,-100%)}.custom-theme .el-badge{position:relative;vertical-align:middle;display:inline-block}.custom-theme .el-badge__content{background-color:#b3450e;border-radius:10px;color:#fff;display:inline-block;font-size:12px;height:18px;line-height:18px;padding:0 6px;text-align:center;white-space:nowrap;border:1px solid #fff}.custom-theme .el-badge__content.is-fixed{position:absolute;top:0;right:10px;-webkit-transform:translateY(-50%) translateX(100%);transform:translateY(-50%) translateX(100%)}.custom-theme .el-badge__content.is-fixed.is-dot{right:5px}.custom-theme .el-badge__content.is-dot{height:8px;width:8px;padding:0;right:0;border-radius:50%}.custom-theme .el-card{border-radius:4px;border:1px solid #e6ebf5;background-color:#fff;overflow:hidden;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);color:#2d2f33}.custom-theme .el-card__header{padding:18px 20px;border-bottom:1px solid #e6ebf5;-webkit-box-sizing:border-box;box-sizing:border-box}.custom-theme .el-card__body{padding:20px}.custom-theme .el-rate{height:20px;line-height:1}.custom-theme .el-rate:active,.custom-theme .el-rate:focus{outline-width:0}.custom-theme .el-rate__item{display:inline-block;position:relative;font-size:0;vertical-align:middle}.custom-theme .el-rate__icon{position:relative;display:inline-block;font-size:18px;margin-right:6px;color:#b4bccc;-webkit-transition:.3s;transition:.3s}.custom-theme .el-rate__icon.hover{-webkit-transform:scale(1.15);transform:scale(1.15)}.custom-theme .el-rate__icon .path2{position:absolute;left:0;top:0}.custom-theme .el-rate__decimal{position:absolute;top:0;left:0;display:inline-block;overflow:hidden}.custom-theme .el-rate__text{font-size:14px;vertical-align:middle}.custom-theme .el-steps{display:-webkit-box;display:-ms-flexbox;display:flex}.custom-theme .el-steps--simple{padding:13px 8%;border-radius:4px;background:#f5f7fa}.custom-theme .el-steps--horizontal{white-space:nowrap}.custom-theme .el-steps--vertical{height:100%;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-flow:column;flex-flow:column}.custom-theme .el-step{position:relative;-ms-flex-negative:1;flex-shrink:1}.custom-theme .el-step:last-of-type .el-step__line{display:none}.custom-theme .el-step:last-of-type.is-flex{-ms-flex-preferred-size:auto!important;flex-basis:auto!important;-ms-flex-negative:0;flex-shrink:0;-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0}.custom-theme .el-step:last-of-type .el-step__description,.custom-theme .el-step:last-of-type .el-step__main{padding-right:0}.custom-theme .el-step__head{position:relative;width:100%}.custom-theme .el-step__head.is-process{color:#2d2f33;border-color:#2d2f33}.custom-theme .el-step__head.is-wait{color:#b4bccc;border-color:#b4bccc}.custom-theme .el-step__head.is-success{color:#409167;border-color:#409167}.custom-theme .el-step__head.is-error{color:#b3450e;border-color:#b3450e}.custom-theme .el-step__head.is-finish{color:#262729;border-color:#262729}.custom-theme .el-step__icon{position:relative;z-index:1;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:24px;height:24px;font-size:14px;-webkit-box-sizing:border-box;box-sizing:border-box;background:#fff;-webkit-transition:.15s ease-out;transition:.15s ease-out}.custom-theme .el-step__icon.is-text{border-radius:50%;border:2px solid;border-color:inherit}.custom-theme .el-step__icon.is-icon{width:40px}.custom-theme .el-step__icon-inner{display:inline-block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-align:center;font-weight:700;line-height:1;color:inherit}.custom-theme .el-step__icon-inner[class*=el-icon]:not(.is-status){font-size:25px;font-weight:400}.custom-theme .el-step__icon-inner.is-status{-webkit-transform:translateY(1px);transform:translateY(1px)}.custom-theme .el-step__line{position:absolute;border-color:inherit;background-color:#b4bccc}.custom-theme .el-step__line-inner{display:block;border-width:1px;border-style:solid;border-color:inherit;-webkit-transition:.15s ease-out;transition:.15s ease-out;-webkit-box-sizing:border-box;box-sizing:border-box;width:0;height:0}.custom-theme .el-step__main{white-space:normal;text-align:left}.custom-theme .el-step__title{font-size:16px;line-height:38px}.custom-theme .el-step__title.is-process{font-weight:700;color:#2d2f33}.custom-theme .el-step__title.is-wait{color:#b4bccc}.custom-theme .el-step__title.is-success{color:#409167}.custom-theme .el-step__title.is-error{color:#b3450e}.custom-theme .el-step__title.is-finish{color:#262729}.custom-theme .el-step__description{padding-right:10%;margin-top:-5px;font-size:12px;line-height:20px;font-weight:400}.custom-theme .el-step__description.is-process{color:#2d2f33}.custom-theme .el-step__description.is-wait{color:#b4bccc}.custom-theme .el-step__description.is-success{color:#409167}.custom-theme .el-step__description.is-error{color:#b3450e}.custom-theme .el-step__description.is-finish{color:#262729}.custom-theme .el-step.is-horizontal{display:inline-block}.custom-theme .el-step.is-horizontal .el-step__line{height:2px;top:11px;left:0;right:0}.custom-theme .el-step.is-vertical{display:-webkit-box;display:-ms-flexbox;display:flex}.custom-theme .el-step.is-vertical .el-step__head{-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0;width:24px}.custom-theme .el-step.is-vertical .el-step__main{padding-left:10px;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.custom-theme .el-step.is-vertical .el-step__title{line-height:24px;padding-bottom:8px}.custom-theme .el-step.is-vertical .el-step__line{width:2px;top:0;bottom:0;left:11px}.custom-theme .el-step.is-vertical .el-step__icon.is-icon{width:24px}.custom-theme .el-step.is-center .el-step__head{text-align:center}.custom-theme .el-step.is-center .el-step__main{text-align:center}.custom-theme .el-step.is-center .el-step__description{padding-left:20%;padding-right:20%}.custom-theme .el-step.is-center .el-step__line{left:50%;right:-50%}.custom-theme .el-step.is-simple{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.custom-theme .el-step.is-simple .el-step__head{width:auto;font-size:0;padding-right:10px}.custom-theme .el-step.is-simple .el-step__icon{background:0 0;width:16px;height:16px;font-size:12px}.custom-theme .el-step.is-simple .el-step__icon-inner[class*=el-icon]:not(.is-status){font-size:18px}.custom-theme .el-step.is-simple .el-step__icon-inner.is-status{-webkit-transform:scale(.8) translateY(1px);transform:scale(.8) translateY(1px)}.custom-theme .el-step.is-simple .el-step__main{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.custom-theme .el-step.is-simple .el-step__title{font-size:16px;line-height:20px}.custom-theme .el-step.is-simple:not(:last-of-type) .el-step__title{max-width:50%;word-break:break-all}.custom-theme .el-step.is-simple .el-step__arrow{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.custom-theme .el-step.is-simple .el-step__arrow::after,.custom-theme .el-step.is-simple .el-step__arrow::before{content:'';display:inline-block;position:absolute;height:15px;width:1px;background:#b4bccc}.custom-theme .el-step.is-simple .el-step__arrow::before{-webkit-transform:rotate(-45deg) translateY(-4px);transform:rotate(-45deg) translateY(-4px);-webkit-transform-origin:0 0;transform-origin:0 0}.custom-theme .el-step.is-simple .el-step__arrow::after{-webkit-transform:rotate(45deg) translateY(4px);transform:rotate(45deg) translateY(4px);-webkit-transform-origin:100% 100%;transform-origin:100% 100%}.custom-theme .el-step.is-simple:last-of-type .el-step__arrow{display:none}.custom-theme .el-carousel{overflow-x:hidden;position:relative}.custom-theme .el-carousel__container{position:relative;height:300px}.custom-theme .el-carousel__arrow{border:none;outline:0;padding:0;margin:0;height:36px;width:36px;cursor:pointer;-webkit-transition:.3s;transition:.3s;border-radius:50%;background-color:rgba(31,45,61,.11);color:#fff;position:absolute;top:50%;z-index:10;-webkit-transform:translateY(-50%);transform:translateY(-50%);text-align:center;font-size:12px}.custom-theme .el-carousel__arrow--left{left:16px}.custom-theme .el-carousel__arrow--right{right:16px}.custom-theme .el-carousel__arrow:hover{background-color:rgba(31,45,61,.23)}.custom-theme .el-carousel__arrow i{cursor:pointer}.custom-theme .el-carousel__indicators{position:absolute;list-style:none;bottom:0;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%);margin:0;padding:0;z-index:2}.custom-theme .el-carousel__indicators--outside{bottom:26px;text-align:center;position:static;-webkit-transform:none;transform:none}.custom-theme .el-carousel__indicators--outside .el-carousel__indicator:hover button{opacity:.64}.custom-theme .el-carousel__indicators--outside button{background-color:#b4bccc;opacity:.24}.custom-theme .el-carousel__indicators--labels{left:0;right:0;-webkit-transform:none;transform:none;text-align:center}.custom-theme .el-carousel__indicators--labels .el-carousel__button{height:auto;width:auto;padding:2px 18px;font-size:12px}.custom-theme .el-carousel__indicators--labels .el-carousel__indicator{padding:6px 4px}.custom-theme .el-carousel__indicator{display:inline-block;background-color:transparent;padding:12px 4px;cursor:pointer}.custom-theme .el-carousel__indicator:hover button{opacity:.72}.custom-theme .el-carousel__indicator.is-active button{opacity:1}.custom-theme .el-carousel__button{display:block;opacity:.48;width:30px;height:2px;background-color:#fff;border:none;outline:0;padding:0;margin:0;cursor:pointer;-webkit-transition:.3s;transition:.3s}.custom-theme .carousel-arrow-left-enter,.custom-theme .carousel-arrow-left-leave-active{-webkit-transform:translateY(-50%) translateX(-10px);transform:translateY(-50%) translateX(-10px);opacity:0}.custom-theme .carousel-arrow-right-enter,.custom-theme .carousel-arrow-right-leave-active{-webkit-transform:translateY(-50%) translateX(10px);transform:translateY(-50%) translateX(10px);opacity:0}.custom-theme .el-scrollbar{overflow:hidden;position:relative}.custom-theme .el-scrollbar:active>.el-scrollbar__bar,.custom-theme .el-scrollbar:focus>.el-scrollbar__bar,.custom-theme .el-scrollbar:hover>.el-scrollbar__bar{opacity:1;-webkit-transition:opacity 340ms ease-out;transition:opacity 340ms ease-out}.custom-theme .el-scrollbar__wrap{overflow:scroll;height:100%}.custom-theme .el-scrollbar__wrap--hidden-default::-webkit-scrollbar{width:0;height:0}.custom-theme .el-scrollbar__thumb{position:relative;display:block;width:0;height:0;cursor:pointer;border-radius:inherit;background-color:rgba(135,141,153,.3);-webkit-transition:.3s background-color;transition:.3s background-color}.custom-theme .el-scrollbar__thumb:hover{background-color:rgba(135,141,153,.5)}.custom-theme .el-scrollbar__bar{position:absolute;right:2px;bottom:2px;z-index:1;border-radius:4px;opacity:0;-webkit-transition:opacity 120ms ease-out;transition:opacity 120ms ease-out}.custom-theme .el-scrollbar__bar.is-vertical{width:6px;top:2px}.custom-theme .el-scrollbar__bar.is-vertical>div{width:100%}.custom-theme .el-scrollbar__bar.is-horizontal{height:6px;left:2px}.custom-theme .el-scrollbar__bar.is-horizontal>div{height:100%}.custom-theme .el-carousel__item{position:absolute;top:0;left:0;width:100%;height:100%;display:inline-block;overflow:hidden;z-index:0}.custom-theme .el-carousel__item.is-active{z-index:2}.custom-theme .el-carousel__item.is-animating{-webkit-transition:-webkit-transform .4s ease-in-out;transition:-webkit-transform .4s ease-in-out;transition:transform .4s ease-in-out;transition:transform .4s ease-in-out,-webkit-transform .4s ease-in-out}.custom-theme .el-carousel__item--card{width:50%;-webkit-transition:-webkit-transform .4s ease-in-out;transition:-webkit-transform .4s ease-in-out;transition:transform .4s ease-in-out;transition:transform .4s ease-in-out,-webkit-transform .4s ease-in-out}.custom-theme .el-carousel__item--card.is-in-stage{cursor:pointer;z-index:1}.custom-theme .el-carousel__item--card.is-in-stage.is-hover .el-carousel__mask,.custom-theme .el-carousel__item--card.is-in-stage:hover .el-carousel__mask{opacity:.12}.custom-theme .el-carousel__item--card.is-active{z-index:2}.custom-theme .el-carousel__mask{position:absolute;width:100%;height:100%;top:0;left:0;background-color:#fff;opacity:.24;-webkit-transition:.2s;transition:.2s}.custom-theme .el-collapse{border-top:1px solid #e6ebf5;border-bottom:1px solid #e6ebf5}.custom-theme .el-collapse-item__header{height:48px;line-height:48px;background-color:#fff;color:#2d2f33;cursor:pointer;border-bottom:1px solid #e6ebf5;font-size:13px;font-weight:500;-webkit-transition:border-bottom-color .3s;transition:border-bottom-color .3s}.custom-theme .el-collapse-item__header:active,.custom-theme .el-collapse-item__header:focus:not(.focusing){outline-width:0}.custom-theme .el-collapse-item__arrow{margin-right:8px;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;float:right;line-height:48px;font-weight:300}.custom-theme .el-collapse-item__wrap{will-change:height;background-color:#fff;overflow:hidden;-webkit-box-sizing:border-box;box-sizing:border-box;border-bottom:1px solid #e6ebf5}.custom-theme .el-collapse-item__content{padding-bottom:25px;font-size:13px;color:#2d2f33;line-height:1.769230769230769}.custom-theme .el-collapse-item.is-active .el-collapse-item__header{border-bottom-color:transparent}.custom-theme .el-collapse-item.is-active .el-collapse-item__header .el-collapse-item__arrow{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.custom-theme .el-collapse-item:last-child{margin-bottom:-1px}.custom-theme .el-input{position:relative;font-size:14px;display:inline-block;width:100%}.custom-theme .el-input::-webkit-scrollbar{z-index:11;width:6px}.custom-theme .el-input::-webkit-scrollbar:horizontal{height:6px}.custom-theme .el-input::-webkit-scrollbar-thumb{border-radius:5px;width:6px;background:#b4bccc}.custom-theme .el-input::-webkit-scrollbar-corner{background:#fff}.custom-theme .el-input::-webkit-scrollbar-track{background:#fff}.custom-theme .el-input::-webkit-scrollbar-track-piece{background:#fff;width:6px}.custom-theme .el-input__inner{-webkit-appearance:none;background-color:#fff;background-image:none;border-radius:4px;border:1px solid #d8dce5;-webkit-box-sizing:border-box;box-sizing:border-box;color:#5a5e66;display:inline-block;font-size:inherit;height:40px;line-height:1;outline:0;padding:0 15px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1);width:100%}.custom-theme .el-input__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner::placeholder{color:#b4bccc}.custom-theme .el-input__inner:hover{border-color:#b4bccc}.custom-theme .el-input__inner:focus{outline:0;border-color:#262729}.custom-theme .el-input__suffix{position:absolute;height:100%;right:5px;top:0;text-align:center;color:#b4bccc;-webkit-transition:all .3s;transition:all .3s;pointer-events:none}.custom-theme .el-input__suffix-inner{pointer-events:all}.custom-theme .el-input__prefix{position:absolute;height:100%;left:5px;top:0;text-align:center;color:#b4bccc;-webkit-transition:all .3s;transition:all .3s}.custom-theme .el-input__icon{height:100%;width:25px;text-align:center;-webkit-transition:all .3s;transition:all .3s;line-height:40px}.custom-theme .el-input__icon:after{content:'';height:100%;width:0;display:inline-block;vertical-align:middle}.custom-theme .el-input__validateIcon{pointer-events:none}.custom-theme .el-input.is-active .el-input__inner{outline:0;border-color:#262729}.custom-theme .el-input.is-disabled .el-input__inner{background-color:#f5f7fa;border-color:#dfe4ed;color:#b4bccc;cursor:not-allowed}.custom-theme .el-input.is-disabled .el-input__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner::placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__icon{cursor:not-allowed}.custom-theme .el-input--suffix .el-input__inner{padding-right:30px}.custom-theme .el-input--prefix .el-input__inner{padding-left:30px}.custom-theme .el-input--medium{font-size:14px}.custom-theme .el-input--medium .el-input__inner{height:36px}.custom-theme .el-input--medium .el-input__icon{line-height:36px}.custom-theme .el-input--small{font-size:13px}.custom-theme .el-input--small .el-input__inner{height:32px}.custom-theme .el-input--small .el-input__icon{line-height:32px}.custom-theme .el-input--mini{font-size:12px}.custom-theme .el-input--mini .el-input__inner{height:28px}.custom-theme .el-input--mini .el-input__icon{line-height:28px}.custom-theme .el-input-group{line-height:normal;display:inline-table;width:100%;border-collapse:separate}.custom-theme .el-input-group>.el-input__inner{vertical-align:middle;display:table-cell}.custom-theme .el-input-group__append,.custom-theme .el-input-group__prepend{background-color:#f5f7fa;color:#0a76a4;vertical-align:middle;display:table-cell;position:relative;border:1px solid #d8dce5;border-radius:4px;padding:0 20px;width:1px;white-space:nowrap}.custom-theme .el-input-group__append:focus,.custom-theme .el-input-group__prepend:focus{outline:0}.custom-theme .el-input-group__append .el-button,.custom-theme .el-input-group__append .el-select,.custom-theme .el-input-group__prepend .el-button,.custom-theme .el-input-group__prepend .el-select{display:inline-block;margin:-20px}.custom-theme .el-input-group__append button.el-button,.custom-theme .el-input-group__append div.el-select .el-input__inner,.custom-theme .el-input-group__append div.el-select:hover .el-input__inner,.custom-theme .el-input-group__prepend button.el-button,.custom-theme .el-input-group__prepend div.el-select .el-input__inner,.custom-theme .el-input-group__prepend div.el-select:hover .el-input__inner{border-color:transparent;background-color:transparent;color:inherit;border-top:0;border-bottom:0}.custom-theme .el-input-group__append .el-button,.custom-theme .el-input-group__append .el-input,.custom-theme .el-input-group__prepend .el-button,.custom-theme .el-input-group__prepend .el-input{font-size:inherit}.custom-theme .el-input-group__prepend{border-right:0;border-top-right-radius:0;border-bottom-right-radius:0}.custom-theme .el-input-group__append{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.custom-theme .el-input-group--prepend .el-input__inner{border-top-left-radius:0;border-bottom-left-radius:0}.custom-theme .el-input-group--append .el-input__inner{border-top-right-radius:0;border-bottom-right-radius:0}.custom-theme .el-textarea{display:inline-block;width:100%;vertical-align:bottom}.custom-theme .el-textarea__inner{display:block;resize:vertical;padding:5px 15px;line-height:1.5;-webkit-box-sizing:border-box;box-sizing:border-box;width:100%;font-size:14px;color:#5a5e66;background-color:#fff;background-image:none;border:1px solid #d8dce5;border-radius:4px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1)}.custom-theme .el-textarea__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner::placeholder{color:#b4bccc}.custom-theme .el-textarea__inner:hover{border-color:#b4bccc}.custom-theme .el-textarea__inner:focus{outline:0;border-color:#262729}.custom-theme .el-textarea.is-disabled .el-textarea__inner{background-color:#f5f7fa;border-color:#dfe4ed;color:#b4bccc;cursor:not-allowed}.custom-theme .el-textarea.is-disabled .el-textarea__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner::placeholder{color:#b4bccc}.custom-theme .el-popper .popper__arrow,.custom-theme .el-popper .popper__arrow::after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.custom-theme .el-popper .popper__arrow{border-width:6px;-webkit-filter:drop-shadow(0 2px 12px rgba(0, 0, 0, .03));filter:drop-shadow(0 2px 12px rgba(0, 0, 0, .03))}.custom-theme .el-popper .popper__arrow::after{content:" ";border-width:6px}.custom-theme .el-popper[x-placement^=top]{margin-bottom:12px}.custom-theme .el-popper[x-placement^=top] .popper__arrow{bottom:-6px;left:50%;margin-right:3px;border-top-color:#e6ebf5;border-bottom-width:0}.custom-theme .el-popper[x-placement^=top] .popper__arrow::after{bottom:1px;margin-left:-6px;border-top-color:#fff;border-bottom-width:0}.custom-theme .el-popper[x-placement^=bottom]{margin-top:12px}.custom-theme .el-popper[x-placement^=bottom] .popper__arrow{top:-6px;left:50%;margin-right:3px;border-top-width:0;border-bottom-color:#e6ebf5}.custom-theme .el-popper[x-placement^=bottom] .popper__arrow::after{top:1px;margin-left:-6px;border-top-width:0;border-bottom-color:#fff}.custom-theme .el-popper[x-placement^=right]{margin-left:12px}.custom-theme .el-popper[x-placement^=right] .popper__arrow{top:50%;left:-6px;margin-bottom:3px;border-right-color:#e6ebf5;border-left-width:0}.custom-theme .el-popper[x-placement^=right] .popper__arrow::after{bottom:-6px;left:1px;border-right-color:#fff;border-left-width:0}.custom-theme .el-popper[x-placement^=left]{margin-right:12px}.custom-theme .el-popper[x-placement^=left] .popper__arrow{top:50%;right:-6px;margin-bottom:3px;border-right-width:0;border-left-color:#e6ebf5}.custom-theme .el-popper[x-placement^=left] .popper__arrow::after{right:1px;bottom:-6px;margin-left:-6px;border-right-width:0;border-left-color:#fff}.custom-theme .el-cascader{display:inline-block;position:relative;font-size:14px;line-height:40px}.custom-theme .el-cascader .el-input,.custom-theme .el-cascader .el-input__inner{cursor:pointer}.custom-theme .el-cascader .el-input__icon{-webkit-transition:none;transition:none}.custom-theme .el-cascader .el-icon-arrow-down{-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;font-size:14px}.custom-theme .el-cascader .el-icon-arrow-down.is-reverse{-webkit-transform:rotateZ(180deg);transform:rotateZ(180deg)}.custom-theme .el-cascader .el-icon-circle-close{z-index:2;-webkit-transition:color .2s cubic-bezier(.645,.045,.355,1);transition:color .2s cubic-bezier(.645,.045,.355,1)}.custom-theme .el-cascader .el-icon-circle-close:hover{color:#878d99}.custom-theme .el-cascader__clearIcon{z-index:2;position:relative}.custom-theme .el-cascader__label{position:absolute;left:0;top:0;height:100%;padding:0 25px 0 15px;color:#5a5e66;width:100%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;-webkit-box-sizing:border-box;box-sizing:border-box;cursor:pointer;text-align:left;font-size:inherit}.custom-theme .el-cascader__label span{color:#000}.custom-theme .el-cascader--medium{font-size:14px;line-height:36px}.custom-theme .el-cascader--small{font-size:13px;line-height:32px}.custom-theme .el-cascader--mini{font-size:12px;line-height:28px}.custom-theme .el-cascader.is-disabled .el-cascader__label{z-index:2;color:#b4bccc}.custom-theme .el-cascader-menus{white-space:nowrap;background:#fff;position:absolute;margin:5px 0;z-index:2;border:solid 1px #dfe4ed;border-radius:2px;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.custom-theme .el-cascader-menus .popper__arrow{-webkit-transform:translateX(-400%);transform:translateX(-400%)}.custom-theme .el-cascader-menu{display:inline-block;vertical-align:top;height:204px;overflow:auto;border-right:solid 1px #dfe4ed;background-color:#fff;-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;padding:6px 0;min-width:160px}.custom-theme .el-cascader-menu:last-child{border-right:0}.custom-theme .el-cascader-menu__item{font-size:14px;padding:8px 20px;position:relative;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#5a5e66;height:34px;line-height:1.5;-webkit-box-sizing:border-box;box-sizing:border-box;cursor:pointer}.custom-theme .el-cascader-menu__item--extensible:after{font-family:element-icons;content:"\e604";font-size:14px;color:#bfcbd9;position:absolute;right:15px}.custom-theme .el-cascader-menu__item.is-disabled{color:#b4bccc;background-color:#fff;cursor:not-allowed}.custom-theme .el-cascader-menu__item.is-disabled:hover{background-color:#fff}.custom-theme .el-cascader-menu__item.is-active{color:#262729}.custom-theme .el-cascader-menu__item:hover{background-color:#f5f7fa}.custom-theme .el-cascader-menu__item.selected{color:#fff;background-color:#f5f7fa}.custom-theme .el-cascader-menu__item__keyword{font-weight:700}.custom-theme .el-cascader-menu--flexible{height:auto;max-height:180px;overflow:auto}.custom-theme .el-cascader-menu--flexible .el-cascader-menu__item{overflow:visible}.custom-theme .el-color-hue-slider{position:relative;-webkit-box-sizing:border-box;box-sizing:border-box;width:280px;height:12px;background-color:red;padding:0 2px}.custom-theme .el-color-hue-slider__bar{position:relative;background:-webkit-gradient(linear,left top,right top,from(red),color-stop(17%,#ff0),color-stop(33%,#0f0),color-stop(50%,#0ff),color-stop(67%,#00f),color-stop(83%,#f0f),to(red));background:linear-gradient(to right,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red 100%);height:100%}.custom-theme .el-color-hue-slider__thumb{position:absolute;cursor:pointer;-webkit-box-sizing:border-box;box-sizing:border-box;left:0;top:0;width:4px;height:100%;border-radius:1px;background:#fff;border:1px solid #f0f0f0;-webkit-box-shadow:0 0 2px rgba(0,0,0,.6);box-shadow:0 0 2px rgba(0,0,0,.6);z-index:1}.custom-theme .el-color-hue-slider.is-vertical{width:12px;height:180px;padding:2px 0}.custom-theme .el-color-hue-slider.is-vertical .el-color-hue-slider__bar{background:-webkit-gradient(linear,left top,left bottom,from(red),color-stop(17%,#ff0),color-stop(33%,#0f0),color-stop(50%,#0ff),color-stop(67%,#00f),color-stop(83%,#f0f),to(red));background:linear-gradient(to bottom,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red 100%)}.custom-theme .el-color-hue-slider.is-vertical .el-color-hue-slider__thumb{left:0;top:0;width:100%;height:4px}.custom-theme .el-color-svpanel{position:relative;width:280px;height:180px}.custom-theme .el-color-svpanel__black,.custom-theme .el-color-svpanel__white{position:absolute;top:0;left:0;right:0;bottom:0}.custom-theme .el-color-svpanel__white{background:-webkit-gradient(linear,left top,right top,from(#fff),to(rgba(255,255,255,0)));background:linear-gradient(to right,#fff,rgba(255,255,255,0))}.custom-theme .el-color-svpanel__black{background:-webkit-gradient(linear,left bottom,left top,from(#000),to(transparent));background:linear-gradient(to top,#000,transparent)}.custom-theme .el-color-svpanel__cursor{position:absolute}.custom-theme .el-color-svpanel__cursor>div{cursor:head;width:4px;height:4px;-webkit-box-shadow:0 0 0 1.5px #fff,inset 0 0 1px 1px rgba(0,0,0,.3),0 0 1px 2px rgba(0,0,0,.4);box-shadow:0 0 0 1.5px #fff,inset 0 0 1px 1px rgba(0,0,0,.3),0 0 1px 2px rgba(0,0,0,.4);border-radius:50%;-webkit-transform:translate(-2px,-2px);transform:translate(-2px,-2px)}.custom-theme .el-color-alpha-slider{position:relative;-webkit-box-sizing:border-box;box-sizing:border-box;width:280px;height:12px;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==)}.custom-theme .el-color-alpha-slider__bar{position:relative;background:-webkit-gradient(linear,left top,right top,from(rgba(255,255,255,0)),to(white));background:linear-gradient(to right,rgba(255,255,255,0) 0,#fff 100%);height:100%}.custom-theme .el-color-alpha-slider__thumb{position:absolute;cursor:pointer;-webkit-box-sizing:border-box;box-sizing:border-box;left:0;top:0;width:4px;height:100%;border-radius:1px;background:#fff;border:1px solid #f0f0f0;-webkit-box-shadow:0 0 2px rgba(0,0,0,.6);box-shadow:0 0 2px rgba(0,0,0,.6);z-index:1}.custom-theme .el-color-alpha-slider.is-vertical{width:20px;height:180px}.custom-theme .el-color-alpha-slider.is-vertical .el-color-alpha-slider__bar{background:-webkit-gradient(linear,left top,left bottom,from(rgba(255,255,255,0)),to(white));background:linear-gradient(to bottom,rgba(255,255,255,0) 0,#fff 100%)}.custom-theme .el-color-alpha-slider.is-vertical .el-color-alpha-slider__thumb{left:0;top:0;width:100%;height:4px}.custom-theme .el-color-dropdown{width:300px}.custom-theme .el-color-dropdown__main-wrapper{margin-bottom:6px}.custom-theme .el-color-dropdown__main-wrapper::after{content:"";display:table;clear:both}.custom-theme .el-color-dropdown__btns{margin-top:6px;text-align:right}.custom-theme .el-color-dropdown__value{float:left;line-height:26px;font-size:12px;color:#000;width:160px}.custom-theme .el-color-dropdown__btn{border:1px solid #dcdcdc;color:#333;line-height:24px;border-radius:2px;padding:0 20px;cursor:pointer;background-color:transparent;outline:0;font-size:12px}.custom-theme .el-color-dropdown__btn[disabled]{color:#ccc;cursor:not-allowed}.custom-theme .el-color-dropdown__btn:hover{color:#262729;border-color:#262729}.custom-theme .el-color-dropdown__link-btn{cursor:pointer;color:#262729;text-decoration:none;padding:15px;font-size:12px}.custom-theme .el-color-dropdown__link-btn:hover{color:tint(#262729,20%)}.custom-theme .el-color-picker{display:inline-block;position:relative;line-height:normal;height:40px}.custom-theme .el-color-picker.is-disabled .el-color-picker__trigger{cursor:not-allowed}.custom-theme .el-color-picker--medium{height:36px}.custom-theme .el-color-picker--medium .el-color-picker__trigger{height:36px;width:36px}.custom-theme .el-color-picker--medium .el-color-picker__mask{height:34px;width:34px}.custom-theme .el-color-picker--small{height:32px}.custom-theme .el-color-picker--small .el-color-picker__trigger{height:32px;width:32px}.custom-theme .el-color-picker--small .el-color-picker__mask{height:30px;width:30px}.custom-theme .el-color-picker--small .el-color-picker__empty,.custom-theme .el-color-picker--small .el-color-picker__icon{-webkit-transform:translate3d(-50%,-50%,0) scale(.8);transform:translate3d(-50%,-50%,0) scale(.8)}.custom-theme .el-color-picker--mini{height:28px}.custom-theme .el-color-picker--mini .el-color-picker__trigger{height:28px;width:28px}.custom-theme .el-color-picker--mini .el-color-picker__mask{height:26px;width:26px}.custom-theme .el-color-picker--mini .el-color-picker__empty,.custom-theme .el-color-picker--mini .el-color-picker__icon{-webkit-transform:translate3d(-50%,-50%,0) scale(.8);transform:translate3d(-50%,-50%,0) scale(.8)}.custom-theme .el-color-picker__mask{height:38px;width:38px;border-radius:4px;position:absolute;top:1px;left:1px;z-index:1;cursor:not-allowed;background-color:rgba(255,255,255,.7)}.custom-theme .el-color-picker__trigger{display:inline-block;-webkit-box-sizing:border-box;box-sizing:border-box;height:40px;width:40px;padding:4px;border:1px solid #e6e6e6;border-radius:4px;font-size:0;position:relative;cursor:pointer}.custom-theme .el-color-picker__color{position:relative;display:block;-webkit-box-sizing:border-box;box-sizing:border-box;border:1px solid #999;border-radius:2px;width:100%;height:100%;text-align:center}.custom-theme .el-color-picker__color.is-alpha{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==)}.custom-theme .el-color-picker__color-inner{position:absolute;left:0;top:0;right:0;bottom:0}.custom-theme .el-color-picker__empty{font-size:12px;color:#999;position:absolute;top:50%;left:50%;-webkit-transform:translate3d(-50%,-50%,0);transform:translate3d(-50%,-50%,0)}.custom-theme .el-color-picker__icon{display:inline-block;position:absolute;width:100%;top:50%;left:50%;-webkit-transform:translate3d(-50%,-50%,0);transform:translate3d(-50%,-50%,0);color:#fff;text-align:center;font-size:12px}.custom-theme .el-color-picker__panel{position:absolute;z-index:10;padding:6px;background-color:#fff;border:1px solid #e6ebf5;border-radius:4px;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.custom-theme .el-input{position:relative;font-size:14px;display:inline-block;width:100%}.custom-theme .el-input::-webkit-scrollbar{z-index:11;width:6px}.custom-theme .el-input::-webkit-scrollbar:horizontal{height:6px}.custom-theme .el-input::-webkit-scrollbar-thumb{border-radius:5px;width:6px;background:#b4bccc}.custom-theme .el-input::-webkit-scrollbar-corner{background:#fff}.custom-theme .el-input::-webkit-scrollbar-track{background:#fff}.custom-theme .el-input::-webkit-scrollbar-track-piece{background:#fff;width:6px}.custom-theme .el-input__inner{-webkit-appearance:none;background-color:#fff;background-image:none;border-radius:4px;border:1px solid #d8dce5;-webkit-box-sizing:border-box;box-sizing:border-box;color:#5a5e66;display:inline-block;font-size:inherit;height:40px;line-height:1;outline:0;padding:0 15px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1);width:100%}.custom-theme .el-input__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input__inner::placeholder{color:#b4bccc}.custom-theme .el-input__inner:hover{border-color:#b4bccc}.custom-theme .el-input__inner:focus{outline:0;border-color:#262729}.custom-theme .el-input__suffix{position:absolute;height:100%;right:5px;top:0;text-align:center;color:#b4bccc;-webkit-transition:all .3s;transition:all .3s;pointer-events:none}.custom-theme .el-input__suffix-inner{pointer-events:all}.custom-theme .el-input__prefix{position:absolute;height:100%;left:5px;top:0;text-align:center;color:#b4bccc;-webkit-transition:all .3s;transition:all .3s}.custom-theme .el-input__icon{height:100%;width:25px;text-align:center;-webkit-transition:all .3s;transition:all .3s;line-height:40px}.custom-theme .el-input__icon:after{content:'';height:100%;width:0;display:inline-block;vertical-align:middle}.custom-theme .el-input__validateIcon{pointer-events:none}.custom-theme .el-input.is-active .el-input__inner{outline:0;border-color:#262729}.custom-theme .el-input.is-disabled .el-input__inner{background-color:#f5f7fa;border-color:#dfe4ed;color:#b4bccc;cursor:not-allowed}.custom-theme .el-input.is-disabled .el-input__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__inner::placeholder{color:#b4bccc}.custom-theme .el-input.is-disabled .el-input__icon{cursor:not-allowed}.custom-theme .el-input--suffix .el-input__inner{padding-right:30px}.custom-theme .el-input--prefix .el-input__inner{padding-left:30px}.custom-theme .el-input--medium{font-size:14px}.custom-theme .el-input--medium .el-input__inner{height:36px}.custom-theme .el-input--medium .el-input__icon{line-height:36px}.custom-theme .el-input--small{font-size:13px}.custom-theme .el-input--small .el-input__inner{height:32px}.custom-theme .el-input--small .el-input__icon{line-height:32px}.custom-theme .el-input--mini{font-size:12px}.custom-theme .el-input--mini .el-input__inner{height:28px}.custom-theme .el-input--mini .el-input__icon{line-height:28px}.custom-theme .el-input-group{line-height:normal;display:inline-table;width:100%;border-collapse:separate}.custom-theme .el-input-group>.el-input__inner{vertical-align:middle;display:table-cell}.custom-theme .el-input-group__append,.custom-theme .el-input-group__prepend{background-color:#f5f7fa;color:#0a76a4;vertical-align:middle;display:table-cell;position:relative;border:1px solid #d8dce5;border-radius:4px;padding:0 20px;width:1px;white-space:nowrap}.custom-theme .el-input-group__append:focus,.custom-theme .el-input-group__prepend:focus{outline:0}.custom-theme .el-input-group__append .el-button,.custom-theme .el-input-group__append .el-select,.custom-theme .el-input-group__prepend .el-button,.custom-theme .el-input-group__prepend .el-select{display:inline-block;margin:-20px}.custom-theme .el-input-group__append button.el-button,.custom-theme .el-input-group__append div.el-select .el-input__inner,.custom-theme .el-input-group__append div.el-select:hover .el-input__inner,.custom-theme .el-input-group__prepend button.el-button,.custom-theme .el-input-group__prepend div.el-select .el-input__inner,.custom-theme .el-input-group__prepend div.el-select:hover .el-input__inner{border-color:transparent;background-color:transparent;color:inherit;border-top:0;border-bottom:0}.custom-theme .el-input-group__append .el-button,.custom-theme .el-input-group__append .el-input,.custom-theme .el-input-group__prepend .el-button,.custom-theme .el-input-group__prepend .el-input{font-size:inherit}.custom-theme .el-input-group__prepend{border-right:0;border-top-right-radius:0;border-bottom-right-radius:0}.custom-theme .el-input-group__append{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.custom-theme .el-input-group--prepend .el-input__inner{border-top-left-radius:0;border-bottom-left-radius:0}.custom-theme .el-input-group--append .el-input__inner{border-top-right-radius:0;border-bottom-right-radius:0}.custom-theme .el-textarea{display:inline-block;width:100%;vertical-align:bottom}.custom-theme .el-textarea__inner{display:block;resize:vertical;padding:5px 15px;line-height:1.5;-webkit-box-sizing:border-box;box-sizing:border-box;width:100%;font-size:14px;color:#5a5e66;background-color:#fff;background-image:none;border:1px solid #d8dce5;border-radius:4px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1)}.custom-theme .el-textarea__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea__inner::placeholder{color:#b4bccc}.custom-theme .el-textarea__inner:hover{border-color:#b4bccc}.custom-theme .el-textarea__inner:focus{outline:0;border-color:#262729}.custom-theme .el-textarea.is-disabled .el-textarea__inner{background-color:#f5f7fa;border-color:#dfe4ed;color:#b4bccc;cursor:not-allowed}.custom-theme .el-textarea.is-disabled .el-textarea__inner::-webkit-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner:-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner::-ms-input-placeholder{color:#b4bccc}.custom-theme .el-textarea.is-disabled .el-textarea__inner::placeholder{color:#b4bccc}.custom-theme .el-button{display:inline-block;line-height:1;white-space:nowrap;cursor:pointer;background:#fff;border:1px solid #d8dce5;border-color:#d8dce5;color:#5a5e66;-webkit-appearance:none;text-align:center;-webkit-box-sizing:border-box;box-sizing:border-box;outline:0;margin:0;-webkit-transition:.1s;transition:.1s;font-weight:500;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;padding:12px 20px;font-size:14px;border-radius:4px}.custom-theme .el-button+.el-button{margin-left:10px}.custom-theme .el-button.is-round{padding:12px 20px}.custom-theme .el-button:focus,.custom-theme .el-button:hover{color:#262729;border-color:#bebebf;background-color:#e9e9ea}.custom-theme .el-button:active{color:#222325;border-color:#222325;outline:0}.custom-theme .el-button::-moz-focus-inner{border:0}.custom-theme .el-button [class*=el-icon-]+span{margin-left:5px}.custom-theme .el-button.is-plain:focus,.custom-theme .el-button.is-plain:hover{background:#fff;border-color:#262729;color:#262729}.custom-theme .el-button.is-plain:active{background:#fff;border-color:#222325;color:#222325;outline:0}.custom-theme .el-button.is-active{color:#222325;border-color:#222325}.custom-theme .el-button.is-disabled,.custom-theme .el-button.is-disabled:focus,.custom-theme .el-button.is-disabled:hover{color:#b4bccc;cursor:not-allowed;background-image:none;background-color:#fff;border-color:#e6ebf5}.custom-theme .el-button.is-disabled.el-button--text{background-color:transparent}.custom-theme .el-button.is-disabled.is-plain,.custom-theme .el-button.is-disabled.is-plain:focus,.custom-theme .el-button.is-disabled.is-plain:hover{background-color:#fff;border-color:#e6ebf5;color:#b4bccc}.custom-theme .el-button.is-loading{position:relative;pointer-events:none}.custom-theme .el-button.is-loading:before{pointer-events:none;content:'';position:absolute;left:-1px;top:-1px;right:-1px;bottom:-1px;border-radius:inherit;background-color:rgba(255,255,255,.35)}.custom-theme .el-button.is-round{border-radius:20px;padding:12px 23px}.custom-theme .el-button--primary{color:#fff;background-color:#262729;border-color:#262729}.custom-theme .el-button--primary:focus,.custom-theme .el-button--primary:hover{background:#515254;border-color:#515254;color:#fff}.custom-theme .el-button--primary:active{background:#222325;border-color:#222325;color:#fff;outline:0}.custom-theme .el-button--primary.is-active{background:#222325;border-color:#222325;color:#fff}.custom-theme .el-button--primary.is-disabled,.custom-theme .el-button--primary.is-disabled:active,.custom-theme .el-button--primary.is-disabled:focus,.custom-theme .el-button--primary.is-disabled:hover{color:#fff;background-color:#939394;border-color:#939394}.custom-theme .el-button--primary.is-plain{color:#262729;background:#e9e9ea;border-color:#a8a9a9}.custom-theme .el-button--primary.is-plain:focus,.custom-theme .el-button--primary.is-plain:hover{background:#262729;border-color:#262729;color:#fff}.custom-theme .el-button--primary.is-plain:active{background:#222325;border-color:#222325;color:#fff;outline:0}.custom-theme .el-button--primary.is-plain.is-disabled,.custom-theme .el-button--primary.is-plain.is-disabled:active,.custom-theme .el-button--primary.is-plain.is-disabled:focus,.custom-theme .el-button--primary.is-plain.is-disabled:hover{color:#7d7d7f;background-color:#e9e9ea;border-color:#d4d4d4}.custom-theme .el-button--success{color:#fff;background-color:#409167;border-color:#409167}.custom-theme .el-button--success:focus,.custom-theme .el-button--success:hover{background:#66a785;border-color:#66a785;color:#fff}.custom-theme .el-button--success:active{background:#3a835d;border-color:#3a835d;color:#fff;outline:0}.custom-theme .el-button--success.is-active{background:#3a835d;border-color:#3a835d;color:#fff}.custom-theme .el-button--success.is-disabled,.custom-theme .el-button--success.is-disabled:active,.custom-theme .el-button--success.is-disabled:focus,.custom-theme .el-button--success.is-disabled:hover{color:#fff;background-color:#a0c8b3;border-color:#a0c8b3}.custom-theme .el-button--success.is-plain{color:#409167;background:#ecf4f0;border-color:#b3d3c2}.custom-theme .el-button--success.is-plain:focus,.custom-theme .el-button--success.is-plain:hover{background:#409167;border-color:#409167;color:#fff}.custom-theme .el-button--success.is-plain:active{background:#3a835d;border-color:#3a835d;color:#fff;outline:0}.custom-theme .el-button--success.is-plain.is-disabled,.custom-theme .el-button--success.is-plain.is-disabled:active,.custom-theme .el-button--success.is-plain.is-disabled:focus,.custom-theme .el-button--success.is-plain.is-disabled:hover{color:#8cbda4;background-color:#ecf4f0;border-color:#d9e9e1}.custom-theme .el-button--warning{color:#fff;background-color:#9da408;border-color:#9da408}.custom-theme .el-button--warning:focus,.custom-theme .el-button--warning:hover{background:#b1b639;border-color:#b1b639;color:#fff}.custom-theme .el-button--warning:active{background:#8d9407;border-color:#8d9407;color:#fff;outline:0}.custom-theme .el-button--warning.is-active{background:#8d9407;border-color:#8d9407;color:#fff}.custom-theme .el-button--warning.is-disabled,.custom-theme .el-button--warning.is-disabled:active,.custom-theme .el-button--warning.is-disabled:focus,.custom-theme .el-button--warning.is-disabled:hover{color:#fff;background-color:#ced284;border-color:#ced284}.custom-theme .el-button--warning.is-plain{color:#9da408;background:#f5f6e6;border-color:#d8db9c}.custom-theme .el-button--warning.is-plain:focus,.custom-theme .el-button--warning.is-plain:hover{background:#9da408;border-color:#9da408;color:#fff}.custom-theme .el-button--warning.is-plain:active{background:#8d9407;border-color:#8d9407;color:#fff;outline:0}.custom-theme .el-button--warning.is-plain.is-disabled,.custom-theme .el-button--warning.is-plain.is-disabled:active,.custom-theme .el-button--warning.is-plain.is-disabled:focus,.custom-theme .el-button--warning.is-plain.is-disabled:hover{color:#c4c86b;background-color:#f5f6e6;border-color:#ebedce}.custom-theme .el-button--danger{color:#fff;background-color:#b3450e;border-color:#b3450e}.custom-theme .el-button--danger:focus,.custom-theme .el-button--danger:hover{background:#c26a3e;border-color:#c26a3e;color:#fff}.custom-theme .el-button--danger:active{background:#a13e0d;border-color:#a13e0d;color:#fff;outline:0}.custom-theme .el-button--danger.is-active{background:#a13e0d;border-color:#a13e0d;color:#fff}.custom-theme .el-button--danger.is-disabled,.custom-theme .el-button--danger.is-disabled:active,.custom-theme .el-button--danger.is-disabled:focus,.custom-theme .el-button--danger.is-disabled:hover{color:#fff;background-color:#d9a287;border-color:#d9a287}.custom-theme .el-button--danger.is-plain{color:#b3450e;background:#f7ece7;border-color:#e1b59f}.custom-theme .el-button--danger.is-plain:focus,.custom-theme .el-button--danger.is-plain:hover{background:#b3450e;border-color:#b3450e;color:#fff}.custom-theme .el-button--danger.is-plain:active{background:#a13e0d;border-color:#a13e0d;color:#fff;outline:0}.custom-theme .el-button--danger.is-plain.is-disabled,.custom-theme .el-button--danger.is-plain.is-disabled:active,.custom-theme .el-button--danger.is-plain.is-disabled:focus,.custom-theme .el-button--danger.is-plain.is-disabled:hover{color:#d18f6e;background-color:#f7ece7;border-color:#f0dacf}.custom-theme .el-button--info{color:#fff;background-color:#0a76a4;border-color:#0a76a4}.custom-theme .el-button--info:focus,.custom-theme .el-button--info:hover{background:#3b91b6;border-color:#3b91b6;color:#fff}.custom-theme .el-button--info:active{background:#096a94;border-color:#096a94;color:#fff;outline:0}.custom-theme .el-button--info.is-active{background:#096a94;border-color:#096a94;color:#fff}.custom-theme .el-button--info.is-disabled,.custom-theme .el-button--info.is-disabled:active,.custom-theme .el-button--info.is-disabled:focus,.custom-theme .el-button--info.is-disabled:hover{color:#fff;background-color:#85bbd2;border-color:#85bbd2}.custom-theme .el-button--info.is-plain{color:#0a76a4;background:#e7f1f6;border-color:#9dc8db}.custom-theme .el-button--info.is-plain:focus,.custom-theme .el-button--info.is-plain:hover{background:#0a76a4;border-color:#0a76a4;color:#fff}.custom-theme .el-button--info.is-plain:active{background:#096a94;border-color:#096a94;color:#fff;outline:0}.custom-theme .el-button--info.is-plain.is-disabled,.custom-theme .el-button--info.is-plain.is-disabled:active,.custom-theme .el-button--info.is-plain.is-disabled:focus,.custom-theme .el-button--info.is-plain.is-disabled:hover{color:#6cadc8;background-color:#e7f1f6;border-color:#cee4ed}.custom-theme .el-button--medium{padding:10px 20px;font-size:14px;border-radius:4px}.custom-theme .el-button--medium.is-round{padding:10px 20px}.custom-theme .el-button--small{padding:9px 15px;font-size:12px;border-radius:3px}.custom-theme .el-button--small.is-round{padding:9px 15px}.custom-theme .el-button--mini{padding:7px 15px;font-size:12px;border-radius:3px}.custom-theme .el-button--mini.is-round{padding:7px 15px}.custom-theme .el-button--text{border:none;color:#262729;background:0 0;padding-left:0;padding-right:0}.custom-theme .el-button--text:focus,.custom-theme .el-button--text:hover{color:#515254;border-color:transparent;background-color:transparent}.custom-theme .el-button--text:active{color:#222325;border-color:transparent;background-color:transparent}.custom-theme .el-button-group{display:inline-block;vertical-align:middle}.custom-theme .el-button-group::after,.custom-theme .el-button-group::before{display:table;content:""}.custom-theme .el-button-group::after{clear:both}.custom-theme .el-button-group .el-button{float:left;position:relative}.custom-theme .el-button-group .el-button+.el-button{margin-left:0}.custom-theme .el-button-group .el-button:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.custom-theme .el-button-group .el-button:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.custom-theme .el-button-group .el-button:not(:first-child):not(:last-child){border-radius:0}.custom-theme .el-button-group .el-button:not(:last-child){margin-right:-1px}.custom-theme .el-button-group .el-button:active,.custom-theme .el-button-group .el-button:focus,.custom-theme .el-button-group .el-button:hover{z-index:1}.custom-theme .el-button-group .el-button.is-active{z-index:1}.custom-theme .el-button-group .el-button--primary:first-child{border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--primary:last-child{border-left-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--primary:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--success:first-child{border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--success:last-child{border-left-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--success:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--warning:first-child{border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--warning:last-child{border-left-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--warning:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--danger:first-child{border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--danger:last-child{border-left-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--danger:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--info:first-child{border-right-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--info:last-child{border-left-color:rgba(255,255,255,.5)}.custom-theme .el-button-group .el-button--info:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.custom-theme .el-checkbox{color:#5a5e66;font-weight:500;font-size:14px;position:relative;cursor:pointer;display:inline-block;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.custom-theme .el-checkbox.is-bordered{padding:9px 20px 9px 10px;border-radius:4px;border:1px solid #d8dce5}.custom-theme .el-checkbox.is-bordered.is-checked{border-color:#262729}.custom-theme .el-checkbox.is-bordered.is-disabled{border-color:#e6ebf5;cursor:not-allowed}.custom-theme .el-checkbox.is-bordered+.el-checkbox.is-bordered{margin-left:10px}.custom-theme .el-checkbox.is-bordered.el-checkbox--medium{padding:7px 20px 7px 10px;border-radius:4px}.custom-theme .el-checkbox.is-bordered.el-checkbox--medium .el-checkbox__label{line-height:17px;font-size:14px}.custom-theme .el-checkbox.is-bordered.el-checkbox--medium .el-checkbox__inner{height:14px;width:14px}.custom-theme .el-checkbox.is-bordered.el-checkbox--small{padding:3px 15px 7px 10px;border-radius:3px}.custom-theme .el-checkbox.is-bordered.el-checkbox--small .el-checkbox__label{line-height:15px;font-size:12px}.custom-theme .el-checkbox.is-bordered.el-checkbox--small .el-checkbox__inner{height:12px;width:12px}.custom-theme .el-checkbox.is-bordered.el-checkbox--small .el-checkbox__inner::after{height:6px;width:2px}.custom-theme .el-checkbox.is-bordered.el-checkbox--mini{padding:1px 15px 5px 10px;border-radius:3px}.custom-theme .el-checkbox.is-bordered.el-checkbox--mini .el-checkbox__label{line-height:12px;font-size:12px}.custom-theme .el-checkbox.is-bordered.el-checkbox--mini .el-checkbox__inner{height:12px;width:12px}.custom-theme .el-checkbox.is-bordered.el-checkbox--mini .el-checkbox__inner::after{height:6px;width:2px}.custom-theme .el-checkbox__input{white-space:nowrap;cursor:pointer;outline:0;display:inline-block;line-height:1;position:relative;vertical-align:middle}.custom-theme .el-checkbox__input.is-disabled .el-checkbox__inner{background-color:#edf2fc;border-color:#d8dce5;cursor:not-allowed}.custom-theme .el-checkbox__input.is-disabled .el-checkbox__inner::after{cursor:not-allowed;border-color:#b4bccc}.custom-theme .el-checkbox__input.is-disabled .el-checkbox__inner+.el-checkbox__label{cursor:not-allowed}.custom-theme .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner{background-color:#edf2fc;border-color:#d8dce5}.custom-theme .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner::after{border-color:#b4bccc}.custom-theme .el-checkbox__input.is-disabled.is-indeterminate .el-checkbox__inner{background-color:#edf2fc;border-color:#d8dce5}.custom-theme .el-checkbox__input.is-disabled.is-indeterminate .el-checkbox__inner::before{background-color:#b4bccc;border-color:#b4bccc}.custom-theme .el-checkbox__input.is-disabled+span.el-checkbox__label{color:#b4bccc;cursor:not-allowed}.custom-theme .el-checkbox__input.is-checked .el-checkbox__inner{background-color:#262729;border-color:#262729}.custom-theme .el-checkbox__input.is-checked .el-checkbox__inner::after{-webkit-transform:rotate(45deg) scaleY(1);transform:rotate(45deg) scaleY(1)}.custom-theme .el-checkbox__input.is-checked+.el-checkbox__label{color:#262729}.custom-theme .el-checkbox__input.is-focus .el-checkbox__inner{border-color:#262729}.custom-theme .el-checkbox__input.is-indeterminate .el-checkbox__inner{background-color:#262729;border-color:#262729}.custom-theme .el-checkbox__input.is-indeterminate .el-checkbox__inner::before{content:'';position:absolute;display:block;background-color:#fff;height:2px;-webkit-transform:scale(.5);transform:scale(.5);left:0;right:0;top:5px}.custom-theme .el-checkbox__input.is-indeterminate .el-checkbox__inner::after{display:none}.custom-theme .el-checkbox__inner{display:inline-block;position:relative;border:1px solid #d8dce5;border-radius:2px;-webkit-box-sizing:border-box;box-sizing:border-box;width:14px;height:14px;background-color:#fff;z-index:1;-webkit-transition:border-color .25s cubic-bezier(.71,-.46,.29,1.46),background-color .25s cubic-bezier(.71,-.46,.29,1.46);transition:border-color .25s cubic-bezier(.71,-.46,.29,1.46),background-color .25s cubic-bezier(.71,-.46,.29,1.46)}.custom-theme .el-checkbox__inner:hover{border-color:#262729}.custom-theme .el-checkbox__inner::after{-webkit-box-sizing:content-box;box-sizing:content-box;content:"";border:1px solid #fff;border-left:0;border-top:0;height:7px;left:4px;position:absolute;top:1px;-webkit-transform:rotate(45deg) scaleY(0);transform:rotate(45deg) scaleY(0);width:3px;-webkit-transition:-webkit-transform .15s cubic-bezier(.71,-.46,.88,.6) 50ms;transition:-webkit-transform .15s cubic-bezier(.71,-.46,.88,.6) 50ms;transition:transform .15s cubic-bezier(.71,-.46,.88,.6) 50ms;transition:transform .15s cubic-bezier(.71,-.46,.88,.6) 50ms,-webkit-transform .15s cubic-bezier(.71,-.46,.88,.6) 50ms;-webkit-transform-origin:center;transform-origin:center}.custom-theme .el-checkbox__original{opacity:0;outline:0;position:absolute;margin:0;width:0;height:0;left:-999px}.custom-theme .el-checkbox__label{display:inline-block;padding-left:10px;line-height:19px;font-size:14px}.custom-theme .el-checkbox+.el-checkbox{margin-left:30px}.custom-theme .el-checkbox-button{position:relative;display:inline-block}.custom-theme .el-checkbox-button__inner{display:inline-block;line-height:1;font-weight:500;white-space:nowrap;vertical-align:middle;cursor:pointer;background:#fff;border:1px solid #d8dce5;border-left:0;color:#5a5e66;-webkit-appearance:none;text-align:center;-webkit-box-sizing:border-box;box-sizing:border-box;outline:0;margin:0;position:relative;-webkit-transition:all .3s cubic-bezier(.645,.045,.355,1);transition:all .3s cubic-bezier(.645,.045,.355,1);-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;padding:12px 20px;font-size:14px;border-radius:0}.custom-theme .el-checkbox-button__inner.is-round{padding:12px 20px}.custom-theme .el-checkbox-button__inner:hover{color:#262729}.custom-theme .el-checkbox-button__inner [class*=el-icon-]{line-height:.9}.custom-theme .el-checkbox-button__inner [class*=el-icon-]+span{margin-left:5px}.custom-theme .el-checkbox-button__original{opacity:0;outline:0;position:absolute;margin:0;left:-999px}.custom-theme .el-checkbox-button.is-checked .el-checkbox-button__inner{color:#fff;background-color:#262729;border-color:#262729;-webkit-box-shadow:-1px 0 0 0 #7d7d7f;box-shadow:-1px 0 0 0 #7d7d7f}.custom-theme .el-checkbox-button.is-disabled .el-checkbox-button__inner{color:#b4bccc;cursor:not-allowed;background-image:none;background-color:#fff;border-color:#e6ebf5;-webkit-box-shadow:none;box-shadow:none}.custom-theme .el-checkbox-button:first-child .el-checkbox-button__inner{border-left:1px solid #d8dce5;border-radius:4px 0 0 4px;-webkit-box-shadow:none!important;box-shadow:none!important}.custom-theme .el-checkbox-button.is-focus .el-checkbox-button__inner{border-color:#262729}.custom-theme .el-checkbox-button:last-child .el-checkbox-button__inner{border-radius:0 4px 4px 0}.custom-theme .el-checkbox-button--medium .el-checkbox-button__inner{padding:10px 20px;font-size:14px;border-radius:0}.custom-theme .el-checkbox-button--medium .el-checkbox-button__inner.is-round{padding:10px 20px}.custom-theme .el-checkbox-button--small .el-checkbox-button__inner{padding:9px 15px;font-size:12px;border-radius:0}.custom-theme .el-checkbox-button--small .el-checkbox-button__inner.is-round{padding:9px 15px}.custom-theme .el-checkbox-button--mini .el-checkbox-button__inner{padding:7px 15px;font-size:12px;border-radius:0}.custom-theme .el-checkbox-button--mini .el-checkbox-button__inner.is-round{padding:7px 15px}.custom-theme .el-checkbox-group{font-size:0}.custom-theme .el-transfer{font-size:14px}.custom-theme .el-transfer__buttons{display:inline-block;vertical-align:middle;padding:0 30px}.custom-theme .el-transfer__button{display:block;margin:0 auto;padding:10px;border-radius:50%;color:#fff;background-color:#262729;font-size:0}.custom-theme .el-transfer__button.is-with-texts{border-radius:4px}.custom-theme .el-transfer__button.is-disabled{border:1px solid #d8dce5;background-color:#f5f7fa;color:#b4bccc}.custom-theme .el-transfer__button.is-disabled:hover{border:1px solid #d8dce5;background-color:#f5f7fa;color:#b4bccc}.custom-theme .el-transfer__button:first-child{margin-bottom:10px}.custom-theme .el-transfer__button:nth-child(2){margin:0}.custom-theme .el-transfer__button i,.custom-theme .el-transfer__button span{font-size:14px}.custom-theme .el-transfer__button [class*=el-icon-]+span{margin-left:0}.custom-theme .el-transfer-panel{border:1px solid #e6ebf5;border-radius:4px;overflow:hidden;background:#fff;display:inline-block;vertical-align:middle;width:200px;-webkit-box-sizing:border-box;box-sizing:border-box;position:relative}.custom-theme .el-transfer-panel__body{height:246px}.custom-theme .el-transfer-panel__body.is-with-footer{padding-bottom:40px}.custom-theme .el-transfer-panel__list{margin:0;padding:6px 0;list-style:none;height:246px;overflow:auto;-webkit-box-sizing:border-box;box-sizing:border-box}.custom-theme .el-transfer-panel__list.is-filterable{height:194px;padding-top:0}.custom-theme .el-transfer-panel__item{height:30px;line-height:30px;padding-left:15px;display:block}.custom-theme .el-transfer-panel__item+.el-transfer-panel__item{margin-left:0}.custom-theme .el-transfer-panel__item.el-checkbox{color:#5a5e66}.custom-theme .el-transfer-panel__item:hover{color:#262729}.custom-theme .el-transfer-panel__item.el-checkbox .el-checkbox__label{width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;-webkit-box-sizing:border-box;box-sizing:border-box;padding-left:24px;line-height:30px}.custom-theme .el-transfer-panel__item .el-checkbox__input{position:absolute;top:8px}.custom-theme .el-transfer-panel__filter{text-align:center;margin:15px;-webkit-box-sizing:border-box;box-sizing:border-box;display:block;width:auto}.custom-theme .el-transfer-panel__filter .el-input__inner{height:32px;width:100%;font-size:12px;display:inline-block;-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:16px;padding-right:10px;padding-left:30px}.custom-theme .el-transfer-panel__filter .el-input__icon{margin-left:5px}.custom-theme .el-transfer-panel__filter .el-icon-circle-close{cursor:pointer}.custom-theme .el-transfer-panel .el-transfer-panel__header{height:40px;line-height:40px;background:#f5f7fa;margin:0;padding-left:15px;border-bottom:1px solid #e6ebf5;-webkit-box-sizing:border-box;box-sizing:border-box;color:#000}.custom-theme .el-transfer-panel .el-transfer-panel__header .el-checkbox{display:block;line-height:40px}.custom-theme .el-transfer-panel .el-transfer-panel__header .el-checkbox .el-checkbox__label{font-size:16px;color:#2d2f33;font-weight:400}.custom-theme .el-transfer-panel .el-transfer-panel__header .el-checkbox .el-checkbox__label span{position:absolute;right:15px;color:#878d99;font-size:12px;font-weight:400}.custom-theme .el-transfer-panel .el-transfer-panel__footer{height:40px;background:#fff;margin:0;padding:0;border-top:1px solid #e6ebf5;position:absolute;bottom:0;left:0;width:100%;z-index:1}.custom-theme .el-transfer-panel .el-transfer-panel__footer::after{display:inline-block;content:"";height:100%;vertical-align:middle}.custom-theme .el-transfer-panel .el-transfer-panel__footer .el-checkbox{padding-left:20px;color:#5a5e66}.custom-theme .el-transfer-panel .el-transfer-panel__empty{margin:0;height:30px;line-height:30px;padding:6px 15px 0;color:#878d99}.custom-theme .el-transfer-panel .el-checkbox__label{padding-left:8px}.custom-theme .el-transfer-panel .el-checkbox__inner{height:14px;width:14px;border-radius:3px}.custom-theme .el-transfer-panel .el-checkbox__inner::after{height:6px;width:3px;left:4px}.custom-theme .el-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-flex:1;-ms-flex:1;flex:1;-webkit-box-sizing:border-box;box-sizing:border-box}.custom-theme .el-container.is-vertical{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.custom-theme .el-header{padding:0 20px;-webkit-box-sizing:border-box;box-sizing:border-box}.custom-theme .el-aside{overflow:auto;-webkit-box-sizing:border-box;box-sizing:border-box}.custom-theme .el-main{-webkit-box-flex:1;-ms-flex:1;flex:1;overflow:auto;-webkit-box-sizing:border-box;box-sizing:border-box;padding:20px}.custom-theme .el-footer{padding:0 20px;-webkit-box-sizing:border-box;box-sizing:border-box} |
src/common/Header.vue
1 | <template> | File was deleted | |
2 | <div class="header"> | ||
3 | <!-- 折叠按钮 --> | ||
4 | <div class="collapse-btn" @click="collapseChage"> | ||
5 | <i v-if="!collapse" class="el-icon-s-fold"></i> | ||
6 | <i v-else class="el-icon-s-unfold"></i> | ||
7 | </div> | ||
8 | <div class="logo">后台管理系统</div> | ||
9 | <div class="header-right"> | ||
10 | <div class="header-user-con"> | ||
11 | <!-- 全屏显示 --> | ||
12 | <div class="btn-fullscreen" @click="handleFullScreen"> | ||
13 | <el-tooltip effect="dark" :content="fullscreen?`取消全屏`:`全屏`" placement="bottom"> | ||
14 | <i class="el-icon-rank"></i> | ||
15 | </el-tooltip> | ||
16 | </div> | ||
17 | <!-- 消息中心 --> | ||
18 | <div class="btn-bell"> | ||
19 | <el-tooltip | ||
20 | effect="dark" | ||
21 | :content="message?`有${message}条未读消息`:`消息中心`" | ||
22 | placement="bottom" | ||
23 | > | ||
24 | <router-link to="/tabs"> | ||
25 | <i class="el-icon-bell"></i> | ||
26 | </router-link> | ||
27 | </el-tooltip> | ||
28 | <span class="btn-bell-badge" v-if="message"></span> | ||
29 | </div> | ||
30 | <!-- 用户头像 --> | ||
31 | <div class="user-avator"> | ||
32 | <img src="../assets/img/img.jpg" /> | ||
33 | </div> | ||
34 | <!-- 用户名下拉菜单 --> | ||
35 | <el-dropdown class="user-name" trigger="click" @command="handleCommand"> | ||
36 | <span class="el-dropdown-link"> | ||
37 | {{username}} | ||
38 | <i class="el-icon-caret-bottom"></i> | ||
39 | </span> | ||
40 | <el-dropdown-menu slot="dropdown"> | ||
41 | <a href="https://github.com/lin-xin/vue-manage-system" target="_blank"> | ||
42 | <el-dropdown-item>项目仓库</el-dropdown-item> | ||
43 | </a> | ||
44 | <el-dropdown-item divided command="loginout">退出登录</el-dropdown-item> | ||
45 | </el-dropdown-menu> | ||
46 | </el-dropdown> | ||
47 | </div> | ||
48 | </div> | ||
49 | </div> | ||
50 | </template> | ||
51 | <script> | ||
52 | import bus from './bus'; | ||
53 | export default { | ||
54 | data() { | ||
55 | return { | ||
56 | collapse: false, | ||
57 | fullscreen: false, | ||
58 | name: 'linxin', | ||
59 | message: 2 | ||
60 | }; | ||
61 | }, | ||
62 | computed: { | ||
63 | username() { | ||
64 | let username = localStorage.getItem('ms_username'); | ||
65 | return username ? username : this.name; | ||
66 | } | ||
67 | }, | ||
68 | methods: { | ||
69 | // 用户名下拉菜单选择事件 | ||
70 | handleCommand(command) { | ||
71 | if (command == 'loginout') { | ||
72 | localStorage.removeItem('ms_username'); | ||
73 | this.$router.push('/login'); | ||
74 | } | ||
75 | }, | ||
76 | // 侧边栏折叠 | ||
77 | collapseChage() { | ||
78 | this.collapse = !this.collapse; | ||
79 | bus.$emit('collapse', this.collapse); | ||
80 | }, | ||
81 | // 全屏事件 | ||
82 | handleFullScreen() { | ||
83 | let element = document.documentElement; | ||
84 | if (this.fullscreen) { | ||
85 | if (document.exitFullscreen) { | ||
86 | document.exitFullscreen(); | ||
87 | } else if (document.webkitCancelFullScreen) { | ||
88 | document.webkitCancelFullScreen(); | ||
89 | } else if (document.mozCancelFullScreen) { | ||
90 | document.mozCancelFullScreen(); | ||
91 | } else if (document.msExitFullscreen) { | ||
92 | document.msExitFullscreen(); | ||
93 | } | ||
94 | } else { | ||
95 | if (element.requestFullscreen) { | ||
96 | element.requestFullscreen(); | ||
97 | } else if (element.webkitRequestFullScreen) { | ||
98 | element.webkitRequestFullScreen(); | ||
99 | } else if (element.mozRequestFullScreen) { | ||
100 | element.mozRequestFullScreen(); | ||
101 | } else if (element.msRequestFullscreen) { | ||
102 | // IE11 | ||
103 | element.msRequestFullscreen(); | ||
104 | } | ||
105 | } | ||
106 | this.fullscreen = !this.fullscreen; | ||
107 | } | ||
108 | }, | ||
109 | mounted() { | ||
110 | if (document.body.clientWidth < 1500) { | ||
111 | this.collapseChage(); | ||
112 | } | ||
113 | } | ||
114 | }; | ||
115 | </script> | ||
116 | <style scoped> | ||
117 | .header { | ||
118 | position: relative; | ||
119 | box-sizing: border-box; | ||
120 | width: 100%; | ||
121 | height: 70px; | ||
122 | font-size: 22px; | ||
123 | color: #fff; | ||
124 | } | ||
125 | .collapse-btn { | ||
126 | float: left; | ||
127 | padding: 0 21px; | ||
128 | cursor: pointer; | ||
129 | line-height: 70px; | ||
130 | } | ||
131 | .header .logo { | ||
132 | float: left; | ||
133 | width: 250px; | ||
134 | line-height: 70px; | ||
135 | } | ||
136 | .header-right { | ||
137 | float: right; | ||
138 | padding-right: 50px; | ||
139 | } | ||
140 | .header-user-con { | ||
141 | display: flex; | ||
142 | height: 70px; | ||
143 | align-items: center; | ||
144 | } | ||
145 | .btn-fullscreen { | ||
146 | transform: rotate(45deg); | ||
147 | margin-right: 5px; | ||
148 | font-size: 24px; | ||
149 | } | ||
150 | .btn-bell, | ||
151 | .btn-fullscreen { | ||
152 | position: relative; | ||
153 | width: 30px; | ||
154 | height: 30px; | ||
155 | text-align: center; | ||
156 | border-radius: 15px; | ||
157 | cursor: pointer; | ||
158 | } | ||
159 | .btn-bell-badge { | ||
160 | position: absolute; | ||
161 | right: 0; | ||
162 | top: -2px; | ||
163 | width: 8px; | ||
164 | height: 8px; | ||
165 | border-radius: 4px; | ||
166 | background: #f56c6c; | ||
167 | color: #fff; | ||
168 | } | ||
169 | .btn-bell .el-icon-bell { | ||
170 | color: #fff; | ||
171 | } | ||
172 | .user-name { | ||
173 | margin-left: 10px; | ||
174 | } | ||
175 | .user-avator { | ||
176 | margin-left: 20px; | ||
177 | } | ||
178 | .user-avator img { | ||
179 | display: block; | ||
180 | width: 40px; | ||
181 | height: 40px; | ||
182 | border-radius: 50%; | ||
183 | } | ||
184 | .el-dropdown-link { | ||
185 | color: #fff; | ||
186 | cursor: pointer; | ||
187 | } | ||
188 | .el-dropdown-menu__item { | ||
189 | text-align: center; | ||
190 | } | ||
191 | </style> |
src/common/Home.vue
1 | <template> | File was deleted | |
2 | <div class="wrapper"> | ||
3 | <v-head></v-head> | ||
4 | <v-sidebar></v-sidebar> | ||
5 | <div class="content-box" :class="{'content-collapse':collapse}"> | ||
6 | <v-tags></v-tags> | ||
7 | <div class="content"> | ||
8 | <transition name="move" mode="out-in"> | ||
9 | <keep-alive :include="tagsList"> | ||
10 | <router-view></router-view> | ||
11 | </keep-alive> | ||
12 | </transition> | ||
13 | <el-backtop target=".content"></el-backtop> | ||
14 | </div> | ||
15 | </div> | ||
16 | </div> | ||
17 | </template> | ||
18 | |||
19 | <script> | ||
20 | import vHead from './Header.vue'; | ||
21 | import vSidebar from './Sidebar.vue'; | ||
22 | import vTags from './Tags.vue'; | ||
23 | import bus from './bus'; | ||
24 | export default { | ||
25 | data() { | ||
26 | return { | ||
27 | tagsList: [], | ||
28 | collapse: false | ||
29 | }; | ||
30 | }, | ||
31 | components: { | ||
32 | vHead, | ||
33 | vSidebar, | ||
34 | vTags | ||
35 | }, | ||
36 | created() { | ||
37 | bus.$on('collapse-content', msg => { | ||
38 | this.collapse = msg; | ||
39 | }); | ||
40 | // 只有在标签页列表里的页面才使用keep-alive,即关闭标签之后就不保存到内存中了。 | ||
41 | bus.$on('tags', msg => { | ||
42 | let arr = []; | ||
43 | for (let i = 0, len = msg.length; i < len; i++) { | ||
44 | msg[i].name && arr.push(msg[i].name); | ||
45 | } | ||
46 | this.tagsList = arr; | ||
47 | }); | ||
48 | } | ||
49 | }; | ||
50 | </script> |
src/common/Sidebar.vue
1 | <template> | File was deleted | |
2 | <div class="sidebar"> | ||
3 | <el-menu | ||
4 | class="sidebar-el-menu" | ||
5 | :default-active="onRoutes" | ||
6 | :collapse="collapse" | ||
7 | background-color="#324157" | ||
8 | text-color="#bfcbd9" | ||
9 | active-text-color="#20a0ff" | ||
10 | unique-opened | ||
11 | router | ||
12 | > | ||
13 | <template v-for="item in items"> | ||
14 | <template v-if="item.subs"> | ||
15 | <el-submenu :index="item.index" :key="item.index"> | ||
16 | <template slot="title"> | ||
17 | <i :class="item.icon"></i> | ||
18 | <span slot="title">{{ item.title }}</span> | ||
19 | </template> | ||
20 | <template v-for="subItem in item.subs"> | ||
21 | <el-submenu | ||
22 | v-if="subItem.subs" | ||
23 | :index="subItem.index" | ||
24 | :key="subItem.index" | ||
25 | > | ||
26 | <template slot="title">{{ subItem.title }}</template> | ||
27 | <el-menu-item | ||
28 | v-for="(threeItem,i) in subItem.subs" | ||
29 | :key="i" | ||
30 | :index="threeItem.index" | ||
31 | >{{ threeItem.title }}</el-menu-item> | ||
32 | </el-submenu> | ||
33 | <el-menu-item | ||
34 | v-else | ||
35 | :index="subItem.index" | ||
36 | :key="subItem.index" | ||
37 | >{{ subItem.title }}</el-menu-item> | ||
38 | </template> | ||
39 | </el-submenu> | ||
40 | </template> | ||
41 | <template v-else> | ||
42 | <el-menu-item :index="item.index" :key="item.index"> | ||
43 | <i :class="item.icon"></i> | ||
44 | <span slot="title">{{ item.title }}</span> | ||
45 | </el-menu-item> | ||
46 | </template> | ||
47 | </template> | ||
48 | </el-menu> | ||
49 | </div> | ||
50 | </template> | ||
51 | |||
52 | <script> | ||
53 | import bus from './bus'; | ||
54 | export default { | ||
55 | data() { | ||
56 | return { | ||
57 | collapse: false, | ||
58 | items: [ | ||
59 | { | ||
60 | icon: 'el-icon-lx-home', | ||
61 | index: 'dashboard', | ||
62 | title: '系统首页' | ||
63 | }, | ||
64 | { | ||
65 | icon: 'el-icon-lx-cascades', | ||
66 | index: 'table', | ||
67 | title: '基础表格' | ||
68 | }, | ||
69 | { | ||
70 | icon: 'el-icon-lx-copy', | ||
71 | index: 'tabs', | ||
72 | title: 'tab选项卡' | ||
73 | }, | ||
74 | { | ||
75 | icon: 'el-icon-lx-calendar', | ||
76 | index: '3', | ||
77 | title: '表单相关', | ||
78 | subs: [ | ||
79 | { | ||
80 | index: 'form', | ||
81 | title: '基本表单' | ||
82 | }, | ||
83 | { | ||
84 | index: '3-2', | ||
85 | title: '三级菜单', | ||
86 | subs: [ | ||
87 | { | ||
88 | index: 'editor', | ||
89 | title: '富文本编辑器' | ||
90 | }, | ||
91 | { | ||
92 | index: 'markdown', | ||
93 | title: 'markdown编辑器' | ||
94 | } | ||
95 | ] | ||
96 | }, | ||
97 | { | ||
98 | index: 'upload', | ||
99 | title: '文件上传' | ||
100 | } | ||
101 | ] | ||
102 | }, | ||
103 | { | ||
104 | icon: 'el-icon-lx-emoji', | ||
105 | index: 'icon', | ||
106 | title: '自定义图标' | ||
107 | }, | ||
108 | { | ||
109 | icon: 'el-icon-pie-chart', | ||
110 | index: 'charts', | ||
111 | title: 'schart图表' | ||
112 | }, | ||
113 | { | ||
114 | icon: 'el-icon-rank', | ||
115 | index: '6', | ||
116 | title: '拖拽组件', | ||
117 | subs: [ | ||
118 | { | ||
119 | index: 'drag', | ||
120 | title: '拖拽列表' | ||
121 | }, | ||
122 | { | ||
123 | index: 'dialog', | ||
124 | title: '拖拽弹框' | ||
125 | } | ||
126 | ] | ||
127 | }, | ||
128 | { | ||
129 | icon: 'el-icon-lx-global', | ||
130 | index: 'i18n', | ||
131 | title: '国际化功能' | ||
132 | }, | ||
133 | { | ||
134 | icon: 'el-icon-lx-warn', | ||
135 | index: '7', | ||
136 | title: '错误处理', | ||
137 | subs: [ | ||
138 | { | ||
139 | index: 'permission', | ||
140 | title: '权限测试' | ||
141 | }, | ||
142 | { | ||
143 | index: '404', | ||
144 | title: '404页面' | ||
145 | } | ||
146 | ] | ||
147 | }, | ||
148 | { | ||
149 | icon: 'el-icon-lx-redpacket_fill', | ||
150 | index: '/donate', | ||
151 | title: '支持作者' | ||
152 | } | ||
153 | ] | ||
154 | }; | ||
155 | }, | ||
156 | computed: { | ||
157 | onRoutes() { | ||
158 | return this.$route.path.replace('/', ''); | ||
159 | } | ||
160 | }, | ||
161 | created() { | ||
162 | // 通过 Event Bus 进行组件间通信,来折叠侧边栏 | ||
163 | bus.$on('collapse', msg => { | ||
164 | this.collapse = msg; | ||
165 | bus.$emit('collapse-content', msg); | ||
166 | }); | ||
167 | } | ||
168 | }; | ||
169 | </script> | ||
170 | |||
171 | <style scoped> | ||
172 | .sidebar { | ||
173 | display: block; | ||
174 | position: absolute; | ||
175 | left: 0; | ||
176 | top: 70px; | ||
177 | bottom: 0; | ||
178 | overflow-y: scroll; | ||
179 | } | ||
180 | .sidebar::-webkit-scrollbar { | ||
181 | width: 0; | ||
182 | } | ||
183 | .sidebar-el-menu:not(.el-menu--collapse) { | ||
184 | width: 250px; | ||
185 | } | ||
186 | .sidebar > ul { | ||
187 | height: 100%; | ||
188 | } | ||
189 | </style> |
src/common/Tags.vue
1 | <template> | File was deleted | |
2 | <div class="tags" v-if="showTags"> | ||
3 | <ul> | ||
4 | <li class="tags-li" v-for="(item,index) in tagsList" :class="{'active': isActive(item.path)}" :key="index"> | ||
5 | <router-link :to="item.path" class="tags-li-title"> | ||
6 | {{item.title}} | ||
7 | </router-link> | ||
8 | <span class="tags-li-icon" @click="closeTags(index)"><i class="el-icon-close"></i></span> | ||
9 | </li> | ||
10 | </ul> | ||
11 | <div class="tags-close-box"> | ||
12 | <el-dropdown @command="handleTags"> | ||
13 | <el-button size="mini" type="primary"> | ||
14 | 标签选项<i class="el-icon-arrow-down el-icon--right"></i> | ||
15 | </el-button> | ||
16 | <el-dropdown-menu size="small" slot="dropdown"> | ||
17 | <el-dropdown-item command="other">关闭其他</el-dropdown-item> | ||
18 | <el-dropdown-item command="all">关闭所有</el-dropdown-item> | ||
19 | </el-dropdown-menu> | ||
20 | </el-dropdown> | ||
21 | </div> | ||
22 | </div> | ||
23 | </template> | ||
24 | |||
25 | <script> | ||
26 | import bus from './bus'; | ||
27 | export default { | ||
28 | data() { | ||
29 | return { | ||
30 | tagsList: [] | ||
31 | } | ||
32 | }, | ||
33 | methods: { | ||
34 | isActive(path) { | ||
35 | return path === this.$route.fullPath; | ||
36 | }, | ||
37 | // 关闭单个标签 | ||
38 | closeTags(index) { | ||
39 | const delItem = this.tagsList.splice(index, 1)[0]; | ||
40 | const item = this.tagsList[index] ? this.tagsList[index] : this.tagsList[index - 1]; | ||
41 | if (item) { | ||
42 | delItem.path === this.$route.fullPath && this.$router.push(item.path); | ||
43 | }else{ | ||
44 | this.$router.push('/'); | ||
45 | } | ||
46 | }, | ||
47 | // 关闭全部标签 | ||
48 | closeAll(){ | ||
49 | this.tagsList = []; | ||
50 | this.$router.push('/'); | ||
51 | }, | ||
52 | // 关闭其他标签 | ||
53 | closeOther(){ | ||
54 | const curItem = this.tagsList.filter(item => { | ||
55 | return item.path === this.$route.fullPath; | ||
56 | }) | ||
57 | this.tagsList = curItem; | ||
58 | }, | ||
59 | // 设置标签 | ||
60 | setTags(route){ | ||
61 | const isExist = this.tagsList.some(item => { | ||
62 | return item.path === route.fullPath; | ||
63 | }) | ||
64 | if(!isExist){ | ||
65 | if(this.tagsList.length >= 8){ | ||
66 | this.tagsList.shift(); | ||
67 | } | ||
68 | this.tagsList.push({ | ||
69 | title: route.meta.title, | ||
70 | path: route.fullPath, | ||
71 | name: route.matched[1].components.default.name | ||
72 | }) | ||
73 | } | ||
74 | bus.$emit('tags', this.tagsList); | ||
75 | }, | ||
76 | handleTags(command){ | ||
77 | command === 'other' ? this.closeOther() : this.closeAll(); | ||
78 | } | ||
79 | }, | ||
80 | computed: { | ||
81 | showTags() { | ||
82 | return this.tagsList.length > 0; | ||
83 | } | ||
84 | }, | ||
85 | watch:{ | ||
86 | $route(newValue, oldValue){ | ||
87 | this.setTags(newValue); | ||
88 | } | ||
89 | }, | ||
90 | created(){ | ||
91 | this.setTags(this.$route); | ||
92 | // 监听关闭当前页面的标签页 | ||
93 | bus.$on('close_current_tags', () => { | ||
94 | for (let i = 0, len = this.tagsList.length; i < len; i++) { | ||
95 | const item = this.tagsList[i]; | ||
96 | if(item.path === this.$route.fullPath){ | ||
97 | if(i < len - 1){ | ||
98 | this.$router.push(this.tagsList[i+1].path); | ||
99 | }else if(i > 0){ | ||
100 | this.$router.push(this.tagsList[i-1].path); | ||
101 | }else{ | ||
102 | this.$router.push('/'); | ||
103 | } | ||
104 | this.tagsList.splice(i, 1); | ||
105 | break; | ||
106 | } | ||
107 | } | ||
108 | }) | ||
109 | } | ||
110 | } | ||
111 | </script> | ||
112 | |||
113 | |||
114 | <style> | ||
115 | .tags { | ||
116 | position: relative; | ||
117 | height: 30px; | ||
118 | overflow: hidden; | ||
119 | background: #fff; | ||
120 | padding-right: 120px; | ||
121 | box-shadow: 0 5px 10px #ddd; | ||
122 | } | ||
123 | .tags ul { | ||
124 | box-sizing: border-box; | ||
125 | width: 100%; | ||
126 | height: 100%; | ||
127 | } | ||
128 | .tags-li { | ||
129 | float: left; | ||
130 | margin: 3px 5px 2px 3px; | ||
131 | border-radius: 3px; | ||
132 | font-size: 12px; | ||
133 | overflow: hidden; | ||
134 | cursor: pointer; | ||
135 | height: 23px; | ||
136 | line-height: 23px; | ||
137 | border: 1px solid #e9eaec; | ||
138 | background: #fff; | ||
139 | padding: 0 5px 0 12px; | ||
140 | vertical-align: middle; | ||
141 | color: #666; | ||
142 | -webkit-transition: all .3s ease-in; | ||
143 | -moz-transition: all .3s ease-in; | ||
144 | transition: all .3s ease-in; | ||
145 | } | ||
146 | .tags-li:not(.active):hover { | ||
147 | background: #f8f8f8; | ||
148 | } | ||
149 | .tags-li.active { | ||
150 | color: #fff; | ||
151 | } | ||
152 | .tags-li-title { | ||
153 | float: left; | ||
154 | max-width: 80px; | ||
155 | overflow: hidden; | ||
156 | white-space: nowrap; | ||
157 | text-overflow: ellipsis; | ||
158 | margin-right: 5px; | ||
159 | color: #666; | ||
160 | } | ||
161 | .tags-li.active .tags-li-title { | ||
162 | color: #fff; | ||
163 | } | ||
164 | .tags-close-box { | ||
165 | position: absolute; | ||
166 | right: 0; | ||
167 | top: 0; | ||
168 | box-sizing: border-box; | ||
169 | padding-top: 1px; | ||
170 | text-align: center; | ||
171 | width: 110px; | ||
172 | height: 30px; | ||
173 | background: #fff; | ||
174 | box-shadow: -3px 0 15px 3px rgba(0, 0, 0, .1); | ||
175 | z-index: 10; | ||
176 | } | ||
177 | </style> |
src/common/bus.js
1 | import Vue from 'vue'; | File was deleted | |
2 | |||
3 | // 使用 Event Bus | ||
4 | const bus = new Vue(); | ||
5 | |||
6 | export default bus; | ||
7 | 1 | import Vue from 'vue'; |
src/common/directives.js
1 | import Vue from 'vue'; | File was deleted | |
2 | |||
3 | // v-dialogDrag: 弹窗拖拽属性 | ||
4 | Vue.directive('dialogDrag', { | ||
5 | bind(el, binding, vnode, oldVnode) { | ||
6 | const dialogHeaderEl = el.querySelector('.el-dialog__header'); | ||
7 | const dragDom = el.querySelector('.el-dialog'); | ||
8 | |||
9 | dialogHeaderEl.style.cssText += ';cursor:move;' | ||
10 | dragDom.style.cssText += ';top:0px;' | ||
11 | |||
12 | // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null); | ||
13 | const sty = (() => { | ||
14 | if (window.document.currentStyle) { | ||
15 | return (dom, attr) => dom.currentStyle[attr]; | ||
16 | } else { | ||
17 | return (dom, attr) => getComputedStyle(dom, false)[attr]; | ||
18 | } | ||
19 | })() | ||
20 | |||
21 | dialogHeaderEl.onmousedown = (e) => { | ||
22 | // 鼠标按下,计算当前元素距离可视区的距离 | ||
23 | const disX = e.clientX - dialogHeaderEl.offsetLeft; | ||
24 | const disY = e.clientY - dialogHeaderEl.offsetTop; | ||
25 | |||
26 | const screenWidth = document.body.clientWidth; // body当前宽度 | ||
27 | const screenHeight = document.documentElement.clientHeight; // 可见区域高度(应为body高度,可某些环境下无法获取) | ||
28 | |||
29 | const dragDomWidth = dragDom.offsetWidth; // 对话框宽度 | ||
30 | const dragDomheight = dragDom.offsetHeight; // 对话框高度 | ||
31 | |||
32 | const minDragDomLeft = dragDom.offsetLeft; | ||
33 | const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth; | ||
34 | |||
35 | const minDragDomTop = dragDom.offsetTop; | ||
36 | const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomheight; | ||
37 | |||
38 | |||
39 | // 获取到的值带px 正则匹配替换 | ||
40 | let styL = sty(dragDom, 'left'); | ||
41 | let styT = sty(dragDom, 'top'); | ||
42 | |||
43 | // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px | ||
44 | if (styL.includes('%')) { | ||
45 | styL = +document.body.clientWidth * (+styL.replace(/\%/g, '') / 100); | ||
46 | styT = +document.body.clientHeight * (+styT.replace(/\%/g, '') / 100); | ||
47 | } else { | ||
48 | styL = +styL.replace(/\px/g, ''); | ||
49 | styT = +styT.replace(/\px/g, ''); | ||
50 | }; | ||
51 | |||
52 | document.onmousemove = function (e) { | ||
53 | // 通过事件委托,计算移动的距离 | ||
54 | let left = e.clientX - disX; | ||
55 | let top = e.clientY - disY; | ||
56 | |||
57 | // 边界处理 | ||
58 | if (-(left) > minDragDomLeft) { | ||
59 | left = -(minDragDomLeft); | ||
60 | } else if (left > maxDragDomLeft) { | ||
61 | left = maxDragDomLeft; | ||
62 | } | ||
63 | |||
64 | if (-(top) > minDragDomTop) { | ||
65 | top = -(minDragDomTop); | ||
66 | } else if (top > maxDragDomTop) { | ||
67 | top = maxDragDomTop; | ||
68 | } | ||
69 | |||
70 | // 移动当前元素 | ||
71 | dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;`; | ||
72 | }; | ||
73 | |||
74 | document.onmouseup = function (e) { | ||
75 | document.onmousemove = null; | ||
76 | document.onmouseup = null; | ||
77 | }; | ||
78 | } | ||
79 | } | ||
80 | }) |
src/common/i18n.js
1 | export const messages = { | File was deleted | |
2 | 'zh': { | ||
3 | i18n: { | ||
4 | breadcrumb: '国际化产品', | ||
5 | tips: '通过切换语言按钮,来改变当前内容的语言。', | ||
6 | btn: '切换英文', | ||
7 | title1: '常用用法', | ||
8 | p1: '要是你把你的秘密告诉了风,那就别怪风把它带给树。', | ||
9 | p2: '没有什么比信念更能支撑我们度过艰难的时光了。', | ||
10 | p3: '只要能把自己的事做好,并让自己快乐,你就领先于大多数人了。', | ||
11 | title2: '组件插值', | ||
12 | info: 'Element组件需要国际化,请参考 {action}。', | ||
13 | value: '文档' | ||
14 | } | ||
15 | }, | ||
16 | 'en': { | ||
17 | i18n: { | ||
18 | breadcrumb: 'International Products', | ||
19 | tips: 'Click on the button to change the current language. ', | ||
20 | btn: 'Switch Chinese', | ||
21 | title1: 'Common usage', | ||
22 | p1: "If you reveal your secrets to the wind you should not blame the wind for revealing them to the trees.", | ||
23 | p2: "Nothing can help us endure dark times better than our faith. ", | ||
24 | p3: "If you can do what you do best and be happy, you're further along in life than most people.", | ||
25 | title2: 'Component interpolation', | ||
26 | info: 'The default language of Element is Chinese. If you wish to use another language, please refer to the {action}.', | ||
27 | value: 'documentation' | ||
28 | } | ||
29 | } | ||
30 | } |
src/components/BackToTop/index.vue
File was created | 1 | <template> | |
2 | <transition :name="transitionName"> | ||
3 | <div v-show="visible" :style="customStyle" class="back-to-ceiling" @click="backToTop"> | ||
4 | <svg width="16" height="16" viewBox="0 0 17 17" xmlns="http://www.w3.org/2000/svg" class="Icon Icon--backToTopArrow" aria-hidden="true" style="height:16px;width:16px"><path d="M12.036 15.59a1 1 0 0 1-.997.995H5.032a.996.996 0 0 1-.997-.996V8.584H1.03c-1.1 0-1.36-.633-.578-1.416L7.33.29a1.003 1.003 0 0 1 1.412 0l6.878 6.88c.782.78.523 1.415-.58 1.415h-3.004v7.004z" /></svg> | ||
5 | </div> | ||
6 | </transition> | ||
7 | </template> | ||
8 | |||
9 | <script> | ||
10 | export default { | ||
11 | name: 'BackToTop', | ||
12 | props: { | ||
13 | visibilityHeight: { | ||
14 | type: Number, | ||
15 | default: 400 | ||
16 | }, | ||
17 | backPosition: { | ||
18 | type: Number, | ||
19 | default: 0 | ||
20 | }, | ||
21 | customStyle: { | ||
22 | type: Object, | ||
23 | default: function() { | ||
24 | return { | ||
25 | right: '50px', | ||
26 | bottom: '50px', | ||
27 | width: '40px', | ||
28 | height: '40px', | ||
29 | 'border-radius': '4px', | ||
30 | 'line-height': '45px', | ||
31 | background: '#e7eaf1' | ||
32 | } | ||
33 | } | ||
34 | }, | ||
35 | transitionName: { | ||
36 | type: String, | ||
37 | default: 'fade' | ||
38 | } | ||
39 | }, | ||
40 | data() { | ||
41 | return { | ||
42 | visible: false, | ||
43 | interval: null, | ||
44 | isMoving: false | ||
45 | } | ||
46 | }, | ||
47 | mounted() { | ||
48 | window.addEventListener('scroll', this.handleScroll) | ||
49 | }, | ||
50 | beforeDestroy() { | ||
51 | window.removeEventListener('scroll', this.handleScroll) | ||
52 | if (this.interval) { | ||
53 | clearInterval(this.interval) | ||
54 | } | ||
55 | }, | ||
56 | methods: { | ||
57 | handleScroll() { | ||
58 | this.visible = window.pageYOffset > this.visibilityHeight | ||
59 | }, | ||
60 | backToTop() { | ||
61 | if (this.isMoving) return | ||
62 | const start = window.pageYOffset | ||
63 | let i = 0 | ||
64 | this.isMoving = true | ||
65 | this.interval = setInterval(() => { | ||
66 | const next = Math.floor(this.easeInOutQuad(10 * i, start, -start, 500)) | ||
67 | if (next <= this.backPosition) { | ||
68 | window.scrollTo(0, this.backPosition) | ||
69 | clearInterval(this.interval) | ||
70 | this.isMoving = false | ||
71 | } else { | ||
72 | window.scrollTo(0, next) | ||
73 | } | ||
74 | i++ | ||
75 | }, 16.7) | ||
76 | }, | ||
77 | easeInOutQuad(t, b, c, d) { | ||
78 | if ((t /= d / 2) < 1) return c / 2 * t * t + b | ||
79 | return -c / 2 * (--t * (t - 2) - 1) + b | ||
80 | } | ||
81 | } | ||
82 | } | ||
83 | </script> | ||
84 | |||
85 | <style scoped> | ||
86 | .back-to-ceiling { | ||
87 | position: fixed; | ||
88 | display: inline-block; | ||
89 | text-align: center; | ||
90 | cursor: pointer; | ||
91 | } | ||
92 | |||
93 | .back-to-ceiling:hover { | ||
94 | background: #d5dbe7; | ||
95 | } | ||
96 | |||
97 | .fade-enter-active, | ||
98 | .fade-leave-active { | ||
99 | transition: opacity .5s; | ||
100 | } | ||
101 | |||
102 | .fade-enter, | ||
103 | .fade-leave-to { | ||
104 | opacity: 0 | ||
105 | } | ||
106 | |||
107 | .back-to-ceiling .Icon { | ||
108 | fill: #9aaabf; | ||
109 | background: none; | ||
110 | } | ||
111 | </style> | ||
112 |
src/components/Breadcrumb/index.vue
1 | <template> | 1 | <template> |
2 | <el-breadcrumb class="app-breadcrumb" separator="/"> | 2 | <el-breadcrumb class="app-breadcrumb" separator="/"> |
3 | <transition-group name="breadcrumb"> | 3 | <transition-group name="breadcrumb"> |
4 | <el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path"> | 4 | <el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path"> |
5 | <span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect">{{ item.meta.title }}</span> | 5 | <span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect"> |
6 | <a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a> | 6 | {{ generateTitle(item.meta.title) }} |
7 | </span> | ||
8 | <a v-else @click.prevent="handleLink(item)">{{ generateTitle(item.meta.title) }}</a> | ||
7 | </el-breadcrumb-item> | 9 | </el-breadcrumb-item> |
8 | </transition-group> | 10 | </transition-group> |
9 | </el-breadcrumb> | 11 | </el-breadcrumb> |
10 | </template> | 12 | </template> |
11 | 13 | ||
12 | <script> | 14 | <script> |
15 | import { generateTitle } from '@/utils/i18n' | ||
13 | import pathToRegexp from 'path-to-regexp' | 16 | import pathToRegexp from 'path-to-regexp' |
14 | 17 | ||
15 | export default { | 18 | export default { |
16 | data() { | 19 | data() { |
17 | return { | 20 | return { |
18 | levelList: null | 21 | levelList: null |
19 | } | 22 | } |
20 | }, | 23 | }, |
21 | watch: { | 24 | watch: { |
22 | $route() { | 25 | $route(route) { |
26 | // if you go to the redirect page, do not update the breadcrumbs | ||
27 | if (route.path.startsWith('/redirect/')) { | ||
28 | return | ||
29 | } | ||
23 | this.getBreadcrumb() | 30 | this.getBreadcrumb() |
24 | } | 31 | } |
25 | }, | 32 | }, |
26 | created() { | 33 | created() { |
27 | this.getBreadcrumb() | 34 | this.getBreadcrumb() |
28 | }, | 35 | }, |
29 | methods: { | 36 | methods: { |
37 | generateTitle, | ||
30 | getBreadcrumb() { | 38 | getBreadcrumb() { |
31 | // only show routes with meta.title | 39 | // only show routes with meta.title |
32 | let matched = this.$route.matched.filter(item => item.meta && item.meta.title) | 40 | let matched = this.$route.matched.filter(item => item.meta && item.meta.title) |
33 | const first = matched[0] | 41 | const first = matched[0] |
34 | 42 | ||
35 | if (!this.isDashboard(first)) { | 43 | if (!this.isDashboard(first)) { |
36 | matched = [{ path: '/dashboard', meta: { title: 'Dashboard' }}].concat(matched) | 44 | matched = [{ path: '/dashboard', meta: { title: 'dashboard' }}].concat(matched) |
37 | } | 45 | } |
38 | 46 | ||
39 | this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false) | 47 | this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false) |
40 | }, | 48 | }, |
41 | isDashboard(route) { | 49 | isDashboard(route) { |
42 | const name = route && route.name | 50 | const name = route && route.name |
43 | if (!name) { | 51 | if (!name) { |
44 | return false | 52 | return false |
45 | } | 53 | } |
46 | return name.trim().toLocaleLowerCase() === 'Dashboard'.toLocaleLowerCase() | 54 | return name.trim().toLocaleLowerCase() === 'Dashboard'.toLocaleLowerCase() |
47 | }, | 55 | }, |
48 | pathCompile(path) { | 56 | pathCompile(path) { |
49 | // To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561 | 57 | // To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561 |
50 | const { params } = this.$route | 58 | const { params } = this.$route |
51 | var toPath = pathToRegexp.compile(path) | 59 | var toPath = pathToRegexp.compile(path) |
52 | return toPath(params) | 60 | return toPath(params) |
53 | }, | 61 | }, |
54 | handleLink(item) { | 62 | handleLink(item) { |
55 | const { redirect, path } = item | 63 | const { redirect, path } = item |
56 | if (redirect) { | 64 | if (redirect) { |
57 | this.$router.push(redirect) | 65 | this.$router.push(redirect) |
58 | return | 66 | return |
59 | } | 67 | } |
60 | this.$router.push(this.pathCompile(path)) | 68 | this.$router.push(this.pathCompile(path)) |
61 | } | 69 | } |
62 | } | 70 | } |
63 | } | 71 | } |
64 | </script> | 72 | </script> |
65 | 73 | ||
66 | <style lang="scss" scoped> | 74 | <style lang="scss" scoped> |
67 | .app-breadcrumb.el-breadcrumb { | 75 | .app-breadcrumb.el-breadcrumb { |
68 | display: inline-block; | 76 | display: inline-block; |
69 | font-size: 14px; | 77 | font-size: 14px; |
70 | line-height: 50px; | 78 | line-height: 50px; |
71 | margin-left: 8px; | 79 | margin-left: 8px; |
72 | 80 | ||
73 | .no-redirect { | 81 | .no-redirect { |
74 | color: #97a8be; | 82 | color: #97a8be; |
75 | cursor: text; | 83 | cursor: text; |
76 | } | 84 | } |
77 | } | 85 | } |
78 | </style> | 86 | </style> |
79 | 87 |
src/components/Charts/Keyboard.vue
File was created | 1 | <template> | |
2 | <div :id="id" :class="className" :style="{height:height,width:width}" /> | ||
3 | </template> | ||
4 | |||
5 | <script> | ||
6 | import echarts from 'echarts' | ||
7 | import resize from './mixins/resize' | ||
8 | |||
9 | export default { | ||
10 | mixins: [resize], | ||
11 | props: { | ||
12 | className: { | ||
13 | type: String, | ||
14 | default: 'chart' | ||
15 | }, | ||
16 | id: { | ||
17 | type: String, | ||
18 | default: 'chart' | ||
19 | }, | ||
20 | width: { | ||
21 | type: String, | ||
22 | default: '200px' | ||
23 | }, | ||
24 | height: { | ||
25 | type: String, | ||
26 | default: '200px' | ||
27 | } | ||
28 | }, | ||
29 | data() { | ||
30 | return { | ||
31 | chart: null | ||
32 | } | ||
33 | }, | ||
34 | mounted() { | ||
35 | this.initChart() | ||
36 | }, | ||
37 | beforeDestroy() { | ||
38 | if (!this.chart) { | ||
39 | return | ||
40 | } | ||
41 | this.chart.dispose() | ||
42 | this.chart = null | ||
43 | }, | ||
44 | methods: { | ||
45 | initChart() { | ||
46 | this.chart = echarts.init(document.getElementById(this.id)) | ||
47 | |||
48 | const xAxisData = [] | ||
49 | const data = [] | ||
50 | const data2 = [] | ||
51 | for (let i = 0; i < 50; i++) { | ||
52 | xAxisData.push(i) | ||
53 | data.push((Math.sin(i / 5) * (i / 5 - 10) + i / 6) * 5) | ||
54 | data2.push((Math.sin(i / 5) * (i / 5 + 10) + i / 6) * 3) | ||
55 | } | ||
56 | this.chart.setOption({ | ||
57 | backgroundColor: '#08263a', | ||
58 | grid: { | ||
59 | left: '5%', | ||
60 | right: '5%' | ||
61 | }, | ||
62 | xAxis: [{ | ||
63 | show: false, | ||
64 | data: xAxisData | ||
65 | }, { | ||
66 | show: false, | ||
67 | data: xAxisData | ||
68 | }], | ||
69 | visualMap: { | ||
70 | show: false, | ||
71 | min: 0, | ||
72 | max: 50, | ||
73 | dimension: 0, | ||
74 | inRange: { | ||
75 | color: ['#4a657a', '#308e92', '#b1cfa5', '#f5d69f', '#f5898b', '#ef5055'] | ||
76 | } | ||
77 | }, | ||
78 | yAxis: { | ||
79 | axisLine: { | ||
80 | show: false | ||
81 | }, | ||
82 | axisLabel: { | ||
83 | textStyle: { | ||
84 | color: '#4a657a' | ||
85 | } | ||
86 | }, | ||
87 | splitLine: { | ||
88 | show: true, | ||
89 | lineStyle: { | ||
90 | color: '#08263f' | ||
91 | } | ||
92 | }, | ||
93 | axisTick: { | ||
94 | show: false | ||
95 | } | ||
96 | }, | ||
97 | series: [{ | ||
98 | name: 'back', | ||
99 | type: 'bar', | ||
100 | data: data2, | ||
101 | z: 1, | ||
102 | itemStyle: { | ||
103 | normal: { | ||
104 | opacity: 0.4, | ||
105 | barBorderRadius: 5, | ||
106 | shadowBlur: 3, | ||
107 | shadowColor: '#111' | ||
108 | } | ||
109 | } | ||
110 | }, { | ||
111 | name: 'Simulate Shadow', | ||
112 | type: 'line', | ||
113 | data, | ||
114 | z: 2, | ||
115 | showSymbol: false, | ||
116 | animationDelay: 0, | ||
117 | animationEasing: 'linear', | ||
118 | animationDuration: 1200, | ||
119 | lineStyle: { | ||
120 | normal: { | ||
121 | color: 'transparent' | ||
122 | } | ||
123 | }, | ||
124 | areaStyle: { | ||
125 | normal: { | ||
126 | color: '#08263a', | ||
127 | shadowBlur: 50, | ||
128 | shadowColor: '#000' | ||
129 | } | ||
130 | } | ||
131 | }, { | ||
132 | name: 'front', | ||
133 | type: 'bar', | ||
134 | data, | ||
135 | xAxisIndex: 1, | ||
136 | z: 3, | ||
137 | itemStyle: { | ||
138 | normal: { | ||
139 | barBorderRadius: 5 | ||
140 | } | ||
141 | } | ||
142 | }], | ||
143 | animationEasing: 'elasticOut', | ||
144 | animationEasingUpdate: 'elasticOut', | ||
145 | animationDelay(idx) { | ||
146 | return idx * 20 | ||
147 | }, | ||
148 | animationDelayUpdate(idx) { | ||
149 | return idx * 20 | ||
150 | } | ||
151 | }) | ||
152 | } | ||
153 | } | ||
154 | } | ||
155 | </script> | ||
156 |
src/components/Charts/LineMarker.vue
File was created | 1 | <template> | |
2 | <div :id="id" :class="className" :style="{height:height,width:width}" /> | ||
3 | </template> | ||
4 | |||
5 | <script> | ||
6 | import echarts from 'echarts' | ||
7 | import resize from './mixins/resize' | ||
8 | |||
9 | export default { | ||
10 | mixins: [resize], | ||
11 | props: { | ||
12 | className: { | ||
13 | type: String, | ||
14 | default: 'chart' | ||
15 | }, | ||
16 | id: { | ||
17 | type: String, | ||
18 | default: 'chart' | ||
19 | }, | ||
20 | width: { | ||
21 | type: String, | ||
22 | default: '200px' | ||
23 | }, | ||
24 | height: { | ||
25 | type: String, | ||
26 | default: '200px' | ||
27 | } | ||
28 | }, | ||
29 | data() { | ||
30 | return { | ||
31 | chart: null | ||
32 | } | ||
33 | }, | ||
34 | mounted() { | ||
35 | this.initChart() | ||
36 | }, | ||
37 | beforeDestroy() { | ||
38 | if (!this.chart) { | ||
39 | return | ||
40 | } | ||
41 | this.chart.dispose() | ||
42 | this.chart = null | ||
43 | }, | ||
44 | methods: { | ||
45 | initChart() { | ||
46 | this.chart = echarts.init(document.getElementById(this.id)) | ||
47 | |||
48 | this.chart.setOption({ | ||
49 | backgroundColor: '#394056', | ||
50 | title: { | ||
51 | top: 20, | ||
52 | text: 'Requests', | ||
53 | textStyle: { | ||
54 | fontWeight: 'normal', | ||
55 | fontSize: 16, | ||
56 | color: '#F1F1F3' | ||
57 | }, | ||
58 | left: '1%' | ||
59 | }, | ||
60 | tooltip: { | ||
61 | trigger: 'axis', | ||
62 | axisPointer: { | ||
63 | lineStyle: { | ||
64 | color: '#57617B' | ||
65 | } | ||
66 | } | ||
67 | }, | ||
68 | legend: { | ||
69 | top: 20, | ||
70 | icon: 'rect', | ||
71 | itemWidth: 14, | ||
72 | itemHeight: 5, | ||
73 | itemGap: 13, | ||
74 | data: ['CMCC', 'CTCC', 'CUCC'], | ||
75 | right: '4%', | ||
76 | textStyle: { | ||
77 | fontSize: 12, | ||
78 | color: '#F1F1F3' | ||
79 | } | ||
80 | }, | ||
81 | grid: { | ||
82 | top: 100, | ||
83 | left: '2%', | ||
84 | right: '2%', | ||
85 | bottom: '2%', | ||
86 | containLabel: true | ||
87 | }, | ||
88 | xAxis: [{ | ||
89 | type: 'category', | ||
90 | boundaryGap: false, | ||
91 | axisLine: { | ||
92 | lineStyle: { | ||
93 | color: '#57617B' | ||
94 | } | ||
95 | }, | ||
96 | data: ['13:00', '13:05', '13:10', '13:15', '13:20', '13:25', '13:30', '13:35', '13:40', '13:45', '13:50', '13:55'] | ||
97 | }], | ||
98 | yAxis: [{ | ||
99 | type: 'value', | ||
100 | name: '(%)', | ||
101 | axisTick: { | ||
102 | show: false | ||
103 | }, | ||
104 | axisLine: { | ||
105 | lineStyle: { | ||
106 | color: '#57617B' | ||
107 | } | ||
108 | }, | ||
109 | axisLabel: { | ||
110 | margin: 10, | ||
111 | textStyle: { | ||
112 | fontSize: 14 | ||
113 | } | ||
114 | }, | ||
115 | splitLine: { | ||
116 | lineStyle: { | ||
117 | color: '#57617B' | ||
118 | } | ||
119 | } | ||
120 | }], | ||
121 | series: [{ | ||
122 | name: 'CMCC', | ||
123 | type: 'line', | ||
124 | smooth: true, | ||
125 | symbol: 'circle', | ||
126 | symbolSize: 5, | ||
127 | showSymbol: false, | ||
128 | lineStyle: { | ||
129 | normal: { | ||
130 | width: 1 | ||
131 | } | ||
132 | }, | ||
133 | areaStyle: { | ||
134 | normal: { | ||
135 | color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ | ||
136 | offset: 0, | ||
137 | color: 'rgba(137, 189, 27, 0.3)' | ||
138 | }, { | ||
139 | offset: 0.8, | ||
140 | color: 'rgba(137, 189, 27, 0)' | ||
141 | }], false), | ||
142 | shadowColor: 'rgba(0, 0, 0, 0.1)', | ||
143 | shadowBlur: 10 | ||
144 | } | ||
145 | }, | ||
146 | itemStyle: { | ||
147 | normal: { | ||
148 | color: 'rgb(137,189,27)', | ||
149 | borderColor: 'rgba(137,189,2,0.27)', | ||
150 | borderWidth: 12 | ||
151 | |||
152 | } | ||
153 | }, | ||
154 | data: [220, 182, 191, 134, 150, 120, 110, 125, 145, 122, 165, 122] | ||
155 | }, { | ||
156 | name: 'CTCC', | ||
157 | type: 'line', | ||
158 | smooth: true, | ||
159 | symbol: 'circle', | ||
160 | symbolSize: 5, | ||
161 | showSymbol: false, | ||
162 | lineStyle: { | ||
163 | normal: { | ||
164 | width: 1 | ||
165 | } | ||
166 | }, | ||
167 | areaStyle: { | ||
168 | normal: { | ||
169 | color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ | ||
170 | offset: 0, | ||
171 | color: 'rgba(0, 136, 212, 0.3)' | ||
172 | }, { | ||
173 | offset: 0.8, | ||
174 | color: 'rgba(0, 136, 212, 0)' | ||
175 | }], false), | ||
176 | shadowColor: 'rgba(0, 0, 0, 0.1)', | ||
177 | shadowBlur: 10 | ||
178 | } | ||
179 | }, | ||
180 | itemStyle: { | ||
181 | normal: { | ||
182 | color: 'rgb(0,136,212)', | ||
183 | borderColor: 'rgba(0,136,212,0.2)', | ||
184 | borderWidth: 12 | ||
185 | |||
186 | } | ||
187 | }, | ||
188 | data: [120, 110, 125, 145, 122, 165, 122, 220, 182, 191, 134, 150] | ||
189 | }, { | ||
190 | name: 'CUCC', | ||
191 | type: 'line', | ||
192 | smooth: true, | ||
193 | symbol: 'circle', | ||
194 | symbolSize: 5, | ||
195 | showSymbol: false, | ||
196 | lineStyle: { | ||
197 | normal: { | ||
198 | width: 1 | ||
199 | } | ||
200 | }, | ||
201 | areaStyle: { | ||
202 | normal: { | ||
203 | color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ | ||
204 | offset: 0, | ||
205 | color: 'rgba(219, 50, 51, 0.3)' | ||
206 | }, { | ||
207 | offset: 0.8, | ||
208 | color: 'rgba(219, 50, 51, 0)' | ||
209 | }], false), | ||
210 | shadowColor: 'rgba(0, 0, 0, 0.1)', | ||
211 | shadowBlur: 10 | ||
212 | } | ||
213 | }, | ||
214 | itemStyle: { | ||
215 | normal: { | ||
216 | color: 'rgb(219,50,51)', | ||
217 | borderColor: 'rgba(219,50,51,0.2)', | ||
218 | borderWidth: 12 | ||
219 | } | ||
220 | }, | ||
221 | data: [220, 182, 125, 145, 122, 191, 134, 150, 120, 110, 165, 122] | ||
222 | }] | ||
223 | }) | ||
224 | } | ||
225 | } | ||
226 | } | ||
227 | </script> | ||
228 |
src/components/Charts/MixChart.vue
File was created | 1 | <template> | |
2 | <div :id="id" :class="className" :style="{height:height,width:width}" /> | ||
3 | </template> | ||
4 | |||
5 | <script> | ||
6 | import echarts from 'echarts' | ||
7 | import resize from './mixins/resize' | ||
8 | |||
9 | export default { | ||
10 | mixins: [resize], | ||
11 | props: { | ||
12 | className: { | ||
13 | type: String, | ||
14 | default: 'chart' | ||
15 | }, | ||
16 | id: { | ||
17 | type: String, | ||
18 | default: 'chart' | ||
19 | }, | ||
20 | width: { | ||
21 | type: String, | ||
22 | default: '200px' | ||
23 | }, | ||
24 | height: { | ||
25 | type: String, | ||
26 | default: '200px' | ||
27 | } | ||
28 | }, | ||
29 | data() { | ||
30 | return { | ||
31 | chart: null | ||
32 | } | ||
33 | }, | ||
34 | mounted() { | ||
35 | this.initChart() | ||
36 | }, | ||
37 | beforeDestroy() { | ||
38 | if (!this.chart) { | ||
39 | return | ||
40 | } | ||
41 | this.chart.dispose() | ||
42 | this.chart = null | ||
43 | }, | ||
44 | methods: { | ||
45 | initChart() { | ||
46 | this.chart = echarts.init(document.getElementById(this.id)) | ||
47 | const xData = (function() { | ||
48 | const data = [] | ||
49 | for (let i = 1; i < 13; i++) { | ||
50 | data.push(i + 'month') | ||
51 | } | ||
52 | return data | ||
53 | }()) | ||
54 | this.chart.setOption({ | ||
55 | backgroundColor: '#344b58', | ||
56 | title: { | ||
57 | text: 'statistics', | ||
58 | x: '20', | ||
59 | top: '20', | ||
60 | textStyle: { | ||
61 | color: '#fff', | ||
62 | fontSize: '22' | ||
63 | }, | ||
64 | subtextStyle: { | ||
65 | color: '#90979c', | ||
66 | fontSize: '16' | ||
67 | } | ||
68 | }, | ||
69 | tooltip: { | ||
70 | trigger: 'axis', | ||
71 | axisPointer: { | ||
72 | textStyle: { | ||
73 | color: '#fff' | ||
74 | } | ||
75 | } | ||
76 | }, | ||
77 | grid: { | ||
78 | left: '5%', | ||
79 | right: '5%', | ||
80 | borderWidth: 0, | ||
81 | top: 150, | ||
82 | bottom: 95, | ||
83 | textStyle: { | ||
84 | color: '#fff' | ||
85 | } | ||
86 | }, | ||
87 | legend: { | ||
88 | x: '5%', | ||
89 | top: '10%', | ||
90 | textStyle: { | ||
91 | color: '#90979c' | ||
92 | }, | ||
93 | data: ['female', 'male', 'average'] | ||
94 | }, | ||
95 | calculable: true, | ||
96 | xAxis: [{ | ||
97 | type: 'category', | ||
98 | axisLine: { | ||
99 | lineStyle: { | ||
100 | color: '#90979c' | ||
101 | } | ||
102 | }, | ||
103 | splitLine: { | ||
104 | show: false | ||
105 | }, | ||
106 | axisTick: { | ||
107 | show: false | ||
108 | }, | ||
109 | splitArea: { | ||
110 | show: false | ||
111 | }, | ||
112 | axisLabel: { | ||
113 | interval: 0 | ||
114 | |||
115 | }, | ||
116 | data: xData | ||
117 | }], | ||
118 | yAxis: [{ | ||
119 | type: 'value', | ||
120 | splitLine: { | ||
121 | show: false | ||
122 | }, | ||
123 | axisLine: { | ||
124 | lineStyle: { | ||
125 | color: '#90979c' | ||
126 | } | ||
127 | }, | ||
128 | axisTick: { | ||
129 | show: false | ||
130 | }, | ||
131 | axisLabel: { | ||
132 | interval: 0 | ||
133 | }, | ||
134 | splitArea: { | ||
135 | show: false | ||
136 | } | ||
137 | }], | ||
138 | dataZoom: [{ | ||
139 | show: true, | ||
140 | height: 30, | ||
141 | xAxisIndex: [ | ||
142 | 0 | ||
143 | ], | ||
144 | bottom: 30, | ||
145 | start: 10, | ||
146 | end: 80, | ||
147 | handleIcon: 'path://M306.1,413c0,2.2-1.8,4-4,4h-59.8c-2.2,0-4-1.8-4-4V200.8c0-2.2,1.8-4,4-4h59.8c2.2,0,4,1.8,4,4V413z', | ||
148 | handleSize: '110%', | ||
149 | handleStyle: { | ||
150 | color: '#d3dee5' | ||
151 | |||
152 | }, | ||
153 | textStyle: { | ||
154 | color: '#fff' }, | ||
155 | borderColor: '#90979c' | ||
156 | |||
157 | }, { | ||
158 | type: 'inside', | ||
159 | show: true, | ||
160 | height: 15, | ||
161 | start: 1, | ||
162 | end: 35 | ||
163 | }], | ||
164 | series: [{ | ||
165 | name: 'female', | ||
166 | type: 'bar', | ||
167 | stack: 'total', | ||
168 | barMaxWidth: 35, | ||
169 | barGap: '10%', | ||
170 | itemStyle: { | ||
171 | normal: { | ||
172 | color: 'rgba(255,144,128,1)', | ||
173 | label: { | ||
174 | show: true, | ||
175 | textStyle: { | ||
176 | color: '#fff' | ||
177 | }, | ||
178 | position: 'insideTop', | ||
179 | formatter(p) { | ||
180 | return p.value > 0 ? p.value : '' | ||
181 | } | ||
182 | } | ||
183 | } | ||
184 | }, | ||
185 | data: [ | ||
186 | 709, | ||
187 | 1917, | ||
188 | 2455, | ||
189 | 2610, | ||
190 | 1719, | ||
191 | 1433, | ||
192 | 1544, | ||
193 | 3285, | ||
194 | 5208, | ||
195 | 3372, | ||
196 | 2484, | ||
197 | 4078 | ||
198 | ] | ||
199 | }, | ||
200 | |||
201 | { | ||
202 | name: 'male', | ||
203 | type: 'bar', | ||
204 | stack: 'total', | ||
205 | itemStyle: { | ||
206 | normal: { | ||
207 | color: 'rgba(0,191,183,1)', | ||
208 | barBorderRadius: 0, | ||
209 | label: { | ||
210 | show: true, | ||
211 | position: 'top', | ||
212 | formatter(p) { | ||
213 | return p.value > 0 ? p.value : '' | ||
214 | } | ||
215 | } | ||
216 | } | ||
217 | }, | ||
218 | data: [ | ||
219 | 327, | ||
220 | 1776, | ||
221 | 507, | ||
222 | 1200, | ||
223 | 800, | ||
224 | 482, | ||
225 | 204, | ||
226 | 1390, | ||
227 | 1001, | ||
228 | 951, | ||
229 | 381, | ||
230 | 220 | ||
231 | ] | ||
232 | }, { | ||
233 | name: 'average', | ||
234 | type: 'line', | ||
235 | stack: 'total', | ||
236 | symbolSize: 10, | ||
237 | symbol: 'circle', | ||
238 | itemStyle: { | ||
239 | normal: { | ||
240 | color: 'rgba(252,230,48,1)', | ||
241 | barBorderRadius: 0, | ||
242 | label: { | ||
243 | show: true, | ||
244 | position: 'top', | ||
245 | formatter(p) { | ||
246 | return p.value > 0 ? p.value : '' | ||
247 | } | ||
248 | } | ||
249 | } | ||
250 | }, | ||
251 | data: [ | ||
252 | 1036, | ||
253 | 3693, | ||
254 | 2962, | ||
255 | 3810, | ||
256 | 2519, | ||
257 | 1915, | ||
258 | 1748, | ||
259 | 4675, | ||
260 | 6209, | ||
261 | 4323, | ||
262 | 2865, | ||
263 | 4298 | ||
264 | ] | ||
265 | } | ||
266 | ] | ||
267 | }) | ||
268 | } | ||
269 | } | ||
270 | } | ||
271 | </script> | ||
272 |
src/components/Charts/mixins/resize.js
File was created | 1 | import { debounce } from '@/utils' | |
2 | |||
3 | export default { | ||
4 | data() { | ||
5 | return { | ||
6 | $_sidebarElm: null, | ||
7 | $_resizeHandler: null | ||
8 | } | ||
9 | }, | ||
10 | mounted() { | ||
11 | this.initListener() | ||
12 | }, | ||
13 | activated() { | ||
14 | if (!this.$_resizeHandler) { | ||
15 | // avoid duplication init | ||
16 | this.initListener() | ||
17 | } | ||
18 | |||
19 | // when keep-alive chart activated, auto resize | ||
20 | this.resize() | ||
21 | }, | ||
22 | beforeDestroy() { | ||
23 | this.destroyListener() | ||
24 | }, | ||
25 | deactivated() { | ||
26 | this.destroyListener() | ||
27 | }, | ||
28 | methods: { | ||
29 | // use $_ for mixins properties | ||
30 | // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential | ||
31 | $_sidebarResizeHandler(e) { | ||
32 | if (e.propertyName === 'width') { | ||
33 | this.$_resizeHandler() | ||
34 | } | ||
35 | }, | ||
36 | initListener() { | ||
37 | this.$_resizeHandler = debounce(() => { | ||
38 | this.resize() | ||
39 | }, 100) | ||
40 | window.addEventListener('resize', this.$_resizeHandler) | ||
41 | |||
42 | this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0] | ||
43 | this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler) | ||
44 | }, | ||
45 | destroyListener() { | ||
46 | window.removeEventListener('resize', this.$_resizeHandler) | ||
47 | this.$_resizeHandler = null | ||
48 | |||
49 | this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler) | ||
50 | }, | ||
51 | resize() { | ||
52 | const { chart } = this | ||
53 | chart && chart.resize() | ||
54 | } | ||
55 | } | ||
56 | } | ||
57 |
src/components/DndList/index.vue
File was created | 1 | <template> | |
2 | <div class="dndList"> | ||
3 | <div :style="{width:width1}" class="dndList-list"> | ||
4 | <h3>{{ list1Title }}</h3> | ||
5 | <draggable :set-data="setData" :list="list1" group="article" class="dragArea"> | ||
6 | <div v-for="element in list1" :key="element.id" class="list-complete-item"> | ||
7 | <div class="list-complete-item-handle"> | ||
8 | {{ element.id }}[{{ element.author }}] {{ element.title }} | ||
9 | </div> | ||
10 | <div style="position:absolute;right:0px;"> | ||
11 | <span style="float: right ;margin-top: -20px;margin-right:5px;" @click="deleteEle(element)"> | ||
12 | <i style="color:#ff4949" class="el-icon-delete" /> | ||
13 | </span> | ||
14 | </div> | ||
15 | </div> | ||
16 | </draggable> | ||
17 | </div> | ||
18 | <div :style="{width:width2}" class="dndList-list"> | ||
19 | <h3>{{ list2Title }}</h3> | ||
20 | <draggable :list="list2" group="article" class="dragArea"> | ||
21 | <div v-for="element in list2" :key="element.id" class="list-complete-item"> | ||
22 | <div class="list-complete-item-handle2" @click="pushEle(element)"> | ||
23 | {{ element.id }} [{{ element.author }}] {{ element.title }} | ||
24 | </div> | ||
25 | </div> | ||
26 | </draggable> | ||
27 | </div> | ||
28 | </div> | ||
29 | </template> | ||
30 | |||
31 | <script> | ||
32 | import draggable from 'vuedraggable' | ||
33 | |||
34 | export default { | ||
35 | name: 'DndList', | ||
36 | components: { draggable }, | ||
37 | props: { | ||
38 | list1: { | ||
39 | type: Array, | ||
40 | default() { | ||
41 | return [] | ||
42 | } | ||
43 | }, | ||
44 | list2: { | ||
45 | type: Array, | ||
46 | default() { | ||
47 | return [] | ||
48 | } | ||
49 | }, | ||
50 | list1Title: { | ||
51 | type: String, | ||
52 | default: 'list1' | ||
53 | }, | ||
54 | list2Title: { | ||
55 | type: String, | ||
56 | default: 'list2' | ||
57 | }, | ||
58 | width1: { | ||
59 | type: String, | ||
60 | default: '48%' | ||
61 | }, | ||
62 | width2: { | ||
63 | type: String, | ||
64 | default: '48%' | ||
65 | } | ||
66 | }, | ||
67 | methods: { | ||
68 | isNotInList1(v) { | ||
69 | return this.list1.every(k => v.id !== k.id) | ||
70 | }, | ||
71 | isNotInList2(v) { | ||
72 | return this.list2.every(k => v.id !== k.id) | ||
73 | }, | ||
74 | deleteEle(ele) { | ||
75 | for (const item of this.list1) { | ||
76 | if (item.id === ele.id) { | ||
77 | const index = this.list1.indexOf(item) | ||
78 | this.list1.splice(index, 1) | ||
79 | break | ||
80 | } | ||
81 | } | ||
82 | if (this.isNotInList2(ele)) { | ||
83 | this.list2.unshift(ele) | ||
84 | } | ||
85 | }, | ||
86 | pushEle(ele) { | ||
87 | for (const item of this.list2) { | ||
88 | if (item.id === ele.id) { | ||
89 | const index = this.list2.indexOf(item) | ||
90 | this.list2.splice(index, 1) | ||
91 | break | ||
92 | } | ||
93 | } | ||
94 | if (this.isNotInList1(ele)) { | ||
95 | this.list1.push(ele) | ||
96 | } | ||
97 | }, | ||
98 | setData(dataTransfer) { | ||
99 | // to avoid Firefox bug | ||
100 | // Detail see : https://github.com/RubaXa/Sortable/issues/1012 | ||
101 | dataTransfer.setData('Text', '') | ||
102 | } | ||
103 | } | ||
104 | } | ||
105 | </script> | ||
106 | |||
107 | <style lang="scss" scoped> | ||
108 | .dndList { | ||
109 | background: #fff; | ||
110 | padding-bottom: 40px; | ||
111 | &:after { | ||
112 | content: ""; | ||
113 | display: table; | ||
114 | clear: both; | ||
115 | } | ||
116 | .dndList-list { | ||
117 | float: left; | ||
118 | padding-bottom: 30px; | ||
119 | &:first-of-type { | ||
120 | margin-right: 2%; | ||
121 | } | ||
122 | .dragArea { | ||
123 | margin-top: 15px; | ||
124 | min-height: 50px; | ||
125 | padding-bottom: 30px; | ||
126 | } | ||
127 | } | ||
128 | } | ||
129 | |||
130 | .list-complete-item { | ||
131 | cursor: pointer; | ||
132 | position: relative; | ||
133 | font-size: 14px; | ||
134 | padding: 5px 12px; | ||
135 | margin-top: 4px; | ||
136 | border: 1px solid #bfcbd9; | ||
137 | transition: all 1s; | ||
138 | } | ||
139 | |||
140 | .list-complete-item-handle { | ||
141 | overflow: hidden; | ||
142 | text-overflow: ellipsis; | ||
143 | white-space: nowrap; | ||
144 | margin-right: 50px; | ||
145 | } | ||
146 | |||
147 | .list-complete-item-handle2 { | ||
148 | overflow: hidden; | ||
149 | text-overflow: ellipsis; | ||
150 | white-space: nowrap; | ||
151 | margin-right: 20px; | ||
152 | } | ||
153 | |||
154 | .list-complete-item.sortable-chosen { | ||
155 | background: #4AB7BD; | ||
156 | } | ||
157 | |||
158 | .list-complete-item.sortable-ghost { | ||
159 | background: #30B08F; | ||
160 | } | ||
161 | |||
162 | .list-complete-enter, | ||
163 | .list-complete-leave-active { | ||
164 | opacity: 0; | ||
165 | } | ||
166 | </style> | ||
167 |
src/components/DragSelect/index.vue
File was created | 1 | <template> | |
2 | <el-select ref="dragSelect" v-model="selectVal" v-bind="$attrs" class="drag-select" multiple v-on="$listeners"> | ||
3 | <slot /> | ||
4 | </el-select> | ||
5 | </template> | ||
6 | |||
7 | <script> | ||
8 | import Sortable from 'sortablejs' | ||
9 | |||
10 | export default { | ||
11 | name: 'DragSelect', | ||
12 | props: { | ||
13 | value: { | ||
14 | type: Array, | ||
15 | required: true | ||
16 | } | ||
17 | }, | ||
18 | computed: { | ||
19 | selectVal: { | ||
20 | get() { | ||
21 | return [...this.value] | ||
22 | }, | ||
23 | set(val) { | ||
24 | this.$emit('input', [...val]) | ||
25 | } | ||
26 | } | ||
27 | }, | ||
28 | mounted() { | ||
29 | this.setSort() | ||
30 | }, | ||
31 | methods: { | ||
32 | setSort() { | ||
33 | const el = this.$refs.dragSelect.$el.querySelectorAll('.el-select__tags > span')[0] | ||
34 | this.sortable = Sortable.create(el, { | ||
35 | ghostClass: 'sortable-ghost', // Class name for the drop placeholder, | ||
36 | setData: function(dataTransfer) { | ||
37 | dataTransfer.setData('Text', '') | ||
38 | // to avoid Firefox bug | ||
39 | // Detail see : https://github.com/RubaXa/Sortable/issues/1012 | ||
40 | }, | ||
41 | onEnd: evt => { | ||
42 | const targetRow = this.value.splice(evt.oldIndex, 1)[0] | ||
43 | this.value.splice(evt.newIndex, 0, targetRow) | ||
44 | } | ||
45 | }) | ||
46 | } | ||
47 | } | ||
48 | } | ||
49 | </script> | ||
50 | |||
51 | <style scoped> | ||
52 | .drag-select >>> .sortable-ghost { | ||
53 | opacity: .8; | ||
54 | color: #fff!important; | ||
55 | background: #42b983!important; | ||
56 | } | ||
57 | |||
58 | .drag-select >>> .el-tag { | ||
59 | cursor: pointer; | ||
60 | } | ||
61 | </style> | ||
62 |
src/components/Dropzone/index.vue
File was created | 1 | <template> | |
2 | <div :id="id" :ref="id" :action="url" class="dropzone"> | ||
3 | <input type="file" name="file"> | ||
4 | </div> | ||
5 | </template> | ||
6 | |||
7 | <script> | ||
8 | import Dropzone from 'dropzone' | ||
9 | import 'dropzone/dist/dropzone.css' | ||
10 | // import { getToken } from 'api/qiniu'; | ||
11 | |||
12 | Dropzone.autoDiscover = false | ||
13 | |||
14 | export default { | ||
15 | props: { | ||
16 | id: { | ||
17 | type: String, | ||
18 | required: true | ||
19 | }, | ||
20 | url: { | ||
21 | type: String, | ||
22 | required: true | ||
23 | }, | ||
24 | clickable: { | ||
25 | type: Boolean, | ||
26 | default: true | ||
27 | }, | ||
28 | defaultMsg: { | ||
29 | type: String, | ||
30 | default: '上传图片' | ||
31 | }, | ||
32 | acceptedFiles: { | ||
33 | type: String, | ||
34 | default: '' | ||
35 | }, | ||
36 | thumbnailHeight: { | ||
37 | type: Number, | ||
38 | default: 200 | ||
39 | }, | ||
40 | thumbnailWidth: { | ||
41 | type: Number, | ||
42 | default: 200 | ||
43 | }, | ||
44 | showRemoveLink: { | ||
45 | type: Boolean, | ||
46 | default: true | ||
47 | }, | ||
48 | maxFilesize: { | ||
49 | type: Number, | ||
50 | default: 2 | ||
51 | }, | ||
52 | maxFiles: { | ||
53 | type: Number, | ||
54 | default: 3 | ||
55 | }, | ||
56 | autoProcessQueue: { | ||
57 | type: Boolean, | ||
58 | default: true | ||
59 | }, | ||
60 | useCustomDropzoneOptions: { | ||
61 | type: Boolean, | ||
62 | default: false | ||
63 | }, | ||
64 | defaultImg: { | ||
65 | default: '', | ||
66 | type: [String, Array] | ||
67 | }, | ||
68 | couldPaste: { | ||
69 | type: Boolean, | ||
70 | default: false | ||
71 | } | ||
72 | }, | ||
73 | data() { | ||
74 | return { | ||
75 | dropzone: '', | ||
76 | initOnce: true | ||
77 | } | ||
78 | }, | ||
79 | watch: { | ||
80 | defaultImg(val) { | ||
81 | if (val.length === 0) { | ||
82 | this.initOnce = false | ||
83 | return | ||
84 | } | ||
85 | if (!this.initOnce) return | ||
86 | this.initImages(val) | ||
87 | this.initOnce = false | ||
88 | } | ||
89 | }, | ||
90 | mounted() { | ||
91 | const element = document.getElementById(this.id) | ||
92 | const vm = this | ||
93 | this.dropzone = new Dropzone(element, { | ||
94 | clickable: this.clickable, | ||
95 | thumbnailWidth: this.thumbnailWidth, | ||
96 | thumbnailHeight: this.thumbnailHeight, | ||
97 | maxFiles: this.maxFiles, | ||
98 | maxFilesize: this.maxFilesize, | ||
99 | dictRemoveFile: 'Remove', | ||
100 | addRemoveLinks: this.showRemoveLink, | ||
101 | acceptedFiles: this.acceptedFiles, | ||
102 | autoProcessQueue: this.autoProcessQueue, | ||
103 | dictDefaultMessage: '<i style="margin-top: 3em;display: inline-block" class="material-icons">' + this.defaultMsg + '</i><br>Drop files here to upload', | ||
104 | dictMaxFilesExceeded: '只能一个图', | ||
105 | previewTemplate: '<div class="dz-preview dz-file-preview"> <div class="dz-image" style="width:' + this.thumbnailWidth + 'px;height:' + this.thumbnailHeight + 'px" ><img style="width:' + this.thumbnailWidth + 'px;height:' + this.thumbnailHeight + 'px" data-dz-thumbnail /></div> <div class="dz-details"><div class="dz-size"><span data-dz-size></span></div> <div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div> <div class="dz-error-message"><span data-dz-errormessage></span></div> <div class="dz-success-mark"> <i class="material-icons">done</i> </div> <div class="dz-error-mark"><i class="material-icons">error</i></div></div>', | ||
106 | init() { | ||
107 | const val = vm.defaultImg | ||
108 | if (!val) return | ||
109 | if (Array.isArray(val)) { | ||
110 | if (val.length === 0) return | ||
111 | val.map((v, i) => { | ||
112 | const mockFile = { name: 'name' + i, size: 12345, url: v } | ||
113 | this.options.addedfile.call(this, mockFile) | ||
114 | this.options.thumbnail.call(this, mockFile, v) | ||
115 | mockFile.previewElement.classList.add('dz-success') | ||
116 | mockFile.previewElement.classList.add('dz-complete') | ||
117 | vm.initOnce = false | ||
118 | return true | ||
119 | }) | ||
120 | } else { | ||
121 | const mockFile = { name: 'name', size: 12345, url: val } | ||
122 | this.options.addedfile.call(this, mockFile) | ||
123 | this.options.thumbnail.call(this, mockFile, val) | ||
124 | mockFile.previewElement.classList.add('dz-success') | ||
125 | mockFile.previewElement.classList.add('dz-complete') | ||
126 | vm.initOnce = false | ||
127 | } | ||
128 | }, | ||
129 | accept: (file, done) => { | ||
130 | /* 七牛*/ | ||
131 | // const token = this.$store.getters.token; | ||
132 | // getToken(token).then(response => { | ||
133 | // file.token = response.data.qiniu_token; | ||
134 | // file.key = response.data.qiniu_key; | ||
135 | // file.url = response.data.qiniu_url; | ||
136 | // done(); | ||
137 | // }) | ||
138 | done() | ||
139 | }, | ||
140 | sending: (file, xhr, formData) => { | ||
141 | // formData.append('token', file.token); | ||
142 | // formData.append('key', file.key); | ||
143 | vm.initOnce = false | ||
144 | } | ||
145 | }) | ||
146 | |||
147 | if (this.couldPaste) { | ||
148 | document.addEventListener('paste', this.pasteImg) | ||
149 | } | ||
150 | |||
151 | this.dropzone.on('success', file => { | ||
152 | vm.$emit('dropzone-success', file, vm.dropzone.element) | ||
153 | }) | ||
154 | this.dropzone.on('addedfile', file => { | ||
155 | vm.$emit('dropzone-fileAdded', file) | ||
156 | }) | ||
157 | this.dropzone.on('removedfile', file => { | ||
158 | vm.$emit('dropzone-removedFile', file) | ||
159 | }) | ||
160 | this.dropzone.on('error', (file, error, xhr) => { | ||
161 | vm.$emit('dropzone-error', file, error, xhr) | ||
162 | }) | ||
163 | this.dropzone.on('successmultiple', (file, error, xhr) => { | ||
164 | vm.$emit('dropzone-successmultiple', file, error, xhr) | ||
165 | }) | ||
166 | }, | ||
167 | destroyed() { | ||
168 | document.removeEventListener('paste', this.pasteImg) | ||
169 | this.dropzone.destroy() | ||
170 | }, | ||
171 | methods: { | ||
172 | removeAllFiles() { | ||
173 | this.dropzone.removeAllFiles(true) | ||
174 | }, | ||
175 | processQueue() { | ||
176 | this.dropzone.processQueue() | ||
177 | }, | ||
178 | pasteImg(event) { | ||
179 | const items = (event.clipboardData || event.originalEvent.clipboardData).items | ||
180 | if (items[0].kind === 'file') { | ||
181 | this.dropzone.addFile(items[0].getAsFile()) | ||
182 | } | ||
183 | }, | ||
184 | initImages(val) { | ||
185 | if (!val) return | ||
186 | if (Array.isArray(val)) { | ||
187 | val.map((v, i) => { | ||
188 | const mockFile = { name: 'name' + i, size: 12345, url: v } | ||
189 | this.dropzone.options.addedfile.call(this.dropzone, mockFile) | ||
190 | this.dropzone.options.thumbnail.call(this.dropzone, mockFile, v) | ||
191 | mockFile.previewElement.classList.add('dz-success') | ||
192 | mockFile.previewElement.classList.add('dz-complete') | ||
193 | return true | ||
194 | }) | ||
195 | } else { | ||
196 | const mockFile = { name: 'name', size: 12345, url: val } | ||
197 | this.dropzone.options.addedfile.call(this.dropzone, mockFile) | ||
198 | this.dropzone.options.thumbnail.call(this.dropzone, mockFile, val) | ||
199 | mockFile.previewElement.classList.add('dz-success') | ||
200 | mockFile.previewElement.classList.add('dz-complete') | ||
201 | } | ||
202 | } | ||
203 | |||
204 | } | ||
205 | } | ||
206 | </script> | ||
207 | |||
208 | <style scoped> | ||
209 | .dropzone { | ||
210 | border: 2px solid #E5E5E5; | ||
211 | font-family: 'Roboto', sans-serif; | ||
212 | color: #777; | ||
213 | transition: background-color .2s linear; | ||
214 | padding: 5px; | ||
215 | } | ||
216 | |||
217 | .dropzone:hover { | ||
218 | background-color: #F6F6F6; | ||
219 | } | ||
220 | |||
221 | i { | ||
222 | color: #CCC; | ||
223 | } | ||
224 | |||
225 | .dropzone .dz-image img { | ||
226 | width: 100%; | ||
227 | height: 100%; | ||
228 | } | ||
229 | |||
230 | .dropzone input[name='file'] { | ||
231 | display: none; | ||
232 | } | ||
233 | |||
234 | .dropzone .dz-preview .dz-image { | ||
235 | border-radius: 0px; | ||
236 | } | ||
237 | |||
238 | .dropzone .dz-preview:hover .dz-image img { | ||
239 | transform: none; | ||
240 | filter: none; | ||
241 | width: 100%; | ||
242 | height: 100%; | ||
243 | } | ||
244 | |||
245 | .dropzone .dz-preview .dz-details { | ||
246 | bottom: 0px; | ||
247 | top: 0px; | ||
248 | color: white; | ||
249 | background-color: rgba(33, 150, 243, 0.8); | ||
250 | transition: opacity .2s linear; | ||
251 | text-align: left; | ||
252 | } | ||
253 | |||
254 | .dropzone .dz-preview .dz-details .dz-filename span, .dropzone .dz-preview .dz-details .dz-size span { | ||
255 | background-color: transparent; | ||
256 | } | ||
257 | |||
258 | .dropzone .dz-preview .dz-details .dz-filename:not(:hover) span { | ||
259 | border: none; | ||
260 | } | ||
261 | |||
262 | .dropzone .dz-preview .dz-details .dz-filename:hover span { | ||
263 | background-color: transparent; | ||
264 | border: none; | ||
265 | } | ||
266 | |||
267 | .dropzone .dz-preview .dz-remove { | ||
268 | position: absolute; | ||
269 | z-index: 30; | ||
270 | color: white; | ||
271 | margin-left: 15px; | ||
272 | padding: 10px; | ||
273 | top: inherit; | ||
274 | bottom: 15px; | ||
275 | border: 2px white solid; | ||
276 | text-decoration: none; | ||
277 | text-transform: uppercase; | ||
278 | font-size: 0.8rem; | ||
279 | font-weight: 800; | ||
280 | letter-spacing: 1.1px; | ||
281 | opacity: 0; | ||
282 | } | ||
283 | |||
284 | .dropzone .dz-preview:hover .dz-remove { | ||
285 | opacity: 1; | ||
286 | } | ||
287 | |||
288 | .dropzone .dz-preview .dz-success-mark, .dropzone .dz-preview .dz-error-mark { | ||
289 | margin-left: -40px; | ||
290 | margin-top: -50px; | ||
291 | } | ||
292 | |||
293 | .dropzone .dz-preview .dz-success-mark i, .dropzone .dz-preview .dz-error-mark i { | ||
294 | color: white; | ||
295 | font-size: 5rem; | ||
296 | } | ||
297 | </style> | ||
298 |
src/components/ErrorLog/index.vue
File was created | 1 | <template> | |
2 | <div v-if="errorLogs.length>0"> | ||
3 | <el-badge :is-dot="true" style="line-height: 25px;margin-top: -5px;" @click.native="dialogTableVisible=true"> | ||
4 | <el-button style="padding: 8px 10px;" size="small" type="danger"> | ||
5 | <svg-icon icon-class="bug" /> | ||
6 | </el-button> | ||
7 | </el-badge> | ||
8 | |||
9 | <el-dialog :visible.sync="dialogTableVisible" width="80%" append-to-body> | ||
10 | <div slot="title"> | ||
11 | <span style="padding-right: 10px;">Error Log</span> | ||
12 | <el-button size="mini" type="primary" icon="el-icon-delete" @click="clearAll">Clear All</el-button> | ||
13 | </div> | ||
14 | <el-table :data="errorLogs" border> | ||
15 | <el-table-column label="Message"> | ||
16 | <template slot-scope="{row}"> | ||
17 | <div> | ||
18 | <span class="message-title">Msg:</span> | ||
19 | <el-tag type="danger"> | ||
20 | {{ row.err.message }} | ||
21 | </el-tag> | ||
22 | </div> | ||
23 | <br> | ||
24 | <div> | ||
25 | <span class="message-title" style="padding-right: 10px;">Info: </span> | ||
26 | <el-tag type="warning"> | ||
27 | {{ row.vm.$vnode.tag }} error in {{ row.info }} | ||
28 | </el-tag> | ||
29 | </div> | ||
30 | <br> | ||
31 | <div> | ||
32 | <span class="message-title" style="padding-right: 16px;">Url: </span> | ||
33 | <el-tag type="success"> | ||
34 | {{ row.url }} | ||
35 | </el-tag> | ||
36 | </div> | ||
37 | </template> | ||
38 | </el-table-column> | ||
39 | <el-table-column label="Stack"> | ||
40 | <template slot-scope="scope"> | ||
41 | {{ scope.row.err.stack }} | ||
42 | </template> | ||
43 | </el-table-column> | ||
44 | </el-table> | ||
45 | </el-dialog> | ||
46 | </div> | ||
47 | </template> | ||
48 | |||
49 | <script> | ||
50 | export default { | ||
51 | name: 'ErrorLog', | ||
52 | data() { | ||
53 | return { | ||
54 | dialogTableVisible: false | ||
55 | } | ||
56 | }, | ||
57 | computed: { | ||
58 | errorLogs() { | ||
59 | return this.$store.getters.errorLogs | ||
60 | } | ||
61 | }, | ||
62 | methods: { | ||
63 | clearAll() { | ||
64 | this.dialogTableVisible = false | ||
65 | this.$store.dispatch('errorLog/clearErrorLog') | ||
66 | } | ||
67 | } | ||
68 | } | ||
69 | </script> | ||
70 | |||
71 | <style scoped> | ||
72 | .message-title { | ||
73 | font-size: 16px; | ||
74 | color: #333; | ||
75 | font-weight: bold; | ||
76 | padding-right: 8px; | ||
77 | } | ||
78 | </style> | ||
79 |
src/components/GithubCorner/index.vue
File was created | 1 | <template> | |
2 | <a href="https://github.com/PanJiaChen/vue-element-admin" target="_blank" class="github-corner" aria-label="View source on Github"> | ||
3 | <svg | ||
4 | width="80" | ||
5 | height="80" | ||
6 | viewBox="0 0 250 250" | ||
7 | style="fill:#40c9c6; color:#fff;" | ||
8 | aria-hidden="true" | ||
9 | > | ||
10 | <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z" /> | ||
11 | <path | ||
12 | d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" | ||
13 | fill="currentColor" | ||
14 | style="transform-origin: 130px 106px;" | ||
15 | class="octo-arm" | ||
16 | /> | ||
17 | <path | ||
18 | d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" | ||
19 | fill="currentColor" | ||
20 | class="octo-body" | ||
21 | /> | ||
22 | </svg> | ||
23 | </a> | ||
24 | </template> | ||
25 | |||
26 | <style scoped> | ||
27 | .github-corner:hover .octo-arm { | ||
28 | animation: octocat-wave 560ms ease-in-out | ||
29 | } | ||
30 | |||
31 | @keyframes octocat-wave { | ||
32 | 0%, | ||
33 | 100% { | ||
34 | transform: rotate(0) | ||
35 | } | ||
36 | 20%, | ||
37 | 60% { | ||
38 | transform: rotate(-25deg) | ||
39 | } | ||
40 | 40%, | ||
41 | 80% { | ||
42 | transform: rotate(10deg) | ||
43 | } | ||
44 | } | ||
45 | |||
46 | @media (max-width:500px) { | ||
47 | .github-corner:hover .octo-arm { | ||
48 | animation: none | ||
49 | } | ||
50 | .github-corner .octo-arm { | ||
51 | animation: octocat-wave 560ms ease-in-out | ||
52 | } | ||
53 | } | ||
54 | </style> | ||
55 |
1 | <template> | 1 | <template> |
2 | <div style="padding: 0 15px;" @click="toggleClick"> | 2 | <div style="padding: 0 15px;" @click="toggleClick"> |
3 | <svg | 3 | <svg |
4 | :class="{'is-active':isActive}" | 4 | :class="{'is-active':isActive}" |
5 | class="hamburger" | 5 | class="hamburger" |
6 | viewBox="0 0 1024 1024" | 6 | viewBox="0 0 1024 1024" |
7 | xmlns="http://www.w3.org/2000/svg" | 7 | xmlns="http://www.w3.org/2000/svg" |
8 | width="64" | 8 | width="64" |
9 | height="64" | 9 | height="64" |
10 | > | 10 | > |
11 | <path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" /> | 11 | <path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" /> |
12 | </svg> | 12 | </svg> |
13 | </div> | 13 | </div> |
14 | </template> | 14 | </template> |
15 | 15 | ||
16 | <script> | 16 | <script> |
17 | export default { | 17 | export default { |
18 | name: 'Hamburger', | 18 | name: 'Hamburger', |
19 | props: { | 19 | props: { |
20 | isActive: { | 20 | isActive: { |
21 | type: Boolean, | 21 | type: Boolean, |
22 | default: false | 22 | default: false |
23 | } | 23 | } |
24 | }, | 24 | }, |
25 | methods: { | 25 | methods: { |
26 | toggleClick() { | 26 | toggleClick() { |
27 | this.$emit('toggleClick') | 27 | this.$emit('toggleClick') |
28 | } | 28 | } |
29 | } | 29 | } |
30 | } | 30 | } |
31 | </script> | 31 | </script> |
32 | 32 | ||
33 | <style scoped> | 33 | <style scoped> |
34 | .hamburger { | 34 | .hamburger { |
35 | display: inline-block; | 35 | display: inline-block; |
36 | vertical-align: middle; | 36 | vertical-align: middle; |
37 | width: 20px; | 37 | width: 20px; |
38 | height: 20px; | 38 | height: 20px; |
39 | } | 39 | } |
40 | 40 | ||
41 | .hamburger.is-active { | 41 | .hamburger.is-active { |
42 | transform: rotate(180deg); | 42 | transform: rotate(180deg); |
43 | } | 43 | } |
44 | </style> | 44 | </style> |
45 | 45 |
src/components/HeaderSearch/index.vue
File was created | 1 | <template> | |
2 | <div :class="{'show':show}" class="header-search"> | ||
3 | <svg-icon class-name="search-icon" icon-class="search" @click.stop="click" /> | ||
4 | <el-select | ||
5 | ref="headerSearchSelect" | ||
6 | v-model="search" | ||
7 | :remote-method="querySearch" | ||
8 | filterable | ||
9 | default-first-option | ||
10 | remote | ||
11 | placeholder="Search" | ||
12 | class="header-search-select" | ||
13 | @change="change" | ||
14 | > | ||
15 | <el-option v-for="item in options" :key="item.path" :value="item" :label="item.title.join(' > ')" /> | ||
16 | </el-select> | ||
17 | </div> | ||
18 | </template> | ||
19 | |||
20 | <script> | ||
21 | // fuse is a lightweight fuzzy-search module | ||
22 | // make search results more in line with expectations | ||
23 | import Fuse from 'fuse.js' | ||
24 | import path from 'path' | ||
25 | import i18n from '@/lang' | ||
26 | |||
27 | export default { | ||
28 | name: 'HeaderSearch', | ||
29 | data() { | ||
30 | return { | ||
31 | search: '', | ||
32 | options: [], | ||
33 | searchPool: [], | ||
34 | show: false, | ||
35 | fuse: undefined | ||
36 | } | ||
37 | }, | ||
38 | computed: { | ||
39 | routes() { | ||
40 | return this.$store.getters.permission_routes | ||
41 | }, | ||
42 | lang() { | ||
43 | return this.$store.getters.language | ||
44 | }, | ||
45 | supportPinyinSearch() { | ||
46 | return this.$store.state.settings.supportPinyinSearch | ||
47 | } | ||
48 | }, | ||
49 | watch: { | ||
50 | lang() { | ||
51 | this.searchPool = this.generateRoutes(this.routes) | ||
52 | }, | ||
53 | routes() { | ||
54 | this.searchPool = this.generateRoutes(this.routes) | ||
55 | }, | ||
56 | searchPool(list) { | ||
57 | // Support pinyin search | ||
58 | if (this.lang === 'zh' && this.supportPinyinSearch) { | ||
59 | this.addPinyinField(list) | ||
60 | } | ||
61 | this.initFuse(list) | ||
62 | }, | ||
63 | show(value) { | ||
64 | if (value) { | ||
65 | document.body.addEventListener('click', this.close) | ||
66 | } else { | ||
67 | document.body.removeEventListener('click', this.close) | ||
68 | } | ||
69 | } | ||
70 | }, | ||
71 | mounted() { | ||
72 | this.searchPool = this.generateRoutes(this.routes) | ||
73 | }, | ||
74 | methods: { | ||
75 | async addPinyinField(list) { | ||
76 | const { default: pinyin } = await import('pinyin') | ||
77 | if (Array.isArray(list)) { | ||
78 | list.forEach(element => { | ||
79 | const title = element.title | ||
80 | if (Array.isArray(title)) { | ||
81 | title.forEach(v => { | ||
82 | v = pinyin(v, { | ||
83 | style: pinyin.STYLE_NORMAL | ||
84 | }).join('') | ||
85 | element.pinyinTitle = v | ||
86 | }) | ||
87 | } | ||
88 | }) | ||
89 | return list | ||
90 | } | ||
91 | }, | ||
92 | click() { | ||
93 | this.show = !this.show | ||
94 | if (this.show) { | ||
95 | this.$refs.headerSearchSelect && this.$refs.headerSearchSelect.focus() | ||
96 | } | ||
97 | }, | ||
98 | close() { | ||
99 | this.$refs.headerSearchSelect && this.$refs.headerSearchSelect.blur() | ||
100 | this.options = [] | ||
101 | this.show = false | ||
102 | }, | ||
103 | change(val) { | ||
104 | this.$router.push(val.path) | ||
105 | this.search = '' | ||
106 | this.options = [] | ||
107 | this.$nextTick(() => { | ||
108 | this.show = false | ||
109 | }) | ||
110 | }, | ||
111 | initFuse(list) { | ||
112 | this.fuse = new Fuse(list, { | ||
113 | shouldSort: true, | ||
114 | threshold: 0.4, | ||
115 | location: 0, | ||
116 | distance: 100, | ||
117 | maxPatternLength: 32, | ||
118 | minMatchCharLength: 1, | ||
119 | keys: [{ | ||
120 | name: 'title', | ||
121 | weight: 0.7 | ||
122 | }, { | ||
123 | name: 'pinyinTitle', | ||
124 | weight: 0.3 | ||
125 | }, { | ||
126 | name: 'path', | ||
127 | weight: 0.3 | ||
128 | }] | ||
129 | }) | ||
130 | }, | ||
131 | // Filter out the routes that can be displayed in the sidebar | ||
132 | // And generate the internationalized title | ||
133 | generateRoutes(routes, basePath = '/', prefixTitle = []) { | ||
134 | let res = [] | ||
135 | for (const router of routes) { | ||
136 | // skip hidden router | ||
137 | if (router.hidden) { continue } | ||
138 | const data = { | ||
139 | path: path.resolve(basePath, router.path), | ||
140 | title: [...prefixTitle] | ||
141 | } | ||
142 | if (router.meta && router.meta.title) { | ||
143 | // generate internationalized title | ||
144 | const i18ntitle = i18n.t(`route.${router.meta.title}`) | ||
145 | data.title = [...data.title, i18ntitle] | ||
146 | if (router.redirect !== 'noRedirect') { | ||
147 | // only push the routes with title | ||
148 | // special case: need to exclude parent router without redirect | ||
149 | res.push(data) | ||
150 | } | ||
151 | } | ||
152 | // recursive child routes | ||
153 | if (router.children) { | ||
154 | const tempRoutes = this.generateRoutes(router.children, data.path, data.title) | ||
155 | if (tempRoutes.length >= 1) { | ||
156 | res = [...res, ...tempRoutes] | ||
157 | } | ||
158 | } | ||
159 | } | ||
160 | return res | ||
161 | }, | ||
162 | querySearch(query) { | ||
163 | if (query !== '') { | ||
164 | this.options = this.fuse.search(query) | ||
165 | } else { | ||
166 | this.options = [] | ||
167 | } | ||
168 | } | ||
169 | } | ||
170 | } | ||
171 | </script> | ||
172 | |||
173 | <style lang="scss" scoped> | ||
174 | .header-search { | ||
175 | font-size: 0 !important; | ||
176 | .search-icon { | ||
177 | cursor: pointer; | ||
178 | font-size: 18px; | ||
179 | vertical-align: middle; | ||
180 | } | ||
181 | .header-search-select { | ||
182 | font-size: 18px; | ||
183 | transition: width 0.2s; | ||
184 | width: 0; | ||
185 | overflow: hidden; | ||
186 | background: transparent; | ||
187 | border-radius: 0; | ||
188 | display: inline-block; | ||
189 | vertical-align: middle; | ||
190 | /deep/ .el-input__inner { | ||
191 | border-radius: 0; | ||
192 | border: 0; | ||
193 | padding-left: 0; | ||
194 | padding-right: 0; | ||
195 | box-shadow: none !important; | ||
196 | border-bottom: 1px solid #d9d9d9; | ||
197 | vertical-align: middle; | ||
198 | } | ||
199 | } | ||
200 | &.show { | ||
201 | .header-search-select { | ||
202 | width: 210px; | ||
203 | margin-left: 10px; | ||
204 | } | ||
205 | } | ||
206 | } | ||
207 | </style> | ||
208 |
src/components/ImageCropper/index.vue
File was created | 1 | <template> | |
2 | <div v-show="value" class="vue-image-crop-upload"> | ||
3 | <div class="vicp-wrap"> | ||
4 | <div class="vicp-close" @click="off"> | ||
5 | <i class="vicp-icon4" /> | ||
6 | </div> | ||
7 | |||
8 | <div v-show="step == 1" class="vicp-step1"> | ||
9 | <div | ||
10 | class="vicp-drop-area" | ||
11 | @dragleave="preventDefault" | ||
12 | @dragover="preventDefault" | ||
13 | @dragenter="preventDefault" | ||
14 | @click="handleClick" | ||
15 | @drop="handleChange" | ||
16 | > | ||
17 | <i v-show="loading != 1" class="vicp-icon1"> | ||
18 | <i class="vicp-icon1-arrow" /> | ||
19 | <i class="vicp-icon1-body" /> | ||
20 | <i class="vicp-icon1-bottom" /> | ||
21 | </i> | ||
22 | <span v-show="loading !== 1" class="vicp-hint">{{ lang.hint }}</span> | ||
23 | <span v-show="!isSupported" class="vicp-no-supported-hint">{{ lang.noSupported }}</span> | ||
24 | <input v-show="false" v-if="step == 1" ref="fileinput" type="file" @change="handleChange"> | ||
25 | </div> | ||
26 | <div v-show="hasError" class="vicp-error"> | ||
27 | <i class="vicp-icon2" /> | ||
28 | {{ errorMsg }} | ||
29 | </div> | ||
30 | <div class="vicp-operate"> | ||
31 | <a @click="off" @mousedown="ripple">{{ lang.btn.off }}</a> | ||
32 | </div> | ||
33 | </div> | ||
34 | |||
35 | <div v-if="step == 2" class="vicp-step2"> | ||
36 | <div class="vicp-crop"> | ||
37 | <div v-show="true" class="vicp-crop-left"> | ||
38 | <div class="vicp-img-container"> | ||
39 | <img | ||
40 | ref="img" | ||
41 | :src="sourceImgUrl" | ||
42 | :style="sourceImgStyle" | ||
43 | class="vicp-img" | ||
44 | draggable="false" | ||
45 | @drag="preventDefault" | ||
46 | @dragstart="preventDefault" | ||
47 | @dragend="preventDefault" | ||
48 | @dragleave="preventDefault" | ||
49 | @dragover="preventDefault" | ||
50 | @dragenter="preventDefault" | ||
51 | @drop="preventDefault" | ||
52 | @touchstart="imgStartMove" | ||
53 | @touchmove="imgMove" | ||
54 | @touchend="createImg" | ||
55 | @touchcancel="createImg" | ||
56 | @mousedown="imgStartMove" | ||
57 | @mousemove="imgMove" | ||
58 | @mouseup="createImg" | ||
59 | @mouseout="createImg" | ||
60 | > | ||
61 | <div :style="sourceImgShadeStyle" class="vicp-img-shade vicp-img-shade-1" /> | ||
62 | <div :style="sourceImgShadeStyle" class="vicp-img-shade vicp-img-shade-2" /> | ||
63 | </div> | ||
64 | |||
65 | <div class="vicp-range"> | ||
66 | <input | ||
67 | :value="scale.range" | ||
68 | type="range" | ||
69 | step="1" | ||
70 | min="0" | ||
71 | max="100" | ||
72 | @input="zoomChange" | ||
73 | > | ||
74 | <i | ||
75 | class="vicp-icon5" | ||
76 | @mousedown="startZoomSub" | ||
77 | @mouseout="endZoomSub" | ||
78 | @mouseup="endZoomSub" | ||
79 | /> | ||
80 | <i | ||
81 | class="vicp-icon6" | ||
82 | @mousedown="startZoomAdd" | ||
83 | @mouseout="endZoomAdd" | ||
84 | @mouseup="endZoomAdd" | ||
85 | /> | ||
86 | </div> | ||
87 | |||
88 | <div v-if="!noRotate" class="vicp-rotate"> | ||
89 | <i @mousedown="startRotateLeft" @mouseout="endRotate" @mouseup="endRotate">↺</i> | ||
90 | <i @mousedown="startRotateRight" @mouseout="endRotate" @mouseup="endRotate">↻</i> | ||
91 | </div> | ||
92 | </div> | ||
93 | <div v-show="true" class="vicp-crop-right"> | ||
94 | <div class="vicp-preview"> | ||
95 | <div v-if="!noSquare" class="vicp-preview-item"> | ||
96 | <img :src="createImgUrl" :style="previewStyle"> | ||
97 | <span>{{ lang.preview }}</span> | ||
98 | </div> | ||
99 | <div v-if="!noCircle" class="vicp-preview-item vicp-preview-item-circle"> | ||
100 | <img :src="createImgUrl" :style="previewStyle"> | ||
101 | <span>{{ lang.preview }}</span> | ||
102 | </div> | ||
103 | </div> | ||
104 | </div> | ||
105 | </div> | ||
106 | <div class="vicp-operate"> | ||
107 | <a @click="setStep(1)" @mousedown="ripple">{{ lang.btn.back }}</a> | ||
108 | <a class="vicp-operate-btn" @click="prepareUpload" @mousedown="ripple">{{ lang.btn.save }}</a> | ||
109 | </div> | ||
110 | </div> | ||
111 | |||
112 | <div v-if="step == 3" class="vicp-step3"> | ||
113 | <div class="vicp-upload"> | ||
114 | <span v-show="loading === 1" class="vicp-loading">{{ lang.loading }}</span> | ||
115 | <div class="vicp-progress-wrap"> | ||
116 | <span v-show="loading === 1" :style="progressStyle" class="vicp-progress" /> | ||
117 | </div> | ||
118 | <div v-show="hasError" class="vicp-error"> | ||
119 | <i class="vicp-icon2" /> | ||
120 | {{ errorMsg }} | ||
121 | </div> | ||
122 | <div v-show="loading === 2" class="vicp-success"> | ||
123 | <i class="vicp-icon3" /> | ||
124 | {{ lang.success }} | ||
125 | </div> | ||
126 | </div> | ||
127 | <div class="vicp-operate"> | ||
128 | <a @click="setStep(2)" @mousedown="ripple">{{ lang.btn.back }}</a> | ||
129 | <a @click="off" @mousedown="ripple">{{ lang.btn.close }}</a> | ||
130 | </div> | ||
131 | </div> | ||
132 | <canvas v-show="false" ref="canvas" :width="width" :height="height" /> | ||
133 | </div> | ||
134 | </div> | ||
135 | </template> | ||
136 | |||
137 | <script> | ||
138 | 'use strict' | ||
139 | import request from '@/utils/request' | ||
140 | import language from './utils/language.js' | ||
141 | import mimes from './utils/mimes.js' | ||
142 | import data2blob from './utils/data2blob.js' | ||
143 | import effectRipple from './utils/effectRipple.js' | ||
144 | export default { | ||
145 | props: { | ||
146 | // 域,上传文件name,触发事件会带上(如果一个页面多个图片上传控件,可以做区分 | ||
147 | field: { | ||
148 | type: String, | ||
149 | default: 'avatar' | ||
150 | }, | ||
151 | // 原名key,类似于id,触发事件会带上(如果一个页面多个图片上传控件,可以做区分 | ||
152 | ki: { | ||
153 | type: Number, | ||
154 | default: 0 | ||
155 | }, | ||
156 | // 显示该控件与否 | ||
157 | value: { | ||
158 | type: Boolean, | ||
159 | default: true | ||
160 | }, | ||
161 | // 上传地址 | ||
162 | url: { | ||
163 | type: String, | ||
164 | default: '' | ||
165 | }, | ||
166 | // 其他要上传文件附带的数据,对象格式 | ||
167 | params: { | ||
168 | type: Object, | ||
169 | default: null | ||
170 | }, | ||
171 | // Add custom headers | ||
172 | headers: { | ||
173 | type: Object, | ||
174 | default: null | ||
175 | }, | ||
176 | // 剪裁图片的宽 | ||
177 | width: { | ||
178 | type: Number, | ||
179 | default: 200 | ||
180 | }, | ||
181 | // 剪裁图片的高 | ||
182 | height: { | ||
183 | type: Number, | ||
184 | default: 200 | ||
185 | }, | ||
186 | // 不显示旋转功能 | ||
187 | noRotate: { | ||
188 | type: Boolean, | ||
189 | default: true | ||
190 | }, | ||
191 | // 不预览圆形图片 | ||
192 | noCircle: { | ||
193 | type: Boolean, | ||
194 | default: false | ||
195 | }, | ||
196 | // 不预览方形图片 | ||
197 | noSquare: { | ||
198 | type: Boolean, | ||
199 | default: false | ||
200 | }, | ||
201 | // 单文件大小限制 | ||
202 | maxSize: { | ||
203 | type: Number, | ||
204 | default: 10240 | ||
205 | }, | ||
206 | // 语言类型 | ||
207 | langType: { | ||
208 | type: String, | ||
209 | default: 'zh' | ||
210 | }, | ||
211 | // 语言包 | ||
212 | langExt: { | ||
213 | type: Object, | ||
214 | default: null | ||
215 | }, | ||
216 | // 图片上传格式 | ||
217 | imgFormat: { | ||
218 | type: String, | ||
219 | default: 'png' | ||
220 | }, | ||
221 | // 是否支持跨域 | ||
222 | withCredentials: { | ||
223 | type: Boolean, | ||
224 | default: false | ||
225 | } | ||
226 | }, | ||
227 | data() { | ||
228 | const { imgFormat, langType, langExt, width, height } = this | ||
229 | let isSupported = true | ||
230 | const allowImgFormat = ['jpg', 'png'] | ||
231 | const tempImgFormat = | ||
232 | allowImgFormat.indexOf(imgFormat) === -1 ? 'jpg' : imgFormat | ||
233 | const lang = language[langType] ? language[langType] : language['en'] | ||
234 | const mime = mimes[tempImgFormat] | ||
235 | // 规范图片格式 | ||
236 | this.imgFormat = tempImgFormat | ||
237 | if (langExt) { | ||
238 | Object.assign(lang, langExt) | ||
239 | } | ||
240 | if (typeof FormData !== 'function') { | ||
241 | isSupported = false | ||
242 | } | ||
243 | return { | ||
244 | // 图片的mime | ||
245 | mime, | ||
246 | // 语言包 | ||
247 | lang, | ||
248 | // 浏览器是否支持该控件 | ||
249 | isSupported, | ||
250 | // 浏览器是否支持触屏事件 | ||
251 | isSupportTouch: document.hasOwnProperty('ontouchstart'), | ||
252 | // 步骤 | ||
253 | step: 1, // 1选择文件 2剪裁 3上传 | ||
254 | // 上传状态及进度 | ||
255 | loading: 0, // 0未开始 1正在 2成功 3错误 | ||
256 | progress: 0, | ||
257 | // 是否有错误及错误信息 | ||
258 | hasError: false, | ||
259 | errorMsg: '', | ||
260 | // 需求图宽高比 | ||
261 | ratio: width / height, | ||
262 | // 原图地址、生成图片地址 | ||
263 | sourceImg: null, | ||
264 | sourceImgUrl: '', | ||
265 | createImgUrl: '', | ||
266 | // 原图片拖动事件初始值 | ||
267 | sourceImgMouseDown: { | ||
268 | on: false, | ||
269 | mX: 0, // 鼠标按下的坐标 | ||
270 | mY: 0, | ||
271 | x: 0, // scale原图坐标 | ||
272 | y: 0 | ||
273 | }, | ||
274 | // 生成图片预览的容器大小 | ||
275 | previewContainer: { | ||
276 | width: 100, | ||
277 | height: 100 | ||
278 | }, | ||
279 | // 原图容器宽高 | ||
280 | sourceImgContainer: { | ||
281 | // sic | ||
282 | width: 240, | ||
283 | height: 184 // 如果生成图比例与此一致会出现bug,先改成特殊的格式吧,哈哈哈 | ||
284 | }, | ||
285 | // 原图展示属性 | ||
286 | scale: { | ||
287 | zoomAddOn: false, // 按钮缩放事件开启 | ||
288 | zoomSubOn: false, // 按钮缩放事件开启 | ||
289 | range: 1, // 最大100 | ||
290 | rotateLeft: false, // 按钮向左旋转事件开启 | ||
291 | rotateRight: false, // 按钮向右旋转事件开启 | ||
292 | degree: 0, // 旋转度数 | ||
293 | x: 0, | ||
294 | y: 0, | ||
295 | width: 0, | ||
296 | height: 0, | ||
297 | maxWidth: 0, | ||
298 | maxHeight: 0, | ||
299 | minWidth: 0, // 最宽 | ||
300 | minHeight: 0, | ||
301 | naturalWidth: 0, // 原宽 | ||
302 | naturalHeight: 0 | ||
303 | } | ||
304 | } | ||
305 | }, | ||
306 | computed: { | ||
307 | // 进度条样式 | ||
308 | progressStyle() { | ||
309 | const { progress } = this | ||
310 | return { | ||
311 | width: progress + '%' | ||
312 | } | ||
313 | }, | ||
314 | // 原图样式 | ||
315 | sourceImgStyle() { | ||
316 | const { scale, sourceImgMasking } = this | ||
317 | const top = scale.y + sourceImgMasking.y + 'px' | ||
318 | const left = scale.x + sourceImgMasking.x + 'px' | ||
319 | return { | ||
320 | top, | ||
321 | left, | ||
322 | width: scale.width + 'px', | ||
323 | height: scale.height + 'px', | ||
324 | transform: 'rotate(' + scale.degree + 'deg)', // 旋转时 左侧原始图旋转样式 | ||
325 | '-ms-transform': 'rotate(' + scale.degree + 'deg)', // 兼容IE9 | ||
326 | '-moz-transform': 'rotate(' + scale.degree + 'deg)', // 兼容FireFox | ||
327 | '-webkit-transform': 'rotate(' + scale.degree + 'deg)', // 兼容Safari 和 chrome | ||
328 | '-o-transform': 'rotate(' + scale.degree + 'deg)' // 兼容 Opera | ||
329 | } | ||
330 | }, | ||
331 | // 原图蒙版属性 | ||
332 | sourceImgMasking() { | ||
333 | const { width, height, ratio, sourceImgContainer } = this | ||
334 | const sic = sourceImgContainer | ||
335 | const sicRatio = sic.width / sic.height // 原图容器宽高比 | ||
336 | let x = 0 | ||
337 | let y = 0 | ||
338 | let w = sic.width | ||
339 | let h = sic.height | ||
340 | let scale = 1 | ||
341 | if (ratio < sicRatio) { | ||
342 | scale = sic.height / height | ||
343 | w = sic.height * ratio | ||
344 | x = (sic.width - w) / 2 | ||
345 | } | ||
346 | if (ratio > sicRatio) { | ||
347 | scale = sic.width / width | ||
348 | h = sic.width / ratio | ||
349 | y = (sic.height - h) / 2 | ||
350 | } | ||
351 | return { | ||
352 | scale, // 蒙版相对需求宽高的缩放 | ||
353 | x, | ||
354 | y, | ||
355 | width: w, | ||
356 | height: h | ||
357 | } | ||
358 | }, | ||
359 | // 原图遮罩样式 | ||
360 | sourceImgShadeStyle() { | ||
361 | const { sourceImgMasking, sourceImgContainer } = this | ||
362 | const sic = sourceImgContainer | ||
363 | const sim = sourceImgMasking | ||
364 | const w = | ||
365 | sim.width === sic.width ? sim.width : (sic.width - sim.width) / 2 | ||
366 | const h = | ||
367 | sim.height === sic.height ? sim.height : (sic.height - sim.height) / 2 | ||
368 | return { | ||
369 | width: w + 'px', | ||
370 | height: h + 'px' | ||
371 | } | ||
372 | }, | ||
373 | previewStyle() { | ||
374 | const { ratio, previewContainer } = this | ||
375 | const pc = previewContainer | ||
376 | let w = pc.width | ||
377 | let h = pc.height | ||
378 | const pcRatio = w / h | ||
379 | if (ratio < pcRatio) { | ||
380 | w = pc.height * ratio | ||
381 | } | ||
382 | if (ratio > pcRatio) { | ||
383 | h = pc.width / ratio | ||
384 | } | ||
385 | return { | ||
386 | width: w + 'px', | ||
387 | height: h + 'px' | ||
388 | } | ||
389 | } | ||
390 | }, | ||
391 | watch: { | ||
392 | value(newValue) { | ||
393 | if (newValue && this.loading !== 1) { | ||
394 | this.reset() | ||
395 | } | ||
396 | } | ||
397 | }, | ||
398 | created() { | ||
399 | // 绑定按键esc隐藏此插件事件 | ||
400 | document.addEventListener('keyup', this.closeHandler) | ||
401 | }, | ||
402 | destroyed() { | ||
403 | document.removeEventListener('keyup', this.closeHandler) | ||
404 | }, | ||
405 | methods: { | ||
406 | // 点击波纹效果 | ||
407 | ripple(e) { | ||
408 | effectRipple(e) | ||
409 | }, | ||
410 | // 关闭控件 | ||
411 | off() { | ||
412 | setTimeout(() => { | ||
413 | this.$emit('input', false) | ||
414 | this.$emit('close') | ||
415 | if (this.step === 3 && this.loading === 2) { | ||
416 | this.setStep(1) | ||
417 | } | ||
418 | }, 200) | ||
419 | }, | ||
420 | // 设置步骤 | ||
421 | setStep(no) { | ||
422 | // 延时是为了显示动画效果呢,哈哈哈 | ||
423 | setTimeout(() => { | ||
424 | this.step = no | ||
425 | }, 200) | ||
426 | }, | ||
427 | /* 图片选择区域函数绑定 | ||
428 | ---------------------------------------------------------------*/ | ||
429 | preventDefault(e) { | ||
430 | e.preventDefault() | ||
431 | return false | ||
432 | }, | ||
433 | handleClick(e) { | ||
434 | if (this.loading !== 1) { | ||
435 | if (e.target !== this.$refs.fileinput) { | ||
436 | e.preventDefault() | ||
437 | if (document.activeElement !== this.$refs) { | ||
438 | this.$refs.fileinput.click() | ||
439 | } | ||
440 | } | ||
441 | } | ||
442 | }, | ||
443 | handleChange(e) { | ||
444 | e.preventDefault() | ||
445 | if (this.loading !== 1) { | ||
446 | const files = e.target.files || e.dataTransfer.files | ||
447 | this.reset() | ||
448 | if (this.checkFile(files[0])) { | ||
449 | this.setSourceImg(files[0]) | ||
450 | } | ||
451 | } | ||
452 | }, | ||
453 | /* ---------------------------------------------------------------*/ | ||
454 | // 检测选择的文件是否合适 | ||
455 | checkFile(file) { | ||
456 | const { lang, maxSize } = this | ||
457 | // 仅限图片 | ||
458 | if (file.type.indexOf('image') === -1) { | ||
459 | this.hasError = true | ||
460 | this.errorMsg = lang.error.onlyImg | ||
461 | return false | ||
462 | } | ||
463 | // 超出大小 | ||
464 | if (file.size / 1024 > maxSize) { | ||
465 | this.hasError = true | ||
466 | this.errorMsg = lang.error.outOfSize + maxSize + 'kb' | ||
467 | return false | ||
468 | } | ||
469 | return true | ||
470 | }, | ||
471 | // 重置控件 | ||
472 | reset() { | ||
473 | this.loading = 0 | ||
474 | this.hasError = false | ||
475 | this.errorMsg = '' | ||
476 | this.progress = 0 | ||
477 | }, | ||
478 | // 设置图片源 | ||
479 | setSourceImg(file) { | ||
480 | const fr = new FileReader() | ||
481 | fr.onload = e => { | ||
482 | this.sourceImgUrl = fr.result | ||
483 | this.startCrop() | ||
484 | } | ||
485 | fr.readAsDataURL(file) | ||
486 | }, | ||
487 | // 剪裁前准备工作 | ||
488 | startCrop() { | ||
489 | const { | ||
490 | width, | ||
491 | height, | ||
492 | ratio, | ||
493 | scale, | ||
494 | sourceImgUrl, | ||
495 | sourceImgMasking, | ||
496 | lang | ||
497 | } = this | ||
498 | const sim = sourceImgMasking | ||
499 | const img = new Image() | ||
500 | img.src = sourceImgUrl | ||
501 | img.onload = () => { | ||
502 | const nWidth = img.naturalWidth | ||
503 | const nHeight = img.naturalHeight | ||
504 | const nRatio = nWidth / nHeight | ||
505 | let w = sim.width | ||
506 | let h = sim.height | ||
507 | let x = 0 | ||
508 | let y = 0 | ||
509 | // 图片像素不达标 | ||
510 | if (nWidth < width || nHeight < height) { | ||
511 | this.hasError = true | ||
512 | this.errorMsg = lang.error.lowestPx + width + '*' + height | ||
513 | return false | ||
514 | } | ||
515 | if (ratio > nRatio) { | ||
516 | h = w / nRatio | ||
517 | y = (sim.height - h) / 2 | ||
518 | } | ||
519 | if (ratio < nRatio) { | ||
520 | w = h * nRatio | ||
521 | x = (sim.width - w) / 2 | ||
522 | } | ||
523 | scale.range = 0 | ||
524 | scale.x = x | ||
525 | scale.y = y | ||
526 | scale.width = w | ||
527 | scale.height = h | ||
528 | scale.degree = 0 | ||
529 | scale.minWidth = w | ||
530 | scale.minHeight = h | ||
531 | scale.maxWidth = nWidth * sim.scale | ||
532 | scale.maxHeight = nHeight * sim.scale | ||
533 | scale.naturalWidth = nWidth | ||
534 | scale.naturalHeight = nHeight | ||
535 | this.sourceImg = img | ||
536 | this.createImg() | ||
537 | this.setStep(2) | ||
538 | } | ||
539 | }, | ||
540 | // 鼠标按下图片准备移动 | ||
541 | imgStartMove(e) { | ||
542 | e.preventDefault() | ||
543 | // 支持触摸事件,则鼠标事件无效 | ||
544 | if (this.isSupportTouch && !e.targetTouches) { | ||
545 | return false | ||
546 | } | ||
547 | const et = e.targetTouches ? e.targetTouches[0] : e | ||
548 | const { sourceImgMouseDown, scale } = this | ||
549 | const simd = sourceImgMouseDown | ||
550 | simd.mX = et.screenX | ||
551 | simd.mY = et.screenY | ||
552 | simd.x = scale.x | ||
553 | simd.y = scale.y | ||
554 | simd.on = true | ||
555 | }, | ||
556 | // 鼠标按下状态下移动,图片移动 | ||
557 | imgMove(e) { | ||
558 | e.preventDefault() | ||
559 | // 支持触摸事件,则鼠标事件无效 | ||
560 | if (this.isSupportTouch && !e.targetTouches) { | ||
561 | return false | ||
562 | } | ||
563 | const et = e.targetTouches ? e.targetTouches[0] : e | ||
564 | const { | ||
565 | sourceImgMouseDown: { on, mX, mY, x, y }, | ||
566 | scale, | ||
567 | sourceImgMasking | ||
568 | } = this | ||
569 | const sim = sourceImgMasking | ||
570 | const nX = et.screenX | ||
571 | const nY = et.screenY | ||
572 | const dX = nX - mX | ||
573 | const dY = nY - mY | ||
574 | let rX = x + dX | ||
575 | let rY = y + dY | ||
576 | if (!on) return | ||
577 | if (rX > 0) { | ||
578 | rX = 0 | ||
579 | } | ||
580 | if (rY > 0) { | ||
581 | rY = 0 | ||
582 | } | ||
583 | if (rX < sim.width - scale.width) { | ||
584 | rX = sim.width - scale.width | ||
585 | } | ||
586 | if (rY < sim.height - scale.height) { | ||
587 | rY = sim.height - scale.height | ||
588 | } | ||
589 | scale.x = rX | ||
590 | scale.y = rY | ||
591 | }, | ||
592 | // 按钮按下开始向右旋转 | ||
593 | startRotateRight(e) { | ||
594 | const { scale } = this | ||
595 | scale.rotateRight = true | ||
596 | const rotate = () => { | ||
597 | if (scale.rotateRight) { | ||
598 | const degree = ++scale.degree | ||
599 | this.createImg(degree) | ||
600 | setTimeout(function() { | ||
601 | rotate() | ||
602 | }, 60) | ||
603 | } | ||
604 | } | ||
605 | rotate() | ||
606 | }, | ||
607 | // 按钮按下开始向左旋转 | ||
608 | startRotateLeft(e) { | ||
609 | const { scale } = this | ||
610 | scale.rotateLeft = true | ||
611 | const rotate = () => { | ||
612 | if (scale.rotateLeft) { | ||
613 | const degree = --scale.degree | ||
614 | this.createImg(degree) | ||
615 | setTimeout(function() { | ||
616 | rotate() | ||
617 | }, 60) | ||
618 | } | ||
619 | } | ||
620 | rotate() | ||
621 | }, | ||
622 | // 停止旋转 | ||
623 | endRotate() { | ||
624 | const { scale } = this | ||
625 | scale.rotateLeft = false | ||
626 | scale.rotateRight = false | ||
627 | }, | ||
628 | // 按钮按下开始放大 | ||
629 | startZoomAdd(e) { | ||
630 | const { scale } = this | ||
631 | scale.zoomAddOn = true | ||
632 | const zoom = () => { | ||
633 | if (scale.zoomAddOn) { | ||
634 | const range = scale.range >= 100 ? 100 : ++scale.range | ||
635 | this.zoomImg(range) | ||
636 | setTimeout(function() { | ||
637 | zoom() | ||
638 | }, 60) | ||
639 | } | ||
640 | } | ||
641 | zoom() | ||
642 | }, | ||
643 | // 按钮松开或移开取消放大 | ||
644 | endZoomAdd(e) { | ||
645 | this.scale.zoomAddOn = false | ||
646 | }, | ||
647 | // 按钮按下开始缩小 | ||
648 | startZoomSub(e) { | ||
649 | const { scale } = this | ||
650 | scale.zoomSubOn = true | ||
651 | const zoom = () => { | ||
652 | if (scale.zoomSubOn) { | ||
653 | const range = scale.range <= 0 ? 0 : --scale.range | ||
654 | this.zoomImg(range) | ||
655 | setTimeout(function() { | ||
656 | zoom() | ||
657 | }, 60) | ||
658 | } | ||
659 | } | ||
660 | zoom() | ||
661 | }, | ||
662 | // 按钮松开或移开取消缩小 | ||
663 | endZoomSub(e) { | ||
664 | const { scale } = this | ||
665 | scale.zoomSubOn = false | ||
666 | }, | ||
667 | zoomChange(e) { | ||
668 | this.zoomImg(e.target.value) | ||
669 | }, | ||
670 | // 缩放原图 | ||
671 | zoomImg(newRange) { | ||
672 | const { sourceImgMasking, scale } = this | ||
673 | const { | ||
674 | maxWidth, | ||
675 | maxHeight, | ||
676 | minWidth, | ||
677 | minHeight, | ||
678 | width, | ||
679 | height, | ||
680 | x, | ||
681 | y | ||
682 | } = scale | ||
683 | const sim = sourceImgMasking | ||
684 | // 蒙版宽高 | ||
685 | const sWidth = sim.width | ||
686 | const sHeight = sim.height | ||
687 | // 新宽高 | ||
688 | const nWidth = minWidth + ((maxWidth - minWidth) * newRange) / 100 | ||
689 | const nHeight = minHeight + ((maxHeight - minHeight) * newRange) / 100 | ||
690 | // 新坐标(根据蒙版中心点缩放) | ||
691 | let nX = sWidth / 2 - (nWidth / width) * (sWidth / 2 - x) | ||
692 | let nY = sHeight / 2 - (nHeight / height) * (sHeight / 2 - y) | ||
693 | // 判断新坐标是否超过蒙版限制 | ||
694 | if (nX > 0) { | ||
695 | nX = 0 | ||
696 | } | ||
697 | if (nY > 0) { | ||
698 | nY = 0 | ||
699 | } | ||
700 | if (nX < sWidth - nWidth) { | ||
701 | nX = sWidth - nWidth | ||
702 | } | ||
703 | if (nY < sHeight - nHeight) { | ||
704 | nY = sHeight - nHeight | ||
705 | } | ||
706 | // 赋值处理 | ||
707 | scale.x = nX | ||
708 | scale.y = nY | ||
709 | scale.width = nWidth | ||
710 | scale.height = nHeight | ||
711 | scale.range = newRange | ||
712 | setTimeout(() => { | ||
713 | if (scale.range === newRange) { | ||
714 | this.createImg() | ||
715 | } | ||
716 | }, 300) | ||
717 | }, | ||
718 | // 生成需求图片 | ||
719 | createImg(e) { | ||
720 | const { | ||
721 | mime, | ||
722 | sourceImg, | ||
723 | scale: { x, y, width, height, degree }, | ||
724 | sourceImgMasking: { scale } | ||
725 | } = this | ||
726 | const canvas = this.$refs.canvas | ||
727 | const ctx = canvas.getContext('2d') | ||
728 | if (e) { | ||
729 | // 取消鼠标按下移动状态 | ||
730 | this.sourceImgMouseDown.on = false | ||
731 | } | ||
732 | canvas.width = this.width | ||
733 | canvas.height = this.height | ||
734 | ctx.clearRect(0, 0, this.width, this.height) | ||
735 | // 将透明区域设置为白色底边 | ||
736 | ctx.fillStyle = '#fff' | ||
737 | ctx.fillRect(0, 0, this.width, this.height) | ||
738 | ctx.translate(this.width * 0.5, this.height * 0.5) | ||
739 | ctx.rotate((Math.PI * degree) / 180) | ||
740 | ctx.translate(-this.width * 0.5, -this.height * 0.5) | ||
741 | ctx.drawImage( | ||
742 | sourceImg, | ||
743 | x / scale, | ||
744 | y / scale, | ||
745 | width / scale, | ||
746 | height / scale | ||
747 | ) | ||
748 | this.createImgUrl = canvas.toDataURL(mime) | ||
749 | }, | ||
750 | prepareUpload() { | ||
751 | const { url, createImgUrl, field, ki } = this | ||
752 | this.$emit('crop-success', createImgUrl, field, ki) | ||
753 | if (typeof url === 'string' && url) { | ||
754 | this.upload() | ||
755 | } else { | ||
756 | this.off() | ||
757 | } | ||
758 | }, | ||
759 | // 上传图片 | ||
760 | upload() { | ||
761 | const { | ||
762 | lang, | ||
763 | imgFormat, | ||
764 | mime, | ||
765 | url, | ||
766 | params, | ||
767 | field, | ||
768 | ki, | ||
769 | createImgUrl | ||
770 | } = this | ||
771 | const fmData = new FormData() | ||
772 | fmData.append( | ||
773 | field, | ||
774 | data2blob(createImgUrl, mime), | ||
775 | field + '.' + imgFormat | ||
776 | ) | ||
777 | // 添加其他参数 | ||
778 | if (typeof params === 'object' && params) { | ||
779 | Object.keys(params).forEach(k => { | ||
780 | fmData.append(k, params[k]) | ||
781 | }) | ||
782 | } | ||
783 | // 监听进度回调 | ||
784 | // const uploadProgress = (event) => { | ||
785 | // if (event.lengthComputable) { | ||
786 | // this.progress = 100 * Math.round(event.loaded) / event.total | ||
787 | // } | ||
788 | // } | ||
789 | // 上传文件 | ||
790 | this.reset() | ||
791 | this.loading = 1 | ||
792 | this.setStep(3) | ||
793 | request({ | ||
794 | url, | ||
795 | method: 'post', | ||
796 | data: fmData | ||
797 | }) | ||
798 | .then(resData => { | ||
799 | this.loading = 2 | ||
800 | this.$emit('crop-upload-success', resData.data) | ||
801 | }) | ||
802 | .catch(err => { | ||
803 | if (this.value) { | ||
804 | this.loading = 3 | ||
805 | this.hasError = true | ||
806 | this.errorMsg = lang.fail | ||
807 | this.$emit('crop-upload-fail', err, field, ki) | ||
808 | } | ||
809 | }) | ||
810 | }, | ||
811 | closeHandler(e) { | ||
812 | if (this.value && (e.key === 'Escape' || e.keyCode === 27)) { | ||
813 | this.off() | ||
814 | } | ||
815 | } | ||
816 | } | ||
817 | } | ||
818 | </script> | ||
819 | |||
820 | <style lang="scss"> | ||
821 | @charset "UTF-8"; | ||
822 | @-webkit-keyframes vicp_progress { | ||
823 | 0% { | ||
824 | background-position-y: 0; | ||
825 | } | ||
826 | 100% { | ||
827 | background-position-y: 40px; | ||
828 | } | ||
829 | } | ||
830 | @keyframes vicp_progress { | ||
831 | 0% { | ||
832 | background-position-y: 0; | ||
833 | } | ||
834 | 100% { | ||
835 | background-position-y: 40px; | ||
836 | } | ||
837 | } | ||
838 | @-webkit-keyframes vicp { | ||
839 | 0% { | ||
840 | opacity: 0; | ||
841 | -webkit-transform: scale(0) translatey(-60px); | ||
842 | transform: scale(0) translatey(-60px); | ||
843 | } | ||
844 | 100% { | ||
845 | opacity: 1; | ||
846 | -webkit-transform: scale(1) translatey(0); | ||
847 | transform: scale(1) translatey(0); | ||
848 | } | ||
849 | } | ||
850 | @keyframes vicp { | ||
851 | 0% { | ||
852 | opacity: 0; | ||
853 | -webkit-transform: scale(0) translatey(-60px); | ||
854 | transform: scale(0) translatey(-60px); | ||
855 | } | ||
856 | 100% { | ||
857 | opacity: 1; | ||
858 | -webkit-transform: scale(1) translatey(0); | ||
859 | transform: scale(1) translatey(0); | ||
860 | } | ||
861 | } | ||
862 | .vue-image-crop-upload { | ||
863 | position: fixed; | ||
864 | display: block; | ||
865 | -webkit-box-sizing: border-box; | ||
866 | box-sizing: border-box; | ||
867 | z-index: 10000; | ||
868 | top: 0; | ||
869 | bottom: 0; | ||
870 | left: 0; | ||
871 | right: 0; | ||
872 | width: 100%; | ||
873 | height: 100%; | ||
874 | background-color: rgba(0, 0, 0, 0.65); | ||
875 | -webkit-tap-highlight-color: transparent; | ||
876 | -moz-tap-highlight-color: transparent; | ||
877 | } | ||
878 | .vue-image-crop-upload .vicp-wrap { | ||
879 | -webkit-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.23); | ||
880 | box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.23); | ||
881 | position: fixed; | ||
882 | display: block; | ||
883 | -webkit-box-sizing: border-box; | ||
884 | box-sizing: border-box; | ||
885 | z-index: 10000; | ||
886 | top: 0; | ||
887 | bottom: 0; | ||
888 | left: 0; | ||
889 | right: 0; | ||
890 | margin: auto; | ||
891 | width: 600px; | ||
892 | height: 330px; | ||
893 | padding: 25px; | ||
894 | background-color: #fff; | ||
895 | border-radius: 2px; | ||
896 | -webkit-animation: vicp 0.12s ease-in; | ||
897 | animation: vicp 0.12s ease-in; | ||
898 | } | ||
899 | .vue-image-crop-upload .vicp-wrap .vicp-close { | ||
900 | position: absolute; | ||
901 | right: -30px; | ||
902 | top: -30px; | ||
903 | } | ||
904 | .vue-image-crop-upload .vicp-wrap .vicp-close .vicp-icon4 { | ||
905 | position: relative; | ||
906 | display: block; | ||
907 | width: 30px; | ||
908 | height: 30px; | ||
909 | cursor: pointer; | ||
910 | -webkit-transition: -webkit-transform 0.18s; | ||
911 | transition: -webkit-transform 0.18s; | ||
912 | transition: transform 0.18s; | ||
913 | transition: transform 0.18s, -webkit-transform 0.18s; | ||
914 | -webkit-transform: rotate(0); | ||
915 | -ms-transform: rotate(0); | ||
916 | transform: rotate(0); | ||
917 | } | ||
918 | .vue-image-crop-upload .vicp-wrap .vicp-close .vicp-icon4::after, | ||
919 | .vue-image-crop-upload .vicp-wrap .vicp-close .vicp-icon4::before { | ||
920 | -webkit-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.23); | ||
921 | box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.23); | ||
922 | content: ""; | ||
923 | position: absolute; | ||
924 | top: 12px; | ||
925 | left: 4px; | ||
926 | width: 20px; | ||
927 | height: 3px; | ||
928 | -webkit-transform: rotate(45deg); | ||
929 | -ms-transform: rotate(45deg); | ||
930 | transform: rotate(45deg); | ||
931 | background-color: #fff; | ||
932 | } | ||
933 | .vue-image-crop-upload .vicp-wrap .vicp-close .vicp-icon4::after { | ||
934 | -webkit-transform: rotate(-45deg); | ||
935 | -ms-transform: rotate(-45deg); | ||
936 | transform: rotate(-45deg); | ||
937 | } | ||
938 | .vue-image-crop-upload .vicp-wrap .vicp-close .vicp-icon4:hover { | ||
939 | -webkit-transform: rotate(90deg); | ||
940 | -ms-transform: rotate(90deg); | ||
941 | transform: rotate(90deg); | ||
942 | } | ||
943 | .vue-image-crop-upload .vicp-wrap .vicp-step1 .vicp-drop-area { | ||
944 | position: relative; | ||
945 | -webkit-box-sizing: border-box; | ||
946 | box-sizing: border-box; | ||
947 | padding: 35px; | ||
948 | height: 170px; | ||
949 | background-color: rgba(0, 0, 0, 0.03); | ||
950 | text-align: center; | ||
951 | border: 1px dashed rgba(0, 0, 0, 0.08); | ||
952 | overflow: hidden; | ||
953 | } | ||
954 | .vue-image-crop-upload .vicp-wrap .vicp-step1 .vicp-drop-area .vicp-icon1 { | ||
955 | display: block; | ||
956 | margin: 0 auto 6px; | ||
957 | width: 42px; | ||
958 | height: 42px; | ||
959 | overflow: hidden; | ||
960 | } | ||
961 | .vue-image-crop-upload | ||
962 | .vicp-wrap | ||
963 | .vicp-step1 | ||
964 | .vicp-drop-area | ||
965 | .vicp-icon1 | ||
966 | .vicp-icon1-arrow { | ||
967 | display: block; | ||
968 | margin: 0 auto; | ||
969 | width: 0; | ||
970 | height: 0; | ||
971 | border-bottom: 14.7px solid rgba(0, 0, 0, 0.3); | ||
972 | border-left: 14.7px solid transparent; | ||
973 | border-right: 14.7px solid transparent; | ||
974 | } | ||
975 | .vue-image-crop-upload | ||
976 | .vicp-wrap | ||
977 | .vicp-step1 | ||
978 | .vicp-drop-area | ||
979 | .vicp-icon1 | ||
980 | .vicp-icon1-body { | ||
981 | display: block; | ||
982 | width: 12.6px; | ||
983 | height: 14.7px; | ||
984 | margin: 0 auto; | ||
985 | background-color: rgba(0, 0, 0, 0.3); | ||
986 | } | ||
987 | .vue-image-crop-upload | ||
988 | .vicp-wrap | ||
989 | .vicp-step1 | ||
990 | .vicp-drop-area | ||
991 | .vicp-icon1 | ||
992 | .vicp-icon1-bottom { | ||
993 | -webkit-box-sizing: border-box; | ||
994 | box-sizing: border-box; | ||
995 | display: block; | ||
996 | height: 12.6px; | ||
997 | border: 6px solid rgba(0, 0, 0, 0.3); | ||
998 | border-top: none; | ||
999 | } | ||
1000 | .vue-image-crop-upload .vicp-wrap .vicp-step1 .vicp-drop-area .vicp-hint { | ||
1001 | display: block; | ||
1002 | padding: 15px; | ||
1003 | font-size: 14px; | ||
1004 | color: #666; | ||
1005 | line-height: 30px; | ||
1006 | } | ||
1007 | .vue-image-crop-upload | ||
1008 | .vicp-wrap | ||
1009 | .vicp-step1 | ||
1010 | .vicp-drop-area | ||
1011 | .vicp-no-supported-hint { | ||
1012 | display: block; | ||
1013 | position: absolute; | ||
1014 | top: 0; | ||
1015 | left: 0; | ||
1016 | padding: 30px; | ||
1017 | width: 100%; | ||
1018 | height: 60px; | ||
1019 | line-height: 30px; | ||
1020 | background-color: #eee; | ||
1021 | text-align: center; | ||
1022 | color: #666; | ||
1023 | font-size: 14px; | ||
1024 | } | ||
1025 | .vue-image-crop-upload .vicp-wrap .vicp-step1 .vicp-drop-area:hover { | ||
1026 | cursor: pointer; | ||
1027 | border-color: rgba(0, 0, 0, 0.1); | ||
1028 | background-color: rgba(0, 0, 0, 0.05); | ||
1029 | } | ||
1030 | .vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop { | ||
1031 | overflow: hidden; | ||
1032 | } | ||
1033 | .vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left { | ||
1034 | float: left; | ||
1035 | } | ||
1036 | .vue-image-crop-upload | ||
1037 | .vicp-wrap | ||
1038 | .vicp-step2 | ||
1039 | .vicp-crop | ||
1040 | .vicp-crop-left | ||
1041 | .vicp-img-container { | ||
1042 | position: relative; | ||
1043 | display: block; | ||
1044 | width: 240px; | ||
1045 | height: 180px; | ||
1046 | background-color: #e5e5e0; | ||
1047 | overflow: hidden; | ||
1048 | } | ||
1049 | .vue-image-crop-upload | ||
1050 | .vicp-wrap | ||
1051 | .vicp-step2 | ||
1052 | .vicp-crop | ||
1053 | .vicp-crop-left | ||
1054 | .vicp-img-container | ||
1055 | .vicp-img { | ||
1056 | position: absolute; | ||
1057 | display: block; | ||
1058 | cursor: move; | ||
1059 | -webkit-user-select: none; | ||
1060 | -moz-user-select: none; | ||
1061 | -ms-user-select: none; | ||
1062 | user-select: none; | ||
1063 | } | ||
1064 | .vue-image-crop-upload | ||
1065 | .vicp-wrap | ||
1066 | .vicp-step2 | ||
1067 | .vicp-crop | ||
1068 | .vicp-crop-left | ||
1069 | .vicp-img-container | ||
1070 | .vicp-img-shade { | ||
1071 | -webkit-box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.18); | ||
1072 | box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.18); | ||
1073 | position: absolute; | ||
1074 | background-color: rgba(241, 242, 243, 0.8); | ||
1075 | } | ||
1076 | .vue-image-crop-upload | ||
1077 | .vicp-wrap | ||
1078 | .vicp-step2 | ||
1079 | .vicp-crop | ||
1080 | .vicp-crop-left | ||
1081 | .vicp-img-container | ||
1082 | .vicp-img-shade.vicp-img-shade-1 { | ||
1083 | top: 0; | ||
1084 | left: 0; | ||
1085 | } | ||
1086 | .vue-image-crop-upload | ||
1087 | .vicp-wrap | ||
1088 | .vicp-step2 | ||
1089 | .vicp-crop | ||
1090 | .vicp-crop-left | ||
1091 | .vicp-img-container | ||
1092 | .vicp-img-shade.vicp-img-shade-2 { | ||
1093 | bottom: 0; | ||
1094 | right: 0; | ||
1095 | } | ||
1096 | .vue-image-crop-upload | ||
1097 | .vicp-wrap | ||
1098 | .vicp-step2 | ||
1099 | .vicp-crop | ||
1100 | .vicp-crop-left | ||
1101 | .vicp-rotate { | ||
1102 | position: relative; | ||
1103 | width: 240px; | ||
1104 | height: 18px; | ||
1105 | } | ||
1106 | .vue-image-crop-upload | ||
1107 | .vicp-wrap | ||
1108 | .vicp-step2 | ||
1109 | .vicp-crop | ||
1110 | .vicp-crop-left | ||
1111 | .vicp-rotate | ||
1112 | i { | ||
1113 | display: block; | ||
1114 | width: 18px; | ||
1115 | height: 18px; | ||
1116 | border-radius: 100%; | ||
1117 | line-height: 18px; | ||
1118 | text-align: center; | ||
1119 | font-size: 12px; | ||
1120 | font-weight: bold; | ||
1121 | background-color: rgba(0, 0, 0, 0.08); | ||
1122 | color: #fff; | ||
1123 | overflow: hidden; | ||
1124 | } | ||
1125 | .vue-image-crop-upload | ||
1126 | .vicp-wrap | ||
1127 | .vicp-step2 | ||
1128 | .vicp-crop | ||
1129 | .vicp-crop-left | ||
1130 | .vicp-rotate | ||
1131 | i:hover { | ||
1132 | -webkit-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12); | ||
1133 | box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12); | ||
1134 | cursor: pointer; | ||
1135 | background-color: rgba(0, 0, 0, 0.14); | ||
1136 | } | ||
1137 | .vue-image-crop-upload | ||
1138 | .vicp-wrap | ||
1139 | .vicp-step2 | ||
1140 | .vicp-crop | ||
1141 | .vicp-crop-left | ||
1142 | .vicp-rotate | ||
1143 | i:first-child { | ||
1144 | float: left; | ||
1145 | } | ||
1146 | .vue-image-crop-upload | ||
1147 | .vicp-wrap | ||
1148 | .vicp-step2 | ||
1149 | .vicp-crop | ||
1150 | .vicp-crop-left | ||
1151 | .vicp-rotate | ||
1152 | i:last-child { | ||
1153 | float: right; | ||
1154 | } | ||
1155 | .vue-image-crop-upload | ||
1156 | .vicp-wrap | ||
1157 | .vicp-step2 | ||
1158 | .vicp-crop | ||
1159 | .vicp-crop-left | ||
1160 | .vicp-range { | ||
1161 | position: relative; | ||
1162 | margin: 30px 0 10px 0; | ||
1163 | width: 240px; | ||
1164 | height: 18px; | ||
1165 | } | ||
1166 | .vue-image-crop-upload | ||
1167 | .vicp-wrap | ||
1168 | .vicp-step2 | ||
1169 | .vicp-crop | ||
1170 | .vicp-crop-left | ||
1171 | .vicp-range | ||
1172 | .vicp-icon5, | ||
1173 | .vue-image-crop-upload | ||
1174 | .vicp-wrap | ||
1175 | .vicp-step2 | ||
1176 | .vicp-crop | ||
1177 | .vicp-crop-left | ||
1178 | .vicp-range | ||
1179 | .vicp-icon6 { | ||
1180 | position: absolute; | ||
1181 | top: 0; | ||
1182 | width: 18px; | ||
1183 | height: 18px; | ||
1184 | border-radius: 100%; | ||
1185 | background-color: rgba(0, 0, 0, 0.08); | ||
1186 | } | ||
1187 | .vue-image-crop-upload | ||
1188 | .vicp-wrap | ||
1189 | .vicp-step2 | ||
1190 | .vicp-crop | ||
1191 | .vicp-crop-left | ||
1192 | .vicp-range | ||
1193 | .vicp-icon5:hover, | ||
1194 | .vue-image-crop-upload | ||
1195 | .vicp-wrap | ||
1196 | .vicp-step2 | ||
1197 | .vicp-crop | ||
1198 | .vicp-crop-left | ||
1199 | .vicp-range | ||
1200 | .vicp-icon6:hover { | ||
1201 | -webkit-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12); | ||
1202 | box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12); | ||
1203 | cursor: pointer; | ||
1204 | background-color: rgba(0, 0, 0, 0.14); | ||
1205 | } | ||
1206 | .vue-image-crop-upload | ||
1207 | .vicp-wrap | ||
1208 | .vicp-step2 | ||
1209 | .vicp-crop | ||
1210 | .vicp-crop-left | ||
1211 | .vicp-range | ||
1212 | .vicp-icon5 { | ||
1213 | left: 0; | ||
1214 | } | ||
1215 | .vue-image-crop-upload | ||
1216 | .vicp-wrap | ||
1217 | .vicp-step2 | ||
1218 | .vicp-crop | ||
1219 | .vicp-crop-left | ||
1220 | .vicp-range | ||
1221 | .vicp-icon5::before { | ||
1222 | position: absolute; | ||
1223 | content: ""; | ||
1224 | display: block; | ||
1225 | left: 3px; | ||
1226 | top: 8px; | ||
1227 | width: 12px; | ||
1228 | height: 2px; | ||
1229 | background-color: #fff; | ||
1230 | } | ||
1231 | .vue-image-crop-upload | ||
1232 | .vicp-wrap | ||
1233 | .vicp-step2 | ||
1234 | .vicp-crop | ||
1235 | .vicp-crop-left | ||
1236 | .vicp-range | ||
1237 | .vicp-icon6 { | ||
1238 | right: 0; | ||
1239 | } | ||
1240 | .vue-image-crop-upload | ||
1241 | .vicp-wrap | ||
1242 | .vicp-step2 | ||
1243 | .vicp-crop | ||
1244 | .vicp-crop-left | ||
1245 | .vicp-range | ||
1246 | .vicp-icon6::before { | ||
1247 | position: absolute; | ||
1248 | content: ""; | ||
1249 | display: block; | ||
1250 | left: 3px; | ||
1251 | top: 8px; | ||
1252 | width: 12px; | ||
1253 | height: 2px; | ||
1254 | background-color: #fff; | ||
1255 | } | ||
1256 | .vue-image-crop-upload | ||
1257 | .vicp-wrap | ||
1258 | .vicp-step2 | ||
1259 | .vicp-crop | ||
1260 | .vicp-crop-left | ||
1261 | .vicp-range | ||
1262 | .vicp-icon6::after { | ||
1263 | position: absolute; | ||
1264 | content: ""; | ||
1265 | display: block; | ||
1266 | top: 3px; | ||
1267 | left: 8px; | ||
1268 | width: 2px; | ||
1269 | height: 12px; | ||
1270 | background-color: #fff; | ||
1271 | } | ||
1272 | .vue-image-crop-upload | ||
1273 | .vicp-wrap | ||
1274 | .vicp-step2 | ||
1275 | .vicp-crop | ||
1276 | .vicp-crop-left | ||
1277 | .vicp-range | ||
1278 | input[type="range"] { | ||
1279 | display: block; | ||
1280 | padding-top: 5px; | ||
1281 | margin: 0 auto; | ||
1282 | width: 180px; | ||
1283 | height: 8px; | ||
1284 | vertical-align: top; | ||
1285 | background: transparent; | ||
1286 | -webkit-appearance: none; | ||
1287 | -moz-appearance: none; | ||
1288 | appearance: none; | ||
1289 | cursor: pointer; | ||
1290 | /* 滑块 | ||
1291 | ---------------------------------------------------------------*/ | ||
1292 | /* 轨道 | ||
1293 | ---------------------------------------------------------------*/ | ||
1294 | } | ||
1295 | .vue-image-crop-upload | ||
1296 | .vicp-wrap | ||
1297 | .vicp-step2 | ||
1298 | .vicp-crop | ||
1299 | .vicp-crop-left | ||
1300 | .vicp-range | ||
1301 | input[type="range"]:focus { | ||
1302 | outline: none; | ||
1303 | } | ||
1304 | .vue-image-crop-upload | ||
1305 | .vicp-wrap | ||
1306 | .vicp-step2 | ||
1307 | .vicp-crop | ||
1308 | .vicp-crop-left | ||
1309 | .vicp-range | ||
1310 | input[type="range"]::-webkit-slider-thumb { | ||
1311 | -webkit-box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.18); | ||
1312 | box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.18); | ||
1313 | -webkit-appearance: none; | ||
1314 | appearance: none; | ||
1315 | margin-top: -3px; | ||
1316 | width: 12px; | ||
1317 | height: 12px; | ||
1318 | background-color: #61c091; | ||
1319 | border-radius: 100%; | ||
1320 | border: none; | ||
1321 | -webkit-transition: 0.2s; | ||
1322 | transition: 0.2s; | ||
1323 | } | ||
1324 | .vue-image-crop-upload | ||
1325 | .vicp-wrap | ||
1326 | .vicp-step2 | ||
1327 | .vicp-crop | ||
1328 | .vicp-crop-left | ||
1329 | .vicp-range | ||
1330 | input[type="range"]::-moz-range-thumb { | ||
1331 | box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.18); | ||
1332 | -moz-appearance: none; | ||
1333 | appearance: none; | ||
1334 | width: 12px; | ||
1335 | height: 12px; | ||
1336 | background-color: #61c091; | ||
1337 | border-radius: 100%; | ||
1338 | border: none; | ||
1339 | -webkit-transition: 0.2s; | ||
1340 | transition: 0.2s; | ||
1341 | } | ||
1342 | .vue-image-crop-upload | ||
1343 | .vicp-wrap | ||
1344 | .vicp-step2 | ||
1345 | .vicp-crop | ||
1346 | .vicp-crop-left | ||
1347 | .vicp-range | ||
1348 | input[type="range"]::-ms-thumb { | ||
1349 | box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.18); | ||
1350 | appearance: none; | ||
1351 | width: 12px; | ||
1352 | height: 12px; | ||
1353 | background-color: #61c091; | ||
1354 | border: none; | ||
1355 | border-radius: 100%; | ||
1356 | -webkit-transition: 0.2s; | ||
1357 | transition: 0.2s; | ||
1358 | } | ||
1359 | .vue-image-crop-upload | ||
1360 | .vicp-wrap | ||
1361 | .vicp-step2 | ||
1362 | .vicp-crop | ||
1363 | .vicp-crop-left | ||
1364 | .vicp-range | ||
1365 | input[type="range"]:active::-moz-range-thumb { | ||
1366 | box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.23); | ||
1367 | width: 14px; | ||
1368 | height: 14px; | ||
1369 | } | ||
1370 | .vue-image-crop-upload | ||
1371 | .vicp-wrap | ||
1372 | .vicp-step2 | ||
1373 | .vicp-crop | ||
1374 | .vicp-crop-left | ||
1375 | .vicp-range | ||
1376 | input[type="range"]:active::-ms-thumb { | ||
1377 | box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.23); | ||
1378 | width: 14px; | ||
1379 | height: 14px; | ||
1380 | } | ||
1381 | .vue-image-crop-upload | ||
1382 | .vicp-wrap | ||
1383 | .vicp-step2 | ||
1384 | .vicp-crop | ||
1385 | .vicp-crop-left | ||
1386 | .vicp-range | ||
1387 | input[type="range"]:active::-webkit-slider-thumb { | ||
1388 | -webkit-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.23); | ||
1389 | box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.23); | ||
1390 | margin-top: -4px; | ||
1391 | width: 14px; | ||
1392 | height: 14px; | ||
1393 | } | ||
1394 | .vue-image-crop-upload | ||
1395 | .vicp-wrap | ||
1396 | .vicp-step2 | ||
1397 | .vicp-crop | ||
1398 | .vicp-crop-left | ||
1399 | .vicp-range | ||
1400 | input[type="range"]::-webkit-slider-runnable-track { | ||
1401 | -webkit-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12); | ||
1402 | box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12); | ||
1403 | width: 100%; | ||
1404 | height: 6px; | ||
1405 | cursor: pointer; | ||
1406 | border-radius: 2px; | ||
1407 | border: none; | ||
1408 | background-color: rgba(68, 170, 119, 0.3); | ||
1409 | } | ||
1410 | .vue-image-crop-upload | ||
1411 | .vicp-wrap | ||
1412 | .vicp-step2 | ||
1413 | .vicp-crop | ||
1414 | .vicp-crop-left | ||
1415 | .vicp-range | ||
1416 | input[type="range"]::-moz-range-track { | ||
1417 | box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12); | ||
1418 | width: 100%; | ||
1419 | height: 6px; | ||
1420 | cursor: pointer; | ||
1421 | border-radius: 2px; | ||
1422 | border: none; | ||
1423 | background-color: rgba(68, 170, 119, 0.3); | ||
1424 | } | ||
1425 | .vue-image-crop-upload | ||
1426 | .vicp-wrap | ||
1427 | .vicp-step2 | ||
1428 | .vicp-crop | ||
1429 | .vicp-crop-left | ||
1430 | .vicp-range | ||
1431 | input[type="range"]::-ms-track { | ||
1432 | box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12); | ||
1433 | width: 100%; | ||
1434 | cursor: pointer; | ||
1435 | background: transparent; | ||
1436 | border-color: transparent; | ||
1437 | color: transparent; | ||
1438 | height: 6px; | ||
1439 | border-radius: 2px; | ||
1440 | border: none; | ||
1441 | } | ||
1442 | .vue-image-crop-upload | ||
1443 | .vicp-wrap | ||
1444 | .vicp-step2 | ||
1445 | .vicp-crop | ||
1446 | .vicp-crop-left | ||
1447 | .vicp-range | ||
1448 | input[type="range"]::-ms-fill-lower { | ||
1449 | background-color: rgba(68, 170, 119, 0.3); | ||
1450 | } | ||
1451 | .vue-image-crop-upload | ||
1452 | .vicp-wrap | ||
1453 | .vicp-step2 | ||
1454 | .vicp-crop | ||
1455 | .vicp-crop-left | ||
1456 | .vicp-range | ||
1457 | input[type="range"]::-ms-fill-upper { | ||
1458 | background-color: rgba(68, 170, 119, 0.15); | ||
1459 | } | ||
1460 | .vue-image-crop-upload | ||
1461 | .vicp-wrap | ||
1462 | .vicp-step2 | ||
1463 | .vicp-crop | ||
1464 | .vicp-crop-left | ||
1465 | .vicp-range | ||
1466 | input[type="range"]:focus::-webkit-slider-runnable-track { | ||
1467 | background-color: rgba(68, 170, 119, 0.5); | ||
1468 | } | ||
1469 | .vue-image-crop-upload | ||
1470 | .vicp-wrap | ||
1471 | .vicp-step2 | ||
1472 | .vicp-crop | ||
1473 | .vicp-crop-left | ||
1474 | .vicp-range | ||
1475 | input[type="range"]:focus::-moz-range-track { | ||
1476 | background-color: rgba(68, 170, 119, 0.5); | ||
1477 | } | ||
1478 | .vue-image-crop-upload | ||
1479 | .vicp-wrap | ||
1480 | .vicp-step2 | ||
1481 | .vicp-crop | ||
1482 | .vicp-crop-left | ||
1483 | .vicp-range | ||
1484 | input[type="range"]:focus::-ms-fill-lower { | ||
1485 | background-color: rgba(68, 170, 119, 0.45); | ||
1486 | } | ||
1487 | .vue-image-crop-upload | ||
1488 | .vicp-wrap | ||
1489 | .vicp-step2 | ||
1490 | .vicp-crop | ||
1491 | .vicp-crop-left | ||
1492 | .vicp-range | ||
1493 | input[type="range"]:focus::-ms-fill-upper { | ||
1494 | background-color: rgba(68, 170, 119, 0.25); | ||
1495 | } | ||
1496 | .vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-right { | ||
1497 | float: right; | ||
1498 | } | ||
1499 | .vue-image-crop-upload | ||
1500 | .vicp-wrap | ||
1501 | .vicp-step2 | ||
1502 | .vicp-crop | ||
1503 | .vicp-crop-right | ||
1504 | .vicp-preview { | ||
1505 | height: 150px; | ||
1506 | overflow: hidden; | ||
1507 | } | ||
1508 | .vue-image-crop-upload | ||
1509 | .vicp-wrap | ||
1510 | .vicp-step2 | ||
1511 | .vicp-crop | ||
1512 | .vicp-crop-right | ||
1513 | .vicp-preview | ||
1514 | .vicp-preview-item { | ||
1515 | position: relative; | ||
1516 | padding: 5px; | ||
1517 | width: 100px; | ||
1518 | height: 100px; | ||
1519 | float: left; | ||
1520 | margin-right: 16px; | ||
1521 | } | ||
1522 | .vue-image-crop-upload | ||
1523 | .vicp-wrap | ||
1524 | .vicp-step2 | ||
1525 | .vicp-crop | ||
1526 | .vicp-crop-right | ||
1527 | .vicp-preview | ||
1528 | .vicp-preview-item | ||
1529 | span { | ||
1530 | position: absolute; | ||
1531 | bottom: -30px; | ||
1532 | width: 100%; | ||
1533 | font-size: 14px; | ||
1534 | color: #bbb; | ||
1535 | display: block; | ||
1536 | text-align: center; | ||
1537 | } | ||
1538 | .vue-image-crop-upload | ||
1539 | .vicp-wrap | ||
1540 | .vicp-step2 | ||
1541 | .vicp-crop | ||
1542 | .vicp-crop-right | ||
1543 | .vicp-preview | ||
1544 | .vicp-preview-item | ||
1545 | img { | ||
1546 | position: absolute; | ||
1547 | display: block; | ||
1548 | top: 0; | ||
1549 | bottom: 0; | ||
1550 | left: 0; | ||
1551 | right: 0; | ||
1552 | margin: auto; | ||
1553 | padding: 3px; | ||
1554 | background-color: #fff; | ||
1555 | border: 1px solid rgba(0, 0, 0, 0.15); | ||
1556 | overflow: hidden; | ||
1557 | -webkit-user-select: none; | ||
1558 | -moz-user-select: none; | ||
1559 | -ms-user-select: none; | ||
1560 | user-select: none; | ||
1561 | } | ||
1562 | .vue-image-crop-upload | ||
1563 | .vicp-wrap | ||
1564 | .vicp-step2 | ||
1565 | .vicp-crop | ||
1566 | .vicp-crop-right | ||
1567 | .vicp-preview | ||
1568 | .vicp-preview-item.vicp-preview-item-circle { | ||
1569 | margin-right: 0; | ||
1570 | } | ||
1571 | .vue-image-crop-upload | ||
1572 | .vicp-wrap | ||
1573 | .vicp-step2 | ||
1574 | .vicp-crop | ||
1575 | .vicp-crop-right | ||
1576 | .vicp-preview | ||
1577 | .vicp-preview-item.vicp-preview-item-circle | ||
1578 | img { | ||
1579 | border-radius: 100%; | ||
1580 | } | ||
1581 | .vue-image-crop-upload .vicp-wrap .vicp-step3 .vicp-upload { | ||
1582 | position: relative; | ||
1583 | -webkit-box-sizing: border-box; | ||
1584 | box-sizing: border-box; | ||
1585 | padding: 35px; | ||
1586 | height: 170px; | ||
1587 | background-color: rgba(0, 0, 0, 0.03); | ||
1588 | text-align: center; | ||
1589 | border: 1px dashed #ddd; | ||
1590 | } | ||
1591 | .vue-image-crop-upload .vicp-wrap .vicp-step3 .vicp-upload .vicp-loading { | ||
1592 | display: block; | ||
1593 | padding: 15px; | ||
1594 | font-size: 16px; | ||
1595 | color: #999; | ||
1596 | line-height: 30px; | ||
1597 | } | ||
1598 | .vue-image-crop-upload .vicp-wrap .vicp-step3 .vicp-upload .vicp-progress-wrap { | ||
1599 | margin-top: 12px; | ||
1600 | background-color: rgba(0, 0, 0, 0.08); | ||
1601 | border-radius: 3px; | ||
1602 | } | ||
1603 | .vue-image-crop-upload | ||
1604 | .vicp-wrap | ||
1605 | .vicp-step3 | ||
1606 | .vicp-upload | ||
1607 | .vicp-progress-wrap | ||
1608 | .vicp-progress { | ||
1609 | position: relative; | ||
1610 | display: block; | ||
1611 | height: 5px; | ||
1612 | border-radius: 3px; | ||
1613 | background-color: #4a7; | ||
1614 | -webkit-box-shadow: 0 2px 6px 0 rgba(68, 170, 119, 0.3); | ||
1615 | box-shadow: 0 2px 6px 0 rgba(68, 170, 119, 0.3); | ||
1616 | -webkit-transition: width 0.15s linear; | ||
1617 | transition: width 0.15s linear; | ||
1618 | background-image: -webkit-linear-gradient( | ||
1619 | 135deg, | ||
1620 | rgba(255, 255, 255, 0.2) 25%, | ||
1621 | transparent 25%, | ||
1622 | transparent 50%, | ||
1623 | rgba(255, 255, 255, 0.2) 50%, | ||
1624 | rgba(255, 255, 255, 0.2) 75%, | ||
1625 | transparent 75%, | ||
1626 | transparent | ||
1627 | ); | ||
1628 | background-image: linear-gradient( | ||
1629 | -45deg, | ||
1630 | rgba(255, 255, 255, 0.2) 25%, | ||
1631 | transparent 25%, | ||
1632 | transparent 50%, | ||
1633 | rgba(255, 255, 255, 0.2) 50%, | ||
1634 | rgba(255, 255, 255, 0.2) 75%, | ||
1635 | transparent 75%, | ||
1636 | transparent | ||
1637 | ); | ||
1638 | background-size: 40px 40px; | ||
1639 | -webkit-animation: vicp_progress 0.5s linear infinite; | ||
1640 | animation: vicp_progress 0.5s linear infinite; | ||
1641 | } | ||
1642 | .vue-image-crop-upload | ||
1643 | .vicp-wrap | ||
1644 | .vicp-step3 | ||
1645 | .vicp-upload | ||
1646 | .vicp-progress-wrap | ||
1647 | .vicp-progress::after { | ||
1648 | content: ""; | ||
1649 | position: absolute; | ||
1650 | display: block; | ||
1651 | top: -3px; | ||
1652 | right: -3px; | ||
1653 | width: 9px; | ||
1654 | height: 9px; | ||
1655 | border: 1px solid rgba(245, 246, 247, 0.7); | ||
1656 | -webkit-box-shadow: 0 1px 4px 0 rgba(68, 170, 119, 0.7); | ||
1657 | box-shadow: 0 1px 4px 0 rgba(68, 170, 119, 0.7); | ||
1658 | border-radius: 100%; | ||
1659 | background-color: #4a7; | ||
1660 | } | ||
1661 | .vue-image-crop-upload .vicp-wrap .vicp-step3 .vicp-upload .vicp-error, | ||
1662 | .vue-image-crop-upload .vicp-wrap .vicp-step3 .vicp-upload .vicp-success { | ||
1663 | height: 100px; | ||
1664 | line-height: 100px; | ||
1665 | } | ||
1666 | .vue-image-crop-upload .vicp-wrap .vicp-operate { | ||
1667 | position: absolute; | ||
1668 | right: 20px; | ||
1669 | bottom: 20px; | ||
1670 | } | ||
1671 | .vue-image-crop-upload .vicp-wrap .vicp-operate a { | ||
1672 | position: relative; | ||
1673 | float: left; | ||
1674 | display: block; | ||
1675 | margin-left: 10px; | ||
1676 | width: 100px; | ||
1677 | height: 36px; | ||
1678 | line-height: 36px; | ||
1679 | text-align: center; | ||
1680 | cursor: pointer; | ||
1681 | font-size: 14px; | ||
1682 | color: #4a7; | ||
1683 | border-radius: 2px; | ||
1684 | overflow: hidden; | ||
1685 | -webkit-user-select: none; | ||
1686 | -moz-user-select: none; | ||
1687 | -ms-user-select: none; | ||
1688 | user-select: none; | ||
1689 | } | ||
1690 | .vue-image-crop-upload .vicp-wrap .vicp-operate a:hover { | ||
1691 | background-color: rgba(0, 0, 0, 0.03); | ||
1692 | } | ||
1693 | .vue-image-crop-upload .vicp-wrap .vicp-error, | ||
1694 | .vue-image-crop-upload .vicp-wrap .vicp-success { | ||
1695 | display: block; | ||
1696 | font-size: 14px; | ||
1697 | line-height: 24px; | ||
1698 | height: 24px; | ||
1699 | color: #d10; | ||
1700 | text-align: center; | ||
1701 | vertical-align: top; | ||
1702 | } | ||
1703 | .vue-image-crop-upload .vicp-wrap .vicp-success { | ||
1704 | color: #4a7; | ||
1705 | } | ||
1706 | .vue-image-crop-upload .vicp-wrap .vicp-icon3 { | ||
1707 | position: relative; | ||
1708 | display: inline-block; | ||
1709 | width: 20px; | ||
1710 | height: 20px; | ||
1711 | top: 4px; | ||
1712 | } | ||
1713 | .vue-image-crop-upload .vicp-wrap .vicp-icon3::after { | ||
1714 | position: absolute; | ||
1715 | top: 3px; | ||
1716 | left: 6px; | ||
1717 | width: 6px; | ||
1718 | height: 10px; | ||
1719 | border-width: 0 2px 2px 0; | ||
1720 | border-color: #4a7; | ||
1721 | border-style: solid; | ||
1722 | -webkit-transform: rotate(45deg); | ||
1723 | -ms-transform: rotate(45deg); | ||
1724 | transform: rotate(45deg); | ||
1725 | content: ""; | ||
1726 | } | ||
1727 | .vue-image-crop-upload .vicp-wrap .vicp-icon2 { | ||
1728 | position: relative; | ||
1729 | display: inline-block; | ||
1730 | width: 20px; | ||
1731 | height: 20px; | ||
1732 | top: 4px; | ||
1733 | } | ||
1734 | .vue-image-crop-upload .vicp-wrap .vicp-icon2::after, | ||
1735 | .vue-image-crop-upload .vicp-wrap .vicp-icon2::before { | ||
1736 | content: ""; | ||
1737 | position: absolute; | ||
1738 | top: 9px; | ||
1739 | left: 4px; | ||
1740 | width: 13px; | ||
1741 | height: 2px; | ||
1742 | background-color: #d10; | ||
1743 | -webkit-transform: rotate(45deg); | ||
1744 | -ms-transform: rotate(45deg); | ||
1745 | transform: rotate(45deg); | ||
1746 | } | ||
1747 | .vue-image-crop-upload .vicp-wrap .vicp-icon2::after { | ||
1748 | -webkit-transform: rotate(-45deg); | ||
1749 | -ms-transform: rotate(-45deg); | ||
1750 | transform: rotate(-45deg); | ||
1751 | } | ||
1752 | .e-ripple { | ||
1753 | position: absolute; | ||
1754 | border-radius: 100%; | ||
1755 | background-color: rgba(0, 0, 0, 0.15); | ||
1756 | background-clip: padding-box; | ||
1757 | pointer-events: none; | ||
1758 | -webkit-user-select: none; | ||
1759 | -moz-user-select: none; | ||
1760 | -ms-user-select: none; | ||
1761 | user-select: none; | ||
1762 | -webkit-transform: scale(0); | ||
1763 | -ms-transform: scale(0); | ||
1764 | transform: scale(0); | ||
1765 | opacity: 1; | ||
1766 | } | ||
1767 | .e-ripple.z-active { | ||
1768 | opacity: 0; | ||
1769 | -webkit-transform: scale(2); | ||
1770 | -ms-transform: scale(2); | ||
1771 | transform: scale(2); | ||
1772 | -webkit-transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out; | ||
1773 | transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out; | ||
1774 | transition: opacity 1.2s ease-out, transform 0.6s ease-out; | ||
1775 | transition: opacity 1.2s ease-out, transform 0.6s ease-out, | ||
1776 | -webkit-transform 0.6s ease-out; | ||
1777 | } | ||
1778 | </style> | ||
1779 |
src/components/ImageCropper/utils/data2blob.js
File was created | 1 | /** | |
2 | * database64文件格式转换为2进制 | ||
3 | * | ||
4 | * @param {[String]} data dataURL 的格式为 “data:image/png;base64,****”,逗号之前都是一些说明性的文字,我们只需要逗号之后的就行了 | ||
5 | * @param {[String]} mime [description] | ||
6 | * @return {[blob]} [description] | ||
7 | */ | ||
8 | export default function(data, mime) { | ||
9 | data = data.split(',')[1] | ||
10 | data = window.atob(data) | ||
11 | var ia = new Uint8Array(data.length) | ||
12 | for (var i = 0; i < data.length; i++) { | ||
13 | ia[i] = data.charCodeAt(i) | ||
14 | } | ||
15 | // canvas.toDataURL 返回的默认格式就是 image/png | ||
16 | return new Blob([ia], { | ||
17 | type: mime | ||
18 | }) | ||
19 | } | ||
20 |
src/components/ImageCropper/utils/effectRipple.js
File was created | 1 | /** | |
2 | * 点击波纹效果 | ||
3 | * | ||
4 | * @param {[event]} e [description] | ||
5 | * @param {[Object]} arg_opts [description] | ||
6 | * @return {[bollean]} [description] | ||
7 | */ | ||
8 | export default function(e, arg_opts) { | ||
9 | var opts = Object.assign({ | ||
10 | ele: e.target, // 波纹作用元素 | ||
11 | type: 'hit', // hit点击位置扩散center中心点扩展 | ||
12 | bgc: 'rgba(0, 0, 0, 0.15)' // 波纹颜色 | ||
13 | }, arg_opts) | ||
14 | var target = opts.ele | ||
15 | if (target) { | ||
16 | var rect = target.getBoundingClientRect() | ||
17 | var ripple = target.querySelector('.e-ripple') | ||
18 | if (!ripple) { | ||
19 | ripple = document.createElement('span') | ||
20 | ripple.className = 'e-ripple' | ||
21 | ripple.style.height = ripple.style.width = Math.max(rect.width, rect.height) + 'px' | ||
22 | target.appendChild(ripple) | ||
23 | } else { | ||
24 | ripple.className = 'e-ripple' | ||
25 | } | ||
26 | switch (opts.type) { | ||
27 | case 'center': | ||
28 | ripple.style.top = (rect.height / 2 - ripple.offsetHeight / 2) + 'px' | ||
29 | ripple.style.left = (rect.width / 2 - ripple.offsetWidth / 2) + 'px' | ||
30 | break | ||
31 | default: | ||
32 | ripple.style.top = (e.pageY - rect.top - ripple.offsetHeight / 2 - document.body.scrollTop) + 'px' | ||
33 | ripple.style.left = (e.pageX - rect.left - ripple.offsetWidth / 2 - document.body.scrollLeft) + 'px' | ||
34 | } | ||
35 | ripple.style.backgroundColor = opts.bgc | ||
36 | ripple.className = 'e-ripple z-active' | ||
37 | return false | ||
38 | } | ||
39 | } | ||
40 |
src/components/ImageCropper/utils/language.js
File was created | 1 | export default { | |
2 | zh: { | ||
3 | hint: '点击,或拖动图片至此处', | ||
4 | loading: '正在上传……', | ||
5 | noSupported: '浏览器不支持该功能,请使用IE10以上或其他现在浏览器!', | ||
6 | success: '上传成功', | ||
7 | fail: '图片上传失败', | ||
8 | preview: '头像预览', | ||
9 | btn: { | ||
10 | off: '取消', | ||
11 | close: '关闭', | ||
12 | back: '上一步', | ||
13 | save: '保存' | ||
14 | }, | ||
15 | error: { | ||
16 | onlyImg: '仅限图片格式', | ||
17 | outOfSize: '单文件大小不能超过 ', | ||
18 | lowestPx: '图片最低像素为(宽*高):' | ||
19 | } | ||
20 | }, | ||
21 | 'zh-tw': { | ||
22 | hint: '點擊,或拖動圖片至此處', | ||
23 | loading: '正在上傳……', | ||
24 | noSupported: '瀏覽器不支持該功能,請使用IE10以上或其他現代瀏覽器!', | ||
25 | success: '上傳成功', | ||
26 | fail: '圖片上傳失敗', | ||
27 | preview: '頭像預覽', | ||
28 | btn: { | ||
29 | off: '取消', | ||
30 | close: '關閉', | ||
31 | back: '上一步', | ||
32 | save: '保存' | ||
33 | }, | ||
34 | error: { | ||
35 | onlyImg: '僅限圖片格式', | ||
36 | outOfSize: '單文件大小不能超過 ', | ||
37 | lowestPx: '圖片最低像素為(寬*高):' | ||
38 | } | ||
39 | }, | ||
40 | en: { | ||
41 | hint: 'Click or drag the file here to upload', | ||
42 | loading: 'Uploading…', | ||
43 | noSupported: 'Browser is not supported, please use IE10+ or other browsers', | ||
44 | success: 'Upload success', | ||
45 | fail: 'Upload failed', | ||
46 | preview: 'Preview', | ||
47 | btn: { | ||
48 | off: 'Cancel', | ||
49 | close: 'Close', | ||
50 | back: 'Back', | ||
51 | save: 'Save' | ||
52 | }, | ||
53 | error: { | ||
54 | onlyImg: 'Image only', | ||
55 | outOfSize: 'Image exceeds size limit: ', | ||
56 | lowestPx: 'Image\'s size is too low. Expected at least: ' | ||
57 | } | ||
58 | }, | ||
59 | ro: { | ||
60 | hint: 'Atinge sau trage fișierul aici', | ||
61 | loading: 'Se încarcă', | ||
62 | noSupported: 'Browser-ul tău nu suportă acest feature. Te rugăm încearcă cu alt browser.', | ||
63 | success: 'S-a încărcat cu succes', | ||
64 | fail: 'A apărut o problemă la încărcare', | ||
65 | preview: 'Previzualizează', | ||
66 | |||
67 | btn: { | ||
68 | off: 'Anulează', | ||
69 | close: 'Închide', | ||
70 | back: 'Înapoi', | ||
71 | save: 'Salvează' | ||
72 | }, | ||
73 | |||
74 | error: { | ||
75 | onlyImg: 'Doar imagini', | ||
76 | outOfSize: 'Imaginea depășește limita de: ', | ||
77 | loewstPx: 'Imaginea este prea mică; Minim: ' | ||
78 | } | ||
79 | }, | ||
80 | ru: { | ||
81 | hint: 'Нажмите, или перетащите файл в это окно', | ||
82 | loading: 'Загружаю……', | ||
83 | noSupported: 'Ваш браузер не поддерживается, пожалуйста, используйте IE10 + или другие браузеры', | ||
84 | success: 'Загрузка выполнена успешно', | ||
85 | fail: 'Ошибка загрузки', | ||
86 | preview: 'Предпросмотр', | ||
87 | btn: { | ||
88 | off: 'Отменить', | ||
89 | close: 'Закрыть', | ||
90 | back: 'Назад', | ||
91 | save: 'Сохранить' | ||
92 | }, | ||
93 | error: { | ||
94 | onlyImg: 'Только изображения', | ||
95 | outOfSize: 'Изображение превышает предельный размер: ', | ||
96 | lowestPx: 'Минимальный размер изображения: ' | ||
97 | } | ||
98 | }, | ||
99 | 'pt-br': { | ||
100 | hint: 'Clique ou arraste o arquivo aqui para carregar', | ||
101 | loading: 'Carregando…', | ||
102 | noSupported: 'Browser não suportado, use o IE10+ ou outro browser', | ||
103 | success: 'Sucesso ao carregar imagem', | ||
104 | fail: 'Falha ao carregar imagem', | ||
105 | preview: 'Pré-visualizar', | ||
106 | btn: { | ||
107 | off: 'Cancelar', | ||
108 | close: 'Fechar', | ||
109 | back: 'Voltar', | ||
110 | save: 'Salvar' | ||
111 | }, | ||
112 | error: { | ||
113 | onlyImg: 'Apenas imagens', | ||
114 | outOfSize: 'A imagem excede o limite de tamanho: ', | ||
115 | lowestPx: 'O tamanho da imagem é muito pequeno. Tamanho mínimo: ' | ||
116 | } | ||
117 | }, | ||
118 | fr: { | ||
119 | hint: 'Cliquez ou glissez le fichier ici.', | ||
120 | loading: 'Téléchargement…', | ||
121 | noSupported: 'Votre navigateur n\'est pas supporté. Utilisez IE10 + ou un autre navigateur s\'il vous plaît.', | ||
122 | success: 'Téléchargement réussit', | ||
123 | fail: 'Téléchargement echoué', | ||
124 | preview: 'Aperçu', | ||
125 | btn: { | ||
126 | off: 'Annuler', | ||
127 | close: 'Fermer', | ||
128 | back: 'Retour', | ||
129 | save: 'Enregistrer' | ||
130 | }, | ||
131 | error: { | ||
132 | onlyImg: 'Image uniquement', | ||
133 | outOfSize: 'L\'image sélectionnée dépasse la taille maximum: ', | ||
134 | lowestPx: 'L\'image sélectionnée est trop petite. Dimensions attendues: ' | ||
135 | } | ||
136 | }, | ||
137 | nl: { | ||
138 | hint: 'Klik hier of sleep een afbeelding in dit vlak', | ||
139 | loading: 'Uploaden…', | ||
140 | noSupported: 'Je browser wordt helaas niet ondersteund. Gebruik IE10+ of een andere browser.', | ||
141 | success: 'Upload succesvol', | ||
142 | fail: 'Upload mislukt', | ||
143 | preview: 'Voorbeeld', | ||
144 | btn: { | ||
145 | off: 'Annuleren', | ||
146 | close: 'Sluiten', | ||
147 | back: 'Terug', | ||
148 | save: 'Opslaan' | ||
149 | }, | ||
150 | error: { | ||
151 | onlyImg: 'Alleen afbeeldingen', | ||
152 | outOfSize: 'De afbeelding is groter dan: ', | ||
153 | lowestPx: 'De afbeelding is te klein! Minimale afmetingen: ' | ||
154 | } | ||
155 | }, | ||
156 | tr: { | ||
157 | hint: 'Tıkla veya yüklemek istediğini buraya sürükle', | ||
158 | loading: 'Yükleniyor…', | ||
159 | noSupported: 'Tarayıcı desteklenmiyor, lütfen IE10+ veya farklı tarayıcı kullanın', | ||
160 | success: 'Yükleme başarılı', | ||
161 | fail: 'Yüklemede hata oluştu', | ||
162 | preview: 'Önizle', | ||
163 | btn: { | ||
164 | off: 'İptal', | ||
165 | close: 'Kapat', | ||
166 | back: 'Geri', | ||
167 | save: 'Kaydet' | ||
168 | }, | ||
169 | error: { | ||
170 | onlyImg: 'Sadece resim', | ||
171 | outOfSize: 'Resim yükleme limitini aşıyor: ', | ||
172 | lowestPx: 'Resmin boyutu çok küçük. En az olması gereken: ' | ||
173 | } | ||
174 | }, | ||
175 | 'es-MX': { | ||
176 | hint: 'Selecciona o arrastra una imagen', | ||
177 | loading: 'Subiendo...', | ||
178 | noSupported: 'Tu navegador no es soportado, porfavor usa IE10+ u otros navegadores mas recientes', | ||
179 | success: 'Subido exitosamente', | ||
180 | fail: 'Sucedió un error', | ||
181 | preview: 'Vista previa', | ||
182 | btn: { | ||
183 | off: 'Cancelar', | ||
184 | close: 'Cerrar', | ||
185 | back: 'Atras', | ||
186 | save: 'Guardar' | ||
187 | }, | ||
188 | error: { | ||
189 | onlyImg: 'Unicamente imagenes', | ||
190 | outOfSize: 'La imagen excede el tamaño maximo:', | ||
191 | lowestPx: 'La imagen es demasiado pequeño. Se espera por lo menos:' | ||
192 | } | ||
193 | }, | ||
194 | de: { | ||
195 | hint: 'Klick hier oder zieh eine Datei hier rein zum Hochladen', | ||
196 | loading: 'Hochladen…', | ||
197 | noSupported: 'Browser wird nicht unterstützt, bitte verwende IE10+ oder andere Browser', | ||
198 | success: 'Upload erfolgreich', | ||
199 | fail: 'Upload fehlgeschlagen', | ||
200 | preview: 'Vorschau', | ||
201 | btn: { | ||
202 | off: 'Abbrechen', | ||
203 | close: 'Schließen', | ||
204 | back: 'Zurück', | ||
205 | save: 'Speichern' | ||
206 | }, | ||
207 | error: { | ||
208 | onlyImg: 'Nur Bilder', | ||
209 | outOfSize: 'Das Bild ist zu groß: ', | ||
210 | lowestPx: 'Das Bild ist zu klein. Mindestens: ' | ||
211 | } | ||
212 | }, | ||
213 | ja: { | ||
214 | hint: 'クリック・ドラッグしてファイルをアップロード', | ||
215 | loading: 'アップロード中...', | ||
216 | noSupported: 'このブラウザは対応されていません。IE10+かその他の主要ブラウザをお使いください。', | ||
217 | success: 'アップロード成功', | ||
218 | fail: 'アップロード失敗', | ||
219 | preview: 'プレビュー', | ||
220 | btn: { | ||
221 | off: 'キャンセル', | ||
222 | close: '閉じる', | ||
223 | back: '戻る', | ||
224 | save: '保存' | ||
225 | }, | ||
226 | error: { | ||
227 | onlyImg: '画像のみ', | ||
228 | outOfSize: '画像サイズが上限を超えています。上限: ', | ||
229 | lowestPx: '画像が小さすぎます。最小サイズ: ' | ||
230 | } | ||
231 | } | ||
232 | } | ||
233 |
src/components/ImageCropper/utils/mimes.js
File was created | 1 | export default { | |
2 | 'jpg': 'image/jpeg', | ||
3 | 'png': 'image/png', | ||
4 | 'gif': 'image/gif', | ||
5 | 'svg': 'image/svg+xml', | ||
6 | 'psd': 'image/photoshop' | ||
7 | } | ||
8 |
src/components/JsonEditor/index.vue
File was created | 1 | <template> | |
2 | <div class="json-editor"> | ||
3 | <textarea ref="textarea" /> | ||
4 | </div> | ||
5 | </template> | ||
6 | |||
7 | <script> | ||
8 | import CodeMirror from 'codemirror' | ||
9 | import 'codemirror/addon/lint/lint.css' | ||
10 | import 'codemirror/lib/codemirror.css' | ||
11 | import 'codemirror/theme/rubyblue.css' | ||
12 | require('script-loader!jsonlint') | ||
13 | import 'codemirror/mode/javascript/javascript' | ||
14 | import 'codemirror/addon/lint/lint' | ||
15 | import 'codemirror/addon/lint/json-lint' | ||
16 | |||
17 | export default { | ||
18 | name: 'JsonEditor', | ||
19 | /* eslint-disable vue/require-prop-types */ | ||
20 | props: ['value'], | ||
21 | data() { | ||
22 | return { | ||
23 | jsonEditor: false | ||
24 | } | ||
25 | }, | ||
26 | watch: { | ||
27 | value(value) { | ||
28 | const editorValue = this.jsonEditor.getValue() | ||
29 | if (value !== editorValue) { | ||
30 | this.jsonEditor.setValue(JSON.stringify(this.value, null, 2)) | ||
31 | } | ||
32 | } | ||
33 | }, | ||
34 | mounted() { | ||
35 | this.jsonEditor = CodeMirror.fromTextArea(this.$refs.textarea, { | ||
36 | lineNumbers: true, | ||
37 | mode: 'application/json', | ||
38 | gutters: ['CodeMirror-lint-markers'], | ||
39 | theme: 'rubyblue', | ||
40 | lint: true | ||
41 | }) | ||
42 | |||
43 | this.jsonEditor.setValue(JSON.stringify(this.value, null, 2)) | ||
44 | this.jsonEditor.on('change', cm => { | ||
45 | this.$emit('changed', cm.getValue()) | ||
46 | this.$emit('input', cm.getValue()) | ||
47 | }) | ||
48 | }, | ||
49 | methods: { | ||
50 | getValue() { | ||
51 | return this.jsonEditor.getValue() | ||
52 | } | ||
53 | } | ||
54 | } | ||
55 | </script> | ||
56 | |||
57 | <style scoped> | ||
58 | .json-editor{ | ||
59 | height: 100%; | ||
60 | position: relative; | ||
61 | } | ||
62 | .json-editor >>> .CodeMirror { | ||
63 | height: auto; | ||
64 | min-height: 300px; | ||
65 | } | ||
66 | .json-editor >>> .CodeMirror-scroll{ | ||
67 | min-height: 300px; | ||
68 | } | ||
69 | .json-editor >>> .cm-s-rubyblue span.cm-string { | ||
70 | color: #F08047; | ||
71 | } | ||
72 | </style> | ||
73 |
src/components/Kanban/index.vue
File was created | 1 | <template> | |
2 | <div class="board-column"> | ||
3 | <div class="board-column-header"> | ||
4 | {{ headerText }} | ||
5 | </div> | ||
6 | <draggable | ||
7 | :list="list" | ||
8 | v-bind="$attrs" | ||
9 | class="board-column-content" | ||
10 | :set-data="setData" | ||
11 | > | ||
12 | <div v-for="element in list" :key="element.id" class="board-item"> | ||
13 | {{ element.name }} {{ element.id }} | ||
14 | </div> | ||
15 | </draggable> | ||
16 | </div> | ||
17 | </template> | ||
18 | |||
19 | <script> | ||
20 | import draggable from 'vuedraggable' | ||
21 | |||
22 | export default { | ||
23 | name: 'DragKanbanDemo', | ||
24 | components: { | ||
25 | draggable | ||
26 | }, | ||
27 | props: { | ||
28 | headerText: { | ||
29 | type: String, | ||
30 | default: 'Header' | ||
31 | }, | ||
32 | options: { | ||
33 | type: Object, | ||
34 | default() { | ||
35 | return {} | ||
36 | } | ||
37 | }, | ||
38 | list: { | ||
39 | type: Array, | ||
40 | default() { | ||
41 | return [] | ||
42 | } | ||
43 | } | ||
44 | }, | ||
45 | methods: { | ||
46 | setData(dataTransfer) { | ||
47 | // to avoid Firefox bug | ||
48 | // Detail see : https://github.com/RubaXa/Sortable/issues/1012 | ||
49 | dataTransfer.setData('Text', '') | ||
50 | } | ||
51 | } | ||
52 | } | ||
53 | </script> | ||
54 | <style lang="scss" scoped> | ||
55 | .board-column { | ||
56 | min-width: 300px; | ||
57 | min-height: 100px; | ||
58 | height: auto; | ||
59 | overflow: hidden; | ||
60 | background: #f0f0f0; | ||
61 | border-radius: 3px; | ||
62 | |||
63 | .board-column-header { | ||
64 | height: 50px; | ||
65 | line-height: 50px; | ||
66 | overflow: hidden; | ||
67 | padding: 0 20px; | ||
68 | text-align: center; | ||
69 | background: #333; | ||
70 | color: #fff; | ||
71 | border-radius: 3px 3px 0 0; | ||
72 | } | ||
73 | |||
74 | .board-column-content { | ||
75 | height: auto; | ||
76 | overflow: hidden; | ||
77 | border: 10px solid transparent; | ||
78 | min-height: 60px; | ||
79 | display: flex; | ||
80 | justify-content: flex-start; | ||
81 | flex-direction: column; | ||
82 | align-items: center; | ||
83 | |||
84 | .board-item { | ||
85 | cursor: pointer; | ||
86 | width: 100%; | ||
87 | height: 64px; | ||
88 | margin: 5px 0; | ||
89 | background-color: #fff; | ||
90 | text-align: left; | ||
91 | line-height: 54px; | ||
92 | padding: 5px 10px; | ||
93 | box-sizing: border-box; | ||
94 | box-shadow: 0px 1px 3px 0 rgba(0, 0, 0, 0.2); | ||
95 | } | ||
96 | } | ||
97 | } | ||
98 | </style> | ||
99 | |||
100 |
src/components/LangSelect/index.vue
File was created | 1 | <template> | |
2 | <el-dropdown trigger="click" class="international" @command="handleSetLanguage"> | ||
3 | <div> | ||
4 | <svg-icon class-name="international-icon" icon-class="language" /> | ||
5 | </div> | ||
6 | <el-dropdown-menu slot="dropdown"> | ||
7 | <el-dropdown-item :disabled="language==='zh'" command="zh"> | ||
8 | 中文 | ||
9 | </el-dropdown-item> | ||
10 | <el-dropdown-item :disabled="language==='en'" command="en"> | ||
11 | English | ||
12 | </el-dropdown-item> | ||
13 | <el-dropdown-item :disabled="language==='es'" command="es"> | ||
14 | Español | ||
15 | </el-dropdown-item> | ||
16 | <el-dropdown-item :disabled="language==='ja'" command="ja"> | ||
17 | 日本語 | ||
18 | </el-dropdown-item> | ||
19 | </el-dropdown-menu> | ||
20 | </el-dropdown> | ||
21 | </template> | ||
22 | |||
23 | <script> | ||
24 | export default { | ||
25 | computed: { | ||
26 | language() { | ||
27 | return this.$store.getters.language | ||
28 | } | ||
29 | }, | ||
30 | methods: { | ||
31 | handleSetLanguage(lang) { | ||
32 | this.$i18n.locale = lang | ||
33 | this.$store.dispatch('app/setLanguage', lang) | ||
34 | this.$message({ | ||
35 | message: 'Switch Language Success', | ||
36 | type: 'success' | ||
37 | }) | ||
38 | } | ||
39 | } | ||
40 | } | ||
41 | </script> | ||
42 |
src/components/MDinput/index.vue
File was created | 1 | <template> | |
2 | <div :class="computedClasses" class="material-input__component"> | ||
3 | <div :class="{iconClass:icon}"> | ||
4 | <i v-if="icon" :class="['el-icon-' + icon]" class="el-input__icon material-input__icon" /> | ||
5 | <input | ||
6 | v-if="type === 'email'" | ||
7 | v-model="currentValue" | ||
8 | :name="name" | ||
9 | :placeholder="fillPlaceHolder" | ||
10 | :readonly="readonly" | ||
11 | :disabled="disabled" | ||
12 | :autocomplete="autoComplete" | ||
13 | :required="required" | ||
14 | type="email" | ||
15 | class="material-input" | ||
16 | @focus="handleMdFocus" | ||
17 | @blur="handleMdBlur" | ||
18 | @input="handleModelInput" | ||
19 | > | ||
20 | <input | ||
21 | v-if="type === 'url'" | ||
22 | v-model="currentValue" | ||
23 | :name="name" | ||
24 | :placeholder="fillPlaceHolder" | ||
25 | :readonly="readonly" | ||
26 | :disabled="disabled" | ||
27 | :autocomplete="autoComplete" | ||
28 | :required="required" | ||
29 | type="url" | ||
30 | class="material-input" | ||
31 | @focus="handleMdFocus" | ||
32 | @blur="handleMdBlur" | ||
33 | @input="handleModelInput" | ||
34 | > | ||
35 | <input | ||
36 | v-if="type === 'number'" | ||
37 | v-model="currentValue" | ||
38 | :name="name" | ||
39 | :placeholder="fillPlaceHolder" | ||
40 | :step="step" | ||
41 | :readonly="readonly" | ||
42 | :disabled="disabled" | ||
43 | :autocomplete="autoComplete" | ||
44 | :max="max" | ||
45 | :min="min" | ||
46 | :minlength="minlength" | ||
47 | :maxlength="maxlength" | ||
48 | :required="required" | ||
49 | type="number" | ||
50 | class="material-input" | ||
51 | @focus="handleMdFocus" | ||
52 | @blur="handleMdBlur" | ||
53 | @input="handleModelInput" | ||
54 | > | ||
55 | <input | ||
56 | v-if="type === 'password'" | ||
57 | v-model="currentValue" | ||
58 | :name="name" | ||
59 | :placeholder="fillPlaceHolder" | ||
60 | :readonly="readonly" | ||
61 | :disabled="disabled" | ||
62 | :autocomplete="autoComplete" | ||
63 | :max="max" | ||
64 | :min="min" | ||
65 | :required="required" | ||
66 | type="password" | ||
67 | class="material-input" | ||
68 | @focus="handleMdFocus" | ||
69 | @blur="handleMdBlur" | ||
70 | @input="handleModelInput" | ||
71 | > | ||
72 | <input | ||
73 | v-if="type === 'tel'" | ||
74 | v-model="currentValue" | ||
75 | :name="name" | ||
76 | :placeholder="fillPlaceHolder" | ||
77 | :readonly="readonly" | ||
78 | :disabled="disabled" | ||
79 | :autocomplete="autoComplete" | ||
80 | :required="required" | ||
81 | type="tel" | ||
82 | class="material-input" | ||
83 | @focus="handleMdFocus" | ||
84 | @blur="handleMdBlur" | ||
85 | @input="handleModelInput" | ||
86 | > | ||
87 | <input | ||
88 | v-if="type === 'text'" | ||
89 | v-model="currentValue" | ||
90 | :name="name" | ||
91 | :placeholder="fillPlaceHolder" | ||
92 | :readonly="readonly" | ||
93 | :disabled="disabled" | ||
94 | :autocomplete="autoComplete" | ||
95 | :minlength="minlength" | ||
96 | :maxlength="maxlength" | ||
97 | :required="required" | ||
98 | type="text" | ||
99 | class="material-input" | ||
100 | @focus="handleMdFocus" | ||
101 | @blur="handleMdBlur" | ||
102 | @input="handleModelInput" | ||
103 | > | ||
104 | <span class="material-input-bar" /> | ||
105 | <label class="material-label"> | ||
106 | <slot /> | ||
107 | </label> | ||
108 | </div> | ||
109 | </div> | ||
110 | </template> | ||
111 | |||
112 | <script> | ||
113 | // source:https://github.com/wemake-services/vue-material-input/blob/master/src/components/MaterialInput.vue | ||
114 | |||
115 | export default { | ||
116 | name: 'MdInput', | ||
117 | props: { | ||
118 | /* eslint-disable */ | ||
119 | icon: String, | ||
120 | name: String, | ||
121 | type: { | ||
122 | type: String, | ||
123 | default: 'text' | ||
124 | }, | ||
125 | value: [String, Number], | ||
126 | placeholder: String, | ||
127 | readonly: Boolean, | ||
128 | disabled: Boolean, | ||
129 | min: String, | ||
130 | max: String, | ||
131 | step: String, | ||
132 | minlength: Number, | ||
133 | maxlength: Number, | ||
134 | required: { | ||
135 | type: Boolean, | ||
136 | default: true | ||
137 | }, | ||
138 | autoComplete: { | ||
139 | type: String, | ||
140 | default: 'off' | ||
141 | }, | ||
142 | validateEvent: { | ||
143 | type: Boolean, | ||
144 | default: true | ||
145 | } | ||
146 | }, | ||
147 | data() { | ||
148 | return { | ||
149 | currentValue: this.value, | ||
150 | focus: false, | ||
151 | fillPlaceHolder: null | ||
152 | } | ||
153 | }, | ||
154 | computed: { | ||
155 | computedClasses() { | ||
156 | return { | ||
157 | 'material--active': this.focus, | ||
158 | 'material--disabled': this.disabled, | ||
159 | 'material--raised': Boolean(this.focus || this.currentValue) // has value | ||
160 | } | ||
161 | } | ||
162 | }, | ||
163 | watch: { | ||
164 | value(newValue) { | ||
165 | this.currentValue = newValue | ||
166 | } | ||
167 | }, | ||
168 | methods: { | ||
169 | handleModelInput(event) { | ||
170 | const value = event.target.value | ||
171 | this.$emit('input', value) | ||
172 | if (this.$parent.$options.componentName === 'ElFormItem') { | ||
173 | if (this.validateEvent) { | ||
174 | this.$parent.$emit('el.form.change', [value]) | ||
175 | } | ||
176 | } | ||
177 | this.$emit('change', value) | ||
178 | }, | ||
179 | handleMdFocus(event) { | ||
180 | this.focus = true | ||
181 | this.$emit('focus', event) | ||
182 | if (this.placeholder && this.placeholder !== '') { | ||
183 | this.fillPlaceHolder = this.placeholder | ||
184 | } | ||
185 | }, | ||
186 | handleMdBlur(event) { | ||
187 | this.focus = false | ||
188 | this.$emit('blur', event) | ||
189 | this.fillPlaceHolder = null | ||
190 | if (this.$parent.$options.componentName === 'ElFormItem') { | ||
191 | if (this.validateEvent) { | ||
192 | this.$parent.$emit('el.form.blur', [this.currentValue]) | ||
193 | } | ||
194 | } | ||
195 | } | ||
196 | } | ||
197 | } | ||
198 | </script> | ||
199 | |||
200 | <style lang="scss" scoped> | ||
201 | // Fonts: | ||
202 | $font-size-base: 16px; | ||
203 | $font-size-small: 18px; | ||
204 | $font-size-smallest: 12px; | ||
205 | $font-weight-normal: normal; | ||
206 | $font-weight-bold: bold; | ||
207 | $apixel: 1px; | ||
208 | // Utils | ||
209 | $spacer: 12px; | ||
210 | $transition: 0.2s ease all; | ||
211 | $index: 0px; | ||
212 | $index-has-icon: 30px; | ||
213 | // Theme: | ||
214 | $color-white: white; | ||
215 | $color-grey: #9E9E9E; | ||
216 | $color-grey-light: #E0E0E0; | ||
217 | $color-blue: #2196F3; | ||
218 | $color-red: #F44336; | ||
219 | $color-black: black; | ||
220 | // Base clases: | ||
221 | %base-bar-pseudo { | ||
222 | content: ''; | ||
223 | height: 1px; | ||
224 | width: 0; | ||
225 | bottom: 0; | ||
226 | position: absolute; | ||
227 | transition: $transition; | ||
228 | } | ||
229 | |||
230 | // Mixins: | ||
231 | @mixin slided-top() { | ||
232 | top: - ($font-size-base + $spacer); | ||
233 | left: 0; | ||
234 | font-size: $font-size-base; | ||
235 | font-weight: $font-weight-bold; | ||
236 | } | ||
237 | |||
238 | // Component: | ||
239 | .material-input__component { | ||
240 | margin-top: 36px; | ||
241 | position: relative; | ||
242 | * { | ||
243 | box-sizing: border-box; | ||
244 | } | ||
245 | .iconClass { | ||
246 | .material-input__icon { | ||
247 | position: absolute; | ||
248 | left: 0; | ||
249 | line-height: $font-size-base; | ||
250 | color: $color-blue; | ||
251 | top: $spacer; | ||
252 | width: $index-has-icon; | ||
253 | height: $font-size-base; | ||
254 | font-size: $font-size-base; | ||
255 | font-weight: $font-weight-normal; | ||
256 | pointer-events: none; | ||
257 | } | ||
258 | .material-label { | ||
259 | left: $index-has-icon; | ||
260 | } | ||
261 | .material-input { | ||
262 | text-indent: $index-has-icon; | ||
263 | } | ||
264 | } | ||
265 | .material-input { | ||
266 | font-size: $font-size-base; | ||
267 | padding: $spacer $spacer $spacer - $apixel * 10 $spacer / 2; | ||
268 | display: block; | ||
269 | width: 100%; | ||
270 | border: none; | ||
271 | line-height: 1; | ||
272 | border-radius: 0; | ||
273 | &:focus { | ||
274 | outline: none; | ||
275 | border: none; | ||
276 | border-bottom: 1px solid transparent; // fixes the height issue | ||
277 | } | ||
278 | } | ||
279 | .material-label { | ||
280 | font-weight: $font-weight-normal; | ||
281 | position: absolute; | ||
282 | pointer-events: none; | ||
283 | left: $index; | ||
284 | top: 0; | ||
285 | transition: $transition; | ||
286 | font-size: $font-size-small; | ||
287 | } | ||
288 | .material-input-bar { | ||
289 | position: relative; | ||
290 | display: block; | ||
291 | width: 100%; | ||
292 | &:before { | ||
293 | @extend %base-bar-pseudo; | ||
294 | left: 50%; | ||
295 | } | ||
296 | &:after { | ||
297 | @extend %base-bar-pseudo; | ||
298 | right: 50%; | ||
299 | } | ||
300 | } | ||
301 | // Disabled state: | ||
302 | &.material--disabled { | ||
303 | .material-input { | ||
304 | border-bottom-style: dashed; | ||
305 | } | ||
306 | } | ||
307 | // Raised state: | ||
308 | &.material--raised { | ||
309 | .material-label { | ||
310 | @include slided-top(); | ||
311 | } | ||
312 | } | ||
313 | // Active state: | ||
314 | &.material--active { | ||
315 | .material-input-bar { | ||
316 | &:before, | ||
317 | &:after { | ||
318 | width: 50%; | ||
319 | } | ||
320 | } | ||
321 | } | ||
322 | } | ||
323 | |||
324 | .material-input__component { | ||
325 | background: $color-white; | ||
326 | .material-input { | ||
327 | background: none; | ||
328 | color: $color-black; | ||
329 | text-indent: $index; | ||
330 | border-bottom: 1px solid $color-grey-light; | ||
331 | } | ||
332 | .material-label { | ||
333 | color: $color-grey; | ||
334 | } | ||
335 | .material-input-bar { | ||
336 | &:before, | ||
337 | &:after { | ||
338 | background: $color-blue; | ||
339 | } | ||
340 | } | ||
341 | // Active state: | ||
342 | &.material--active { | ||
343 | .material-label { | ||
344 | color: $color-blue; | ||
345 | } | ||
346 | } | ||
347 | // Errors: | ||
348 | &.material--has-errors { | ||
349 | &.material--active .material-label { | ||
350 | color: $color-red; | ||
351 | } | ||
352 | .material-input-bar { | ||
353 | &:before, | ||
354 | &:after { | ||
355 | background: transparent; | ||
356 | } | ||
357 | } | ||
358 | } | ||
359 | } | ||
360 | </style> | ||
361 |
src/components/MarkdownEditor/default-options.js
File was created | 1 | // doc: https://nhnent.github.io/tui.editor/api/latest/ToastUIEditor.html#ToastUIEditor | |
2 | export default { | ||
3 | minHeight: '200px', | ||
4 | previewStyle: 'vertical', | ||
5 | useCommandShortcut: true, | ||
6 | useDefaultHTMLSanitizer: true, | ||
7 | usageStatistics: false, | ||
8 | hideModeSwitch: false, | ||
9 | toolbarItems: [ | ||
10 | 'heading', | ||
11 | 'bold', | ||
12 | 'italic', | ||
13 | 'strike', | ||
14 | 'divider', | ||
15 | 'hr', | ||
16 | 'quote', | ||
17 | 'divider', | ||
18 | 'ul', | ||
19 | 'ol', | ||
20 | 'task', | ||
21 | 'indent', | ||
22 | 'outdent', | ||
23 | 'divider', | ||
24 | 'table', | ||
25 | 'image', | ||
26 | 'link', | ||
27 | 'divider', | ||
28 | 'code', | ||
29 | 'codeblock' | ||
30 | ] | ||
31 | } | ||
32 |
src/components/MarkdownEditor/index.vue
File was created | 1 | <template> | |
2 | <div :id="id" /> | ||
3 | </template> | ||
4 | |||
5 | <script> | ||
6 | // deps for editor | ||
7 | import 'codemirror/lib/codemirror.css' // codemirror | ||
8 | import 'tui-editor/dist/tui-editor.css' // editor ui | ||
9 | import 'tui-editor/dist/tui-editor-contents.css' // editor content | ||
10 | |||
11 | import Editor from 'tui-editor' | ||
12 | import defaultOptions from './default-options' | ||
13 | |||
14 | export default { | ||
15 | name: 'MarkdownEditor', | ||
16 | props: { | ||
17 | value: { | ||
18 | type: String, | ||
19 | default: '' | ||
20 | }, | ||
21 | id: { | ||
22 | type: String, | ||
23 | required: false, | ||
24 | default() { | ||
25 | return 'markdown-editor-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '') | ||
26 | } | ||
27 | }, | ||
28 | options: { | ||
29 | type: Object, | ||
30 | default() { | ||
31 | return defaultOptions | ||
32 | } | ||
33 | }, | ||
34 | mode: { | ||
35 | type: String, | ||
36 | default: 'markdown' | ||
37 | }, | ||
38 | height: { | ||
39 | type: String, | ||
40 | required: false, | ||
41 | default: '300px' | ||
42 | }, | ||
43 | language: { | ||
44 | type: String, | ||
45 | required: false, | ||
46 | default: 'en_US' // https://github.com/nhnent/tui.editor/tree/master/src/js/langs | ||
47 | } | ||
48 | }, | ||
49 | data() { | ||
50 | return { | ||
51 | editor: null | ||
52 | } | ||
53 | }, | ||
54 | computed: { | ||
55 | editorOptions() { | ||
56 | const options = Object.assign({}, defaultOptions, this.options) | ||
57 | options.initialEditType = this.mode | ||
58 | options.height = this.height | ||
59 | options.language = this.language | ||
60 | return options | ||
61 | } | ||
62 | }, | ||
63 | watch: { | ||
64 | value(newValue, preValue) { | ||
65 | if (newValue !== preValue && newValue !== this.editor.getValue()) { | ||
66 | this.editor.setValue(newValue) | ||
67 | } | ||
68 | }, | ||
69 | language(val) { | ||
70 | this.destroyEditor() | ||
71 | this.initEditor() | ||
72 | }, | ||
73 | height(newValue) { | ||
74 | this.editor.height(newValue) | ||
75 | }, | ||
76 | mode(newValue) { | ||
77 | this.editor.changeMode(newValue) | ||
78 | } | ||
79 | }, | ||
80 | mounted() { | ||
81 | this.initEditor() | ||
82 | }, | ||
83 | destroyed() { | ||
84 | this.destroyEditor() | ||
85 | }, | ||
86 | methods: { | ||
87 | initEditor() { | ||
88 | this.editor = new Editor({ | ||
89 | el: document.getElementById(this.id), | ||
90 | ...this.editorOptions | ||
91 | }) | ||
92 | if (this.value) { | ||
93 | this.editor.setValue(this.value) | ||
94 | } | ||
95 | this.editor.on('change', () => { | ||
96 | this.$emit('input', this.editor.getValue()) | ||
97 | }) | ||
98 | }, | ||
99 | destroyEditor() { | ||
100 | if (!this.editor) return | ||
101 | this.editor.off('change') | ||
102 | this.editor.remove() | ||
103 | }, | ||
104 | setValue(value) { | ||
105 | this.editor.setValue(value) | ||
106 | }, | ||
107 | getValue() { | ||
108 | return this.editor.getValue() | ||
109 | }, | ||
110 | setHtml(value) { | ||
111 | this.editor.setHtml(value) | ||
112 | }, | ||
113 | getHtml() { | ||
114 | return this.editor.getHtml() | ||
115 | } | ||
116 | } | ||
117 | } | ||
118 | </script> | ||
119 |
src/components/Pagination/index.vue
File was created | 1 | <template> | |
2 | <div :class="{'hidden':hidden}" class="pagination-container"> | ||
3 | <el-pagination | ||
4 | :background="background" | ||
5 | :current-page.sync="currentPage" | ||
6 | :page-size.sync="pageSize" | ||
7 | :layout="layout" | ||
8 | :page-sizes="pageSizes" | ||
9 | :total="total" | ||
10 | v-bind="$attrs" | ||
11 | @size-change="handleSizeChange" | ||
12 | @current-change="handleCurrentChange" | ||
13 | /> | ||
14 | </div> | ||
15 | </template> | ||
16 | |||
17 | <script> | ||
18 | import { scrollTo } from '@/utils/scroll-to' | ||
19 | |||
20 | export default { | ||
21 | name: 'Pagination', | ||
22 | props: { | ||
23 | total: { | ||
24 | required: true, | ||
25 | type: Number | ||
26 | }, | ||
27 | page: { | ||
28 | type: Number, | ||
29 | default: 1 | ||
30 | }, | ||
31 | limit: { | ||
32 | type: Number, | ||
33 | default: 20 | ||
34 | }, | ||
35 | pageSizes: { | ||
36 | type: Array, | ||
37 | default() { | ||
38 | return [10, 20, 30, 50] | ||
39 | } | ||
40 | }, | ||
41 | layout: { | ||
42 | type: String, | ||
43 | default: 'total, sizes, prev, pager, next, jumper' | ||
44 | }, | ||
45 | background: { | ||
46 | type: Boolean, | ||
47 | default: true | ||
48 | }, | ||
49 | autoScroll: { | ||
50 | type: Boolean, | ||
51 | default: true | ||
52 | }, | ||
53 | hidden: { | ||
54 | type: Boolean, | ||
55 | default: false | ||
56 | } | ||
57 | }, | ||
58 | computed: { | ||
59 | currentPage: { | ||
60 | get() { | ||
61 | return this.page | ||
62 | }, | ||
63 | set(val) { | ||
64 | this.$emit('update:page', val) | ||
65 | } | ||
66 | }, | ||
67 | pageSize: { | ||
68 | get() { | ||
69 | return this.limit | ||
70 | }, | ||
71 | set(val) { | ||
72 | this.$emit('update:limit', val) | ||
73 | } | ||
74 | } | ||
75 | }, | ||
76 | methods: { | ||
77 | handleSizeChange(val) { | ||
78 | this.$emit('pagination', { page: this.currentPage, limit: val }) | ||
79 | if (this.autoScroll) { | ||
80 | scrollTo(0, 800) | ||
81 | } | ||
82 | }, | ||
83 | handleCurrentChange(val) { | ||
84 | this.$emit('pagination', { page: val, limit: this.pageSize }) | ||
85 | if (this.autoScroll) { | ||
86 | scrollTo(0, 800) | ||
87 | } | ||
88 | } | ||
89 | } | ||
90 | } | ||
91 | </script> | ||
92 | |||
93 | <style scoped> | ||
94 | .pagination-container { | ||
95 | background: #fff; | ||
96 | padding: 32px 16px; | ||
97 | } | ||
98 | .pagination-container.hidden { | ||
99 | display: none; | ||
100 | } | ||
101 | </style> | ||
102 |
src/components/PanThumb/index.vue
File was created | 1 | <template> | |
2 | <div :style="{zIndex:zIndex,height:height,width:width}" class="pan-item"> | ||
3 | <div class="pan-info"> | ||
4 | <div class="pan-info-roles-container"> | ||
5 | <slot /> | ||
6 | </div> | ||
7 | </div> | ||
8 | <!-- eslint-disable-next-line --> | ||
9 | <div :style="{backgroundImage: `url(${image})`}" class="pan-thumb"></div> | ||
10 | </div> | ||
11 | </template> | ||
12 | |||
13 | <script> | ||
14 | export default { | ||
15 | name: 'PanThumb', | ||
16 | props: { | ||
17 | image: { | ||
18 | type: String, | ||
19 | required: true | ||
20 | }, | ||
21 | zIndex: { | ||
22 | type: Number, | ||
23 | default: 1 | ||
24 | }, | ||
25 | width: { | ||
26 | type: String, | ||
27 | default: '150px' | ||
28 | }, | ||
29 | height: { | ||
30 | type: String, | ||
31 | default: '150px' | ||
32 | } | ||
33 | } | ||
34 | } | ||
35 | </script> | ||
36 | |||
37 | <style scoped> | ||
38 | .pan-item { | ||
39 | width: 200px; | ||
40 | height: 200px; | ||
41 | border-radius: 50%; | ||
42 | display: inline-block; | ||
43 | position: relative; | ||
44 | cursor: default; | ||
45 | box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); | ||
46 | } | ||
47 | |||
48 | .pan-info-roles-container { | ||
49 | padding: 20px; | ||
50 | text-align: center; | ||
51 | } | ||
52 | |||
53 | .pan-thumb { | ||
54 | width: 100%; | ||
55 | height: 100%; | ||
56 | background-position: center center; | ||
57 | background-size: cover; | ||
58 | border-radius: 50%; | ||
59 | overflow: hidden; | ||
60 | position: absolute; | ||
61 | transform-origin: 95% 40%; | ||
62 | transition: all 0.3s ease-in-out; | ||
63 | } | ||
64 | |||
65 | /* .pan-thumb:after { | ||
66 | content: ''; | ||
67 | width: 8px; | ||
68 | height: 8px; | ||
69 | position: absolute; | ||
70 | border-radius: 50%; | ||
71 | top: 40%; | ||
72 | left: 95%; | ||
73 | margin: -4px 0 0 -4px; | ||
74 | background: radial-gradient(ellipse at center, rgba(14, 14, 14, 1) 0%, rgba(125, 126, 125, 1) 100%); | ||
75 | box-shadow: 0 0 1px rgba(255, 255, 255, 0.9); | ||
76 | } */ | ||
77 | |||
78 | .pan-info { | ||
79 | position: absolute; | ||
80 | width: inherit; | ||
81 | height: inherit; | ||
82 | border-radius: 50%; | ||
83 | overflow: hidden; | ||
84 | box-shadow: inset 0 0 0 5px rgba(0, 0, 0, 0.05); | ||
85 | } | ||
86 | |||
87 | .pan-info h3 { | ||
88 | color: #fff; | ||
89 | text-transform: uppercase; | ||
90 | position: relative; | ||
91 | letter-spacing: 2px; | ||
92 | font-size: 18px; | ||
93 | margin: 0 60px; | ||
94 | padding: 22px 0 0 0; | ||
95 | height: 85px; | ||
96 | font-family: 'Open Sans', Arial, sans-serif; | ||
97 | text-shadow: 0 0 1px #fff, 0 1px 2px rgba(0, 0, 0, 0.3); | ||
98 | } | ||
99 | |||
100 | .pan-info p { | ||
101 | color: #fff; | ||
102 | padding: 10px 5px; | ||
103 | font-style: italic; | ||
104 | margin: 0 30px; | ||
105 | font-size: 12px; | ||
106 | border-top: 1px solid rgba(255, 255, 255, 0.5); | ||
107 | } | ||
108 | |||
109 | .pan-info p a { | ||
110 | display: block; | ||
111 | color: #333; | ||
112 | width: 80px; | ||
113 | height: 80px; | ||
114 | background: rgba(255, 255, 255, 0.3); | ||
115 | border-radius: 50%; | ||
116 | color: #fff; | ||
117 | font-style: normal; | ||
118 | font-weight: 700; | ||
119 | text-transform: uppercase; | ||
120 | font-size: 9px; | ||
121 | letter-spacing: 1px; | ||
122 | padding-top: 24px; | ||
123 | margin: 7px auto 0; | ||
124 | font-family: 'Open Sans', Arial, sans-serif; | ||
125 | opacity: 0; | ||
126 | transition: transform 0.3s ease-in-out 0.2s, opacity 0.3s ease-in-out 0.2s, background 0.2s linear 0s; | ||
127 | transform: translateX(60px) rotate(90deg); | ||
128 | } | ||
129 | |||
130 | .pan-info p a:hover { | ||
131 | background: rgba(255, 255, 255, 0.5); | ||
132 | } | ||
133 | |||
134 | .pan-item:hover .pan-thumb { | ||
135 | transform: rotate(-110deg); | ||
136 | } | ||
137 | |||
138 | .pan-item:hover .pan-info p a { | ||
139 | opacity: 1; | ||
140 | transform: translateX(0px) rotate(0deg); | ||
141 | } | ||
142 | </style> | ||
143 |
src/components/RightPanel/index.vue
File was created | 1 | <template> | |
2 | <div ref="rightPanel" :class="{show:show}" class="rightPanel-container"> | ||
3 | <div class="rightPanel-background" /> | ||
4 | <div class="rightPanel"> | ||
5 | <div class="handle-button" :style="{'top':buttonTop+'px','background-color':theme}" @click="show=!show"> | ||
6 | <i :class="show?'el-icon-close':'el-icon-setting'" /> | ||
7 | </div> | ||
8 | <div class="rightPanel-items"> | ||
9 | <slot /> | ||
10 | </div> | ||
11 | </div> | ||
12 | </div> | ||
13 | </template> | ||
14 | |||
15 | <script> | ||
16 | import { addClass, removeClass } from '@/utils' | ||
17 | |||
18 | export default { | ||
19 | name: 'RightPanel', | ||
20 | props: { | ||
21 | clickNotClose: { | ||
22 | default: false, | ||
23 | type: Boolean | ||
24 | }, | ||
25 | buttonTop: { | ||
26 | default: 250, | ||
27 | type: Number | ||
28 | } | ||
29 | }, | ||
30 | data() { | ||
31 | return { | ||
32 | show: false | ||
33 | } | ||
34 | }, | ||
35 | computed: { | ||
36 | theme() { | ||
37 | return this.$store.state.settings.theme | ||
38 | } | ||
39 | }, | ||
40 | watch: { | ||
41 | show(value) { | ||
42 | if (value && !this.clickNotClose) { | ||
43 | this.addEventClick() | ||
44 | } | ||
45 | if (value) { | ||
46 | addClass(document.body, 'showRightPanel') | ||
47 | } else { | ||
48 | removeClass(document.body, 'showRightPanel') | ||
49 | } | ||
50 | } | ||
51 | }, | ||
52 | mounted() { | ||
53 | this.insertToBody() | ||
54 | }, | ||
55 | beforeDestroy() { | ||
56 | const elx = this.$refs.rightPanel | ||
57 | elx.remove() | ||
58 | }, | ||
59 | methods: { | ||
60 | addEventClick() { | ||
61 | window.addEventListener('click', this.closeSidebar) | ||
62 | }, | ||
63 | closeSidebar(evt) { | ||
64 | const parent = evt.target.closest('.rightPanel') | ||
65 | if (!parent) { | ||
66 | this.show = false | ||
67 | window.removeEventListener('click', this.closeSidebar) | ||
68 | } | ||
69 | }, | ||
70 | insertToBody() { | ||
71 | const elx = this.$refs.rightPanel | ||
72 | const body = document.querySelector('body') | ||
73 | body.insertBefore(elx, body.firstChild) | ||
74 | } | ||
75 | } | ||
76 | } | ||
77 | </script> | ||
78 | |||
79 | <style> | ||
80 | .showRightPanel { | ||
81 | overflow: hidden; | ||
82 | position: relative; | ||
83 | width: calc(100% - 15px); | ||
84 | } | ||
85 | </style> | ||
86 | |||
87 | <style lang="scss" scoped> | ||
88 | .rightPanel-background { | ||
89 | position: fixed; | ||
90 | top: 0; | ||
91 | left: 0; | ||
92 | opacity: 0; | ||
93 | transition: opacity .3s cubic-bezier(.7, .3, .1, 1); | ||
94 | background: rgba(0, 0, 0, .2); | ||
95 | z-index: -1; | ||
96 | } | ||
97 | |||
98 | .rightPanel { | ||
99 | width: 100%; | ||
100 | max-width: 260px; | ||
101 | height: 100vh; | ||
102 | position: fixed; | ||
103 | top: 0; | ||
104 | right: 0; | ||
105 | box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, .05); | ||
106 | transition: all .25s cubic-bezier(.7, .3, .1, 1); | ||
107 | transform: translate(100%); | ||
108 | background: #fff; | ||
109 | z-index: 40000; | ||
110 | } | ||
111 | |||
112 | .show { | ||
113 | transition: all .3s cubic-bezier(.7, .3, .1, 1); | ||
114 | |||
115 | .rightPanel-background { | ||
116 | z-index: 20000; | ||
117 | opacity: 1; | ||
118 | width: 100%; | ||
119 | height: 100%; | ||
120 | } | ||
121 | |||
122 | .rightPanel { | ||
123 | transform: translate(0); | ||
124 | } | ||
125 | } | ||
126 | |||
127 | .handle-button { | ||
128 | width: 48px; | ||
129 | height: 48px; | ||
130 | position: absolute; | ||
131 | left: -48px; | ||
132 | text-align: center; | ||
133 | font-size: 24px; | ||
134 | border-radius: 6px 0 0 6px !important; | ||
135 | z-index: 0; | ||
136 | pointer-events: auto; | ||
137 | cursor: pointer; | ||
138 | color: #fff; | ||
139 | line-height: 48px; | ||
140 | i { | ||
141 | font-size: 24px; | ||
142 | line-height: 48px; | ||
143 | } | ||
144 | } | ||
145 | </style> | ||
146 |
src/components/Screenfull/index.vue
File was created | 1 | <template> | |
2 | <div> | ||
3 | <svg-icon :icon-class="isFullscreen?'exit-fullscreen':'fullscreen'" @click="click" /> | ||
4 | </div> | ||
5 | </template> | ||
6 | |||
7 | <script> | ||
8 | import screenfull from 'screenfull' | ||
9 | |||
10 | export default { | ||
11 | name: 'Screenfull', | ||
12 | data() { | ||
13 | return { | ||
14 | isFullscreen: false | ||
15 | } | ||
16 | }, | ||
17 | mounted() { | ||
18 | this.init() | ||
19 | }, | ||
20 | beforeDestroy() { | ||
21 | this.destroy() | ||
22 | }, | ||
23 | methods: { | ||
24 | click() { | ||
25 | if (!screenfull.enabled) { | ||
26 | this.$message({ | ||
27 | message: 'you browser can not work', | ||
28 | type: 'warning' | ||
29 | }) | ||
30 | return false | ||
31 | } | ||
32 | screenfull.toggle() | ||
33 | }, | ||
34 | change() { | ||
35 | this.isFullscreen = screenfull.isFullscreen | ||
36 | }, | ||
37 | init() { | ||
38 | if (screenfull.enabled) { | ||
39 | screenfull.on('change', this.change) | ||
40 | } | ||
41 | }, | ||
42 | destroy() { | ||
43 | if (screenfull.enabled) { | ||
44 | screenfull.off('change', this.change) | ||
45 | } | ||
46 | } | ||
47 | } | ||
48 | } | ||
49 | </script> | ||
50 | |||
51 | <style scoped> | ||
52 | .screenfull-svg { | ||
53 | display: inline-block; | ||
54 | cursor: pointer; | ||
55 | fill: #5a5e66;; | ||
56 | width: 20px; | ||
57 | height: 20px; | ||
58 | vertical-align: 10px; | ||
59 | } | ||
60 | </style> | ||
61 |
src/components/Share/DropdownMenu.vue
File was created | 1 | <template> | |
2 | <div :class="{active:isActive}" class="share-dropdown-menu"> | ||
3 | <div class="share-dropdown-menu-wrapper"> | ||
4 | <span class="share-dropdown-menu-title" @click.self="clickTitle">{{ title }}</span> | ||
5 | <div v-for="(item,index) of items" :key="index" class="share-dropdown-menu-item"> | ||
6 | <a v-if="item.href" :href="item.href" target="_blank">{{ item.title }}</a> | ||
7 | <span v-else>{{ item.title }}</span> | ||
8 | </div> | ||
9 | </div> | ||
10 | </div> | ||
11 | </template> | ||
12 | |||
13 | <script> | ||
14 | export default { | ||
15 | props: { | ||
16 | items: { | ||
17 | type: Array, | ||
18 | default: function() { | ||
19 | return [] | ||
20 | } | ||
21 | }, | ||
22 | title: { | ||
23 | type: String, | ||
24 | default: 'vue' | ||
25 | } | ||
26 | }, | ||
27 | data() { | ||
28 | return { | ||
29 | isActive: false | ||
30 | } | ||
31 | }, | ||
32 | methods: { | ||
33 | clickTitle() { | ||
34 | this.isActive = !this.isActive | ||
35 | } | ||
36 | } | ||
37 | } | ||
38 | </script> | ||
39 | |||
40 | <style lang="scss" > | ||
41 | $n: 9; //和items.length 相同 | ||
42 | $t: .1s; | ||
43 | .share-dropdown-menu { | ||
44 | width: 250px; | ||
45 | position: relative; | ||
46 | z-index: 1; | ||
47 | height: auto!important; | ||
48 | &-title { | ||
49 | width: 100%; | ||
50 | display: block; | ||
51 | cursor: pointer; | ||
52 | background: black; | ||
53 | color: white; | ||
54 | height: 60px; | ||
55 | line-height: 60px; | ||
56 | font-size: 20px; | ||
57 | text-align: center; | ||
58 | z-index: 2; | ||
59 | transform: translate3d(0,0,0); | ||
60 | } | ||
61 | &-wrapper { | ||
62 | position: relative; | ||
63 | } | ||
64 | &-item { | ||
65 | text-align: center; | ||
66 | position: absolute; | ||
67 | width: 100%; | ||
68 | background: #e0e0e0; | ||
69 | color: #000; | ||
70 | line-height: 60px; | ||
71 | height: 60px; | ||
72 | cursor: pointer; | ||
73 | font-size: 18px; | ||
74 | overflow: hidden; | ||
75 | opacity: 1; | ||
76 | transition: transform 0.28s ease; | ||
77 | &:hover { | ||
78 | background: black; | ||
79 | color: white; | ||
80 | } | ||
81 | @for $i from 1 through $n { | ||
82 | &:nth-of-type(#{$i}) { | ||
83 | z-index: -1; | ||
84 | transition-delay: $i*$t; | ||
85 | transform: translate3d(0, -60px, 0); | ||
86 | } | ||
87 | } | ||
88 | } | ||
89 | &.active { | ||
90 | .share-dropdown-menu-wrapper { | ||
91 | z-index: 1; | ||
92 | } | ||
93 | .share-dropdown-menu-item { | ||
94 | @for $i from 1 through $n { | ||
95 | &:nth-of-type(#{$i}) { | ||
96 | transition-delay: ($n - $i)*$t; | ||
97 | transform: translate3d(0, ($i - 1)*60px, 0); | ||
98 | } | ||
99 | } | ||
100 | } | ||
101 | } | ||
102 | } | ||
103 | </style> | ||
104 |
src/components/SizeSelect/index.vue
File was created | 1 | <template> | |
2 | <el-dropdown trigger="click" @command="handleSetSize"> | ||
3 | <div> | ||
4 | <svg-icon class-name="size-icon" icon-class="size" /> | ||
5 | </div> | ||
6 | <el-dropdown-menu slot="dropdown"> | ||
7 | <el-dropdown-item v-for="item of sizeOptions" :key="item.value" :disabled="size===item.value" :command="item.value"> | ||
8 | {{ | ||
9 | item.label }} | ||
10 | </el-dropdown-item> | ||
11 | </el-dropdown-menu> | ||
12 | </el-dropdown> | ||
13 | </template> | ||
14 | |||
15 | <script> | ||
16 | export default { | ||
17 | data() { | ||
18 | return { | ||
19 | sizeOptions: [ | ||
20 | { label: 'Default', value: 'default' }, | ||
21 | { label: 'Medium', value: 'medium' }, | ||
22 | { label: 'Small', value: 'small' }, | ||
23 | { label: 'Mini', value: 'mini' } | ||
24 | ] | ||
25 | } | ||
26 | }, | ||
27 | computed: { | ||
28 | size() { | ||
29 | return this.$store.getters.size | ||
30 | } | ||
31 | }, | ||
32 | methods: { | ||
33 | handleSetSize(size) { | ||
34 | this.$ELEMENT.size = size | ||
35 | this.$store.dispatch('app/setSize', size) | ||
36 | this.refreshView() | ||
37 | this.$message({ | ||
38 | message: 'Switch Size Success', | ||
39 | type: 'success' | ||
40 | }) | ||
41 | }, | ||
42 | refreshView() { | ||
43 | // In order to make the cached page re-rendered | ||
44 | this.$store.dispatch('tagsView/delAllCachedViews', this.$route) | ||
45 | |||
46 | const { fullPath } = this.$route | ||
47 | |||
48 | this.$nextTick(() => { | ||
49 | this.$router.replace({ | ||
50 | path: '/redirect' + fullPath | ||
51 | }) | ||
52 | }) | ||
53 | } | ||
54 | } | ||
55 | |||
56 | } | ||
57 | </script> | ||
58 |
src/components/Sticky/index.vue
File was created | 1 | <template> | |
2 | <div :style="{height:height+'px',zIndex:zIndex}"> | ||
3 | <div | ||
4 | :class="className" | ||
5 | :style="{top:(isSticky ? stickyTop +'px' : ''),zIndex:zIndex,position:position,width:width,height:height+'px'}" | ||
6 | > | ||
7 | <slot> | ||
8 | <div>sticky</div> | ||
9 | </slot> | ||
10 | </div> | ||
11 | </div> | ||
12 | </template> | ||
13 | |||
14 | <script> | ||
15 | export default { | ||
16 | name: 'Sticky', | ||
17 | props: { | ||
18 | stickyTop: { | ||
19 | type: Number, | ||
20 | default: 0 | ||
21 | }, | ||
22 | zIndex: { | ||
23 | type: Number, | ||
24 | default: 1 | ||
25 | }, | ||
26 | className: { | ||
27 | type: String, | ||
28 | default: '' | ||
29 | } | ||
30 | }, | ||
31 | data() { | ||
32 | return { | ||
33 | active: false, | ||
34 | position: '', | ||
35 | width: undefined, | ||
36 | height: undefined, | ||
37 | isSticky: false | ||
38 | } | ||
39 | }, | ||
40 | mounted() { | ||
41 | this.height = this.$el.getBoundingClientRect().height | ||
42 | window.addEventListener('scroll', this.handleScroll) | ||
43 | window.addEventListener('resize', this.handleResize) | ||
44 | }, | ||
45 | activated() { | ||
46 | this.handleScroll() | ||
47 | }, | ||
48 | destroyed() { | ||
49 | window.removeEventListener('scroll', this.handleScroll) | ||
50 | window.removeEventListener('resize', this.handleResize) | ||
51 | }, | ||
52 | methods: { | ||
53 | sticky() { | ||
54 | if (this.active) { | ||
55 | return | ||
56 | } | ||
57 | this.position = 'fixed' | ||
58 | this.active = true | ||
59 | this.width = this.width + 'px' | ||
60 | this.isSticky = true | ||
61 | }, | ||
62 | handleReset() { | ||
63 | if (!this.active) { | ||
64 | return | ||
65 | } | ||
66 | this.reset() | ||
67 | }, | ||
68 | reset() { | ||
69 | this.position = '' | ||
70 | this.width = 'auto' | ||
71 | this.active = false | ||
72 | this.isSticky = false | ||
73 | }, | ||
74 | handleScroll() { | ||
75 | const width = this.$el.getBoundingClientRect().width | ||
76 | this.width = width || 'auto' | ||
77 | const offsetTop = this.$el.getBoundingClientRect().top | ||
78 | if (offsetTop < this.stickyTop) { | ||
79 | this.sticky() | ||
80 | return | ||
81 | } | ||
82 | this.handleReset() | ||
83 | }, | ||
84 | handleResize() { | ||
85 | if (this.isSticky) { | ||
86 | this.width = this.$el.getBoundingClientRect().width + 'px' | ||
87 | } | ||
88 | } | ||
89 | } | ||
90 | } | ||
91 | </script> | ||
92 |
1 | <template> | 1 | <template> |
2 | <div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" /> | 2 | <div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" /> |
3 | <svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners"> | 3 | <svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners"> |
4 | <use :href="iconName" /> | 4 | <use :href="iconName" /> |
5 | </svg> | 5 | </svg> |
6 | </template> | 6 | </template> |
7 | 7 | ||
8 | <script> | 8 | <script> |
9 | // doc: https://panjiachen.github.io/vue-element-admin-site/feature/component/svg-icon.html#usage | 9 | // doc: https://panjiachen.github.io/vue-element-admin-site/feature/component/svg-icon.html#usage |
10 | import { isExternal } from '@/utils/validate' | 10 | import { isExternal } from '@/utils/validate' |
11 | 11 | ||
12 | export default { | 12 | export default { |
13 | name: 'SvgIcon', | 13 | name: 'SvgIcon', |
14 | props: { | 14 | props: { |
15 | iconClass: { | 15 | iconClass: { |
16 | type: String, | 16 | type: String, |
17 | required: true | 17 | required: true |
18 | }, | 18 | }, |
19 | className: { | 19 | className: { |
20 | type: String, | 20 | type: String, |
21 | default: '' | 21 | default: '' |
22 | } | 22 | } |
23 | }, | 23 | }, |
24 | computed: { | 24 | computed: { |
25 | isExternal() { | 25 | isExternal() { |
26 | return isExternal(this.iconClass) | 26 | return isExternal(this.iconClass) |
27 | }, | 27 | }, |
28 | iconName() { | 28 | iconName() { |
29 | return `#icon-${this.iconClass}` | 29 | return `#icon-${this.iconClass}` |
30 | }, | 30 | }, |
31 | svgClass() { | 31 | svgClass() { |
32 | if (this.className) { | 32 | if (this.className) { |
33 | return 'svg-icon ' + this.className | 33 | return 'svg-icon ' + this.className |
34 | } else { | 34 | } else { |
35 | return 'svg-icon' | 35 | return 'svg-icon' |
36 | } | 36 | } |
37 | }, | 37 | }, |
38 | styleExternalIcon() { | 38 | styleExternalIcon() { |
39 | return { | 39 | return { |
40 | mask: `url(${this.iconClass}) no-repeat 50% 50%`, | 40 | mask: `url(${this.iconClass}) no-repeat 50% 50%`, |
41 | '-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%` | 41 | '-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%` |
42 | } | 42 | } |
43 | } | 43 | } |
44 | } | 44 | } |
45 | } | 45 | } |
46 | </script> | 46 | </script> |
47 | 47 | ||
48 | <style scoped> | 48 | <style scoped> |
49 | .svg-icon { | 49 | .svg-icon { |
50 | width: 1em; | 50 | width: 1em; |
51 | height: 1em; | 51 | height: 1em; |
52 | vertical-align: -0.15em; | 52 | vertical-align: -0.15em; |
53 | fill: currentColor; | 53 | fill: currentColor; |
54 | overflow: hidden; | 54 | overflow: hidden; |
55 | } | 55 | } |
56 | 56 | ||
57 | .svg-external-icon { | 57 | .svg-external-icon { |
58 | background-color: currentColor; | 58 | background-color: currentColor; |
59 | mask-size: cover!important; | 59 | mask-size: cover!important; |
60 | display: inline-block; | 60 | display: inline-block; |
61 | } | 61 | } |
62 | </style> | 62 | </style> |
63 | 63 |
src/components/TextHoverEffect/Mallki.vue
File was created | 1 | <template> | |
2 | <a :class="className" class="link--mallki" href="#"> | ||
3 | {{ text }} | ||
4 | <span :data-letters="text" /> | ||
5 | <span :data-letters="text" /> | ||
6 | </a> | ||
7 | </template> | ||
8 | |||
9 | <script> | ||
10 | export default { | ||
11 | props: { | ||
12 | className: { | ||
13 | type: String, | ||
14 | default: '' | ||
15 | }, | ||
16 | text: { | ||
17 | type: String, | ||
18 | default: 'vue-element-admin' | ||
19 | } | ||
20 | } | ||
21 | } | ||
22 | </script> | ||
23 | |||
24 | <style> | ||
25 | /* Mallki */ | ||
26 | |||
27 | .link--mallki { | ||
28 | font-weight: 800; | ||
29 | color: #4dd9d5; | ||
30 | font-family: 'Dosis', sans-serif; | ||
31 | -webkit-transition: color 0.5s 0.25s; | ||
32 | transition: color 0.5s 0.25s; | ||
33 | overflow: hidden; | ||
34 | position: relative; | ||
35 | display: inline-block; | ||
36 | line-height: 1; | ||
37 | outline: none; | ||
38 | text-decoration: none; | ||
39 | } | ||
40 | |||
41 | .link--mallki:hover { | ||
42 | -webkit-transition: none; | ||
43 | transition: none; | ||
44 | color: transparent; | ||
45 | } | ||
46 | |||
47 | .link--mallki::before { | ||
48 | content: ''; | ||
49 | width: 100%; | ||
50 | height: 6px; | ||
51 | margin: -3px 0 0 0; | ||
52 | background: #3888fa; | ||
53 | position: absolute; | ||
54 | left: 0; | ||
55 | top: 50%; | ||
56 | -webkit-transform: translate3d(-100%, 0, 0); | ||
57 | transform: translate3d(-100%, 0, 0); | ||
58 | -webkit-transition: -webkit-transform 0.4s; | ||
59 | transition: transform 0.4s; | ||
60 | -webkit-transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); | ||
61 | transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); | ||
62 | } | ||
63 | |||
64 | .link--mallki:hover::before { | ||
65 | -webkit-transform: translate3d(100%, 0, 0); | ||
66 | transform: translate3d(100%, 0, 0); | ||
67 | } | ||
68 | |||
69 | .link--mallki span { | ||
70 | position: absolute; | ||
71 | height: 50%; | ||
72 | width: 100%; | ||
73 | left: 0; | ||
74 | top: 0; | ||
75 | overflow: hidden; | ||
76 | } | ||
77 | |||
78 | .link--mallki span::before { | ||
79 | content: attr(data-letters); | ||
80 | color: red; | ||
81 | position: absolute; | ||
82 | left: 0; | ||
83 | width: 100%; | ||
84 | color: #3888fa; | ||
85 | -webkit-transition: -webkit-transform 0.5s; | ||
86 | transition: transform 0.5s; | ||
87 | } | ||
88 | |||
89 | .link--mallki span:nth-child(2) { | ||
90 | top: 50%; | ||
91 | } | ||
92 | |||
93 | .link--mallki span:first-child::before { | ||
94 | top: 0; | ||
95 | -webkit-transform: translate3d(0, 100%, 0); | ||
96 | transform: translate3d(0, 100%, 0); | ||
97 | } | ||
98 | |||
99 | .link--mallki span:nth-child(2)::before { | ||
100 | bottom: 0; | ||
101 | -webkit-transform: translate3d(0, -100%, 0); | ||
102 | transform: translate3d(0, -100%, 0); | ||
103 | } | ||
104 | |||
105 | .link--mallki:hover span::before { | ||
106 | -webkit-transition-delay: 0.3s; | ||
107 | transition-delay: 0.3s; | ||
108 | -webkit-transform: translate3d(0, 0, 0); | ||
109 | transform: translate3d(0, 0, 0); | ||
110 | -webkit-transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1); | ||
111 | transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1); | ||
112 | } | ||
113 | </style> | ||
114 |
src/components/ThemePicker/index.vue
File was created | 1 | <template> | |
2 | <el-color-picker | ||
3 | v-model="theme" | ||
4 | :predefine="['#409EFF', '#1890ff', '#304156','#212121','#11a983', '#13c2c2', '#6959CD', '#f5222d', ]" | ||
5 | class="theme-picker" | ||
6 | popper-class="theme-picker-dropdown" | ||
7 | /> | ||
8 | </template> | ||
9 | |||
10 | <script> | ||
11 | const version = require('element-ui/package.json').version // element-ui version from node_modules | ||
12 | const ORIGINAL_THEME = '#409EFF' // default color | ||
13 | |||
14 | export default { | ||
15 | data() { | ||
16 | return { | ||
17 | chalk: '', // content of theme-chalk css | ||
18 | theme: '' | ||
19 | } | ||
20 | }, | ||
21 | computed: { | ||
22 | defaultTheme() { | ||
23 | return this.$store.state.settings.theme | ||
24 | } | ||
25 | }, | ||
26 | watch: { | ||
27 | defaultTheme: { | ||
28 | handler: function(val, oldVal) { | ||
29 | this.theme = val | ||
30 | }, | ||
31 | immediate: true | ||
32 | }, | ||
33 | async theme(val) { | ||
34 | const oldVal = this.chalk ? this.theme : ORIGINAL_THEME | ||
35 | if (typeof val !== 'string') return | ||
36 | const themeCluster = this.getThemeCluster(val.replace('#', '')) | ||
37 | const originalCluster = this.getThemeCluster(oldVal.replace('#', '')) | ||
38 | console.log(themeCluster, originalCluster) | ||
39 | |||
40 | const $message = this.$message({ | ||
41 | message: ' Compiling the theme', | ||
42 | customClass: 'theme-message', | ||
43 | type: 'success', | ||
44 | duration: 0, | ||
45 | iconClass: 'el-icon-loading' | ||
46 | }) | ||
47 | |||
48 | const getHandler = (variable, id) => { | ||
49 | return () => { | ||
50 | const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', '')) | ||
51 | const newStyle = this.updateStyle(this[variable], originalCluster, themeCluster) | ||
52 | |||
53 | let styleTag = document.getElementById(id) | ||
54 | if (!styleTag) { | ||
55 | styleTag = document.createElement('style') | ||
56 | styleTag.setAttribute('id', id) | ||
57 | document.head.appendChild(styleTag) | ||
58 | } | ||
59 | styleTag.innerText = newStyle | ||
60 | } | ||
61 | } | ||
62 | |||
63 | if (!this.chalk) { | ||
64 | const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css` | ||
65 | await this.getCSSString(url, 'chalk') | ||
66 | } | ||
67 | |||
68 | const chalkHandler = getHandler('chalk', 'chalk-style') | ||
69 | |||
70 | chalkHandler() | ||
71 | |||
72 | const styles = [].slice.call(document.querySelectorAll('style')) | ||
73 | .filter(style => { | ||
74 | const text = style.innerText | ||
75 | return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text) | ||
76 | }) | ||
77 | styles.forEach(style => { | ||
78 | const { innerText } = style | ||
79 | if (typeof innerText !== 'string') return | ||
80 | style.innerText = this.updateStyle(innerText, originalCluster, themeCluster) | ||
81 | }) | ||
82 | |||
83 | this.$emit('change', val) | ||
84 | |||
85 | $message.close() | ||
86 | } | ||
87 | }, | ||
88 | |||
89 | methods: { | ||
90 | updateStyle(style, oldCluster, newCluster) { | ||
91 | let newStyle = style | ||
92 | oldCluster.forEach((color, index) => { | ||
93 | newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index]) | ||
94 | }) | ||
95 | return newStyle | ||
96 | }, | ||
97 | |||
98 | getCSSString(url, variable) { | ||
99 | return new Promise(resolve => { | ||
100 | const xhr = new XMLHttpRequest() | ||
101 | xhr.onreadystatechange = () => { | ||
102 | if (xhr.readyState === 4 && xhr.status === 200) { | ||
103 | this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '') | ||
104 | resolve() | ||
105 | } | ||
106 | } | ||
107 | xhr.open('GET', url) | ||
108 | xhr.send() | ||
109 | }) | ||
110 | }, | ||
111 | |||
112 | getThemeCluster(theme) { | ||
113 | const tintColor = (color, tint) => { | ||
114 | let red = parseInt(color.slice(0, 2), 16) | ||
115 | let green = parseInt(color.slice(2, 4), 16) | ||
116 | let blue = parseInt(color.slice(4, 6), 16) | ||
117 | |||
118 | if (tint === 0) { // when primary color is in its rgb space | ||
119 | return [red, green, blue].join(',') | ||
120 | } else { | ||
121 | red += Math.round(tint * (255 - red)) | ||
122 | green += Math.round(tint * (255 - green)) | ||
123 | blue += Math.round(tint * (255 - blue)) | ||
124 | |||
125 | red = red.toString(16) | ||
126 | green = green.toString(16) | ||
127 | blue = blue.toString(16) | ||
128 | |||
129 | return `#${red}${green}${blue}` | ||
130 | } | ||
131 | } | ||
132 | |||
133 | const shadeColor = (color, shade) => { | ||
134 | let red = parseInt(color.slice(0, 2), 16) | ||
135 | let green = parseInt(color.slice(2, 4), 16) | ||
136 | let blue = parseInt(color.slice(4, 6), 16) | ||
137 | |||
138 | red = Math.round((1 - shade) * red) | ||
139 | green = Math.round((1 - shade) * green) | ||
140 | blue = Math.round((1 - shade) * blue) | ||
141 | |||
142 | red = red.toString(16) | ||
143 | green = green.toString(16) | ||
144 | blue = blue.toString(16) | ||
145 | |||
146 | return `#${red}${green}${blue}` | ||
147 | } | ||
148 | |||
149 | const clusters = [theme] | ||
150 | for (let i = 0; i <= 9; i++) { | ||
151 | clusters.push(tintColor(theme, Number((i / 10).toFixed(2)))) | ||
152 | } | ||
153 | clusters.push(shadeColor(theme, 0.1)) | ||
154 | return clusters | ||
155 | } | ||
156 | } | ||
157 | } | ||
158 | </script> | ||
159 | |||
160 | <style> | ||
161 | .theme-message, | ||
162 | .theme-picker-dropdown { | ||
163 | z-index: 99999 !important; | ||
164 | } | ||
165 | |||
166 | .theme-picker .el-color-picker__trigger { | ||
167 | height: 26px !important; | ||
168 | width: 26px !important; | ||
169 | padding: 2px; | ||
170 | } | ||
171 | |||
172 | .theme-picker-dropdown .el-color-dropdown__link-btn { | ||
173 | display: none; | ||
174 | } | ||
175 | </style> | ||
176 |
src/components/Tinymce/components/EditorImage.vue
File was created | 1 | <template> | |
2 | <div class="upload-container"> | ||
3 | <el-button :style="{background:color,borderColor:color}" icon="el-icon-upload" size="mini" type="primary" @click=" dialogVisible=true"> | ||
4 | upload | ||
5 | </el-button> | ||
6 | <el-dialog :visible.sync="dialogVisible"> | ||
7 | <el-upload | ||
8 | :multiple="true" | ||
9 | :file-list="fileList" | ||
10 | :show-file-list="true" | ||
11 | :on-remove="handleRemove" | ||
12 | :on-success="handleSuccess" | ||
13 | :before-upload="beforeUpload" | ||
14 | class="editor-slide-upload" | ||
15 | action="https://httpbin.org/post" | ||
16 | list-type="picture-card" | ||
17 | > | ||
18 | <el-button size="small" type="primary"> | ||
19 | Click upload | ||
20 | </el-button> | ||
21 | </el-upload> | ||
22 | <el-button @click="dialogVisible = false"> | ||
23 | Cancel | ||
24 | </el-button> | ||
25 | <el-button type="primary" @click="handleSubmit"> | ||
26 | Confirm | ||
27 | </el-button> | ||
28 | </el-dialog> | ||
29 | </div> | ||
30 | </template> | ||
31 | |||
32 | <script> | ||
33 | // import { getToken } from 'api/qiniu' | ||
34 | |||
35 | export default { | ||
36 | name: 'EditorSlideUpload', | ||
37 | props: { | ||
38 | color: { | ||
39 | type: String, | ||
40 | default: '#1890ff' | ||
41 | } | ||
42 | }, | ||
43 | data() { | ||
44 | return { | ||
45 | dialogVisible: false, | ||
46 | listObj: {}, | ||
47 | fileList: [] | ||
48 | } | ||
49 | }, | ||
50 | methods: { | ||
51 | checkAllSuccess() { | ||
52 | return Object.keys(this.listObj).every(item => this.listObj[item].hasSuccess) | ||
53 | }, | ||
54 | handleSubmit() { | ||
55 | const arr = Object.keys(this.listObj).map(v => this.listObj[v]) | ||
56 | if (!this.checkAllSuccess()) { | ||
57 | this.$message('Please wait for all images to be uploaded successfully. If there is a network problem, please refresh the page and upload again!') | ||
58 | return | ||
59 | } | ||
60 | this.$emit('successCBK', arr) | ||
61 | this.listObj = {} | ||
62 | this.fileList = [] | ||
63 | this.dialogVisible = false | ||
64 | }, | ||
65 | handleSuccess(response, file) { | ||
66 | const uid = file.uid | ||
67 | const objKeyArr = Object.keys(this.listObj) | ||
68 | for (let i = 0, len = objKeyArr.length; i < len; i++) { | ||
69 | if (this.listObj[objKeyArr[i]].uid === uid) { | ||
70 | this.listObj[objKeyArr[i]].url = response.files.file | ||
71 | this.listObj[objKeyArr[i]].hasSuccess = true | ||
72 | return | ||
73 | } | ||
74 | } | ||
75 | }, | ||
76 | handleRemove(file) { | ||
77 | const uid = file.uid | ||
78 | const objKeyArr = Object.keys(this.listObj) | ||
79 | for (let i = 0, len = objKeyArr.length; i < len; i++) { | ||
80 | if (this.listObj[objKeyArr[i]].uid === uid) { | ||
81 | delete this.listObj[objKeyArr[i]] | ||
82 | return | ||
83 | } | ||
84 | } | ||
85 | }, | ||
86 | beforeUpload(file) { | ||
87 | const _self = this | ||
88 | const _URL = window.URL || window.webkitURL | ||
89 | const fileName = file.uid | ||
90 | this.listObj[fileName] = {} | ||
91 | return new Promise((resolve, reject) => { | ||
92 | const img = new Image() | ||
93 | img.src = _URL.createObjectURL(file) | ||
94 | img.onload = function() { | ||
95 | _self.listObj[fileName] = { hasSuccess: false, uid: file.uid, width: this.width, height: this.height } | ||
96 | } | ||
97 | resolve(true) | ||
98 | }) | ||
99 | } | ||
100 | } | ||
101 | } | ||
102 | </script> | ||
103 | |||
104 | <style lang="scss" scoped> | ||
105 | .editor-slide-upload { | ||
106 | margin-bottom: 20px; | ||
107 | /deep/ .el-upload--picture-card { | ||
108 | width: 100%; | ||
109 | } | ||
110 | } | ||
111 | </style> | ||
112 |
src/components/Tinymce/dynamicLoadScript.js
File was created | 1 | let callbacks = [] | |
2 | |||
3 | function loadedTinymce() { | ||
4 | // to fixed https://github.com/PanJiaChen/vue-element-admin/issues/2144 | ||
5 | // check is successfully downloaded script | ||
6 | return window.tinymce | ||
7 | } | ||
8 | |||
9 | const dynamicLoadScript = (src, callback) => { | ||
10 | const existingScript = document.getElementById(src) | ||
11 | const cb = callback || function() {} | ||
12 | |||
13 | if (!existingScript) { | ||
14 | const script = document.createElement('script') | ||
15 | script.src = src // src url for the third-party library being loaded. | ||
16 | script.id = src | ||
17 | document.body.appendChild(script) | ||
18 | callbacks.push(cb) | ||
19 | const onEnd = 'onload' in script ? stdOnEnd : ieOnEnd | ||
20 | onEnd(script) | ||
21 | } | ||
22 | |||
23 | if (existingScript && cb) { | ||
24 | if (loadedTinymce()) { | ||
25 | cb(null, existingScript) | ||
26 | } else { | ||
27 | callbacks.push(cb) | ||
28 | } | ||
29 | } | ||
30 | |||
31 | function stdOnEnd(script) { | ||
32 | script.onload = function() { | ||
33 | // this.onload = null here is necessary | ||
34 | // because even IE9 works not like others | ||
35 | this.onerror = this.onload = null | ||
36 | for (const cb of callbacks) { | ||
37 | cb(null, script) | ||
38 | } | ||
39 | callbacks = null | ||
40 | } | ||
41 | script.onerror = function() { | ||
42 | this.onerror = this.onload = null | ||
43 | cb(new Error('Failed to load ' + src), script) | ||
44 | } | ||
45 | } | ||
46 | |||
47 | function ieOnEnd(script) { | ||
48 | script.onreadystatechange = function() { | ||
49 | if (this.readyState !== 'complete' && this.readyState !== 'loaded') return | ||
50 | this.onreadystatechange = null | ||
51 | for (const cb of callbacks) { | ||
52 | cb(null, script) // there is no way to catch loading errors in IE8 | ||
53 | } | ||
54 | callbacks = null | ||
55 | } | ||
56 | } | ||
57 | } | ||
58 | |||
59 | export default dynamicLoadScript | ||
60 |
src/components/Tinymce/index.vue
File was created | 1 | <template> | |
2 | <div :class="{fullscreen:fullscreen}" class="tinymce-container" :style="{width:containerWidth}"> | ||
3 | <textarea :id="tinymceId" class="tinymce-textarea" /> | ||
4 | <div class="editor-custom-btn-container"> | ||
5 | <editorImage color="#1890ff" class="editor-upload-btn" @successCBK="imageSuccessCBK" /> | ||
6 | </div> | ||
7 | </div> | ||
8 | </template> | ||
9 | |||
10 | <script> | ||
11 | /** | ||
12 | * docs: | ||
13 | * https://panjiachen.github.io/vue-element-admin-site/feature/component/rich-editor.html#tinymce | ||
14 | */ | ||
15 | import editorImage from './components/EditorImage' | ||
16 | import plugins from './plugins' | ||
17 | import toolbar from './toolbar' | ||
18 | import load from './dynamicLoadScript' | ||
19 | |||
20 | // why use this cdn, detail see https://github.com/PanJiaChen/tinymce-all-in-one | ||
21 | const tinymceCDN = 'https://cdn.jsdelivr.net/npm/tinymce-all-in-one@4.9.3/tinymce.min.js' | ||
22 | |||
23 | export default { | ||
24 | name: 'Tinymce', | ||
25 | components: { editorImage }, | ||
26 | props: { | ||
27 | id: { | ||
28 | type: String, | ||
29 | default: function() { | ||
30 | return 'vue-tinymce-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '') | ||
31 | } | ||
32 | }, | ||
33 | value: { | ||
34 | type: String, | ||
35 | default: '' | ||
36 | }, | ||
37 | toolbar: { | ||
38 | type: Array, | ||
39 | required: false, | ||
40 | default() { | ||
41 | return [] | ||
42 | } | ||
43 | }, | ||
44 | menubar: { | ||
45 | type: String, | ||
46 | default: 'file edit insert view format table' | ||
47 | }, | ||
48 | height: { | ||
49 | type: [Number, String], | ||
50 | required: false, | ||
51 | default: 360 | ||
52 | }, | ||
53 | width: { | ||
54 | type: [Number, String], | ||
55 | required: false, | ||
56 | default: 'auto' | ||
57 | } | ||
58 | }, | ||
59 | data() { | ||
60 | return { | ||
61 | hasChange: false, | ||
62 | hasInit: false, | ||
63 | tinymceId: this.id, | ||
64 | fullscreen: false, | ||
65 | languageTypeList: { | ||
66 | 'en': 'en', | ||
67 | 'zh': 'zh_CN', | ||
68 | 'es': 'es_MX', | ||
69 | 'ja': 'ja' | ||
70 | } | ||
71 | } | ||
72 | }, | ||
73 | computed: { | ||
74 | language() { | ||
75 | return this.languageTypeList[this.$store.getters.language] | ||
76 | }, | ||
77 | containerWidth() { | ||
78 | const width = this.width | ||
79 | if (/^[\d]+(\.[\d]+)?$/.test(width)) { // matches `100`, `'100'` | ||
80 | return `${width}px` | ||
81 | } | ||
82 | return width | ||
83 | } | ||
84 | }, | ||
85 | watch: { | ||
86 | value(val) { | ||
87 | if (!this.hasChange && this.hasInit) { | ||
88 | this.$nextTick(() => | ||
89 | window.tinymce.get(this.tinymceId).setContent(val || '')) | ||
90 | } | ||
91 | }, | ||
92 | language() { | ||
93 | this.destroyTinymce() | ||
94 | this.$nextTick(() => this.initTinymce()) | ||
95 | } | ||
96 | }, | ||
97 | mounted() { | ||
98 | this.init() | ||
99 | }, | ||
100 | activated() { | ||
101 | if (window.tinymce) { | ||
102 | this.initTinymce() | ||
103 | } | ||
104 | }, | ||
105 | deactivated() { | ||
106 | this.destroyTinymce() | ||
107 | }, | ||
108 | destroyed() { | ||
109 | this.destroyTinymce() | ||
110 | }, | ||
111 | methods: { | ||
112 | init() { | ||
113 | // dynamic load tinymce from cdn | ||
114 | load(tinymceCDN, (err) => { | ||
115 | if (err) { | ||
116 | this.$message.error(err.message) | ||
117 | return | ||
118 | } | ||
119 | this.initTinymce() | ||
120 | }) | ||
121 | }, | ||
122 | initTinymce() { | ||
123 | const _this = this | ||
124 | window.tinymce.init({ | ||
125 | language: this.language, | ||
126 | selector: `#${this.tinymceId}`, | ||
127 | height: this.height, | ||
128 | body_class: 'panel-body ', | ||
129 | object_resizing: false, | ||
130 | toolbar: this.toolbar.length > 0 ? this.toolbar : toolbar, | ||
131 | menubar: this.menubar, | ||
132 | plugins: plugins, | ||
133 | end_container_on_empty_block: true, | ||
134 | powerpaste_word_import: 'clean', | ||
135 | code_dialog_height: 450, | ||
136 | code_dialog_width: 1000, | ||
137 | advlist_bullet_styles: 'square', | ||
138 | advlist_number_styles: 'default', | ||
139 | imagetools_cors_hosts: ['www.tinymce.com', 'codepen.io'], | ||
140 | default_link_target: '_blank', | ||
141 | link_title: false, | ||
142 | nonbreaking_force_tab: true, // inserting nonbreaking space need Nonbreaking Space Plugin | ||
143 | init_instance_callback: editor => { | ||
144 | if (_this.value) { | ||
145 | editor.setContent(_this.value) | ||
146 | } | ||
147 | _this.hasInit = true | ||
148 | editor.on('NodeChange Change KeyUp SetContent', () => { | ||
149 | this.hasChange = true | ||
150 | this.$emit('input', editor.getContent()) | ||
151 | }) | ||
152 | }, | ||
153 | setup(editor) { | ||
154 | editor.on('FullscreenStateChanged', (e) => { | ||
155 | _this.fullscreen = e.state | ||
156 | }) | ||
157 | } | ||
158 | // 整合七牛上传 | ||
159 | // images_dataimg_filter(img) { | ||
160 | // setTimeout(() => { | ||
161 | // const $image = $(img); | ||
162 | // $image.removeAttr('width'); | ||
163 | // $image.removeAttr('height'); | ||
164 | // if ($image[0].height && $image[0].width) { | ||
165 | // $image.attr('data-wscntype', 'image'); | ||
166 | // $image.attr('data-wscnh', $image[0].height); | ||
167 | // $image.attr('data-wscnw', $image[0].width); | ||
168 | // $image.addClass('wscnph'); | ||
169 | // } | ||
170 | // }, 0); | ||
171 | // return img | ||
172 | // }, | ||
173 | // images_upload_handler(blobInfo, success, failure, progress) { | ||
174 | // progress(0); | ||
175 | // const token = _this.$store.getters.token; | ||
176 | // getToken(token).then(response => { | ||
177 | // const url = response.data.qiniu_url; | ||
178 | // const formData = new FormData(); | ||
179 | // formData.append('token', response.data.qiniu_token); | ||
180 | // formData.append('key', response.data.qiniu_key); | ||
181 | // formData.append('file', blobInfo.blob(), url); | ||
182 | // upload(formData).then(() => { | ||
183 | // success(url); | ||
184 | // progress(100); | ||
185 | // }) | ||
186 | // }).catch(err => { | ||
187 | // failure('出现未知问题,刷新页面,或者联系程序员') | ||
188 | // console.log(err); | ||
189 | // }); | ||
190 | // }, | ||
191 | }) | ||
192 | }, | ||
193 | destroyTinymce() { | ||
194 | const tinymce = window.tinymce.get(this.tinymceId) | ||
195 | if (this.fullscreen) { | ||
196 | tinymce.execCommand('mceFullScreen') | ||
197 | } | ||
198 | |||
199 | if (tinymce) { | ||
200 | tinymce.destroy() | ||
201 | } | ||
202 | }, | ||
203 | setContent(value) { | ||
204 | window.tinymce.get(this.tinymceId).setContent(value) | ||
205 | }, | ||
206 | getContent() { | ||
207 | window.tinymce.get(this.tinymceId).getContent() | ||
208 | }, | ||
209 | imageSuccessCBK(arr) { | ||
210 | const _this = this | ||
211 | arr.forEach(v => { | ||
212 | window.tinymce.get(_this.tinymceId).insertContent(`<img class="wscnph" src="${v.url}" >`) | ||
213 | }) | ||
214 | } | ||
215 | } | ||
216 | } | ||
217 | </script> | ||
218 | |||
219 | <style scoped> | ||
220 | .tinymce-container { | ||
221 | position: relative; | ||
222 | line-height: normal; | ||
223 | } | ||
224 | .tinymce-container>>>.mce-fullscreen { | ||
225 | z-index: 10000; | ||
226 | } | ||
227 | .tinymce-textarea { | ||
228 | visibility: hidden; | ||
229 | z-index: -1; | ||
230 | } | ||
231 | .editor-custom-btn-container { | ||
232 | position: absolute; | ||
233 | right: 4px; | ||
234 | top: 4px; | ||
235 | /*z-index: 2005;*/ | ||
236 | } | ||
237 | .fullscreen .editor-custom-btn-container { | ||
238 | z-index: 10000; | ||
239 | position: fixed; | ||
240 | } | ||
241 | .editor-upload-btn { | ||
242 | display: inline-block; | ||
243 | } | ||
244 | </style> | ||
245 |
src/components/Tinymce/plugins.js
File was created | 1 | // Any plugins you want to use has to be imported | |
2 | // Detail plugins list see https://www.tinymce.com/docs/plugins/ | ||
3 | // Custom builds see https://www.tinymce.com/download/custom-builds/ | ||
4 | |||
5 | const plugins = ['advlist anchor autolink autosave code codesample colorpicker colorpicker contextmenu directionality emoticons fullscreen hr image imagetools insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textcolor textpattern visualblocks visualchars wordcount'] | ||
6 | |||
7 | export default plugins | ||
8 |
src/components/Tinymce/toolbar.js
File was created | 1 | // Here is a list of the toolbar | |
2 | // Detail list see https://www.tinymce.com/docs/advanced/editor-control-identifiers/#toolbarcontrols | ||
3 | |||
4 | const toolbar = ['searchreplace bold italic underline strikethrough alignleft aligncenter alignright outdent indent blockquote undo redo removeformat subscript superscript code codesample', 'hr bullist numlist link image charmap preview anchor pagebreak insertdatetime media table emoticons forecolor backcolor fullscreen'] | ||
5 | |||
6 | export default toolbar | ||
7 |
src/components/Upload/SingleImage.vue
File was created | 1 | <template> | |
2 | <div class="upload-container"> | ||
3 | <el-upload | ||
4 | :data="dataObj" | ||
5 | :multiple="false" | ||
6 | :show-file-list="false" | ||
7 | :on-success="handleImageSuccess" | ||
8 | class="image-uploader" | ||
9 | drag | ||
10 | action="https://httpbin.org/post" | ||
11 | > | ||
12 | <i class="el-icon-upload" /> | ||
13 | <div class="el-upload__text"> | ||
14 | 将文件拖到此处,或<em>点击上传</em> | ||
15 | </div> | ||
16 | </el-upload> | ||
17 | <div class="image-preview"> | ||
18 | <div v-show="imageUrl.length>1" class="image-preview-wrapper"> | ||
19 | <img :src="imageUrl+'?imageView2/1/w/200/h/200'"> | ||
20 | <div class="image-preview-action"> | ||
21 | <i class="el-icon-delete" @click="rmImage" /> | ||
22 | </div> | ||
23 | </div> | ||
24 | </div> | ||
25 | </div> | ||
26 | </template> | ||
27 | |||
28 | <script> | ||
29 | import { getToken } from '@/api/qiniu' | ||
30 | |||
31 | export default { | ||
32 | name: 'SingleImageUpload', | ||
33 | props: { | ||
34 | value: { | ||
35 | type: String, | ||
36 | default: '' | ||
37 | } | ||
38 | }, | ||
39 | data() { | ||
40 | return { | ||
41 | tempUrl: '', | ||
42 | dataObj: { token: '', key: '' } | ||
43 | } | ||
44 | }, | ||
45 | computed: { | ||
46 | imageUrl() { | ||
47 | return this.value | ||
48 | } | ||
49 | }, | ||
50 | methods: { | ||
51 | rmImage() { | ||
52 | this.emitInput('') | ||
53 | }, | ||
54 | emitInput(val) { | ||
55 | this.$emit('input', val) | ||
56 | }, | ||
57 | handleImageSuccess() { | ||
58 | this.emitInput(this.tempUrl) | ||
59 | }, | ||
60 | beforeUpload() { | ||
61 | const _self = this | ||
62 | return new Promise((resolve, reject) => { | ||
63 | getToken().then(response => { | ||
64 | const key = response.data.qiniu_key | ||
65 | const token = response.data.qiniu_token | ||
66 | _self._data.dataObj.token = token | ||
67 | _self._data.dataObj.key = key | ||
68 | this.tempUrl = response.data.qiniu_url | ||
69 | resolve(true) | ||
70 | }).catch(err => { | ||
71 | console.log(err) | ||
72 | reject(false) | ||
73 | }) | ||
74 | }) | ||
75 | } | ||
76 | } | ||
77 | } | ||
78 | </script> | ||
79 | |||
80 | <style lang="scss" scoped> | ||
81 | @import "~@/styles/mixin.scss"; | ||
82 | .upload-container { | ||
83 | width: 100%; | ||
84 | position: relative; | ||
85 | @include clearfix; | ||
86 | .image-uploader { | ||
87 | width: 60%; | ||
88 | float: left; | ||
89 | } | ||
90 | .image-preview { | ||
91 | width: 200px; | ||
92 | height: 200px; | ||
93 | position: relative; | ||
94 | border: 1px dashed #d9d9d9; | ||
95 | float: left; | ||
96 | margin-left: 50px; | ||
97 | .image-preview-wrapper { | ||
98 | position: relative; | ||
99 | width: 100%; | ||
100 | height: 100%; | ||
101 | img { | ||
102 | width: 100%; | ||
103 | height: 100%; | ||
104 | } | ||
105 | } | ||
106 | .image-preview-action { | ||
107 | position: absolute; | ||
108 | width: 100%; | ||
109 | height: 100%; | ||
110 | left: 0; | ||
111 | top: 0; | ||
112 | cursor: default; | ||
113 | text-align: center; | ||
114 | color: #fff; | ||
115 | opacity: 0; | ||
116 | font-size: 20px; | ||
117 | background-color: rgba(0, 0, 0, .5); | ||
118 | transition: opacity .3s; | ||
119 | cursor: pointer; | ||
120 | text-align: center; | ||
121 | line-height: 200px; | ||
122 | .el-icon-delete { | ||
123 | font-size: 36px; | ||
124 | } | ||
125 | } | ||
126 | &:hover { | ||
127 | .image-preview-action { | ||
128 | opacity: 1; | ||
129 | } | ||
130 | } | ||
131 | } | ||
132 | } | ||
133 | |||
134 | </style> | ||
135 |
src/components/Upload/SingleImage2.vue
File was created | 1 | <template> | |
2 | <div class="singleImageUpload2 upload-container"> | ||
3 | <el-upload | ||
4 | :data="dataObj" | ||
5 | :multiple="false" | ||
6 | :show-file-list="false" | ||
7 | :on-success="handleImageSuccess" | ||
8 | class="image-uploader" | ||
9 | drag | ||
10 | action="https://httpbin.org/post" | ||
11 | > | ||
12 | <i class="el-icon-upload" /> | ||
13 | <div class="el-upload__text"> | ||
14 | Drag或<em>点击上传</em> | ||
15 | </div> | ||
16 | </el-upload> | ||
17 | <div v-show="imageUrl.length>0" class="image-preview"> | ||
18 | <div v-show="imageUrl.length>1" class="image-preview-wrapper"> | ||
19 | <img :src="imageUrl"> | ||
20 | <div class="image-preview-action"> | ||
21 | <i class="el-icon-delete" @click="rmImage" /> | ||
22 | </div> | ||
23 | </div> | ||
24 | </div> | ||
25 | </div> | ||
26 | </template> | ||
27 | |||
28 | <script> | ||
29 | import { getToken } from '@/api/qiniu' | ||
30 | |||
31 | export default { | ||
32 | name: 'SingleImageUpload2', | ||
33 | props: { | ||
34 | value: { | ||
35 | type: String, | ||
36 | default: '' | ||
37 | } | ||
38 | }, | ||
39 | data() { | ||
40 | return { | ||
41 | tempUrl: '', | ||
42 | dataObj: { token: '', key: '' } | ||
43 | } | ||
44 | }, | ||
45 | computed: { | ||
46 | imageUrl() { | ||
47 | return this.value | ||
48 | } | ||
49 | }, | ||
50 | methods: { | ||
51 | rmImage() { | ||
52 | this.emitInput('') | ||
53 | }, | ||
54 | emitInput(val) { | ||
55 | this.$emit('input', val) | ||
56 | }, | ||
57 | handleImageSuccess() { | ||
58 | this.emitInput(this.tempUrl) | ||
59 | }, | ||
60 | beforeUpload() { | ||
61 | const _self = this | ||
62 | return new Promise((resolve, reject) => { | ||
63 | getToken().then(response => { | ||
64 | const key = response.data.qiniu_key | ||
65 | const token = response.data.qiniu_token | ||
66 | _self._data.dataObj.token = token | ||
67 | _self._data.dataObj.key = key | ||
68 | this.tempUrl = response.data.qiniu_url | ||
69 | resolve(true) | ||
70 | }).catch(() => { | ||
71 | reject(false) | ||
72 | }) | ||
73 | }) | ||
74 | } | ||
75 | } | ||
76 | } | ||
77 | </script> | ||
78 | |||
79 | <style lang="scss" scoped> | ||
80 | .upload-container { | ||
81 | width: 100%; | ||
82 | height: 100%; | ||
83 | position: relative; | ||
84 | .image-uploader { | ||
85 | height: 100%; | ||
86 | } | ||
87 | .image-preview { | ||
88 | width: 100%; | ||
89 | height: 100%; | ||
90 | position: absolute; | ||
91 | left: 0px; | ||
92 | top: 0px; | ||
93 | border: 1px dashed #d9d9d9; | ||
94 | .image-preview-wrapper { | ||
95 | position: relative; | ||
96 | width: 100%; | ||
97 | height: 100%; | ||
98 | img { | ||
99 | width: 100%; | ||
100 | height: 100%; | ||
101 | } | ||
102 | } | ||
103 | .image-preview-action { | ||
104 | position: absolute; | ||
105 | width: 100%; | ||
106 | height: 100%; | ||
107 | left: 0; | ||
108 | top: 0; | ||
109 | cursor: default; | ||
110 | text-align: center; | ||
111 | color: #fff; | ||
112 | opacity: 0; | ||
113 | font-size: 20px; | ||
114 | background-color: rgba(0, 0, 0, .5); | ||
115 | transition: opacity .3s; | ||
116 | cursor: pointer; | ||
117 | text-align: center; | ||
118 | line-height: 200px; | ||
119 | .el-icon-delete { | ||
120 | font-size: 36px; | ||
121 | } | ||
122 | } | ||
123 | &:hover { | ||
124 | .image-preview-action { | ||
125 | opacity: 1; | ||
126 | } | ||
127 | } | ||
128 | } | ||
129 | } | ||
130 | </style> | ||
131 |
src/components/Upload/SingleImage3.vue
File was created | 1 | <template> | |
2 | <div class="upload-container"> | ||
3 | <el-upload | ||
4 | :data="dataObj" | ||
5 | :multiple="false" | ||
6 | :show-file-list="false" | ||
7 | :on-success="handleImageSuccess" | ||
8 | class="image-uploader" | ||
9 | drag | ||
10 | action="https://httpbin.org/post" | ||
11 | > | ||
12 | <i class="el-icon-upload" /> | ||
13 | <div class="el-upload__text"> | ||
14 | 将文件拖到此处,或<em>点击上传</em> | ||
15 | </div> | ||
16 | </el-upload> | ||
17 | <div class="image-preview image-app-preview"> | ||
18 | <div v-show="imageUrl.length>1" class="image-preview-wrapper"> | ||
19 | <img :src="imageUrl"> | ||
20 | <div class="image-preview-action"> | ||
21 | <i class="el-icon-delete" @click="rmImage" /> | ||
22 | </div> | ||
23 | </div> | ||
24 | </div> | ||
25 | <div class="image-preview"> | ||
26 | <div v-show="imageUrl.length>1" class="image-preview-wrapper"> | ||
27 | <img :src="imageUrl"> | ||
28 | <div class="image-preview-action"> | ||
29 | <i class="el-icon-delete" @click="rmImage" /> | ||
30 | </div> | ||
31 | </div> | ||
32 | </div> | ||
33 | </div> | ||
34 | </template> | ||
35 | |||
36 | <script> | ||
37 | import { getToken } from '@/api/qiniu' | ||
38 | |||
39 | export default { | ||
40 | name: 'SingleImageUpload3', | ||
41 | props: { | ||
42 | value: { | ||
43 | type: String, | ||
44 | default: '' | ||
45 | } | ||
46 | }, | ||
47 | data() { | ||
48 | return { | ||
49 | tempUrl: '', | ||
50 | dataObj: { token: '', key: '' } | ||
51 | } | ||
52 | }, | ||
53 | computed: { | ||
54 | imageUrl() { | ||
55 | return this.value | ||
56 | } | ||
57 | }, | ||
58 | methods: { | ||
59 | rmImage() { | ||
60 | this.emitInput('') | ||
61 | }, | ||
62 | emitInput(val) { | ||
63 | this.$emit('input', val) | ||
64 | }, | ||
65 | handleImageSuccess(file) { | ||
66 | this.emitInput(file.files.file) | ||
67 | }, | ||
68 | beforeUpload() { | ||
69 | const _self = this | ||
70 | return new Promise((resolve, reject) => { | ||
71 | getToken().then(response => { | ||
72 | const key = response.data.qiniu_key | ||
73 | const token = response.data.qiniu_token | ||
74 | _self._data.dataObj.token = token | ||
75 | _self._data.dataObj.key = key | ||
76 | this.tempUrl = response.data.qiniu_url | ||
77 | resolve(true) | ||
78 | }).catch(err => { | ||
79 | console.log(err) | ||
80 | reject(false) | ||
81 | }) | ||
82 | }) | ||
83 | } | ||
84 | } | ||
85 | } | ||
86 | </script> | ||
87 | |||
88 | <style lang="scss" scoped> | ||
89 | @import "~@/styles/mixin.scss"; | ||
90 | .upload-container { | ||
91 | width: 100%; | ||
92 | position: relative; | ||
93 | @include clearfix; | ||
94 | .image-uploader { | ||
95 | width: 35%; | ||
96 | float: left; | ||
97 | } | ||
98 | .image-preview { | ||
99 | width: 200px; | ||
100 | height: 200px; | ||
101 | position: relative; | ||
102 | border: 1px dashed #d9d9d9; | ||
103 | float: left; | ||
104 | margin-left: 50px; | ||
105 | .image-preview-wrapper { | ||
106 | position: relative; | ||
107 | width: 100%; | ||
108 | height: 100%; | ||
109 | img { | ||
110 | width: 100%; | ||
111 | height: 100%; | ||
112 | } | ||
113 | } | ||
114 | .image-preview-action { | ||
115 | position: absolute; | ||
116 | width: 100%; | ||
117 | height: 100%; | ||
118 | left: 0; | ||
119 | top: 0; | ||
120 | cursor: default; | ||
121 | text-align: center; | ||
122 | color: #fff; | ||
123 | opacity: 0; | ||
124 | font-size: 20px; | ||
125 | background-color: rgba(0, 0, 0, .5); | ||
126 | transition: opacity .3s; | ||
127 | cursor: pointer; | ||
128 | text-align: center; | ||
129 | line-height: 200px; | ||
130 | .el-icon-delete { | ||
131 | font-size: 36px; | ||
132 | } | ||
133 | } | ||
134 | &:hover { | ||
135 | .image-preview-action { | ||
136 | opacity: 1; | ||
137 | } | ||
138 | } | ||
139 | } | ||
140 | .image-app-preview { | ||
141 | width: 320px; | ||
142 | height: 180px; | ||
143 | position: relative; | ||
144 | border: 1px dashed #d9d9d9; | ||
145 | float: left; | ||
146 | margin-left: 50px; | ||
147 | .app-fake-conver { | ||
148 | height: 44px; | ||
149 | position: absolute; | ||
150 | width: 100%; // background: rgba(0, 0, 0, .1); | ||
151 | text-align: center; | ||
152 | line-height: 64px; | ||
153 | color: #fff; | ||
154 | } | ||
155 | } | ||
156 | } | ||
157 | </style> | ||
158 |
src/components/UploadExcel/index.vue
File was created | 1 | <template> | |
2 | <div> | ||
3 | <input ref="excel-upload-input" class="excel-upload-input" type="file" accept=".xlsx, .xls" @change="handleClick"> | ||
4 | <div class="drop" @drop="handleDrop" @dragover="handleDragover" @dragenter="handleDragover"> | ||
5 | Drop excel file here or | ||
6 | <el-button :loading="loading" style="margin-left:16px;" size="mini" type="primary" @click="handleUpload"> | ||
7 | Browse | ||
8 | </el-button> | ||
9 | </div> | ||
10 | </div> | ||
11 | </template> | ||
12 | |||
13 | <script> | ||
14 | import XLSX from 'xlsx' | ||
15 | |||
16 | export default { | ||
17 | props: { | ||
18 | beforeUpload: Function, // eslint-disable-line | ||
19 | onSuccess: Function// eslint-disable-line | ||
20 | }, | ||
21 | data() { | ||
22 | return { | ||
23 | loading: false, | ||
24 | excelData: { | ||
25 | header: null, | ||
26 | results: null | ||
27 | } | ||
28 | } | ||
29 | }, | ||
30 | methods: { | ||
31 | generateData({ header, results }) { | ||
32 | this.excelData.header = header | ||
33 | this.excelData.results = results | ||
34 | this.onSuccess && this.onSuccess(this.excelData) | ||
35 | }, | ||
36 | handleDrop(e) { | ||
37 | e.stopPropagation() | ||
38 | e.preventDefault() | ||
39 | if (this.loading) return | ||
40 | const files = e.dataTransfer.files | ||
41 | if (files.length !== 1) { | ||
42 | this.$message.error('Only support uploading one file!') | ||
43 | return | ||
44 | } | ||
45 | const rawFile = files[0] // only use files[0] | ||
46 | |||
47 | if (!this.isExcel(rawFile)) { | ||
48 | this.$message.error('Only supports upload .xlsx, .xls, .csv suffix files') | ||
49 | return false | ||
50 | } | ||
51 | this.upload(rawFile) | ||
52 | e.stopPropagation() | ||
53 | e.preventDefault() | ||
54 | }, | ||
55 | handleDragover(e) { | ||
56 | e.stopPropagation() | ||
57 | e.preventDefault() | ||
58 | e.dataTransfer.dropEffect = 'copy' | ||
59 | }, | ||
60 | handleUpload() { | ||
61 | this.$refs['excel-upload-input'].click() | ||
62 | }, | ||
63 | handleClick(e) { | ||
64 | const files = e.target.files | ||
65 | const rawFile = files[0] // only use files[0] | ||
66 | if (!rawFile) return | ||
67 | this.upload(rawFile) | ||
68 | }, | ||
69 | upload(rawFile) { | ||
70 | this.$refs['excel-upload-input'].value = null // fix can't select the same excel | ||
71 | |||
72 | if (!this.beforeUpload) { | ||
73 | this.readerData(rawFile) | ||
74 | return | ||
75 | } | ||
76 | const before = this.beforeUpload(rawFile) | ||
77 | if (before) { | ||
78 | this.readerData(rawFile) | ||
79 | } | ||
80 | }, | ||
81 | readerData(rawFile) { | ||
82 | this.loading = true | ||
83 | return new Promise((resolve, reject) => { | ||
84 | const reader = new FileReader() | ||
85 | reader.onload = e => { | ||
86 | const data = e.target.result | ||
87 | const workbook = XLSX.read(data, { type: 'array' }) | ||
88 | const firstSheetName = workbook.SheetNames[0] | ||
89 | const worksheet = workbook.Sheets[firstSheetName] | ||
90 | const header = this.getHeaderRow(worksheet) | ||
91 | const results = XLSX.utils.sheet_to_json(worksheet) | ||
92 | this.generateData({ header, results }) | ||
93 | this.loading = false | ||
94 | resolve() | ||
95 | } | ||
96 | reader.readAsArrayBuffer(rawFile) | ||
97 | }) | ||
98 | }, | ||
99 | getHeaderRow(sheet) { | ||
100 | const headers = [] | ||
101 | const range = XLSX.utils.decode_range(sheet['!ref']) | ||
102 | let C | ||
103 | const R = range.s.r | ||
104 | /* start in the first row */ | ||
105 | for (C = range.s.c; C <= range.e.c; ++C) { /* walk every column in the range */ | ||
106 | const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })] | ||
107 | /* find the cell in the first row */ | ||
108 | let hdr = 'UNKNOWN ' + C // <-- replace with your desired default | ||
109 | if (cell && cell.t) hdr = XLSX.utils.format_cell(cell) | ||
110 | headers.push(hdr) | ||
111 | } | ||
112 | return headers | ||
113 | }, | ||
114 | isExcel(file) { | ||
115 | return /\.(xlsx|xls|csv)$/.test(file.name) | ||
116 | } | ||
117 | } | ||
118 | } | ||
119 | </script> | ||
120 | |||
121 | <style scoped> | ||
122 | .excel-upload-input{ | ||
123 | display: none; | ||
124 | z-index: -9999; | ||
125 | } | ||
126 | .drop{ | ||
127 | border: 2px dashed #bbb; | ||
128 | width: 600px; | ||
129 | height: 160px; | ||
130 | line-height: 160px; | ||
131 | margin: 0 auto; | ||
132 | font-size: 24px; | ||
133 | border-radius: 5px; | ||
134 | text-align: center; | ||
135 | color: #bbb; | ||
136 | position: relative; | ||
137 | } | ||
138 | </style> | ||
139 |
src/directive/clipboard/clipboard.js
File was created | 1 | // Inspired by https://github.com/Inndy/vue-clipboard2 | |
2 | const Clipboard = require('clipboard') | ||
3 | if (!Clipboard) { | ||
4 | throw new Error('you should npm install `clipboard` --save at first ') | ||
5 | } | ||
6 | |||
7 | export default { | ||
8 | bind(el, binding) { | ||
9 | if (binding.arg === 'success') { | ||
10 | el._v_clipboard_success = binding.value | ||
11 | } else if (binding.arg === 'error') { | ||
12 | el._v_clipboard_error = binding.value | ||
13 | } else { | ||
14 | const clipboard = new Clipboard(el, { | ||
15 | text() { return binding.value }, | ||
16 | action() { return binding.arg === 'cut' ? 'cut' : 'copy' } | ||
17 | }) | ||
18 | clipboard.on('success', e => { | ||
19 | const callback = el._v_clipboard_success | ||
20 | callback && callback(e) // eslint-disable-line | ||
21 | }) | ||
22 | clipboard.on('error', e => { | ||
23 | const callback = el._v_clipboard_error | ||
24 | callback && callback(e) // eslint-disable-line | ||
25 | }) | ||
26 | el._v_clipboard = clipboard | ||
27 | } | ||
28 | }, | ||
29 | update(el, binding) { | ||
30 | if (binding.arg === 'success') { | ||
31 | el._v_clipboard_success = binding.value | ||
32 | } else if (binding.arg === 'error') { | ||
33 | el._v_clipboard_error = binding.value | ||
34 | } else { | ||
35 | el._v_clipboard.text = function() { return binding.value } | ||
36 | el._v_clipboard.action = function() { return binding.arg === 'cut' ? 'cut' : 'copy' } | ||
37 | } | ||
38 | }, | ||
39 | unbind(el, binding) { | ||
40 | if (binding.arg === 'success') { | ||
41 | delete el._v_clipboard_success | ||
42 | } else if (binding.arg === 'error') { | ||
43 | delete el._v_clipboard_error | ||
44 | } else { | ||
45 | el._v_clipboard.destroy() | ||
46 | delete el._v_clipboard | ||
47 | } | ||
48 | } | ||
49 | } | ||
50 |
src/directive/clipboard/index.js
File was created | 1 | import Clipboard from './clipboard' | |
2 | |||
3 | const install = function(Vue) { | ||
4 | Vue.directive('Clipboard', Clipboard) | ||
5 | } | ||
6 | |||
7 | if (window.Vue) { | ||
8 | window.clipboard = Clipboard | ||
9 | Vue.use(install); // eslint-disable-line | ||
10 | } | ||
11 | |||
12 | Clipboard.install = install | ||
13 | export default Clipboard | ||
14 |
src/directive/el-drag-dialog/drag.js
File was created | 1 | export default { | |
2 | bind(el, binding, vnode) { | ||
3 | const dialogHeaderEl = el.querySelector('.el-dialog__header') | ||
4 | const dragDom = el.querySelector('.el-dialog') | ||
5 | dialogHeaderEl.style.cssText += ';cursor:move;' | ||
6 | dragDom.style.cssText += ';top:0px;' | ||
7 | |||
8 | // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null); | ||
9 | const getStyle = (function() { | ||
10 | if (window.document.currentStyle) { | ||
11 | return (dom, attr) => dom.currentStyle[attr] | ||
12 | } else { | ||
13 | return (dom, attr) => getComputedStyle(dom, false)[attr] | ||
14 | } | ||
15 | })() | ||
16 | |||
17 | dialogHeaderEl.onmousedown = (e) => { | ||
18 | // 鼠标按下,计算当前元素距离可视区的距离 | ||
19 | const disX = e.clientX - dialogHeaderEl.offsetLeft | ||
20 | const disY = e.clientY - dialogHeaderEl.offsetTop | ||
21 | |||
22 | const dragDomWidth = dragDom.offsetWidth | ||
23 | const dragDomHeight = dragDom.offsetHeight | ||
24 | |||
25 | const screenWidth = document.body.clientWidth | ||
26 | const screenHeight = document.body.clientHeight | ||
27 | |||
28 | const minDragDomLeft = dragDom.offsetLeft | ||
29 | const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth | ||
30 | |||
31 | const minDragDomTop = dragDom.offsetTop | ||
32 | const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomHeight | ||
33 | |||
34 | // 获取到的值带px 正则匹配替换 | ||
35 | let styL = getStyle(dragDom, 'left') | ||
36 | let styT = getStyle(dragDom, 'top') | ||
37 | |||
38 | if (styL.includes('%')) { | ||
39 | styL = +document.body.clientWidth * (+styL.replace(/\%/g, '') / 100) | ||
40 | styT = +document.body.clientHeight * (+styT.replace(/\%/g, '') / 100) | ||
41 | } else { | ||
42 | styL = +styL.replace(/\px/g, '') | ||
43 | styT = +styT.replace(/\px/g, '') | ||
44 | } | ||
45 | |||
46 | document.onmousemove = function(e) { | ||
47 | // 通过事件委托,计算移动的距离 | ||
48 | let left = e.clientX - disX | ||
49 | let top = e.clientY - disY | ||
50 | |||
51 | // 边界处理 | ||
52 | if (-(left) > minDragDomLeft) { | ||
53 | left = -minDragDomLeft | ||
54 | } else if (left > maxDragDomLeft) { | ||
55 | left = maxDragDomLeft | ||
56 | } | ||
57 | |||
58 | if (-(top) > minDragDomTop) { | ||
59 | top = -minDragDomTop | ||
60 | } else if (top > maxDragDomTop) { | ||
61 | top = maxDragDomTop | ||
62 | } | ||
63 | |||
64 | // 移动当前元素 | ||
65 | dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;` | ||
66 | |||
67 | // emit onDrag event | ||
68 | vnode.child.$emit('dragDialog') | ||
69 | } | ||
70 | |||
71 | document.onmouseup = function(e) { | ||
72 | document.onmousemove = null | ||
73 | document.onmouseup = null | ||
74 | } | ||
75 | } | ||
76 | } | ||
77 | } | ||
78 |
src/directive/el-drag-dialog/index.js
File was created | 1 | import drag from './drag' | |
2 | |||
3 | const install = function(Vue) { | ||
4 | Vue.directive('el-drag-dialog', drag) | ||
5 | } | ||
6 | |||
7 | if (window.Vue) { | ||
8 | window['el-drag-dialog'] = drag | ||
9 | Vue.use(install); // eslint-disable-line | ||
10 | } | ||
11 | |||
12 | drag.install = install | ||
13 | export default drag | ||
14 |
src/directive/el-table/adaptive.js
File was created | 1 | import { addResizeListener, removeResizeListener } from 'element-ui/src/utils/resize-event' | |
2 | |||
3 | /** | ||
4 | * How to use | ||
5 | * <el-table height="100px" v-el-height-adaptive-table="{bottomOffset: 30}">...</el-table> | ||
6 | * el-table height is must be set | ||
7 | * bottomOffset: 30(default) // The height of the table from the bottom of the page. | ||
8 | */ | ||
9 | |||
10 | const doResize = (el, binding, vnode) => { | ||
11 | const { componentInstance: $table } = vnode | ||
12 | |||
13 | const { value } = binding | ||
14 | |||
15 | if (!$table.height) { | ||
16 | throw new Error(`el-$table must set the height. Such as height='100px'`) | ||
17 | } | ||
18 | const bottomOffset = (value && value.bottomOffset) || 30 | ||
19 | |||
20 | if (!$table) return | ||
21 | |||
22 | const height = window.innerHeight - el.getBoundingClientRect().top - bottomOffset | ||
23 | $table.layout.setHeight(height) | ||
24 | $table.doLayout() | ||
25 | } | ||
26 | |||
27 | export default { | ||
28 | bind(el, binding, vnode) { | ||
29 | el.resizeListener = () => { | ||
30 | doResize(el, binding, vnode) | ||
31 | } | ||
32 | // parameter 1 is must be "Element" type | ||
33 | addResizeListener(window.document.body, el.resizeListener) | ||
34 | }, | ||
35 | inserted(el, binding, vnode) { | ||
36 | doResize(el, binding, vnode) | ||
37 | }, | ||
38 | unbind(el) { | ||
39 | removeResizeListener(window.document.body, el.resizeListener) | ||
40 | } | ||
41 | } | ||
42 |
src/directive/el-table/index.js
File was created | 1 | import adaptive from './adaptive' | |
2 | |||
3 | const install = function(Vue) { | ||
4 | Vue.directive('el-height-adaptive-table', adaptive) | ||
5 | } | ||
6 | |||
7 | if (window.Vue) { | ||
8 | window['el-height-adaptive-table'] = adaptive | ||
9 | Vue.use(install); // eslint-disable-line | ||
10 | } | ||
11 | |||
12 | adaptive.install = install | ||
13 | export default adaptive | ||
14 |
src/directive/permission/index.js
File was created | 1 | import permission from './permission' | |
2 | |||
3 | const install = function(Vue) { | ||
4 | Vue.directive('permission', permission) | ||
5 | } | ||
6 | |||
7 | if (window.Vue) { | ||
8 | window['permission'] = permission | ||
9 | Vue.use(install); // eslint-disable-line | ||
10 | } | ||
11 | |||
12 | permission.install = install | ||
13 | export default permission | ||
14 |
src/directive/permission/permission.js
File was created | 1 | import store from '@/store' | |
2 | |||
3 | export default { | ||
4 | inserted(el, binding, vnode) { | ||
5 | const { value } = binding | ||
6 | const roles = store.getters && store.getters.roles | ||
7 | |||
8 | if (value && value instanceof Array && value.length > 0) { | ||
9 | const permissionRoles = value | ||
10 | |||
11 | const hasPermission = roles.some(role => { | ||
12 | return permissionRoles.includes(role) | ||
13 | }) | ||
14 | |||
15 | if (!hasPermission) { | ||
16 | el.parentNode && el.parentNode.removeChild(el) | ||
17 | } | ||
18 | } else { | ||
19 | throw new Error(`need roles! Like v-permission="['admin','editor']"`) | ||
20 | } | ||
21 | } | ||
22 | } | ||
23 |
src/directive/sticky.js
File was created | 1 | const vueSticky = {} | |
2 | let listenAction | ||
3 | vueSticky.install = Vue => { | ||
4 | Vue.directive('sticky', { | ||
5 | inserted(el, binding) { | ||
6 | const params = binding.value || {} | ||
7 | const stickyTop = params.stickyTop || 0 | ||
8 | const zIndex = params.zIndex || 1000 | ||
9 | const elStyle = el.style | ||
10 | |||
11 | elStyle.position = '-webkit-sticky' | ||
12 | elStyle.position = 'sticky' | ||
13 | // if the browser support css sticky(Currently Safari, Firefox and Chrome Canary) | ||
14 | // if (~elStyle.position.indexOf('sticky')) { | ||
15 | // elStyle.top = `${stickyTop}px`; | ||
16 | // elStyle.zIndex = zIndex; | ||
17 | // return | ||
18 | // } | ||
19 | const elHeight = el.getBoundingClientRect().height | ||
20 | const elWidth = el.getBoundingClientRect().width | ||
21 | elStyle.cssText = `top: ${stickyTop}px; z-index: ${zIndex}` | ||
22 | |||
23 | const parentElm = el.parentNode || document.documentElement | ||
24 | const placeholder = document.createElement('div') | ||
25 | placeholder.style.display = 'none' | ||
26 | placeholder.style.width = `${elWidth}px` | ||
27 | placeholder.style.height = `${elHeight}px` | ||
28 | parentElm.insertBefore(placeholder, el) | ||
29 | |||
30 | let active = false | ||
31 | |||
32 | const getScroll = (target, top) => { | ||
33 | const prop = top ? 'pageYOffset' : 'pageXOffset' | ||
34 | const method = top ? 'scrollTop' : 'scrollLeft' | ||
35 | let ret = target[prop] | ||
36 | if (typeof ret !== 'number') { | ||
37 | ret = window.document.documentElement[method] | ||
38 | } | ||
39 | return ret | ||
40 | } | ||
41 | |||
42 | const sticky = () => { | ||
43 | if (active) { | ||
44 | return | ||
45 | } | ||
46 | if (!elStyle.height) { | ||
47 | elStyle.height = `${el.offsetHeight}px` | ||
48 | } | ||
49 | |||
50 | elStyle.position = 'fixed' | ||
51 | elStyle.width = `${elWidth}px` | ||
52 | placeholder.style.display = 'inline-block' | ||
53 | active = true | ||
54 | } | ||
55 | |||
56 | const reset = () => { | ||
57 | if (!active) { | ||
58 | return | ||
59 | } | ||
60 | |||
61 | elStyle.position = '' | ||
62 | placeholder.style.display = 'none' | ||
63 | active = false | ||
64 | } | ||
65 | |||
66 | const check = () => { | ||
67 | const scrollTop = getScroll(window, true) | ||
68 | const offsetTop = el.getBoundingClientRect().top | ||
69 | if (offsetTop < stickyTop) { | ||
70 | sticky() | ||
71 | } else { | ||
72 | if (scrollTop < elHeight + stickyTop) { | ||
73 | reset() | ||
74 | } | ||
75 | } | ||
76 | } | ||
77 | listenAction = () => { | ||
78 | check() | ||
79 | } | ||
80 | |||
81 | window.addEventListener('scroll', listenAction) | ||
82 | }, | ||
83 | |||
84 | unbind() { | ||
85 | window.removeEventListener('scroll', listenAction) | ||
86 | } | ||
87 | }) | ||
88 | } | ||
89 | |||
90 | export default vueSticky | ||
91 | |||
92 |
src/directive/waves/index.js
File was created | 1 | import waves from './waves' | |
2 | |||
3 | const install = function(Vue) { | ||
4 | Vue.directive('waves', waves) | ||
5 | } | ||
6 | |||
7 | if (window.Vue) { | ||
8 | window.waves = waves | ||
9 | Vue.use(install); // eslint-disable-line | ||
10 | } | ||
11 | |||
12 | waves.install = install | ||
13 | export default waves | ||
14 |
src/directive/waves/waves.css
File was created | 1 | .waves-ripple { | |
2 | position: absolute; | ||
3 | border-radius: 100%; | ||
4 | background-color: rgba(0, 0, 0, 0.15); | ||
5 | background-clip: padding-box; | ||
6 | pointer-events: none; | ||
7 | -webkit-user-select: none; | ||
8 | -moz-user-select: none; | ||
9 | -ms-user-select: none; | ||
10 | user-select: none; | ||
11 | -webkit-transform: scale(0); | ||
12 | -ms-transform: scale(0); | ||
13 | transform: scale(0); | ||
14 | opacity: 1; | ||
15 | } | ||
16 | |||
17 | .waves-ripple.z-active { | ||
18 | opacity: 0; | ||
19 | -webkit-transform: scale(2); | ||
20 | -ms-transform: scale(2); | ||
21 | transform: scale(2); | ||
22 | -webkit-transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out; | ||
23 | transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out; | ||
24 | transition: opacity 1.2s ease-out, transform 0.6s ease-out; | ||
25 | transition: opacity 1.2s ease-out, transform 0.6s ease-out, -webkit-transform 0.6s ease-out; | ||
26 | } |
src/directive/waves/waves.js
File was created | 1 | import './waves.css' | |
2 | |||
3 | const context = '@@wavesContext' | ||
4 | |||
5 | function handleClick(el, binding) { | ||
6 | function handle(e) { | ||
7 | const customOpts = Object.assign({}, binding.value) | ||
8 | const opts = Object.assign({ | ||
9 | ele: el, // 波纹作用元素 | ||
10 | type: 'hit', // hit 点击位置扩散 center中心点扩展 | ||
11 | color: 'rgba(0, 0, 0, 0.15)' // 波纹颜色 | ||
12 | }, | ||
13 | customOpts | ||
14 | ) | ||
15 | const target = opts.ele | ||
16 | if (target) { | ||
17 | target.style.position = 'relative' | ||
18 | target.style.overflow = 'hidden' | ||
19 | const rect = target.getBoundingClientRect() | ||
20 | let ripple = target.querySelector('.waves-ripple') | ||
21 | if (!ripple) { | ||
22 | ripple = document.createElement('span') | ||
23 | ripple.className = 'waves-ripple' | ||
24 | ripple.style.height = ripple.style.width = Math.max(rect.width, rect.height) + 'px' | ||
25 | target.appendChild(ripple) | ||
26 | } else { | ||
27 | ripple.className = 'waves-ripple' | ||
28 | } | ||
29 | switch (opts.type) { | ||
30 | case 'center': | ||
31 | ripple.style.top = rect.height / 2 - ripple.offsetHeight / 2 + 'px' | ||
32 | ripple.style.left = rect.width / 2 - ripple.offsetWidth / 2 + 'px' | ||
33 | break | ||
34 | default: | ||
35 | ripple.style.top = | ||
36 | (e.pageY - rect.top - ripple.offsetHeight / 2 - document.documentElement.scrollTop || | ||
37 | document.body.scrollTop) + 'px' | ||
38 | ripple.style.left = | ||
39 | (e.pageX - rect.left - ripple.offsetWidth / 2 - document.documentElement.scrollLeft || | ||
40 | document.body.scrollLeft) + 'px' | ||
41 | } | ||
42 | ripple.style.backgroundColor = opts.color | ||
43 | ripple.className = 'waves-ripple z-active' | ||
44 | return false | ||
45 | } | ||
46 | } | ||
47 | |||
48 | if (!el[context]) { | ||
49 | el[context] = { | ||
50 | removeHandle: handle | ||
51 | } | ||
52 | } else { | ||
53 | el[context].removeHandle = handle | ||
54 | } | ||
55 | |||
56 | return handle | ||
57 | } | ||
58 | |||
59 | export default { | ||
60 | bind(el, binding) { | ||
61 | el.addEventListener('click', handleClick(el, binding), false) | ||
62 | }, | ||
63 | update(el, binding) { | ||
64 | el.removeEventListener('click', el[context].removeHandle, false) | ||
65 | el.addEventListener('click', handleClick(el, binding), false) | ||
66 | }, | ||
67 | unbind(el) { | ||
68 | el.removeEventListener('click', el[context].removeHandle, false) | ||
69 | el[context] = null | ||
70 | delete el[context] | ||
71 | } | ||
72 | } | ||
73 |
src/filters/index.js
File was created | 1 | // import parseTime, formatTime and set to filter | |
2 | export { parseTime, formatTime } from '@/utils' | ||
3 | |||
4 | /** | ||
5 | * Show plural label if time is plural number | ||
6 | * @param {number} time | ||
7 | * @param {string} label | ||
8 | * @return {string} | ||
9 | */ | ||
10 | function pluralize(time, label) { | ||
11 | if (time === 1) { | ||
12 | return time + label | ||
13 | } | ||
14 | return time + label + 's' | ||
15 | } | ||
16 | |||
17 | /** | ||
18 | * @param {number} time | ||
19 | */ | ||
20 | export function timeAgo(time) { | ||
21 | const between = Date.now() / 1000 - Number(time) | ||
22 | if (between < 3600) { | ||
23 | return pluralize(~~(between / 60), ' minute') | ||
24 | } else if (between < 86400) { | ||
25 | return pluralize(~~(between / 3600), ' hour') | ||
26 | } else { | ||
27 | return pluralize(~~(between / 86400), ' day') | ||
28 | } | ||
29 | } | ||
30 | |||
31 | /** | ||
32 | * Number formatting | ||
33 | * like 10000 => 10k | ||
34 | * @param {number} num | ||
35 | * @param {number} digits | ||
36 | */ | ||
37 | export function numberFormatter(num, digits) { | ||
38 | const si = [ | ||
39 | { value: 1E18, symbol: 'E' }, | ||
40 | { value: 1E15, symbol: 'P' }, | ||
41 | { value: 1E12, symbol: 'T' }, | ||
42 | { value: 1E9, symbol: 'G' }, | ||
43 | { value: 1E6, symbol: 'M' }, | ||
44 | { value: 1E3, symbol: 'k' } | ||
45 | ] | ||
46 | for (let i = 0; i < si.length; i++) { | ||
47 | if (num >= si[i].value) { | ||
48 | return (num / si[i].value).toFixed(digits).replace(/\.0+$|(\.[0-9]*[1-9])0+$/, '$1') + si[i].symbol | ||
49 | } | ||
50 | } | ||
51 | return num.toString() | ||
52 | } | ||
53 | |||
54 | /** | ||
55 | * 10000 => "10,000" | ||
56 | * @param {number} num | ||
57 | */ | ||
58 | export function toThousandFilter(num) { | ||
59 | return (+num || 0).toString().replace(/^-?\d+/g, m => m.replace(/(?=(?!\b)(\d{3})+$)/g, ',')) | ||
60 | } | ||
61 | |||
62 | /** | ||
63 | * Upper case first char | ||
64 | * @param {String} string | ||
65 | */ | ||
66 | export function uppercaseFirst(string) { | ||
67 | return string.charAt(0).toUpperCase() + string.slice(1) | ||
68 | } | ||
69 |
1 | import Vue from 'vue' | 1 | import Vue from 'vue' |
2 | import SvgIcon from '@/components/SvgIcon'// svg component | 2 | import SvgIcon from '@/components/SvgIcon'// svg component |
3 | 3 | ||
4 | // register globally | 4 | // register globally |
5 | Vue.component('svg-icon', SvgIcon) | 5 | Vue.component('svg-icon', SvgIcon) |
6 | 6 | ||
7 | const req = require.context('./svg', false, /\.svg$/) | 7 | const req = require.context('./svg', false, /\.svg$/) |
8 | const requireAll = requireContext => requireContext.keys().map(requireContext) | 8 | const requireAll = requireContext => requireContext.keys().map(requireContext) |
9 | requireAll(req) | 9 | requireAll(req) |
10 | 10 |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M121.718 73.272v9.953c3.957-7.584 6.199-16.05 6.199-24.995C127.917 26.079 99.273 0 63.958 0 28.644 0 0 26.079 0 58.23c0 .403.028.806.028 1.21l22.97-25.953h13.34l-19.76 27.187h6.42V53.77l13.728-19.477v49.361H22.998V73.272H2.158c5.951 20.284 23.608 36.208 45.998 41.399-1.44 3.3-5.618 11.263-12.565 12.674-8.607 1.764 23.358.428 46.163-13.178 17.519-4.611 31.938-15.849 39.77-30.513h-13.506V73.272H85.02V59.464l22.998-25.977h13.008l-19.429 27.187h6.421v-7.433l13.727-19.402v39.433h-.027zm-78.24 2.822a10.516 10.516 0 0 1-.996-4.535V44.548c0-1.613.332-3.124.996-4.535a11.66 11.66 0 0 1 2.713-3.68c1.134-1.032 2.49-1.864 4.04-2.468 1.55-.605 3.21-.908 4.982-.908h11.292c1.77 0 3.431.303 4.981.908 1.522.604 2.85 1.41 3.986 2.418l-12.26 16.303v-2.898a1.96 1.96 0 0 0-.665-1.512c-.443-.403-.996-.604-1.66-.604-.665 0-1.218.201-1.661.604a1.96 1.96 0 0 0-.664 1.512v9.071L44.364 77.606a10.556 10.556 0 0 1-.886-1.512zm35.73-4.535c0 1.613-.332 3.124-.997 4.535a11.66 11.66 0 0 1-2.712 3.68c-1.134 1.032-2.49 1.864-4.04 2.469-1.55.604-3.21.907-4.982.907H55.185c-1.77 0-3.431-.303-4.981-.907-1.55-.605-2.906-1.437-4.041-2.47a12.49 12.49 0 0 1-1.384-1.512l13.727-18.217v6.375c0 .605.222 1.109.665 1.512.442.403.996.604 1.66.604.664 0 1.218-.201 1.66-.604a1.96 1.96 0 0 0 .665-1.512V53.87L75.97 36.838c.913.932 1.66 1.99 2.214 3.175.664 1.41.996 2.922.996 4.535v27.011h.028z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M121.718 73.272v9.953c3.957-7.584 6.199-16.05 6.199-24.995C127.917 26.079 99.273 0 63.958 0 28.644 0 0 26.079 0 58.23c0 .403.028.806.028 1.21l22.97-25.953h13.34l-19.76 27.187h6.42V53.77l13.728-19.477v49.361H22.998V73.272H2.158c5.951 20.284 23.608 36.208 45.998 41.399-1.44 3.3-5.618 11.263-12.565 12.674-8.607 1.764 23.358.428 46.163-13.178 17.519-4.611 31.938-15.849 39.77-30.513h-13.506V73.272H85.02V59.464l22.998-25.977h13.008l-19.429 27.187h6.421v-7.433l13.727-19.402v39.433h-.027zm-78.24 2.822a10.516 10.516 0 0 1-.996-4.535V44.548c0-1.613.332-3.124.996-4.535a11.66 11.66 0 0 1 2.713-3.68c1.134-1.032 2.49-1.864 4.04-2.468 1.55-.605 3.21-.908 4.982-.908h11.292c1.77 0 3.431.303 4.981.908 1.522.604 2.85 1.41 3.986 2.418l-12.26 16.303v-2.898a1.96 1.96 0 0 0-.665-1.512c-.443-.403-.996-.604-1.66-.604-.665 0-1.218.201-1.661.604a1.96 1.96 0 0 0-.664 1.512v9.071L44.364 77.606a10.556 10.556 0 0 1-.886-1.512zm35.73-4.535c0 1.613-.332 3.124-.997 4.535a11.66 11.66 0 0 1-2.712 3.68c-1.134 1.032-2.49 1.864-4.04 2.469-1.55.604-3.21.907-4.982.907H55.185c-1.77 0-3.431-.303-4.981-.907-1.55-.605-2.906-1.437-4.041-2.47a12.49 12.49 0 0 1-1.384-1.512l13.727-18.217v6.375c0 .605.222 1.109.665 1.512.442.403.996.604 1.66.604.664 0 1.218-.201 1.66-.604a1.96 1.96 0 0 0 .665-1.512V53.87L75.97 36.838c.913.932 1.66 1.99 2.214 3.175.664 1.41.996 2.922.996 4.535v27.011h.028z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M127.88 73.143c0 1.412-.506 2.635-1.518 3.669-1.011 1.033-2.209 1.55-3.592 1.55h-17.887c0 9.296-1.783 17.178-5.35 23.645l16.609 17.044c1.011 1.034 1.517 2.257 1.517 3.67 0 1.412-.506 2.635-1.517 3.668-.958 1.033-2.155 1.55-3.593 1.55-1.438 0-2.635-.517-3.593-1.55l-15.811-16.063a15.49 15.49 0 0 1-1.196 1.06c-.532.434-1.65 1.208-3.353 2.322a50.104 50.104 0 0 1-5.192 2.974c-1.758.87-3.94 1.658-6.546 2.364-2.607.706-5.189 1.06-7.748 1.06V47.044H58.89v73.062c-2.716 0-5.417-.367-8.106-1.102-2.688-.734-5.003-1.631-6.945-2.692a66.769 66.769 0 0 1-5.268-3.179c-1.571-1.057-2.73-1.94-3.476-2.65L33.9 109.34l-14.611 16.877c-1.066 1.14-2.344 1.711-3.833 1.711-1.277 0-2.422-.434-3.434-1.304-1.012-.978-1.557-2.187-1.635-3.627-.079-1.44.333-2.705 1.236-3.794l16.129-18.51c-3.087-6.197-4.63-13.644-4.63-22.342H5.235c-1.383 0-2.58-.517-3.592-1.55S.125 74.545.125 73.132c0-1.412.506-2.635 1.518-3.668 1.012-1.034 2.21-1.55 3.592-1.55h17.887V43.939L9.308 29.833c-1.012-1.033-1.517-2.256-1.517-3.669 0-1.412.505-2.635 1.517-3.668 1.012-1.034 2.21-1.55 3.593-1.55s2.58.516 3.593 1.55l13.813 14.106h67.396l13.814-14.106c1.012-1.034 2.21-1.55 3.592-1.55 1.384 0 2.581.516 3.593 1.55 1.012 1.033 1.518 2.256 1.518 3.668 0 1.413-.506 2.636-1.518 3.67l-13.814 14.105v23.975h17.887c1.383 0 2.58.516 3.593 1.55 1.011 1.033 1.517 2.256 1.517 3.668l-.005.01zM89.552 26.175H38.448c0-7.23 2.489-13.386 7.466-18.469C50.892 2.623 56.92.082 64 .082c7.08 0 13.108 2.541 18.086 7.624 4.977 5.083 7.466 11.24 7.466 18.469z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M127.88 73.143c0 1.412-.506 2.635-1.518 3.669-1.011 1.033-2.209 1.55-3.592 1.55h-17.887c0 9.296-1.783 17.178-5.35 23.645l16.609 17.044c1.011 1.034 1.517 2.257 1.517 3.67 0 1.412-.506 2.635-1.517 3.668-.958 1.033-2.155 1.55-3.593 1.55-1.438 0-2.635-.517-3.593-1.55l-15.811-16.063a15.49 15.49 0 0 1-1.196 1.06c-.532.434-1.65 1.208-3.353 2.322a50.104 50.104 0 0 1-5.192 2.974c-1.758.87-3.94 1.658-6.546 2.364-2.607.706-5.189 1.06-7.748 1.06V47.044H58.89v73.062c-2.716 0-5.417-.367-8.106-1.102-2.688-.734-5.003-1.631-6.945-2.692a66.769 66.769 0 0 1-5.268-3.179c-1.571-1.057-2.73-1.94-3.476-2.65L33.9 109.34l-14.611 16.877c-1.066 1.14-2.344 1.711-3.833 1.711-1.277 0-2.422-.434-3.434-1.304-1.012-.978-1.557-2.187-1.635-3.627-.079-1.44.333-2.705 1.236-3.794l16.129-18.51c-3.087-6.197-4.63-13.644-4.63-22.342H5.235c-1.383 0-2.58-.517-3.592-1.55S.125 74.545.125 73.132c0-1.412.506-2.635 1.518-3.668 1.012-1.034 2.21-1.55 3.592-1.55h17.887V43.939L9.308 29.833c-1.012-1.033-1.517-2.256-1.517-3.669 0-1.412.505-2.635 1.517-3.668 1.012-1.034 2.21-1.55 3.593-1.55s2.58.516 3.593 1.55l13.813 14.106h67.396l13.814-14.106c1.012-1.034 2.21-1.55 3.592-1.55 1.384 0 2.581.516 3.593 1.55 1.012 1.033 1.518 2.256 1.518 3.668 0 1.413-.506 2.636-1.518 3.67l-13.814 14.105v23.975h17.887c1.383 0 2.58.516 3.593 1.55 1.011 1.033 1.517 2.256 1.517 3.668l-.005.01zM89.552 26.175H38.448c0-7.23 2.489-13.386 7.466-18.469C50.892 2.623 56.92.082 64 .082c7.08 0 13.108 2.541 18.086 7.624 4.977 5.083 7.466 11.24 7.466 18.469z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M0 54.857h36.571V128H0V54.857zM91.429 27.43H128V128H91.429V27.429zM45.714 0h36.572v128H45.714V0z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M0 54.857h36.571V128H0V54.857zM91.429 27.43H128V128H91.429V27.429zM45.714 0h36.572v128H45.714V0z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M54.857 118.857h64V73.143H89.143c-1.902 0-3.52-.668-4.855-2.002-1.335-1.335-2.002-2.954-2.002-4.855V36.57H54.857v82.286zM73.143 16v-4.571a2.2 2.2 0 0 0-.677-1.61 2.198 2.198 0 0 0-1.609-.676H20.571c-.621 0-1.158.225-1.609.676a2.198 2.198 0 0 0-.676 1.61V16a2.2 2.2 0 0 0 .676 1.61c.451.45.988.676 1.61.676h50.285c.622 0 1.158-.226 1.61-.677.45-.45.676-.987.676-1.609zm18.286 48h21.357L91.43 42.642V64zM128 73.143v48c0 1.902-.667 3.52-2.002 4.855-1.335 1.335-2.953 2.002-4.855 2.002H52.57c-1.901 0-3.52-.667-4.854-2.002-1.335-1.335-2.003-2.953-2.003-4.855v-11.429H6.857c-1.902 0-3.52-.667-4.855-2.002C.667 106.377 0 104.759 0 102.857v-96c0-1.902.667-3.52 2.002-4.855C3.337.667 4.955 0 6.857 0h77.714c1.902 0 3.52.667 4.855 2.002 1.335 1.335 2.003 2.953 2.003 4.855V30.29c1 .622 1.856 1.29 2.569 2.003l29.147 29.147c1.335 1.335 2.478 3.145 3.429 5.43.95 2.287 1.426 4.383 1.426 6.291v-.018z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M54.857 118.857h64V73.143H89.143c-1.902 0-3.52-.668-4.855-2.002-1.335-1.335-2.002-2.954-2.002-4.855V36.57H54.857v82.286zM73.143 16v-4.571a2.2 2.2 0 0 0-.677-1.61 2.198 2.198 0 0 0-1.609-.676H20.571c-.621 0-1.158.225-1.609.676a2.198 2.198 0 0 0-.676 1.61V16a2.2 2.2 0 0 0 .676 1.61c.451.45.988.676 1.61.676h50.285c.622 0 1.158-.226 1.61-.677.45-.45.676-.987.676-1.609zm18.286 48h21.357L91.43 42.642V64zM128 73.143v48c0 1.902-.667 3.52-2.002 4.855-1.335 1.335-2.953 2.002-4.855 2.002H52.57c-1.901 0-3.52-.667-4.854-2.002-1.335-1.335-2.003-2.953-2.003-4.855v-11.429H6.857c-1.902 0-3.52-.667-4.855-2.002C.667 106.377 0 104.759 0 102.857v-96c0-1.902.667-3.52 2.002-4.855C3.337.667 4.955 0 6.857 0h77.714c1.902 0 3.52.667 4.855 2.002 1.335 1.335 2.003 2.953 2.003 4.855V30.29c1 .622 1.856 1.29 2.569 2.003l29.147 29.147c1.335 1.335 2.478 3.145 3.429 5.43.95 2.287 1.426 4.383 1.426 6.291v-.018z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h54.857v54.857H0V0zm0 73.143h54.857V128H0V73.143zm73.143 0H128V128H73.143V73.143zm27.428-18.286C115.72 54.857 128 42.577 128 27.43 128 12.28 115.72 0 100.571 0 85.423 0 73.143 12.28 73.143 27.429c0 15.148 12.28 27.428 27.428 27.428z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h54.857v54.857H0V0zm0 73.143h54.857V128H0V73.143zm73.143 0H128V128H73.143V73.143zm27.428-18.286C115.72 54.857 128 42.577 128 27.43 128 12.28 115.72 0 100.571 0 85.423 0 73.143 12.28 73.143 27.429c0 15.148 12.28 27.428 27.428 27.428z"/></svg> |
1 | <svg width="128" height="100" xmlns="http://www.w3.org/2000/svg"><path d="M27.429 63.638c0-2.508-.893-4.65-2.679-6.424-1.786-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.465 2.662-1.785 1.774-2.678 3.916-2.678 6.424 0 2.508.893 4.65 2.678 6.424 1.786 1.775 3.94 2.662 6.465 2.662 2.524 0 4.678-.887 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zm13.714-31.801c0-2.508-.893-4.65-2.679-6.424-1.785-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zM71.714 65.98l7.215-27.116c.285-1.23.107-2.378-.536-3.443-.643-1.064-1.56-1.762-2.75-2.094-1.19-.33-2.333-.177-3.429.462-1.095.639-1.81 1.573-2.143 2.804l-7.214 27.116c-2.857.237-5.405 1.266-7.643 3.088-2.238 1.822-3.738 4.152-4.5 6.992-.952 3.644-.476 7.098 1.429 10.364 1.905 3.265 4.69 5.37 8.357 6.317 3.667.947 7.143.474 10.429-1.42 3.285-1.892 5.404-4.66 6.357-8.305.762-2.84.619-5.607-.429-8.305-1.047-2.697-2.762-4.85-5.143-6.46zm47.143-2.342c0-2.508-.893-4.65-2.678-6.424-1.786-1.775-3.94-2.662-6.465-2.662-2.524 0-4.678.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.786 1.775 3.94 2.662 6.464 2.662 2.524 0 4.679-.887 6.465-2.662 1.785-1.775 2.678-3.916 2.678-6.424zm-45.714-45.43c0-2.509-.893-4.65-2.679-6.425C68.68 10.01 66.524 9.122 64 9.122c-2.524 0-4.679.887-6.464 2.661-1.786 1.775-2.679 3.916-2.679 6.425 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zm32 13.629c0-2.508-.893-4.65-2.679-6.424-1.785-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zM128 63.638c0 12.351-3.357 23.78-10.071 34.286-.905 1.372-2.19 2.058-3.858 2.058H13.93c-1.667 0-2.953-.686-3.858-2.058C3.357 87.465 0 76.037 0 63.638c0-8.613 1.69-16.847 5.071-24.703C8.452 31.08 13 24.312 18.714 18.634c5.715-5.68 12.524-10.199 20.429-13.559C47.048 1.715 55.333.035 64 .035c8.667 0 16.952 1.68 24.857 5.04 7.905 3.36 14.714 7.88 20.429 13.559 5.714 5.678 10.262 12.446 13.643 20.301 3.38 7.856 5.071 16.09 5.071 24.703z"/></svg> | 1 | <svg width="128" height="100" xmlns="http://www.w3.org/2000/svg"><path d="M27.429 63.638c0-2.508-.893-4.65-2.679-6.424-1.786-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.465 2.662-1.785 1.774-2.678 3.916-2.678 6.424 0 2.508.893 4.65 2.678 6.424 1.786 1.775 3.94 2.662 6.465 2.662 2.524 0 4.678-.887 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zm13.714-31.801c0-2.508-.893-4.65-2.679-6.424-1.785-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zM71.714 65.98l7.215-27.116c.285-1.23.107-2.378-.536-3.443-.643-1.064-1.56-1.762-2.75-2.094-1.19-.33-2.333-.177-3.429.462-1.095.639-1.81 1.573-2.143 2.804l-7.214 27.116c-2.857.237-5.405 1.266-7.643 3.088-2.238 1.822-3.738 4.152-4.5 6.992-.952 3.644-.476 7.098 1.429 10.364 1.905 3.265 4.69 5.37 8.357 6.317 3.667.947 7.143.474 10.429-1.42 3.285-1.892 5.404-4.66 6.357-8.305.762-2.84.619-5.607-.429-8.305-1.047-2.697-2.762-4.85-5.143-6.46zm47.143-2.342c0-2.508-.893-4.65-2.678-6.424-1.786-1.775-3.94-2.662-6.465-2.662-2.524 0-4.678.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.786 1.775 3.94 2.662 6.464 2.662 2.524 0 4.679-.887 6.465-2.662 1.785-1.775 2.678-3.916 2.678-6.424zm-45.714-45.43c0-2.509-.893-4.65-2.679-6.425C68.68 10.01 66.524 9.122 64 9.122c-2.524 0-4.679.887-6.464 2.661-1.786 1.775-2.679 3.916-2.679 6.425 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zm32 13.629c0-2.508-.893-4.65-2.679-6.424-1.785-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zM128 63.638c0 12.351-3.357 23.78-10.071 34.286-.905 1.372-2.19 2.058-3.858 2.058H13.93c-1.667 0-2.953-.686-3.858-2.058C3.357 87.465 0 76.037 0 63.638c0-8.613 1.69-16.847 5.071-24.703C8.452 31.08 13 24.312 18.714 18.634c5.715-5.68 12.524-10.199 20.429-13.559C47.048 1.715 55.333.035 64 .035c8.667 0 16.952 1.68 24.857 5.04 7.905 3.36 14.714 7.88 20.429 13.559 5.714 5.678 10.262 12.446 13.643 20.301 3.38 7.856 5.071 16.09 5.071 24.703z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M71.984 44.815H115.9L71.984 9.642v35.173zM16.094.05h63.875l47.906 38.37v76.74c0 3.392-1.682 6.645-4.677 9.044-2.995 2.399-7.056 3.746-11.292 3.746H16.094c-4.236 0-8.297-1.347-11.292-3.746-2.995-2.399-4.677-5.652-4.677-9.044V12.84C.125 5.742 7.23.05 16.094.05zm71.86 102.32V89.58h-71.86v12.79h71.86zm23.952-25.58V64H16.094v12.79h95.812z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M71.984 44.815H115.9L71.984 9.642v35.173zM16.094.05h63.875l47.906 38.37v76.74c0 3.392-1.682 6.645-4.677 9.044-2.995 2.399-7.056 3.746-11.292 3.746H16.094c-4.236 0-8.297-1.347-11.292-3.746-2.995-2.399-4.677-5.652-4.677-9.044V12.84C.125 5.742 7.23.05 16.094.05zm71.86 102.32V89.58h-71.86v12.79h71.86zm23.952-25.58V64H16.094v12.79h95.812z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M73.137 29.08h-9.209 29.7L63.886.093 34.373 29.08h20.49v27.035H27.238v17.948h27.625v27.133h18.274V74.063h27.41V56.115h-27.41V29.08zm-9.245 98.827l27.518-26.711H36.59l27.302 26.71zM.042 64.982l27.196 27.029V38.167L.042 64.982zm100.505-26.815V92.01l27.41-27.029-27.41-26.815z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M73.137 29.08h-9.209 29.7L63.886.093 34.373 29.08h20.49v27.035H27.238v17.948h27.625v27.133h18.274V74.063h27.41V56.115h-27.41V29.08zm-9.245 98.827l27.518-26.711H36.59l27.302 26.71zM.042 64.982l27.196 27.029V38.167L.042 64.982zm100.505-26.815V92.01l27.41-27.029-27.41-26.815z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M106.133 67.2a4.797 4.797 0 0 0-4.8 4.8c0 .187.014.36.027.533h-.027V118.4H9.6V26.667h50.133c2.654 0 4.8-2.147 4.8-4.8 0-2.654-2.146-4.8-4.8-4.8H9.6a9.594 9.594 0 0 0-9.6 9.6V118.4c0 5.307 4.293 9.6 9.6 9.6h91.733c5.307 0 9.6-4.293 9.6-9.6V72.533h-.026c.013-.173.026-.346.026-.533 0-2.653-2.146-4.8-4.8-4.8z"/><path d="M125.16 13.373L114.587 2.8c-3.747-3.747-9.854-3.72-13.6.027l-52.96 52.96a4.264 4.264 0 0 0-.907 1.36L33.813 88.533c-.746 1.76-.226 3.534.907 4.68 1.133 1.147 2.92 1.667 4.693.92l31.4-13.293c.507-.213.96-.52 1.36-.907l52.96-52.96c3.747-3.746 3.774-9.853.027-13.6zM66.107 72.4l-18.32 7.76 7.76-18.32L92.72 24.667l10.56 10.56L66.107 72.4zm52.226-52.227l-8.266 8.267-10.56-10.56 8.266-8.267.027-.026 10.56 10.56-.027.026z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M106.133 67.2a4.797 4.797 0 0 0-4.8 4.8c0 .187.014.36.027.533h-.027V118.4H9.6V26.667h50.133c2.654 0 4.8-2.147 4.8-4.8 0-2.654-2.146-4.8-4.8-4.8H9.6a9.594 9.594 0 0 0-9.6 9.6V118.4c0 5.307 4.293 9.6 9.6 9.6h91.733c5.307 0 9.6-4.293 9.6-9.6V72.533h-.026c.013-.173.026-.346.026-.533 0-2.653-2.146-4.8-4.8-4.8z"/><path d="M125.16 13.373L114.587 2.8c-3.747-3.747-9.854-3.72-13.6.027l-52.96 52.96a4.264 4.264 0 0 0-.907 1.36L33.813 88.533c-.746 1.76-.226 3.534.907 4.68 1.133 1.147 2.92 1.667 4.693.92l31.4-13.293c.507-.213.96-.52 1.36-.907l52.96-52.96c3.747-3.746 3.774-9.853.027-13.6zM66.107 72.4l-18.32 7.76 7.76-18.32L92.72 24.667l10.56 10.56L66.107 72.4zm52.226-52.227l-8.266 8.267-10.56-10.56 8.266-8.267.027-.026 10.56 10.56-.027.026z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M88.883 119.565c-7.284 0-19.434 2.495-21.333 8.25v.127c-4.232.13-5.222 0-7.108 0-1.895-5.76-14.045-8.256-21.333-8.256H0V0h42.523c9.179 0 17.109 5.47 21.47 13.551C68.352 5.475 76.295 0 85.478 0H128v119.57l-39.113-.005h-.004zM60.442 24.763c0-9.651-8.978-16.507-17.777-16.507H7.108V111.43H39.11c7.054-.14 18.177.082 21.333 6.12v-4.628c-.134-5.722-.004-13.522 0-13.832V27.413l.004-2.655-.004.005zm60.442-16.517h-35.55c-8.802 0-17.78 6.856-17.78 16.493v74.259c.004.32.138 8.115 0 13.813v4.627c3.155-6.022 14.279-6.26 21.333-6.114h32V8.25l-.003-.005z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M88.883 119.565c-7.284 0-19.434 2.495-21.333 8.25v.127c-4.232.13-5.222 0-7.108 0-1.895-5.76-14.045-8.256-21.333-8.256H0V0h42.523c9.179 0 17.109 5.47 21.47 13.551C68.352 5.475 76.295 0 85.478 0H128v119.57l-39.113-.005h-.004zM60.442 24.763c0-9.651-8.978-16.507-17.777-16.507H7.108V111.43H39.11c7.054-.14 18.177.082 21.333 6.12v-4.628c-.134-5.722-.004-13.522 0-13.832V27.413l.004-2.655-.004.005zm60.442-16.517h-35.55c-8.802 0-17.78 6.856-17.78 16.493v74.259c.004.32.138 8.115 0 13.813v4.627c3.155-6.022 14.279-6.26 21.333-6.114h32V8.25l-.003-.005z"/></svg> |
1 | <svg width="128" height="96" xmlns="http://www.w3.org/2000/svg"><path d="M64.125 56.975L120.188.912A12.476 12.476 0 0 0 115.5 0h-103c-1.588 0-3.113.3-4.513.838l56.138 56.137z"/><path d="M64.125 68.287l-62.3-62.3A12.42 12.42 0 0 0 0 12.5v71C0 90.4 5.6 96 12.5 96h103c6.9 0 12.5-5.6 12.5-12.5v-71a12.47 12.47 0 0 0-1.737-6.35L64.125 68.287z"/></svg> | 1 | <svg width="128" height="96" xmlns="http://www.w3.org/2000/svg"><path d="M64.125 56.975L120.188.912A12.476 12.476 0 0 0 115.5 0h-103c-1.588 0-3.113.3-4.513.838l56.138 56.137z"/><path d="M64.125 68.287l-62.3-62.3A12.42 12.42 0 0 0 0 12.5v71C0 90.4 5.6 96 12.5 96h103c6.9 0 12.5-5.6 12.5-12.5v-71a12.47 12.47 0 0 0-1.737-6.35L64.125 68.287z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M96.258 57.462h31.421C124.794 27.323 100.426 2.956 70.287.07v31.422a32.856 32.856 0 0 1 25.971 25.97zm-38.796-25.97V.07C27.323 2.956 2.956 27.323.07 57.462h31.422a32.856 32.856 0 0 1 25.97-25.97zm12.825 64.766v31.421c30.46-2.885 54.507-27.253 57.713-57.712H96.579c-2.886 13.466-13.146 23.726-26.292 26.291zM31.492 70.287H.07c2.886 30.46 27.253 54.507 57.713 57.713V96.579c-13.466-2.886-23.726-13.146-26.291-26.292z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M96.258 57.462h31.421C124.794 27.323 100.426 2.956 70.287.07v31.422a32.856 32.856 0 0 1 25.971 25.97zm-38.796-25.97V.07C27.323 2.956 2.956 27.323.07 57.462h31.422a32.856 32.856 0 0 1 25.97-25.97zm12.825 64.766v31.421c30.46-2.885 54.507-27.253 57.713-57.712H96.579c-2.886 13.466-13.146 23.726-26.292 26.291zM31.492 70.287H.07c2.886 30.46 27.253 54.507 57.713 57.713V96.579c-13.466-2.886-23.726-13.146-26.291-26.292z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M78.208 16.576v8.384h38.72v5.376h-38.72v8.704h38.72v5.376h-38.72v8.576h38.72v5.376h-38.72v8.576h38.72v5.376h-38.72v8.576h38.72v5.376h-38.72v8.512h38.72v5.376h-38.72v11.136H128v-94.72H78.208zM0 114.368L72.128 128V0L0 13.632v100.736z"/><path d="M28.672 82.56h-11.2l14.784-23.488-14.08-22.592h11.52l8.192 14.976 8.448-14.976h11.136l-14.08 22.208L58.368 82.56H46.656l-8.768-15.68z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M78.208 16.576v8.384h38.72v5.376h-38.72v8.704h38.72v5.376h-38.72v8.576h38.72v5.376h-38.72v8.576h38.72v5.376h-38.72v8.576h38.72v5.376h-38.72v8.512h38.72v5.376h-38.72v11.136H128v-94.72H78.208zM0 114.368L72.128 128V0L0 13.632v100.736z"/><path d="M28.672 82.56h-11.2l14.784-23.488-14.08-22.592h11.52l8.192 14.976 8.448-14.976h11.136l-14.08 22.208L58.368 82.56H46.656l-8.768-15.68z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M49.217 41.329l-.136-35.24c-.06-2.715-2.302-4.345-5.022-4.405h-3.65c-2.712-.06-4.866 2.303-4.806 5.016l.152 19.164-24.151-23.79a6.698 6.698 0 0 0-9.499 0 6.76 6.76 0 0 0 0 9.526l23.93 23.713-18.345.074c-2.712-.069-5.228 1.813-5.64 5.02v3.462c.069 2.721 2.31 4.97 5.022 5.03l35.028-.207c.052.005.087.025.133.025l2.457.054a4.626 4.626 0 0 0 3.436-1.38c.88-.874 1.205-2.096 1.169-3.462l-.262-2.465c0-.048.182-.081.182-.136h.002zm52.523 51.212l18.32-.073c2.713.06 5.224-1.609 5.64-4.815v-3.462c-.068-2.722-2.317-4.97-5.021-5.04l-34.58.21c-.053 0-.086-.021-.138-.021l-2.451-.06a4.64 4.64 0 0 0-3.445 1.381c-.885.868-1.201 2.094-1.174 3.46l.27 2.46c.005.06-.177.095-.177.141l.141 34.697c.069 2.713 2.31 4.338 5.022 4.397l3.45.006c2.705.062 4.867-2.31 4.8-5.026l-.153-18.752 24.151 23.946a6.69 6.69 0 0 0 9.494 0 6.747 6.747 0 0 0 0-9.523L101.74 92.54v.001zM48.125 80.662a4.636 4.636 0 0 0-3.437-1.382l-2.457.06c-.05 0-.082.022-.137.022l-35.025-.21c-2.712.07-4.957 2.318-5.022 5.04v3.462c.409 3.206 2.925 4.874 5.633 4.814l18.554.06-24.132 23.928c-2.62 2.626-2.62 6.89 0 9.524a6.694 6.694 0 0 0 9.496 0l24.155-23.79-.155 18.866c-.06 2.722 2.094 5.093 4.801 5.025h3.65c2.72-.069 4.962-1.685 5.022-4.406l.141-34.956c0-.05-.182-.082-.182-.136l.262-2.46c.03-1.366-.286-2.592-1.166-3.46h-.001zM80.08 47.397a4.62 4.62 0 0 0 3.443 1.374l2.45-.054c.055 0 .088-.02.143-.028l35.08.21c2.712-.062 4.953-2.312 5.021-5.033l.009-3.463c-.417-3.211-2.937-5.084-5.64-5.025l-18.615-.073 23.917-23.715c2.63-2.623 2.63-6.879.008-9.513a6.691 6.691 0 0 0-9.494 0L92.251 26.016l.155-19.312c.065-2.713-2.097-5.085-4.802-5.025h-3.45c-2.713.069-4.954 1.693-5.022 4.406l-.139 35.247c0 .054.18.088.18.136l-.267 2.465c-.028 1.366.288 2.588 1.174 3.463v.001z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M49.217 41.329l-.136-35.24c-.06-2.715-2.302-4.345-5.022-4.405h-3.65c-2.712-.06-4.866 2.303-4.806 5.016l.152 19.164-24.151-23.79a6.698 6.698 0 0 0-9.499 0 6.76 6.76 0 0 0 0 9.526l23.93 23.713-18.345.074c-2.712-.069-5.228 1.813-5.64 5.02v3.462c.069 2.721 2.31 4.97 5.022 5.03l35.028-.207c.052.005.087.025.133.025l2.457.054a4.626 4.626 0 0 0 3.436-1.38c.88-.874 1.205-2.096 1.169-3.462l-.262-2.465c0-.048.182-.081.182-.136h.002zm52.523 51.212l18.32-.073c2.713.06 5.224-1.609 5.64-4.815v-3.462c-.068-2.722-2.317-4.97-5.021-5.04l-34.58.21c-.053 0-.086-.021-.138-.021l-2.451-.06a4.64 4.64 0 0 0-3.445 1.381c-.885.868-1.201 2.094-1.174 3.46l.27 2.46c.005.06-.177.095-.177.141l.141 34.697c.069 2.713 2.31 4.338 5.022 4.397l3.45.006c2.705.062 4.867-2.31 4.8-5.026l-.153-18.752 24.151 23.946a6.69 6.69 0 0 0 9.494 0 6.747 6.747 0 0 0 0-9.523L101.74 92.54v.001zM48.125 80.662a4.636 4.636 0 0 0-3.437-1.382l-2.457.06c-.05 0-.082.022-.137.022l-35.025-.21c-2.712.07-4.957 2.318-5.022 5.04v3.462c.409 3.206 2.925 4.874 5.633 4.814l18.554.06-24.132 23.928c-2.62 2.626-2.62 6.89 0 9.524a6.694 6.694 0 0 0 9.496 0l24.155-23.79-.155 18.866c-.06 2.722 2.094 5.093 4.801 5.025h3.65c2.72-.069 4.962-1.685 5.022-4.406l.141-34.956c0-.05-.182-.082-.182-.136l.262-2.46c.03-1.366-.286-2.592-1.166-3.46h-.001zM80.08 47.397a4.62 4.62 0 0 0 3.443 1.374l2.45-.054c.055 0 .088-.02.143-.028l35.08.21c2.712-.062 4.953-2.312 5.021-5.033l.009-3.463c-.417-3.211-2.937-5.084-5.64-5.025l-18.615-.073 23.917-23.715c2.63-2.623 2.63-6.879.008-9.513a6.691 6.691 0 0 0-9.494 0L92.251 26.016l.155-19.312c.065-2.713-2.097-5.085-4.802-5.025h-3.45c-2.713.069-4.954 1.693-5.022 4.406l-.139 35.247c0 .054.18.088.18.136l-.267 2.465c-.028 1.366.288 2.588 1.174 3.463v.001z"/></svg> |
1 | <svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="128" height="128"><defs><style/></defs><path d="M512 128q69.675 0 135.51 21.163t115.498 54.997 93.483 74.837 73.685 82.006 51.67 74.837 32.17 54.827L1024 512q-2.347 4.992-6.315 13.483T998.87 560.17t-31.658 51.669-44.331 59.99-56.832 64.34-69.504 60.16-82.347 51.5-94.848 34.687T512 896q-69.675 0-135.51-21.163t-115.498-54.826-93.483-74.326-73.685-81.493-51.67-74.496-32.17-54.997L0 513.707q2.347-4.992 6.315-13.483t18.816-34.816 31.658-51.84 44.331-60.33 56.832-64.683 69.504-60.331 82.347-51.84 94.848-34.816T512 128.085zm0 85.333q-46.677 0-91.648 12.331t-81.152 31.83-70.656 47.146-59.648 54.485-48.853 57.686-37.675 52.821-26.325 43.99q12.33 21.674 26.325 43.52t37.675 52.351 48.853 57.003 59.648 53.845T339.2 767.02t81.152 31.488T512 810.667t91.648-12.331 81.152-31.659 70.656-46.848 59.648-54.186 48.853-57.344 37.675-52.651T927.957 512q-12.33-21.675-26.325-43.648t-37.675-52.65-48.853-57.345-59.648-54.186-70.656-46.848-81.152-31.659T512 213.334zm0 128q70.656 0 120.661 50.006T682.667 512 632.66 632.661 512 682.667 391.339 632.66 341.333 512t50.006-120.661T512 341.333zm0 85.334q-35.328 0-60.33 25.002T426.666 512t25.002 60.33T512 597.334t60.33-25.002T597.334 512t-25.002-60.33T512 426.666z"/></svg> | 1 | <svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="128" height="128"><defs><style/></defs><path d="M512 128q69.675 0 135.51 21.163t115.498 54.997 93.483 74.837 73.685 82.006 51.67 74.837 32.17 54.827L1024 512q-2.347 4.992-6.315 13.483T998.87 560.17t-31.658 51.669-44.331 59.99-56.832 64.34-69.504 60.16-82.347 51.5-94.848 34.687T512 896q-69.675 0-135.51-21.163t-115.498-54.826-93.483-74.326-73.685-81.493-51.67-74.496-32.17-54.997L0 513.707q2.347-4.992 6.315-13.483t18.816-34.816 31.658-51.84 44.331-60.33 56.832-64.683 69.504-60.331 82.347-51.84 94.848-34.816T512 128.085zm0 85.333q-46.677 0-91.648 12.331t-81.152 31.83-70.656 47.146-59.648 54.485-48.853 57.686-37.675 52.821-26.325 43.99q12.33 21.674 26.325 43.52t37.675 52.351 48.853 57.003 59.648 53.845T339.2 767.02t81.152 31.488T512 810.667t91.648-12.331 81.152-31.659 70.656-46.848 59.648-54.186 48.853-57.344 37.675-52.651T927.957 512q-12.33-21.675-26.325-43.648t-37.675-52.65-48.853-57.345-59.648-54.186-70.656-46.848-81.152-31.659T512 213.334zm0 128q70.656 0 120.661 50.006T682.667 512 632.66 632.661 512 682.667 391.339 632.66 341.333 512t50.006-120.661T512 341.333zm0 85.334q-35.328 0-60.33 25.002T426.666 512t25.002 60.33T512 597.334t60.33-25.002T597.334 512t-25.002-60.33T512 426.666z"/></svg> |
1 | <svg width="128" height="64" xmlns="http://www.w3.org/2000/svg"><path d="M127.072 7.994c1.37-2.208.914-5.152-.914-6.87-2.056-1.717-4.797-1.226-6.396.982-.229.245-25.586 32.382-55.74 32.382-29.24 0-55.74-32.382-55.968-32.627-1.6-1.963-4.57-2.208-6.397-.49C-.17 3.086-.399 6.275 1.2 8.238c.457.736 5.94 7.36 14.62 14.72L4.17 35.96c-1.828 1.963-1.6 5.152.228 6.87.457.98 1.6 1.471 2.742 1.471s2.284-.49 3.198-1.472l12.564-13.983c5.94 4.416 13.021 8.587 20.788 11.53l-4.797 17.418c-.685 2.699.686 5.397 3.198 6.133h1.37c2.057 0 3.884-1.472 4.341-3.68L52.6 42.83c3.655.736 7.538 1.227 11.422 1.227 3.883 0 7.767-.49 11.422-1.227l4.797 17.173c.457 2.208 2.513 3.68 4.34 3.68.457 0 .914 0 1.143-.246 2.513-.736 3.883-3.434 3.198-6.133l-4.797-17.172c7.767-2.944 14.848-7.114 20.788-11.53l12.336 13.738c.913.981 2.056 1.472 3.198 1.472s2.284-.49 3.198-1.472c1.828-1.963 1.828-4.906.228-6.87l-11.65-13.001c9.366-7.36 14.849-14.474 14.849-14.474z"/></svg> | 1 | <svg width="128" height="64" xmlns="http://www.w3.org/2000/svg"><path d="M127.072 7.994c1.37-2.208.914-5.152-.914-6.87-2.056-1.717-4.797-1.226-6.396.982-.229.245-25.586 32.382-55.74 32.382-29.24 0-55.74-32.382-55.968-32.627-1.6-1.963-4.57-2.208-6.397-.49C-.17 3.086-.399 6.275 1.2 8.238c.457.736 5.94 7.36 14.62 14.72L4.17 35.96c-1.828 1.963-1.6 5.152.228 6.87.457.98 1.6 1.471 2.742 1.471s2.284-.49 3.198-1.472l12.564-13.983c5.94 4.416 13.021 8.587 20.788 11.53l-4.797 17.418c-.685 2.699.686 5.397 3.198 6.133h1.37c2.057 0 3.884-1.472 4.341-3.68L52.6 42.83c3.655.736 7.538 1.227 11.422 1.227 3.883 0 7.767-.49 11.422-1.227l4.797 17.173c.457 2.208 2.513 3.68 4.34 3.68.457 0 .914 0 1.143-.246 2.513-.736 3.883-3.434 3.198-6.133l-4.797-17.172c7.767-2.944 14.848-7.114 20.788-11.53l12.336 13.738c.913.981 2.056 1.472 3.198 1.472s2.284-.49 3.198-1.472c1.828-1.963 1.828-4.906.228-6.87l-11.65-13.001c9.366-7.36 14.849-14.474 14.849-14.474z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M84.068 23.784c-1.02 0-1.877-.32-2.572-.96a8.588 8.588 0 0 1-1.738-2.237 11.524 11.524 0 0 1-1.042-2.621c-.232-.895-.348-1.641-.348-2.238V0h.278c.834 0 1.622.085 2.363.256.742.17 1.645.575 2.711 1.214 1.066.64 2.363 1.535 3.892 2.686 1.53 1.15 3.453 2.664 5.77 4.54 2.502 2.045 4.494 3.771 5.977 5.178 1.483 1.406 2.618 2.6 3.406 3.58.787.98 1.274 1.812 1.46 2.494.185.682.277 1.278.277 1.79v2.046H84.068zM127.3 84.01c.278.682.464 1.535.556 2.558.093 1.023-.37 2.003-1.39 2.94-.463.427-.88.832-1.25 1.215-.372.384-.696.704-.974.96a6.69 6.69 0 0 1-.973.767l-11.816-10.741a44.331 44.331 0 0 0 1.877-1.535 31.028 31.028 0 0 1 1.737-1.406c1.112-.938 2.317-1.343 3.615-1.215 1.297.128 2.363.405 3.197.83.927.427 1.923 1.173 2.989 2.239 1.065 1.065 1.876 2.195 2.432 3.388zM78.23 95.902c2.038 0 3.752-.511 5.143-1.534l-26.969 25.83H18.037c-1.761 0-3.684-.47-5.77-1.407a24.549 24.549 0 0 1-5.838-3.709 21.373 21.373 0 0 1-4.518-5.306c-1.204-2.003-1.807-4.07-1.807-6.202V16.495c0-1.79.44-3.665 1.32-5.626A18.41 18.41 0 0 1 5.04 5.562a21.798 21.798 0 0 1 5.213-3.964C12.198.533 14.237 0 16.37 0h53.24v15.984c0 1.62.278 3.367.834 5.242a16.704 16.704 0 0 0 2.572 5.179c1.159 1.577 2.665 2.898 4.518 3.964 1.853 1.066 4.078 1.598 6.673 1.598h20.295v42.325L85.458 92.45c1.02-1.364 1.529-2.856 1.529-4.476 0-2.216-.857-4.113-2.572-5.69-1.714-1.577-3.776-2.366-6.186-2.366H26.1c-2.409 0-4.448.789-6.116 2.366-1.668 1.577-2.502 3.474-2.502 5.69 0 2.217.834 4.092 2.502 5.626 1.668 1.535 3.707 2.302 6.117 2.302h52.13zM26.1 47.951c-2.41 0-4.449.789-6.117 2.366-1.668 1.577-2.502 3.473-2.502 5.69 0 2.216.834 4.092 2.502 5.626 1.668 1.534 3.707 2.302 6.117 2.302h52.13c2.409 0 4.47-.768 6.185-2.302 1.715-1.534 2.572-3.41 2.572-5.626 0-2.217-.857-4.113-2.572-5.69-1.714-1.577-3.776-2.366-6.186-2.366H26.1zm52.407 64.063l1.807-1.663 3.476-3.196a479.75 479.75 0 0 0 4.587-4.284 500.757 500.757 0 0 1 5.004-4.667c3.985-3.666 8.48-7.758 13.485-12.276l11.677 10.741-13.485 12.404-5.004 4.603-4.587 4.22a179.46 179.46 0 0 0-3.267 3.068c-.88.853-1.367 1.322-1.46 1.407-.463.341-.973.703-1.529 1.087-.556.383-1.112.703-1.668.959-.556.256-1.413.575-2.572.959a83.5 83.5 0 0 1-3.545 1.087 72.2 72.2 0 0 1-3.475.895c-1.112.256-1.946.426-2.502.511-1.112.17-1.854.043-2.224-.383-.371-.426-.464-1.151-.278-2.174.092-.511.278-1.279.556-2.302.278-1.023.602-2.067.973-3.132l1.042-3.005c.325-.938.58-1.577.765-1.918a10.157 10.157 0 0 1 2.224-2.941z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M84.068 23.784c-1.02 0-1.877-.32-2.572-.96a8.588 8.588 0 0 1-1.738-2.237 11.524 11.524 0 0 1-1.042-2.621c-.232-.895-.348-1.641-.348-2.238V0h.278c.834 0 1.622.085 2.363.256.742.17 1.645.575 2.711 1.214 1.066.64 2.363 1.535 3.892 2.686 1.53 1.15 3.453 2.664 5.77 4.54 2.502 2.045 4.494 3.771 5.977 5.178 1.483 1.406 2.618 2.6 3.406 3.58.787.98 1.274 1.812 1.46 2.494.185.682.277 1.278.277 1.79v2.046H84.068zM127.3 84.01c.278.682.464 1.535.556 2.558.093 1.023-.37 2.003-1.39 2.94-.463.427-.88.832-1.25 1.215-.372.384-.696.704-.974.96a6.69 6.69 0 0 1-.973.767l-11.816-10.741a44.331 44.331 0 0 0 1.877-1.535 31.028 31.028 0 0 1 1.737-1.406c1.112-.938 2.317-1.343 3.615-1.215 1.297.128 2.363.405 3.197.83.927.427 1.923 1.173 2.989 2.239 1.065 1.065 1.876 2.195 2.432 3.388zM78.23 95.902c2.038 0 3.752-.511 5.143-1.534l-26.969 25.83H18.037c-1.761 0-3.684-.47-5.77-1.407a24.549 24.549 0 0 1-5.838-3.709 21.373 21.373 0 0 1-4.518-5.306c-1.204-2.003-1.807-4.07-1.807-6.202V16.495c0-1.79.44-3.665 1.32-5.626A18.41 18.41 0 0 1 5.04 5.562a21.798 21.798 0 0 1 5.213-3.964C12.198.533 14.237 0 16.37 0h53.24v15.984c0 1.62.278 3.367.834 5.242a16.704 16.704 0 0 0 2.572 5.179c1.159 1.577 2.665 2.898 4.518 3.964 1.853 1.066 4.078 1.598 6.673 1.598h20.295v42.325L85.458 92.45c1.02-1.364 1.529-2.856 1.529-4.476 0-2.216-.857-4.113-2.572-5.69-1.714-1.577-3.776-2.366-6.186-2.366H26.1c-2.409 0-4.448.789-6.116 2.366-1.668 1.577-2.502 3.474-2.502 5.69 0 2.217.834 4.092 2.502 5.626 1.668 1.535 3.707 2.302 6.117 2.302h52.13zM26.1 47.951c-2.41 0-4.449.789-6.117 2.366-1.668 1.577-2.502 3.473-2.502 5.69 0 2.216.834 4.092 2.502 5.626 1.668 1.534 3.707 2.302 6.117 2.302h52.13c2.409 0 4.47-.768 6.185-2.302 1.715-1.534 2.572-3.41 2.572-5.626 0-2.217-.857-4.113-2.572-5.69-1.714-1.577-3.776-2.366-6.186-2.366H26.1zm52.407 64.063l1.807-1.663 3.476-3.196a479.75 479.75 0 0 0 4.587-4.284 500.757 500.757 0 0 1 5.004-4.667c3.985-3.666 8.48-7.758 13.485-12.276l11.677 10.741-13.485 12.404-5.004 4.603-4.587 4.22a179.46 179.46 0 0 0-3.267 3.068c-.88.853-1.367 1.322-1.46 1.407-.463.341-.973.703-1.529 1.087-.556.383-1.112.703-1.668.959-.556.256-1.413.575-2.572.959a83.5 83.5 0 0 1-3.545 1.087 72.2 72.2 0 0 1-3.475.895c-1.112.256-1.946.426-2.502.511-1.112.17-1.854.043-2.224-.383-.371-.426-.464-1.151-.278-2.174.092-.511.278-1.279.556-2.302.278-1.023.602-2.067.973-3.132l1.042-3.005c.325-.938.58-1.577.765-1.918a10.157 10.157 0 0 1 2.224-2.941z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M38.47 52L52 38.462l-23.648-23.67L43.209 0H.035L0 43.137l14.757-14.865L38.47 52zm74.773 47.726L89.526 76 76 89.536l23.648 23.672L84.795 128h43.174L128 84.863l-14.757 14.863zM89.538 52l23.668-23.648L128 43.207V.038L84.866 0 99.73 14.76 76 38.472 89.538 52zM38.46 76L14.792 99.651 0 84.794v43.173l43.137.033-14.865-14.757L52 89.53 38.46 76z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M38.47 52L52 38.462l-23.648-23.67L43.209 0H.035L0 43.137l14.757-14.865L38.47 52zm74.773 47.726L89.526 76 76 89.536l23.648 23.672L84.795 128h43.174L128 84.863l-14.757 14.863zM89.538 52l23.668-23.648L128 43.207V.038L84.866 0 99.73 14.76 76 38.472 89.538 52zM38.46 76L14.792 99.651 0 84.794v43.173l43.137.033-14.865-14.757L52 89.53 38.46 76z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M1.482 70.131l36.204 16.18 69.932-65.485-61.38 70.594 46.435 18.735c1.119.425 2.397-.17 2.797-1.363v-.085L127.998.047 1.322 65.874c-1.12.597-1.519 1.959-1.04 3.151.32.511.72.937 1.2 1.107zm44.676 57.821L64.22 107.26l-18.062-7.834v28.527z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M1.482 70.131l36.204 16.18 69.932-65.485-61.38 70.594 46.435 18.735c1.119.425 2.397-.17 2.797-1.363v-.085L127.998.047 1.322 65.874c-1.12.597-1.519 1.959-1.04 3.151.32.511.72.937 1.2 1.107zm44.676 57.821L64.22 107.26l-18.062-7.834v28.527z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M115.147.062a13 13 0 0 1 4.94.945c1.55.63 2.907 1.526 4.069 2.688a13.148 13.148 0 0 1 2.761 4.069c.678 1.55 1.017 3.245 1.017 5.086v102.3c0 3.681-1.187 6.733-3.56 9.155-2.373 2.422-5.352 3.633-8.937 3.633H12.992c-3.875 0-7-1.26-9.373-3.779-2.373-2.518-3.56-5.667-3.56-9.445V12.704c0-3.39 1.163-6.345 3.488-8.863C5.872 1.32 8.972.062 12.847.062h102.3zM81.434 109.047c1.744 0 3.003-.412 3.778-1.235.775-.824 1.163-1.914 1.163-3.27 0-1.26-.388-2.325-1.163-3.197-.775-.872-2.034-1.307-3.778-1.307H72.57c.097-.194.145-.485.145-.872V27.09h9.01c1.743 0 2.954-.436 3.633-1.308.678-.872 1.017-1.938 1.017-3.197 0-1.26-.34-2.325-1.017-3.197-.679-.872-1.89-1.308-3.633-1.308H46.268c-1.743 0-2.954.436-3.632 1.308-.678.872-1.018 1.938-1.018 3.197 0 1.26.34 2.325 1.018 3.197.678.872 1.889 1.308 3.632 1.308h8.138v72.075c0 .193.024.339.073.436.048.096.072.242.072.436H46.56c-1.744 0-3.003.435-3.778 1.307-.775.872-1.163 1.938-1.163 3.197 0 1.356.388 2.446 1.163 3.27.775.823 2.034 1.235 3.778 1.235h34.875z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M115.147.062a13 13 0 0 1 4.94.945c1.55.63 2.907 1.526 4.069 2.688a13.148 13.148 0 0 1 2.761 4.069c.678 1.55 1.017 3.245 1.017 5.086v102.3c0 3.681-1.187 6.733-3.56 9.155-2.373 2.422-5.352 3.633-8.937 3.633H12.992c-3.875 0-7-1.26-9.373-3.779-2.373-2.518-3.56-5.667-3.56-9.445V12.704c0-3.39 1.163-6.345 3.488-8.863C5.872 1.32 8.972.062 12.847.062h102.3zM81.434 109.047c1.744 0 3.003-.412 3.778-1.235.775-.824 1.163-1.914 1.163-3.27 0-1.26-.388-2.325-1.163-3.197-.775-.872-2.034-1.307-3.778-1.307H72.57c.097-.194.145-.485.145-.872V27.09h9.01c1.743 0 2.954-.436 3.633-1.308.678-.872 1.017-1.938 1.017-3.197 0-1.26-.34-2.325-1.017-3.197-.679-.872-1.89-1.308-3.633-1.308H46.268c-1.743 0-2.954.436-3.632 1.308-.678.872-1.018 1.938-1.018 3.197 0 1.26.34 2.325 1.018 3.197.678.872 1.889 1.308 3.632 1.308h8.138v72.075c0 .193.024.339.073.436.048.096.072.242.072.436H46.56c-1.744 0-3.003.435-3.778 1.307-.775.872-1.163 1.938-1.163 3.197 0 1.356.388 2.446 1.163 3.27.775.823 2.034 1.235 3.778 1.235h34.875z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M83.287 103.01c-1.57-3.84-6.778-10.414-15.447-19.548-2.327-2.444-2.182-4.306-1.338-9.862v-.64c.553-3.81 1.513-6.05 14.313-8.087 6.516-1.018 8.203 1.57 10.589 5.178l.785 1.193a12.625 12.625 0 0 0 6.43 5.207c1.134.524 2.53 1.164 4.421 2.24 4.596 2.53 4.596 5.41 4.596 11.753v.727a26.91 26.91 0 0 1-5.178 17.454 59.055 59.055 0 0 1-19.025 11.026c3.49-6.546.814-14.313 0-16.553l-.146-.087zM64 5.12a58.502 58.502 0 0 1 25.484 5.818 54.313 54.313 0 0 0-12.859 10.327c-.93 1.28-1.716 2.473-2.472 3.579-2.444 3.694-3.637 5.352-5.818 5.614a25.105 25.105 0 0 1-4.219 0c-4.276-.29-10.094-.64-11.956 4.422-1.193 3.23-1.396 11.956 2.444 16.495.66 1.077.778 2.4.32 3.578a7.01 7.01 0 0 1-2.066 3.229 18.938 18.938 0 0 1-2.909-2.91 18.91 18.91 0 0 0-8.32-6.603c-1.25-.349-2.647-.64-3.985-.93-3.782-.786-8.03-1.688-9.019-3.812a14.895 14.895 0 0 1-.727-5.818 21.935 21.935 0 0 0-1.396-9.25 8.873 8.873 0 0 0-5.557-4.946A58.705 58.705 0 0 1 64 5.12zM0 64c0 35.346 28.654 64 64 64 35.346 0 64-28.654 64-64 0-35.346-28.654-64-64-64C28.654 0 0 28.654 0 64z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M83.287 103.01c-1.57-3.84-6.778-10.414-15.447-19.548-2.327-2.444-2.182-4.306-1.338-9.862v-.64c.553-3.81 1.513-6.05 14.313-8.087 6.516-1.018 8.203 1.57 10.589 5.178l.785 1.193a12.625 12.625 0 0 0 6.43 5.207c1.134.524 2.53 1.164 4.421 2.24 4.596 2.53 4.596 5.41 4.596 11.753v.727a26.91 26.91 0 0 1-5.178 17.454 59.055 59.055 0 0 1-19.025 11.026c3.49-6.546.814-14.313 0-16.553l-.146-.087zM64 5.12a58.502 58.502 0 0 1 25.484 5.818 54.313 54.313 0 0 0-12.859 10.327c-.93 1.28-1.716 2.473-2.472 3.579-2.444 3.694-3.637 5.352-5.818 5.614a25.105 25.105 0 0 1-4.219 0c-4.276-.29-10.094-.64-11.956 4.422-1.193 3.23-1.396 11.956 2.444 16.495.66 1.077.778 2.4.32 3.578a7.01 7.01 0 0 1-2.066 3.229 18.938 18.938 0 0 1-2.909-2.91 18.91 18.91 0 0 0-8.32-6.603c-1.25-.349-2.647-.64-3.985-.93-3.782-.786-8.03-1.688-9.019-3.812a14.895 14.895 0 0 1-.727-5.818 21.935 21.935 0 0 0-1.396-9.25 8.873 8.873 0 0 0-5.557-4.946A58.705 58.705 0 0 1 64 5.12zM0 64c0 35.346 28.654 64 64 64 35.346 0 64-28.654 64-64 0-35.346-28.654-64-64-64C28.654 0 0 28.654 0 64z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M84.742 36.8c2.398 7.2 5.595 12.8 11.19 18.4 4.795-4.8 7.992-11.2 10.39-18.4h-21.58zm-52.748 40h20.78l-10.39-28-10.39 28z"/><path d="M111.916 0H16.009C7.218 0 .025 7.2.025 16v96c0 8.8 7.193 16 15.984 16h95.907c8.791 0 15.984-7.2 15.984-16V16c0-8.8-6.394-16-15.984-16zM72.754 103.2c-1.598 1.6-3.197 1.6-4.795 1.6-.8 0-2.398 0-3.197-.8-.8-.8-1.599 0-1.599-.8s-.799-1.6-1.598-3.2c-.8-1.6-.8-2.4-1.599-4l-3.196-8.8H28.797L25.6 96c-1.598 3.2-2.398 5.6-3.197 7.2-.8 1.6-2.398 1.6-4.795 1.6-1.599 0-3.197-.8-4.796-1.6-1.598-1.6-2.397-2.4-2.397-4 0-.8 0-1.6.799-3.2.8-1.6.8-2.4 1.598-4l17.583-44.8c.8-1.6.8-3.2 1.599-4.8.799-1.6 1.598-3.2 2.397-4 .8-.8 1.599-2.4 3.197-3.2 1.599-.8 3.197-.8 4.796-.8 1.598 0 3.196 0 4.795.8 1.598.8 2.398 1.6 3.197 3.2.799.8 1.598 2.4 2.397 4 .8 1.6 1.599 3.2 2.398 5.6l17.583 44c1.598 3.2 2.398 5.6 2.398 7.2-.8.8-1.599 2.4-2.398 4zM116.711 72c-8.791-3.2-15.185-7.2-20.78-12-5.594 5.6-12.787 9.6-21.579 12l-2.397-4c8.791-2.4 15.984-5.6 21.579-11.2C87.939 51.2 83.144 44 81.545 36h-7.992v-3.2h21.58c-1.6-2.4-3.198-5.6-4.796-8l2.397-.8c1.599 2.4 3.997 5.6 5.595 8.8h19.98v4h-7.992c-2.397 8-6.393 15.2-11.189 20 5.595 4.8 11.988 8.8 20.78 11.2l-3.197 4z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M84.742 36.8c2.398 7.2 5.595 12.8 11.19 18.4 4.795-4.8 7.992-11.2 10.39-18.4h-21.58zm-52.748 40h20.78l-10.39-28-10.39 28z"/><path d="M111.916 0H16.009C7.218 0 .025 7.2.025 16v96c0 8.8 7.193 16 15.984 16h95.907c8.791 0 15.984-7.2 15.984-16V16c0-8.8-6.394-16-15.984-16zM72.754 103.2c-1.598 1.6-3.197 1.6-4.795 1.6-.8 0-2.398 0-3.197-.8-.8-.8-1.599 0-1.599-.8s-.799-1.6-1.598-3.2c-.8-1.6-.8-2.4-1.599-4l-3.196-8.8H28.797L25.6 96c-1.598 3.2-2.398 5.6-3.197 7.2-.8 1.6-2.398 1.6-4.795 1.6-1.599 0-3.197-.8-4.796-1.6-1.598-1.6-2.397-2.4-2.397-4 0-.8 0-1.6.799-3.2.8-1.6.8-2.4 1.598-4l17.583-44.8c.8-1.6.8-3.2 1.599-4.8.799-1.6 1.598-3.2 2.397-4 .8-.8 1.599-2.4 3.197-3.2 1.599-.8 3.197-.8 4.796-.8 1.598 0 3.196 0 4.795.8 1.598.8 2.398 1.6 3.197 3.2.799.8 1.598 2.4 2.397 4 .8 1.6 1.599 3.2 2.398 5.6l17.583 44c1.598 3.2 2.398 5.6 2.398 7.2-.8.8-1.599 2.4-2.398 4zM116.711 72c-8.791-3.2-15.185-7.2-20.78-12-5.594 5.6-12.787 9.6-21.579 12l-2.397-4c8.791-2.4 15.984-5.6 21.579-11.2C87.939 51.2 83.144 44 81.545 36h-7.992v-3.2h21.58c-1.6-2.4-3.198-5.6-4.796-8l2.397-.8c1.599 2.4 3.997 5.6 5.595 8.8h19.98v4h-7.992c-2.397 8-6.393 15.2-11.189 20 5.595 4.8 11.988 8.8 20.78 11.2l-3.197 4z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M115.625 127.937H.063V12.375h57.781v12.374H12.438v90.813h90.813V70.156h12.374z"/><path d="M116.426 2.821l8.753 8.753-56.734 56.734-8.753-8.745z"/><path d="M127.893 37.982h-12.375V12.375H88.706V0h39.187z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M115.625 127.937H.063V12.375h57.781v12.374H12.438v90.813h90.813V70.156h12.374z"/><path d="M116.426 2.821l8.753 8.753-56.734 56.734-8.753-8.745z"/><path d="M127.893 37.982h-12.375V12.375H88.706V0h39.187z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M1.585 12.087c0 6.616 3.974 11.98 8.877 11.98 4.902 0 8.877-5.364 8.877-11.98 0-6.616-3.975-11.98-8.877-11.98-4.903 0-8.877 5.364-8.877 11.98zM125.86.107H35.613c-1.268 0-2.114 1.426-2.114 2.852v18.255c0 1.712 1.057 2.853 2.114 2.853h90.247c1.268 0 2.114-1.426 2.114-2.853V2.96c0-1.711-1.057-2.852-2.114-2.852zM.106 62.86c0 6.615 3.974 11.979 8.876 11.979 4.903 0 8.877-5.364 8.877-11.98 0-6.616-3.974-11.98-8.877-11.98-4.902 0-8.876 5.364-8.876 11.98zM124.17 50.88H33.921c-1.268 0-2.114 1.425-2.114 2.851v18.256c0 1.711 1.057 2.852 2.114 2.852h90.247c1.268 0 2.114-1.426 2.114-2.852V53.73c0-1.426-.846-2.852-2.114-2.852zM.106 115.913c0 6.616 3.974 11.98 8.876 11.98 4.903 0 8.877-5.364 8.877-11.98 0-6.616-3.974-11.98-8.877-11.98-4.902 0-8.876 5.364-8.876 11.98zm124.064-11.98H33.921c-1.268 0-2.114 1.426-2.114 2.853v18.255c0 1.711 1.057 2.852 2.114 2.852h90.247c1.268 0 2.114-1.426 2.114-2.852v-18.255c0-1.427-.846-2.853-2.114-2.853z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M1.585 12.087c0 6.616 3.974 11.98 8.877 11.98 4.902 0 8.877-5.364 8.877-11.98 0-6.616-3.975-11.98-8.877-11.98-4.903 0-8.877 5.364-8.877 11.98zM125.86.107H35.613c-1.268 0-2.114 1.426-2.114 2.852v18.255c0 1.712 1.057 2.853 2.114 2.853h90.247c1.268 0 2.114-1.426 2.114-2.853V2.96c0-1.711-1.057-2.852-2.114-2.852zM.106 62.86c0 6.615 3.974 11.979 8.876 11.979 4.903 0 8.877-5.364 8.877-11.98 0-6.616-3.974-11.98-8.877-11.98-4.902 0-8.876 5.364-8.876 11.98zM124.17 50.88H33.921c-1.268 0-2.114 1.425-2.114 2.851v18.256c0 1.711 1.057 2.852 2.114 2.852h90.247c1.268 0 2.114-1.426 2.114-2.852V53.73c0-1.426-.846-2.852-2.114-2.852zM.106 115.913c0 6.616 3.974 11.98 8.876 11.98 4.903 0 8.877-5.364 8.877-11.98 0-6.616-3.974-11.98-8.877-11.98-4.902 0-8.876 5.364-8.876 11.98zm124.064-11.98H33.921c-1.268 0-2.114 1.426-2.114 2.853v18.255c0 1.711 1.057 2.852 2.114 2.852h90.247c1.268 0 2.114-1.426 2.114-2.852v-18.255c0-1.427-.846-2.853-2.114-2.853z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M119.88 49.674h-7.987V39.52C111.893 17.738 90.45.08 63.996.08 37.543.08 16.1 17.738 16.1 39.52v10.154H8.113c-4.408 0-7.987 2.94-7.987 6.577v65.13c0 3.637 3.57 6.577 7.987 6.577H119.88c4.407 0 7.987-2.94 7.987-6.577v-65.13c-.008-3.636-3.58-6.577-7.987-6.577zm-23.953 0H32.065V39.52c0-14.524 14.301-26.295 31.931-26.295 17.63 0 31.932 11.777 31.932 26.295v10.153z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M119.88 49.674h-7.987V39.52C111.893 17.738 90.45.08 63.996.08 37.543.08 16.1 17.738 16.1 39.52v10.154H8.113c-4.408 0-7.987 2.94-7.987 6.577v65.13c0 3.637 3.57 6.577 7.987 6.577H119.88c4.407 0 7.987-2.94 7.987-6.577v-65.13c-.008-3.636-3.58-6.577-7.987-6.577zm-23.953 0H32.065V39.52c0-14.524 14.301-26.295 31.931-26.295 17.63 0 31.932 11.777 31.932 26.295v10.153z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M0 20.967v59.59c0 11.59 8.537 20.966 19.075 20.966h28.613l1 26.477L76.8 101.523h32.125c10.538 0 19.075-9.377 19.075-20.966v-59.59C128 9.377 119.463 0 108.925 0h-89.85C8.538 0 0 9.377 0 20.967zm82.325 33.1c0-5.524 4.013-9.935 9.037-9.935 5.026 0 9.038 4.41 9.038 9.934 0 5.524-4.025 9.934-9.038 9.934-5.024 0-9.037-4.41-9.037-9.934zm-27.613 0c0-5.524 4.013-9.935 9.038-9.935s9.037 4.41 9.037 9.934c0 5.524-4.025 9.934-9.037 9.934-5.025 0-9.038-4.41-9.038-9.934zm-27.1 0c0-5.524 4.013-9.935 9.038-9.935s9.038 4.41 9.038 9.934c0 5.524-4.026 9.934-9.05 9.934-5.013 0-9.025-4.41-9.025-9.934z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M0 20.967v59.59c0 11.59 8.537 20.966 19.075 20.966h28.613l1 26.477L76.8 101.523h32.125c10.538 0 19.075-9.377 19.075-20.966v-59.59C128 9.377 119.463 0 108.925 0h-89.85C8.538 0 0 9.377 0 20.967zm82.325 33.1c0-5.524 4.013-9.935 9.037-9.935 5.026 0 9.038 4.41 9.038 9.934 0 5.524-4.025 9.934-9.038 9.934-5.024 0-9.037-4.41-9.037-9.934zm-27.613 0c0-5.524 4.013-9.935 9.038-9.935s9.037 4.41 9.037 9.934c0 5.524-4.025 9.934-9.037 9.934-5.025 0-9.038-4.41-9.038-9.934zm-27.1 0c0-5.524 4.013-9.935 9.038-9.935s9.038 4.41 9.038 9.934c0 5.524-4.026 9.934-9.05 9.934-5.013 0-9.025-4.41-9.025-9.934z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M54.122 127.892v-28.68H7.513V87.274h46.609v-12.4H7.513v-12.86h38.003L.099 0h22.6l32.556 45.07c3.617 5.144 6.44 9.611 8.487 13.385 1.788-3.05 4.89-7.779 9.301-14.186L103.93 0h24.01L82.385 62.013h38.34v12.862h-46.41v12.4h46.41v11.937h-46.41v28.68H54.123z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M54.122 127.892v-28.68H7.513V87.274h46.609v-12.4H7.513v-12.86h38.003L.099 0h22.6l32.556 45.07c3.617 5.144 6.44 9.611 8.487 13.385 1.788-3.05 4.89-7.779 9.301-14.186L103.93 0h24.01L82.385 62.013h38.34v12.862h-46.41v12.4h46.41v11.937h-46.41v28.68H54.123z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.002 9.2c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-5.043-3.58-9.132-7.997-9.132S.002 4.157.002 9.2zM31.997.066h95.981V18.33H31.997V.066zm0 45.669c0 5.044 3.58 9.132 7.998 9.132 4.417 0 7.997-4.088 7.997-9.132 0-3.263-1.524-6.278-3.998-7.91-2.475-1.63-5.524-1.63-7.998 0-2.475 1.632-4 4.647-4 7.91zM63.992 36.6h63.986v18.265H63.992V36.6zm-31.995 82.2c0 5.043 3.58 9.132 7.998 9.132 4.417 0 7.997-4.089 7.997-9.132 0-5.044-3.58-9.133-7.997-9.133s-7.998 4.089-7.998 9.133zm31.995-9.131h63.986v18.265H63.992V109.67zm0-27.404c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-3.263-1.524-6.277-3.998-7.909-2.475-1.631-5.524-1.631-7.998 0-2.475 1.632-4 4.646-4 7.91zm31.995-9.13h31.991V91.4H95.987V73.135z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.002 9.2c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-5.043-3.58-9.132-7.997-9.132S.002 4.157.002 9.2zM31.997.066h95.981V18.33H31.997V.066zm0 45.669c0 5.044 3.58 9.132 7.998 9.132 4.417 0 7.997-4.088 7.997-9.132 0-3.263-1.524-6.278-3.998-7.91-2.475-1.63-5.524-1.63-7.998 0-2.475 1.632-4 4.647-4 7.91zM63.992 36.6h63.986v18.265H63.992V36.6zm-31.995 82.2c0 5.043 3.58 9.132 7.998 9.132 4.417 0 7.997-4.089 7.997-9.132 0-5.044-3.58-9.133-7.997-9.133s-7.998 4.089-7.998 9.133zm31.995-9.131h63.986v18.265H63.992V109.67zm0-27.404c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-3.263-1.524-6.277-3.998-7.909-2.475-1.631-5.524-1.631-7.998 0-2.475 1.632-4 4.646-4 7.91zm31.995-9.13h31.991V91.4H95.987V73.135z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M108.8 44.322H89.6v-5.36c0-9.04-3.308-24.163-25.6-24.163-23.145 0-25.6 16.881-25.6 24.162v5.361H19.2v-5.36C19.2 15.281 36.798 0 64 0c27.202 0 44.8 15.281 44.8 38.961v5.361zm-32 39.356c0-5.44-5.763-9.832-12.8-9.832-7.037 0-12.8 4.392-12.8 9.832 0 3.682 2.567 6.808 6.407 8.477v11.205c0 2.718 2.875 4.962 6.4 4.962 3.524 0 6.4-2.244 6.4-4.962V92.155c3.833-1.669 6.393-4.795 6.393-8.477zM128 64v49.201c0 8.158-8.645 14.799-19.2 14.799H19.2C8.651 128 0 121.359 0 113.201V64c0-8.153 8.645-14.799 19.2-14.799h89.6c10.555 0 19.2 6.646 19.2 14.799z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M108.8 44.322H89.6v-5.36c0-9.04-3.308-24.163-25.6-24.163-23.145 0-25.6 16.881-25.6 24.162v5.361H19.2v-5.36C19.2 15.281 36.798 0 64 0c27.202 0 44.8 15.281 44.8 38.961v5.361zm-32 39.356c0-5.44-5.763-9.832-12.8-9.832-7.037 0-12.8 4.392-12.8 9.832 0 3.682 2.567 6.808 6.407 8.477v11.205c0 2.718 2.875 4.962 6.4 4.962 3.524 0 6.4-2.244 6.4-4.962V92.155c3.833-1.669 6.393-4.795 6.393-8.477zM128 64v49.201c0 8.158-8.645 14.799-19.2 14.799H19.2C8.651 128 0 121.359 0 113.201V64c0-8.153 8.645-14.799 19.2-14.799h89.6c10.555 0 19.2 6.646 19.2 14.799z"/></svg> |
1 | <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="128" height="128"><path d="M869.073 277.307H657.111V65.344l211.962 211.963zm-238.232 26.27V65.344l-476.498-.054v416.957h714.73v-178.67H630.841zm-335.836 360.57c-5.07-3.064-10.944-5.133-17.61-6.201-6.67-1.064-13.603-1.6-20.81-1.6h-48.821v85.641h48.822c7.206 0 14.14-.532 20.81-1.6 6.665-1.065 12.54-3.133 17.609-6.202 5.064-3.063 9.134-7.406 12.208-13.007 3.065-5.602 4.6-12.937 4.6-22.011 0-9.07-1.535-16.408-4.6-22.01-3.074-5.603-7.144-9.94-12.208-13.01zM35.82 541.805v416.904h952.358V541.805H35.821zm331.421 191.179c-3.6 11.071-9.343 20.879-17.209 29.413-7.874 8.542-18.078 15.408-30.617 20.61-12.544 5.206-27.747 7.807-45.621 7.807h-66.036v102.45h-62.831V607.517h128.867c17.874 0 33.077 2.6 45.62 7.802 12.541 5.207 22.745 12.076 30.618 20.615 7.866 8.538 13.604 18.277 17.21 29.212 3.6 10.943 5.401 22.278 5.401 34.018 0 11.477-1.8 22.752-5.402 33.819zM644.9 806.417c-5.343 17.61-13.408 32.818-24.212 45.627-10.807 12.803-24.283 22.879-40.423 30.213-16.146 7.343-35.155 11.007-57.03 11.007h-123.26V607.518h123.26c18.41 0 35.552 2.941 51.428 8.808 15.873 5.869 29.618 14.671 41.22 26.412 11.608 11.744 20.674 26.411 27.217 44.02 6.535 17.61 9.803 38.288 9.803 62.035 0 20.81-2.67 40.02-8.003 57.624zm245.362-146.07h-138.07v66.03h119.66v48.829h-119.66v118.058h-62.83V607.518h200.9v52.829h-.001zm-318.2 25.611c-6.402-8.266-14.877-14.604-25.412-19.01-10.544-4.402-23.551-6.602-39.019-6.602h-44.825v180.088h56.029c9.07 0 17.872-1.463 26.415-4.401 8.535-2.932 16.14-7.802 22.812-14.609 6.665-6.8 12.007-15.667 16.007-26.61 4.003-10.94 6.003-24.275 6.003-40.021 0-14.408-1.4-27.416-4.202-39.019-2.8-11.607-7.406-21.542-13.808-29.816zm0 0"/></svg> | 1 | <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="128" height="128"><path d="M869.073 277.307H657.111V65.344l211.962 211.963zm-238.232 26.27V65.344l-476.498-.054v416.957h714.73v-178.67H630.841zm-335.836 360.57c-5.07-3.064-10.944-5.133-17.61-6.201-6.67-1.064-13.603-1.6-20.81-1.6h-48.821v85.641h48.822c7.206 0 14.14-.532 20.81-1.6 6.665-1.065 12.54-3.133 17.609-6.202 5.064-3.063 9.134-7.406 12.208-13.007 3.065-5.602 4.6-12.937 4.6-22.011 0-9.07-1.535-16.408-4.6-22.01-3.074-5.603-7.144-9.94-12.208-13.01zM35.82 541.805v416.904h952.358V541.805H35.821zm331.421 191.179c-3.6 11.071-9.343 20.879-17.209 29.413-7.874 8.542-18.078 15.408-30.617 20.61-12.544 5.206-27.747 7.807-45.621 7.807h-66.036v102.45h-62.831V607.517h128.867c17.874 0 33.077 2.6 45.62 7.802 12.541 5.207 22.745 12.076 30.618 20.615 7.866 8.538 13.604 18.277 17.21 29.212 3.6 10.943 5.401 22.278 5.401 34.018 0 11.477-1.8 22.752-5.402 33.819zM644.9 806.417c-5.343 17.61-13.408 32.818-24.212 45.627-10.807 12.803-24.283 22.879-40.423 30.213-16.146 7.343-35.155 11.007-57.03 11.007h-123.26V607.518h123.26c18.41 0 35.552 2.941 51.428 8.808 15.873 5.869 29.618 14.671 41.22 26.412 11.608 11.744 20.674 26.411 27.217 44.02 6.535 17.61 9.803 38.288 9.803 62.035 0 20.81-2.67 40.02-8.003 57.624zm245.362-146.07h-138.07v66.03h119.66v48.829h-119.66v118.058h-62.83V607.518h200.9v52.829h-.001zm-318.2 25.611c-6.402-8.266-14.877-14.604-25.412-19.01-10.544-4.402-23.551-6.602-39.019-6.602h-44.825v180.088h56.029c9.07 0 17.872-1.463 26.415-4.401 8.535-2.932 16.14-7.802 22.812-14.609 6.665-6.8 12.007-15.667 16.007-26.61 4.003-10.94 6.003-24.275 6.003-40.021 0-14.408-1.4-27.416-4.202-39.019-2.8-11.607-7.406-21.542-13.808-29.816zm0 0"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M104.185 95.254c8.161 7.574 13.145 17.441 13.145 28.28 0 1.508-.098 2.998-.285 4.466h-10.784c.238-1.465.403-2.948.403-4.465 0-8.983-4.36-17.115-11.419-23.216C86 104.66 75.355 107.162 64 107.162c-11.344 0-21.98-2.495-31.22-6.83-7.064 6.099-11.444 14.218-11.444 23.203 0 1.517.165 3 .403 4.465H10.955a35.444 35.444 0 0 1-.285-4.465c0-10.838 4.974-20.713 13.127-28.291C9.294 85.42.003 70.417.003 53.58.003 23.99 28.656.001 64 .001s63.997 23.988 63.997 53.58c0 16.842-9.299 31.85-23.812 41.673zM64 36.867c-29.454 0-53.33-10.077-53.33 15.342 0 25.418 23.876 46.023 53.33 46.023 29.454 0 53.33-20.605 53.33-46.023 0-25.419-23.876-15.342-53.33-15.342zm24.888 25.644c-3.927 0-7.111-2.665-7.111-5.953 0-3.288 3.184-5.954 7.11-5.954 3.928 0 7.111 2.666 7.111 5.954s-3.183 5.953-7.11 5.953zm-3.556 16.372c0 4.11-9.55 7.442-21.332 7.442-11.781 0-21.332-3.332-21.332-7.442 0-1.06.656-2.064 1.8-2.976 3.295 2.626 10.79 4.465 19.532 4.465 8.743 0 16.237-1.84 19.531-4.465 1.145.912 1.801 1.916 1.801 2.976zm-46.22-16.372c-3.927 0-7.11-2.665-7.11-5.953 0-3.288 3.183-5.954 7.11-5.954 3.927 0 7.111 2.666 7.111 5.954s-3.184 5.953-7.11 5.953z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M104.185 95.254c8.161 7.574 13.145 17.441 13.145 28.28 0 1.508-.098 2.998-.285 4.466h-10.784c.238-1.465.403-2.948.403-4.465 0-8.983-4.36-17.115-11.419-23.216C86 104.66 75.355 107.162 64 107.162c-11.344 0-21.98-2.495-31.22-6.83-7.064 6.099-11.444 14.218-11.444 23.203 0 1.517.165 3 .403 4.465H10.955a35.444 35.444 0 0 1-.285-4.465c0-10.838 4.974-20.713 13.127-28.291C9.294 85.42.003 70.417.003 53.58.003 23.99 28.656.001 64 .001s63.997 23.988 63.997 53.58c0 16.842-9.299 31.85-23.812 41.673zM64 36.867c-29.454 0-53.33-10.077-53.33 15.342 0 25.418 23.876 46.023 53.33 46.023 29.454 0 53.33-20.605 53.33-46.023 0-25.419-23.876-15.342-53.33-15.342zm24.888 25.644c-3.927 0-7.111-2.665-7.111-5.953 0-3.288 3.184-5.954 7.11-5.954 3.928 0 7.111 2.666 7.111 5.954s-3.183 5.953-7.11 5.953zm-3.556 16.372c0 4.11-9.55 7.442-21.332 7.442-11.781 0-21.332-3.332-21.332-7.442 0-1.06.656-2.064 1.8-2.976 3.295 2.626 10.79 4.465 19.532 4.465 8.743 0 16.237-1.84 19.531-4.465 1.145.912 1.801 1.916 1.801 2.976zm-46.22-16.372c-3.927 0-7.11-2.665-7.11-5.953 0-3.288 3.183-5.954 7.11-5.954 3.927 0 7.111 2.666 7.111 5.954s-3.184 5.953-7.11 5.953z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M95.648 118.762c0 5.035-3.563 9.121-7.979 9.121H7.98c-4.416 0-7.979-4.086-7.979-9.121C0 100.519 15.408 83.47 31.152 76.75c-9.099-6.43-15.216-17.863-15.216-30.987v-9.128c0-20.16 14.293-36.518 31.893-36.518s31.894 16.358 31.894 36.518v9.122c0 13.137-6.123 24.556-15.216 30.993 15.738 6.726 31.141 23.769 31.141 42.012z"/><path d="M106.032 118.252h15.867c3.376 0 6.101-3.125 6.101-6.972 0-13.957-11.787-26.984-23.819-32.123 6.955-4.919 11.638-13.66 11.638-23.704v-6.985c0-15.416-10.928-27.926-24.39-27.926-1.674 0-3.306.193-4.89.561 1.936 4.713 3.018 9.974 3.018 15.526v9.121c0 13.137-3.056 23.111-11.066 30.993 14.842 4.41 27.312 23.42 27.541 41.509z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M95.648 118.762c0 5.035-3.563 9.121-7.979 9.121H7.98c-4.416 0-7.979-4.086-7.979-9.121C0 100.519 15.408 83.47 31.152 76.75c-9.099-6.43-15.216-17.863-15.216-30.987v-9.128c0-20.16 14.293-36.518 31.893-36.518s31.894 16.358 31.894 36.518v9.122c0 13.137-6.123 24.556-15.216 30.993 15.738 6.726 31.141 23.769 31.141 42.012z"/><path d="M106.032 118.252h15.867c3.376 0 6.101-3.125 6.101-6.972 0-13.957-11.787-26.984-23.819-32.123 6.955-4.919 11.638-13.66 11.638-23.704v-6.985c0-15.416-10.928-27.926-24.39-27.926-1.674 0-3.306.193-4.89.561 1.936 4.713 3.018 9.974 3.018 15.526v9.121c0 13.137-3.056 23.111-11.066 30.993 14.842 4.41 27.312 23.42 27.541 41.509z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M18.448 57.545l-.244-.744-.198-.968-.132-.53v-2.181l.236-.859.24-.908.317-.953.428-1.06.561-1.103.794-1.104v-.773l.077-.724.123-.984.34-1.106.313-1.194.25-.548.289-.511.371-.569.405-.423v-2.73l.234-1.407.236-1.633.42-1.955.577-2.035.43-1.118.426-1.217.468-1.135.559-1.216.57-1.332.655-1.247.737-1.331.929-1.33.43-.762.457-.624.995-1.406 1.025-1.403 1.163-1.444 1.246-1.405 1.352-1.384 1.41-1.423 1.708-1.536 1.083-.934 1.322-1.008 1.34-.89 1.448-.855 1.392-.76 1.57-.63 1.667-.775 1.657-.532 1.653-.552 1.787-.548 1.785-.417 1.876-.347L59.128.68l1.879-.245 1.876-.252 2.002-.106h5.912l1.97.243 1.981.231 2.019.207 1.874.441 1.979.413 1.857.475 2.035.53 1.862.646 1.782.738 1.904.78 1.736.853 1.689.95 1.655 1.044 1.425.971.662.548.693.401 1.323 1.1 1.115 1.064 1.112 1.1 1.083 1.214.894 1.178 1.064 1.217.74 1.306.752 1.162.798 1.352.661 1.175 1.113 2.489.546 1.286.428 1.192.428 1.294.384 1.217.267 1.047.347 1.231.607 2.198.388 1.924.253 1.861.217 1.497.342 2.28.077.362.274.41.737 1.18.473.8.42.832.534.892.472 1.07.307 1.093.334 1.2.252 1.232.115.605.106.746v.648l-.106.643v.8l-.192.774-.35 1.5-.403.76-.299.852v.213l.142.264.4.623 1.746 2.53 1.377 1.9.66 1.267.889 1.389.774 1.52.893 1.627.894 1.828 1.006 2.069.567 1.268.518 1.239.447 1.307.44 1.175.336 1.235.342 1.16.432 2.261.343 2.31.235 2.05v2.891l-.158 1.025-.226 1.768-.308 1.59-.48 1.44-.18.588-.336.707-.28.493-.375.607-.33.383-.42.494-.375.4-.401.34-.48.207-.432.207-.355.114h-.543l-.346-.114-.66-.32-.302-.212-.317-.223-.347-.304-.35-.342-.579-.63-.684-.89-.539-.917-.538-.734-.526-.855-.741-1.517-.833-1.579-.098-.055h-.138l-.338.247-.196.415-.326.516-.567 1.533-.856 2.182-1.096 2.626-.824 1.308-.864 1.366-1.027 1.536-1.09 1.503-.557.68-.676.743-1.555 1.497.136.135.21.214.777.446 3.235 1.524 1.41.779 1.347.756 1.332.953 1.187.982.574.443.432.511.445.593.367.643.198.533.242.64.105.554.115.647-.115.433v.44l-.105.454-.242.415-.092.325-.22.394-.587.784-.543.627-.42.47-.35.348-.893.638-1.01.556-1.077.532-1.155.511-1.287.495-.693.207-.608.167-1.496.342-1.545.325-1.552.323-1.689.27-1.74.072-1.785.21h-5.539l-1.998-.114-1.86-.168-2.005-.27-1.99-.209-2.095-.286-2.03-.495-1.981-.374-1.968-.552-2.019-.707-1.98-.585-1.044-.342-.927-.323-.586-.223-.582-.12h-1.647l-1.904-.131-.962-.096-1.24-.135-.795.705-1.085.665-1.471.701-1.628.875-.99.475-1.033.376-2.281.914-1.24.305-1.3.343-1.803.344-1.13.086-1.193.1-1.246.135-1.45.053h-5.926l-3.346-.053-3.25-.321-1.644-.23-1.589-.23-1.546-.227-1.547-.305-1.442-.456-1.434-.325-1.294-.51-1.223-.474-1.142-.533-.99-.583-.984-.71-.336-.343-.44-.415-.334-.362-.3-.417-.278-.415-.215-.42-.311-.89-.109-.46-.138-.51v-.473l.138-.533v-.53l.109-.53v-1.069l.052-.564.259-.647.215-.646.39-.779.286-.3.236-.348.615-.738.49-.38.464-.266.428-.338.676-.21.543-.324.676-.341.77-.227.775-.231.897-.192.85-.11 1.008-.13 1.093-.081.284-.092h.063l.137-.115v-.13l-.2-.266-.58-.27-1.45-1.231-.975-.761-1.127-.967-1.136-1.082-1.181-1.382-1.36-1.558-.508-.843-.672-.87-.58-1.007-.522-1.1-.704-1.047-.459-1.194-.547-1.192-.546-1.33-.397-1.273-.378-1.575-.112-.057h-.115l-.059-.113h-.14l-.23.113-.114.057-.158.264-.057.321-.119.286-.206.477-.664 1.157-.345.701-.546.612-.58.736-.641.816-.677.724-.795.701-.734.658-.814.524-.89.546-.855.325-1.008.247-.99.095h-.233l-.228-.095-.18-.384-.29-.188-.38-.912-.237-.493-.255-.707-.21-.734-.113-.724-.313-1.648-.12-.972v-3.185l.12-2.379.196-1.214.23-1.252.21-1.347.374-1.254.42-1.443.431-1.407.578-1.448.545-1.38.754-1.4.699-1.52.855-1.425 1.006-1.538 1.023-1.382 1.069-1.538.891-1.071 1.142-1.227 1.202-1.237.56-.59.678-.662.985-.836 1.012-.853 1.647-1.446 1.242-.889z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M18.448 57.545l-.244-.744-.198-.968-.132-.53v-2.181l.236-.859.24-.908.317-.953.428-1.06.561-1.103.794-1.104v-.773l.077-.724.123-.984.34-1.106.313-1.194.25-.548.289-.511.371-.569.405-.423v-2.73l.234-1.407.236-1.633.42-1.955.577-2.035.43-1.118.426-1.217.468-1.135.559-1.216.57-1.332.655-1.247.737-1.331.929-1.33.43-.762.457-.624.995-1.406 1.025-1.403 1.163-1.444 1.246-1.405 1.352-1.384 1.41-1.423 1.708-1.536 1.083-.934 1.322-1.008 1.34-.89 1.448-.855 1.392-.76 1.57-.63 1.667-.775 1.657-.532 1.653-.552 1.787-.548 1.785-.417 1.876-.347L59.128.68l1.879-.245 1.876-.252 2.002-.106h5.912l1.97.243 1.981.231 2.019.207 1.874.441 1.979.413 1.857.475 2.035.53 1.862.646 1.782.738 1.904.78 1.736.853 1.689.95 1.655 1.044 1.425.971.662.548.693.401 1.323 1.1 1.115 1.064 1.112 1.1 1.083 1.214.894 1.178 1.064 1.217.74 1.306.752 1.162.798 1.352.661 1.175 1.113 2.489.546 1.286.428 1.192.428 1.294.384 1.217.267 1.047.347 1.231.607 2.198.388 1.924.253 1.861.217 1.497.342 2.28.077.362.274.41.737 1.18.473.8.42.832.534.892.472 1.07.307 1.093.334 1.2.252 1.232.115.605.106.746v.648l-.106.643v.8l-.192.774-.35 1.5-.403.76-.299.852v.213l.142.264.4.623 1.746 2.53 1.377 1.9.66 1.267.889 1.389.774 1.52.893 1.627.894 1.828 1.006 2.069.567 1.268.518 1.239.447 1.307.44 1.175.336 1.235.342 1.16.432 2.261.343 2.31.235 2.05v2.891l-.158 1.025-.226 1.768-.308 1.59-.48 1.44-.18.588-.336.707-.28.493-.375.607-.33.383-.42.494-.375.4-.401.34-.48.207-.432.207-.355.114h-.543l-.346-.114-.66-.32-.302-.212-.317-.223-.347-.304-.35-.342-.579-.63-.684-.89-.539-.917-.538-.734-.526-.855-.741-1.517-.833-1.579-.098-.055h-.138l-.338.247-.196.415-.326.516-.567 1.533-.856 2.182-1.096 2.626-.824 1.308-.864 1.366-1.027 1.536-1.09 1.503-.557.68-.676.743-1.555 1.497.136.135.21.214.777.446 3.235 1.524 1.41.779 1.347.756 1.332.953 1.187.982.574.443.432.511.445.593.367.643.198.533.242.64.105.554.115.647-.115.433v.44l-.105.454-.242.415-.092.325-.22.394-.587.784-.543.627-.42.47-.35.348-.893.638-1.01.556-1.077.532-1.155.511-1.287.495-.693.207-.608.167-1.496.342-1.545.325-1.552.323-1.689.27-1.74.072-1.785.21h-5.539l-1.998-.114-1.86-.168-2.005-.27-1.99-.209-2.095-.286-2.03-.495-1.981-.374-1.968-.552-2.019-.707-1.98-.585-1.044-.342-.927-.323-.586-.223-.582-.12h-1.647l-1.904-.131-.962-.096-1.24-.135-.795.705-1.085.665-1.471.701-1.628.875-.99.475-1.033.376-2.281.914-1.24.305-1.3.343-1.803.344-1.13.086-1.193.1-1.246.135-1.45.053h-5.926l-3.346-.053-3.25-.321-1.644-.23-1.589-.23-1.546-.227-1.547-.305-1.442-.456-1.434-.325-1.294-.51-1.223-.474-1.142-.533-.99-.583-.984-.71-.336-.343-.44-.415-.334-.362-.3-.417-.278-.415-.215-.42-.311-.89-.109-.46-.138-.51v-.473l.138-.533v-.53l.109-.53v-1.069l.052-.564.259-.647.215-.646.39-.779.286-.3.236-.348.615-.738.49-.38.464-.266.428-.338.676-.21.543-.324.676-.341.77-.227.775-.231.897-.192.85-.11 1.008-.13 1.093-.081.284-.092h.063l.137-.115v-.13l-.2-.266-.58-.27-1.45-1.231-.975-.761-1.127-.967-1.136-1.082-1.181-1.382-1.36-1.558-.508-.843-.672-.87-.58-1.007-.522-1.1-.704-1.047-.459-1.194-.547-1.192-.546-1.33-.397-1.273-.378-1.575-.112-.057h-.115l-.059-.113h-.14l-.23.113-.114.057-.158.264-.057.321-.119.286-.206.477-.664 1.157-.345.701-.546.612-.58.736-.641.816-.677.724-.795.701-.734.658-.814.524-.89.546-.855.325-1.008.247-.99.095h-.233l-.228-.095-.18-.384-.29-.188-.38-.912-.237-.493-.255-.707-.21-.734-.113-.724-.313-1.648-.12-.972v-3.185l.12-2.379.196-1.214.23-1.252.21-1.347.374-1.254.42-1.443.431-1.407.578-1.448.545-1.38.754-1.4.699-1.52.855-1.425 1.006-1.538 1.023-1.382 1.069-1.538.891-1.071 1.142-1.227 1.202-1.237.56-.59.678-.662.985-.836 1.012-.853 1.647-1.446 1.242-.889z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M124.884 109.812L94.256 79.166c-.357-.357-.757-.629-1.129-.914a50.366 50.366 0 0 0 8.186-27.59C101.327 22.689 78.656 0 50.67 0 22.685 0 0 22.688 0 50.663c0 27.989 22.685 50.663 50.656 50.663 10.186 0 19.643-3.03 27.6-8.201.286.385.557.771.9 1.114l30.628 30.632a10.633 10.633 0 0 0 7.543 3.129c2.728 0 5.457-1.043 7.543-3.115 4.171-4.157 4.171-10.915.014-15.073M50.671 85.338C31.557 85.338 16 69.78 16 50.663c0-19.102 15.557-34.661 34.67-34.661 19.115 0 34.657 15.559 34.657 34.675 0 19.102-15.557 34.661-34.656 34.661"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M124.884 109.812L94.256 79.166c-.357-.357-.757-.629-1.129-.914a50.366 50.366 0 0 0 8.186-27.59C101.327 22.689 78.656 0 50.67 0 22.685 0 0 22.688 0 50.663c0 27.989 22.685 50.663 50.656 50.663 10.186 0 19.643-3.03 27.6-8.201.286.385.557.771.9 1.114l30.628 30.632a10.633 10.633 0 0 0 7.543 3.129c2.728 0 5.457-1.043 7.543-3.115 4.171-4.157 4.171-10.915.014-15.073M50.671 85.338C31.557 85.338 16 69.78 16 50.663c0-19.102 15.557-34.661 34.67-34.661 19.115 0 34.657 15.559 34.657 34.675 0 19.102-15.557 34.661-34.656 34.661"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M42.913 101.36c1.642 0 3.198.332 4.667.996a12.28 12.28 0 0 1 3.89 2.772c1.123 1.184 1.987 2.582 2.592 4.193.605 1.612.908 3.318.908 5.118 0 1.8-.303 3.507-.908 5.118-.605 1.611-1.469 3.01-2.593 4.194a13.3 13.3 0 0 1-3.889 2.843 10.582 10.582 0 0 1-4.667 1.066c-1.729 0-3.306-.355-4.732-1.066a13.604 13.604 0 0 1-3.825-2.843c-1.123-1.185-1.988-2.583-2.593-4.194a14.437 14.437 0 0 1-.907-5.118c0-1.8.302-3.506.907-5.118.605-1.61 1.47-3.009 2.593-4.193a12.515 12.515 0 0 1 3.825-2.772c1.426-.664 3.003-.996 4.732-.996zm53.932.285c1.643 0 3.22.331 4.733.995a11.386 11.386 0 0 1 3.889 2.772c1.08 1.185 1.945 2.583 2.593 4.194.648 1.61.972 3.317.972 5.118 0 1.8-.324 3.506-.972 5.117-.648 1.611-1.513 3.01-2.593 4.194a12.253 12.253 0 0 1-3.89 2.843 11 11 0 0 1-4.732 1.066 10.58 10.58 0 0 1-4.667-1.066 12.478 12.478 0 0 1-3.824-2.843c-1.08-1.185-1.945-2.583-2.593-4.194a13.581 13.581 0 0 1-.973-5.117c0-1.801.325-3.507.973-5.118.648-1.611 1.512-3.01 2.593-4.194a11.559 11.559 0 0 1 3.824-2.772 11.212 11.212 0 0 1 4.667-.995zm21.781-80.747c2.42 0 4.3.355 5.64 1.066 1.34.71 2.29 1.587 2.852 2.63a6.427 6.427 0 0 1 .778 3.34c-.044 1.185-.195 2.204-.454 3.057-.26.853-.8 2.606-1.62 5.26a589.268 589.268 0 0 1-2.788 8.743 1236.373 1236.373 0 0 0-3.047 9.453c-.994 3.128-1.75 5.592-2.269 7.393-1.123 3.79-2.55 6.42-4.278 7.89-1.728 1.469-3.846 2.203-6.352 2.203H39.023l1.945 12.795h65.342c4.148 0 6.223 1.943 6.223 5.828 0 1.896-.41 3.53-1.232 4.905-.821 1.374-2.442 2.061-4.862 2.061H38.505c-1.729 0-3.176-.426-4.343-1.28-1.167-.852-2.14-1.966-2.917-3.34a21.277 21.277 0 0 1-1.88-4.478 44.128 44.128 0 0 1-1.102-4.55c-.087-.568-.324-1.942-.713-4.122-.39-2.18-.865-4.904-1.426-8.174l-1.88-10.947c-.692-4.027-1.383-8.079-2.075-12.154-1.642-9.572-3.5-20.234-5.574-31.986H6.87c-1.296 0-2.377-.356-3.24-1.067a9.024 9.024 0 0 1-2.14-2.558 10.416 10.416 0 0 1-1.167-3.2C.108 8.53 0 7.488 0 6.54c0-1.896.583-3.46 1.75-4.69C2.917.615 4.494 0 6.482 0h13.095c1.728 0 3.111.284 4.148.853 1.037.569 1.858 1.28 2.463 2.132a8.548 8.548 0 0 1 1.297 2.701c.26.948.475 1.754.648 2.417.173.758.346 1.825.519 3.199.173 1.374.345 2.772.518 4.193.26 1.706.519 3.507.778 5.403h88.678z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M42.913 101.36c1.642 0 3.198.332 4.667.996a12.28 12.28 0 0 1 3.89 2.772c1.123 1.184 1.987 2.582 2.592 4.193.605 1.612.908 3.318.908 5.118 0 1.8-.303 3.507-.908 5.118-.605 1.611-1.469 3.01-2.593 4.194a13.3 13.3 0 0 1-3.889 2.843 10.582 10.582 0 0 1-4.667 1.066c-1.729 0-3.306-.355-4.732-1.066a13.604 13.604 0 0 1-3.825-2.843c-1.123-1.185-1.988-2.583-2.593-4.194a14.437 14.437 0 0 1-.907-5.118c0-1.8.302-3.506.907-5.118.605-1.61 1.47-3.009 2.593-4.193a12.515 12.515 0 0 1 3.825-2.772c1.426-.664 3.003-.996 4.732-.996zm53.932.285c1.643 0 3.22.331 4.733.995a11.386 11.386 0 0 1 3.889 2.772c1.08 1.185 1.945 2.583 2.593 4.194.648 1.61.972 3.317.972 5.118 0 1.8-.324 3.506-.972 5.117-.648 1.611-1.513 3.01-2.593 4.194a12.253 12.253 0 0 1-3.89 2.843 11 11 0 0 1-4.732 1.066 10.58 10.58 0 0 1-4.667-1.066 12.478 12.478 0 0 1-3.824-2.843c-1.08-1.185-1.945-2.583-2.593-4.194a13.581 13.581 0 0 1-.973-5.117c0-1.801.325-3.507.973-5.118.648-1.611 1.512-3.01 2.593-4.194a11.559 11.559 0 0 1 3.824-2.772 11.212 11.212 0 0 1 4.667-.995zm21.781-80.747c2.42 0 4.3.355 5.64 1.066 1.34.71 2.29 1.587 2.852 2.63a6.427 6.427 0 0 1 .778 3.34c-.044 1.185-.195 2.204-.454 3.057-.26.853-.8 2.606-1.62 5.26a589.268 589.268 0 0 1-2.788 8.743 1236.373 1236.373 0 0 0-3.047 9.453c-.994 3.128-1.75 5.592-2.269 7.393-1.123 3.79-2.55 6.42-4.278 7.89-1.728 1.469-3.846 2.203-6.352 2.203H39.023l1.945 12.795h65.342c4.148 0 6.223 1.943 6.223 5.828 0 1.896-.41 3.53-1.232 4.905-.821 1.374-2.442 2.061-4.862 2.061H38.505c-1.729 0-3.176-.426-4.343-1.28-1.167-.852-2.14-1.966-2.917-3.34a21.277 21.277 0 0 1-1.88-4.478 44.128 44.128 0 0 1-1.102-4.55c-.087-.568-.324-1.942-.713-4.122-.39-2.18-.865-4.904-1.426-8.174l-1.88-10.947c-.692-4.027-1.383-8.079-2.075-12.154-1.642-9.572-3.5-20.234-5.574-31.986H6.87c-1.296 0-2.377-.356-3.24-1.067a9.024 9.024 0 0 1-2.14-2.558 10.416 10.416 0 0 1-1.167-3.2C.108 8.53 0 7.488 0 6.54c0-1.896.583-3.46 1.75-4.69C2.917.615 4.494 0 6.482 0h13.095c1.728 0 3.111.284 4.148.853 1.037.569 1.858 1.28 2.463 2.132a8.548 8.548 0 0 1 1.297 2.701c.26.948.475 1.754.648 2.417.173.758.346 1.825.519 3.199.173 1.374.345 2.772.518 4.193.26 1.706.519 3.507.778 5.403h88.678z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M0 54.857h54.796v18.286H36.531V128H18.265V73.143H0V54.857zm127.857-36.571H91.935V128H72.456V18.286H36.534V0h91.326l-.003 18.286z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M0 54.857h54.796v18.286H36.531V128H18.265V73.143H0V54.857zm127.857-36.571H91.935V128H72.456V18.286H36.534V0h91.326l-.003 18.286z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M31.652 93.206h33.401c1.44 2.418 3.077 4.663 4.93 6.692h-38.33v-6.692zm0-10.586h28.914a44.8 44.8 0 0 1-1.264-6.688h-27.65v6.688zm0-17.27H59.39c.288-2.286.714-4.532 1.34-6.687H31.65v6.687h.003zm53.913 44.84v5.85c0 2.798-2.095 5.075-4.667 5.075h-70.07c-2.576 0-4.663-2.277-4.663-5.075V31.26l23.22-20.96v22.25H17.16v6.688h18.39V6.688h45.348c2.576 0 4.667 2.277 4.667 5.066v20.009c1.987-.675 4.053-1.128 6.17-1.445v-18.56C91.738 5.28 86.874 0 80.902 0H31.15L0 28.118v87.917c0 6.48 4.859 11.759 10.832 11.759h70.07c5.974 0 10.837-5.27 10.837-11.759v-4.41c-2.117-.312-4.183-.765-6.17-1.435h-.004zM23.279 58.667h-7.96v6.688h7.96v-6.688zm-7.956 41.23h7.96v-6.691h-7.96v6.692zm7.956-23.96h-7.96v6.687h7.96v-6.688zm89.718-15.042l-4.896-4.07-12.447 17.613-11.19-9.305-3.762 5.311 16.091 13.38 16.204-22.929zM128 70.978c0-18.632-13.97-33.782-31.147-33.782-17.168 0-31.135 15.155-31.135 33.782 0 18.628 13.97 33.783 31.135 33.783 17.172 0 31.143-15.15 31.143-33.783H128zm-6.17 0c0 14.933-11.203 27.1-24.981 27.1-13.77 0-24.987-12.158-24.987-27.1 0-14.941 11.195-27.099 24.987-27.099 13.778 0 24.982 12.158 24.982 27.1z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M31.652 93.206h33.401c1.44 2.418 3.077 4.663 4.93 6.692h-38.33v-6.692zm0-10.586h28.914a44.8 44.8 0 0 1-1.264-6.688h-27.65v6.688zm0-17.27H59.39c.288-2.286.714-4.532 1.34-6.687H31.65v6.687h.003zm53.913 44.84v5.85c0 2.798-2.095 5.075-4.667 5.075h-70.07c-2.576 0-4.663-2.277-4.663-5.075V31.26l23.22-20.96v22.25H17.16v6.688h18.39V6.688h45.348c2.576 0 4.667 2.277 4.667 5.066v20.009c1.987-.675 4.053-1.128 6.17-1.445v-18.56C91.738 5.28 86.874 0 80.902 0H31.15L0 28.118v87.917c0 6.48 4.859 11.759 10.832 11.759h70.07c5.974 0 10.837-5.27 10.837-11.759v-4.41c-2.117-.312-4.183-.765-6.17-1.435h-.004zM23.279 58.667h-7.96v6.688h7.96v-6.688zm-7.956 41.23h7.96v-6.691h-7.96v6.692zm7.956-23.96h-7.96v6.687h7.96v-6.688zm89.718-15.042l-4.896-4.07-12.447 17.613-11.19-9.305-3.762 5.311 16.091 13.38 16.204-22.929zM128 70.978c0-18.632-13.97-33.782-31.147-33.782-17.168 0-31.135 15.155-31.135 33.782 0 18.628 13.97 33.783 31.135 33.783 17.172 0 31.143-15.15 31.143-33.783H128zm-6.17 0c0 14.933-11.203 27.1-24.981 27.1-13.77 0-24.987-12.158-24.987-27.1 0-14.941 11.195-27.099 24.987-27.099 13.778 0 24.982 12.158 24.982 27.1z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M70.66 4.328l14.01 29.693c1.088 2.29 3.177 3.882 5.603 4.25l31.347 4.76c6.087.926 8.528 8.756 4.117 13.247L103.05 79.395c-1.75 1.78-2.544 4.352-2.132 6.867l5.352 32.641c1.043 6.337-5.33 11.182-10.778 8.19l-28.039-15.409a7.13 7.13 0 0 0-6.91 0l-28.039 15.41c-5.448 2.99-11.821-1.854-10.777-8.19l5.352-32.642c.415-2.515-.387-5.088-2.136-6.867L2.264 56.278C-2.146 51.787.286 43.957 6.38 43.031l31.343-4.76c2.419-.368 4.51-1.96 5.595-4.25L57.334 4.328c2.728-5.77 10.605-5.77 13.325 0z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M70.66 4.328l14.01 29.693c1.088 2.29 3.177 3.882 5.603 4.25l31.347 4.76c6.087.926 8.528 8.756 4.117 13.247L103.05 79.395c-1.75 1.78-2.544 4.352-2.132 6.867l5.352 32.641c1.043 6.337-5.33 11.182-10.778 8.19l-28.039-15.409a7.13 7.13 0 0 0-6.91 0l-28.039 15.41c-5.448 2.99-11.821-1.854-10.777-8.19l5.352-32.642c.415-2.515-.387-5.088-2.136-6.867L2.264 56.278C-2.146 51.787.286 43.957 6.38 43.031l31.343-4.76c2.419-.368 4.51-1.96 5.595-4.25L57.334 4.328c2.728-5.77 10.605-5.77 13.325 0z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M78.921.052H49.08c-1.865 0-3.198 1.599-3.198 3.464v6.661c0 1.865 1.6 3.464 3.198 3.464h29.84c1.865 0 3.198-1.599 3.198-3.464V3.516C82.385 1.65 80.786.052 78.92.052zm45.563 0H94.642c-1.865 0-3.464 1.599-3.464 3.464v6.661c0 1.865 1.599 3.464 3.464 3.464h29.842c1.865-.266 3.464-1.599 3.464-3.464V3.516c0-1.865-1.599-3.464-3.464-3.464zm0 22.382H40.02c-1.866 0-3.464-1.599-3.464-3.464V3.516c0-1.865-1.599-3.464-3.464-3.464H3.516C1.65.052.052 1.651.052 3.516V124.75c0 1.598 1.599 3.197 3.464 3.197h120.968c1.865 0 3.464-1.599 3.464-3.464V25.898c0-1.865-1.599-3.464-3.464-3.464z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M78.921.052H49.08c-1.865 0-3.198 1.599-3.198 3.464v6.661c0 1.865 1.6 3.464 3.198 3.464h29.84c1.865 0 3.198-1.599 3.198-3.464V3.516C82.385 1.65 80.786.052 78.92.052zm45.563 0H94.642c-1.865 0-3.464 1.599-3.464 3.464v6.661c0 1.865 1.599 3.464 3.464 3.464h29.842c1.865-.266 3.464-1.599 3.464-3.464V3.516c0-1.865-1.599-3.464-3.464-3.464zm0 22.382H40.02c-1.866 0-3.464-1.599-3.464-3.464V3.516c0-1.865-1.599-3.464-3.464-3.464H3.516C1.65.052.052 1.651.052 3.516V124.75c0 1.598 1.599 3.197 3.464 3.197h120.968c1.865 0 3.464-1.599 3.464-3.464V25.898c0-1.865-1.599-3.464-3.464-3.464z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M125.5 36.984L95.336 2.83C93.735 1.018 91.565 0 89.3 0c-2.263 0-4.433 1.018-6.033 2.83l-3.786 4.286c-1.6 1.812-3.77 2.83-6.032 2.831H54.553c-2.263 0-4.434-1.018-6.033-2.83L44.734 2.83C43.134 1.018 40.964 0 38.701 0c-2.263 0-4.434 1.018-6.034 2.83L2.5 36.984C.9 38.796 0 41.254 0 43.815c0 2.562.899 5.02 2.5 6.831L14.565 64.31c2.178 2.468 5.367 3.403 8.33 2.444 1.35-.435 2.709.592 2.709 2.18v49.407c0 5.313 3.84 9.66 8.532 9.66h59.726c4.693 0 8.532-4.347 8.532-9.66V68.934c0-1.59 1.36-2.616 2.71-2.181 2.962.96 6.15.024 8.329-2.444L125.5 50.646c1.6-1.811 2.499-4.269 2.499-6.83 0-2.563-.899-5.02-2.5-6.832z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M125.5 36.984L95.336 2.83C93.735 1.018 91.565 0 89.3 0c-2.263 0-4.433 1.018-6.033 2.83l-3.786 4.286c-1.6 1.812-3.77 2.83-6.032 2.831H54.553c-2.263 0-4.434-1.018-6.033-2.83L44.734 2.83C43.134 1.018 40.964 0 38.701 0c-2.263 0-4.434 1.018-6.034 2.83L2.5 36.984C.9 38.796 0 41.254 0 43.815c0 2.562.899 5.02 2.5 6.831L14.565 64.31c2.178 2.468 5.367 3.403 8.33 2.444 1.35-.435 2.709.592 2.709 2.18v49.407c0 5.313 3.84 9.66 8.532 9.66h59.726c4.693 0 8.532-4.347 8.532-9.66V68.934c0-1.59 1.36-2.616 2.71-2.181 2.962.96 6.15.024 8.329-2.444L125.5 50.646c1.6-1.811 2.499-4.269 2.499-6.83 0-2.563-.899-5.02-2.5-6.832z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M44.8 0h79.543C126.78 0 128 1.422 128 4.267v23.466c0 2.845-1.219 4.267-3.657 4.267H44.8c-2.438 0-3.657-1.422-3.657-4.267V4.267C41.143 1.422 42.362 0 44.8 0zm22.857 48h56.686c2.438 0 3.657 1.422 3.657 4.267v23.466c0 2.845-1.219 4.267-3.657 4.267H67.657C65.22 80 64 78.578 64 75.733V52.267C64 49.422 65.219 48 67.657 48zm0 48h56.686c2.438 0 3.657 1.422 3.657 4.267v23.466c0 2.845-1.219 4.267-3.657 4.267H67.657C65.22 128 64 126.578 64 123.733v-23.466C64 97.422 65.219 96 67.657 96zM50.286 68.267c2.02 0 3.657-1.91 3.657-4.267 0-2.356-1.638-4.267-3.657-4.267H17.37V32h6.4c2.02 0 3.658-1.91 3.658-4.267V4.267C27.429 1.91 25.79 0 23.77 0H3.657C1.637 0 0 1.91 0 4.267v23.466C0 30.09 1.637 32 3.657 32h6.4v80c0 2.356 1.638 4.267 3.657 4.267h36.572c2.02 0 3.657-1.91 3.657-4.267 0-2.356-1.638-4.267-3.657-4.267H17.37V68.267h32.915z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M44.8 0h79.543C126.78 0 128 1.422 128 4.267v23.466c0 2.845-1.219 4.267-3.657 4.267H44.8c-2.438 0-3.657-1.422-3.657-4.267V4.267C41.143 1.422 42.362 0 44.8 0zm22.857 48h56.686c2.438 0 3.657 1.422 3.657 4.267v23.466c0 2.845-1.219 4.267-3.657 4.267H67.657C65.22 80 64 78.578 64 75.733V52.267C64 49.422 65.219 48 67.657 48zm0 48h56.686c2.438 0 3.657 1.422 3.657 4.267v23.466c0 2.845-1.219 4.267-3.657 4.267H67.657C65.22 128 64 126.578 64 123.733v-23.466C64 97.422 65.219 96 67.657 96zM50.286 68.267c2.02 0 3.657-1.91 3.657-4.267 0-2.356-1.638-4.267-3.657-4.267H17.37V32h6.4c2.02 0 3.658-1.91 3.658-4.267V4.267C27.429 1.91 25.79 0 23.77 0H3.657C1.637 0 0 1.91 0 4.267v23.466C0 30.09 1.637 32 3.657 32h6.4v80c0 2.356 1.638 4.267 3.657 4.267h36.572c2.02 0 3.657-1.91 3.657-4.267 0-2.356-1.638-4.267-3.657-4.267H17.37V68.267h32.915z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M126.713 90.023c.858.985 1.287 2.134 1.287 3.447v29.553c0 1.423-.429 2.6-1.287 3.53-.858.93-1.907 1.395-3.146 1.395H97.824c-1.145 0-2.146-.465-3.004-1.395-.858-.93-1.287-2.107-1.287-3.53V93.47c0-.875.19-1.696.572-2.462.382-.766.906-1.368 1.573-1.806a3.84 3.84 0 0 1 2.146-.657h9.725V69.007a3.84 3.84 0 0 0-.43-1.806 3.569 3.569 0 0 0-1.143-1.313 2.714 2.714 0 0 0-1.573-.492h-36.47v23.149h9.725c1.144 0 2.145.492 3.004 1.478.858.985 1.287 2.134 1.287 3.447v29.553c0 .876-.191 1.696-.573 2.463-.38.766-.905 1.368-1.573 1.806a3.84 3.84 0 0 1-2.145.656H51.915a3.84 3.84 0 0 1-2.145-.656c-.668-.438-1.216-1.04-1.645-1.806a4.96 4.96 0 0 1-.644-2.463V93.47c0-1.313.43-2.462 1.288-3.447.858-.986 1.907-1.478 3.146-1.478h9.582v-23.15h-37.9c-.953 0-1.74.356-2.359 1.068-.62.711-.93 1.56-.93 2.544v19.538h9.726c1.239 0 2.264.492 3.074 1.478.81.985 1.216 2.134 1.216 3.447v29.553c0 1.423-.405 2.6-1.216 3.53-.81.93-1.835 1.395-3.074 1.395H4.29c-.476 0-.93-.082-1.358-.246a4.1 4.1 0 0 1-1.144-.657 4.658 4.658 0 0 1-.93-1.067 5.186 5.186 0 0 1-.643-1.395 5.566 5.566 0 0 1-.215-1.56V93.47c0-.437.048-.875.143-1.313a3.95 3.95 0 0 1 .429-1.15c.19-.328.429-.656.715-.984.286-.329.572-.602.858-.821.286-.22.62-.383 1.001-.493.382-.11.763-.164 1.144-.164h9.726V61.619c0-.985.31-1.833.93-2.544.619-.712 1.358-1.068 2.216-1.068h44.335V39.62h-9.582c-1.24 0-2.288-.492-3.146-1.477a5.09 5.09 0 0 1-1.287-3.448V5.14c0-1.423.429-2.627 1.287-3.612.858-.985 1.907-1.477 3.146-1.477h25.743c.763 0 1.478.246 2.145.739a5.17 5.17 0 0 1 1.573 1.888c.382.766.573 1.587.573 2.462v29.553c0 1.313-.43 2.463-1.287 3.448-.859.985-1.86 1.477-3.004 1.477h-9.725v18.389h42.762c.954 0 1.74.355 2.36 1.067.62.711.93 1.56.93 2.545v26.925h9.582c1.239 0 2.288.492 3.146 1.478z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M126.713 90.023c.858.985 1.287 2.134 1.287 3.447v29.553c0 1.423-.429 2.6-1.287 3.53-.858.93-1.907 1.395-3.146 1.395H97.824c-1.145 0-2.146-.465-3.004-1.395-.858-.93-1.287-2.107-1.287-3.53V93.47c0-.875.19-1.696.572-2.462.382-.766.906-1.368 1.573-1.806a3.84 3.84 0 0 1 2.146-.657h9.725V69.007a3.84 3.84 0 0 0-.43-1.806 3.569 3.569 0 0 0-1.143-1.313 2.714 2.714 0 0 0-1.573-.492h-36.47v23.149h9.725c1.144 0 2.145.492 3.004 1.478.858.985 1.287 2.134 1.287 3.447v29.553c0 .876-.191 1.696-.573 2.463-.38.766-.905 1.368-1.573 1.806a3.84 3.84 0 0 1-2.145.656H51.915a3.84 3.84 0 0 1-2.145-.656c-.668-.438-1.216-1.04-1.645-1.806a4.96 4.96 0 0 1-.644-2.463V93.47c0-1.313.43-2.462 1.288-3.447.858-.986 1.907-1.478 3.146-1.478h9.582v-23.15h-37.9c-.953 0-1.74.356-2.359 1.068-.62.711-.93 1.56-.93 2.544v19.538h9.726c1.239 0 2.264.492 3.074 1.478.81.985 1.216 2.134 1.216 3.447v29.553c0 1.423-.405 2.6-1.216 3.53-.81.93-1.835 1.395-3.074 1.395H4.29c-.476 0-.93-.082-1.358-.246a4.1 4.1 0 0 1-1.144-.657 4.658 4.658 0 0 1-.93-1.067 5.186 5.186 0 0 1-.643-1.395 5.566 5.566 0 0 1-.215-1.56V93.47c0-.437.048-.875.143-1.313a3.95 3.95 0 0 1 .429-1.15c.19-.328.429-.656.715-.984.286-.329.572-.602.858-.821.286-.22.62-.383 1.001-.493.382-.11.763-.164 1.144-.164h9.726V61.619c0-.985.31-1.833.93-2.544.619-.712 1.358-1.068 2.216-1.068h44.335V39.62h-9.582c-1.24 0-2.288-.492-3.146-1.477a5.09 5.09 0 0 1-1.287-3.448V5.14c0-1.423.429-2.627 1.287-3.612.858-.985 1.907-1.477 3.146-1.477h25.743c.763 0 1.478.246 2.145.739a5.17 5.17 0 0 1 1.573 1.888c.382.766.573 1.587.573 2.462v29.553c0 1.313-.43 2.463-1.287 3.448-.859.985-1.86 1.477-3.004 1.477h-9.725v18.389h42.762c.954 0 1.74.355 2.36 1.067.62.711.93 1.56.93 2.545v26.925h9.582c1.239 0 2.288.492 3.146 1.478z"/></svg> |
1 | <svg width="130" height="130" xmlns="http://www.w3.org/2000/svg"><path d="M63.444 64.996c20.633 0 37.359-14.308 37.359-31.953 0-17.649-16.726-31.952-37.359-31.952-20.631 0-37.36 14.303-37.358 31.952 0 17.645 16.727 31.953 37.359 31.953zM80.57 75.65H49.434c-26.652 0-48.26 18.477-48.26 41.27v2.664c0 9.316 21.608 9.325 48.26 9.325H80.57c26.649 0 48.256-.344 48.256-9.325v-2.663c0-22.794-21.605-41.271-48.256-41.271z" stroke="#979797"/></svg> | 1 | <svg width="130" height="130" xmlns="http://www.w3.org/2000/svg"><path d="M63.444 64.996c20.633 0 37.359-14.308 37.359-31.953 0-17.649-16.726-31.952-37.359-31.952-20.631 0-37.36 14.303-37.358 31.952 0 17.645 16.727 31.953 37.359 31.953zM80.57 75.65H49.434c-26.652 0-48.26 18.477-48.26 41.27v2.664c0 9.316 21.608 9.325 48.26 9.325H80.57c26.649 0 48.256-.344 48.256-9.325v-2.663c0-22.794-21.605-41.271-48.256-41.271z" stroke="#979797"/></svg> |
1 | <svg width="128" height="110" xmlns="http://www.w3.org/2000/svg"><path d="M86.635 33.334c1.467 0 2.917.113 4.358.283C87.078 14.392 67.58.111 45.321.111 20.44.111.055 17.987.055 40.687c0 13.104 6.781 23.863 18.115 32.209l-4.527 14.352 15.82-8.364c5.666 1.182 10.207 2.395 15.858 2.395 1.42 0 2.829-.073 4.227-.189-.886-3.19-1.398-6.53-1.398-9.996 0-20.845 16.98-37.76 38.485-37.76zm-24.34-12.936c3.407 0 5.665 2.363 5.665 5.954 0 3.576-2.258 5.97-5.666 5.97-3.392 0-6.795-2.395-6.795-5.97 0-3.591 3.403-5.954 6.795-5.954zM30.616 32.323c-3.393 0-6.818-2.395-6.818-5.971 0-3.591 3.425-5.954 6.818-5.954 3.392 0 5.65 2.363 5.65 5.954 0 3.576-2.258 5.97-5.65 5.97z"/><path d="M127.945 70.52c0-19.075-18.108-34.623-38.448-34.623-21.537 0-38.5 15.548-38.5 34.623 0 19.108 16.963 34.622 38.5 34.622 4.508 0 9.058-1.2 13.584-2.395l12.414 7.167-3.404-11.923c9.087-7.184 15.854-16.712 15.854-27.471zm-50.928-5.97c-2.254 0-4.53-2.362-4.53-4.773 0-2.378 2.276-4.771 4.53-4.771 3.422 0 5.665 2.393 5.665 4.771 0 2.41-2.243 4.773-5.665 4.773zm24.897 0c-2.24 0-4.498-2.362-4.498-4.773 0-2.378 2.258-4.771 4.498-4.771 3.392 0 5.665 2.393 5.665 4.771 0 2.41-2.273 4.773-5.665 4.773z"/></svg> | 1 | <svg width="128" height="110" xmlns="http://www.w3.org/2000/svg"><path d="M86.635 33.334c1.467 0 2.917.113 4.358.283C87.078 14.392 67.58.111 45.321.111 20.44.111.055 17.987.055 40.687c0 13.104 6.781 23.863 18.115 32.209l-4.527 14.352 15.82-8.364c5.666 1.182 10.207 2.395 15.858 2.395 1.42 0 2.829-.073 4.227-.189-.886-3.19-1.398-6.53-1.398-9.996 0-20.845 16.98-37.76 38.485-37.76zm-24.34-12.936c3.407 0 5.665 2.363 5.665 5.954 0 3.576-2.258 5.97-5.666 5.97-3.392 0-6.795-2.395-6.795-5.97 0-3.591 3.403-5.954 6.795-5.954zM30.616 32.323c-3.393 0-6.818-2.395-6.818-5.971 0-3.591 3.425-5.954 6.818-5.954 3.392 0 5.65 2.363 5.65 5.954 0 3.576-2.258 5.97-5.65 5.97z"/><path d="M127.945 70.52c0-19.075-18.108-34.623-38.448-34.623-21.537 0-38.5 15.548-38.5 34.623 0 19.108 16.963 34.622 38.5 34.622 4.508 0 9.058-1.2 13.584-2.395l12.414 7.167-3.404-11.923c9.087-7.184 15.854-16.712 15.854-27.471zm-50.928-5.97c-2.254 0-4.53-2.362-4.53-4.773 0-2.378 2.276-4.771 4.53-4.771 3.422 0 5.665 2.393 5.665 4.771 0 2.41-2.243 4.773-5.665 4.773zm24.897 0c-2.24 0-4.498-2.362-4.498-4.773 0-2.378 2.258-4.771 4.498-4.771 3.392 0 5.665 2.393 5.665 4.771 0 2.41-2.273 4.773-5.665 4.773z"/></svg> |
1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M78.527 116.793c.178.008.348.024.527.024h40.233c4.711-.005 8.53-3.677 8.534-8.21V18.895c-.004-4.532-3.823-8.204-8.534-8.209H79.054c-.179 0-.353.016-.527.024V0L0 10.082v107.406l78.527 10.342v-11.037zm0-101.362c.174-.024.348-.052.527-.052h40.233c2.018 0 3.659 1.578 3.659 3.52v89.713c-.003 1.942-1.64 3.517-3.659 3.519H79.054c-.179 0-.353-.028-.527-.052V15.431zM30.262 75.757l-18.721-.46V72.37l11.3-16.673v-.148l-10.266.164v-4.51l17.504-.44v3.264L18.696 70.76v.144l11.566.176v4.678zm9.419.231l-5.823-.144V50.671l5.823-.144v25.461zm22.255-11.632c-2.168 1.922-5.353 2.76-9.02 2.736-.702.004-1.402-.04-2.097-.131v9.303l-5.997-.148V50.743c1.852-.352 4.473-.647 8.218-.743 3.838-.096 6.608.539 8.48 1.913 1.807 1.306 3.032 3.5 3.032 6.112s-.926 4.833-2.612 6.331h-.004zM53.36 54.45c-.856-.01-1.71.083-2.541.275v7.682c.523.116 1.167.152 2.06.152 3.301-.004 5.36-1.614 5.36-4.314 0-2.425-1.772-3.843-4.875-3.791l-.004-.004zm39.847-37.066h9.564v3.795h-9.564v-3.795zm-9.568 5.68h9.564v3.8h-9.564v-3.8zm9.568 6.216h9.564v3.799h-9.564V29.28zm0 12h9.564v3.794h-9.564V41.28zm-9.568-6.096h9.564v3.795h-9.564v-3.795zm9.472 47.064c2.512 0 4.921-.96 6.697-2.67 1.776-1.708 2.773-4.026 2.772-6.442l-1.748-15.263c0-5.033-2.492-9.112-7.725-9.112-5.232 0-7.72 4.079-7.72 9.112l-1.752 15.263c-.001 2.417.996 4.735 2.773 6.444 1.777 1.71 4.187 2.669 6.7 2.668h.003zm-3.135-16.75h6.27v12.743h-6.27V65.5z"/></svg> | 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M78.527 116.793c.178.008.348.024.527.024h40.233c4.711-.005 8.53-3.677 8.534-8.21V18.895c-.004-4.532-3.823-8.204-8.534-8.209H79.054c-.179 0-.353.016-.527.024V0L0 10.082v107.406l78.527 10.342v-11.037zm0-101.362c.174-.024.348-.052.527-.052h40.233c2.018 0 3.659 1.578 3.659 3.52v89.713c-.003 1.942-1.64 3.517-3.659 3.519H79.054c-.179 0-.353-.028-.527-.052V15.431zM30.262 75.757l-18.721-.46V72.37l11.3-16.673v-.148l-10.266.164v-4.51l17.504-.44v3.264L18.696 70.76v.144l11.566.176v4.678zm9.419.231l-5.823-.144V50.671l5.823-.144v25.461zm22.255-11.632c-2.168 1.922-5.353 2.76-9.02 2.736-.702.004-1.402-.04-2.097-.131v9.303l-5.997-.148V50.743c1.852-.352 4.473-.647 8.218-.743 3.838-.096 6.608.539 8.48 1.913 1.807 1.306 3.032 3.5 3.032 6.112s-.926 4.833-2.612 6.331h-.004zM53.36 54.45c-.856-.01-1.71.083-2.541.275v7.682c.523.116 1.167.152 2.06.152 3.301-.004 5.36-1.614 5.36-4.314 0-2.425-1.772-3.843-4.875-3.791l-.004-.004zm39.847-37.066h9.564v3.795h-9.564v-3.795zm-9.568 5.68h9.564v3.8h-9.564v-3.8zm9.568 6.216h9.564v3.799h-9.564V29.28zm0 12h9.564v3.794h-9.564V41.28zm-9.568-6.096h9.564v3.795h-9.564v-3.795zm9.472 47.064c2.512 0 4.921-.96 6.697-2.67 1.776-1.708 2.773-4.026 2.772-6.442l-1.748-15.263c0-5.033-2.492-9.112-7.725-9.112-5.232 0-7.72 4.079-7.72 9.112l-1.752 15.263c-.001 2.417.996 4.735 2.773 6.444 1.777 1.71 4.187 2.669 6.7 2.668h.003zm-3.135-16.75h6.27v12.743h-6.27V65.5z"/></svg> |
1 | # replace default config | 1 | # replace default config |
2 | 2 | ||
3 | # multipass: true | 3 | # multipass: true |
4 | # full: true | 4 | # full: true |
5 | 5 | ||
6 | plugins: | 6 | plugins: |
7 | 7 | ||
8 | # - name | 8 | # - name |
9 | # | 9 | # |
10 | # or: | 10 | # or: |
11 | # - name: false | 11 | # - name: false |
12 | # - name: true | 12 | # - name: true |
13 | # | 13 | # |
14 | # or: | 14 | # or: |
15 | # - name: | 15 | # - name: |
16 | # param1: 1 | 16 | # param1: 1 |
17 | # param2: 2 | 17 | # param2: 2 |
18 | 18 | ||
19 | - removeAttrs: | 19 | - removeAttrs: |
20 | attrs: | 20 | attrs: |
21 | - 'fill' | 21 | - 'fill' |
22 | - 'fill-rule' | 22 | - 'fill-rule' |
23 | 23 |
src/lang/en.js
File was created | 1 | export default { | |
2 | route: { | ||
3 | dashboard: 'Dashboard', | ||
4 | documentation: 'Documentation', | ||
5 | guide: 'Guide', | ||
6 | permission: 'Permission', | ||
7 | pagePermission: 'Page Permission', | ||
8 | rolePermission: 'Role Permission', | ||
9 | directivePermission: 'Directive Permission', | ||
10 | icons: 'Icons', | ||
11 | components: 'Components', | ||
12 | tinymce: 'Tinymce', | ||
13 | markdown: 'Markdown', | ||
14 | jsonEditor: 'JSON Editor', | ||
15 | dndList: 'Dnd List', | ||
16 | splitPane: 'SplitPane', | ||
17 | avatarUpload: 'Avatar Upload', | ||
18 | dropzone: 'Dropzone', | ||
19 | sticky: 'Sticky', | ||
20 | countTo: 'Count To', | ||
21 | componentMixin: 'Mixin', | ||
22 | backToTop: 'Back To Top', | ||
23 | dragDialog: 'Drag Dialog', | ||
24 | dragSelect: 'Drag Select', | ||
25 | dragKanban: 'Drag Kanban', | ||
26 | charts: 'Charts', | ||
27 | keyboardChart: 'Keyboard Chart', | ||
28 | lineChart: 'Line Chart', | ||
29 | mixChart: 'Mix Chart', | ||
30 | example: 'Example', | ||
31 | nested: 'Nested Routes', | ||
32 | menu1: 'Menu 1', | ||
33 | 'menu1-1': 'Menu 1-1', | ||
34 | 'menu1-2': 'Menu 1-2', | ||
35 | 'menu1-2-1': 'Menu 1-2-1', | ||
36 | 'menu1-2-2': 'Menu 1-2-2', | ||
37 | 'menu1-3': 'Menu 1-3', | ||
38 | menu2: 'Menu 2', | ||
39 | Table: 'Table', | ||
40 | dynamicTable: 'Dynamic Table', | ||
41 | dragTable: 'Drag Table', | ||
42 | inlineEditTable: 'Inline Edit', | ||
43 | complexTable: 'Complex Table', | ||
44 | tab: 'Tab', | ||
45 | form: 'Form', | ||
46 | createArticle: 'Create Article', | ||
47 | editArticle: 'Edit Article', | ||
48 | articleList: 'Article List', | ||
49 | errorPages: 'Error Pages', | ||
50 | page401: '401', | ||
51 | page404: '404', | ||
52 | errorLog: 'Error Log', | ||
53 | excel: 'Excel', | ||
54 | exportExcel: 'Export Excel', | ||
55 | selectExcel: 'Export Selected', | ||
56 | mergeHeader: 'Merge Header', | ||
57 | uploadExcel: 'Upload Excel', | ||
58 | zip: 'Zip', | ||
59 | pdf: 'PDF', | ||
60 | exportZip: 'Export Zip', | ||
61 | theme: 'Theme', | ||
62 | clipboardDemo: 'Clipboard', | ||
63 | i18n: 'I18n', | ||
64 | externalLink: 'External Link', | ||
65 | profile: 'Profile' | ||
66 | }, | ||
67 | navbar: { | ||
68 | dashboard: 'Dashboard', | ||
69 | github: 'Github', | ||
70 | logOut: 'Log Out', | ||
71 | profile: 'Profile', | ||
72 | theme: 'Theme', | ||
73 | size: 'Global Size' | ||
74 | }, | ||
75 | login: { | ||
76 | title: 'Login Form', | ||
77 | logIn: 'Login', | ||
78 | username: 'Username', | ||
79 | password: 'Password', | ||
80 | any: 'any', | ||
81 | thirdparty: 'Or connect with', | ||
82 | thirdpartyTips: 'Can not be simulated on local, so please combine you own business simulation! ! !' | ||
83 | }, | ||
84 | documentation: { | ||
85 | documentation: 'Documentation', | ||
86 | github: 'Github Repository' | ||
87 | }, | ||
88 | permission: { | ||
89 | addRole: 'New Role', | ||
90 | editPermission: 'Edit', | ||
91 | roles: 'Your roles', | ||
92 | switchRoles: 'Switch roles', | ||
93 | 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.', | ||
94 | delete: 'Delete', | ||
95 | confirm: 'Confirm', | ||
96 | cancel: 'Cancel' | ||
97 | }, | ||
98 | guide: { | ||
99 | 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 ', | ||
100 | button: 'Show Guide' | ||
101 | }, | ||
102 | components: { | ||
103 | documentation: 'Documentation', | ||
104 | 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.', | ||
105 | 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.', | ||
106 | stickyTips: 'when the page is scrolled to the preset position will be sticky on the top.', | ||
107 | backToTopTips1: 'When the page is scrolled to the specified position, the Back to Top button appears in the lower right corner', | ||
108 | 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', | ||
109 | 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.' | ||
110 | }, | ||
111 | table: { | ||
112 | dynamicTips1: 'Fixed header, sorted by header order', | ||
113 | dynamicTips2: 'Not fixed header, sorted by click order', | ||
114 | dragTips1: 'The default order', | ||
115 | dragTips2: 'The after dragging order', | ||
116 | title: 'Title', | ||
117 | importance: 'Imp', | ||
118 | type: 'Type', | ||
119 | remark: 'Remark', | ||
120 | search: 'Search', | ||
121 | add: 'Add', | ||
122 | export: 'Export', | ||
123 | reviewer: 'reviewer', | ||
124 | id: 'ID', | ||
125 | date: 'Date', | ||
126 | author: 'Author', | ||
127 | readings: 'Readings', | ||
128 | status: 'Status', | ||
129 | actions: 'Actions', | ||
130 | edit: 'Edit', | ||
131 | publish: 'Publish', | ||
132 | draft: 'Draft', | ||
133 | delete: 'Delete', | ||
134 | cancel: 'Cancel', | ||
135 | confirm: 'Confirm' | ||
136 | }, | ||
137 | example: { | ||
138 | 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' | ||
139 | }, | ||
140 | errorLog: { | ||
141 | tips: 'Please click the bug icon in the upper right corner', | ||
142 | 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.', | ||
143 | documentation: 'Document introduction' | ||
144 | }, | ||
145 | excel: { | ||
146 | export: 'Export', | ||
147 | selectedExport: 'Export Selected Items', | ||
148 | placeholder: 'Please enter the file name (default excel-list)' | ||
149 | }, | ||
150 | zip: { | ||
151 | export: 'Export', | ||
152 | placeholder: 'Please enter the file name (default file)' | ||
153 | }, | ||
154 | pdf: { | ||
155 | tips: 'Here we use window.print() to implement the feature of downloading PDF.' | ||
156 | }, | ||
157 | theme: { | ||
158 | change: 'Change Theme', | ||
159 | documentation: 'Theme documentation', | ||
160 | 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.' | ||
161 | }, | ||
162 | tagsView: { | ||
163 | refresh: 'Refresh', | ||
164 | close: 'Close', | ||
165 | closeOthers: 'Close Others', | ||
166 | closeAll: 'Close All' | ||
167 | }, | ||
168 | settings: { | ||
169 | title: 'Page style setting', | ||
170 | theme: 'Theme Color', | ||
171 | tagsView: 'Open Tags-View', | ||
172 | fixedHeader: 'Fixed Header', | ||
173 | sidebarLogo: 'Sidebar Logo' | ||
174 | } | ||
175 | } | ||
176 |
src/lang/es.js
File was created | 1 | export default { | |
2 | route: { | ||
3 | dashboard: 'Panel de control', | ||
4 | documentation: 'Documentación', | ||
5 | guide: 'Guía', | ||
6 | permission: 'Permisos', | ||
7 | rolePermission: 'Permisos de rol', | ||
8 | pagePermission: 'Permisos de la página', | ||
9 | directivePermission: 'Permisos de la directiva', | ||
10 | icons: 'Iconos', | ||
11 | components: 'Componentes', | ||
12 | tinymce: 'Tinymce', | ||
13 | markdown: 'Markdown', | ||
14 | jsonEditor: 'Editor JSON', | ||
15 | dndList: 'Lista Dnd', | ||
16 | splitPane: 'Panel dividido', | ||
17 | avatarUpload: 'Subir avatar', | ||
18 | dropzone: 'Subir ficheros', | ||
19 | sticky: 'Sticky', | ||
20 | countTo: 'CountTo', | ||
21 | componentMixin: 'Mixin', | ||
22 | backToTop: 'Ir arriba', | ||
23 | dragDialog: 'Drag Dialog', | ||
24 | dragSelect: 'Drag Select', | ||
25 | dragKanban: 'Drag Kanban', | ||
26 | charts: 'Gráficos', | ||
27 | keyboardChart: 'Keyboard Chart', | ||
28 | lineChart: 'Gráfico de líneas', | ||
29 | mixChart: 'Mix Chart', | ||
30 | example: 'Ejemplo', | ||
31 | nested: 'Rutas anidadass', | ||
32 | menu1: 'Menu 1', | ||
33 | 'menu1-1': 'Menu 1-1', | ||
34 | 'menu1-2': 'Menu 1-2', | ||
35 | 'menu1-2-1': 'Menu 1-2-1', | ||
36 | 'menu1-2-2': 'Menu 1-2-2', | ||
37 | 'menu1-3': 'Menu 1-3', | ||
38 | menu2: 'Menu 2', | ||
39 | Table: 'Tabla', | ||
40 | dynamicTable: 'Tabla dinámica', | ||
41 | dragTable: 'Arrastrar tabla', | ||
42 | inlineEditTable: 'Editor', | ||
43 | complexTable: 'Complex Table', | ||
44 | tab: 'Pestaña', | ||
45 | form: 'Formulario', | ||
46 | createArticle: 'Crear artículo', | ||
47 | editArticle: 'Editar artículo', | ||
48 | articleList: 'Listado de artículos', | ||
49 | errorPages: 'Páginas de error', | ||
50 | page401: '401', | ||
51 | page404: '404', | ||
52 | errorLog: 'Registro de errores', | ||
53 | excel: 'Excel', | ||
54 | exportExcel: 'Exportar a Excel', | ||
55 | selectExcel: 'Export seleccionado', | ||
56 | mergeHeader: 'Merge Header', | ||
57 | uploadExcel: 'Subir Excel', | ||
58 | zip: 'Zip', | ||
59 | pdf: 'PDF', | ||
60 | exportZip: 'Exportar a Zip', | ||
61 | theme: 'Tema', | ||
62 | clipboardDemo: 'Clipboard', | ||
63 | i18n: 'I18n', | ||
64 | externalLink: 'Enlace externo', | ||
65 | profile: 'Profile' | ||
66 | }, | ||
67 | navbar: { | ||
68 | logOut: 'Salir', | ||
69 | dashboard: 'Panel de control', | ||
70 | github: 'Github', | ||
71 | theme: 'Tema', | ||
72 | size: 'Tamaño global', | ||
73 | profile: 'Profile' | ||
74 | }, | ||
75 | login: { | ||
76 | title: 'Formulario de acceso', | ||
77 | logIn: 'Acceso', | ||
78 | username: 'Usuario', | ||
79 | password: 'Contraseña', | ||
80 | any: 'nada', | ||
81 | thirdparty: 'Conectar con', | ||
82 | thirdpartyTips: 'No se puede simular en local, así que combine su propia simulación de negocios. ! !' | ||
83 | }, | ||
84 | documentation: { | ||
85 | documentation: 'Documentación', | ||
86 | github: 'Repositorio Github' | ||
87 | }, | ||
88 | permission: { | ||
89 | addRole: 'Nuevo rol', | ||
90 | editPermission: 'Permiso de edición', | ||
91 | roles: 'Tus permisos', | ||
92 | switchRoles: 'Cambiar permisos', | ||
93 | 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.', | ||
94 | delete: 'Borrar', | ||
95 | confirm: 'Confirmar', | ||
96 | cancel: 'Cancelar' | ||
97 | }, | ||
98 | guide: { | ||
99 | 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 ', | ||
100 | button: 'Ver guía' | ||
101 | }, | ||
102 | components: { | ||
103 | documentation: 'Documentación', | ||
104 | 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.', | ||
105 | 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.', | ||
106 | stickyTips: 'when the page is scrolled to the preset position will be sticky on the top.', | ||
107 | backToTopTips1: 'When the page is scrolled to the specified position, the Back to Top button appears in the lower right corner', | ||
108 | 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', | ||
109 | 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.' | ||
110 | }, | ||
111 | table: { | ||
112 | dynamicTips1: 'Fixed header, sorted by header order', | ||
113 | dynamicTips2: 'Not fixed header, sorted by click order', | ||
114 | dragTips1: 'Orden por defecto', | ||
115 | dragTips2: 'The after dragging order', | ||
116 | title: 'Título', | ||
117 | importance: 'Importancia', | ||
118 | type: 'Tipo', | ||
119 | remark: 'Remark', | ||
120 | search: 'Buscar', | ||
121 | add: 'Añadir', | ||
122 | export: 'Exportar', | ||
123 | reviewer: 'reviewer', | ||
124 | id: 'ID', | ||
125 | date: 'Fecha', | ||
126 | author: 'Autor', | ||
127 | readings: 'Lector', | ||
128 | status: 'Estado', | ||
129 | actions: 'Acciones', | ||
130 | edit: 'Editar', | ||
131 | publish: 'Publicar', | ||
132 | draft: 'Draft', | ||
133 | delete: 'Eliminar', | ||
134 | cancel: 'Cancelar', | ||
135 | confirm: 'Confirmar' | ||
136 | }, | ||
137 | example: { | ||
138 | 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' | ||
139 | }, | ||
140 | errorLog: { | ||
141 | tips: 'Please click the bug icon in the upper right corner', | ||
142 | 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.', | ||
143 | documentation: 'Documento de introducción' | ||
144 | }, | ||
145 | excel: { | ||
146 | export: 'Exportar', | ||
147 | selectedExport: 'Exportar seleccionados', | ||
148 | placeholder: 'Por favor escribe un nombre de fichero' | ||
149 | }, | ||
150 | zip: { | ||
151 | export: 'Exportar', | ||
152 | placeholder: 'Por favor escribe un nombre de fichero' | ||
153 | }, | ||
154 | pdf: { | ||
155 | tips: 'Here we use window.print() to implement the feature of downloading pdf.' | ||
156 | }, | ||
157 | theme: { | ||
158 | change: 'Cambiar tema', | ||
159 | documentation: 'Documentación del tema', | ||
160 | 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.' | ||
161 | }, | ||
162 | tagsView: { | ||
163 | refresh: 'Actualizar', | ||
164 | close: 'Cerrar', | ||
165 | closeOthers: 'Cerrar otros', | ||
166 | closeAll: 'Cerrar todos' | ||
167 | }, | ||
168 | settings: { | ||
169 | title: 'Page style setting', | ||
170 | theme: 'Theme Color', | ||
171 | tagsView: 'Open Tags-View', | ||
172 | fixedHeader: 'Fixed Header', | ||
173 | sidebarLogo: 'Sidebar Logo' | ||
174 | } | ||
175 | } | ||
176 |
src/lang/index.js
File was created | 1 | import Vue from 'vue' | |
2 | import VueI18n from 'vue-i18n' | ||
3 | import Cookies from 'js-cookie' | ||
4 | import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang | ||
5 | import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang | ||
6 | import elementEsLocale from 'element-ui/lib/locale/lang/es'// element-ui lang | ||
7 | import elementJaLocale from 'element-ui/lib/locale/lang/ja'// element-ui lang | ||
8 | import enLocale from './en' | ||
9 | import zhLocale from './zh' | ||
10 | import esLocale from './es' | ||
11 | import jaLocale from './ja' | ||
12 | |||
13 | Vue.use(VueI18n) | ||
14 | |||
15 | const messages = { | ||
16 | en: { | ||
17 | ...enLocale, | ||
18 | ...elementEnLocale | ||
19 | }, | ||
20 | zh: { | ||
21 | ...zhLocale, | ||
22 | ...elementZhLocale | ||
23 | }, | ||
24 | es: { | ||
25 | ...esLocale, | ||
26 | ...elementEsLocale | ||
27 | }, | ||
28 | ja: { | ||
29 | ...jaLocale, | ||
30 | ...elementJaLocale | ||
31 | } | ||
32 | } | ||
33 | export function getLanguage() { | ||
34 | const chooseLanguage = Cookies.get('language') | ||
35 | if (chooseLanguage) return chooseLanguage | ||
36 | |||
37 | // if has not choose language | ||
38 | const language = (navigator.language || navigator.browserLanguage).toLowerCase() | ||
39 | const locales = Object.keys(messages) | ||
40 | for (const locale of locales) { | ||
41 | if (language.indexOf(locale) > -1) { | ||
42 | return locale | ||
43 | } | ||
44 | } | ||
45 | return 'en' | ||
46 | } | ||
47 | const i18n = new VueI18n({ | ||
48 | // set locale | ||
49 | // options: en | zh | es | ||
50 | locale: getLanguage(), | ||
51 | // set locale messages | ||
52 | messages | ||
53 | }) | ||
54 | |||
55 | export default i18n | ||
56 |
src/lang/ja.js
File was created | 1 | export default { | |
2 | route: { | ||
3 | dashboard: 'トップ', | ||
4 | documentation: 'ドキュメント', | ||
5 | guide: 'ガイド', | ||
6 | permission: '権限', | ||
7 | rolePermission: '権限ロール', | ||
8 | pagePermission: 'ページ権限', | ||
9 | directivePermission: 'ディレクティブ権限', | ||
10 | icons: 'アイコン', | ||
11 | components: 'コンポーネント', | ||
12 | tinymce: 'TinyMCE', | ||
13 | markdown: 'Markdown', | ||
14 | jsonEditor: 'JSON Editor', | ||
15 | dndList: 'Drag-And-Drop', | ||
16 | splitPane: 'パネル', | ||
17 | avatarUpload: 'アバターアップロード', | ||
18 | dropzone: 'Dropzone', | ||
19 | sticky: 'Sticky', | ||
20 | countTo: 'Count To', | ||
21 | componentMixin: 'コンポーネントMixin', | ||
22 | backToTop: 'BackToTop', | ||
23 | dragDialog: 'Drag Dialog', | ||
24 | dragSelect: 'Drag Select', | ||
25 | dragKanban: 'Drag 看板', | ||
26 | charts: 'チャート', | ||
27 | keyboardChart: 'Keyboardチャート', | ||
28 | lineChart: 'Lineチャート', | ||
29 | mixChart: 'Mixチャート', | ||
30 | example: 'Example', | ||
31 | nested: 'Nested Routes', | ||
32 | menu1: 'メニュー1', | ||
33 | 'menu1-1': 'メニュー 1-1', | ||
34 | 'menu1-2': 'メニュー 1-2', | ||
35 | 'menu1-2-1': 'メニュー 1-2-1', | ||
36 | 'menu1-2-2': 'メニュー 1-2-2', | ||
37 | 'menu1-3': 'メニュー 1-3', | ||
38 | menu2: 'メニュー 2', | ||
39 | Table: 'Table', | ||
40 | dynamicTable: '可変 Table', | ||
41 | dragTable: 'Drag Table', | ||
42 | inlineEditTable: 'Inline Edit Table', | ||
43 | complexTable: 'Complex Table', | ||
44 | tab: 'Tab', | ||
45 | form: 'フォーム', | ||
46 | createArticle: '投稿作成', | ||
47 | editArticle: '投稿編集', | ||
48 | articleList: '投稿リスト', | ||
49 | errorPages: 'エラーページ', | ||
50 | page401: '401', | ||
51 | page404: '404', | ||
52 | errorLog: 'エラーログ', | ||
53 | excel: 'Excel', | ||
54 | exportExcel: '一括エクスポート', | ||
55 | selectExcel: '複数選択エクスポート', | ||
56 | mergeHeader: 'ヘッダーマージ', | ||
57 | uploadExcel: 'アップロード', | ||
58 | zip: 'Zip', | ||
59 | pdf: 'PDF', | ||
60 | exportZip: 'Export Zip', | ||
61 | theme: 'テーマ変更', | ||
62 | clipboardDemo: 'Clipboard', | ||
63 | i18n: '多言語', | ||
64 | externalLink: '外部リンク', | ||
65 | profile: 'プロフィール' | ||
66 | }, | ||
67 | navbar: { | ||
68 | dashboard: 'トップ', | ||
69 | github: 'GitHub', | ||
70 | logOut: 'ログアウト', | ||
71 | profile: 'プロフィール', | ||
72 | theme: 'テーマ変更', | ||
73 | size: '画面サイズ' | ||
74 | }, | ||
75 | login: { | ||
76 | title: 'ユーザログイン', | ||
77 | logIn: 'ログイン', | ||
78 | username: 'ユーザ名', | ||
79 | password: 'パスワード', | ||
80 | any: 'password', | ||
81 | thirdparty: '外部IDでログイン', | ||
82 | thirdpartyTips: 'ローカル環境ではログインできません。実装が必要です。' | ||
83 | }, | ||
84 | documentation: { | ||
85 | documentation: 'ドキュメント', | ||
86 | github: 'Github Link' | ||
87 | }, | ||
88 | permission: { | ||
89 | addRole: 'ロール追加', | ||
90 | editPermission: 'ロール変更', | ||
91 | roles: 'ロール', | ||
92 | switchRoles: 'ロール切替', | ||
93 | tips: 'v-permissionは使えない時があります。例えば: Element-UI の el-tab、 el-table-column 及び他の dom。v-ifを使う必要があります。', | ||
94 | delete: '削除', | ||
95 | confirm: '確認', | ||
96 | cancel: 'キャンセル' | ||
97 | }, | ||
98 | guide: { | ||
99 | description: 'ガイドは各機能の説明です。', | ||
100 | button: 'ガイドを見る' | ||
101 | }, | ||
102 | components: { | ||
103 | documentation: 'ドキュメント', | ||
104 | tinymceTips: 'tinymceは管理画面に重要な機能ですが、その同時に落とし穴がありあす。tinymceを使う道のりが大変でした。Tinymceを使う時に各自のプロジェクト状況で判断が必要です。ドキュメントはこちら', | ||
105 | dropzoneTips: 'Third partyのパッケージを使わず、独自の実装しています。詳細は @/components/Dropzone', | ||
106 | stickyTips: 'ページの指定位置へスクロールした場合、表示されます。', | ||
107 | backToTopTips1: 'トップへスクロールが表示されます。', | ||
108 | backToTopTips2: 'ボタンのスタイルはカスタマイズできます。例えば、show/hide、height、position。 またはElementのel-tooltipを使って、ツールチップを実装できます。', | ||
109 | imageUploadTips: 'mockjsは使えないため、カスタマイズしています。公式の最新バージョンを使ってください。' | ||
110 | }, | ||
111 | table: { | ||
112 | dynamicTips1: '先頭は固定、最後に追加', | ||
113 | dynamicTips2: '戦後に追加せず、指定列に追加', | ||
114 | dragTips1: 'デフォルト順番', | ||
115 | dragTips2: 'Drag後の順番', | ||
116 | title: 'タイトル', | ||
117 | importance: '重要', | ||
118 | type: 'タイプ', | ||
119 | remark: '評価', | ||
120 | search: '検索', | ||
121 | add: '追加', | ||
122 | export: 'エクスポート', | ||
123 | reviewer: 'レビュアー', | ||
124 | id: '番号', | ||
125 | date: '日時', | ||
126 | author: '作成者', | ||
127 | readings: '閲覧数', | ||
128 | status: 'ステータス', | ||
129 | actions: '操作', | ||
130 | edit: '編集', | ||
131 | publish: '公開', | ||
132 | draft: '下書き', | ||
133 | delete: 'キャンセル', | ||
134 | cancel: 'キャンセル', | ||
135 | confirm: '確認' | ||
136 | }, | ||
137 | example: { | ||
138 | warning: '新規作成と編集画面は keep-alive を使えないです。keep-alive の include はrouteのキャッシュは使えないです。そのため、component name を使ってキャッシュさせるようにします。このようなキャッシュ機能を作りたい場合,localStorageを使う手があります。もしくは keep-alive の includeを使って、全ページキャッシュする方法はあります。' | ||
139 | }, | ||
140 | errorLog: { | ||
141 | tips: '右上のbugアイコンをクリックしてください。', | ||
142 | description: '管理画面はspaを使う場合が多い、ユーザ体現向上はできますが、想定外エラーが発生する場合があります。Vueはそのエラーハンドリング機能を提供し、エラーレポートができます。', | ||
143 | documentation: 'ドキュメント' | ||
144 | }, | ||
145 | excel: { | ||
146 | export: 'エクスポート', | ||
147 | selectedExport: 'エクスポート対象を選択してください。', | ||
148 | placeholder: 'ファイル名を入力してください。' | ||
149 | }, | ||
150 | zip: { | ||
151 | export: 'エクスポート', | ||
152 | placeholder: 'ファイル名を入力してください。' | ||
153 | }, | ||
154 | pdf: { | ||
155 | tips: 'window.print() を使ってPDFダウンロードしています。' | ||
156 | }, | ||
157 | theme: { | ||
158 | change: 'テーマ切替', | ||
159 | documentation: 'ドキュメント', | ||
160 | tips: 'Tips: テーマの切り替え方法はnavbarのtheme-pickと異なります、使い方はドキュメントを確認してください。' | ||
161 | }, | ||
162 | tagsView: { | ||
163 | refresh: '更新', | ||
164 | close: '閉じる', | ||
165 | closeOthers: 'その他閉じる', | ||
166 | closeAll: 'すべて閉じる' | ||
167 | }, | ||
168 | settings: { | ||
169 | title: 'システムテーマ', | ||
170 | theme: 'テーマ色', | ||
171 | tagsView: 'Tags-View 開く', | ||
172 | fixedHeader: 'Fixed Header', | ||
173 | sidebarLogo: 'Sidebar Logo' | ||
174 | } | ||
175 | } | ||
176 |
src/lang/zh.js
File was created | 1 | export default { | |
2 | route: { | ||
3 | dashboard: '首页', | ||
4 | documentation: '文档', | ||
5 | guide: '引导页', | ||
6 | permission: '权限测试页', | ||
7 | rolePermission: '角色权限', | ||
8 | pagePermission: '页面权限', | ||
9 | directivePermission: '指令权限', | ||
10 | icons: '图标', | ||
11 | components: '组件', | ||
12 | tinymce: '富文本编辑器', | ||
13 | markdown: 'Markdown', | ||
14 | jsonEditor: 'JSON 编辑器', | ||
15 | dndList: '列表拖拽', | ||
16 | splitPane: 'Splitpane', | ||
17 | avatarUpload: '头像上传', | ||
18 | dropzone: 'Dropzone', | ||
19 | sticky: 'Sticky', | ||
20 | countTo: 'Count To', | ||
21 | componentMixin: '小组件', | ||
22 | backToTop: '返回顶部', | ||
23 | dragDialog: '拖拽 Dialog', | ||
24 | dragSelect: '拖拽 Select', | ||
25 | dragKanban: '可拖拽看板', | ||
26 | charts: '图表', | ||
27 | keyboardChart: '键盘图表', | ||
28 | lineChart: '折线图', | ||
29 | mixChart: '混合图表', | ||
30 | example: '综合实例', | ||
31 | nested: '路由嵌套', | ||
32 | menu1: '菜单1', | ||
33 | 'menu1-1': '菜单 1-1', | ||
34 | 'menu1-2': '菜单 1-2', | ||
35 | 'menu1-2-1': '菜单 1-2-1', | ||
36 | 'menu1-2-2': '菜单 1-2-2', | ||
37 | 'menu1-3': '菜单 1-3', | ||
38 | menu2: '菜单 2', | ||
39 | Table: 'Table', | ||
40 | dynamicTable: '动态 Table', | ||
41 | dragTable: '拖拽 Table', | ||
42 | inlineEditTable: 'Table 内编辑', | ||
43 | complexTable: '综合 Table', | ||
44 | tab: 'Tab', | ||
45 | form: '表单', | ||
46 | createArticle: '创建文章', | ||
47 | editArticle: '编辑文章', | ||
48 | articleList: '文章列表', | ||
49 | errorPages: '错误页面', | ||
50 | page401: '401', | ||
51 | page404: '404', | ||
52 | errorLog: '错误日志', | ||
53 | excel: 'Excel', | ||
54 | exportExcel: '导出 Excel', | ||
55 | selectExcel: '导出 已选择项', | ||
56 | mergeHeader: '导出 多级表头', | ||
57 | uploadExcel: '上传 Excel', | ||
58 | zip: 'Zip', | ||
59 | pdf: 'PDF', | ||
60 | exportZip: 'Export Zip', | ||
61 | theme: '换肤', | ||
62 | clipboardDemo: 'Clipboard', | ||
63 | i18n: '国际化', | ||
64 | externalLink: '外链', | ||
65 | profile: '个人中心' | ||
66 | }, | ||
67 | navbar: { | ||
68 | dashboard: '首页', | ||
69 | github: '项目地址', | ||
70 | logOut: '退出登录', | ||
71 | profile: '个人中心', | ||
72 | theme: '换肤', | ||
73 | size: '布局大小' | ||
74 | }, | ||
75 | login: { | ||
76 | title: '系统登录', | ||
77 | logIn: '登录', | ||
78 | username: '账号', | ||
79 | password: '密码', | ||
80 | any: '随便填', | ||
81 | thirdparty: '第三方登录', | ||
82 | thirdpartyTips: '本地不能模拟,请结合自己业务进行模拟!!!' | ||
83 | }, | ||
84 | documentation: { | ||
85 | documentation: '文档', | ||
86 | github: 'Github 地址' | ||
87 | }, | ||
88 | permission: { | ||
89 | addRole: '新增角色', | ||
90 | editPermission: '编辑权限', | ||
91 | roles: '你的权限', | ||
92 | switchRoles: '切换权限', | ||
93 | tips: '在某些情况下,不适合使用 v-permission。例如:Element-UI 的 el-tab 或 el-table-column 以及其它动态渲染 dom 的场景。你只能通过手动设置 v-if 来实现。', | ||
94 | delete: '删除', | ||
95 | confirm: '确定', | ||
96 | cancel: '取消' | ||
97 | }, | ||
98 | guide: { | ||
99 | description: '引导页对于一些第一次进入项目的人很有用,你可以简单介绍下项目的功能。本 Demo 是基于', | ||
100 | button: '打开引导' | ||
101 | }, | ||
102 | components: { | ||
103 | documentation: '文档', | ||
104 | tinymceTips: '富文本是管理后台一个核心的功能,但同时又是一个有很多坑的地方。在选择富文本的过程中我也走了不少的弯路,市面上常见的富文本都基本用过了,最终权衡了一下选择了Tinymce。更详细的富文本比较和介绍见', | ||
105 | dropzoneTips: '由于我司业务有特殊需求,而且要传七牛 所以没用第三方,选择了自己封装。代码非常的简单,具体代码你可以在这里看到 @/components/Dropzone', | ||
106 | stickyTips: '当页面滚动到预设的位置会吸附在顶部', | ||
107 | backToTopTips1: '页面滚动到指定位置会在右下角出现返回顶部按钮', | ||
108 | backToTopTips2: '可自定义按钮的样式、show/hide、出现的高度、返回的位置 如需文字提示,可在外部使用Element的el-tooltip元素', | ||
109 | imageUploadTips: '由于我在使用时它只有vue@1版本,而且和mockjs不兼容,所以自己改造了一下,如果大家要使用的话,优先还是使用官方版本。' | ||
110 | }, | ||
111 | table: { | ||
112 | dynamicTips1: '固定表头, 按照表头顺序排序', | ||
113 | dynamicTips2: '不固定表头, 按照点击顺序排序', | ||
114 | dragTips1: '默认顺序', | ||
115 | dragTips2: '拖拽后顺序', | ||
116 | title: '标题', | ||
117 | importance: '重要性', | ||
118 | type: '类型', | ||
119 | remark: '点评', | ||
120 | search: '搜索', | ||
121 | add: '添加', | ||
122 | export: '导出', | ||
123 | reviewer: '审核人', | ||
124 | id: '序号', | ||
125 | date: '时间', | ||
126 | author: '作者', | ||
127 | readings: '阅读数', | ||
128 | status: '状态', | ||
129 | actions: '操作', | ||
130 | edit: '编辑', | ||
131 | publish: '发布', | ||
132 | draft: '草稿', | ||
133 | delete: '删除', | ||
134 | cancel: '取 消', | ||
135 | confirm: '确 定' | ||
136 | }, | ||
137 | example: { | ||
138 | warning: '创建和编辑页面是不能被 keep-alive 缓存的,因为keep-alive 的 include 目前不支持根据路由来缓存,所以目前都是基于 component name 来进行缓存的。如果你想类似的实现缓存效果,可以使用 localStorage 等浏览器缓存方案。或者不要使用 keep-alive 的 include,直接缓存所有页面。详情见' | ||
139 | }, | ||
140 | errorLog: { | ||
141 | tips: '请点击右上角bug小图标', | ||
142 | description: '现在的管理后台基本都是spa的形式了,它增强了用户体验,但同时也会增加页面出问题的可能性,可能一个小小的疏忽就导致整个页面的死锁。好在 Vue 官网提供了一个方法来捕获处理异常,你可以在其中进行错误处理或者异常上报。', | ||
143 | documentation: '文档介绍' | ||
144 | }, | ||
145 | excel: { | ||
146 | export: '导出', | ||
147 | selectedExport: '导出已选择项', | ||
148 | placeholder: '请输入文件名(默认excel-list)' | ||
149 | }, | ||
150 | zip: { | ||
151 | export: '导出', | ||
152 | placeholder: '请输入文件名(默认file)' | ||
153 | }, | ||
154 | pdf: { | ||
155 | tips: '这里使用 window.print() 来实现下载pdf的功能' | ||
156 | }, | ||
157 | theme: { | ||
158 | change: '换肤', | ||
159 | documentation: '换肤文档', | ||
160 | tips: 'Tips: 它区别于 navbar 上的 theme-pick, 是两种不同的换肤方法,各自有不同的应用场景,具体请参考文档。' | ||
161 | }, | ||
162 | tagsView: { | ||
163 | refresh: '刷新', | ||
164 | close: '关闭', | ||
165 | closeOthers: '关闭其它', | ||
166 | closeAll: '关闭所有' | ||
167 | }, | ||
168 | settings: { | ||
169 | title: '系统布局配置', | ||
170 | theme: '主题色', | ||
171 | tagsView: '开启 Tags-View', | ||
172 | fixedHeader: '固定 Header', | ||
173 | sidebarLogo: '侧边栏 Logo' | ||
174 | } | ||
175 | } | ||
176 |
src/layout/components/AppMain.vue
1 | <template> | 1 | <template> |
2 | <section class="app-main"> | 2 | <section class="app-main"> |
3 | <transition name="fade-transform" mode="out-in"> | 3 | <transition name="fade-transform" mode="out-in"> |
4 | <router-view :key="key" /> | 4 | <keep-alive :include="cachedViews"> |
5 | <router-view :key="key" /> | ||
6 | </keep-alive> | ||
5 | </transition> | 7 | </transition> |
6 | </section> | 8 | </section> |
7 | </template> | 9 | </template> |
8 | 10 | ||
9 | <script> | 11 | <script> |
10 | export default { | 12 | export default { |
11 | name: 'AppMain', | 13 | name: 'AppMain', |
12 | computed: { | 14 | computed: { |
13 | // key() { | 15 | cachedViews() { |
14 | // return this.$route.name !== undefined? this.$route.name + +new Date(): this.$route + +new Date() | 16 | return this.$store.state.tagsView.cachedViews |
15 | // } | 17 | }, |
16 | key() { | 18 | key() { |
17 | return this.$route.path | 19 | return this.$route.path |
18 | } | 20 | } |
19 | } | 21 | } |
20 | } | 22 | } |
21 | </script> | 23 | </script> |
22 | 24 | ||
23 | <style scoped> | 25 | <style lang="scss" scoped> |
24 | .app-main { | 26 | .app-main { |
25 | /*50 = navbar */ | 27 | /* 50= navbar 50 */ |
26 | min-height: calc(100vh - 50px); | 28 | min-height: calc(100vh - 50px); |
27 | width: 100%; | 29 | width: 100%; |
28 | position: relative; | 30 | position: relative; |
29 | overflow: hidden; | 31 | overflow: hidden; |
30 | } | 32 | } |
33 | |||
31 | .fixed-header+.app-main { | 34 | .fixed-header+.app-main { |
32 | padding-top: 50px; | 35 | padding-top: 50px; |
33 | } | 36 | } |
37 | |||
38 | .hasTagsView { | ||
39 | .app-main { | ||
40 | /* 84 = navbar + tags-view = 50 + 34 */ | ||
41 | min-height: calc(100vh - 84px); | ||
42 | } | ||
43 | |||
44 | .fixed-header+.app-main { | ||
45 | padding-top: 84px; | ||
46 | } | ||
47 | } | ||
34 | </style> | 48 | </style> |
35 | 49 | ||
36 | <style lang="scss"> | 50 | <style lang="scss"> |
37 | // fix css style bug in open el-dialog | 51 | // fix css style bug in open el-dialog |
38 | .el-popup-parent--hidden { | 52 | .el-popup-parent--hidden { |
39 | .fixed-header { | 53 | .fixed-header { |
40 | padding-right: 15px; | 54 | padding-right: 15px; |
41 | } | 55 | } |
42 | } | 56 | } |
43 | </style> | 57 | </style> |
44 | 58 |
src/layout/components/Navbar.vue
1 | <template> | 1 | <template> |
2 | <div class="navbar"> | 2 | <div class="navbar"> |
3 | <hamburger | 3 | <hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" /> |
4 | :is-active="sidebar.opened" | ||
5 | class="hamburger-container" | ||
6 | @toggleClick="toggleSideBar" | ||
7 | /> | ||
8 | 4 | ||
9 | <breadcrumb class="breadcrumb-container" /> | 5 | <breadcrumb id="breadcrumb-container" class="breadcrumb-container" /> |
10 | 6 | ||
11 | <div class="right-menu"> | 7 | <div class="right-menu"> |
12 | <el-menu | 8 | <template v-if="device!=='mobile'"> |
13 | :default-active="activeIndex" | 9 | <search id="header-search" class="right-menu-item" /> |
14 | class="el-menu-demo" | 10 | |
15 | mode="horizontal" | 11 | <error-log class="errLog-container right-menu-item hover-effect" /> |
16 | @select="handleSelect" | 12 | |
17 | > | 13 | <screenfull id="screenfull" class="right-menu-item hover-effect" /> |
18 | <el-menu-item index="1"> | 14 | |
19 | <i class="el-icon-bell"></i>通知中心 | 15 | <el-tooltip :content="$t('navbar.size')" effect="dark" placement="bottom"> |
20 | <el-badge class="mark" :value="12" /> | 16 | <size-select id="size-select" class="right-menu-item hover-effect" /> |
21 | </el-menu-item> | 17 | </el-tooltip> |
22 | <el-submenu index="2"> | 18 | |
23 | <template slot="title"> | 19 | <lang-select class="right-menu-item hover-effect" /> |
24 | <i class="el-icon-custom"></i>个人设置 | 20 | |
25 | </template> | 21 | </template> |
26 | <el-menu-item index="2-1">选项1</el-menu-item> | 22 | |
27 | <el-menu-item index="2-2">选项2</el-menu-item> | 23 | <el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click"> |
28 | <el-menu-item index="2-3">选项3</el-menu-item> | 24 | <div class="avatar-wrapper"> |
29 | </el-submenu> | 25 | <img :src="avatar+'?imageView2/1/w/80/h/80'" class="user-avatar"> |
30 | <el-dropdown class="avatar-container" trigger="click"> | 26 | <i class="el-icon-caret-bottom" /> |
31 | <div class="avatar-wrapper"> | 27 | </div> |
32 | <img :src="avatar+'?imageView2/1/w/80/h/80'" class="user-avatar" /> | 28 | <el-dropdown-menu slot="dropdown"> |
33 | <i class="el-icon-caret-bottom" /> | 29 | <router-link to="/profile/index"> |
34 | </div> | 30 | <el-dropdown-item> |
35 | <el-dropdown-menu slot="dropdown" class="user-dropdown"> | 31 | {{ $t('navbar.profile') }} |
36 | <router-link to="/"> | ||
37 | <el-dropdown-item>Home</el-dropdown-item> | ||
38 | </router-link> | ||
39 | <router-link to="/seting"> | ||
40 | <el-dropdown-item>个人设置</el-dropdown-item> | ||
41 | </router-link> | ||
42 | <!-- <a target="_blank" href="https://github.com/PanJiaChen/vue-admin-template/"> | ||
43 | <el-dropdown-item>Github</el-dropdown-item> | ||
44 | </a>--> | ||
45 | <!-- <a target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/#/"> | ||
46 | <el-dropdown-item>Docs</el-dropdown-item> | ||
47 | </a>--> | ||
48 | <el-dropdown-item divided @click.native="logout"> | ||
49 | <span style="display:block;">退出系统</span> | ||
50 | </el-dropdown-item> | 32 | </el-dropdown-item> |
51 | </el-dropdown-menu> | 33 | </router-link> |
52 | </el-dropdown> | 34 | <router-link to="/"> |
53 | <el-menu-item index="3" disabled>ddd</el-menu-item> | 35 | <el-dropdown-item> |
54 | <el-menu-item index="4"> | 36 | {{ $t('navbar.dashboard') }} |
55 | <a href="https://glass.xiuyetang.com" target="_blank">跳到外部链接</a> | 37 | </el-dropdown-item> |
56 | </el-menu-item> | 38 | </router-link> |
57 | </el-menu> | 39 | <a target="_blank" href="https://github.com/PanJiaChen/vue-element-admin/"> |
40 | <el-dropdown-item> | ||
41 | {{ $t('navbar.github') }} | ||
42 | </el-dropdown-item> | ||
43 | </a> | ||
44 | <a target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/#/"> | ||
45 | <el-dropdown-item>Docs</el-dropdown-item> | ||
46 | </a> | ||
47 | <el-dropdown-item divided @click.native="logout"> | ||
48 | <span style="display:block;">{{ $t('navbar.logOut') }}</span> | ||
49 | </el-dropdown-item> | ||
50 | </el-dropdown-menu> | ||
51 | </el-dropdown> | ||
58 | </div> | 52 | </div> |
59 | </div> | 53 | </div> |
60 | </template> | 54 | </template> |
61 | 55 | ||
62 | <script> | 56 | <script> |
63 | import { mapGetters } from "vuex"; | 57 | import { mapGetters } from 'vuex' |
64 | import Breadcrumb from "@/components/Breadcrumb"; | 58 | import Breadcrumb from '@/components/Breadcrumb' |
65 | import Hamburger from "@/components/Hamburger"; | 59 | import Hamburger from '@/components/Hamburger' |
60 | import ErrorLog from '@/components/ErrorLog' | ||
61 | import Screenfull from '@/components/Screenfull' | ||
62 | import SizeSelect from '@/components/SizeSelect' | ||
63 | import LangSelect from '@/components/LangSelect' | ||
64 | import Search from '@/components/HeaderSearch' | ||
66 | 65 | ||
67 | export default { | 66 | export default { |
68 | components: { | 67 | components: { |
69 | Breadcrumb, | 68 | Breadcrumb, |
70 | Hamburger | 69 | Hamburger, |
70 | ErrorLog, | ||
71 | Screenfull, | ||
72 | SizeSelect, | ||
73 | LangSelect, | ||
74 | Search | ||
71 | }, | 75 | }, |
72 | computed: { | 76 | computed: { |
73 | ...mapGetters(["sidebar", "avatar"]) | 77 | ...mapGetters([ |
78 | 'sidebar', | ||
79 | 'avatar', | ||
80 | 'device' | ||
81 | ]) | ||
74 | }, | 82 | }, |
75 | methods: { | 83 | methods: { |
76 | toggleSideBar() { | 84 | toggleSideBar() { |
77 | this.$store.dispatch("app/toggleSideBar"); | 85 | this.$store.dispatch('app/toggleSideBar') |
78 | }, | 86 | }, |
79 | async logout() { | 87 | async logout() { |
80 | await this.$store.dispatch("user/logout"); | 88 | await this.$store.dispatch('user/logout') |
81 | this.$router.push(`/login?redirect=${this.$route.fullPath}`); | 89 | this.$router.push(`/login?redirect=${this.$route.fullPath}`) |
82 | } | 90 | } |
83 | } | 91 | } |
84 | }; | 92 | } |
85 | </script> | 93 | </script> |
86 | 94 | ||
87 | <style lang="scss" scoped> | 95 | <style lang="scss" scoped> |
88 | .item { | ||
89 | margin-top: 10px; | ||
90 | margin-right: 20px; | ||
91 | } | ||
92 | .navbar { | 96 | .navbar { |
93 | height: 50px; | 97 | height: 50px; |
94 | overflow: hidden; | 98 | overflow: hidden; |
95 | position: relative; | 99 | position: relative; |
96 | background: #fff; | 100 | background: #fff; |
97 | box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08); | 101 | box-shadow: 0 1px 4px rgba(0,21,41,.08); |
98 | 102 | ||
99 | .hamburger-container { | 103 | .hamburger-container { |
100 | line-height: 46px; | 104 | line-height: 46px; |
101 | height: 100%; | 105 | height: 100%; |
102 | float: left; | 106 | float: left; |
103 | cursor: pointer; | 107 | cursor: pointer; |
104 | transition: background 0.3s; | 108 | transition: background .3s; |
105 | -webkit-tap-highlight-color: transparent; | 109 | -webkit-tap-highlight-color:transparent; |
106 | 110 | ||
107 | &:hover { | 111 | &:hover { |
108 | background: rgba(0, 0, 0, 0.025); | 112 | background: rgba(0, 0, 0, .025) |
109 | } | 113 | } |
110 | } | 114 | } |
111 | 115 | ||
112 | .breadcrumb-container { | 116 | .breadcrumb-container { |
113 | float: left; | 117 | float: left; |
114 | } | 118 | } |
115 | 119 | ||
120 | .errLog-container { | ||
121 | display: inline-block; | ||
122 | vertical-align: top; | ||
123 | } | ||
124 | |||
116 | .right-menu { | 125 | .right-menu { |
117 | float: right; | 126 | float: right; |
118 | height: 100%; | 127 | height: 100%; |
119 | line-height: 50px; | 128 | line-height: 50px; |
120 | 129 | ||
121 | &:focus { | 130 | &:focus { |
122 | outline: none; | 131 | outline: none; |
123 | } | 132 | } |
124 | 133 | ||
125 | .right-menu-item { | 134 | .right-menu-item { |
126 | display: inline-block; | 135 | display: inline-block; |
127 | padding: 0 8px; | 136 | padding: 0 8px; |
128 | height: 100%; | 137 | height: 100%; |
129 | font-size: 18px; | 138 | font-size: 18px; |
130 | color: #5a5e66; | 139 | color: #5a5e66; |
131 | vertical-align: text-bottom; | 140 | vertical-align: text-bottom; |
132 | 141 | ||
133 | &.hover-effect { | 142 | &.hover-effect { |
134 | cursor: pointer; | 143 | cursor: pointer; |
135 | transition: background 0.3s; | 144 | transition: background .3s; |
136 | 145 | ||
137 | &:hover { | 146 | &:hover { |
138 | background: rgba(0, 0, 0, 0.025); | 147 | background: rgba(0, 0, 0, .025) |
139 | } | 148 | } |
140 | } | 149 | } |
141 | } | 150 | } |
142 | 151 | ||
143 | .avatar-container { | 152 | .avatar-container { |
144 | margin-right: 30px; | 153 | margin-right: 30px; |
145 | 154 | ||
146 | .avatar-wrapper { | 155 | .avatar-wrapper { |
147 | margin-top: 5px; | 156 | margin-top: 5px; |
src/layout/components/Settings/index.vue
File was created | 1 | <template> | |
2 | <div class="drawer-container"> | ||
3 | <div> | ||
4 | <h3 class="drawer-title">{{ $t('settings.title') }}</h3> | ||
5 | |||
6 | <div class="drawer-item"> | ||
7 | <span>{{ $t('settings.theme') }}</span> | ||
8 | <theme-picker style="float: right;height: 26px;margin: -3px 8px 0 0;" @change="themeChange" /> | ||
9 | </div> | ||
10 | |||
11 | <div class="drawer-item"> | ||
12 | <span>{{ $t('settings.tagsView') }}</span> | ||
13 | <el-switch v-model="tagsView" class="drawer-switch" /> | ||
14 | </div> | ||
15 | |||
16 | <div class="drawer-item"> | ||
17 | <span>{{ $t('settings.fixedHeader') }}</span> | ||
18 | <el-switch v-model="fixedHeader" class="drawer-switch" /> | ||
19 | </div> | ||
20 | |||
21 | <div class="drawer-item"> | ||
22 | <span>{{ $t('settings.sidebarLogo') }}</span> | ||
23 | <el-switch v-model="sidebarLogo" class="drawer-switch" /> | ||
24 | </div> | ||
25 | <a v-if="isShowJob" href="https://panjiachen.github.io/vue-element-admin-site/zh/job/" target="_blank" class="job-link"> | ||
26 | <el-alert | ||
27 | title="部门目前非常缺人!有兴趣的可以点击了解详情。坐标: 字节跳动" | ||
28 | type="success" | ||
29 | :closable="false" | ||
30 | /> | ||
31 | </a> | ||
32 | |||
33 | <div v-if="lang === 'zh'" class="drawer-item"> | ||
34 | <span>菜单支持拼音搜索</span> | ||
35 | <el-switch v-model="supportPinyinSearch" class="drawer-switch" /> | ||
36 | </div> | ||
37 | |||
38 | </div> | ||
39 | </div> | ||
40 | </template> | ||
41 | |||
42 | <script> | ||
43 | import ThemePicker from '@/components/ThemePicker' | ||
44 | |||
45 | export default { | ||
46 | components: { ThemePicker }, | ||
47 | data() { | ||
48 | return {} | ||
49 | }, | ||
50 | computed: { | ||
51 | isShowJob() { | ||
52 | return this.$store.getters.language === 'zh' | ||
53 | }, | ||
54 | fixedHeader: { | ||
55 | get() { | ||
56 | return this.$store.state.settings.fixedHeader | ||
57 | }, | ||
58 | set(val) { | ||
59 | this.$store.dispatch('settings/changeSetting', { | ||
60 | key: 'fixedHeader', | ||
61 | value: val | ||
62 | }) | ||
63 | } | ||
64 | }, | ||
65 | tagsView: { | ||
66 | get() { | ||
67 | return this.$store.state.settings.tagsView | ||
68 | }, | ||
69 | set(val) { | ||
70 | this.$store.dispatch('settings/changeSetting', { | ||
71 | key: 'tagsView', | ||
72 | value: val | ||
73 | }) | ||
74 | } | ||
75 | }, | ||
76 | sidebarLogo: { | ||
77 | get() { | ||
78 | return this.$store.state.settings.sidebarLogo | ||
79 | }, | ||
80 | set(val) { | ||
81 | this.$store.dispatch('settings/changeSetting', { | ||
82 | key: 'sidebarLogo', | ||
83 | value: val | ||
84 | }) | ||
85 | } | ||
86 | }, | ||
87 | supportPinyinSearch: { | ||
88 | get() { | ||
89 | return this.$store.state.settings.supportPinyinSearch | ||
90 | }, | ||
91 | set(val) { | ||
92 | this.$store.dispatch('settings/changeSetting', { | ||
93 | key: 'supportPinyinSearch', | ||
94 | value: val | ||
95 | }) | ||
96 | } | ||
97 | }, | ||
98 | lang() { | ||
99 | return this.$store.getters.language | ||
100 | } | ||
101 | }, | ||
102 | methods: { | ||
103 | themeChange(val) { | ||
104 | this.$store.dispatch('settings/changeSetting', { | ||
105 | key: 'theme', | ||
106 | value: val | ||
107 | }) | ||
108 | } | ||
109 | } | ||
110 | } | ||
111 | </script> | ||
112 | |||
113 | <style lang="scss" scoped> | ||
114 | .drawer-container { | ||
115 | padding: 24px; | ||
116 | font-size: 14px; | ||
117 | line-height: 1.5; | ||
118 | word-wrap: break-word; | ||
119 | |||
120 | .drawer-title { | ||
121 | margin-bottom: 12px; | ||
122 | color: rgba(0, 0, 0, .85); | ||
123 | font-size: 14px; | ||
124 | line-height: 22px; | ||
125 | } | ||
126 | |||
127 | .drawer-item { | ||
128 | color: rgba(0, 0, 0, .65); | ||
129 | font-size: 14px; | ||
130 | padding: 12px 0; | ||
131 | } | ||
132 | |||
133 | .drawer-switch { | ||
134 | float: right | ||
135 | } | ||
136 | |||
137 | .job-link{ | ||
138 | display: block; | ||
139 | position: absolute; | ||
140 | width: 100%; | ||
141 | left: 0; | ||
142 | bottom: 0; | ||
143 | } | ||
144 | } | ||
145 | </style> | ||
146 |
1 | export default { | 1 | export default { |
2 | computed: { | 2 | computed: { |
3 | device() { | 3 | device() { |
4 | return this.$store.state.app.device | 4 | return this.$store.state.app.device |
5 | } | 5 | } |
6 | }, | 6 | }, |
7 | mounted() { | 7 | mounted() { |
8 | // In order to fix the click on menu on the ios device will trigger the mouseleave bug | 8 | // In order to fix the click on menu on the ios device will trigger the mouseleave bug |
9 | // https://github.com/PanJiaChen/vue-element-admin/issues/1135 | 9 | // https://github.com/PanJiaChen/vue-element-admin/issues/1135 |
10 | this.fixBugIniOS() | 10 | this.fixBugIniOS() |
11 | }, | 11 | }, |
12 | methods: { | 12 | methods: { |
13 | fixBugIniOS() { | 13 | fixBugIniOS() { |
14 | const $subMenu = this.$refs.subMenu | 14 | const $subMenu = this.$refs.subMenu |
15 | if ($subMenu) { | 15 | if ($subMenu) { |
16 | const handleMouseleave = $subMenu.handleMouseleave | 16 | const handleMouseleave = $subMenu.handleMouseleave |
17 | $subMenu.handleMouseleave = (e) => { | 17 | $subMenu.handleMouseleave = (e) => { |
18 | if (this.device === 'mobile') { | 18 | if (this.device === 'mobile') { |
19 | return | 19 | return |
20 | } | 20 | } |
21 | handleMouseleave(e) | 21 | handleMouseleave(e) |
22 | } | 22 | } |
23 | } | 23 | } |
24 | } | 24 | } |
25 | } | 25 | } |
26 | } | 26 | } |
27 | 27 |
1 | <script> | 1 | <script> |
2 | export default { | 2 | export default { |
3 | name: 'MenuItem', | 3 | name: 'MenuItem', |
4 | functional: true, | 4 | functional: true, |
5 | props: { | 5 | props: { |
6 | icon: { | 6 | icon: { |
7 | type: String, | 7 | type: String, |
8 | default: '' | 8 | default: '' |
9 | }, | 9 | }, |
10 | title: { | 10 | title: { |
11 | type: String, | 11 | type: String, |
12 | default: '' | 12 | default: '' |
13 | } | 13 | } |
14 | }, | 14 | }, |
15 | render(h, context) { | 15 | render(h, context) { |
16 | const { icon, title } = context.props | 16 | const { icon, title } = context.props |
17 | const vnodes = [] | 17 | const vnodes = [] |
18 | 18 | ||
19 | if (icon) { | 19 | if (icon) { |
20 | vnodes.push(<svg-icon icon-class={icon}/>) | 20 | vnodes.push(<svg-icon icon-class={icon}/>) |
21 | } | 21 | } |
22 | 22 | ||
23 | if (title) { | 23 | if (title) { |
24 | vnodes.push(<span slot='title'>{(title)}</span>) | 24 | vnodes.push(<span slot='title'>{(title)}</span>) |
25 | } | 25 | } |
26 | return vnodes | 26 | return vnodes |
27 | } | 27 | } |
28 | } | 28 | } |
29 | </script> | 29 | </script> |
30 | 30 |
1 | 1 | ||
2 | <template> | 2 | <template> |
3 | <!-- eslint-disable vue/require-component-is --> | 3 | <!-- eslint-disable vue/require-component-is --> |
4 | <component v-bind="linkProps(to)"> | 4 | <component v-bind="linkProps(to)"> |
5 | <slot /> | 5 | <slot /> |
6 | </component> | 6 | </component> |
7 | </template> | 7 | </template> |
8 | 8 | ||
9 | <script> | 9 | <script> |
10 | import { isExternal } from '@/utils/validate' | 10 | import { isExternal } from '@/utils/validate' |
11 | 11 | ||
12 | export default { | 12 | export default { |
13 | props: { | 13 | props: { |
14 | to: { | 14 | to: { |
15 | type: String, | 15 | type: String, |
16 | required: true | 16 | required: true |
17 | } | 17 | } |
18 | }, | 18 | }, |
19 | methods: { | 19 | methods: { |
20 | linkProps(url) { | 20 | linkProps(url) { |
21 | if (isExternal(url)) { | 21 | if (isExternal(url)) { |
22 | return { | 22 | return { |
23 | is: 'a', | 23 | is: 'a', |
24 | href: url, | 24 | href: url, |
25 | target: '_blank', | 25 | target: '_blank', |
26 | rel: 'noopener' | 26 | rel: 'noopener' |
27 | } | 27 | } |
28 | } | 28 | } |
29 | return { | 29 | return { |
30 | is: 'router-link', | 30 | is: 'router-link', |
31 | to: url | 31 | to: url |
32 | } | 32 | } |
33 | } | 33 | } |
34 | } | 34 | } |
35 | } | 35 | } |
36 | </script> | 36 | </script> |
37 | 37 |
src/layout/components/Sidebar/Logo.vue
1 | <template> | 1 | <template> |
2 | <div class="sidebar-logo-container" :class="{'collapse':collapse}"> | 2 | <div class="sidebar-logo-container" :class="{'collapse':collapse}"> |
3 | <transition name="sidebarLogoFade"> | 3 | <transition name="sidebarLogoFade"> |
4 | <router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/"> | 4 | <router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/"> |
5 | <img v-if="logo" :src="logo" class="sidebar-logo"> | 5 | <img v-if="logo" :src="logo" class="sidebar-logo"> |
6 | <h1 v-else class="sidebar-title">{{ title }} </h1> | 6 | <h1 v-else class="sidebar-title">{{ title }} </h1> |
7 | </router-link> | 7 | </router-link> |
8 | <router-link v-else key="expand" class="sidebar-logo-link" to="/"> | 8 | <router-link v-else key="expand" class="sidebar-logo-link" to="/"> |
9 | <img v-if="logo" :src="logo" class="sidebar-logo"> | 9 | <img v-if="logo" :src="logo" class="sidebar-logo"> |
10 | <h1 class="sidebar-title">{{ title }} </h1> | 10 | <h1 class="sidebar-title">{{ title }} </h1> |
11 | </router-link> | 11 | </router-link> |
12 | </transition> | 12 | </transition> |
13 | </div> | 13 | </div> |
14 | </template> | 14 | </template> |
15 | 15 | ||
16 | <script> | 16 | <script> |
17 | export default { | 17 | export default { |
18 | name: 'SidebarLogo', | 18 | name: 'SidebarLogo', |
19 | props: { | 19 | props: { |
20 | collapse: { | 20 | collapse: { |
21 | type: Boolean, | 21 | type: Boolean, |
22 | required: true | 22 | required: true |
23 | } | 23 | } |
24 | }, | 24 | }, |
25 | data() { | 25 | data() { |
26 | return { | 26 | return { |
27 | title: '鱼皮出海', | 27 | title: 'Vue Element Admin', |
28 | logo: 'https://wpimg.wallstcn.com/69a1c46c-eb1c-4b46-8bd4-e9e686ef5251.png' | 28 | logo: 'https://wpimg.wallstcn.com/69a1c46c-eb1c-4b46-8bd4-e9e686ef5251.png' |
29 | } | 29 | } |
30 | } | 30 | } |
31 | } | 31 | } |
32 | </script> | 32 | </script> |
33 | 33 | ||
34 | <style lang="scss" scoped> | 34 | <style lang="scss" scoped> |
35 | .sidebarLogoFade-enter-active { | 35 | .sidebarLogoFade-enter-active { |
36 | transition: opacity 1.5s; | 36 | transition: opacity 1.5s; |
37 | } | 37 | } |
38 | 38 | ||
39 | .sidebarLogoFade-enter, | 39 | .sidebarLogoFade-enter, |
40 | .sidebarLogoFade-leave-to { | 40 | .sidebarLogoFade-leave-to { |
41 | opacity: 0; | 41 | opacity: 0; |
42 | } | 42 | } |
43 | 43 | ||
44 | .sidebar-logo-container { | 44 | .sidebar-logo-container { |
45 | position: relative; | 45 | position: relative; |
46 | width: 100%; | 46 | width: 100%; |
47 | height: 50px; | 47 | height: 50px; |
48 | line-height: 50px; | 48 | line-height: 50px; |
49 | background: #2b2f3a; | 49 | background: #2b2f3a; |
50 | text-align: center; | 50 | text-align: center; |
51 | overflow: hidden; | 51 | overflow: hidden; |
52 | 52 | ||
53 | & .sidebar-logo-link { | 53 | & .sidebar-logo-link { |
54 | height: 100%; | 54 | height: 100%; |
55 | width: 100%; | 55 | width: 100%; |
56 | 56 | ||
57 | & .sidebar-logo { | 57 | & .sidebar-logo { |
58 | width: 32px; | 58 | width: 32px; |
59 | height: 32px; | 59 | height: 32px; |
60 | vertical-align: middle; | 60 | vertical-align: middle; |
61 | margin-right: 12px; | 61 | margin-right: 12px; |
62 | } | 62 | } |
63 | 63 | ||
64 | & .sidebar-title { | 64 | & .sidebar-title { |
65 | display: inline-block; | 65 | display: inline-block; |
66 | margin: 0; | 66 | margin: 0; |
67 | color: #fff; | 67 | color: #fff; |
68 | font-weight: 600; | 68 | font-weight: 600; |
69 | line-height: 50px; | 69 | line-height: 50px; |
70 | font-size: 14px; | 70 | font-size: 14px; |
71 | font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif; | 71 | font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif; |
72 | vertical-align: middle; | 72 | vertical-align: middle; |
73 | } | 73 | } |
74 | } | 74 | } |
75 | 75 | ||
76 | &.collapse { | 76 | &.collapse { |
77 | .sidebar-logo { | 77 | .sidebar-logo { |
78 | margin-right: 0px; | 78 | margin-right: 0px; |
79 | } | 79 | } |
80 | } | 80 | } |
81 | } | 81 | } |
82 | </style> | 82 | </style> |
83 | 83 |
src/layout/components/Sidebar/SidebarItem.vue
1 | <template> | 1 | <template> |
2 | <div v-if="!item.hidden"> | 2 | <div v-if="!item.hidden"> |
3 | <template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow"> | 3 | <template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow"> |
4 | <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)"> | 4 | <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)"> |
5 | <el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}"> | 5 | <el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}"> |
6 | <item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="onlyOneChild.meta.title" /> | 6 | <item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="generateTitle(onlyOneChild.meta.title)" /> |
7 | </el-menu-item> | 7 | </el-menu-item> |
8 | </app-link> | 8 | </app-link> |
9 | </template> | 9 | </template> |
10 | 10 | ||
11 | <el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body> | 11 | <el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body> |
12 | <template slot="title"> | 12 | <template slot="title"> |
13 | <item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" /> | 13 | <item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="generateTitle(item.meta.title)" /> |
14 | </template> | 14 | </template> |
15 | <sidebar-item | 15 | <sidebar-item |
16 | v-for="child in item.children" | 16 | v-for="child in item.children" |
17 | :key="child.path" | 17 | :key="child.path" |
18 | :is-nest="true" | 18 | :is-nest="true" |
19 | :item="child" | 19 | :item="child" |
20 | :base-path="resolvePath(child.path)" | 20 | :base-path="resolvePath(child.path)" |
21 | class="nest-menu" | 21 | class="nest-menu" |
22 | /> | 22 | /> |
23 | </el-submenu> | 23 | </el-submenu> |
24 | </div> | 24 | </div> |
25 | </template> | 25 | </template> |
26 | 26 | ||
27 | <script> | 27 | <script> |
28 | import path from 'path' | 28 | import path from 'path' |
29 | import { generateTitle } from '@/utils/i18n' | ||
29 | import { isExternal } from '@/utils/validate' | 30 | import { isExternal } from '@/utils/validate' |
30 | import Item from './Item' | 31 | import Item from './Item' |
31 | import AppLink from './Link' | 32 | import AppLink from './Link' |
32 | import FixiOSBug from './FixiOSBug' | 33 | import FixiOSBug from './FixiOSBug' |
33 | 34 | ||
34 | export default { | 35 | export default { |
35 | name: 'SidebarItem', | 36 | name: 'SidebarItem', |
36 | components: { Item, AppLink }, | 37 | components: { Item, AppLink }, |
37 | mixins: [FixiOSBug], | 38 | mixins: [FixiOSBug], |
38 | props: { | 39 | props: { |
39 | // route object | 40 | // route object |
40 | item: { | 41 | item: { |
41 | type: Object, | 42 | type: Object, |
42 | required: true | 43 | required: true |
43 | }, | 44 | }, |
44 | isNest: { | 45 | isNest: { |
45 | type: Boolean, | 46 | type: Boolean, |
46 | default: false | 47 | default: false |
47 | }, | 48 | }, |
48 | basePath: { | 49 | basePath: { |
49 | type: String, | 50 | type: String, |
50 | default: '' | 51 | default: '' |
51 | } | 52 | } |
52 | }, | 53 | }, |
53 | data() { | 54 | data() { |
54 | // To fix https://github.com/PanJiaChen/vue-admin-template/issues/237 | 55 | // To fix https://github.com/PanJiaChen/vue-admin-template/issues/237 |
55 | // TODO: refactor with render function | 56 | // TODO: refactor with render function |
56 | this.onlyOneChild = null | 57 | this.onlyOneChild = null |
57 | return {} | 58 | return {} |
58 | }, | 59 | }, |
59 | methods: { | 60 | methods: { |
60 | hasOneShowingChild(children = [], parent) { | 61 | hasOneShowingChild(children = [], parent) { |
61 | const showingChildren = children.filter(item => { | 62 | const showingChildren = children.filter(item => { |
62 | if (item.hidden) { | 63 | if (item.hidden) { |
63 | return false | 64 | return false |
64 | } else { | 65 | } else { |
65 | // Temp set(will be used if only has one showing child) | 66 | // Temp set(will be used if only has one showing child) |
66 | this.onlyOneChild = item | 67 | this.onlyOneChild = item |
67 | return true | 68 | return true |
68 | } | 69 | } |
69 | }) | 70 | }) |
70 | 71 | ||
71 | // When there is only one child router, the child router is displayed by default | 72 | // When there is only one child router, the child router is displayed by default |
72 | if (showingChildren.length === 1) { | 73 | if (showingChildren.length === 1) { |
73 | return true | 74 | return true |
74 | } | 75 | } |
75 | 76 | ||
76 | // Show parent if there are no child router to display | 77 | // Show parent if there are no child router to display |
77 | if (showingChildren.length === 0) { | 78 | if (showingChildren.length === 0) { |
78 | this.onlyOneChild = { ... parent, path: '', noShowingChildren: true } | 79 | this.onlyOneChild = { ... parent, path: '', noShowingChildren: true } |
79 | return true | 80 | return true |
80 | } | 81 | } |
81 | 82 | ||
82 | return false | 83 | return false |
83 | }, | 84 | }, |
84 | resolvePath(routePath) { | 85 | resolvePath(routePath) { |
85 | if (isExternal(routePath)) { | 86 | if (isExternal(routePath)) { |
86 | return routePath | 87 | return routePath |
87 | } | 88 | } |
88 | if (isExternal(this.basePath)) { | 89 | if (isExternal(this.basePath)) { |
89 | return this.basePath | 90 | return this.basePath |
90 | } | 91 | } |
91 | return path.resolve(this.basePath, routePath) | 92 | return path.resolve(this.basePath, routePath) |
92 | } | 93 | }, |
94 | |||
95 | generateTitle | ||
93 | } | 96 | } |
94 | } | 97 | } |
95 | </script> | 98 | </script> |
96 | 99 |
1 | <template> | 1 | <template> |
2 | <div :class="{'has-logo':showLogo}"> | 2 | <div :class="{'has-logo':showLogo}"> |
3 | <logo v-if="showLogo" :collapse="isCollapse" /> | 3 | <logo v-if="showLogo" :collapse="isCollapse" /> |
4 | <el-scrollbar wrap-class="scrollbar-wrapper"> | 4 | <el-scrollbar wrap-class="scrollbar-wrapper"> |
5 | <el-menu | 5 | <el-menu |
6 | :default-active="activeMenu" | 6 | :default-active="activeMenu" |
7 | :collapse="isCollapse" | 7 | :collapse="isCollapse" |
8 | :background-color="variables.menuBg" | 8 | :background-color="variables.menuBg" |
9 | :text-color="variables.menuText" | 9 | :text-color="variables.menuText" |
10 | :unique-opened="false" | 10 | :unique-opened="false" |
11 | :active-text-color="variables.menuActiveText" | 11 | :active-text-color="variables.menuActiveText" |
12 | :collapse-transition="false" | 12 | :collapse-transition="false" |
13 | mode="vertical" | 13 | mode="vertical" |
14 | > | 14 | > |
15 | <sidebar-item v-for="route in permission_routes" :key="route.path" :item="route" :base-path="route.path" /> | 15 | <sidebar-item v-for="route in permission_routes" :key="route.path" :item="route" :base-path="route.path" /> |
16 | </el-menu> | 16 | </el-menu> |
17 | </el-scrollbar> | 17 | </el-scrollbar> |
18 | </div> | 18 | </div> |
19 | </template> | 19 | </template> |
20 | 20 | ||
21 | <script> | 21 | <script> |
22 | import { mapGetters } from 'vuex' | 22 | import { mapGetters } from 'vuex' |
23 | import Logo from './Logo' | 23 | import Logo from './Logo' |
24 | import SidebarItem from './SidebarItem' | 24 | import SidebarItem from './SidebarItem' |
25 | import variables from '@/styles/variables.scss' | 25 | import variables from '@/styles/variables.scss' |
26 | 26 | ||
27 | export default { | 27 | export default { |
28 | components: { SidebarItem, Logo }, | 28 | components: { SidebarItem, Logo }, |
29 | computed: { | 29 | computed: { |
30 | ...mapGetters([ | 30 | ...mapGetters([ |
31 | 'permission_routes', | 31 | 'permission_routes', |
32 | 'sidebar' | 32 | 'sidebar' |
33 | ]), | 33 | ]), |
34 | activeMenu() { | 34 | activeMenu() { |
35 | const route = this.$route | 35 | const route = this.$route |
36 | const { meta, path } = route | 36 | const { meta, path } = route |
37 | // if set path, the sidebar will highlight the path you set | 37 | // if set path, the sidebar will highlight the path you set |
38 | if (meta.activeMenu) { | 38 | if (meta.activeMenu) { |
39 | return meta.activeMenu | 39 | return meta.activeMenu |
40 | } | 40 | } |
41 | return path | 41 | return path |
42 | }, | 42 | }, |
43 | showLogo() { | 43 | showLogo() { |
44 | return this.$store.state.settings.sidebarLogo | 44 | return this.$store.state.settings.sidebarLogo |
45 | }, | 45 | }, |
46 | variables() { | 46 | variables() { |
47 | return variables | 47 | return variables |
48 | }, | 48 | }, |
49 | isCollapse() { | 49 | isCollapse() { |
50 | return !this.sidebar.opened | 50 | return !this.sidebar.opened |
51 | } | 51 | } |
52 | } | 52 | } |
53 | } | 53 | } |
54 | </script> | 54 | </script> |
55 | 55 |
src/layout/components/TagsView/ScrollPane.vue
File was created | 1 | <template> | |
2 | <el-scrollbar ref="scrollContainer" :vertical="false" class="scroll-container" @wheel.native.prevent="handleScroll"> | ||
3 | <slot /> | ||
4 | </el-scrollbar> | ||
5 | </template> | ||
6 | |||
7 | <script> | ||
8 | const tagAndTagSpacing = 4 // tagAndTagSpacing | ||
9 | |||
10 | export default { | ||
11 | name: 'ScrollPane', | ||
12 | data() { | ||
13 | return { | ||
14 | left: 0 | ||
15 | } | ||
16 | }, | ||
17 | computed: { | ||
18 | scrollWrapper() { | ||
19 | return this.$refs.scrollContainer.$refs.wrap | ||
20 | } | ||
21 | }, | ||
22 | methods: { | ||
23 | handleScroll(e) { | ||
24 | const eventDelta = e.wheelDelta || -e.deltaY * 40 | ||
25 | const $scrollWrapper = this.scrollWrapper | ||
26 | $scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4 | ||
27 | }, | ||
28 | moveToTarget(currentTag) { | ||
29 | const $container = this.$refs.scrollContainer.$el | ||
30 | const $containerWidth = $container.offsetWidth | ||
31 | const $scrollWrapper = this.scrollWrapper | ||
32 | const tagList = this.$parent.$refs.tag | ||
33 | |||
34 | let firstTag = null | ||
35 | let lastTag = null | ||
36 | |||
37 | // find first tag and last tag | ||
38 | if (tagList.length > 0) { | ||
39 | firstTag = tagList[0] | ||
40 | lastTag = tagList[tagList.length - 1] | ||
41 | } | ||
42 | |||
43 | if (firstTag === currentTag) { | ||
44 | $scrollWrapper.scrollLeft = 0 | ||
45 | } else if (lastTag === currentTag) { | ||
46 | $scrollWrapper.scrollLeft = $scrollWrapper.scrollWidth - $containerWidth | ||
47 | } else { | ||
48 | // find preTag and nextTag | ||
49 | const currentIndex = tagList.findIndex(item => item === currentTag) | ||
50 | const prevTag = tagList[currentIndex - 1] | ||
51 | const nextTag = tagList[currentIndex + 1] | ||
52 | |||
53 | // the tag's offsetLeft after of nextTag | ||
54 | const afterNextTagOffsetLeft = nextTag.$el.offsetLeft + nextTag.$el.offsetWidth + tagAndTagSpacing | ||
55 | |||
56 | // the tag's offsetLeft before of prevTag | ||
57 | const beforePrevTagOffsetLeft = prevTag.$el.offsetLeft - tagAndTagSpacing | ||
58 | |||
59 | if (afterNextTagOffsetLeft > $scrollWrapper.scrollLeft + $containerWidth) { | ||
60 | $scrollWrapper.scrollLeft = afterNextTagOffsetLeft - $containerWidth | ||
61 | } else if (beforePrevTagOffsetLeft < $scrollWrapper.scrollLeft) { | ||
62 | $scrollWrapper.scrollLeft = beforePrevTagOffsetLeft | ||
63 | } | ||
64 | } | ||
65 | } | ||
66 | } | ||
67 | } | ||
68 | </script> | ||
69 | |||
70 | <style lang="scss" scoped> | ||
71 | .scroll-container { | ||
72 | white-space: nowrap; | ||
73 | position: relative; | ||
74 | overflow: hidden; | ||
75 | width: 100%; | ||
76 | /deep/ { | ||
77 | .el-scrollbar__bar { | ||
78 | bottom: 0px; | ||
79 | } | ||
80 | .el-scrollbar__wrap { | ||
81 | height: 49px; | ||
82 | } | ||
83 | } | ||
84 | } | ||
85 | </style> | ||
86 |
src/layout/components/TagsView/index.vue
File was created | 1 | <template> | |
2 | <div id="tags-view-container" class="tags-view-container"> | ||
3 | <scroll-pane ref="scrollPane" class="tags-view-wrapper"> | ||
4 | <router-link | ||
5 | v-for="tag in visitedViews" | ||
6 | ref="tag" | ||
7 | :key="tag.path" | ||
8 | :class="isActive(tag)?'active':''" | ||
9 | :to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }" | ||
10 | tag="span" | ||
11 | class="tags-view-item" | ||
12 | @click.middle.native="!isAffix(tag)?closeSelectedTag(tag):''" | ||
13 | @contextmenu.prevent.native="openMenu(tag,$event)" | ||
14 | > | ||
15 | {{ generateTitle(tag.title) }} | ||
16 | <span v-if="!isAffix(tag)" class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)" /> | ||
17 | </router-link> | ||
18 | </scroll-pane> | ||
19 | <ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu"> | ||
20 | <li @click="refreshSelectedTag(selectedTag)">{{ $t('tagsView.refresh') }}</li> | ||
21 | <li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)">{{ $t('tagsView.close') }}</li> | ||
22 | <li @click="closeOthersTags">{{ $t('tagsView.closeOthers') }}</li> | ||
23 | <li @click="closeAllTags(selectedTag)">{{ $t('tagsView.closeAll') }}</li> | ||
24 | </ul> | ||
25 | </div> | ||
26 | </template> | ||
27 | |||
28 | <script> | ||
29 | import ScrollPane from './ScrollPane' | ||
30 | import { generateTitle } from '@/utils/i18n' | ||
31 | import path from 'path' | ||
32 | |||
33 | export default { | ||
34 | components: { ScrollPane }, | ||
35 | data() { | ||
36 | return { | ||
37 | visible: false, | ||
38 | top: 0, | ||
39 | left: 0, | ||
40 | selectedTag: {}, | ||
41 | affixTags: [] | ||
42 | } | ||
43 | }, | ||
44 | computed: { | ||
45 | visitedViews() { | ||
46 | return this.$store.state.tagsView.visitedViews | ||
47 | }, | ||
48 | routes() { | ||
49 | return this.$store.state.permission.routes | ||
50 | } | ||
51 | }, | ||
52 | watch: { | ||
53 | $route() { | ||
54 | this.addTags() | ||
55 | this.moveToCurrentTag() | ||
56 | }, | ||
57 | visible(value) { | ||
58 | if (value) { | ||
59 | document.body.addEventListener('click', this.closeMenu) | ||
60 | } else { | ||
61 | document.body.removeEventListener('click', this.closeMenu) | ||
62 | } | ||
63 | } | ||
64 | }, | ||
65 | mounted() { | ||
66 | this.initTags() | ||
67 | this.addTags() | ||
68 | }, | ||
69 | methods: { | ||
70 | generateTitle, // generateTitle by vue-i18n | ||
71 | isActive(route) { | ||
72 | return route.path === this.$route.path | ||
73 | }, | ||
74 | isAffix(tag) { | ||
75 | return tag.meta && tag.meta.affix | ||
76 | }, | ||
77 | filterAffixTags(routes, basePath = '/') { | ||
78 | let tags = [] | ||
79 | routes.forEach(route => { | ||
80 | if (route.meta && route.meta.affix) { | ||
81 | const tagPath = path.resolve(basePath, route.path) | ||
82 | tags.push({ | ||
83 | fullPath: tagPath, | ||
84 | path: tagPath, | ||
85 | name: route.name, | ||
86 | meta: { ...route.meta } | ||
87 | }) | ||
88 | } | ||
89 | if (route.children) { | ||
90 | const tempTags = this.filterAffixTags(route.children, route.path) | ||
91 | if (tempTags.length >= 1) { | ||
92 | tags = [...tags, ...tempTags] | ||
93 | } | ||
94 | } | ||
95 | }) | ||
96 | return tags | ||
97 | }, | ||
98 | initTags() { | ||
99 | const affixTags = this.affixTags = this.filterAffixTags(this.routes) | ||
100 | for (const tag of affixTags) { | ||
101 | // Must have tag name | ||
102 | if (tag.name) { | ||
103 | this.$store.dispatch('tagsView/addVisitedView', tag) | ||
104 | } | ||
105 | } | ||
106 | }, | ||
107 | addTags() { | ||
108 | const { name } = this.$route | ||
109 | if (name) { | ||
110 | this.$store.dispatch('tagsView/addView', this.$route) | ||
111 | } | ||
112 | return false | ||
113 | }, | ||
114 | moveToCurrentTag() { | ||
115 | const tags = this.$refs.tag | ||
116 | this.$nextTick(() => { | ||
117 | for (const tag of tags) { | ||
118 | if (tag.to.path === this.$route.path) { | ||
119 | this.$refs.scrollPane.moveToTarget(tag) | ||
120 | // when query is different then update | ||
121 | if (tag.to.fullPath !== this.$route.fullPath) { | ||
122 | this.$store.dispatch('tagsView/updateVisitedView', this.$route) | ||
123 | } | ||
124 | break | ||
125 | } | ||
126 | } | ||
127 | }) | ||
128 | }, | ||
129 | refreshSelectedTag(view) { | ||
130 | this.$store.dispatch('tagsView/delCachedView', view).then(() => { | ||
131 | const { fullPath } = view | ||
132 | this.$nextTick(() => { | ||
133 | this.$router.replace({ | ||
134 | path: '/redirect' + fullPath | ||
135 | }) | ||
136 | }) | ||
137 | }) | ||
138 | }, | ||
139 | closeSelectedTag(view) { | ||
140 | this.$store.dispatch('tagsView/delView', view).then(({ visitedViews }) => { | ||
141 | if (this.isActive(view)) { | ||
142 | this.toLastView(visitedViews, view) | ||
143 | } | ||
144 | }) | ||
145 | }, | ||
146 | closeOthersTags() { | ||
147 | this.$router.push(this.selectedTag) | ||
148 | this.$store.dispatch('tagsView/delOthersViews', this.selectedTag).then(() => { | ||
149 | this.moveToCurrentTag() | ||
150 | }) | ||
151 | }, | ||
152 | closeAllTags(view) { | ||
153 | this.$store.dispatch('tagsView/delAllViews').then(({ visitedViews }) => { | ||
154 | if (this.affixTags.some(tag => tag.path === view.path)) { | ||
155 | return | ||
156 | } | ||
157 | this.toLastView(visitedViews, view) | ||
158 | }) | ||
159 | }, | ||
160 | toLastView(visitedViews, view) { | ||
161 | const latestView = visitedViews.slice(-1)[0] | ||
162 | if (latestView) { | ||
163 | this.$router.push(latestView.fullPath) | ||
164 | } else { | ||
165 | // now the default is to redirect to the home page if there is no tags-view, | ||
166 | // you can adjust it according to your needs. | ||
167 | if (view.name === 'Dashboard') { | ||
168 | // to reload home page | ||
169 | this.$router.replace({ path: '/redirect' + view.fullPath }) | ||
170 | } else { | ||
171 | this.$router.push('/') | ||
172 | } | ||
173 | } | ||
174 | }, | ||
175 | openMenu(tag, e) { | ||
176 | const menuMinWidth = 105 | ||
177 | const offsetLeft = this.$el.getBoundingClientRect().left // container margin left | ||
178 | const offsetWidth = this.$el.offsetWidth // container width | ||
179 | const maxLeft = offsetWidth - menuMinWidth // left boundary | ||
180 | const left = e.clientX - offsetLeft + 15 // 15: margin right | ||
181 | |||
182 | if (left > maxLeft) { | ||
183 | this.left = maxLeft | ||
184 | } else { | ||
185 | this.left = left | ||
186 | } | ||
187 | |||
188 | this.top = e.clientY | ||
189 | this.visible = true | ||
190 | this.selectedTag = tag | ||
191 | }, | ||
192 | closeMenu() { | ||
193 | this.visible = false | ||
194 | } | ||
195 | } | ||
196 | } | ||
197 | </script> | ||
198 | |||
199 | <style lang="scss" scoped> | ||
200 | .tags-view-container { | ||
201 | height: 34px; | ||
202 | width: 100%; | ||
203 | background: #fff; | ||
204 | border-bottom: 1px solid #d8dce5; | ||
205 | box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .12), 0 0 3px 0 rgba(0, 0, 0, .04); | ||
206 | .tags-view-wrapper { | ||
207 | .tags-view-item { | ||
208 | display: inline-block; | ||
209 | position: relative; | ||
210 | cursor: pointer; | ||
211 | height: 26px; | ||
212 | line-height: 26px; | ||
213 | border: 1px solid #d8dce5; | ||
214 | color: #495060; | ||
215 | background: #fff; | ||
216 | padding: 0 8px; | ||
217 | font-size: 12px; | ||
218 | margin-left: 5px; | ||
219 | margin-top: 4px; | ||
220 | &:first-of-type { | ||
221 | margin-left: 15px; | ||
222 | } | ||
223 | &:last-of-type { | ||
224 | margin-right: 15px; | ||
225 | } | ||
226 | &.active { | ||
227 | background-color: #42b983; | ||
228 | color: #fff; | ||
229 | border-color: #42b983; | ||
230 | &::before { | ||
231 | content: ''; | ||
232 | background: #fff; | ||
233 | display: inline-block; | ||
234 | width: 8px; | ||
235 | height: 8px; | ||
236 | border-radius: 50%; | ||
237 | position: relative; | ||
238 | margin-right: 2px; | ||
239 | } | ||
240 | } | ||
241 | } | ||
242 | } | ||
243 | .contextmenu { | ||
244 | margin: 0; | ||
245 | background: #fff; | ||
246 | z-index: 3000; | ||
247 | position: absolute; | ||
248 | list-style-type: none; | ||
249 | padding: 5px 0; | ||
250 | border-radius: 4px; | ||
251 | font-size: 12px; | ||
252 | font-weight: 400; | ||
253 | color: #333; | ||
254 | box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3); | ||
255 | li { | ||
256 | margin: 0; | ||
257 | padding: 7px 16px; | ||
258 | cursor: pointer; | ||
259 | &:hover { | ||
260 | background: #eee; | ||
261 | } | ||
262 | } | ||
263 | } | ||
264 | } | ||
265 | </style> | ||
266 | |||
267 | <style lang="scss"> | ||
268 | //reset element css of el-icon-close | ||
269 | .tags-view-wrapper { | ||
270 | .tags-view-item { | ||
271 | .el-icon-close { | ||
272 | width: 16px; | ||
273 | height: 16px; | ||
274 | vertical-align: 2px; | ||
275 | border-radius: 50%; | ||
276 | text-align: center; | ||
277 | transition: all .3s cubic-bezier(.645, .045, .355, 1); | ||
278 | transform-origin: 100% 50%; | ||
279 | &:before { | ||
280 | transform: scale(.6); | ||
281 | display: inline-block; | ||
282 | vertical-align: -3px; | ||
283 | } | ||
284 | &:hover { | ||
285 | background-color: #b4bccc; | ||
286 | color: #fff; | ||
287 | } | ||
288 | } | ||
289 | } | ||
290 | } | ||
291 | </style> | ||
292 |
src/layout/components/index.js
1 | // export { default as Navbar } from '../../common/Header' | ||
2 | export { default as Navbar } from './Navbar' | ||
3 | export { default as Sidebar } from './Sidebar' | ||
4 | export { default as AppMain } from './AppMain' | 1 | export { default as AppMain } from './AppMain' |
2 | export { default as Navbar } from './Navbar' | ||
3 | export { default as Settings } from './Settings' |
src/layout/index.vue
1 | <template> | 1 | <template> |
2 | <div :class="classObj" class="app-wrapper"> | 2 | <div :class="classObj" class="app-wrapper"> |
3 | <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" /> | 3 | <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" /> |
4 | <sidebar class="sidebar-container" /> | 4 | <sidebar class="sidebar-container" /> |
5 | <div class="main-container"> | 5 | <div :class="{hasTagsView:needTagsView}" class="main-container"> |
6 | <div :class="{'fixed-header':fixedHeader}"> | 6 | <div :class="{'fixed-header':fixedHeader}"> |
7 | <navbar /> | 7 | <navbar /> |
8 | <tags-view v-if="needTagsView" /> | ||
8 | </div> | 9 | </div> |
9 | <app-main /> | 10 | <app-main /> |
11 | <right-panel v-if="showSettings"> | ||
12 | <settings /> | ||
13 | </right-panel> | ||
10 | </div> | 14 | </div> |
11 | </div> | 15 | </div> |
12 | </template> | 16 | </template> |
13 | 17 | ||
14 | <script> | 18 | <script> |
15 | import { Navbar, Sidebar, AppMain } from './components' | 19 | import RightPanel from '@/components/RightPanel' |
20 | import { AppMain, Navbar, Settings, Sidebar, TagsView } from './components' | ||
16 | import ResizeMixin from './mixin/ResizeHandler' | 21 | import ResizeMixin from './mixin/ResizeHandler' |
22 | import { mapState } from 'vuex' | ||
17 | 23 | ||
18 | export default { | 24 | export default { |
19 | name: 'Layout', | 25 | name: 'Layout', |
20 | components: { | 26 | components: { |
27 | AppMain, | ||
21 | Navbar, | 28 | Navbar, |
29 | RightPanel, | ||
30 | Settings, | ||
22 | Sidebar, | 31 | Sidebar, |
23 | AppMain | 32 | TagsView |
24 | }, | 33 | }, |
25 | mixins: [ResizeMixin], | 34 | mixins: [ResizeMixin], |
26 | computed: { | 35 | computed: { |
27 | sidebar() { | 36 | ...mapState({ |
28 | return this.$store.state.app.sidebar | 37 | sidebar: state => state.app.sidebar, |
29 | }, | 38 | device: state => state.app.device, |
30 | device() { | 39 | showSettings: state => state.settings.showSettings, |
31 | return this.$store.state.app.device | 40 | needTagsView: state => state.settings.tagsView, |
32 | }, | 41 | fixedHeader: state => state.settings.fixedHeader |
33 | fixedHeader() { | 42 | }), |
34 | return this.$store.state.settings.fixedHeader | ||
35 | }, | ||
36 | classObj() { | 43 | classObj() { |
37 | return { | 44 | return { |
38 | hideSidebar: !this.sidebar.opened, | 45 | hideSidebar: !this.sidebar.opened, |
39 | openSidebar: this.sidebar.opened, | 46 | openSidebar: this.sidebar.opened, |
40 | withoutAnimation: this.sidebar.withoutAnimation, | 47 | withoutAnimation: this.sidebar.withoutAnimation, |
41 | mobile: this.device === 'mobile' | 48 | mobile: this.device === 'mobile' |
42 | } | 49 | } |
43 | } | 50 | } |
44 | }, | 51 | }, |
45 | methods: { | 52 | methods: { |
46 | handleClickOutside() { | 53 | handleClickOutside() { |
47 | this.$store.dispatch('app/closeSideBar', { withoutAnimation: false }) | 54 | this.$store.dispatch('app/closeSideBar', { withoutAnimation: false }) |
48 | } | 55 | } |
49 | } | 56 | } |
50 | } | 57 | } |
51 | </script> | 58 | </script> |
52 | 59 | ||
53 | <style lang="scss" scoped> | 60 | <style lang="scss" scoped> |
54 | @import "~@/styles/mixin.scss"; | 61 | @import "~@/styles/mixin.scss"; |
55 | @import "~@/styles/variables.scss"; | 62 | @import "~@/styles/variables.scss"; |
56 | 63 | ||
57 | .app-wrapper { | 64 | .app-wrapper { |
58 | @include clearfix; | 65 | @include clearfix; |
59 | position: relative; | 66 | position: relative; |
60 | height: 100%; | 67 | height: 100%; |
61 | width: 100%; | 68 | width: 100%; |
62 | &.mobile.openSidebar{ | 69 | |
70 | &.mobile.openSidebar { | ||
63 | position: fixed; | 71 | position: fixed; |
64 | top: 0; | 72 | top: 0; |
65 | } | 73 | } |
66 | } | 74 | } |
75 | |||
67 | .drawer-bg { | 76 | .drawer-bg { |
68 | background: #000; | 77 | background: #000; |
69 | opacity: 0.3; | 78 | opacity: 0.3; |
70 | width: 100%; | 79 | width: 100%; |
71 | top: 0; | 80 | top: 0; |
72 | height: 100%; | 81 | height: 100%; |
73 | position: absolute; | 82 | position: absolute; |
74 | z-index: 999; | 83 | z-index: 999; |
75 | } | 84 | } |
76 | 85 | ||
77 | .fixed-header { | 86 | .fixed-header { |
78 | position: fixed; | 87 | position: fixed; |
79 | top: 0; | 88 | top: 0; |
80 | right: 0; | 89 | right: 0; |
81 | z-index: 9; | 90 | z-index: 9; |
82 | width: calc(100% - #{$sideBarWidth}); | 91 | width: calc(100% - #{$sideBarWidth}); |
83 | transition: width 0.28s; | 92 | transition: width 0.28s; |
84 | } | 93 | } |
85 | 94 | ||
86 | .hideSidebar .fixed-header { | 95 | .hideSidebar .fixed-header { |
87 | width: calc(100% - 54px) | 96 | width: calc(100% - 54px) |
88 | } | 97 | } |
89 | 98 | ||
90 | .mobile .fixed-header { | 99 | .mobile .fixed-header { |
91 | width: 100%; | 100 | width: 100%; |
92 | } | 101 | } |
1 | import store from '@/store' | 1 | import store from '@/store' |
2 | 2 | ||
3 | const { body } = document | 3 | const { body } = document |
4 | const WIDTH = 992 // refer to Bootstrap's responsive design | 4 | const WIDTH = 992 // refer to Bootstrap's responsive design |
5 | 5 | ||
6 | export default { | 6 | export default { |
7 | watch: { | 7 | watch: { |
8 | $route(route) { | 8 | $route(route) { |
9 | if (this.device === 'mobile' && this.sidebar.opened) { | 9 | if (this.device === 'mobile' && this.sidebar.opened) { |
10 | store.dispatch('app/closeSideBar', { withoutAnimation: false }) | 10 | store.dispatch('app/closeSideBar', { withoutAnimation: false }) |
11 | } | 11 | } |
12 | } | 12 | } |
13 | }, | 13 | }, |
14 | beforeMount() { | 14 | beforeMount() { |
15 | window.addEventListener('resize', this.$_resizeHandler) | 15 | window.addEventListener('resize', this.$_resizeHandler) |
16 | }, | 16 | }, |
17 | beforeDestroy() { | 17 | beforeDestroy() { |
18 | window.removeEventListener('resize', this.$_resizeHandler) | 18 | window.removeEventListener('resize', this.$_resizeHandler) |
19 | }, | 19 | }, |
20 | mounted() { | 20 | mounted() { |
21 | const isMobile = this.$_isMobile() | 21 | const isMobile = this.$_isMobile() |
22 | if (isMobile) { | 22 | if (isMobile) { |
23 | store.dispatch('app/toggleDevice', 'mobile') | 23 | store.dispatch('app/toggleDevice', 'mobile') |
24 | store.dispatch('app/closeSideBar', { withoutAnimation: true }) | 24 | store.dispatch('app/closeSideBar', { withoutAnimation: true }) |
25 | } | 25 | } |
26 | }, | 26 | }, |
27 | methods: { | 27 | methods: { |
28 | // use $_ for mixins properties | 28 | // use $_ for mixins properties |
29 | // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential | 29 | // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential |
30 | $_isMobile() { | 30 | $_isMobile() { |
31 | const rect = body.getBoundingClientRect() | 31 | const rect = body.getBoundingClientRect() |
32 | return rect.width - 1 < WIDTH | 32 | return rect.width - 1 < WIDTH |
33 | }, | 33 | }, |
34 | $_resizeHandler() { | 34 | $_resizeHandler() { |
35 | if (!document.hidden) { | 35 | if (!document.hidden) { |
36 | const isMobile = this.$_isMobile() | 36 | const isMobile = this.$_isMobile() |
37 | store.dispatch('app/toggleDevice', isMobile ? 'mobile' : 'desktop') | 37 | store.dispatch('app/toggleDevice', isMobile ? 'mobile' : 'desktop') |
38 | 38 | ||
39 | if (isMobile) { | 39 | if (isMobile) { |
40 | store.dispatch('app/closeSideBar', { withoutAnimation: true }) | 40 | store.dispatch('app/closeSideBar', { withoutAnimation: true }) |
41 | } | 41 | } |
42 | } | 42 | } |
43 | } | 43 | } |
44 | } | 44 | } |
45 | } | 45 | } |
46 | 46 |
src/main.js
1 | import Vue from 'vue' | 1 | import Vue from 'vue' |
2 | 2 | ||
3 | import 'normalize.css/normalize.css' // A modern alternative to CSS resets | 3 | import Cookies from 'js-cookie' |
4 | 4 | ||
5 | import ElementUI from 'element-ui' | 5 | import 'normalize.css/normalize.css' // a modern alternative to CSS resets |
6 | import 'element-ui/lib/theme-chalk/index.css' | 6 | |
7 | // import locale from 'element-ui/lib/locale/lang/en' // lang i18n | 7 | import Element from 'element-ui' |
8 | // import local_zh from 'element-ui/lib/locale/lang/zh-CN' // 在node_module里面 | 8 | import './styles/element-variables.scss' |
9 | 9 | ||
10 | import '@/styles/index.scss' // global css | 10 | import '@/styles/index.scss' // global css |
11 | 11 | ||
12 | import App from './App' | 12 | import App from './App' |
13 | import store from './store' | 13 | import store from './store' |
14 | import router from './router' | 14 | import router from './router' |
15 | 15 | ||
16 | import '@/icons' // icon | 16 | import i18n from './lang' // internationalization |
17 | import '@/permission' // permission control | 17 | import './icons' // icon |
18 | import './permission' // permission control | ||
19 | import './utils/error-log' // error log | ||
20 | |||
21 | import * as filters from './filters' // global filters | ||
18 | 22 | ||
19 | /** | 23 | /** |
20 | * If you don't want to use mock-server | 24 | * If you don't want to use mock-server |
21 | * you want to use MockJs for mock api | 25 | * you want to use MockJs for mock api |
22 | * you can execute: mockXHR() | 26 | * you can execute: mockXHR() |
23 | * | 27 | * |
24 | * Currently MockJs will be used in the production environment, | 28 | * Currently MockJs will be used in the production environment, |
25 | * please remove it before going online ! ! ! | 29 | * please remove it before going online ! ! ! |
26 | */ | 30 | */ |
27 | if (process.env.NODE_ENV === 'production') { | 31 | if (process.env.NODE_ENV === 'production') { |
28 | const { mockXHR } = require('../mock') | 32 | const { mockXHR } = require('../mock') |
29 | mockXHR() | 33 | mockXHR() |
30 | } | 34 | } |
31 | 35 | ||
32 | Vue.use(ElementUI, { size: 'small', zIndex: 3000 }) | 36 | Vue.use(Element, { |
33 | // set ElementUI lang to EN | 37 | size: Cookies.get('size') || 'medium', // set element-ui default size |
34 | // Vue.use(ElementUI, { locale }) | 38 | i18n: (key, value) => i18n.t(key, value) |
35 | // 如果想要中文版 element-ui,按如下方式声明 | 39 | }) |
36 | // Vue.use(ElementUI, {local_zh}) | 40 | |
41 | // register global utility filters | ||
42 | Object.keys(filters).forEach(key => { | ||
43 | Vue.filter(key, filters[key]) | ||
44 | }) | ||
45 | |||
37 | Vue.config.productionTip = false | 46 | Vue.config.productionTip = false |
38 | 47 | ||
39 | new Vue({ | 48 | new Vue({ |
40 | el: '#app', | 49 | el: '#app', |
41 | router, | 50 | router, |
42 | store, | 51 | store, |
52 | i18n, | ||
43 | render: h => h(App) | 53 | render: h => h(App) |
44 | }) | 54 | }) |
45 | 55 |
src/permission.js
1 | import router from './router' | 1 | import router from './router' |
2 | import store from './store' | 2 | import store from './store' |
3 | import { Message } from 'element-ui' | 3 | import { Message } from 'element-ui' |
4 | import NProgress from 'nprogress' // progress bar | 4 | import NProgress from 'nprogress' // progress bar |
5 | import 'nprogress/nprogress.css' // progress bar style | 5 | import 'nprogress/nprogress.css' // progress bar style |
6 | import { getToken } from '@/utils/auth' // get token from cookie | 6 | import { getToken } from '@/utils/auth' // get token from cookie |
7 | import getPageTitle from '@/utils/get-page-title' | 7 | import getPageTitle from '@/utils/get-page-title' |
8 | 8 | ||
9 | NProgress.configure({ showSpinner: false }) // NProgress Configuration | 9 | NProgress.configure({ showSpinner: false }) // NProgress Configuration |
10 | 10 | ||
11 | const whiteList = ['/login'] // no redirect whitelist | 11 | const whiteList = ['/login', '/auth-redirect'] // no redirect whitelist |
12 | 12 | ||
13 | router.beforeEach(async(to, from, next) => { | 13 | router.beforeEach(async(to, from, next) => { |
14 | // start progress bar | 14 | // start progress bar |
15 | NProgress.start() | 15 | NProgress.start() |
16 | 16 | ||
17 | // set page title | 17 | // set page title |
18 | document.title = getPageTitle(to.meta.title) | 18 | document.title = getPageTitle(to.meta.title) |
19 | 19 | ||
20 | // determine whether the user has logged in | 20 | // determine whether the user has logged in |
21 | const hasToken = getToken() | 21 | const hasToken = getToken() |
22 | 22 | ||
23 | if (hasToken) { | 23 | if (hasToken) { |
24 | if (to.path === '/login') { | 24 | if (to.path === '/login') { |
25 | // if is logged in, redirect to the home page | 25 | // if is logged in, redirect to the home page |
26 | next({ path: '/' }) | 26 | next({ path: '/' }) |
27 | NProgress.done() | 27 | NProgress.done() |
28 | } else { | 28 | } else { |
29 | // determine whether the user has obtained his permission roles through getInfo | 29 | // determine whether the user has obtained his permission roles through getInfo |
30 | const hasRoles = store.getters.roles && store.getters.roles.length > 0 | 30 | const hasRoles = store.getters.roles && store.getters.roles.length > 0 |
31 | if (hasRoles) { | 31 | if (hasRoles) { |
32 | next() | 32 | next() |
33 | } else { | 33 | } else { |
34 | try { | 34 | try { |
35 | // get user info | 35 | // get user info |
36 | // note: roles must be a object array! such as: ['admin'] or ,['developer','editor'] | 36 | // note: roles must be a object array! such as: ['admin'] or ,['developer','editor'] |
37 | const { roles } = await store.dispatch('user/getInfo') | 37 | const { roles } = await store.dispatch('user/getInfo') |
38 | 38 | ||
39 | // generate accessible routes map based on roles | 39 | // generate accessible routes map based on roles |
40 | const accessRoutes = await store.dispatch('permission/generateRoutes', roles) | 40 | const accessRoutes = await store.dispatch('permission/generateRoutes', roles) |
41 | 41 | ||
42 | // dynamically add accessible routes | 42 | // dynamically add accessible routes |
43 | router.addRoutes(accessRoutes) | 43 | router.addRoutes(accessRoutes) |
44 | 44 | ||
45 | // hack method to ensure that addRoutes is complete | 45 | // hack method to ensure that addRoutes is complete |
46 | // set the replace: true, so the navigation will not leave a history record | 46 | // set the replace: true, so the navigation will not leave a history record |
47 | next({ ...to, replace: true }) | 47 | next({ ...to, replace: true }) |
48 | } catch (error) { | 48 | } catch (error) { |
49 | // remove token and go to login page to re-login | 49 | // remove token and go to login page to re-login |
50 | await store.dispatch('user/resetToken') | 50 | await store.dispatch('user/resetToken') |
51 | Message.error(error || 'Has Error') | 51 | Message.error(error || 'Has Error') |
52 | next(`/login?redirect=${to.path}`) | 52 | next(`/login?redirect=${to.path}`) |
53 | NProgress.done() | 53 | NProgress.done() |
54 | } | 54 | } |
55 | } | 55 | } |
56 | } | 56 | } |
57 | } else { | 57 | } else { |
58 | /* has no token*/ | 58 | /* has no token*/ |
59 | 59 | ||
60 | if (whiteList.indexOf(to.path) !== -1) { | 60 | if (whiteList.indexOf(to.path) !== -1) { |
61 | // in the free login whitelist, go directly | 61 | // in the free login whitelist, go directly |
62 | next() | 62 | next() |
63 | } else { | 63 | } else { |
64 | // other pages that do not have permission to access are redirected to the login page. | 64 | // other pages that do not have permission to access are redirected to the login page. |
65 | next(`/login?redirect=${to.path}`) | 65 | next(`/login?redirect=${to.path}`) |
66 | NProgress.done() | 66 | NProgress.done() |
67 | } | 67 | } |
68 | } | 68 | } |
69 | }) | 69 | }) |
70 | 70 | ||
71 | router.afterEach(() => { | 71 | router.afterEach(() => { |
72 | // finish progress bar | 72 | // finish progress bar |
73 | NProgress.done() | 73 | NProgress.done() |
74 | }) | 74 | }) |
75 | 75 |
src/router/index.js
1 | import Vue from 'vue' | 1 | import Vue from 'vue' |
2 | import Router from 'vue-router' | 2 | import Router from 'vue-router' |
3 | 3 | ||
4 | Vue.use(Router) | 4 | Vue.use(Router) |
5 | 5 | ||
6 | /* Layout */ | 6 | /* Layout */ |
7 | import Layout from '@/layout' | 7 | import Layout from '@/layout' |
8 | 8 | ||
9 | /* Router Modules */ | ||
10 | import componentsRouter from './modules/components' | ||
11 | import chartsRouter from './modules/charts' | ||
12 | import tableRouter from './modules/table' | ||
13 | import nestedRouter from './modules/nested' | ||
14 | |||
9 | /** | 15 | /** |
10 | * Note: sub-menu only appear when route children.length >= 1 | 16 | * Note: sub-menu only appear when route children.length >= 1 |
11 | * Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html | 17 | * Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html |
12 | * | 18 | * |
13 | * hidden: true if set true, item will not show in the sidebar(default is false) | 19 | * hidden: true if set true, item will not show in the sidebar(default is false) |
14 | * alwaysShow: true if set true, will always show the root menu | 20 | * alwaysShow: true if set true, will always show the root menu |
15 | * if not set alwaysShow, when item has more than one children route, | 21 | * if not set alwaysShow, when item has more than one children route, |
16 | * it will becomes nested mode, otherwise not show the root menu | 22 | * it will becomes nested mode, otherwise not show the root menu |
17 | * redirect: noRedirect if set noRedirect will no redirect in the breadcrumb | 23 | * redirect: noRedirect if set noRedirect will no redirect in the breadcrumb |
18 | * name:'router-name' the name is used by <keep-alive> (must set!!!) | 24 | * name:'router-name' the name is used by <keep-alive> (must set!!!) |
19 | * meta : { | 25 | * meta : { |
20 | roles: ['admin','editor'] control the page roles (you can set multiple roles) | 26 | roles: ['admin','editor'] control the page roles (you can set multiple roles) |
21 | title: 'title' the name show in sidebar and breadcrumb (recommend set) | 27 | title: 'title' the name show in sidebar and breadcrumb (recommend set) |
22 | icon: 'svg-name' the icon show in the sidebar | 28 | icon: 'svg-name' the icon show in the sidebar |
29 | noCache: true if set true, the page will no be cached(default is false) | ||
30 | affix: true if set true, the tag will affix in the tags-view | ||
23 | breadcrumb: false if set false, the item will hidden in breadcrumb(default is true) | 31 | breadcrumb: false if set false, the item will hidden in breadcrumb(default is true) |
24 | activeMenu: '/example/list' if set path, the sidebar will highlight the path you set | 32 | activeMenu: '/example/list' if set path, the sidebar will highlight the path you set |
25 | } | 33 | } |
26 | */ | 34 | */ |
27 | 35 | ||
28 | /** | 36 | /** |
29 | * constantRoutes | 37 | * constantRoutes |
30 | * a base page that does not have permission requirements | 38 | * a base page that does not have permission requirements |
31 | * all roles can be accessed | 39 | * all roles can be accessed |
32 | */ | 40 | */ |
33 | export const constantRoutes = [{ | 41 | export const constantRoutes = [ |
42 | { | ||
43 | path: '/redirect', | ||
44 | component: Layout, | ||
45 | hidden: true, | ||
46 | children: [ | ||
47 | { | ||
48 | path: '/redirect/:path*', | ||
49 | component: () => import('@/views/redirect/index') | ||
50 | } | ||
51 | ] | ||
52 | }, | ||
53 | { | ||
34 | path: '/login', | 54 | path: '/login', |
35 | component: () => import('@/views/login/index'), | 55 | component: () => import('@/views/login/index'), |
36 | hidden: true | 56 | hidden: true |
37 | }, | 57 | }, |
38 | { | 58 | { |
59 | path: '/auth-redirect', | ||
60 | component: () => import('@/views/login/auth-redirect'), | ||
61 | hidden: true | ||
62 | }, | ||
63 | { | ||
39 | path: '/404', | 64 | path: '/404', |
40 | component: () => import('@/views/404'), | 65 | component: () => import('@/views/error-page/404'), |
66 | hidden: true | ||
67 | }, | ||
68 | { | ||
69 | path: '/401', | ||
70 | component: () => import('@/views/error-page/401'), | ||
41 | hidden: true | 71 | hidden: true |
42 | }, | 72 | }, |
43 | { | 73 | { |
44 | path: '/', | 74 | path: '/', |
45 | component: Layout, | 75 | component: Layout, |
46 | redirect: '/dashboard', | 76 | redirect: '/dashboard', |
47 | children: [{ | 77 | children: [ |
48 | path: 'dashboard', | 78 | { |
49 | name: 'Dashboard', | 79 | path: 'dashboard', |
50 | component: () => import('@/views/dashboard/index'), | 80 | component: () => import('@/views/dashboard/index'), |
51 | meta: { | 81 | name: 'Dashboard', |
52 | title: '中控台', | 82 | meta: { title: 'dashboard', icon: 'dashboard', affix: true } |
53 | icon: 'dashboard' | ||
54 | } | 83 | } |
55 | }] | 84 | ] |
56 | }, | 85 | }, |
86 | // { | ||
87 | // path: '/documentation', | ||
88 | // component: Layout, | ||
89 | // children: [ | ||
90 | // { | ||
91 | // path: 'index', | ||
92 | // component: () => import('@/views/documentation/index'), | ||
93 | // name: 'Documentation', | ||
94 | // meta: { title: 'documentation', icon: 'documentation', affix: true } | ||
95 | // } | ||
96 | // ] | ||
97 | // }, | ||
98 | // { | ||
99 | // path: '/guide', | ||
100 | // component: Layout, | ||
101 | // redirect: '/guide/index', | ||
102 | // children: [ | ||
103 | // { | ||
104 | // path: 'index', | ||
105 | // component: () => import('@/views/guide/index'), | ||
106 | // name: 'Guide', | ||
107 | // meta: { title: 'guide', icon: 'guide', noCache: true } | ||
108 | // } | ||
109 | // ] | ||
110 | // }, | ||
57 | { | 111 | { |
58 | path: '/user', //用户管理 | 112 | path: '/profile', |
59 | component: Layout, | 113 | component: Layout, |
60 | redirect: '/user/list', | 114 | redirect: '/profile/index', |
61 | name: 'user', | 115 | hidden: true, |
62 | meta: { | 116 | children: [ |
63 | title: '用户管理', | 117 | { |
64 | icon: 'people' | 118 | path: 'index', |
65 | }, | 119 | component: () => import('@/views/profile/index'), |
66 | children: [{ | 120 | name: 'Profile', |
67 | path: 'user', | 121 | meta: { title: 'profile', icon: 'user', noCache: true } |
68 | name: 'User', | ||
69 | component: () => import('@/views/table/index'), | ||
70 | meta: { | ||
71 | title: '用户列表', | ||
72 | icon: 'peoples' | ||
73 | } | ||
74 | } | 122 | } |
75 | // , | ||
76 | // { | ||
77 | // path: 'tree', | ||
78 | // name: '', | ||
79 | // component: () => import('@/views/tree/index'), | ||
80 | // meta: { | ||
81 | // title: '权限控制', | ||
82 | // icon: 'lock' | ||
83 | // } | ||
84 | // } | ||
85 | ] | 123 | ] |
86 | }, | 124 | } |
125 | ] | ||
126 | |||
127 | /** | ||
128 | * asyncRoutes | ||
129 | * the routes that need to be dynamically loaded based on user roles | ||
130 | */ | ||
131 | export const asyncRoutes = [ | ||
87 | { | 132 | { |
88 | path: '/shop', | 133 | path: '/permission', |
89 | component: Layout, | 134 | component: Layout, |
135 | redirect: '/permission/page', | ||
136 | alwaysShow: true, // will always show the root menu | ||
137 | name: 'Permission', | ||
90 | meta: { | 138 | meta: { |
91 | title: '商家管理', | 139 | title: 'permission', |
92 | icon: 'shopping' | 140 | icon: 'lock', |
141 | roles: ['admin', 'editor'] // you can set roles in root nav | ||
93 | }, | 142 | }, |
94 | children: [{ | 143 | children: [ |
95 | path: 'shop', | 144 | { |
96 | name: 'Shop', | 145 | path: 'page', |
97 | component: () => import('@/views/table/index'), | 146 | component: () => import('@/views/permission/page'), |
147 | name: 'PagePermission', | ||
98 | meta: { | 148 | meta: { |
99 | title: '商家列表', | 149 | title: 'pagePermission', |
100 | icon: 'table' | 150 | roles: ['admin'] // or you can only set roles in sub nav |
101 | } | 151 | } |
102 | }, | 152 | }, |
103 | { | 153 | { |
104 | path: 'tree', | 154 | path: 'directive', |
105 | name: 'Tree', | 155 | component: () => import('@/views/permission/directive'), |
106 | component: () => import('@/views/tree/index'), | 156 | name: 'DirectivePermission', |
107 | meta: { | 157 | meta: { |
108 | title: '图片分析', | 158 | title: 'directivePermission' |
109 | icon: 'chart' | 159 | // if do not set roles, means: this page does not require permission |
110 | } | 160 | } |
111 | } | ||
112 | ] | ||
113 | }, | ||
114 | { | ||
115 | path: '/prod', | ||
116 | component: Layout, | ||
117 | redirect: '/prod/table', | ||
118 | name: 'Prod', | ||
119 | meta: { | ||
120 | title: '产品管理', | ||
121 | icon: 'tree' | ||
122 | }, | ||
123 | children: [{ | ||
124 | path: 'table', | ||
125 | name: 'Tree', | ||
126 | meta: { | ||
127 | title: '成镜', | ||
128 | icon: 'tree-table' | ||
129 | }, | ||
130 | children: [{ | ||
131 | path: 'table', | ||
132 | name: 'tree', | ||
133 | component: () => import('@/views/tree/index'), | ||
134 | meta: { | ||
135 | title: '款式索引', | ||
136 | icon: 'tree-table' | ||
137 | }, | ||
138 | children: [{ | ||
139 | path: 'table', | ||
140 | name: 'Table1', | ||
141 | component: () => import('@/views/table/index'), | ||
142 | meta: { | ||
143 | title: '青春学子风', | ||
144 | icon: 'guide' | ||
145 | } | ||
146 | },{ | ||
147 | path: 'table', | ||
148 | name: 'Table1', | ||
149 | component: () => import('@/views/table/index'), | ||
150 | meta: { | ||
151 | title: '质感哥特风', | ||
152 | icon: 'guide' | ||
153 | } | ||
154 | }] | ||
155 | },{ | ||
156 | path: 'table', | ||
157 | name: 'tree', | ||
158 | component: () => import('@/views/table/index'), | ||
159 | meta: { | ||
160 | title: '颜色索引', | ||
161 | icon: 'tree-table' | ||
162 | } | ||
163 | }] | ||
164 | }, | 161 | }, |
165 | { | 162 | { |
166 | path: 'tree', | 163 | path: 'role', |
167 | name: 'Tree', | 164 | component: () => import('@/views/permission/role'), |
168 | component: () => import('@/views/table/index'), | 165 | name: 'RolePermission', |
169 | meta: { | 166 | meta: { |
170 | title: '镜片', | 167 | title: 'rolePermission', |
171 | icon: 'tree-table' | 168 | roles: ['admin', 'editor'] |
172 | } | 169 | } |
173 | } | 170 | } |
174 | ] | 171 | ] |
175 | }, | 172 | }, |
173 | |||
176 | { | 174 | { |
177 | path: '/Meta', | 175 | path: '/icon', |
178 | component: Layout, | 176 | component: Layout, |
179 | redirect: '/meta/table', | 177 | children: [ |
180 | name: 'Meta', | ||
181 | meta: { | ||
182 | title: '元管理', | ||
183 | icon: 'guide' | ||
184 | }, | ||
185 | children: [{ | ||
186 | path: 'table', | ||
187 | name: 'Table', | ||
188 | component: () => import('@/views/table/index'), | ||
189 | meta: { | ||
190 | title: 'Table', | ||
191 | icon: 'table' | ||
192 | } | ||
193 | }, | ||
194 | { | 178 | { |
195 | path: 'tree', | 179 | path: 'index', |
196 | name: 'Tree', | 180 | component: () => import('@/views/icons/index'), |
197 | component: () => import('@/views/tree/index'), | 181 | name: 'Icons', |
198 | meta: { | 182 | meta: { title: 'icons', icon: 'icon', noCache: true } |
199 | title: 'Tree', | ||
200 | icon: 'tree' | ||
201 | } | ||
202 | } | 183 | } |
203 | ] | 184 | ] |
204 | }, | 185 | }, |
186 | |||
187 | /** when your routing map is too long, you can split it into small modules **/ | ||
188 | componentsRouter, | ||
189 | chartsRouter, | ||
190 | nestedRouter, | ||
191 | tableRouter, | ||
192 | |||
193 | // { | ||
194 | // path: '/example', | ||
195 | // component: Layout, | ||
196 | // redirect: '/example/list', | ||
197 | // name: 'Example', | ||
198 | // meta: { | ||
199 | // title: 'example', | ||
200 | // icon: 'example' | ||
201 | // }, | ||
202 | // children: [ | ||
203 | // { | ||
204 | // path: 'create', | ||
205 | // component: () => import('@/views/example/create'), | ||
206 | // name: 'CreateArticle', | ||
207 | // meta: { title: 'createArticle', icon: 'edit' } | ||
208 | // }, | ||
209 | // { | ||
210 | // path: 'edit/:id(\\d+)', | ||
211 | // component: () => import('@/views/example/edit'), | ||
212 | // name: 'EditArticle', | ||
213 | // meta: { title: 'editArticle', noCache: true, activeMenu: '/example/list' }, | ||
214 | // hidden: true | ||
215 | // }, | ||
216 | // { | ||
217 | // path: 'list', | ||
218 | // component: () => import('@/views/example/list'), | ||
219 | // name: 'ArticleList', | ||
220 | // meta: { title: 'articleList', icon: 'list' } | ||
221 | // } | ||
222 | // ] | ||
223 | // }, | ||
224 | |||
205 | { | 225 | { |
206 | path: '/trade', | 226 | path: '/tab', |
207 | component: Layout, | 227 | component: Layout, |
208 | redirect: '/example/table', | 228 | children: [ |
209 | name: 'Trade', | ||
210 | meta: { | ||
211 | title: '交易管理', | ||
212 | icon: 'money' | ||
213 | }, | ||
214 | children: [{ | ||
215 | path: 'table', | ||
216 | name: 'Table', | ||
217 | component: () => import('@/views/table/index'), | ||
218 | meta: { | ||
219 | title: '成交清单', | ||
220 | icon: 'table' | ||
221 | } | ||
222 | }, | ||
223 | { | 229 | { |
224 | path: 'tree', | 230 | path: 'index', |
225 | name: 'Tree', | 231 | component: () => import('@/views/tab/index'), |
226 | component: () => import('@/views/tree/index'), | 232 | name: 'Tab', |
227 | meta: { | 233 | meta: { title: 'tab', icon: 'tab' } |
228 | title: '未成交清单', | ||
229 | icon: 'table' | ||
230 | } | ||
231 | } | 234 | } |
232 | ] | 235 | ] |
233 | }, { | 236 | }, |
234 | path: '/recommand', | 237 | |
235 | component: Layout, | 238 | // { |
236 | redirect: '/recommand/table', | 239 | // path: '/error', |
237 | name: 'Recommand', | 240 | // component: Layout, |
238 | meta: { | 241 | // redirect: 'noRedirect', |
239 | title: '推荐系统', | 242 | // name: 'ErrorPages', |
240 | icon: 'size' | 243 | // meta: { |
241 | }, | 244 | // title: 'errorPages', |
242 | children: [{ | 245 | // icon: '404' |
243 | path: 'table', | 246 | // }, |
244 | name: 'Table', | 247 | // children: [ |
245 | component: () => import('@/views/table/index'), | 248 | // { |
246 | meta: { | 249 | // path: '401', |
247 | title: '推荐系统教学', | 250 | // component: () => import('@/views/error-page/401'), |
248 | icon: 'table' | 251 | // name: 'Page401', |
249 | } | 252 | // meta: { title: 'page401', noCache: true } |
250 | }] | 253 | // }, |
251 | }, { | 254 | // { |
252 | path: '/system', | 255 | // path: '404', |
256 | // component: () => import('@/views/error-page/404'), | ||
257 | // name: 'Page404', | ||
258 | // meta: { title: 'page404', noCache: true } | ||
259 | // } | ||
260 | // ] | ||
261 | // }, | ||
262 | |||
263 | // { | ||
264 | // path: '/error-log', | ||
265 | // component: Layout, | ||
266 | // children: [ | ||
267 | // { | ||
268 | // path: 'log', | ||
269 | // component: () => import('@/views/error-log/index'), | ||
270 | // name: 'ErrorLog', | ||
271 | // meta: { title: 'errorLog', icon: 'bug' } | ||
272 | // } | ||
273 | // ] | ||
274 | // }, | ||
275 | |||
276 | // { | ||
277 | // path: '/excel', | ||
278 | // component: Layout, | ||
279 | // redirect: '/excel/export-excel', | ||
280 | // name: 'Excel', | ||
281 | // meta: { | ||
282 | // title: 'excel', | ||
283 | // icon: 'excel' | ||
284 | // }, | ||
285 | // children: [ | ||
286 | // { | ||
287 | // path: 'export-excel', | ||
288 | // component: () => import('@/views/excel/export-excel'), | ||
289 | // name: 'ExportExcel', | ||
290 | // meta: { title: 'exportExcel' } | ||
291 | // }, | ||
292 | // { | ||
293 | // path: 'export-selected-excel', | ||
294 | // component: () => import('@/views/excel/select-excel'), | ||
295 | // name: 'SelectExcel', | ||
296 | // meta: { title: 'selectExcel' } | ||
297 | // }, | ||
298 | // { | ||
299 | // path: 'export-merge-header', | ||
300 | // component: () => import('@/views/excel/merge-header'), | ||
301 | // name: 'MergeHeader', | ||
302 | // meta: { title: 'mergeHeader' } | ||
303 | // }, | ||
304 | // { | ||
305 | // path: 'upload-excel', | ||
306 | // component: () => import('@/views/excel/upload-excel'), | ||
307 | // name: 'UploadExcel', | ||
308 | // meta: { title: 'uploadExcel' } | ||
309 | // } | ||
310 | // ] | ||
311 | // }, | ||
312 | |||
313 | // { | ||
314 | // path: '/zip', |
src/router/modules/charts.js
File was created | 1 | /** When your routing table is too long, you can split it into small modules**/ | |
2 | |||
3 | import Layout from '@/layout' | ||
4 | |||
5 | const chartsRouter = { | ||
6 | path: '/charts', | ||
7 | component: Layout, | ||
8 | redirect: 'noRedirect', | ||
9 | name: 'Charts', | ||
10 | meta: { | ||
11 | title: 'charts', | ||
12 | icon: 'chart' | ||
13 | }, | ||
14 | children: [ | ||
15 | { | ||
16 | path: 'keyboard', | ||
17 | component: () => import('@/views/charts/keyboard'), | ||
18 | name: 'KeyboardChart', | ||
19 | meta: { title: 'keyboardChart', noCache: true } | ||
20 | }, | ||
21 | { | ||
22 | path: 'line', | ||
23 | component: () => import('@/views/charts/line'), | ||
24 | name: 'LineChart', | ||
25 | meta: { title: 'lineChart', noCache: true } | ||
26 | }, | ||
27 | { | ||
28 | path: 'mix-chart', | ||
29 | component: () => import('@/views/charts/mix-chart'), | ||
30 | name: 'MixChart', | ||
31 | meta: { title: 'mixChart', noCache: true } | ||
32 | } | ||
33 | ] | ||
34 | } | ||
35 | |||
36 | export default chartsRouter | ||
37 |
src/router/modules/components.js
File was created | 1 | /** When your routing table is too long, you can split it into small modules **/ | |
2 | |||
3 | import Layout from '@/layout' | ||
4 | |||
5 | const componentsRouter = { | ||
6 | path: '/components', | ||
7 | component: Layout, | ||
8 | redirect: 'noRedirect', | ||
9 | name: 'ComponentDemo', | ||
10 | meta: { | ||
11 | title: 'components', | ||
12 | icon: 'component' | ||
13 | }, | ||
14 | children: [ | ||
15 | { | ||
16 | path: 'tinymce', | ||
17 | component: () => import('@/views/components-demo/tinymce'), | ||
18 | name: 'TinymceDemo', | ||
19 | meta: { title: 'tinymce' } | ||
20 | }, | ||
21 | { | ||
22 | path: 'markdown', | ||
23 | component: () => import('@/views/components-demo/markdown'), | ||
24 | name: 'MarkdownDemo', | ||
25 | meta: { title: 'markdown' } | ||
26 | }, | ||
27 | { | ||
28 | path: 'json-editor', | ||
29 | component: () => import('@/views/components-demo/json-editor'), | ||
30 | name: 'JsonEditorDemo', | ||
31 | meta: { title: 'jsonEditor' } | ||
32 | }, | ||
33 | { | ||
34 | path: 'split-pane', | ||
35 | component: () => import('@/views/components-demo/split-pane'), | ||
36 | name: 'SplitpaneDemo', | ||
37 | meta: { title: 'splitPane' } | ||
38 | }, | ||
39 | { | ||
40 | path: 'avatar-upload', | ||
41 | component: () => import('@/views/components-demo/avatar-upload'), | ||
42 | name: 'AvatarUploadDemo', | ||
43 | meta: { title: 'avatarUpload' } | ||
44 | }, | ||
45 | { | ||
46 | path: 'dropzone', | ||
47 | component: () => import('@/views/components-demo/dropzone'), | ||
48 | name: 'DropzoneDemo', | ||
49 | meta: { title: 'dropzone' } | ||
50 | }, | ||
51 | { | ||
52 | path: 'sticky', | ||
53 | component: () => import('@/views/components-demo/sticky'), | ||
54 | name: 'StickyDemo', | ||
55 | meta: { title: 'sticky' } | ||
56 | }, | ||
57 | { | ||
58 | path: 'count-to', | ||
59 | component: () => import('@/views/components-demo/count-to'), | ||
60 | name: 'CountToDemo', | ||
61 | meta: { title: 'countTo' } | ||
62 | }, | ||
63 | { | ||
64 | path: 'mixin', | ||
65 | component: () => import('@/views/components-demo/mixin'), | ||
66 | name: 'ComponentMixinDemo', | ||
67 | meta: { title: 'componentMixin' } | ||
68 | }, | ||
69 | { | ||
70 | path: 'back-to-top', | ||
71 | component: () => import('@/views/components-demo/back-to-top'), | ||
72 | name: 'BackToTopDemo', | ||
73 | meta: { title: 'backToTop' } | ||
74 | }, | ||
75 | { | ||
76 | path: 'drag-dialog', | ||
77 | component: () => import('@/views/components-demo/drag-dialog'), | ||
78 | name: 'DragDialogDemo', | ||
79 | meta: { title: 'dragDialog' } | ||
80 | }, | ||
81 | { | ||
82 | path: 'drag-select', | ||
83 | component: () => import('@/views/components-demo/drag-select'), | ||
84 | name: 'DragSelectDemo', | ||
85 | meta: { title: 'dragSelect' } | ||
86 | }, | ||
87 | { | ||
88 | path: 'dnd-list', | ||
89 | component: () => import('@/views/components-demo/dnd-list'), | ||
90 | name: 'DndListDemo', | ||
91 | meta: { title: 'dndList' } | ||
92 | }, | ||
93 | { | ||
94 | path: 'drag-kanban', | ||
95 | component: () => import('@/views/components-demo/drag-kanban'), | ||
96 | name: 'DragKanbanDemo', | ||
97 | meta: { title: 'dragKanban' } | ||
98 | } | ||
99 | ] | ||
100 | } | ||
101 | |||
102 | export default componentsRouter | ||
103 |
src/router/modules/nested.js
File was created | 1 | /** When your routing table is too long, you can split it into small modules **/ | |
2 | |||
3 | import Layout from '@/layout' | ||
4 | |||
5 | const nestedRouter = { | ||
6 | path: '/nested', | ||
7 | component: Layout, | ||
8 | redirect: '/nested/menu1/menu1-1', | ||
9 | name: 'Nested', | ||
10 | meta: { | ||
11 | title: 'nested', | ||
12 | icon: 'nested' | ||
13 | }, | ||
14 | children: [ | ||
15 | { | ||
16 | path: 'menu1', | ||
17 | component: () => import('@/views/nested/menu1/index'), // Parent router-view | ||
18 | name: 'Menu1', | ||
19 | meta: { title: 'menu1' }, | ||
20 | redirect: '/nested/menu1/menu1-1', | ||
21 | children: [ | ||
22 | { | ||
23 | path: 'menu1-1', | ||
24 | component: () => import('@/views/nested/menu1/menu1-1'), | ||
25 | name: 'Menu1-1', | ||
26 | meta: { title: 'menu1-1' } | ||
27 | }, | ||
28 | { | ||
29 | path: 'menu1-2', | ||
30 | component: () => import('@/views/nested/menu1/menu1-2'), | ||
31 | name: 'Menu1-2', | ||
32 | redirect: '/nested/menu1/menu1-2/menu1-2-1', | ||
33 | meta: { title: 'menu1-2' }, | ||
34 | children: [ | ||
35 | { | ||
36 | path: 'menu1-2-1', | ||
37 | component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'), | ||
38 | name: 'Menu1-2-1', | ||
39 | meta: { title: 'menu1-2-1' } | ||
40 | }, | ||
41 | { | ||
42 | path: 'menu1-2-2', | ||
43 | component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'), | ||
44 | name: 'Menu1-2-2', | ||
45 | meta: { title: 'menu1-2-2' } | ||
46 | } | ||
47 | ] | ||
48 | }, | ||
49 | { | ||
50 | path: 'menu1-3', | ||
51 | component: () => import('@/views/nested/menu1/menu1-3'), | ||
52 | name: 'Menu1-3', | ||
53 | meta: { title: 'menu1-3' } | ||
54 | } | ||
55 | ] | ||
56 | }, | ||
57 | { | ||
58 | path: 'menu2', | ||
59 | name: 'Menu2', | ||
60 | component: () => import('@/views/nested/menu2/index'), | ||
61 | meta: { title: 'menu2' } | ||
62 | } | ||
63 | ] | ||
64 | } | ||
65 | |||
66 | export default nestedRouter | ||
67 |
src/router/modules/table.js
File was created | 1 | /** When your routing table is too long, you can split it into small modules **/ | |
2 | |||
3 | import Layout from '@/layout' | ||
4 | |||
5 | const tableRouter = { | ||
6 | path: '/table', | ||
7 | component: Layout, | ||
8 | redirect: '/table/complex-table', | ||
9 | name: 'Table', | ||
10 | meta: { | ||
11 | title: 'Table', | ||
12 | icon: 'table' | ||
13 | }, | ||
14 | children: [ | ||
15 | { | ||
16 | path: 'dynamic-table', | ||
17 | component: () => import('@/views/table/dynamic-table/index'), | ||
18 | name: 'DynamicTable', | ||
19 | meta: { title: 'dynamicTable' } | ||
20 | }, | ||
21 | { | ||
22 | path: 'drag-table', | ||
23 | component: () => import('@/views/table/drag-table'), | ||
24 | name: 'DragTable', | ||
25 | meta: { title: 'dragTable' } | ||
26 | }, | ||
27 | { | ||
28 | path: 'inline-edit-table', | ||
29 | component: () => import('@/views/table/inline-edit-table'), | ||
30 | name: 'InlineEditTable', | ||
31 | meta: { title: 'inlineEditTable' } | ||
32 | }, | ||
33 | { | ||
34 | path: 'complex-table', | ||
35 | component: () => import('@/views/table/complex-table'), | ||
36 | name: 'ComplexTable', | ||
37 | meta: { title: 'complexTable' } | ||
38 | } | ||
39 | ] | ||
40 | } | ||
41 | export default tableRouter | ||
42 |
src/settings.js
1 | module.exports = { | 1 | module.exports = { |
2 | title: 'Vue Element Admin', | ||
2 | 3 | ||
3 | title: '鱼皮出海', | 4 | /** |
5 | * @type {boolean} true | false | ||
6 | * @description Whether show the settings right-panel | ||
7 | */ | ||
8 | showSettings: true, | ||
9 | |||
10 | /** | ||
11 | * @type {boolean} true | false | ||
12 | * @description Whether need tagsView | ||
13 | */ | ||
14 | tagsView: true, | ||
4 | 15 | ||
5 | /** | 16 | /** |
6 | * @type {boolean} true | false | 17 | * @type {boolean} true | false |
7 | * @description Whether fix the header | 18 | * @description Whether fix the header |
8 | */ | 19 | */ |
9 | fixedHeader: true, | 20 | fixedHeader: false, |
10 | 21 | ||
11 | /** | 22 | /** |
12 | * @type {boolean} true | false | 23 | * @type {boolean} true | false |
13 | * @description Whether show the logo in sidebar | 24 | * @description Whether show the logo in sidebar |
14 | */ | 25 | */ |
15 | sidebarLogo: true | 26 | sidebarLogo: false, |
27 | |||
28 | /** | ||
29 | * @type {boolean} true | false | ||
30 | * @description Whether support pinyin search in headerSearch | ||
31 | * Bundle size minified 47.3kb,minified + gzipped 63kb | ||
32 | */ | ||
33 | supportPinyinSearch: true, | ||
34 | |||
35 | /** | ||
36 | * @type {string | array} 'production' | ['production', 'development'] | ||
37 | * @description Need show err logs component. | ||
38 | * The default is only used in the production env | ||
39 | * If you want to also use it in dev, you can pass ['production', 'development'] | ||
40 | */ | ||
41 | errorLog: 'production' | ||
16 | } | 42 | } |
17 | 43 |
src/store/getters.js
1 | const getters = { | 1 | const getters = { |
2 | sidebar: state => state.app.sidebar, | 2 | sidebar: state => state.app.sidebar, |
3 | language: state => state.app.language, | ||
4 | size: state => state.app.size, | ||
3 | device: state => state.app.device, | 5 | device: state => state.app.device, |
6 | visitedViews: state => state.tagsView.visitedViews, | ||
7 | cachedViews: state => state.tagsView.cachedViews, | ||
4 | token: state => state.user.token, | 8 | token: state => state.user.token, |
5 | avatar: state => state.user.avatar, | 9 | avatar: state => state.user.avatar, |
6 | name: state => state.user.name, | 10 | name: state => state.user.name, |
11 | introduction: state => state.user.introduction, | ||
7 | roles: state => state.user.roles, | 12 | roles: state => state.user.roles, |
8 | permission_routes: state => state.permission.routes | 13 | permission_routes: state => state.permission.routes, |
14 | errorLogs: state => state.errorLog.logs | ||
9 | } | 15 | } |
10 | export default getters | 16 | export default getters |
11 | 17 |
src/store/index.js
1 | import Vue from 'vue' | 1 | import Vue from 'vue' |
2 | import Vuex from 'vuex' | 2 | import Vuex from 'vuex' |
3 | import getters from './getters' | 3 | import getters from './getters' |
4 | import app from './modules/app' | ||
5 | import permission from './modules/permission' | ||
6 | import settings from './modules/settings' | ||
7 | import user from './modules/user' | ||
8 | 4 | ||
9 | Vue.use(Vuex) | 5 | Vue.use(Vuex) |
10 | 6 | ||
7 | // https://webpack.js.org/guides/dependency-management/#requirecontext | ||
8 | const modulesFiles = require.context('./modules', true, /\.js$/) | ||
9 | |||
10 | // you do not need `import app from './modules/app'` | ||
11 | // it will auto require all vuex module from modules file | ||
12 | const modules = modulesFiles.keys().reduce((modules, modulePath) => { | ||
13 | // set './app.js' => 'app' | ||
14 | const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1') | ||
15 | const value = modulesFiles(modulePath) | ||
16 | modules[moduleName] = value.default | ||
17 | return modules | ||
18 | }, {}) | ||
19 | |||
11 | const store = new Vuex.Store({ | 20 | const store = new Vuex.Store({ |
12 | modules: { | 21 | modules, |
13 | app, |
src/store/modules/app.js
1 | import Cookies from 'js-cookie' | 1 | import Cookies from 'js-cookie' |
2 | import { getLanguage } from '@/lang/index' | ||
2 | 3 | ||
3 | //state | ||
4 | const state = { | 4 | const state = { |
5 | sidebar: { | 5 | sidebar: { |
6 | opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true, | 6 | opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true, |
7 | withoutAnimation: false | 7 | withoutAnimation: false |
8 | }, | 8 | }, |
9 | device: 'desktop' | 9 | device: 'desktop', |
10 | language: getLanguage(), | ||
11 | size: Cookies.get('size') || 'medium' | ||
10 | } | 12 | } |
11 | 13 | ||
12 | //mutations | ||
13 | const mutations = { | 14 | const mutations = { |
14 | TOGGLE_SIDEBAR: state => { | 15 | TOGGLE_SIDEBAR: state => { |
15 | state.sidebar.opened = !state.sidebar.opened | 16 | state.sidebar.opened = !state.sidebar.opened |
16 | state.sidebar.withoutAnimation = false | 17 | state.sidebar.withoutAnimation = false |
17 | if (state.sidebar.opened) { | 18 | if (state.sidebar.opened) { |
18 | Cookies.set('sidebarStatus', 1) | 19 | Cookies.set('sidebarStatus', 1) |
19 | } else { | 20 | } else { |
20 | Cookies.set('sidebarStatus', 0) | 21 | Cookies.set('sidebarStatus', 0) |
21 | } | 22 | } |
22 | }, | 23 | }, |
23 | CLOSE_SIDEBAR: (state, withoutAnimation) => { | 24 | CLOSE_SIDEBAR: (state, withoutAnimation) => { |
24 | Cookies.set('sidebarStatus', 0) | 25 | Cookies.set('sidebarStatus', 0) |
25 | state.sidebar.opened = false | 26 | state.sidebar.opened = false |
26 | state.sidebar.withoutAnimation = withoutAnimation | 27 | state.sidebar.withoutAnimation = withoutAnimation |
27 | }, | 28 | }, |
28 | TOGGLE_DEVICE: (state, device) => { | 29 | TOGGLE_DEVICE: (state, device) => { |
29 | state.device = device | 30 | state.device = device |
31 | }, | ||
32 | SET_LANGUAGE: (state, language) => { | ||
33 | state.language = language | ||
34 | Cookies.set('language', language) | ||
35 | }, | ||
36 | SET_SIZE: (state, size) => { | ||
37 | state.size = size | ||
38 | Cookies.set('size', size) | ||
30 | } | 39 | } |
31 | } | 40 | } |
32 | 41 | ||
33 | //actions | ||
34 | const actions = { | 42 | const actions = { |
35 | toggleSideBar({ commit }) { | 43 | toggleSideBar({ commit }) { |
36 | commit('TOGGLE_SIDEBAR') | 44 | commit('TOGGLE_SIDEBAR') |
37 | }, | 45 | }, |
38 | closeSideBar({ commit }, { withoutAnimation }) { | 46 | closeSideBar({ commit }, { withoutAnimation }) { |
39 | commit('CLOSE_SIDEBAR', withoutAnimation) | 47 | commit('CLOSE_SIDEBAR', withoutAnimation) |
40 | }, | 48 | }, |
41 | toggleDevice({ commit }, device) { | 49 | toggleDevice({ commit }, device) { |
42 | commit('TOGGLE_DEVICE', device) | 50 | commit('TOGGLE_DEVICE', device) |
51 | }, | ||
52 | setLanguage({ commit }, language) { | ||
53 | commit('SET_LANGUAGE', language) | ||
54 | }, | ||
55 | setSize({ commit }, size) { | ||
56 | commit('SET_SIZE', size) | ||
43 | } | 57 | } |
44 | } | 58 | } |
45 | 59 | ||
46 | export default { | 60 | export default { |
47 | namespaced: true, | 61 | namespaced: true, |
48 | state, | 62 | state, |
49 | mutations, | 63 | mutations, |
src/store/modules/errorLog.js
File was created | 1 | const state = { | |
2 | logs: [] | ||
3 | } | ||
4 | |||
5 | const mutations = { | ||
6 | ADD_ERROR_LOG: (state, log) => { | ||
7 | state.logs.push(log) | ||
8 | }, | ||
9 | CLEAR_ERROR_LOG: (state) => { | ||
10 | state.logs.splice(0) | ||
11 | } | ||
12 | } | ||
13 | |||
14 | const actions = { | ||
15 | addErrorLog({ commit }, log) { | ||
16 | commit('ADD_ERROR_LOG', log) | ||
17 | }, | ||
18 | clearErrorLog({ commit }) { | ||
19 | commit('CLEAR_ERROR_LOG') | ||
20 | } | ||
21 | } | ||
22 | |||
23 | export default { | ||
24 | namespaced: true, | ||
25 | state, | ||
26 | mutations, | ||
27 | actions | ||
28 | } | ||
29 |
src/store/modules/permission.js
1 | import { asyncRoutes, constantRoutes } from '@/router' | 1 | import { asyncRoutes, constantRoutes } from '@/router' |
2 | 2 | ||
3 | /** | 3 | /** |
4 | * Use meta.role to determine if the current user has permission | 4 | * Use meta.role to determine if the current user has permission |
5 | * @param roles | 5 | * @param roles |
6 | * @param route | 6 | * @param route |
7 | */ | 7 | */ |
8 | function hasPermission(roles, route) { | 8 | function hasPermission(roles, route) { |
9 | if (route.meta && route.meta.roles) { | 9 | if (route.meta && route.meta.roles) { |
10 | return roles.some(role => route.meta.roles.includes(role)) | 10 | return roles.some(role => route.meta.roles.includes(role)) |
11 | } else { | 11 | } else { |
12 | return true | 12 | return true |
13 | } | 13 | } |
14 | } | 14 | } |
15 | 15 | ||
16 | /** | 16 | /** |
17 | * Filter asynchronous routing tables by recursion | 17 | * Filter asynchronous routing tables by recursion |
18 | * @param routes asyncRoutes | 18 | * @param routes asyncRoutes |
19 | * @param roles | 19 | * @param roles |
20 | */ | 20 | */ |
21 | export function filterAsyncRoutes(routes, roles) { | 21 | export function filterAsyncRoutes(routes, roles) { |
22 | const res = [] | 22 | const res = [] |
23 | |||
23 | routes.forEach(route => { | 24 | routes.forEach(route => { |
24 | const tmp = { ...route } | 25 | const tmp = { ...route } |
25 | if (hasPermission(roles, tmp)) { | 26 | if (hasPermission(roles, tmp)) { |
26 | if (tmp.children) { | 27 | if (tmp.children) { |
27 | tmp.children = filterAsyncRoutes(tmp.children, roles) | 28 | tmp.children = filterAsyncRoutes(tmp.children, roles) |
28 | } | 29 | } |
29 | res.push(tmp) | 30 | res.push(tmp) |
30 | } | 31 | } |
31 | }) | 32 | }) |
32 | 33 | ||
33 | return res | 34 | return res |
34 | } | 35 | } |
35 | 36 | ||
36 | const state = { | 37 | const state = { |
37 | routes: [], | 38 | routes: [], |
38 | addRoutes: [] | 39 | addRoutes: [] |
39 | } | 40 | } |
40 | 41 | ||
41 | const mutations = { | 42 | const mutations = { |
42 | SET_ROUTES: (state, routes) => { | 43 | SET_ROUTES: (state, routes) => { |
43 | state.addRoutes = routes | 44 | state.addRoutes = routes |
44 | state.routes = constantRoutes.concat(routes) | 45 | state.routes = constantRoutes.concat(routes) |
45 | } | 46 | } |
46 | } | 47 | } |
47 | //根据动作进行判断 | 48 | |
48 | const actions = { | 49 | const actions = { |
49 | generateRoutes({ commit }, roles) { | 50 | generateRoutes({ commit }, roles) { |
50 | return new Promise(resolve => { | 51 | return new Promise(resolve => { |
51 | let accessedRoutes | 52 | let accessedRoutes |
52 | if (roles.includes('admin')) { | 53 | if (roles.includes('admin')) { |
53 | console.log('------------generateRoutes----asyncRoutes-----------', asyncRoutes, roles); | ||
54 | accessedRoutes = asyncRoutes || [] | 54 | accessedRoutes = asyncRoutes || [] |
55 | } else { | 55 | } else { |
56 | accessedRoutes = filterAsyncRoutes(asyncRoutes, roles) | 56 | accessedRoutes = filterAsyncRoutes(asyncRoutes, roles) |
57 | accessedRoutes.push({}); | ||
58 | } | 57 | } |
59 | commit('SET_ROUTES', accessedRoutes) | 58 | commit('SET_ROUTES', accessedRoutes) |
60 | resolve(accessedRoutes) | 59 | resolve(accessedRoutes) |
61 | }) | 60 | }) |
62 | } | 61 | } |
63 | } | 62 | } |
64 | 63 | ||
65 | export default { | 64 | export default { |
66 | namespaced: true, | 65 | namespaced: true, |
67 | state, | 66 | state, |
68 | mutations, | 67 | mutations, |
69 | actions | 68 | actions |
70 | } | 69 | } |
src/store/modules/settings.js
1 | import variables from '@/styles/element-variables.scss' | ||
1 | import defaultSettings from '@/settings' | 2 | import defaultSettings from '@/settings' |
2 | 3 | ||
3 | const { showSettings, fixedHeader, sidebarLogo } = defaultSettings | 4 | const { showSettings, tagsView, fixedHeader, sidebarLogo, supportPinyinSearch } = defaultSettings |
4 | 5 | ||
5 | const state = { | 6 | const state = { |
6 | showSettings: showSettings, | 7 | theme: variables.theme, |
7 | fixedHeader: fixedHeader, | 8 | showSettings, |
8 | sidebarLogo: sidebarLogo | 9 | tagsView, |
10 | fixedHeader, | ||
11 | sidebarLogo, | ||
12 | supportPinyinSearch | ||
9 | } | 13 | } |
10 | 14 | ||
11 | const mutations = { | 15 | const mutations = { |
12 | CHANGE_SETTING: (state, { key, value }) => { | 16 | CHANGE_SETTING: (state, { key, value }) => { |
13 | if (state.hasOwnProperty(key)) { | 17 | if (state.hasOwnProperty(key)) { |
14 | state[key] = value | 18 | state[key] = value |
15 | } | 19 | } |
16 | } | 20 | } |
17 | } | 21 | } |
18 | 22 | ||
19 | const actions = { | 23 | const actions = { |
20 | changeSetting({ commit }, data) { | 24 | changeSetting({ commit }, data) { |
21 | commit('CHANGE_SETTING', data) | 25 | commit('CHANGE_SETTING', data) |
22 | } | 26 | } |
23 | } | 27 | } |
24 | 28 | ||
25 | export default { | 29 | export default { |
26 | namespaced: true, | 30 | namespaced: true, |
27 | state, | 31 | state, |
28 | mutations, | 32 | mutations, |
29 | actions | 33 | actions |
30 | } | 34 | } |
31 | 35 | ||
32 | 36 |
src/store/modules/tagsView.js
File was created | 1 | const state = { | |
2 | visitedViews: [], | ||
3 | cachedViews: [] | ||
4 | } | ||
5 | |||
6 | const mutations = { | ||
7 | ADD_VISITED_VIEW: (state, view) => { | ||
8 | if (state.visitedViews.some(v => v.path === view.path)) return | ||
9 | state.visitedViews.push( | ||
10 | Object.assign({}, view, { | ||
11 | title: view.meta.title || 'no-name' | ||
12 | }) | ||
13 | ) | ||
14 | }, | ||
15 | ADD_CACHED_VIEW: (state, view) => { | ||
16 | if (state.cachedViews.includes(view.name)) return | ||
17 | if (!view.meta.noCache) { | ||
18 | state.cachedViews.push(view.name) | ||
19 | } | ||
20 | }, | ||
21 | |||
22 | DEL_VISITED_VIEW: (state, view) => { | ||
23 | for (const [i, v] of state.visitedViews.entries()) { | ||
24 | if (v.path === view.path) { | ||
25 | state.visitedViews.splice(i, 1) | ||
26 | break | ||
27 | } | ||
28 | } | ||
29 | }, | ||
30 | DEL_CACHED_VIEW: (state, view) => { | ||
31 | const index = state.cachedViews.indexOf(view.name) | ||
32 | index > -1 && state.cachedViews.splice(index, 1) | ||
33 | }, | ||
34 | |||
35 | DEL_OTHERS_VISITED_VIEWS: (state, view) => { | ||
36 | state.visitedViews = state.visitedViews.filter(v => { | ||
37 | return v.meta.affix || v.path === view.path | ||
38 | }) | ||
39 | }, | ||
40 | DEL_OTHERS_CACHED_VIEWS: (state, view) => { | ||
41 | const index = state.cachedViews.indexOf(view.name) | ||
42 | if (index > -1) { | ||
43 | state.cachedViews = state.cachedViews.slice(index, index + 1) | ||
44 | } else { | ||
45 | // if index = -1, there is no cached tags | ||
46 | state.cachedViews = [] | ||
47 | } | ||
48 | }, | ||
49 | |||
50 | DEL_ALL_VISITED_VIEWS: state => { | ||
51 | // keep affix tags | ||
52 | const affixTags = state.visitedViews.filter(tag => tag.meta.affix) | ||
53 | state.visitedViews = affixTags | ||
54 | }, | ||
55 | DEL_ALL_CACHED_VIEWS: state => { | ||
56 | state.cachedViews = [] | ||
57 | }, | ||
58 | |||
59 | UPDATE_VISITED_VIEW: (state, view) => { | ||
60 | for (let v of state.visitedViews) { | ||
61 | if (v.path === view.path) { | ||
62 | v = Object.assign(v, view) | ||
63 | break | ||
64 | } | ||
65 | } | ||
66 | } | ||
67 | } | ||
68 | |||
69 | const actions = { | ||
70 | addView({ dispatch }, view) { | ||
71 | dispatch('addVisitedView', view) | ||
72 | dispatch('addCachedView', view) | ||
73 | }, | ||
74 | addVisitedView({ commit }, view) { | ||
75 | commit('ADD_VISITED_VIEW', view) | ||
76 | }, | ||
77 | addCachedView({ commit }, view) { | ||
78 | commit('ADD_CACHED_VIEW', view) | ||
79 | }, | ||
80 | |||
81 | delView({ dispatch, state }, view) { | ||
82 | return new Promise(resolve => { | ||
83 | dispatch('delVisitedView', view) | ||
84 | dispatch('delCachedView', view) | ||
85 | resolve({ | ||
86 | visitedViews: [...state.visitedViews], | ||
87 | cachedViews: [...state.cachedViews] | ||
88 | }) | ||
89 | }) | ||
90 | }, | ||
91 | delVisitedView({ commit, state }, view) { | ||
92 | return new Promise(resolve => { | ||
93 | commit('DEL_VISITED_VIEW', view) | ||
94 | resolve([...state.visitedViews]) | ||
95 | }) | ||
96 | }, | ||
97 | delCachedView({ commit, state }, view) { | ||
98 | return new Promise(resolve => { | ||
99 | commit('DEL_CACHED_VIEW', view) | ||
100 | resolve([...state.cachedViews]) | ||
101 | }) | ||
102 | }, | ||
103 | |||
104 | delOthersViews({ dispatch, state }, view) { | ||
105 | return new Promise(resolve => { | ||
106 | dispatch('delOthersVisitedViews', view) | ||
107 | dispatch('delOthersCachedViews', view) | ||
108 | resolve({ | ||
109 | visitedViews: [...state.visitedViews], | ||
110 | cachedViews: [...state.cachedViews] | ||
111 | }) | ||
112 | }) | ||
113 | }, | ||
114 | delOthersVisitedViews({ commit, state }, view) { | ||
115 | return new Promise(resolve => { | ||
116 | commit('DEL_OTHERS_VISITED_VIEWS', view) | ||
117 | resolve([...state.visitedViews]) | ||
118 | }) | ||
119 | }, | ||
120 | delOthersCachedViews({ commit, state }, view) { | ||
121 | return new Promise(resolve => { | ||
122 | commit('DEL_OTHERS_CACHED_VIEWS', view) | ||
123 | resolve([...state.cachedViews]) | ||
124 | }) | ||
125 | }, | ||
126 | |||
127 | delAllViews({ dispatch, state }, view) { | ||
128 | return new Promise(resolve => { | ||
129 | dispatch('delAllVisitedViews', view) | ||
130 | dispatch('delAllCachedViews', view) | ||
131 | resolve({ | ||
132 | visitedViews: [...state.visitedViews], | ||
133 | cachedViews: [...state.cachedViews] | ||
134 | }) | ||
135 | }) | ||
136 | }, | ||
137 | delAllVisitedViews({ commit, state }) { | ||
138 | return new Promise(resolve => { | ||
139 | commit('DEL_ALL_VISITED_VIEWS') | ||
140 | resolve([...state.visitedViews]) | ||
141 | }) | ||
142 | }, | ||
143 | delAllCachedViews({ commit, state }) { | ||
144 | return new Promise(resolve => { | ||
145 | commit('DEL_ALL_CACHED_VIEWS') | ||
146 | resolve([...state.cachedViews]) | ||
147 | }) | ||
148 | }, | ||
149 | |||
150 | updateVisitedView({ commit }, view) { | ||
151 | commit('UPDATE_VISITED_VIEW', view) | ||
152 | } | ||
153 | } | ||
154 | |||
155 | export default { | ||
156 | namespaced: true, | ||
157 | state, | ||
158 | mutations, | ||
159 | actions | ||
160 | } | ||
161 |
src/store/modules/user.js
1 | import { | 1 | import { login, logout, getInfo } from '@/api/user' |
2 | login, | 2 | import { getToken, setToken, removeToken } from '@/utils/auth' |
3 | logout, | 3 | import router, { resetRouter } from '@/router' |
4 | getInfo | ||
5 | } from '@/api/user' | ||
6 | import { | ||
7 | getToken, | ||
8 | setToken, | ||
9 | removeToken | ||
10 | } from '@/utils/auth' | ||
11 | import { | ||
12 | resetRouter | ||
13 | } from '@/router' | ||
14 | |||
15 | const getDefaultState = () => { | ||
16 | return { | ||
17 | token: getToken(), | ||
18 | name: '', | ||
19 | avatar: '', | ||
20 | roles: [] | ||
21 | } | ||
22 | } | ||
23 | 4 | ||
24 | const state = getDefaultState() | 5 | const state = { |
6 | token: getToken(), | ||
7 | name: '', | ||
8 | avatar: '', | ||
9 | introduction: '', | ||
10 | roles: [] | ||
11 | } | ||
25 | 12 | ||
26 | const mutations = { | 13 | const mutations = { |
27 | RESET_STATE: (state) => { | ||
28 | Object.assign(state, getDefaultState()) | ||
29 | }, | ||
30 | SET_TOKEN: (state, token) => { | 14 | SET_TOKEN: (state, token) => { |
31 | state.token = token | 15 | state.token = token |
32 | }, | 16 | }, |
17 | SET_INTRODUCTION: (state, introduction) => { | ||
18 | state.introduction = introduction | ||
19 | }, | ||
33 | SET_NAME: (state, name) => { | 20 | SET_NAME: (state, name) => { |
34 | state.name = name | 21 | state.name = name |
35 | }, | 22 | }, |
36 | SET_AVATAR: (state, avatar) => { | 23 | SET_AVATAR: (state, avatar) => { |
37 | state.avatar = avatar | 24 | state.avatar = avatar |
38 | }, | 25 | }, |
39 | SET_ROLES: (state, roles) => { | 26 | SET_ROLES: (state, roles) => { |
40 | state.roles = roles | 27 | state.roles = roles |
41 | } | 28 | } |
42 | } | 29 | } |
43 | 30 | ||
44 | const actions = { | 31 | const actions = { |
45 | // user login | 32 | // user login |
46 | login({ | 33 | login({ commit }, userInfo) { |
47 | commit | 34 | const { username, password } = userInfo |
48 | }, userInfo) { | ||
49 | const { | ||
50 | username, | ||
51 | password | ||
52 | } = userInfo | ||
53 | return new Promise((resolve, reject) => { | 35 | return new Promise((resolve, reject) => { |
54 | login({ | 36 | login({ username: username.trim(), password: password }).then(response => { |
55 | username: username.trim(), | 37 | const { data } = response |
56 | password: password | 38 | commit('SET_TOKEN', data.token) |
57 | }).then(response => { | 39 | setToken(data.token) |
58 | console.log('返回的数据-- step 3------>', response); | ||
59 | // const { token, name, id, password } = response | ||
60 | const { | ||
61 | token, | ||
62 | name | ||
63 | } = response | ||
64 | console.log('返回的数据-- step 4------>', response); | ||
65 | commit('SET_TOKEN', token) | ||
66 | setToken(token) | ||
67 | resolve() | 40 | resolve() |
68 | }).catch(error => { | 41 | }).catch(error => { |
69 | console.log('返回的数据-- step 4.1------>', error); | ||
70 | reject(error) | 42 | reject(error) |
71 | }) | 43 | }) |
72 | }) | 44 | }) |
73 | }, | 45 | }, |
74 | 46 | ||
75 | // get user info | 47 | // get user info |
76 | getInfo({ | 48 | getInfo({ commit, state }) { |
77 | commit, | ||
78 | state | ||
79 | }) { | ||
80 | return new Promise((resolve, reject) => { | 49 | return new Promise((resolve, reject) => { |
81 | getInfo(state.token).then(response => { | 50 | getInfo(state.token).then(response => { |
82 | console.log('返回的数据-- step 5------>', state); | 51 | const { data } = response |
83 | console.log('返回的数据-- step 5.1------>', response); | 52 | |
84 | const { | 53 | if (!data) { |
85 | avatar, | ||
86 | id, | ||
87 | name, | ||
88 | password, | ||
89 | roles, | ||
90 | token | ||
91 | } = response | ||
92 | if (!roles) { | ||
93 | reject('Verification failed, please Login again.') | 54 | reject('Verification failed, please Login again.') |
94 | } | 55 | } |
95 | console.error('返回的数据-- step 5.2------>', response); | 56 | |
57 | const { roles, name, avatar, introduction } = data | ||
58 | |||
96 | // roles must be a non-empty array | 59 | // roles must be a non-empty array |
97 | if (!roles || roles.length <= 0) { | 60 | if (!roles || roles.length <= 0) { |
98 | reject('getInfo: roles must be a non-null array!') | 61 | reject('getInfo: roles must be a non-null array!') |
99 | } | 62 | } |
63 | |||
100 | commit('SET_ROLES', roles) | 64 | commit('SET_ROLES', roles) |
101 | commit('SET_NAME', name) | 65 | commit('SET_NAME', name) |
102 | commit('SET_AVATAR', avatar) | 66 | commit('SET_AVATAR', avatar) |
103 | resolve(response) | 67 | commit('SET_INTRODUCTION', introduction) |
68 | resolve(data) | ||
104 | }).catch(error => { | 69 | }).catch(error => { |
105 | console.log('返回的数据-- step 5.3------>', error); | ||
106 | reject(error) | 70 | reject(error) |
107 | }) | 71 | }) |
108 | }) | 72 | }) |
109 | }, | 73 | }, |
110 | 74 | ||
111 | // user logout | 75 | // user logout |
112 | logout({ | 76 | logout({ commit, state, dispatch }) { |
113 | commit, | ||
114 | state | ||
115 | }) { | ||
116 | return new Promise((resolve, reject) => { | 77 | return new Promise((resolve, reject) => { |
117 | logout(state.token).then(() => { | 78 | logout(state.token).then(() => { |
118 | removeToken() // must remove token first | 79 | commit('SET_TOKEN', '') |
80 | commit('SET_ROLES', []) | ||
81 | removeToken() | ||
119 | resetRouter() | 82 | resetRouter() |
120 | commit('RESET_STATE') | 83 | |
84 | // reset visited views and cached views | ||
85 | // to fixed https://github.com/PanJiaChen/vue-element-admin/issues/2485 | ||
86 | dispatch('tagsView/delAllViews', null, { root: true }) | ||
87 | |||
121 | resolve() | 88 | resolve() |
122 | }).catch(error => { | 89 | }).catch(error => { |
123 | reject(error) | 90 | reject(error) |
124 | }) | 91 | }) |
125 | }) | 92 | }) |
126 | }, | 93 | }, |
127 | 94 |
src/styles/btn.scss
File was created | 1 | @import './variables.scss'; | |
2 | |||
3 | @mixin colorBtn($color) { | ||
4 | background: $color; | ||
5 | |||
6 | &:hover { | ||
7 | color: $color; | ||
8 | |||
9 | &:before, | ||
10 | &:after { | ||
11 | background: $color; | ||
12 | } | ||
13 | } | ||
14 | } | ||
15 | |||
16 | .blue-btn { | ||
17 | @include colorBtn($blue) | ||
18 | } | ||
19 | |||
20 | .light-blue-btn { | ||
21 | @include colorBtn($light-blue) | ||
22 | } | ||
23 | |||
24 | .red-btn { | ||
25 | @include colorBtn($red) | ||
26 | } | ||
27 | |||
28 | .pink-btn { | ||
29 | @include colorBtn($pink) | ||
30 | } | ||
31 | |||
32 | .green-btn { | ||
33 | @include colorBtn($green) | ||
34 | } | ||
35 | |||
36 | .tiffany-btn { | ||
37 | @include colorBtn($tiffany) | ||
38 | } | ||
39 | |||
40 | .yellow-btn { | ||
41 | @include colorBtn($yellow) | ||
42 | } | ||
43 | |||
44 | .pan-btn { | ||
45 | font-size: 14px; | ||
46 | color: #fff; | ||
47 | padding: 14px 36px; | ||
48 | border-radius: 8px; | ||
49 | border: none; | ||
50 | outline: none; | ||
51 | transition: 600ms ease all; | ||
52 | position: relative; | ||
53 | display: inline-block; | ||
54 | |||
55 | &:hover { | ||
56 | background: #fff; | ||
57 | |||
58 | &:before, | ||
59 | &:after { | ||
60 | width: 100%; | ||
61 | transition: 600ms ease all; | ||
62 | } | ||
63 | } | ||
64 | |||
65 | &:before, | ||
66 | &:after { | ||
67 | content: ''; | ||
68 | position: absolute; | ||
69 | top: 0; | ||
70 | right: 0; | ||
71 | height: 2px; | ||
72 | width: 0; | ||
73 | transition: 400ms ease all; | ||
74 | } | ||
75 | |||
76 | &::after { | ||
77 | right: inherit; | ||
78 | top: inherit; | ||
79 | left: 0; | ||
80 | bottom: 0; | ||
81 | } | ||
82 | } | ||
83 | |||
84 | .custom-button { | ||
85 | display: inline-block; | ||
86 | line-height: 1; | ||
87 | white-space: nowrap; | ||
88 | cursor: pointer; | ||
89 | background: #fff; | ||
90 | color: #fff; | ||
91 | -webkit-appearance: none; | ||
92 | text-align: center; | ||
93 | box-sizing: border-box; | ||
94 | outline: 0; | ||
95 | margin: 0; | ||
96 | padding: 10px 15px; | ||
97 | font-size: 14px; | ||
98 | border-radius: 4px; | ||
99 | } | ||
100 |
src/styles/element-ui.scss
1 | // cover some element-ui styles | 1 | // cover some element-ui styles |
2 | 2 | ||
3 | .el-breadcrumb__inner, | 3 | .el-breadcrumb__inner, |
4 | .el-breadcrumb__inner a { | 4 | .el-breadcrumb__inner a { |
5 | font-weight: 400 !important; | 5 | font-weight: 400 !important; |
6 | } | 6 | } |
7 | 7 | ||
8 | .el-upload { | 8 | .el-upload { |
9 | input[type="file"] { | 9 | input[type="file"] { |
10 | display: none !important; | 10 | display: none !important; |
11 | } | 11 | } |
12 | } | 12 | } |
13 | 13 | ||
14 | .el-upload__input { | 14 | .el-upload__input { |
15 | display: none; | 15 | display: none; |
16 | } | 16 | } |
17 | 17 | ||
18 | .cell { | ||
19 | .el-tag { | ||
20 | margin-right: 0px; | ||
21 | } | ||
22 | } | ||
23 | |||
24 | .small-padding { | ||
25 | .cell { | ||
26 | padding-left: 5px; | ||
27 | padding-right: 5px; | ||
28 | } | ||
29 | } | ||
30 | |||
31 | .fixed-width { | ||
32 | .el-button--mini { | ||
33 | padding: 7px 10px; | ||
34 | width: 60px; | ||
35 | } | ||
36 | } | ||
37 | |||
38 | .status-col { | ||
39 | .cell { | ||
40 | padding: 0 10px; | ||
41 | text-align: center; | ||
42 | |||
43 | .el-tag { | ||
44 | margin-right: 0px; | ||
45 | } | ||
46 | } | ||
47 | } | ||
18 | 48 | ||
19 | // to fixed https://github.com/ElemeFE/element/issues/2461 | 49 | // to fixed https://github.com/ElemeFE/element/issues/2461 |
20 | .el-dialog { | 50 | .el-dialog { |
21 | transform: none; | 51 | transform: none; |
22 | left: 0; | 52 | left: 0; |
23 | position: relative; | 53 | position: relative; |
24 | margin: 0 auto; | 54 | margin: 0 auto; |
25 | } | 55 | } |
26 | 56 | ||
27 | // refine element ui upload | 57 | // refine element ui upload |
28 | .upload-container { | 58 | .upload-container { |
29 | .el-upload { | 59 | .el-upload { |
30 | width: 100%; | 60 | width: 100%; |
31 | 61 | ||
32 | .el-upload-dragger { | 62 | .el-upload-dragger { |
33 | width: 100%; | 63 | width: 100%; |
34 | height: 200px; | 64 | height: 200px; |
35 | } | 65 | } |
36 | } | 66 | } |
37 | } | 67 | } |
38 | 68 | ||
39 | // dropdown | 69 | // dropdown |
40 | .el-dropdown-menu { | 70 | .el-dropdown-menu { |
41 | a { | 71 | a { |
42 | display: block | 72 | display: block |
43 | } | 73 | } |
44 | } | 74 | } |
45 | 75 | ||
76 | // fix date-picker ui bug in filter-item | ||
77 | .el-range-editor.el-input__inner { | ||
78 | display: inline-flex !important; | ||
79 | } | ||
80 | |||
46 | // to fix el-date-picker css style | 81 | // to fix el-date-picker css style |
47 | .el-range-separator { | 82 | .el-range-separator { |
48 | box-sizing: content-box; | 83 | box-sizing: content-box; |
49 | } | 84 | } |
50 | 85 |
src/styles/element-variables.scss
File was created | 1 | /** | |
2 | * I think element-ui's default theme color is too light for long-term use. | ||
3 | * So I modified the default color and you can modify it to your liking. | ||
4 | **/ | ||
5 | |||
6 | /* theme color */ | ||
7 | $--color-primary: #1890ff; | ||
8 | $--color-success: #13ce66; | ||
9 | $--color-warning: #FFBA00; | ||
10 | $--color-danger: #ff4949; | ||
11 | // $--color-info: #1E1E1E; | ||
12 | |||
13 | $--button-font-weight: 400; | ||
14 | |||
15 | // $--color-text-regular: #1f2d3d; | ||
16 | |||
17 | $--border-color-light: #dfe4ed; | ||
18 | $--border-color-lighter: #e6ebf5; | ||
19 | |||
20 | $--table-border:1px solid#dfe6ec; | ||
21 | |||
22 | /* icon font path, required */ | ||
23 | $--font-path: '~element-ui/lib/theme-chalk/fonts'; | ||
24 | |||
25 | @import "~element-ui/packages/theme-chalk/src/index"; | ||
26 | |||
27 | // the :export directive is the magic sauce for webpack | ||
28 | // https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass | ||
29 | :export { | ||
30 | theme: $--color-primary; | ||
31 | } | ||
32 |
src/styles/index.scss
1 | @import './variables.scss'; | 1 | @import './variables.scss'; |
2 | @import './mixin.scss'; | 2 | @import './mixin.scss'; |
3 | @import './transition.scss'; | 3 | @import './transition.scss'; |
4 | @import './element-ui.scss'; | 4 | @import './element-ui.scss'; |
5 | @import './sidebar.scss'; | 5 | @import './sidebar.scss'; |
6 | @import './btn.scss'; | ||
6 | 7 | ||
7 | body { | 8 | body { |
8 | height: 100%; | 9 | height: 100%; |
9 | -moz-osx-font-smoothing: grayscale; | 10 | -moz-osx-font-smoothing: grayscale; |
10 | -webkit-font-smoothing: antialiased; | 11 | -webkit-font-smoothing: antialiased; |
11 | text-rendering: optimizeLegibility; | 12 | text-rendering: optimizeLegibility; |
12 | font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif; | 13 | font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif; |
13 | } | 14 | } |
14 | 15 | ||
15 | label { | 16 | label { |
16 | font-weight: 700; | 17 | font-weight: 700; |
17 | } | 18 | } |
18 | 19 | ||
19 | html { | 20 | html { |
20 | height: 100%; | 21 | height: 100%; |
21 | box-sizing: border-box; | 22 | box-sizing: border-box; |
22 | } | 23 | } |
23 | 24 | ||
24 | #app { | 25 | #app { |
25 | height: 100%; | 26 | height: 100%; |
26 | } | 27 | } |
27 | 28 | ||
28 | *, | 29 | *, |
29 | *:before, | 30 | *:before, |
30 | *:after { | 31 | *:after { |
31 | box-sizing: inherit; | 32 | box-sizing: inherit; |
32 | } | 33 | } |
33 | 34 | ||
35 | .no-padding { | ||
36 | padding: 0px !important; | ||
37 | } | ||
38 | |||
39 | .padding-content { | ||
40 | padding: 4px 0; | ||
41 | } | ||
42 | |||
34 | a:focus, | 43 | a:focus, |
35 | a:active { | 44 | a:active { |
36 | outline: none; | 45 | outline: none; |
37 | } | 46 | } |
38 | 47 | ||
39 | a, | 48 | a, |
40 | a:focus, | 49 | a:focus, |
41 | a:hover { | 50 | a:hover { |
42 | cursor: pointer; | 51 | cursor: pointer; |
43 | color: inherit; | 52 | color: inherit; |
44 | text-decoration: none; | 53 | text-decoration: none; |
45 | } | 54 | } |
46 | 55 | ||
47 | div:focus { | 56 | div:focus { |
48 | outline: none; | 57 | outline: none; |
49 | } | 58 | } |
50 | 59 | ||
60 | .fr { | ||
61 | float: right; | ||
62 | } | ||
63 | |||
64 | .fl { | ||
65 | float: left; | ||
66 | } | ||
67 | |||
68 | .pr-5 { | ||
69 | padding-right: 5px; | ||
70 | } | ||
71 | |||
72 | .pl-5 { | ||
73 | padding-left: 5px; | ||
74 | } | ||
75 | |||
76 | .block { | ||
77 | display: block; | ||
78 | } | ||
79 | |||
80 | .pointer { | ||
81 | cursor: pointer; | ||
82 | } | ||
83 | |||
84 | .inlineBlock { | ||
85 | display: block; | ||
86 | } | ||
87 | |||
51 | .clearfix { | 88 | .clearfix { |
52 | &:after { | 89 | &:after { |
53 | visibility: hidden; | 90 | visibility: hidden; |
54 | display: block; | 91 | display: block; |
55 | font-size: 0; | 92 | font-size: 0; |
56 | content: " "; | 93 | content: " "; |
57 | clear: both; | 94 | clear: both; |
58 | height: 0; | 95 | height: 0; |
59 | } | 96 | } |
60 | } | 97 | } |
61 | 98 | ||
62 | // main-container global css | 99 | aside { |
100 | background: #eef1f6; | ||
101 | padding: 8px 24px; | ||
102 | margin-bottom: 20px; | ||
103 | border-radius: 2px; | ||
104 | display: block; | ||
105 | line-height: 32px; | ||
106 | font-size: 16px; | ||
107 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; | ||
108 | color: #2c3e50; | ||
109 | -webkit-font-smoothing: antialiased; | ||
110 | -moz-osx-font-smoothing: grayscale; | ||
111 | |||
112 | a { | ||
113 | color: #337ab7; | ||
114 | cursor: pointer; | ||
115 | |||
116 | &:hover { | ||
117 | color: rgb(32, 160, 255); | ||
118 | } | ||
119 | } | ||
120 | } | ||
121 | |||
122 | //main-container全局样式 | ||
63 | .app-container { | 123 | .app-container { |
64 | padding: 20px; | 124 | padding: 20px; |
65 | } | 125 | } |
126 | |||
127 | .components-container { | ||
128 | margin: 30px 50px; | ||
129 | position: relative; | ||
130 | } | ||
131 | |||
132 | .pagination-container { | ||
133 | margin-top: 30px; | ||
134 | } | ||
135 | |||
136 | .text-center { | ||
137 | text-align: center | ||
138 | } | ||
139 | |||
140 | .sub-navbar { | ||
141 | height: 50px; | ||
142 | line-height: 50px; | ||
143 | position: relative; | ||
144 | width: 100%; | ||
145 | text-align: right; | ||
146 | padding-right: 20px; | ||
147 | transition: 600ms ease position; | ||
148 | background: linear-gradient(90deg, rgba(32, 182, 249, 1) 0%, rgba(32, 182, 249, 1) 0%, rgba(33, 120, 241, 1) 100%, rgba(33, 120, 241, 1) 100%); | ||
149 | |||
150 | .subtitle { | ||
151 | font-size: 20px; | ||
152 | color: #fff; | ||
153 | } | ||
154 | |||
155 | &.draft { | ||
156 | background: #d0d0d0; | ||
157 | } | ||
158 | |||
159 | &.deleted { | ||
160 | background: #d0d0d0; | ||
161 | } | ||
162 | } | ||
163 | |||
164 | .link-type, | ||
165 | .link-type:focus { | ||
166 | color: #337ab7; | ||
167 | cursor: pointer; | ||
168 | |||
169 | &:hover { | ||
170 | color: rgb(32, 160, 255); | ||
171 | } | ||
172 | } | ||
173 | |||
174 | .filter-container { | ||
175 | padding-bottom: 10px; | ||
176 | |||
177 | .filter-item { | ||
178 | display: inline-block; | ||
179 | vertical-align: middle; | ||
180 | margin-bottom: 10px; | ||
181 | } | ||
182 | } | ||
183 | |||
184 | //refine vue-multiselect plugin | ||
185 | .multiselect { | ||
186 | line-height: 16px; | ||
187 | } | ||
188 | |||
189 | .multiselect--active { | ||
190 | z-index: 1000 !important; | ||
191 | } | ||
66 | 192 |
src/styles/mixin.scss
1 | @mixin clearfix { | 1 | @mixin clearfix { |
2 | &:after { | 2 | &:after { |
3 | content: ""; | 3 | content: ""; |
4 | display: table; | 4 | display: table; |
5 | clear: both; | 5 | clear: both; |
6 | } | 6 | } |
7 | } | 7 | } |
8 | 8 | ||
9 | @mixin scrollBar { | 9 | @mixin scrollBar { |
10 | &::-webkit-scrollbar-track-piece { | 10 | &::-webkit-scrollbar-track-piece { |
11 | background: #d3dce6; | 11 | background: #d3dce6; |
12 | } | 12 | } |
13 | 13 | ||
14 | &::-webkit-scrollbar { | 14 | &::-webkit-scrollbar { |
15 | width: 6px; | 15 | width: 6px; |
16 | } | 16 | } |
17 | 17 | ||
18 | &::-webkit-scrollbar-thumb { | 18 | &::-webkit-scrollbar-thumb { |
19 | background: #99a9bf; | 19 | background: #99a9bf; |
20 | border-radius: 20px; | 20 | border-radius: 20px; |
21 | } | 21 | } |
22 | } | 22 | } |
23 | 23 | ||
24 | @mixin relative { | 24 | @mixin relative { |
25 | position: relative; | 25 | position: relative; |
26 | width: 100%; | 26 | width: 100%; |
27 | height: 100%; | 27 | height: 100%; |
28 | } | 28 | } |
29 | |||
30 | @mixin pct($pct) { | ||
31 | width: #{$pct}; | ||
32 | position: relative; | ||
33 | margin: 0 auto; | ||
34 | } | ||
35 | |||
36 | @mixin triangle($width, $height, $color, $direction) { | ||
37 | $width: $width/2; | ||
38 | $color-border-style: $height solid $color; | ||
39 | $transparent-border-style: $width solid transparent; | ||
40 | height: 0; | ||
41 | width: 0; | ||
42 | |||
43 | @if $direction==up { | ||
44 | border-bottom: $color-border-style; | ||
45 | border-left: $transparent-border-style; | ||
46 | border-right: $transparent-border-style; | ||
47 | } | ||
48 | |||
49 | @else if $direction==right { | ||
50 | border-left: $color-border-style; | ||
51 | border-top: $transparent-border-style; | ||
52 | border-bottom: $transparent-border-style; | ||
53 | } | ||
54 | |||
55 | @else if $direction==down { | ||
56 | border-top: $color-border-style; | ||
57 | border-left: $transparent-border-style; | ||
58 | border-right: $transparent-border-style; | ||
59 | } | ||
60 | |||
61 | @else if $direction==left { | ||
62 | border-right: $color-border-style; | ||
63 | border-top: $transparent-border-style; | ||
64 | border-bottom: $transparent-border-style; | ||
65 | } | ||
66 | } | ||
29 | 67 |
1 | #app { | 1 | #app { |
2 | 2 | ||
3 | .main-container { | 3 | .main-container { |
4 | min-height: 100%; | 4 | min-height: 100%; |
5 | transition: margin-left .28s; | 5 | transition: margin-left .28s; |
6 | margin-left: $sideBarWidth; | 6 | margin-left: $sideBarWidth; |
7 | position: relative; | 7 | position: relative; |
8 | } | 8 | } |
9 | 9 | ||
10 | .sidebar-container { | 10 | .sidebar-container { |
11 | transition: width 0.28s; | 11 | transition: width 0.28s; |
12 | width: $sideBarWidth !important; | 12 | width: $sideBarWidth !important; |
13 | background-color: $menuBg; | 13 | background-color: $menuBg; |
14 | height: 100%; | 14 | height: 100%; |
15 | position: fixed; | 15 | position: fixed; |
16 | font-size: 0px; | 16 | font-size: 0px; |
17 | top: 0; | 17 | top: 0; |
18 | bottom: 0; | 18 | bottom: 0; |
19 | left: 0; | 19 | left: 0; |
20 | z-index: 1001; | 20 | z-index: 1001; |
21 | overflow: hidden; | 21 | overflow: hidden; |
22 | 22 | ||
23 | // reset element-ui css | 23 | // reset element-ui css |
24 | .horizontal-collapse-transition { | 24 | .horizontal-collapse-transition { |
25 | transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out; | 25 | transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out; |
26 | } | 26 | } |
27 | 27 | ||
28 | .scrollbar-wrapper { | 28 | .scrollbar-wrapper { |
29 | overflow-x: hidden !important; | 29 | overflow-x: hidden !important; |
30 | } | 30 | } |
31 | 31 | ||
32 | .el-scrollbar__bar.is-vertical { | 32 | .el-scrollbar__bar.is-vertical { |
33 | right: 0px; | 33 | right: 0px; |
34 | } | 34 | } |
35 | 35 | ||
36 | .el-scrollbar { | 36 | .el-scrollbar { |
37 | height: 100%; | 37 | height: 100%; |
38 | } | 38 | } |
39 | 39 | ||
40 | &.has-logo { | 40 | &.has-logo { |
41 | .el-scrollbar { | 41 | .el-scrollbar { |
42 | height: calc(100% - 50px); | 42 | height: calc(100% - 50px); |
43 | } | 43 | } |
44 | } | 44 | } |
45 | 45 | ||
46 | .is-horizontal { | 46 | .is-horizontal { |
47 | display: none; | 47 | display: none; |
48 | } | 48 | } |
49 | 49 | ||
50 | a { | 50 | a { |
51 | display: inline-block; | 51 | display: inline-block; |
52 | width: 100%; | 52 | width: 100%; |
53 | overflow: hidden; | 53 | overflow: hidden; |
54 | } | 54 | } |
55 | 55 | ||
56 | .svg-icon { | 56 | .svg-icon { |
57 | margin-right: 16px; | 57 | margin-right: 16px; |
58 | } | 58 | } |
59 | 59 | ||
60 | .el-menu { | 60 | .el-menu { |
61 | border: none; | 61 | border: none; |
62 | height: 100%; | 62 | height: 100%; |
63 | width: 100% !important; | 63 | width: 100% !important; |
64 | } | 64 | } |
65 | 65 | ||
66 | // menu hover | 66 | // menu hover |
67 | .submenu-title-noDropdown, | 67 | .submenu-title-noDropdown, |
68 | .el-submenu__title { | 68 | .el-submenu__title { |
69 | &:hover { | 69 | &:hover { |
70 | background-color: $menuHover !important; | 70 | background-color: $menuHover !important; |
71 | } | 71 | } |
72 | } | 72 | } |
73 | 73 | ||
74 | .is-active>.el-submenu__title { | 74 | .is-active>.el-submenu__title { |
75 | color: $subMenuActiveText !important; | 75 | color: $subMenuActiveText !important; |
76 | } | 76 | } |
77 | 77 | ||
78 | & .nest-menu .el-submenu>.el-submenu__title, | 78 | & .nest-menu .el-submenu>.el-submenu__title, |
79 | & .el-submenu .el-menu-item { | 79 | & .el-submenu .el-menu-item { |
80 | min-width: $sideBarWidth !important; | 80 | min-width: $sideBarWidth !important; |
81 | background-color: $subMenuBg !important; | 81 | background-color: $subMenuBg !important; |
82 | 82 | ||
83 | &:hover { | 83 | &:hover { |
84 | background-color: $subMenuHover !important; | 84 | background-color: $subMenuHover !important; |
85 | } | 85 | } |
86 | } | 86 | } |
87 | } | 87 | } |
88 | 88 | ||
89 | .hideSidebar { | 89 | .hideSidebar { |
90 | .sidebar-container { | 90 | .sidebar-container { |
91 | width: 54px !important; | 91 | width: 54px !important; |
92 | } | 92 | } |
93 | 93 | ||
94 | .main-container { | 94 | .main-container { |
95 | margin-left: 54px; | 95 | margin-left: 54px; |
96 | } | 96 | } |
97 | 97 | ||
98 | .submenu-title-noDropdown { | 98 | .submenu-title-noDropdown { |
99 | padding: 0 !important; | 99 | padding: 0 !important; |
100 | position: relative; | 100 | position: relative; |
101 | 101 | ||
102 | .el-tooltip { | 102 | .el-tooltip { |
103 | padding: 0 !important; | 103 | padding: 0 !important; |
104 | 104 | ||
105 | .svg-icon { | 105 | .svg-icon { |
106 | margin-left: 20px; | 106 | margin-left: 20px; |
107 | } | 107 | } |
108 | } | 108 | } |
109 | } | 109 | } |
110 | 110 | ||
111 | .el-submenu { | 111 | .el-submenu { |
112 | overflow: hidden; | 112 | overflow: hidden; |
113 | 113 | ||
114 | &>.el-submenu__title { | 114 | &>.el-submenu__title { |
115 | padding: 0 !important; | 115 | padding: 0 !important; |
116 | 116 | ||
117 | .svg-icon { | 117 | .svg-icon { |
118 | margin-left: 20px; | 118 | margin-left: 20px; |
119 | } | 119 | } |
120 | 120 | ||
121 | .el-submenu__icon-arrow { | 121 | .el-submenu__icon-arrow { |
122 | display: none; | 122 | display: none; |
123 | } | 123 | } |
124 | } | 124 | } |
125 | } | 125 | } |
126 | 126 | ||
127 | .el-menu--collapse { | 127 | .el-menu--collapse { |
128 | .el-submenu { | 128 | .el-submenu { |
129 | &>.el-submenu__title { | 129 | &>.el-submenu__title { |
130 | &>span { | 130 | &>span { |
131 | height: 0; | 131 | height: 0; |
132 | width: 0; | 132 | width: 0; |
133 | overflow: hidden; | 133 | overflow: hidden; |
134 | visibility: hidden; | 134 | visibility: hidden; |
135 | display: inline-block; | 135 | display: inline-block; |
136 | } | 136 | } |
137 | } | 137 | } |
138 | } | 138 | } |
139 | } | 139 | } |
140 | } | 140 | } |
141 | 141 | ||
142 | .el-menu--collapse .el-menu .el-submenu { | 142 | .el-menu--collapse .el-menu .el-submenu { |
143 | min-width: $sideBarWidth !important; | 143 | min-width: $sideBarWidth !important; |
144 | } | 144 | } |
145 | 145 | ||
146 | // mobile responsive | 146 | // mobile responsive |
147 | .mobile { | 147 | .mobile { |
148 | .main-container { | 148 | .main-container { |
149 | margin-left: 0px; | 149 | margin-left: 0px; |
150 | } | 150 | } |
151 | 151 | ||
152 | .sidebar-container { | 152 | .sidebar-container { |
153 | transition: transform .28s; | 153 | transition: transform .28s; |
154 | width: $sideBarWidth !important; | 154 | width: $sideBarWidth !important; |
155 | } | 155 | } |
156 | 156 | ||
157 | &.hideSidebar { | 157 | &.hideSidebar { |
158 | .sidebar-container { | 158 | .sidebar-container { |
159 | pointer-events: none; | 159 | pointer-events: none; |
160 | transition-duration: 0.3s; | 160 | transition-duration: 0.3s; |
161 | transform: translate3d(-$sideBarWidth, 0, 0); | 161 | transform: translate3d(-$sideBarWidth, 0, 0); |
162 | } | 162 | } |
163 | } | 163 | } |
164 | } | 164 | } |
165 | 165 | ||
166 | .withoutAnimation { | 166 | .withoutAnimation { |
167 | 167 | ||
168 | .main-container, | 168 | .main-container, |
169 | .sidebar-container { | 169 | .sidebar-container { |
170 | transition: none; | 170 | transition: none; |
171 | } | 171 | } |
172 | } | 172 | } |
173 | } | 173 | } |
174 | 174 | ||
175 | // when menu collapsed | 175 | // when menu collapsed |
176 | .el-menu--vertical { | 176 | .el-menu--vertical { |
177 | &>.el-menu { | 177 | &>.el-menu { |
178 | .svg-icon { | 178 | .svg-icon { |
179 | margin-right: 16px; | 179 | margin-right: 16px; |
180 | } | 180 | } |
181 | } | 181 | } |
182 | 182 | ||
183 | .nest-menu .el-submenu>.el-submenu__title, | 183 | .nest-menu .el-submenu>.el-submenu__title, |
184 | .el-menu-item { | 184 | .el-menu-item { |
185 | &:hover { | 185 | &:hover { |
186 | // you can use $subMenuHover | 186 | // you can use $subMenuHover |
187 | background-color: $menuHover !important; | 187 | background-color: $menuHover !important; |
188 | } | 188 | } |
189 | } | 189 | } |
190 | 190 | ||
191 | // the scroll bar appears when the subMenu is too long | 191 | // the scroll bar appears when the subMenu is too long |
192 | >.el-menu--popup { | 192 | >.el-menu--popup { |
193 | max-height: 100vh; | 193 | max-height: 100vh; |
194 | overflow-y: auto; | 194 | overflow-y: auto; |
195 | 195 | ||
196 | &::-webkit-scrollbar-track-piece { | 196 | &::-webkit-scrollbar-track-piece { |
197 | background: #d3dce6; | 197 | background: #d3dce6; |
198 | } | 198 | } |
199 | 199 | ||
200 | &::-webkit-scrollbar { | 200 | &::-webkit-scrollbar { |
201 | width: 6px; | 201 | width: 6px; |
202 | } | 202 | } |
203 | 203 | ||
204 | &::-webkit-scrollbar-thumb { | 204 | &::-webkit-scrollbar-thumb { |
205 | background: #99a9bf; | 205 | background: #99a9bf; |
206 | border-radius: 20px; | 206 | border-radius: 20px; |
207 | } | 207 | } |
208 | } | 208 | } |
209 | } | 209 | } |
210 | 210 |
1 | // global transition css | 1 | // global transition css |
2 | 2 | ||
3 | /* fade */ | 3 | /* fade */ |
4 | .fade-enter-active, | 4 | .fade-enter-active, |
5 | .fade-leave-active { | 5 | .fade-leave-active { |
6 | transition: opacity 0.28s; | 6 | transition: opacity 0.28s; |
7 | } | 7 | } |
8 | 8 | ||
9 | .fade-enter, | 9 | .fade-enter, |
10 | .fade-leave-active { | 10 | .fade-leave-active { |
11 | opacity: 0; | 11 | opacity: 0; |
12 | } | 12 | } |
13 | 13 | ||
14 | /* fade-transform */ | 14 | /* fade-transform */ |
15 | .fade-transform-leave-active, | 15 | .fade-transform-leave-active, |
16 | .fade-transform-enter-active { | 16 | .fade-transform-enter-active { |
17 | transition: all .5s; | 17 | transition: all .5s; |
18 | } | 18 | } |
19 | 19 | ||
20 | .fade-transform-enter { | 20 | .fade-transform-enter { |
21 | opacity: 0; | 21 | opacity: 0; |
22 | transform: translateX(-30px); | 22 | transform: translateX(-30px); |
23 | } | 23 | } |
24 | 24 | ||
25 | .fade-transform-leave-to { | 25 | .fade-transform-leave-to { |
26 | opacity: 0; | 26 | opacity: 0; |
27 | transform: translateX(30px); | 27 | transform: translateX(30px); |
28 | } | 28 | } |
29 | 29 | ||
30 | /* breadcrumb transition */ | 30 | /* breadcrumb transition */ |
31 | .breadcrumb-enter-active, | 31 | .breadcrumb-enter-active, |
32 | .breadcrumb-leave-active { | 32 | .breadcrumb-leave-active { |
33 | transition: all .5s; | 33 | transition: all .5s; |
34 | } | 34 | } |
35 | 35 | ||
36 | .breadcrumb-enter, | 36 | .breadcrumb-enter, |
37 | .breadcrumb-leave-active { | 37 | .breadcrumb-leave-active { |
38 | opacity: 0; | 38 | opacity: 0; |
39 | transform: translateX(20px); | 39 | transform: translateX(20px); |
40 | } | 40 | } |
41 | 41 | ||
42 | .breadcrumb-move { | 42 | .breadcrumb-move { |
43 | transition: all .5s; | 43 | transition: all .5s; |
44 | } | 44 | } |
45 | 45 | ||
46 | .breadcrumb-leave-active { | 46 | .breadcrumb-leave-active { |
47 | position: absolute; | 47 | position: absolute; |
48 | } | 48 | } |
49 | 49 |
src/styles/variables.scss
1 | // base color | ||
2 | $blue:#324157; | ||
3 | $light-blue:#3A71A8; | ||
4 | $red:#C03639; | ||
5 | $pink: #E65D6E; | ||
6 | $green: #30B08F; | ||
7 | $tiffany: #4AB7BD; | ||
8 | $yellow:#FEC171; | ||
9 | $panGreen: #30B08F; | ||
10 | |||
1 | // sidebar | 11 | // sidebar |
2 | $menuText:#bfcbd9; | 12 | $menuText:#bfcbd9; |
3 | $menuActiveText:#409EFF; | 13 | $menuActiveText:#409EFF; |
4 | $subMenuActiveText:#f4f4f5; //https://github.com/ElemeFE/element/issues/12951 | 14 | $subMenuActiveText:#f4f4f5; // https://github.com/ElemeFE/element/issues/12951 |
5 | 15 | ||
6 | $menuBg:#304156; | 16 | $menuBg:#304156; |
7 | $menuHover:#263445; | 17 | $menuHover:#263445; |
8 | 18 | ||
9 | $subMenuBg:#1f2d3d; | 19 | $subMenuBg:#1f2d3d; |
10 | $subMenuHover:#001528; | 20 | $subMenuHover:#001528; |
11 | 21 | ||
12 | $sideBarWidth: 210px; | 22 | $sideBarWidth: 210px; |
13 | 23 | ||
14 | // the :export directive is the magic sauce for webpack | 24 | // the :export directive is the magic sauce for webpack |
15 | // https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass | 25 | // https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass |
16 | :export { | 26 | :export { |
17 | menuText: $menuText; | 27 | menuText: $menuText; |
18 | menuActiveText: $menuActiveText; | 28 | menuActiveText: $menuActiveText; |
19 | subMenuActiveText: $subMenuActiveText; | 29 | subMenuActiveText: $subMenuActiveText; |
20 | menuBg: $menuBg; | 30 | menuBg: $menuBg; |
21 | menuHover: $menuHover; | 31 | menuHover: $menuHover; |
22 | subMenuBg: $subMenuBg; | 32 | subMenuBg: $subMenuBg; |
23 | subMenuHover: $subMenuHover; | 33 | subMenuHover: $subMenuHover; |
24 | sideBarWidth: $sideBarWidth; | 34 | sideBarWidth: $sideBarWidth; |
25 | } | 35 | } |
26 | 36 |
src/utils/auth.js
1 | import Cookies from 'js-cookie' | 1 | import Cookies from 'js-cookie' |
2 | 2 | ||
3 | const TokenKey = 'vue_admin_template_token' | 3 | const TokenKey = 'Admin-Token' |
4 | 4 | ||
5 | export function getToken() { | 5 | export function getToken() { |
6 | return Cookies.get(TokenKey) | 6 | return Cookies.get(TokenKey) |
7 | } | 7 | } |
8 | 8 | ||
9 | export function setToken(token) { | 9 | export function setToken(token) { |
10 | return Cookies.set(TokenKey, token) | 10 | return Cookies.set(TokenKey, token) |
11 | } | 11 | } |
12 | 12 | ||
13 | export function removeToken() { | 13 | export function removeToken() { |
14 | return Cookies.remove(TokenKey) | 14 | return Cookies.remove(TokenKey) |
15 | } | 15 | } |
16 | 16 |
src/utils/clipboard.js
File was created | 1 | import Vue from 'vue' | |
2 | import Clipboard from 'clipboard' | ||
3 | |||
4 | function clipboardSuccess() { | ||
5 | Vue.prototype.$message({ | ||
6 | message: 'Copy successfully', | ||
7 | type: 'success', | ||
8 | duration: 1500 | ||
9 | }) | ||
10 | } | ||
11 | |||
12 | function clipboardError() { | ||
13 | Vue.prototype.$message({ | ||
14 | message: 'Copy failed', | ||
15 | type: 'error' | ||
16 | }) | ||
17 | } | ||
18 | |||
19 | export default function handleClipboard(text, event) { | ||
20 | const clipboard = new Clipboard(event.target, { | ||
21 | text: () => text | ||
22 | }) | ||
23 | clipboard.on('success', () => { | ||
24 | clipboardSuccess() | ||
25 | clipboard.destroy() | ||
26 | }) | ||
27 | clipboard.on('error', () => { | ||
28 | clipboardError() | ||
29 | clipboard.destroy() | ||
30 | }) | ||
31 | clipboard.onClick(event) | ||
32 | } | ||
33 |
src/utils/error-log.js
File was created | 1 | import Vue from 'vue' | |
2 | import store from '@/store' | ||
3 | import { isString, isArray } from '@/utils/validate' | ||
4 | import settings from '@/settings' | ||
5 | |||
6 | // you can set in settings.js | ||
7 | // errorLog:'production' | ['production', 'development'] | ||
8 | const { errorLog: needErrorLog } = settings | ||
9 | |||
10 | function checkNeed() { | ||
11 | const env = process.env.NODE_ENV | ||
12 | if (isString(needErrorLog)) { | ||
13 | return env === needErrorLog | ||
14 | } | ||
15 | if (isArray(needErrorLog)) { | ||
16 | return needErrorLog.includes(env) | ||
17 | } | ||
18 | return false | ||
19 | } | ||
20 | |||
21 | if (checkNeed()) { | ||
22 | Vue.config.errorHandler = function(err, vm, info, a) { | ||
23 | // Don't ask me why I use Vue.nextTick, it just a hack. | ||
24 | // detail see https://forum.vuejs.org/t/dispatch-in-vue-config-errorhandler-has-some-problem/23500 | ||
25 | Vue.nextTick(() => { | ||
26 | store.dispatch('errorLog/addErrorLog', { | ||
27 | err, | ||
28 | vm, | ||
29 | info, | ||
30 | url: window.location.href | ||
31 | }) | ||
32 | console.error(err, info) | ||
33 | }) | ||
34 | } | ||
35 | } | ||
36 |
src/utils/get-page-title.js
1 | import defaultSettings from '@/settings' | 1 | import defaultSettings from '@/settings' |
2 | import i18n from '@/lang' | ||
2 | 3 | ||
3 | const title = defaultSettings.title || 'Vue Admin Template' | 4 | const title = defaultSettings.title || 'Vue Element Admin' |
4 | 5 | ||
5 | export default function getPageTitle(pageTitle) { | 6 | export default function getPageTitle(key) { |
6 | if (pageTitle) { | 7 | const hasKey = i18n.te(`route.${key}`) |
7 | return `${pageTitle} - ${title}` | 8 | if (hasKey) { |
9 | const pageName = i18n.t(`route.${key}`) | ||
10 | return `${pageName} - ${title}` | ||
8 | } | 11 | } |
9 | return `${title}` | 12 | return `${title}` |
10 | } | 13 | } |
11 | 14 |
src/utils/i18n.js
File was created | 1 | // translate router.meta.title, be used in breadcrumb sidebar tagsview | |
2 | export function generateTitle(title) { | ||
3 | const hasKey = this.$te('route.' + title) | ||
4 | |||
5 | if (hasKey) { | ||
6 | // $t :this method from vue-i18n, inject in @/lang/index.js | ||
7 | const translatedTitle = this.$t('route.' + title) | ||
8 | |||
9 | return translatedTitle | ||
10 | } | ||
11 | return title | ||
12 | } | ||
13 |
src/utils/index.js
1 | /** | 1 | /** |
2 | * Created by PanJiaChen on 16/11/18. | 2 | * Created by PanJiaChen on 16/11/18. |
3 | */ | 3 | */ |
4 | 4 | ||
5 | /** | 5 | /** |
6 | * Parse the time to string | 6 | * Parse the time to string |
7 | * @param {(Object|string|number)} time | 7 | * @param {(Object|string|number)} time |
8 | * @param {string} cFormat | 8 | * @param {string} cFormat |
9 | * @returns {string | null} | 9 | * @returns {string | null} |
10 | */ | 10 | */ |
11 | export function parseTime(time, cFormat) { | 11 | export function parseTime(time, cFormat) { |
12 | if (arguments.length === 0) { | 12 | if (arguments.length === 0) { |
13 | return null | 13 | return null |
14 | } | 14 | } |
15 | const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}' | 15 | const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}' |
16 | let date | 16 | let date |
17 | if (typeof time === 'object') { | 17 | if (typeof time === 'object') { |
18 | date = time | 18 | date = time |
19 | } else { | 19 | } else { |
20 | if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) { | 20 | if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) { |
21 | time = parseInt(time) | 21 | time = parseInt(time) |
22 | } | 22 | } |
23 | if ((typeof time === 'number') && (time.toString().length === 10)) { | 23 | if ((typeof time === 'number') && (time.toString().length === 10)) { |
24 | time = time * 1000 | 24 | time = time * 1000 |
25 | } | 25 | } |
26 | date = new Date(time) | 26 | date = new Date(time) |
27 | } | 27 | } |
28 | const formatObj = { | 28 | const formatObj = { |
29 | y: date.getFullYear(), | 29 | y: date.getFullYear(), |
30 | m: date.getMonth() + 1, | 30 | m: date.getMonth() + 1, |
31 | d: date.getDate(), | 31 | d: date.getDate(), |
32 | h: date.getHours(), | 32 | h: date.getHours(), |
33 | i: date.getMinutes(), | 33 | i: date.getMinutes(), |
34 | s: date.getSeconds(), | 34 | s: date.getSeconds(), |
35 | a: date.getDay() | 35 | a: date.getDay() |
36 | } | 36 | } |
37 | const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => { | 37 | const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => { |
38 | const value = formatObj[key] | 38 | const value = formatObj[key] |
39 | // Note: getDay() returns 0 on Sunday | 39 | // Note: getDay() returns 0 on Sunday |
40 | if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value ] } | 40 | if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value ] } |
41 | return value.toString().padStart(2, '0') | 41 | return value.toString().padStart(2, '0') |
42 | }) | 42 | }) |
43 | return time_str | 43 | return time_str |
44 | } | 44 | } |
45 | 45 | ||
46 | /** | 46 | /** |
47 | * @param {number} time | 47 | * @param {number} time |
48 | * @param {string} option | 48 | * @param {string} option |
49 | * @returns {string} | 49 | * @returns {string} |
50 | */ | 50 | */ |
51 | export function formatTime(time, option) { | 51 | export function formatTime(time, option) { |
52 | if (('' + time).length === 10) { | 52 | if (('' + time).length === 10) { |
53 | time = parseInt(time) * 1000 | 53 | time = parseInt(time) * 1000 |
54 | } else { | 54 | } else { |
55 | time = +time | 55 | time = +time |
56 | } | 56 | } |
57 | const d = new Date(time) | 57 | const d = new Date(time) |
58 | const now = Date.now() | 58 | const now = Date.now() |
59 | 59 | ||
60 | const diff = (now - d) / 1000 | 60 | const diff = (now - d) / 1000 |
61 | 61 | ||
62 | if (diff < 30) { | 62 | if (diff < 30) { |
63 | return '刚刚' | 63 | return '刚刚' |
64 | } else if (diff < 3600) { | 64 | } else if (diff < 3600) { |
65 | // less 1 hour | 65 | // less 1 hour |
66 | return Math.ceil(diff / 60) + '分钟前' | 66 | return Math.ceil(diff / 60) + '分钟前' |
67 | } else if (diff < 3600 * 24) { | 67 | } else if (diff < 3600 * 24) { |
68 | return Math.ceil(diff / 3600) + '小时前' | 68 | return Math.ceil(diff / 3600) + '小时前' |
69 | } else if (diff < 3600 * 24 * 2) { | 69 | } else if (diff < 3600 * 24 * 2) { |
70 | return '1天前' | 70 | return '1天前' |
71 | } | 71 | } |
72 | if (option) { | 72 | if (option) { |
73 | return parseTime(time, option) | 73 | return parseTime(time, option) |
74 | } else { | 74 | } else { |
75 | return ( | 75 | return ( |
76 | d.getMonth() + | 76 | d.getMonth() + |
77 | 1 + | 77 | 1 + |
78 | '月' + | 78 | '月' + |
79 | d.getDate() + | 79 | d.getDate() + |
80 | '日' + | 80 | '日' + |
81 | d.getHours() + | 81 | d.getHours() + |
82 | '时' + | 82 | '时' + |
83 | d.getMinutes() + | 83 | d.getMinutes() + |
84 | '分' | 84 | '分' |
85 | ) | 85 | ) |
86 | } | 86 | } |
87 | } | 87 | } |
88 | 88 | ||
89 | /** | 89 | /** |
90 | * @param {string} url | 90 | * @param {string} url |
91 | * @returns {Object} | 91 | * @returns {Object} |
92 | */ | 92 | */ |
93 | export function getQueryObject(url) { | ||
94 | url = url == null ? window.location.href : url | ||
95 | const search = url.substring(url.lastIndexOf('?') + 1) | ||
96 | const obj = {} | ||
97 | const reg = /([^?&=]+)=([^?&=]*)/g | ||
98 | search.replace(reg, (rs, $1, $2) => { | ||
99 | const name = decodeURIComponent($1) | ||
100 | let val = decodeURIComponent($2) | ||
101 | val = String(val) | ||
102 | obj[name] = val | ||
103 | return rs | ||
104 | }) | ||
105 | return obj | ||
106 | } | ||
107 | |||
108 | /** | ||
109 | * @param {string} input value | ||
110 | * @returns {number} output value | ||
111 | */ | ||
112 | export function byteLength(str) { | ||
113 | // returns the byte length of an utf8 string | ||
114 | let s = str.length | ||
115 | for (var i = str.length - 1; i >= 0; i--) { | ||
116 | const code = str.charCodeAt(i) | ||
117 | if (code > 0x7f && code <= 0x7ff) s++ | ||
118 | else if (code > 0x7ff && code <= 0xffff) s += 2 | ||
119 | if (code >= 0xDC00 && code <= 0xDFFF) i-- | ||
120 | } | ||
121 | return s | ||
122 | } | ||
123 | |||
124 | /** | ||
125 | * @param {Array} actual | ||
126 | * @returns {Array} | ||
127 | */ | ||
128 | export function cleanArray(actual) { | ||
129 | const newArray = [] | ||
130 | for (let i = 0; i < actual.length; i++) { | ||
131 | if (actual[i]) { | ||
132 | newArray.push(actual[i]) | ||
133 | } | ||
134 | } | ||
135 | return newArray | ||
136 | } | ||
137 | |||
138 | /** | ||
139 | * @param {Object} json | ||
140 | * @returns {Array} | ||
141 | */ | ||
142 | export function param(json) { | ||
143 | if (!json) return '' | ||
144 | return cleanArray( | ||
145 | Object.keys(json).map(key => { | ||
146 | if (json[key] === undefined) return '' | ||
147 | return encodeURIComponent(key) + '=' + encodeURIComponent(json[key]) | ||
148 | }) | ||
149 | ).join('&') | ||
150 | } | ||
151 | |||
152 | /** | ||
153 | * @param {string} url | ||
154 | * @returns {Object} | ||
155 | */ | ||
93 | export function param2Obj(url) { | 156 | export function param2Obj(url) { |
94 | const search = url.split('?')[1] | 157 | const search = url.split('?')[1] |
95 | if (!search) { | 158 | if (!search) { |
96 | return {} | 159 | return {} |
97 | } | 160 | } |
98 | return JSON.parse( | 161 | return JSON.parse( |
99 | '{"' + | 162 | '{"' + |
100 | decodeURIComponent(search) | 163 | decodeURIComponent(search) |
101 | .replace(/"/g, '\\"') | 164 | .replace(/"/g, '\\"') |
102 | .replace(/&/g, '","') | 165 | .replace(/&/g, '","') |
103 | .replace(/=/g, '":"') | 166 | .replace(/=/g, '":"') |
104 | .replace(/\+/g, ' ') + | 167 | .replace(/\+/g, ' ') + |
105 | '"}' | 168 | '"}' |
106 | ) | 169 | ) |
107 | } | 170 | } |
171 | |||
172 | /** | ||
173 | * @param {string} val | ||
174 | * @returns {string} | ||
175 | */ | ||
176 | export function html2Text(val) { | ||
177 | const div = document.createElement('div') | ||
178 | div.innerHTML = val | ||
179 | return div.textContent || div.innerText | ||
180 | } | ||
181 | |||
182 | /** | ||
183 | * Merges two objects, giving the last one precedence | ||
184 | * @param {Object} target | ||
185 | * @param {(Object|Array)} source | ||
186 | * @returns {Object} | ||
187 | */ | ||
188 | export function objectMerge(target, source) { | ||
189 | if (typeof target !== 'object') { | ||
190 | target = {} | ||
191 | } | ||
192 | if (Array.isArray(source)) { | ||
193 | return source.slice() | ||
194 | } | ||
195 | Object.keys(source).forEach(property => { | ||
196 | const sourceProperty = source[property] | ||
197 | if (typeof sourceProperty === 'object') { | ||
198 | target[property] = objectMerge(target[property], sourceProperty) | ||
199 | } else { | ||
200 | target[property] = sourceProperty | ||
201 | } | ||
202 | }) | ||
203 | return target | ||
204 | } | ||
205 | |||
206 | /** | ||
207 | * @param {HTMLElement} element | ||
208 | * @param {string} className | ||
209 | */ | ||
210 | export function toggleClass(element, className) { | ||
211 | if (!element || !className) { | ||
212 | return | ||
213 | } | ||
214 | let classString = element.className | ||
215 | const nameIndex = classString.indexOf(className) | ||
216 | if (nameIndex === -1) { | ||
217 | classString += '' + className | ||
218 | } else { | ||
219 | classString = | ||
220 | classString.substr(0, nameIndex) + | ||
221 | classString.substr(nameIndex + className.length) | ||
222 | } | ||
223 | element.className = classString | ||
224 | } | ||
225 | |||
226 | /** | ||
227 | * @param {string} type | ||
228 | * @returns {Date} | ||
229 | */ | ||
230 | export function getTime(type) { | ||
231 | if (type === 'start') { | ||
232 | return new Date().getTime() - 3600 * 1000 * 24 * 90 | ||
233 | } else { | ||
234 | return new Date(new Date().toDateString()) | ||
235 | } | ||
236 | } | ||
237 | |||
238 | /** | ||
239 | * @param {Function} func | ||
240 | * @param {number} wait | ||
241 | * @param {boolean} immediate | ||
242 | * @return {*} | ||
243 | */ | ||
244 | export function debounce(func, wait, immediate) { | ||
245 | let timeout, args, context, timestamp, result | ||
246 | |||
247 | const later = function() { | ||
248 | // 据上一次触发时间间隔 | ||
249 | const last = +new Date() - timestamp | ||
250 | |||
251 | // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait | ||
252 | if (last < wait && last > 0) { | ||
253 | timeout = setTimeout(later, wait - last) | ||
254 | } else { | ||
255 | timeout = null | ||
256 | // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用 | ||
257 | if (!immediate) { | ||
258 | result = func.apply(context, args) | ||
259 | if (!timeout) context = args = null | ||
260 | } | ||
261 | } | ||
262 | } | ||
263 | |||
264 | return function(...args) { | ||
265 | context = this | ||
266 | timestamp = +new Date() | ||
267 | const callNow = immediate && !timeout | ||
268 | // 如果延时不存在,重新设定延时 | ||
269 | if (!timeout) timeout = setTimeout(later, wait) | ||
270 | if (callNow) { | ||
271 | result = func.apply(context, args) | ||
272 | context = args = null | ||
273 | } | ||
274 | |||
275 | return result | ||
276 | } | ||
277 | } | ||
278 | |||
279 | /** | ||
280 | * This is just a simple version of deep copy | ||
281 | * Has a lot of edge cases bug | ||
282 | * If you want to use a perfect deep copy, use lodash's _.cloneDeep | ||
283 | * @param {Object} source | ||
284 | * @returns {Object} | ||
285 | */ | ||
286 | export function deepClone(source) { | ||
287 | if (!source && typeof source !== 'object') { | ||
288 | throw new Error('error arguments', 'deepClone') | ||
289 | } | ||
290 | const targetObj = source.constructor === Array ? [] : {} | ||
291 | Object.keys(source).forEach(keys => { | ||
292 | if (source[keys] && typeof source[keys] === 'object') { | ||
293 | targetObj[keys] = deepClone(source[keys]) | ||
294 | } else { | ||
295 | targetObj[keys] = source[keys] | ||
296 | } | ||
297 | }) | ||
298 | return targetObj | ||
299 | } | ||
300 | |||
301 | /** | ||
302 | * @param {Array} arr | ||
303 | * @returns {Array} | ||
304 | */ | ||
305 | export function uniqueArr(arr) { | ||
306 | return Array.from(new Set(arr)) | ||
307 | } | ||
308 | |||
309 | /** | ||
310 | * @returns {string} | ||
311 | */ | ||
312 | export function createUniqueString() { | ||
313 | const timestamp = +new Date() + '' | ||
314 | const randomNum = parseInt((1 + Math.random()) * 65536) + '' | ||
315 | return (+(randomNum + timestamp)).toString(32) | ||
316 | } | ||
317 | |||
318 | /** | ||
319 | * Check if an element has a class | ||
320 | * @param {HTMLElement} elm | ||
321 | * @param {string} cls | ||
322 | * @returns {boolean} | ||
323 | */ | ||
324 | export function hasClass(ele, cls) { | ||
325 | return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)')) | ||
326 | } | ||
327 | |||
328 | /** | ||
329 | * Add class to element | ||
330 | * @param {HTMLElement} elm | ||
331 | * @param {string} cls | ||
332 | */ | ||
333 | export function addClass(ele, cls) { | ||
334 | if (!hasClass(ele, cls)) ele.className += ' ' + cls | ||
335 | } | ||
336 | |||
337 | /** | ||
338 | * Remove class from element | ||
339 | * @param {HTMLElement} elm | ||
340 | * @param {string} cls | ||
341 | */ | ||
342 | export function removeClass(ele, cls) { | ||
343 | if (hasClass(ele, cls)) { | ||
344 | const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)') | ||
345 | ele.className = ele.className.replace(reg, ' ') | ||
346 | } | ||
347 | } | ||
108 | 348 |
src/utils/open-window.js
File was created | 1 | /** | |
2 | *Created by PanJiaChen on 16/11/29. | ||
3 | * @param {Sting} url | ||
4 | * @param {Sting} title | ||
5 | * @param {Number} w | ||
6 | * @param {Number} h | ||
7 | */ | ||
8 | export default function openWindow(url, title, w, h) { | ||
9 | // Fixes dual-screen position Most browsers Firefox | ||
10 | const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left | ||
11 | const dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top | ||
12 | |||
13 | const width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width | ||
14 | const height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height | ||
15 | |||
16 | const left = ((width / 2) - (w / 2)) + dualScreenLeft | ||
17 | const top = ((height / 2) - (h / 2)) + dualScreenTop | ||
18 | const newWindow = window.open(url, title, 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=yes, copyhistory=no, width=' + w + ', height=' + h + ', top=' + top + ', left=' + left) | ||
19 | |||
20 | // Puts focus on the newWindow | ||
21 | if (window.focus) { | ||
22 | newWindow.focus() | ||
23 | } | ||
24 | } | ||
25 | |||
26 |
src/utils/permission.js
File was created | 1 | import store from '@/store' | |
2 | |||
3 | /** | ||
4 | * @param {Array} value | ||
5 | * @returns {Boolean} | ||
6 | * @example see @/views/permission/directive.vue | ||
7 | */ | ||
8 | export default function checkPermission(value) { | ||
9 | if (value && value instanceof Array && value.length > 0) { | ||
10 | const roles = store.getters && store.getters.roles | ||
11 | const permissionRoles = value | ||
12 | |||
13 | const hasPermission = roles.some(role => { | ||
14 | return permissionRoles.includes(role) | ||
15 | }) | ||
16 | |||
17 | if (!hasPermission) { | ||
18 | return false | ||
19 | } | ||
20 | return true | ||
21 | } else { | ||
22 | console.error(`need roles! Like v-permission="['admin','editor']"`) | ||
23 | return false | ||
24 | } | ||
25 | } | ||
26 |
src/utils/request.js
1 | import axios from 'axios' | 1 | import axios from 'axios' |
2 | import { | 2 | import { MessageBox, Message } from 'element-ui' |
3 | MessageBox, | ||
4 | Message | ||
5 | } from 'element-ui' | ||
6 | import store from '@/store' | 3 | import store from '@/store' |
7 | import { | 4 | import { getToken } from '@/utils/auth' |
8 | getToken | ||
9 | } from '@/utils/auth' | ||
10 | 5 | ||
11 | // create an axios instance | 6 | // create an axios instance |
12 | // 创建axios实例 | ||
13 | const service = axios.create({ | 7 | const service = axios.create({ |
14 | // baseURL: '', // url = base url + request url | ||
15 | baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url | 8 | baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url |
16 | // withCredentials: true, // send cookies when cross-domain requests | 9 | // withCredentials: true, // send cookies when cross-domain requests |
17 | timeout: 5000, // request timeout | 10 | timeout: 5000 // request timeout |
18 | // headers: { | ||
19 | // 'Content-Type': 'application/x-www-form-urlencoded' | ||
20 | // } | ||
21 | }) | 11 | }) |
22 | 12 | ||
23 | // request interceptor | 13 | // request interceptor |
24 | // request拦截器 | ||
25 | service.interceptors.request.use( | 14 | service.interceptors.request.use( |
26 | config => { | 15 | config => { |
27 | // do something before request is sent | 16 | // do something before request is sent |
28 | // console.log('do something before request is sent') | 17 | |
29 | if (store.getters.token) { | 18 | if (store.getters.token) { |
30 | // console.log('[X-Token] is a custom headers key') | ||
31 | // let each request carry token | 19 | // let each request carry token |
32 | // ['X-Token'] is a custom headers key | 20 | // ['X-Token'] is a custom headers key |
33 | // please modify it according to the actual situation | 21 | // please modify it according to the actual situation |
34 | config.headers['X-Token'] = getToken(); | 22 | config.headers['X-Token'] = getToken() |
35 | // config.headers['Content-Type'] = 'application/x-www-form-urlencoded'; | ||
36 | // var token = getToken() | ||
37 | // Object.assign(config.headers, { 'token': token }) | ||
38 | } | 23 | } |
39 | return config | 24 | return config |
40 | }, | 25 | }, |
41 | error => { | 26 | error => { |
42 | // console.log('do something with request error') | ||
43 | // do something with request error | 27 | // do something with request error |
44 | console.error('出现错误。在use里。======>', error) // for debug | 28 | console.log(error) // for debug |
45 | return Promise.reject(error) | 29 | return Promise.reject(error) |
46 | } | 30 | } |
47 | ) | 31 | ) |
48 | 32 | ||
49 | // response interceptor | 33 | // response interceptor |
50 | // respone拦截器 | ||
51 | service.interceptors.response.use( | 34 | service.interceptors.response.use( |
52 | /** | 35 | /** |
53 | * If you want to get http information such as headers or status | 36 | * If you want to get http information such as headers or status |
54 | * Please return response => response | 37 | * Please return response => response |
55 | */ | 38 | */ |
56 | 39 | ||
57 | /** | 40 | /** |
58 | * Determine the request status by custom code | 41 | * Determine the request status by custom code |
59 | * Here is just an example | 42 | * Here is just an example |
60 | * You can also judge the status by HTTP Status Code | 43 | * You can also judge the status by HTTP Status Code |
61 | */ | 44 | */ |
62 | response => { | 45 | response => { |
63 | const res = response.data | 46 | const res = response.data |
64 | console.log('返回的数据-- step 1------>', res); | 47 | |
65 | /** | 48 | // if the custom code is not 20000, it is judged as an error. |
66 | * 下面的注释为通过response自定义code来标示请求状态,当code返回如下情况为权限有问题,登出并返回到登录页 | ||
67 | * 如通过xmlhttprequest 状态码标识 逻辑可写在下面error中 | ||
68 | */ | ||
69 | // console.log('if the custom code is not 20000, it is judged as an error.') | ||
70 | if (res.code !== 20000) { | 49 | if (res.code !== 20000) { |
71 | Message({ | 50 | Message({ |
72 | message: res.message || 'Error', | 51 | message: res.message || 'Error', |
73 | type: 'error', | 52 | type: 'error', |
74 | duration: 5 * 1000 | 53 | duration: 5 * 1000 |
75 | }) | 54 | }) |
76 | 55 | ||
77 | // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; | 56 | // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired; |
78 | if (res.code === 50008 || res.code === 50012 || res.code === 50014) { | 57 | if (res.code === 50008 || res.code === 50012 || res.code === 50014) { |
79 | // to re-login | 58 | // to re-login |
80 | // MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', { | 59 | MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', { |
81 | MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', { | 60 | confirmButtonText: 'Re-Login', |
82 | // confirmButtonText: 'Re-Login', | 61 | cancelButtonText: 'Cancel', |
83 | confirmButtonText: '重新登录', | ||
84 | // cancelButtonText: 'Cancel', | ||
85 | cancelButtonText: '取消', | ||
86 | type: 'warning' | 62 | type: 'warning' |
87 | }).then(() => { | 63 | }).then(() => { |
88 | store.dispatch('user/resetToken').then(() => { | 64 | store.dispatch('user/resetToken').then(() => { |
89 | location.reload() // 为了重新实例化vue-router对象 避免bug | 65 | location.reload() |
90 | }) | 66 | }) |
91 | }) | 67 | }) |
92 | } | 68 | } |
93 | return Promise.reject(new Error(res.message || 'Error')) | 69 | return Promise.reject(new Error(res.message || 'Error')) |
94 | } else { | 70 | } else { |
95 | // const token = res.data.token; | 71 | return res |
96 | console.log('进入20000号判断- step 2------->', res.data); | ||
97 | const data = res.data; | ||
98 | return data; | ||
99 | } | 72 | } |
100 | }, | 73 | }, |
101 | error => { | 74 | error => { |
102 | console.error('===============发生错误!!!!!===============' + error.message); // for debug | 75 | console.log('err' + error) // for debug |
103 | // Message({ | 76 | Message({ |
104 | // message: error.message, | 77 | message: error.message, |
105 | // type: 'error', | 78 | type: 'error', |
106 | // duration: 5 * 1000 | 79 | duration: 5 * 1000 |
107 | // }) | 80 | }) |
108 | return Promise.reject(error) | 81 | return Promise.reject(error) |
109 | } | 82 | } |
110 | ) | 83 | ) |
111 | 84 | ||
112 | export default service | 85 | export default service |
113 | 86 |
src/utils/scroll-to.js
File was created | 1 | Math.easeInOutQuad = function(t, b, c, d) { | |
2 | t /= d / 2 | ||
3 | if (t < 1) { | ||
4 | return c / 2 * t * t + b | ||
5 | } | ||
6 | t-- | ||
7 | return -c / 2 * (t * (t - 2) - 1) + b | ||
8 | } | ||
9 | |||
10 | // requestAnimationFrame for Smart Animating http://goo.gl/sx5sts | ||
11 | var requestAnimFrame = (function() { | ||
12 | return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) } | ||
13 | })() | ||
14 | |||
15 | /** | ||
16 | * Because it's so fucking difficult to detect the scrolling element, just move them all | ||
17 | * @param {number} amount | ||
18 | */ | ||
19 | function move(amount) { | ||
20 | document.documentElement.scrollTop = amount | ||
21 | document.body.parentNode.scrollTop = amount | ||
22 | document.body.scrollTop = amount | ||
23 | } | ||
24 | |||
25 | function position() { | ||
26 | return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop | ||
27 | } | ||
28 | |||
29 | /** | ||
30 | * @param {number} to | ||
31 | * @param {number} duration | ||
32 | * @param {Function} callback | ||
33 | */ | ||
34 | export function scrollTo(to, duration, callback) { | ||
35 | const start = position() | ||
36 | const change = to - start | ||
37 | const increment = 20 | ||
38 | let currentTime = 0 | ||
39 | duration = (typeof (duration) === 'undefined') ? 500 : duration | ||
40 | var animateScroll = function() { | ||
41 | // increment the time | ||
42 | currentTime += increment | ||
43 | // find the value with the quadratic in-out easing function | ||
44 | var val = Math.easeInOutQuad(currentTime, start, change, duration) | ||
45 | // move the document.body | ||
46 | move(val) | ||
47 | // do the animation unless its over | ||
48 | if (currentTime < duration) { | ||
49 | requestAnimFrame(animateScroll) | ||
50 | } else { | ||
51 | if (callback && typeof (callback) === 'function') { | ||
52 | // the animation is done so lets callback | ||
53 | callback() | ||
54 | } | ||
55 | } | ||
56 | } | ||
57 | animateScroll() | ||
58 | } | ||
59 |
src/utils/validate.js
1 | /** | 1 | /** |
2 | * Created by PanJiaChen on 16/11/18. | 2 | * Created by PanJiaChen on 16/11/18. |
3 | */ | 3 | */ |
4 | 4 | ||
5 | /** | 5 | /** |
6 | * @param {string} path | 6 | * @param {string} path |
7 | * @returns {Boolean} | 7 | * @returns {Boolean} |
8 | */ | 8 | */ |
9 | export function isExternal(path) { | 9 | export function isExternal(path) { |
10 | return /^(https?:|mailto:|tel:)/.test(path) | 10 | return /^(https?:|mailto:|tel:)/.test(path) |
11 | } | 11 | } |
12 | 12 | ||
13 | /** | 13 | /** |
14 | * @param {string} str | 14 | * @param {string} str |
15 | * @returns {Boolean} | 15 | * @returns {Boolean} |
16 | */ | 16 | */ |
17 | export function validUsername(str) { | 17 | export function validUsername(str) { |
18 | const valid_map = ['admin', 'editor'] | 18 | const valid_map = ['admin', 'editor'] |
19 | return valid_map.indexOf(str.trim()) >= 0 | 19 | return valid_map.indexOf(str.trim()) >= 0 |
20 | } | 20 | } |
21 | |||
22 | /** | ||
23 | * @param {string} url | ||
24 | * @returns {Boolean} | ||
25 | */ | ||
26 | export function validURL(url) { | ||
27 | const reg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/ | ||
28 | return reg.test(url) | ||
29 | } | ||
30 | |||
31 | /** | ||
32 | * @param {string} str | ||
33 | * @returns {Boolean} | ||
34 | */ | ||
35 | export function validLowerCase(str) { | ||
36 | const reg = /^[a-z]+$/ | ||
37 | return reg.test(str) | ||
38 | } | ||
39 | |||
40 | /** | ||
41 | * @param {string} str | ||
42 | * @returns {Boolean} | ||
43 | */ | ||
44 | export function validUpperCase(str) { | ||
45 | const reg = /^[A-Z]+$/ | ||
46 | return reg.test(str) | ||
47 | } | ||
48 | |||
49 | /** | ||
50 | * @param {string} str | ||
51 | * @returns {Boolean} | ||
52 | */ | ||
53 | export function validAlphabets(str) { | ||
54 | const reg = /^[A-Za-z]+$/ | ||
55 | return reg.test(str) | ||
56 | } | ||
57 | |||
58 | /** | ||
59 | * @param {string} email | ||
60 | * @returns {Boolean} | ||
61 | */ | ||
62 | export function validEmail(email) { | ||
63 | const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ | ||
64 | return reg.test(email) | ||
65 | } | ||
66 | |||
67 | /** | ||
68 | * @param {string} str | ||
69 | * @returns {Boolean} | ||
70 | */ | ||
71 | export function isString(str) { | ||
72 | if (typeof str === 'string' || str instanceof String) { | ||
73 | return true | ||
74 | } | ||
75 | return false | ||
76 | } | ||
77 | |||
78 | /** | ||
79 | * @param {Array} arg | ||
80 | * @returns {Boolean} | ||
81 | */ | ||
82 | export function isArray(arg) { | ||
83 | if (typeof Array.isArray === 'undefined') { | ||
84 | return Object.prototype.toString.call(arg) === '[object Array]' | ||
85 | } | ||
86 | return Array.isArray(arg) | ||
87 | } | ||
21 | 88 |
src/vendor/Export2Excel.js
File was created | 1 | /* eslint-disable */ | |
2 | import { saveAs } from 'file-saver' | ||
3 | import XLSX from 'xlsx' | ||
4 | |||
5 | function generateArray(table) { | ||
6 | var out = []; | ||
7 | var rows = table.querySelectorAll('tr'); | ||
8 | var ranges = []; | ||
9 | for (var R = 0; R < rows.length; ++R) { | ||
10 | var outRow = []; | ||
11 | var row = rows[R]; | ||
12 | var columns = row.querySelectorAll('td'); | ||
13 | for (var C = 0; C < columns.length; ++C) { | ||
14 | var cell = columns[C]; | ||
15 | var colspan = cell.getAttribute('colspan'); | ||
16 | var rowspan = cell.getAttribute('rowspan'); | ||
17 | var cellValue = cell.innerText; | ||
18 | if (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue; | ||
19 | |||
20 | //Skip ranges | ||
21 | ranges.forEach(function (range) { | ||
22 | if (R >= range.s.r && R <= range.e.r && outRow.length >= range.s.c && outRow.length <= range.e.c) { | ||
23 | for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null); | ||
24 | } | ||
25 | }); | ||
26 | |||
27 | //Handle Row Span | ||
28 | if (rowspan || colspan) { | ||
29 | rowspan = rowspan || 1; | ||
30 | colspan = colspan || 1; | ||
31 | ranges.push({ | ||
32 | s: { | ||
33 | r: R, | ||
34 | c: outRow.length | ||
35 | }, | ||
36 | e: { | ||
37 | r: R + rowspan - 1, | ||
38 | c: outRow.length + colspan - 1 | ||
39 | } | ||
40 | }); | ||
41 | }; | ||
42 | |||
43 | //Handle Value | ||
44 | outRow.push(cellValue !== "" ? cellValue : null); | ||
45 | |||
46 | //Handle Colspan | ||
47 | if (colspan) | ||
48 | for (var k = 0; k < colspan - 1; ++k) outRow.push(null); | ||
49 | } | ||
50 | out.push(outRow); | ||
51 | } | ||
52 | return [out, ranges]; | ||
53 | }; | ||
54 | |||
55 | function datenum(v, date1904) { | ||
56 | if (date1904) v += 1462; | ||
57 | var epoch = Date.parse(v); | ||
58 | return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000); | ||
59 | } | ||
60 | |||
61 | function sheet_from_array_of_arrays(data, opts) { | ||
62 | var ws = {}; | ||
63 | var range = { | ||
64 | s: { | ||
65 | c: 10000000, | ||
66 | r: 10000000 | ||
67 | }, | ||
68 | e: { | ||
69 | c: 0, | ||
70 | r: 0 | ||
71 | } | ||
72 | }; | ||
73 | for (var R = 0; R != data.length; ++R) { | ||
74 | for (var C = 0; C != data[R].length; ++C) { | ||
75 | if (range.s.r > R) range.s.r = R; | ||
76 | if (range.s.c > C) range.s.c = C; | ||
77 | if (range.e.r < R) range.e.r = R; | ||
78 | if (range.e.c < C) range.e.c = C; | ||
79 | var cell = { | ||
80 | v: data[R][C] | ||
81 | }; | ||
82 | if (cell.v == null) continue; | ||
83 | var cell_ref = XLSX.utils.encode_cell({ | ||
84 | c: C, | ||
85 | r: R | ||
86 | }); | ||
87 | |||
88 | if (typeof cell.v === 'number') cell.t = 'n'; | ||
89 | else if (typeof cell.v === 'boolean') cell.t = 'b'; | ||
90 | else if (cell.v instanceof Date) { | ||
91 | cell.t = 'n'; | ||
92 | cell.z = XLSX.SSF._table[14]; | ||
93 | cell.v = datenum(cell.v); | ||
94 | } else cell.t = 's'; | ||
95 | |||
96 | ws[cell_ref] = cell; | ||
97 | } | ||
98 | } | ||
99 | if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range); | ||
100 | return ws; | ||
101 | } | ||
102 | |||
103 | function Workbook() { | ||
104 | if (!(this instanceof Workbook)) return new Workbook(); | ||
105 | this.SheetNames = []; | ||
106 | this.Sheets = {}; | ||
107 | } | ||
108 | |||
109 | function s2ab(s) { | ||
110 | var buf = new ArrayBuffer(s.length); | ||
111 | var view = new Uint8Array(buf); | ||
112 | for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF; | ||
113 | return buf; | ||
114 | } | ||
115 | |||
116 | export function export_table_to_excel(id) { | ||
117 | var theTable = document.getElementById(id); | ||
118 | var oo = generateArray(theTable); | ||
119 | var ranges = oo[1]; | ||
120 | |||
121 | /* original data */ | ||
122 | var data = oo[0]; | ||
123 | var ws_name = "SheetJS"; | ||
124 | |||
125 | var wb = new Workbook(), | ||
126 | ws = sheet_from_array_of_arrays(data); | ||
127 | |||
128 | /* add ranges to worksheet */ | ||
129 | // ws['!cols'] = ['apple', 'banan']; | ||
130 | ws['!merges'] = ranges; | ||
131 | |||
132 | /* add worksheet to workbook */ | ||
133 | wb.SheetNames.push(ws_name); | ||
134 | wb.Sheets[ws_name] = ws; | ||
135 | |||
136 | var wbout = XLSX.write(wb, { | ||
137 | bookType: 'xlsx', | ||
138 | bookSST: false, | ||
139 | type: 'binary' | ||
140 | }); | ||
141 | |||
142 | saveAs(new Blob([s2ab(wbout)], { | ||
143 | type: "application/octet-stream" | ||
144 | }), "test.xlsx") | ||
145 | } | ||
146 | |||
147 | export function export_json_to_excel({ | ||
148 | multiHeader = [], | ||
149 | header, | ||
150 | data, | ||
151 | filename, | ||
152 | merges = [], | ||
153 | autoWidth = true, | ||
154 | bookType = 'xlsx' | ||
155 | } = {}) { | ||
156 | /* original data */ | ||
157 | filename = filename || 'excel-list' | ||
158 | data = [...data] | ||
159 | data.unshift(header); | ||
160 | |||
161 | for (let i = multiHeader.length - 1; i > -1; i--) { | ||
162 | data.unshift(multiHeader[i]) | ||
163 | } | ||
164 | |||
165 | var ws_name = "SheetJS"; | ||
166 | var wb = new Workbook(), | ||
167 | ws = sheet_from_array_of_arrays(data); | ||
168 | |||
169 | if (merges.length > 0) { | ||
170 | if (!ws['!merges']) ws['!merges'] = []; | ||
171 | merges.forEach(item => { | ||
172 | ws['!merges'].push(XLSX.utils.decode_range(item)) | ||
173 | }) | ||
174 | } | ||
175 | |||
176 | if (autoWidth) { | ||
177 | /*设置worksheet每列的最大宽度*/ | ||
178 | const colWidth = data.map(row => row.map(val => { | ||
179 | /*先判断是否为null/undefined*/ | ||
180 | if (val == null) { | ||
181 | return { | ||
182 | 'wch': 10 | ||
183 | }; | ||
184 | } | ||
185 | /*再判断是否为中文*/ | ||
186 | else if (val.toString().charCodeAt(0) > 255) { | ||
187 | return { | ||
188 | 'wch': val.toString().length * 2 | ||
189 | }; | ||
190 | } else { | ||
191 | return { | ||
192 | 'wch': val.toString().length | ||
193 | }; | ||
194 | } | ||
195 | })) | ||
196 | /*以第一行为初始值*/ | ||
197 | let result = colWidth[0]; | ||
198 | for (let i = 1; i < colWidth.length; i++) { | ||
199 | for (let j = 0; j < colWidth[i].length; j++) { | ||
200 | if (result[j]['wch'] < colWidth[i][j]['wch']) { | ||
201 | result[j]['wch'] = colWidth[i][j]['wch']; | ||
202 | } | ||
203 | } | ||
204 | } | ||
205 | ws['!cols'] = result; | ||
206 | } | ||
207 | |||
208 | /* add worksheet to workbook */ | ||
209 | wb.SheetNames.push(ws_name); | ||
210 | wb.Sheets[ws_name] = ws; | ||
211 | |||
212 | var wbout = XLSX.write(wb, { | ||
213 | bookType: bookType, | ||
214 | bookSST: false, | ||
215 | type: 'binary' | ||
216 | }); | ||
217 | saveAs(new Blob([s2ab(wbout)], { | ||
218 | type: "application/octet-stream" | ||
219 | }), `${filename}.${bookType}`); | ||
220 | } | ||
221 |
src/vendor/Export2Zip.js
File was created | 1 | /* eslint-disable */ | |
2 | import { saveAs } from 'file-saver' | ||
3 | import JSZip from 'jszip' | ||
4 | |||
5 | export function export_txt_to_zip(th, jsonData, txtName, zipName) { | ||
6 | const zip = new JSZip() | ||
7 | const txt_name = txtName || 'file' | ||
8 | const zip_name = zipName || 'file' | ||
9 | const data = jsonData | ||
10 | let txtData = `${th}\r\n` | ||
11 | data.forEach((row) => { | ||
12 | let tempStr = '' | ||
13 | tempStr = row.toString() | ||
14 | txtData += `${tempStr}\r\n` | ||
15 | }) | ||
16 | zip.file(`${txt_name}.txt`, txtData) | ||
17 | zip.generateAsync({ | ||
18 | type: "blob" | ||
19 | }).then((blob) => { | ||
20 | saveAs(blob, `${zip_name}.zip`) | ||
21 | }, (err) => { | ||
22 | alert('导出失败') | ||
23 | }) | ||
24 | } | ||
25 |
src/views/404.vue
1 | <template> | File was deleted | |
2 | <div class="wscn-http404-container"> | ||
3 | <div class="wscn-http404"> | ||
4 | <div class="pic-404"> | ||
5 | <img class="pic-404__parent" src="@/assets/404_images/404.png" alt="404" /> | ||
6 | <img class="pic-404__child left" src="@/assets/404_images/404_cloud.png" alt="404" /> | ||
7 | <img class="pic-404__child mid" src="@/assets/404_images/404_cloud.png" alt="404" /> | ||
8 | <img class="pic-404__child right" src="@/assets/404_images/404_cloud.png" alt="404" /> | ||
9 | </div> | ||
10 | <div class="bullshit"> | ||
11 | <div class="bullshit__oops">OOPS!</div> | ||
12 | <div class="bullshit__info"> | ||
13 | All rights reserved | ||
14 | <a | ||
15 | style="color:#20a0ff" | ||
16 | href="https://wallstreetcn.com" | ||
17 | target="_blank" | ||
18 | >wallstreetcn</a> | ||
19 | </div> | ||
20 | <div class="bullshit__headline">{{ message }}</div> | ||
21 | <div | ||
22 | class="bullshit__info" | ||
23 | >Please check that the URL you entered is correct, or click the button below to return to the homepage.</div> | ||
24 | <a href class="bullshit__return-home">Back to home</a> | ||
25 | </div> | ||
26 | </div> | ||
27 | </div> | ||
28 | </template> | ||
29 | |||
30 | <script> | ||
31 | export default { | ||
32 | name: "Page404", | ||
33 | computed: { | ||
34 | message() { | ||
35 | return "The webmaster said that you can not enter this page..."; | ||
36 | } | ||
37 | } | ||
38 | }; | ||
39 | </script> | ||
40 | |||
41 | <style lang="scss" scoped> | ||
42 | .wscn-http404-container { | ||
43 | transform: translate(-50%, -50%); | ||
44 | position: absolute; | ||
45 | top: 40%; | ||
46 | left: 50%; | ||
47 | } | ||
48 | .wscn-http404 { | ||
49 | position: relative; | ||
50 | width: 1200px; | ||
51 | padding: 0 50px; | ||
52 | overflow: hidden; | ||
53 | .pic-404 { | ||
54 | position: relative; | ||
55 | float: left; | ||
56 | width: 600px; | ||
57 | overflow: hidden; | ||
58 | &__parent { | ||
59 | width: 100%; | ||
60 | } | ||
61 | &__child { | ||
62 | position: absolute; | ||
63 | &.left { | ||
64 | width: 80px; | ||
65 | top: 17px; | ||
66 | left: 220px; | ||
67 | opacity: 0; | ||
68 | animation-name: cloudLeft; | ||
69 | animation-duration: 2s; | ||
70 | animation-timing-function: linear; | ||
71 | animation-fill-mode: forwards; | ||
72 | animation-delay: 1s; | ||
73 | } | ||
74 | &.mid { | ||
75 | width: 46px; | ||
76 | top: 10px; | ||
77 | left: 420px; | ||
78 | opacity: 0; | ||
79 | animation-name: cloudMid; | ||
80 | animation-duration: 2s; | ||
81 | animation-timing-function: linear; | ||
82 | animation-fill-mode: forwards; | ||
83 | animation-delay: 1.2s; | ||
84 | } | ||
85 | &.right { | ||
86 | width: 62px; | ||
87 | top: 100px; | ||
88 | left: 500px; | ||
89 | opacity: 0; | ||
90 | animation-name: cloudRight; | ||
91 | animation-duration: 2s; | ||
92 | animation-timing-function: linear; | ||
93 | animation-fill-mode: forwards; | ||
94 | animation-delay: 1s; | ||
95 | } | ||
96 | @keyframes cloudLeft { | ||
97 | 0% { | ||
98 | top: 17px; | ||
99 | left: 220px; | ||
100 | opacity: 0; | ||
101 | } | ||
102 | 20% { | ||
103 | top: 33px; | ||
104 | left: 188px; | ||
105 | opacity: 1; | ||
106 | } | ||
107 | 80% { | ||
108 | top: 81px; | ||
109 | left: 92px; | ||
110 | opacity: 1; | ||
111 | } | ||
112 | 100% { | ||
113 | top: 97px; | ||
114 | left: 60px; | ||
115 | opacity: 0; | ||
116 | } | ||
117 | } | ||
118 | @keyframes cloudMid { | ||
119 | 0% { | ||
120 | top: 10px; | ||
121 | left: 420px; | ||
122 | opacity: 0; | ||
123 | } | ||
124 | 20% { | ||
125 | top: 40px; | ||
126 | left: 360px; | ||
127 | opacity: 1; | ||
128 | } | ||
129 | 70% { | ||
130 | top: 130px; | ||
131 | left: 180px; | ||
132 | opacity: 1; | ||
133 | } | ||
134 | 100% { | ||
135 | top: 160px; | ||
136 | left: 120px; | ||
137 | opacity: 0; | ||
138 | } | ||
139 | } | ||
140 | @keyframes cloudRight { | ||
141 | 0% { | ||
142 | top: 100px; | ||
143 | left: 500px; | ||
144 | opacity: 0; | ||
145 | } | ||
146 | 20% { | ||
147 | top: 120px; | ||
148 | left: 460px; | ||
149 | opacity: 1; | ||
150 | } | ||
151 | 80% { | ||
152 | top: 180px; | ||
153 | left: 340px; | ||
154 | opacity: 1; | ||
155 | } | ||
156 | 100% { | ||
157 | top: 200px; | ||
158 | left: 300px; | ||
159 | opacity: 0; | ||
160 | } | ||
161 | } | ||
162 | } | ||
163 | } | ||
164 | .bullshit { | ||
165 | position: relative; | ||
166 | float: left; | ||
167 | width: 300px; | ||
168 | padding: 30px 0; | ||
169 | overflow: hidden; | ||
170 | &__oops { | ||
171 | font-size: 32px; | ||
172 | font-weight: bold; | ||
173 | line-height: 40px; | ||
174 | color: #1482f0; | ||
175 | opacity: 0; | ||
176 | margin-bottom: 20px; | ||
177 | animation-name: slideUp; | ||
178 | animation-duration: 0.5s; | ||
179 | animation-fill-mode: forwards; | ||
180 | } | ||
181 | &__headline { | ||
182 | font-size: 20px; | ||
183 | line-height: 24px; | ||
184 | color: #222; | ||
185 | font-weight: bold; | ||
186 | opacity: 0; | ||
187 | margin-bottom: 10px; | ||
188 | animation-name: slideUp; | ||
189 | animation-duration: 0.5s; | ||
190 | animation-delay: 0.1s; | ||
191 | animation-fill-mode: forwards; | ||
192 | } | ||
193 | &__info { | ||
194 | font-size: 13px; | ||
195 | line-height: 21px; | ||
196 | color: grey; | ||
197 | opacity: 0; | ||
198 | margin-bottom: 30px; | ||
199 | animation-name: slideUp; | ||
200 | animation-duration: 0.5s; | ||
201 | animation-delay: 0.2s; | ||
202 | animation-fill-mode: forwards; | ||
203 | } | ||
204 | &__return-home { | ||
205 | display: block; | ||
206 | float: left; | ||
207 | width: 110px; | ||
208 | height: 36px; | ||
209 | background: #1482f0; | ||
210 | border-radius: 100px; | ||
211 | text-align: center; | ||
212 | color: #ffffff; | ||
213 | opacity: 0; | ||
214 | font-size: 14px; | ||
215 | line-height: 36px; | ||
216 | cursor: pointer; | ||
217 | animation-name: slideUp; | ||
218 | animation-duration: 0.5s; | ||
219 | animation-delay: 0.3s; | ||
220 | animation-fill-mode: forwards; | ||
221 | } | ||
222 | @keyframes slideUp { | ||
223 | 0% { | ||
224 | transform: translateY(60px); | ||
225 | opacity: 0; | ||
226 | } | ||
227 | 100% { | ||
228 | transform: translateY(0); | ||
229 | opacity: 1; | ||
230 | } | ||
231 | } | ||
232 | } | ||
233 | } | ||
234 | </style> | ||
235 | 1 | <template> |
src/views/charts/keyboard.vue
File was created | 1 | <template> | |
2 | <div class="chart-container"> | ||
3 | <chart height="100%" width="100%" /> | ||
4 | </div> | ||
5 | </template> | ||
6 | |||
7 | <script> | ||
8 | import Chart from '@/components/Charts/Keyboard' | ||
9 | |||
10 | export default { | ||
11 | name: 'KeyboardChart', | ||
12 | components: { Chart } | ||
13 | } | ||
14 | </script> | ||
15 | |||
16 | <style scoped> | ||
17 | .chart-container{ | ||
18 | position: relative; | ||
19 | width: 100%; | ||
20 | height: calc(100vh - 84px); | ||
21 | } | ||
22 | </style> | ||
23 | |||
24 |
src/views/charts/line.vue
File was created | 1 | <template> | |
2 | <div class="chart-container"> | ||
3 | <chart height="100%" width="100%" /> | ||
4 | </div> | ||
5 | </template> | ||
6 | |||
7 | <script> | ||
8 | import Chart from '@/components/Charts/LineMarker' | ||
9 | |||
10 | export default { | ||
11 | name: 'LineChart', | ||
12 | components: { Chart } | ||
13 | } | ||
14 | </script> | ||
15 | |||
16 | <style scoped> | ||
17 | .chart-container{ | ||
18 | position: relative; | ||
19 | width: 100%; | ||
20 | height: calc(100vh - 84px); | ||
21 | } | ||
22 | </style> | ||
23 | |||
24 |
src/views/charts/mix-chart.vue
File was created | 1 | <template> | |
2 | <div class="chart-container"> | ||
3 | <chart height="100%" width="100%" /> | ||
4 | </div> | ||
5 | </template> | ||
6 | |||
7 | <script> | ||
8 | import Chart from '@/components/Charts/MixChart' | ||
9 | |||
10 | export default { | ||
11 | name: 'MixChart', | ||
12 | components: { Chart } | ||
13 | } | ||
14 | </script> | ||
15 | |||
16 | <style scoped> | ||
17 | .chart-container{ | ||
18 | position: relative; | ||
19 | width: 100%; | ||
20 | height: calc(100vh - 84px); | ||
21 | } | ||
22 | </style> | ||
23 | |||
24 |
src/views/clipboard/index.vue
File was created | 1 | <template> | |
2 | <div class="app-container"> | ||
3 | <el-tabs v-model="activeName"> | ||
4 | <el-tab-pane label="use clipboard directly" name="directly"> | ||
5 | <el-input v-model="inputData" placeholder="Please input" style="width:400px;max-width:100%;" /> | ||
6 | <el-button type="primary" icon="el-icon-document" @click="handleCopy(inputData,$event)"> | ||
7 | copy | ||
8 | </el-button> | ||
9 | </el-tab-pane> | ||
10 | <el-tab-pane label="use clipboard by v-directive" name="v-directive"> | ||
11 | <el-input v-model="inputData" placeholder="Please input" style="width:400px;max-width:100%;" /> | ||
12 | <el-button v-clipboard:copy="inputData" v-clipboard:success="clipboardSuccess" type="primary" icon="el-icon-document"> | ||
13 | copy | ||
14 | </el-button> | ||
15 | </el-tab-pane> | ||
16 | </el-tabs> | ||
17 | </div> | ||
18 | </template> | ||
19 | |||
20 | <script> | ||
21 | import clip from '@/utils/clipboard' // use clipboard directly | ||
22 | import clipboard from '@/directive/clipboard/index.js' // use clipboard by v-directive | ||
23 | |||
24 | export default { | ||
25 | name: 'ClipboardDemo', | ||
26 | directives: { | ||
27 | clipboard | ||
28 | }, | ||
29 | data() { | ||
30 | return { | ||
31 | activeName: 'directly', | ||
32 | inputData: 'https://github.com/PanJiaChen/vue-element-admin' | ||
33 | } | ||
34 | }, | ||
35 | methods: { | ||
36 | handleCopy(text, event) { | ||
37 | clip(text, event) | ||
38 | }, | ||
39 | clipboardSuccess() { | ||
40 | this.$message({ | ||
41 | message: 'Copy successfully', | ||
42 | type: 'success', | ||
43 | duration: 1500 | ||
44 | }) | ||
45 | } | ||
46 | } | ||
47 | } | ||
48 | </script> | ||
49 | |||
50 |
src/views/components-demo/avatar-upload.vue
File was created | 1 | <template> | |
2 | <div class="components-container"> | ||
3 | <aside>This is based on | ||
4 | <a class="link-type" href="//github.com/dai-siki/vue-image-crop-upload"> vue-image-crop-upload</a>. | ||
5 | {{ $t('components.imageUploadTips') }} | ||
6 | </aside> | ||
7 | |||
8 | <pan-thumb :image="image" /> | ||
9 | |||
10 | <el-button type="primary" icon="el-icon-upload" style="position: absolute;bottom: 15px;margin-left: 40px;" @click="imagecropperShow=true"> | ||
11 | Change Avatar | ||
12 | </el-button> | ||
13 | |||
14 | <image-cropper | ||
15 | v-show="imagecropperShow" | ||
16 | :key="imagecropperKey" | ||
17 | :width="300" | ||
18 | :height="300" | ||
19 | url="https://httpbin.org/post" | ||
20 | lang-type="en" | ||
21 | @close="close" | ||
22 | @crop-upload-success="cropSuccess" | ||
23 | /> | ||
24 | </div> | ||
25 | </template> | ||
26 | |||
27 | <script> | ||
28 | import ImageCropper from '@/components/ImageCropper' | ||
29 | import PanThumb from '@/components/PanThumb' | ||
30 | |||
31 | export default { | ||
32 | name: 'AvatarUploadDemo', | ||
33 | components: { ImageCropper, PanThumb }, | ||
34 | data() { | ||
35 | return { | ||
36 | imagecropperShow: false, | ||
37 | imagecropperKey: 0, | ||
38 | image: 'https://wpimg.wallstcn.com/577965b9-bb9e-4e02-9f0c-095b41417191' | ||
39 | } | ||
40 | }, | ||
41 | methods: { | ||
42 | cropSuccess(resData) { | ||
43 | this.imagecropperShow = false | ||
44 | this.imagecropperKey = this.imagecropperKey + 1 | ||
45 | this.image = resData.files.avatar | ||
46 | }, | ||
47 | close() { | ||
48 | this.imagecropperShow = false | ||
49 | } | ||
50 | } | ||
51 | } | ||
52 | </script> | ||
53 | |||
54 | <style scoped> | ||
55 | .avatar{ | ||
56 | width: 200px; | ||
57 | height: 200px; | ||
58 | border-radius: 50%; | ||
59 | } | ||
60 | </style> | ||
61 | |||
62 |
src/views/components-demo/back-to-top.vue
File was created | 1 | <template> | |
2 | <div class="components-container"> | ||
3 | <aside>{{ $t('components.backToTopTips1') }}</aside> | ||
4 | <aside>{{ $t('components.backToTopTips2') }}</aside> | ||
5 | <div class="placeholder-container"> | ||
6 | <div>placeholder</div> | ||
7 | <div>placeholder</div> | ||
8 | <div>placeholder</div> | ||
9 | <div>placeholder</div> | ||
10 | <div>placeholder</div> | ||
11 | <div>placeholder</div> | ||
12 | <div>placeholder</div> | ||
13 | <div>placeholder</div> | ||
14 | <div>placeholder</div> | ||
15 | <div>placeholder</div> | ||
16 | <div>placeholder</div> | ||
17 | <div>placeholder</div> | ||
18 | <div>placeholder</div> | ||
19 | <div>placeholder</div> | ||
20 | <div>placeholder</div> | ||
21 | <div>placeholder</div> | ||
22 | <div>placeholder</div> | ||
23 | <div>placeholder</div> | ||
24 | <div>placeholder</div> | ||
25 | <div>placeholder</div> | ||
26 | <div>placeholder</div> | ||
27 | <div>placeholder</div> | ||
28 | <div>placeholder</div> | ||
29 | <div>placeholder</div> | ||
30 | <div>placeholder</div> | ||
31 | <div>placeholder</div> | ||
32 | <div>placeholder</div> | ||
33 | <div>placeholder</div> | ||
34 | <div>placeholder</div> | ||
35 | <div>placeholder</div> | ||
36 | <div>placeholder</div> | ||
37 | <div>placeholder</div> | ||
38 | <div>placeholder</div> | ||
39 | <div>placeholder</div> | ||
40 | <div>placeholder</div> | ||
41 | <div>placeholder</div> | ||
42 | <div>placeholder</div> | ||
43 | <div>placeholder</div> | ||
44 | <div>placeholder</div> | ||
45 | <div>placeholder</div> | ||
46 | <div>placeholder</div> | ||
47 | <div>placeholder</div> | ||
48 | <div>placeholder</div> | ||
49 | <div>placeholder</div> | ||
50 | <div>placeholder</div> | ||
51 | <div>placeholder</div> | ||
52 | <div>placeholder</div> | ||
53 | <div>placeholder</div> | ||
54 | <div>placeholder</div> | ||
55 | <div>placeholder</div> | ||
56 | <div>placeholder</div> | ||
57 | <div>placeholder</div> | ||
58 | <div>placeholder</div> | ||
59 | <div>placeholder</div> | ||
60 | <div>placeholder</div> | ||
61 | <div>placeholder</div> | ||
62 | <div>placeholder</div> | ||
63 | <div>placeholder</div> | ||
64 | <div>placeholder</div> | ||
65 | <div>placeholder</div> | ||
66 | <div>placeholder</div> | ||
67 | <div>placeholder</div> | ||
68 | <div>placeholder</div> | ||
69 | <div>placeholder</div> | ||
70 | <div>placeholder</div> | ||
71 | <div>placeholder</div> | ||
72 | <div>placeholder</div> | ||
73 | <div>placeholder</div> | ||
74 | <div>placeholder</div> | ||
75 | <div>placeholder</div> | ||
76 | <div>placeholder</div> | ||
77 | <div>placeholder</div> | ||
78 | <div>placeholder</div> | ||
79 | <div>placeholder</div> | ||
80 | <div>placeholder</div> | ||
81 | <div>placeholder</div> | ||
82 | <div>placeholder</div> | ||
83 | <div>placeholder</div> | ||
84 | <div>placeholder</div> | ||
85 | <div>placeholder</div> | ||
86 | <div>placeholder</div> | ||
87 | <div>placeholder</div> | ||
88 | <div>placeholder</div> | ||
89 | <div>placeholder</div> | ||
90 | <div>placeholder</div> | ||
91 | <div>placeholder</div> | ||
92 | <div>placeholder</div> | ||
93 | <div>placeholder</div> | ||
94 | <div>placeholder</div> | ||
95 | <div>placeholder</div> | ||
96 | <div>placeholder</div> | ||
97 | <div>placeholder</div> | ||
98 | <div>placeholder</div> | ||
99 | <div>placeholder</div> | ||
100 | <div>placeholder</div> | ||
101 | <div>placeholder</div> | ||
102 | <div>placeholder</div> | ||
103 | <div>placeholder</div> | ||
104 | <div>placeholder</div> | ||
105 | <div>placeholder</div> | ||
106 | <div>placeholder</div> | ||
107 | <div>placeholder</div> | ||
108 | <div>placeholder</div> | ||
109 | <div>placeholder</div> | ||
110 | <div>placeholder</div> | ||
111 | <div>placeholder</div> | ||
112 | <div>placeholder</div> | ||
113 | <div>placeholder</div> | ||
114 | <div>placeholder</div> | ||
115 | </div> | ||
116 | <!-- you can add element-ui's tooltip --> | ||
117 | <el-tooltip placement="top" content="tooltip"> | ||
118 | <back-to-top :custom-style="myBackToTopStyle" :visibility-height="300" :back-position="50" transition-name="fade" /> | ||
119 | </el-tooltip> | ||
120 | </div> | ||
121 | </template> | ||
122 | |||
123 | <script> | ||
124 | import BackToTop from '@/components/BackToTop' | ||
125 | |||
126 | export default { | ||
127 | name: 'BackToTopDemo', | ||
128 | components: { BackToTop }, | ||
129 | data() { | ||
130 | return { | ||
131 | // customizable button style, show/hide critical point, return position | ||
132 | myBackToTopStyle: { | ||
133 | right: '50px', | ||
134 | bottom: '50px', | ||
135 | width: '40px', | ||
136 | height: '40px', | ||
137 | 'border-radius': '4px', | ||
138 | 'line-height': '45px', // 请保持与高度一致以垂直居中 Please keep consistent with height to center vertically | ||
139 | background: '#e7eaf1'// 按钮的背景颜色 The background color of the button | ||
140 | } | ||
141 | } | ||
142 | } | ||
143 | } | ||
144 | </script> | ||
145 | |||
146 | <style scoped> | ||
147 | .placeholder-container div { | ||
148 | margin: 10px; | ||
149 | } | ||
150 | </style> | ||
151 |
src/views/components-demo/count-to.vue
File was created | 1 | <template> | |
2 | <div class="components-container"> | ||
3 | <aside> | ||
4 | <a href="https://github.com/PanJiaChen/vue-countTo" target="_blank">countTo-component</a> | ||
5 | </aside> | ||
6 | <count-to | ||
7 | ref="example" | ||
8 | :start-val="_startVal" | ||
9 | :end-val="_endVal" | ||
10 | :duration="_duration" | ||
11 | :decimals="_decimals" | ||
12 | :separator="_separator" | ||
13 | :prefix="_prefix" | ||
14 | :suffix="_suffix" | ||
15 | :autoplay="false" | ||
16 | class="example" | ||
17 | /> | ||
18 | <div style="margin-left: 25%;margin-top: 40px;"> | ||
19 | <label class="label" for="startValInput">startVal: | ||
20 | <input v-model.number="setStartVal" type="number" name="startValInput"> | ||
21 | </label> | ||
22 | <label class="label" for="endValInput">endVal: | ||
23 | <input v-model.number="setEndVal" type="number" name="endVaInput"> | ||
24 | </label> | ||
25 | <label class="label" for="durationInput">duration: | ||
26 | <input v-model.number="setDuration" type="number" name="durationInput"> | ||
27 | </label> | ||
28 | <div class="startBtn example-btn" @click="start"> | ||
29 | Start | ||
30 | </div> | ||
31 | <div class="pause-resume-btn example-btn" @click="pauseResume"> | ||
32 | pause/resume | ||
33 | </div> | ||
34 | <br> | ||
35 | <label class="label" for="decimalsInput">decimals: | ||
36 | <input v-model.number="setDecimals" type="number" name="decimalsInput"> | ||
37 | </label> | ||
38 | <label class="label" for="separatorInput">separator: | ||
39 | <input v-model="setSeparator" name="separatorInput"> | ||
40 | </label> | ||
41 | <label class="label" for="prefixInput">prefix: | ||
42 | <input v-model="setPrefix" name="prefixInput"> | ||
43 | </label> | ||
44 | <label class="label" for="suffixInput">suffix: | ||
45 | <input v-model="setSuffix" name="suffixInput"> | ||
46 | </label> | ||
47 | </div> | ||
48 | <aside><count-to :start-val='{{ _startVal }}' :end-val='{{ _endVal }}' :duration='{{ _duration }}' | ||
49 | :decimals='{{ _decimals }}' :separator='{{ _separator }}' :prefix='{{ _prefix }}' :suffix='{{ _suffix }}' | ||
50 | :autoplay=false></aside> | ||
51 | </div> | ||
52 | </template> | ||
53 | |||
54 | <script> | ||
55 | import countTo from 'vue-count-to' | ||
56 | |||
57 | export default { | ||
58 | name: 'CountToDemo', | ||
59 | components: { countTo }, | ||
60 | data() { | ||
61 | return { | ||
62 | setStartVal: 0, | ||
63 | setEndVal: 2017, | ||
64 | setDuration: 4000, | ||
65 | setDecimals: 0, | ||
66 | setSeparator: ',', | ||
67 | setSuffix: ' rmb', | ||
68 | setPrefix: '¥ ' | ||
69 | } | ||
70 | }, | ||
71 | computed: { | ||
72 | _startVal() { | ||
73 | if (this.setStartVal) { | ||
74 | return this.setStartVal | ||
75 | } else { | ||
76 | return 0 | ||
77 | } | ||
78 | }, | ||
79 | _endVal() { | ||
80 | if (this.setEndVal) { | ||
81 | return this.setEndVal | ||
82 | } else { | ||
83 | return 0 | ||
84 | } | ||
85 | }, | ||
86 | _duration() { | ||
87 | if (this.setDuration) { | ||
88 | return this.setDuration | ||
89 | } else { | ||
90 | return 100 | ||
91 | } | ||
92 | }, | ||
93 | _decimals() { | ||
94 | if (this.setDecimals) { | ||
95 | if (this.setDecimals < 0 || this.setDecimals > 20) { | ||
96 | alert('digits argument must be between 0 and 20') | ||
97 | return 0 | ||
98 | } | ||
99 | return this.setDecimals | ||
100 | } else { | ||
101 | return 0 | ||
102 | } | ||
103 | }, | ||
104 | _separator() { | ||
105 | return this.setSeparator | ||
106 | }, | ||
107 | _suffix() { | ||
108 | return this.setSuffix | ||
109 | }, | ||
110 | _prefix() { | ||
111 | return this.setPrefix | ||
112 | } | ||
113 | }, | ||
114 | methods: { | ||
115 | start() { | ||
116 | this.$refs.example.start() | ||
117 | }, | ||
118 | pauseResume() { | ||
119 | this.$refs.example.pauseResume() | ||
120 | } | ||
121 | } | ||
122 | } | ||
123 | </script> | ||
124 | |||
125 | <style scoped> | ||
126 | .example-btn { | ||
127 | display: inline-block; | ||
128 | margin-bottom: 0; | ||
129 | font-weight: 500; | ||
130 | text-align: center; | ||
131 | -ms-touch-action: manipulation; | ||
132 | touch-action: manipulation; | ||
133 | cursor: pointer; | ||
134 | background-image: none; | ||
135 | border: 1px solid transparent; | ||
136 | white-space: nowrap; | ||
137 | line-height: 1.5; | ||
138 | padding: 4px 15px; | ||
139 | font-size: 12px; | ||
140 | border-radius: 4px; | ||
141 | -webkit-user-select: none; | ||
142 | -moz-user-select: none; | ||
143 | -ms-user-select: none; | ||
144 | user-select: none; | ||
145 | -webkit-transition: all .3s cubic-bezier(.645, .045, .355, 1); | ||
146 | transition: all .3s cubic-bezier(.645, .045, .355, 1); | ||
147 | position: relative; | ||
148 | color: rgba(0, 0, 0, .65); | ||
149 | background-color: #fff; | ||
150 | border-color: #d9d9d9; | ||
151 | } | ||
152 | |||
153 | .example-btn:hover { | ||
154 | color: #4AB7BD; | ||
155 | background-color: #fff; | ||
156 | border-color: #4AB7BD; | ||
157 | } | ||
158 | .example { | ||
159 | font-size: 50px; | ||
160 | color: #F6416C; | ||
161 | display: block; | ||
162 | margin: 10px 0; | ||
163 | text-align: center; | ||
164 | font-size: 80px; | ||
165 | font-weight: 500; | ||
166 | } | ||
167 | |||
168 | .label { | ||
169 | color: #2f4f4f; | ||
170 | font-size: 16px; | ||
171 | display: inline-block; | ||
172 | margin: 15px 30px 15px 0; | ||
173 | } | ||
174 | |||
175 | input { | ||
176 | position: relative; | ||
177 | display: inline-block; | ||
178 | padding: 4px 7px; | ||
179 | width: 70px; | ||
180 | height: 28px; | ||
181 | cursor: text; | ||
182 | font-size: 12px; | ||
183 | line-height: 1.5; | ||
184 | color: rgba(0, 0, 0, .65); | ||
185 | background-color: #fff; | ||
186 | background-image: none; | ||
187 | border: 1px solid #d9d9d9; | ||
188 | border-radius: 4px; | ||
189 | -webkit-transition: all .3s; | ||
190 | transition: all .3s; | ||
191 | } | ||
192 | |||
193 | .startBtn { | ||
194 | margin-left: 20px; | ||
195 | font-size: 20px; | ||
196 | color: #30B08F; | ||
197 | background-color: #fff; | ||
198 | } | ||
199 | |||
200 | .startBtn:hover { | ||
201 | background-color: #30B08F; | ||
202 | color: #fff; | ||
203 | border-color: #30B08F; | ||
204 | } | ||
205 | |||
206 | .pause-resume-btn { | ||
207 | font-size: 20px; | ||
208 | color: #E65D6E; | ||
209 | background-color: #fff; | ||
210 | } | ||
211 | |||
212 | .pause-resume-btn:hover { | ||
213 | background-color: #E65D6E; | ||
214 | color: #fff; | ||
215 | border-color: #E65D6E; | ||
216 | } | ||
217 | </style> | ||
218 | |||
219 |
src/views/components-demo/dnd-list.vue
File was created | 1 | <template> | |
2 | <div class="components-container"> | ||
3 | <aside>drag-list base on | ||
4 | <a href="https://github.com/SortableJS/Vue.Draggable" target="_blank">Vue.Draggable</a> | ||
5 | </aside> | ||
6 | <div class="editor-container"> | ||
7 | <dnd-list :list1="list1" :list2="list2" list1-title="List" list2-title="Article pool" /> | ||
8 | </div> | ||
9 | </div> | ||
10 | </template> | ||
11 | |||
12 | <script> | ||
13 | import DndList from '@/components/DndList' | ||
14 | import { fetchList } from '@/api/article' | ||
15 | |||
16 | export default { | ||
17 | name: 'DndListDemo', | ||
18 | components: { DndList }, | ||
19 | data() { | ||
20 | return { | ||
21 | list1: [], | ||
22 | list2: [] | ||
23 | } | ||
24 | }, | ||
25 | created() { | ||
26 | this.getData() | ||
27 | }, | ||
28 | methods: { | ||
29 | getData() { | ||
30 | this.listLoading = true | ||
31 | fetchList().then(response => { | ||
32 | this.list1 = response.data.items.splice(0, 5) | ||
33 | this.list2 = response.data.items | ||
34 | }) | ||
35 | } | ||
36 | } | ||
37 | } | ||
38 | </script> | ||
39 | |||
40 |
src/views/components-demo/drag-dialog.vue
File was created | 1 | <template> | |
2 | <div class="components-container"> | ||
3 | <el-button type="primary" @click="dialogTableVisible = true"> | ||
4 | open a Drag Dialog | ||
5 | </el-button> | ||
6 | <el-dialog v-el-drag-dialog :visible.sync="dialogTableVisible" title="Shipping address" @dragDialog="handleDrag"> | ||
7 | <el-select ref="select" v-model="value" placeholder="请选择"> | ||
8 | <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" /> | ||
9 | </el-select> | ||
10 | <el-table :data="gridData"> | ||
11 | <el-table-column property="date" label="Date" width="150" /> | ||
12 | <el-table-column property="name" label="Name" width="200" /> | ||
13 | <el-table-column property="address" label="Address" /> | ||
14 | </el-table> | ||
15 | </el-dialog> | ||
16 | </div> | ||
17 | </template> | ||
18 | |||
19 | <script> | ||
20 | import elDragDialog from '@/directive/el-drag-dialog' // base on element-ui | ||
21 | |||
22 | export default { | ||
23 | name: 'DragDialogDemo', | ||
24 | directives: { elDragDialog }, | ||
25 | data() { | ||
26 | return { | ||
27 | dialogTableVisible: false, | ||
28 | options: [ | ||
29 | { value: '选项1', label: '黄金糕' }, | ||
30 | { value: '选项2', label: '双皮奶' }, | ||
31 | { value: '选项3', label: '蚵仔煎' }, | ||
32 | { value: '选项4', label: '龙须面' } | ||
33 | ], | ||
34 | value: '', | ||
35 | gridData: [{ | ||
36 | date: '2016-05-02', | ||
37 | name: 'John Smith', | ||
38 | address: 'No.1518, Jinshajiang Road, Putuo District' | ||
39 | }, { | ||
40 | date: '2016-05-04', | ||
41 | name: 'John Smith', | ||
42 | address: 'No.1518, Jinshajiang Road, Putuo District' | ||
43 | }, { | ||
44 | date: '2016-05-01', | ||
45 | name: 'John Smith', | ||
46 | address: 'No.1518, Jinshajiang Road, Putuo District' | ||
47 | }, { | ||
48 | date: '2016-05-03', | ||
49 | name: 'John Smith', | ||
50 | address: 'No.1518, Jinshajiang Road, Putuo District' | ||
51 | }] | ||
52 | } | ||
53 | }, | ||
54 | methods: { | ||
55 | // v-el-drag-dialog onDrag callback function | ||
56 | handleDrag() { | ||
57 | this.$refs.select.blur() | ||
58 | } | ||
59 | } | ||
60 | } | ||
61 | </script> | ||
62 |
src/views/components-demo/drag-kanban.vue
File was created | 1 | <template> | |
2 | <div class="components-container board"> | ||
3 | <Kanban :key="1" :list="list1" :group="group" class="kanban todo" header-text="Todo" /> | ||
4 | <Kanban :key="2" :list="list2" :group="group" class="kanban working" header-text="Working" /> | ||
5 | <Kanban :key="3" :list="list3" :group="group" class="kanban done" header-text="Done" /> | ||
6 | </div> | ||
7 | </template> | ||
8 | <script> | ||
9 | import Kanban from '@/components/Kanban' | ||
10 | |||
11 | export default { | ||
12 | name: 'DragKanbanDemo', | ||
13 | components: { | ||
14 | Kanban | ||
15 | }, | ||
16 | data() { | ||
17 | return { | ||
18 | group: 'mission', | ||
19 | list1: [ | ||
20 | { name: 'Mission', id: 1 }, | ||
21 | { name: 'Mission', id: 2 }, | ||
22 | { name: 'Mission', id: 3 }, | ||
23 | { name: 'Mission', id: 4 } | ||
24 | ], | ||
25 | list2: [ | ||
26 | { name: 'Mission', id: 5 }, | ||
27 | { name: 'Mission', id: 6 }, | ||
28 | { name: 'Mission', id: 7 } | ||
29 | ], | ||
30 | list3: [ | ||
31 | { name: 'Mission', id: 8 }, | ||
32 | { name: 'Mission', id: 9 }, | ||
33 | { name: 'Mission', id: 10 } | ||
34 | ] | ||
35 | } | ||
36 | } | ||
37 | } | ||
38 | </script> | ||
39 | <style lang="scss"> | ||
40 | .board { | ||
41 | width: 1000px; | ||
42 | margin-left: 20px; | ||
43 | display: flex; | ||
44 | justify-content: space-around; | ||
45 | flex-direction: row; | ||
46 | align-items: flex-start; | ||
47 | } | ||
48 | .kanban { | ||
49 | &.todo { | ||
50 | .board-column-header { | ||
51 | background: #4A9FF9; | ||
52 | } | ||
53 | } | ||
54 | &.working { | ||
55 | .board-column-header { | ||
56 | background: #f9944a; | ||
57 | } | ||
58 | } | ||
59 | &.done { | ||
60 | .board-column-header { | ||
61 | background: #2ac06d; | ||
62 | } | ||
63 | } | ||
64 | } | ||
65 | </style> | ||
66 | |||
67 |
src/views/components-demo/drag-select.vue
File was created | 1 | <template> | |
2 | <div class="components-container"> | ||
3 | <el-drag-select v-model="value" style="width:500px;" multiple placeholder="请选择"> | ||
4 | <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" /> | ||
5 | </el-drag-select> | ||
6 | |||
7 | <div style="margin-top:30px;"> | ||
8 | <el-tag v-for="item of value" :key="item" style="margin-right:15px;"> | ||
9 | {{ item }} | ||
10 | </el-tag> | ||
11 | </div> | ||
12 | </div> | ||
13 | </template> | ||
14 | |||
15 | <script> | ||
16 | import ElDragSelect from '@/components/DragSelect' // base on element-ui | ||
17 | |||
18 | export default { | ||
19 | name: 'DragSelectDemo', | ||
20 | components: { ElDragSelect }, | ||
21 | data() { | ||
22 | return { | ||
23 | value: ['Apple', 'Banana', 'Orange'], | ||
24 | options: [{ | ||
25 | value: 'Apple', | ||
26 | label: 'Apple' | ||
27 | }, { | ||
28 | value: 'Banana', | ||
29 | label: 'Banana' | ||
30 | }, { | ||
31 | value: 'Orange', | ||
32 | label: 'Orange' | ||
33 | }, { | ||
34 | value: 'Pear', | ||
35 | label: 'Pear' | ||
36 | }, { | ||
37 | value: 'Strawberry', | ||
38 | label: 'Strawberry' | ||
39 | }] | ||
40 | } | ||
41 | } | ||
42 | } | ||
43 | </script> | ||
44 |
src/views/components-demo/dropzone.vue
File was created | 1 | <template> | |
2 | <div class="components-container"> | ||
3 | <aside> | ||
4 | Based on <a class="link-type" href="https://github.com/rowanwins/vue-dropzone"> dropzone </a>. | ||
5 | {{ $t('components.dropzoneTips') }} | ||
6 | </aside> | ||
7 | <div class="editor-container"> | ||
8 | <dropzone id="myVueDropzone" url="https://httpbin.org/post" @dropzone-removedFile="dropzoneR" @dropzone-success="dropzoneS" /> | ||
9 | </div> | ||
10 | </div> | ||
11 | </template> | ||
12 | |||
13 | <script> | ||
14 | import Dropzone from '@/components/Dropzone' | ||
15 | |||
16 | export default { | ||
17 | name: 'DropzoneDemo', | ||
18 | components: { Dropzone }, | ||
19 | methods: { | ||
20 | dropzoneS(file) { | ||
21 | console.log(file) | ||
22 | this.$message({ message: 'Upload success', type: 'success' }) | ||
23 | }, | ||
24 | dropzoneR(file) { | ||
25 | console.log(file) | ||
26 | this.$message({ message: 'Delete success', type: 'success' }) | ||
27 | } | ||
28 | } | ||
29 | } | ||
30 | </script> | ||
31 | |||
32 |
src/views/components-demo/json-editor.vue
File was created | 1 | <template> | |
2 | <div class="components-container"> | ||
3 | <aside>Json-Editor is base on <a href="https://github.com/codemirror/CodeMirror" target="_blank">CodeMirrorr</a>. Lint | ||
4 | base on <a | ||
5 | href="https://github.com/codemirror/CodeMirror/blob/master/addon/lint/json-lint.js" | ||
6 | target="_blank" | ||
7 | >json-lint</a>.</aside> | ||
8 | <div class="editor-container"> | ||
9 | <json-editor ref="jsonEditor" v-model="value" /> | ||
10 | </div> | ||
11 | </div> | ||
12 | </template> | ||
13 | |||
14 | <script> | ||
15 | import JsonEditor from '@/components/JsonEditor' | ||
16 | |||
17 | const jsonData = '[{"items":[{"market_type":"forexdata","symbol":"XAUUSD"},{"market_type":"forexdata","symbol":"UKOIL"},{"market_type":"forexdata","symbol":"CORN"}],"name":""},{"items":[{"market_type":"forexdata","symbol":"XAUUSD"},{"market_type":"forexdata","symbol":"XAGUSD"},{"market_type":"forexdata","symbol":"AUTD"},{"market_type":"forexdata","symbol":"AGTD"}],"name":"贵金属"},{"items":[{"market_type":"forexdata","symbol":"CORN"},{"market_type":"forexdata","symbol":"WHEAT"},{"market_type":"forexdata","symbol":"SOYBEAN"},{"market_type":"forexdata","symbol":"SUGAR"}],"name":"农产品"},{"items":[{"market_type":"forexdata","symbol":"UKOIL"},{"market_type":"forexdata","symbol":"USOIL"},{"market_type":"forexdata","symbol":"NGAS"}],"name":"能源化工"}]' | ||
18 | |||
19 | export default { | ||
20 | name: 'JsonEditorDemo', | ||
21 | components: { JsonEditor }, | ||
22 | data() { | ||
23 | return { | ||
24 | value: JSON.parse(jsonData) | ||
25 | } | ||
26 | } | ||
27 | } | ||
28 | </script> | ||
29 | |||
30 | <style scoped> | ||
31 | .editor-container{ | ||
32 | position: relative; | ||
33 | height: 100%; | ||
34 | } | ||
35 | </style> | ||
36 | |||
37 |
src/views/components-demo/markdown.vue
File was created | 1 | <template> | |
2 | <div class="components-container"> | ||
3 | <aside>Markdown is based on | ||
4 | <a href="https://github.com/nhnent/tui.editor" target="_blank">tui.editor</a> ,simply wrapped with Vue. | ||
5 | <a | ||
6 | target="_blank" | ||
7 | href="https://panjiachen.github.io/vue-element-admin-site/feature/component/markdown-editor.html" | ||
8 | > | ||
9 | Documentation </a> | ||
10 | </aside> | ||
11 | |||
12 | <div class="editor-container"> | ||
13 | <el-tag class="tag-title"> | ||
14 | Basic: | ||
15 | </el-tag> | ||
16 | <markdown-editor v-model="content1" height="300px" /> | ||
17 | </div> | ||
18 | |||
19 | <div class="editor-container"> | ||
20 | <el-tag class="tag-title"> | ||
21 | Markdown Mode: | ||
22 | </el-tag> | ||
23 | <markdown-editor ref="markdownEditor" v-model="content2" :options="{hideModeSwitch:true,previewStyle:'tab'}" height="200px" /> | ||
24 | </div> | ||
25 | |||
26 | <div class="editor-container"> | ||
27 | <el-tag class="tag-title"> | ||
28 | Customize Toolbar: | ||
29 | </el-tag> | ||
30 | <markdown-editor v-model="content3" :options="{ toolbarItems: ['heading','bold','italic']}" /> | ||
31 | </div> | ||
32 | |||
33 | <div class="editor-container"> | ||
34 | <el-tag class="tag-title"> | ||
35 | I18n: | ||
36 | </el-tag> | ||
37 | <el-alert | ||
38 | :closable="false" | ||
39 | title="You can change the language of the admin system to see the effect" | ||
40 | type="success" | ||
41 | /> | ||
42 | <markdown-editor ref="markdownEditor" v-model="content4" :language="language" height="300px" /> | ||
43 | </div> | ||
44 | |||
45 | <el-button style="margin-top:80px;" type="primary" icon="el-icon-document" @click="getHtml"> | ||
46 | Get HTML | ||
47 | </el-button> | ||
48 | <div v-html="html" /> | ||
49 | </div> | ||
50 | </template> | ||
51 | |||
52 | <script> | ||
53 | import MarkdownEditor from '@/components/MarkdownEditor' | ||
54 | |||
55 | const content = ` | ||
56 | **This is test** | ||
57 | |||
58 | * vue | ||
59 | * element | ||
60 | * webpack | ||
61 | |||
62 | ` | ||
63 | export default { | ||
64 | name: 'MarkdownDemo', | ||
65 | components: { MarkdownEditor }, | ||
66 | data() { | ||
67 | return { | ||
68 | content1: content, | ||
69 | content2: content, | ||
70 | content3: content, | ||
71 | content4: content, | ||
72 | html: '', | ||
73 | languageTypeList: { | ||
74 | 'en': 'en_US', | ||
75 | 'zh': 'zh_CN', | ||
76 | 'es': 'es_ES' | ||
77 | } | ||
78 | } | ||
79 | }, | ||
80 | computed: { | ||
81 | language() { | ||
82 | return this.languageTypeList[this.$store.getters.language] | ||
83 | } | ||
84 | }, | ||
85 | methods: { | ||
86 | getHtml() { | ||
87 | this.html = this.$refs.markdownEditor.getHtml() | ||
88 | console.log(this.html) | ||
89 | } | ||
90 | } | ||
91 | } | ||
92 | </script> | ||
93 | |||
94 | <style scoped> | ||
95 | .editor-container{ | ||
96 | margin-bottom: 30px; | ||
97 | } | ||
98 | .tag-title{ | ||
99 | margin-bottom: 5px; | ||
100 | } | ||
101 | </style> | ||
102 |
src/views/components-demo/mixin.vue
File was created | 1 | <template> | |
2 | <div class="mixin-components-container"> | ||
3 | <el-row> | ||
4 | <el-card class="box-card"> | ||
5 | <div slot="header" class="clearfix"> | ||
6 | <span>Buttons</span> | ||
7 | </div> | ||
8 | <div style="margin-bottom:50px;"> | ||
9 | <el-col :span="4" class="text-center"> | ||
10 | <router-link class="pan-btn blue-btn" to="/documentation/index"> | ||
11 | Documentation | ||
12 | </router-link> | ||
13 | </el-col> | ||
14 | <el-col :span="4" class="text-center"> | ||
15 | <router-link class="pan-btn light-blue-btn" to="/icon/index"> | ||
16 | Icons | ||
17 | </router-link> | ||
18 | </el-col> | ||
19 | <el-col :span="4" class="text-center"> | ||
20 | <router-link class="pan-btn pink-btn" to="/excel/export-excel"> | ||
21 | Excel | ||
22 | </router-link> | ||
23 | </el-col> | ||
24 | <el-col :span="4" class="text-center"> | ||
25 | <router-link class="pan-btn green-btn" to="/table/complex-table"> | ||
26 | Table | ||
27 | </router-link> | ||
28 | </el-col> | ||
29 | <el-col :span="4" class="text-center"> | ||
30 | <router-link class="pan-btn tiffany-btn" to="/example/create"> | ||
31 | Form | ||
32 | </router-link> | ||
33 | </el-col> | ||
34 | <el-col :span="4" class="text-center"> | ||
35 | <router-link class="pan-btn yellow-btn" to="/theme/index"> | ||
36 | Theme | ||
37 | </router-link> | ||
38 | </el-col> | ||
39 | </div> | ||
40 | </el-card> | ||
41 | </el-row> | ||
42 | |||
43 | <el-row :gutter="20" style="margin-top:50px;"> | ||
44 | <el-col :span="6"> | ||
45 | <el-card class="box-card"> | ||
46 | <div slot="header" class="clearfix"> | ||
47 | <span>Material Design 的input</span> | ||
48 | </div> | ||
49 | <div style="height:100px;"> | ||
50 | <el-form :model="demo" :rules="demoRules"> | ||
51 | <el-form-item prop="title"> | ||
52 | <md-input v-model="demo.title" icon="el-icon-search" name="title" placeholder="输入标题"> | ||
53 | 标题 | ||
54 | </md-input> | ||
55 | </el-form-item> | ||
56 | </el-form> | ||
57 | </div> | ||
58 | </el-card> | ||
59 | </el-col> | ||
60 | |||
61 | <el-col :span="6"> | ||
62 | <el-card class="box-card"> | ||
63 | <div slot="header" class="clearfix"> | ||
64 | <span>图片hover效果</span> | ||
65 | </div> | ||
66 | <div class="component-item"> | ||
67 | <pan-thumb width="100px" height="100px" image="https://wpimg.wallstcn.com/577965b9-bb9e-4e02-9f0c-095b41417191"> | ||
68 | vue-element-admin | ||
69 | </pan-thumb> | ||
70 | </div> | ||
71 | </el-card> | ||
72 | </el-col> | ||
73 | |||
74 | <el-col :span="6"> | ||
75 | <el-card class="box-card"> | ||
76 | <div slot="header" class="clearfix"> | ||
77 | <span>水波纹 waves v-directive</span> | ||
78 | </div> | ||
79 | <div class="component-item"> | ||
80 | <el-button v-waves type="primary"> | ||
81 | 水波纹效果 | ||
82 | </el-button> | ||
83 | </div> | ||
84 | </el-card> | ||
85 | </el-col> | ||
86 | |||
87 | <el-col :span="6"> | ||
88 | <el-card class="box-card"> | ||
89 | <div slot="header" class="clearfix"> | ||
90 | <span>hover text</span> | ||
91 | </div> | ||
92 | <div class="component-item"> | ||
93 | <mallki class-name="mallki-text" text="vue-element-admin" /> | ||
94 | </div> | ||
95 | </el-card> | ||
96 | </el-col> | ||
97 | </el-row> | ||
98 | |||
99 | <el-row :gutter="20" style="margin-top:50px;"> | ||
100 | <el-col :span="8"> | ||
101 | <el-card class="box-card"> | ||
102 | <div slot="header" class="clearfix"> | ||
103 | <span>Share</span> | ||
104 | </div> | ||
105 | <div class="component-item" style="height:420px;"> | ||
106 | <dropdown-menu :items="articleList" style="margin:0 auto;" title="系列文章" /> | ||
107 | </div> | ||
108 | </el-card> | ||
109 | </el-col> | ||
110 | </el-row> | ||
111 | </div> | ||
112 | </template> | ||
113 | |||
114 | <script> | ||
115 | import PanThumb from '@/components/PanThumb' | ||
116 | import MdInput from '@/components/MDinput' | ||
117 | import Mallki from '@/components/TextHoverEffect/Mallki' | ||
118 | import DropdownMenu from '@/components/Share/DropdownMenu' | ||
119 | import waves from '@/directive/waves/index.js' // 水波纹指令 | ||
120 | |||
121 | export default { | ||
122 | name: 'ComponentMixinDemo', | ||
123 | components: { | ||
124 | PanThumb, | ||
125 | MdInput, | ||
126 | Mallki, | ||
127 | DropdownMenu | ||
128 | }, | ||
129 | directives: { | ||
130 | waves | ||
131 | }, | ||
132 | data() { | ||
133 | const validate = (rule, value, callback) => { | ||
134 | if (value.length !== 6) { | ||
135 | callback(new Error('请输入六个字符')) | ||
136 | } else { | ||
137 | callback() | ||
138 | } | ||
139 | } | ||
140 | return { | ||
141 | demo: { | ||
142 | title: '' | ||
143 | }, | ||
144 | demoRules: { | ||
145 | title: [{ required: true, trigger: 'change', validator: validate }] | ||
146 | }, | ||
147 | articleList: [ | ||
148 | { title: '基础篇', href: 'https://juejin.im/post/59097cd7a22b9d0065fb61d2' }, | ||
149 | { title: '登录权限篇', href: 'https://juejin.im/post/591aa14f570c35006961acac' }, | ||
150 | { title: '实战篇', href: 'https://juejin.im/post/593121aa0ce4630057f70d35' }, | ||
151 | { title: 'vue-admin-template 篇', href: 'https://juejin.im/post/595b4d776fb9a06bbe7dba56' }, | ||
152 | { title: 'v4.0 篇', href: 'https://juejin.im/post/5c92ff94f265da6128275a85' }, | ||
153 | { title: '优雅的使用 icon', href: 'https://juejin.im/post/59bb864b5188257e7a427c09' } | ||
154 | ] | ||
155 | } | ||
156 | } | ||
157 | } | ||
158 | </script> | ||
159 | |||
160 | <style scoped> | ||
161 | .mixin-components-container { | ||
162 | background-color: #f0f2f5; | ||
163 | padding: 30px; | ||
164 | min-height: calc(100vh - 84px); | ||
165 | } | ||
166 | .component-item{ | ||
167 | min-height: 100px; | ||
168 | } | ||
169 | </style> | ||
170 |
src/views/components-demo/split-pane.vue
File was created | 1 | <template> | |
2 | <div class="components-container"> | ||
3 | <aside><strong>SplitPane</strong> If you've used | ||
4 | <a href="https://codepen.io/" target="_blank"> codepen</a>, | ||
5 | <a href="https://jsfiddle.net/" target="_blank"> jsfiddle </a>will not be unfamiliar. | ||
6 | <a href="https://github.com/PanJiaChen/vue-split-pane" target="_blank"> Github repository</a> | ||
7 | </aside> | ||
8 | <split-pane split="vertical" @resize="resize"> | ||
9 | <template slot="paneL"> | ||
10 | <div class="left-container" /> | ||
11 | </template> | ||
12 | <template slot="paneR"> | ||
13 | <split-pane split="horizontal"> | ||
14 | <template slot="paneL"> | ||
15 | <div class="top-container" /> | ||
16 | </template> | ||
17 | <template slot="paneR"> | ||
18 | <div class="bottom-container" /> | ||
19 | </template> | ||
20 | </split-pane> | ||
21 | </template> | ||
22 | </split-pane> | ||
23 | </div> | ||
24 | </template> | ||
25 | |||
26 | <script> | ||
27 | import splitPane from 'vue-splitpane' | ||
28 | |||
29 | export default { | ||
30 | name: 'SplitpaneDemo', | ||
31 | components: { splitPane }, | ||
32 | methods: { | ||
33 | resize() { | ||
34 | console.log('resize') | ||
35 | } | ||
36 | } | ||
37 | } | ||
38 | </script> | ||
39 | |||
40 | <style scoped> | ||
41 | .components-container { | ||
42 | position: relative; | ||
43 | height: 100vh; | ||
44 | } | ||
45 | |||
46 | .left-container { | ||
47 | background-color: #F38181; | ||
48 | height: 100%; | ||
49 | } | ||
50 | |||
51 | .right-container { | ||
52 | background-color: #FCE38A; | ||
53 | height: 200px; | ||
54 | } | ||
55 | |||
56 | .top-container { | ||
57 | background-color: #FCE38A; | ||
58 | width: 100%; | ||
59 | height: 100%; | ||
60 | } | ||
61 | |||
62 | .bottom-container { | ||
63 | width: 100%; | ||
64 | background-color: #95E1D3; | ||
65 | height: 100%; | ||
66 | } | ||
67 | </style> | ||
68 |
src/views/components-demo/sticky.vue
File was created | 1 | <template> | |
2 | <div> | ||
3 | <sticky :z-index="10" class-name="sub-navbar"> | ||
4 | <el-dropdown trigger="click"> | ||
5 | <el-button plain> | ||
6 | Platform<i class="el-icon-caret-bottom el-icon--right" /> | ||
7 | </el-button> | ||
8 | <el-dropdown-menu slot="dropdown" class="no-border"> | ||
9 | <el-checkbox-group v-model="platforms" style="padding: 5px 15px;"> | ||
10 | <el-checkbox v-for="item in platformsOptions" :key="item.key" :label="item.key"> | ||
11 | {{ item.name }} | ||
12 | </el-checkbox> | ||
13 | </el-checkbox-group> | ||
14 | </el-dropdown-menu> | ||
15 | </el-dropdown> | ||
16 | |||
17 | <el-dropdown trigger="click"> | ||
18 | <el-button plain> | ||
19 | Link<i class="el-icon-caret-bottom el-icon--right" /> | ||
20 | </el-button> | ||
21 | <el-dropdown-menu slot="dropdown" class="no-padding no-border" style="width:300px"> | ||
22 | <el-input v-model="url" placeholder="Please enter the content"> | ||
23 | <template slot="prepend"> | ||
24 | Url | ||
25 | </template> | ||
26 | </el-input> | ||
27 | </el-dropdown-menu> | ||
28 | </el-dropdown> | ||
29 | |||
30 | <div class="time-container"> | ||
31 | <el-date-picker v-model="time" type="datetime" format="yyyy-MM-dd HH:mm:ss" placeholder="Release time" /> | ||
32 | </div> | ||
33 | |||
34 | <el-button style="margin-left: 10px;" type="success"> | ||
35 | publish | ||
36 | </el-button> | ||
37 | </sticky> | ||
38 | |||
39 | <div class="components-container"> | ||
40 | <aside>Sticky header, {{ $t('components.stickyTips') }}</aside> | ||
41 | <div>placeholder</div> | ||
42 | <div>placeholder</div> | ||
43 | <div>placeholder</div> | ||
44 | <div>placeholder</div> | ||
45 | <div>placeholder</div> | ||
46 | <div>placeholder</div> | ||
47 | <div>placeholder</div> | ||
48 | <div>placeholder</div> | ||
49 | <div>placeholder</div> | ||
50 | <div>placeholder</div> | ||
51 | <div>placeholder</div> | ||
52 | <div>placeholder</div> | ||
53 | <div>placeholder</div> | ||
54 | <sticky :sticky-top="200"> | ||
55 | <el-button type="primary"> placeholder</el-button> | ||
56 | </sticky> | ||
57 | <div>placeholder</div> | ||
58 | <div>placeholder</div> | ||
59 | <div>placeholder</div> | ||
60 | <div>placeholder</div> | ||
61 | <div>placeholder</div> | ||
62 | <div>placeholder</div> | ||
63 | <div>placeholder</div> | ||
64 | <div>placeholder</div> | ||
65 | <div>placeholder</div> | ||
66 | <div>placeholder</div> | ||
67 | <div>placeholder</div> | ||
68 | <div>placeholder</div> | ||
69 | <div>placeholder</div> | ||
70 | <div>placeholder</div> | ||
71 | <div>placeholder</div> | ||
72 | <div>placeholder</div> | ||
73 | <div>placeholder</div> | ||
74 | <div>placeholder</div> | ||
75 | <div>placeholder</div> | ||
76 | <div>placeholder</div> | ||
77 | <div>placeholder</div> | ||
78 | <div>placeholder</div> | ||
79 | <div>placeholder</div> | ||
80 | <div>placeholder</div> | ||
81 | <div>placeholder</div> | ||
82 | <div>placeholder</div> | ||
83 | <div>placeholder</div> | ||
84 | <div>placeholder</div> | ||
85 | <div>placeholder</div> | ||
86 | <div>placeholder</div> | ||
87 | <div>placeholder</div> | ||
88 | <div>placeholder</div> | ||
89 | <div>placeholder</div> | ||
90 | <div>placeholder</div> | ||
91 | <div>placeholder</div> | ||
92 | <div>placeholder</div> | ||
93 | <div>placeholder</div> | ||
94 | <div>placeholder</div> | ||
95 | </div> | ||
96 | </div> | ||
97 | </template> | ||
98 | |||
99 | <script> | ||
100 | import Sticky from '@/components/Sticky' | ||
101 | |||
102 | export default { | ||
103 | name: 'StickyDemo', | ||
104 | components: { Sticky }, | ||
105 | data() { | ||
106 | return { | ||
107 | time: '', | ||
108 | url: '', | ||
109 | platforms: ['a-platform'], | ||
110 | platformsOptions: [ | ||
111 | { key: 'a-platform', name: 'platformA' }, | ||
112 | { key: 'b-platform', name: 'platformB' }, | ||
113 | { key: 'c-platform', name: 'platformC' } | ||
114 | ], | ||
115 | pickerOptions: { | ||
116 | disabledDate(time) { | ||
117 | return time.getTime() > Date.now() | ||
118 | } | ||
119 | } | ||
120 | } | ||
121 | } | ||
122 | } | ||
123 | </script> | ||
124 | |||
125 | <style scoped> | ||
126 | .components-container div { | ||
127 | margin: 10px; | ||
128 | } | ||
129 | |||
130 | .time-container { | ||
131 | display: inline-block; | ||
132 | } | ||
133 | </style> | ||
134 |
src/views/components-demo/tinymce.vue
File was created | 1 | <template> | |
2 | <div class="components-container"> | ||
3 | <aside> | ||
4 | {{ $t('components.tinymceTips') }} | ||
5 | <a target="_blank" class="link-type" href="https://panjiachen.github.io/vue-element-admin-site/component/rich-editor.html"> {{ $t('components.documentation') }}</a> | ||
6 | </aside> | ||
7 | <div> | ||
8 | <tinymce v-model="content" :height="300" /> | ||
9 | </div> | ||
10 | <div class="editor-content" v-html="content" /> | ||
11 | </div> | ||
12 | </template> | ||
13 | |||
14 | <script> | ||
15 | import Tinymce from '@/components/Tinymce' | ||
16 | |||
17 | export default { | ||
18 | name: 'TinymceDemo', | ||
19 | components: { Tinymce }, | ||
20 | data() { | ||
21 | return { | ||
22 | content: | ||
23 | `<h1 style="text-align: center;">Welcome to the TinyMCE demo!</h1><p style="text-align: center; font-size: 15px;"><img title="TinyMCE Logo" src="//www.tinymce.com/images/glyph-tinymce@2x.png" alt="TinyMCE Logo" width="110" height="97" /><ul> | ||
24 | <li>Our <a href="//www.tinymce.com/docs/">documentation</a> is a great resource for learning how to configure TinyMCE.</li><li>Have a specific question? Visit the <a href="https://community.tinymce.com/forum/">Community Forum</a>.</li><li>We also offer enterprise grade support as part of <a href="https://tinymce.com/pricing">TinyMCE premium subscriptions</a>.</li> | ||
25 | </ul>` | ||
26 | } | ||
27 | } | ||
28 | } | ||
29 | </script> | ||
30 | |||
31 | <style scoped> | ||
32 | .editor-content{ | ||
33 | margin-top: 20px; | ||
34 | } | ||
35 | </style> | ||
36 | |||
37 |
src/views/dashboard/admin/components/BarChart.vue
File was created | 1 | <template> | |
2 | <div :class="className" :style="{height:height,width:width}" /> | ||
3 | </template> | ||
4 | |||
5 | <script> | ||
6 | import echarts from 'echarts' | ||
7 | require('echarts/theme/macarons') // echarts theme | ||
8 | import resize from './mixins/resize' | ||
9 | |||
10 | const animationDuration = 6000 | ||
11 | |||
12 | export default { | ||
13 | mixins: [resize], | ||
14 | props: { | ||
15 | className: { | ||
16 | type: String, | ||
17 | default: 'chart' | ||
18 | }, | ||
19 | width: { | ||
20 | type: String, | ||
21 | default: '100%' | ||
22 | }, | ||
23 | height: { | ||
24 | type: String, | ||
25 | default: '300px' | ||
26 | } | ||
27 | }, | ||
28 | data() { | ||
29 | return { | ||
30 | chart: null | ||
31 | } | ||
32 | }, | ||
33 | mounted() { | ||
34 | this.$nextTick(() => { | ||
35 | this.initChart() | ||
36 | }) | ||
37 | }, | ||
38 | beforeDestroy() { | ||
39 | if (!this.chart) { | ||
40 | return | ||
41 | } | ||
42 | this.chart.dispose() | ||
43 | this.chart = null | ||
44 | }, | ||
45 | methods: { | ||
46 | initChart() { | ||
47 | this.chart = echarts.init(this.$el, 'macarons') | ||
48 | |||
49 | this.chart.setOption({ | ||
50 | tooltip: { | ||
51 | trigger: 'axis', | ||
52 | axisPointer: { // 坐标轴指示器,坐标轴触发有效 | ||
53 | type: 'shadow' // 默认为直线,可选为:'line' | 'shadow' | ||
54 | } | ||
55 | }, | ||
56 | grid: { | ||
57 | top: 10, | ||
58 | left: '2%', | ||
59 | right: '2%', | ||
60 | bottom: '3%', | ||
61 | containLabel: true | ||
62 | }, | ||
63 | xAxis: [{ | ||
64 | type: 'category', | ||
65 | data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], | ||
66 | axisTick: { | ||
67 | alignWithLabel: true | ||
68 | } | ||
69 | }], | ||
70 | yAxis: [{ | ||
71 | type: 'value', | ||
72 | axisTick: { | ||
73 | show: false | ||
74 | } | ||
75 | }], | ||
76 | series: [{ | ||
77 | name: 'pageA', | ||
78 | type: 'bar', | ||
79 | stack: 'vistors', | ||
80 | barWidth: '60%', | ||
81 | data: [79, 52, 200, 334, 390, 330, 220], | ||
82 | animationDuration | ||
83 | }, { | ||
84 | name: 'pageB', | ||
85 | type: 'bar', | ||
86 | stack: 'vistors', | ||
87 | barWidth: '60%', | ||
88 | data: [80, 52, 200, 334, 390, 330, 220], | ||
89 | animationDuration | ||
90 | }, { | ||
91 | name: 'pageC', | ||
92 | type: 'bar', | ||
93 | stack: 'vistors', | ||
94 | barWidth: '60%', | ||
95 | data: [30, 52, 200, 334, 390, 330, 220], | ||
96 | animationDuration | ||
97 | }] | ||
98 | }) | ||
99 | } | ||
100 | } | ||
101 | } | ||
102 | </script> | ||
103 |
src/views/dashboard/admin/components/BoxCard.vue
File was created | 1 | <template> | |
2 | <el-card class="box-card-component" style="margin-left:8px;"> | ||
3 | <div slot="header" class="box-card-header"> | ||
4 | <img src="https://wpimg.wallstcn.com/e7d23d71-cf19-4b90-a1cc-f56af8c0903d.png"> | ||
5 | </div> | ||
6 | <div style="position:relative;"> | ||
7 | <pan-thumb :image="avatar" class="panThumb" /> | ||
8 | <mallki class-name="mallki-text" text="vue-element-admin" /> | ||
9 | <div style="padding-top:35px;" class="progress-item"> | ||
10 | <span>Vue</span> | ||
11 | <el-progress :percentage="70" /> | ||
12 | </div> | ||
13 | <div class="progress-item"> | ||
14 | <span>JavaScript</span> | ||
15 | <el-progress :percentage="18" /> | ||
16 | </div> | ||
17 | <div class="progress-item"> | ||
18 | <span>Css</span> | ||
19 | <el-progress :percentage="12" /> | ||
20 | </div> | ||
21 | <div class="progress-item"> | ||
22 | <span>ESLint</span> | ||
23 | <el-progress :percentage="100" status="success" /> | ||
24 | </div> | ||
25 | </div> | ||
26 | </el-card> | ||
27 | </template> | ||
28 | |||
29 | <script> | ||
30 | import { mapGetters } from 'vuex' | ||
31 | import PanThumb from '@/components/PanThumb' | ||
32 | import Mallki from '@/components/TextHoverEffect/Mallki' | ||
33 | |||
34 | export default { | ||
35 | components: { PanThumb, Mallki }, | ||
36 | |||
37 | filters: { | ||
38 | statusFilter(status) { | ||
39 | const statusMap = { | ||
40 | success: 'success', | ||
41 | pending: 'danger' | ||
42 | } | ||
43 | return statusMap[status] | ||
44 | } | ||
45 | }, | ||
46 | data() { | ||
47 | return { | ||
48 | statisticsData: { | ||
49 | article_count: 1024, | ||
50 | pageviews_count: 1024 | ||
51 | } | ||
52 | } | ||
53 | }, | ||
54 | computed: { | ||
55 | ...mapGetters([ | ||
56 | 'name', | ||
57 | 'avatar', | ||
58 | 'roles' | ||
59 | ]) | ||
60 | } | ||
61 | } | ||
62 | </script> | ||
63 | |||
64 | <style lang="scss" > | ||
65 | .box-card-component{ | ||
66 | .el-card__header { | ||
67 | padding: 0px!important; | ||
68 | } | ||
69 | } | ||
70 | </style> | ||
71 | <style lang="scss" scoped> | ||
72 | .box-card-component { | ||
73 | .box-card-header { | ||
74 | position: relative; | ||
75 | height: 220px; | ||
76 | img { | ||
77 | width: 100%; | ||
78 | height: 100%; | ||
79 | transition: all 0.2s linear; | ||
80 | &:hover { | ||
81 | transform: scale(1.1, 1.1); | ||
82 | filter: contrast(130%); | ||
83 | } | ||
84 | } | ||
85 | } | ||
86 | .mallki-text { | ||
87 | position: absolute; | ||
88 | top: 0px; | ||
89 | right: 0px; | ||
90 | font-size: 20px; | ||
91 | font-weight: bold; | ||
92 | } | ||
93 | .panThumb { | ||
94 | z-index: 100; | ||
95 | height: 70px!important; | ||
96 | width: 70px!important; | ||
97 | position: absolute!important; | ||
98 | top: -45px; | ||
99 | left: 0px; | ||
100 | border: 5px solid #ffffff; | ||
101 | background-color: #fff; | ||
102 | margin: auto; | ||
103 | box-shadow: none!important; | ||
104 | /deep/ .pan-info { | ||
105 | box-shadow: none!important; | ||
106 | } | ||
107 | } | ||
108 | .progress-item { | ||
109 | margin-bottom: 10px; | ||
110 | font-size: 14px; | ||
111 | } | ||
112 | @media only screen and (max-width: 1510px){ | ||
113 | .mallki-text{ | ||
114 | display: none; | ||
115 | } | ||
116 | } | ||
117 | } | ||
118 | </style> | ||
119 |
src/views/dashboard/admin/components/LineChart.vue
File was created | 1 | <template> | |
2 | <div :class="className" :style="{height:height,width:width}" /> | ||
3 | </template> | ||
4 | |||
5 | <script> | ||
6 | import echarts from 'echarts' | ||
7 | require('echarts/theme/macarons') // echarts theme | ||
8 | import resize from './mixins/resize' | ||
9 | |||
10 | export default { | ||
11 | mixins: [resize], | ||
12 | props: { | ||
13 | className: { | ||
14 | type: String, | ||
15 | default: 'chart' | ||
16 | }, | ||
17 | width: { | ||
18 | type: String, | ||
19 | default: '100%' | ||
20 | }, | ||
21 | height: { | ||
22 | type: String, | ||
23 | default: '350px' | ||
24 | }, | ||
25 | autoResize: { | ||
26 | type: Boolean, | ||
27 | default: true | ||
28 | }, | ||
29 | chartData: { | ||
30 | type: Object, | ||
31 | required: true | ||
32 | } | ||
33 | }, | ||
34 | data() { | ||
35 | return { | ||
36 | chart: null | ||
37 | } | ||
38 | }, | ||
39 | watch: { | ||
40 | chartData: { | ||
41 | deep: true, | ||
42 | handler(val) { | ||
43 | this.setOptions(val) | ||
44 | } | ||
45 | } | ||
46 | }, | ||
47 | mounted() { | ||
48 | this.$nextTick(() => { | ||
49 | this.initChart() | ||
50 | }) | ||
51 | }, | ||
52 | beforeDestroy() { | ||
53 | if (!this.chart) { | ||
54 | return | ||
55 | } | ||
56 | this.chart.dispose() | ||
57 | this.chart = null | ||
58 | }, | ||
59 | methods: { | ||
60 | initChart() { | ||
61 | this.chart = echarts.init(this.$el, 'macarons') | ||
62 | this.setOptions(this.chartData) | ||
63 | }, | ||
64 | setOptions({ expectedData, actualData } = {}) { | ||
65 | this.chart.setOption({ | ||
66 | xAxis: { | ||
67 | data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], | ||
68 | boundaryGap: false, | ||
69 | axisTick: { | ||
70 | show: false | ||
71 | } | ||
72 | }, | ||
73 | grid: { | ||
74 | left: 10, | ||
75 | right: 10, | ||
76 | bottom: 20, | ||
77 | top: 30, | ||
78 | containLabel: true | ||
79 | }, | ||
80 | tooltip: { | ||
81 | trigger: 'axis', | ||
82 | axisPointer: { | ||
83 | type: 'cross' | ||
84 | }, | ||
85 | padding: [5, 10] | ||
86 | }, | ||
87 | yAxis: { | ||
88 | axisTick: { | ||
89 | show: false | ||
90 | } | ||
91 | }, | ||
92 | legend: { | ||
93 | data: ['expected', 'actual'] | ||
94 | }, | ||
95 | series: [{ | ||
96 | name: 'expected', itemStyle: { | ||
97 | normal: { | ||
98 | color: '#FF005A', | ||
99 | lineStyle: { | ||
100 | color: '#FF005A', | ||
101 | width: 2 | ||
102 | } | ||
103 | } | ||
104 | }, | ||
105 | smooth: true, | ||
106 | type: 'line', | ||
107 | data: expectedData, | ||
108 | animationDuration: 2800, | ||
109 | animationEasing: 'cubicInOut' | ||
110 | }, | ||
111 | { | ||
112 | name: 'actual', | ||
113 | smooth: true, | ||
114 | type: 'line', | ||
115 | itemStyle: { | ||
116 | normal: { | ||
117 | color: '#3888fa', | ||
118 | lineStyle: { | ||
119 | color: '#3888fa', | ||
120 | width: 2 | ||
121 | }, | ||
122 | areaStyle: { | ||
123 | color: '#f3f8ff' | ||
124 | } | ||
125 | } | ||
126 | }, | ||
127 | data: actualData, | ||
128 | animationDuration: 2800, | ||
129 | animationEasing: 'quadraticOut' | ||
130 | }] | ||
131 | }) | ||
132 | } | ||
133 | } | ||
134 | } | ||
135 | </script> | ||
136 |
src/views/dashboard/admin/components/PanelGroup.vue
File was created | 1 | <template> | |
2 | <el-row :gutter="40" class="panel-group"> | ||
3 | <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col"> | ||
4 | <div class="card-panel" @click="handleSetLineChartData('newVisitis')"> | ||
5 | <div class="card-panel-icon-wrapper icon-people"> | ||
6 | <svg-icon icon-class="peoples" class-name="card-panel-icon" /> | ||
7 | </div> | ||
8 | <div class="card-panel-description"> | ||
9 | <div class="card-panel-text"> | ||
10 | New Visits | ||
11 | </div> | ||
12 | <count-to :start-val="0" :end-val="102400" :duration="2600" class="card-panel-num" /> | ||
13 | </div> | ||
14 | </div> | ||
15 | </el-col> | ||
16 | <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col"> | ||
17 | <div class="card-panel" @click="handleSetLineChartData('messages')"> | ||
18 | <div class="card-panel-icon-wrapper icon-message"> | ||
19 | <svg-icon icon-class="message" class-name="card-panel-icon" /> | ||
20 | </div> | ||
21 | <div class="card-panel-description"> | ||
22 | <div class="card-panel-text"> | ||
23 | Messages | ||
24 | </div> | ||
25 | <count-to :start-val="0" :end-val="81212" :duration="3000" class="card-panel-num" /> | ||
26 | </div> | ||
27 | </div> | ||
28 | </el-col> | ||
29 | <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col"> | ||
30 | <div class="card-panel" @click="handleSetLineChartData('purchases')"> | ||
31 | <div class="card-panel-icon-wrapper icon-money"> | ||
32 | <svg-icon icon-class="money" class-name="card-panel-icon" /> | ||
33 | </div> | ||
34 | <div class="card-panel-description"> | ||
35 | <div class="card-panel-text"> | ||
36 | Purchases | ||
37 | </div> | ||
38 | <count-to :start-val="0" :end-val="9280" :duration="3200" class="card-panel-num" /> | ||
39 | </div> | ||
40 | </div> | ||
41 | </el-col> | ||
42 | <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col"> | ||
43 | <div class="card-panel" @click="handleSetLineChartData('shoppings')"> | ||
44 | <div class="card-panel-icon-wrapper icon-shopping"> | ||
45 | <svg-icon icon-class="shopping" class-name="card-panel-icon" /> | ||
46 | </div> | ||
47 | <div class="card-panel-description"> | ||
48 | <div class="card-panel-text"> | ||
49 | Shoppings | ||
50 | </div> | ||
51 | <count-to :start-val="0" :end-val="13600" :duration="3600" class="card-panel-num" /> | ||
52 | </div> | ||
53 | </div> | ||
54 | </el-col> | ||
55 | </el-row> | ||
56 | </template> | ||
57 | |||
58 | <script> | ||
59 | import CountTo from 'vue-count-to' | ||
60 | |||
61 | export default { | ||
62 | components: { | ||
63 | CountTo | ||
64 | }, | ||
65 | methods: { | ||
66 | handleSetLineChartData(type) { | ||
67 | this.$emit('handleSetLineChartData', type) | ||
68 | } | ||
69 | } | ||
70 | } | ||
71 | </script> | ||
72 | |||
73 | <style lang="scss" scoped> | ||
74 | .panel-group { | ||
75 | margin-top: 18px; | ||
76 | |||
77 | .card-panel-col { | ||
78 | margin-bottom: 32px; | ||
79 | } | ||
80 | |||
81 | .card-panel { | ||
82 | height: 108px; | ||
83 | cursor: pointer; | ||
84 | font-size: 12px; | ||
85 | position: relative; | ||
86 | overflow: hidden; | ||
87 | color: #666; | ||
88 | background: #fff; | ||
89 | box-shadow: 4px 4px 40px rgba(0, 0, 0, .05); | ||
90 | border-color: rgba(0, 0, 0, .05); | ||
91 | |||
92 | &:hover { | ||
93 | .card-panel-icon-wrapper { | ||
94 | color: #fff; | ||
95 | } | ||
96 | |||
97 | .icon-people { | ||
98 | background: #40c9c6; | ||
99 | } | ||
100 | |||
101 | .icon-message { | ||
102 | background: #36a3f7; | ||
103 | } | ||
104 | |||
105 | .icon-money { | ||
106 | background: #f4516c; | ||
107 | } | ||
108 | |||
109 | .icon-shopping { | ||
110 | background: #34bfa3 | ||
111 | } | ||
112 | } | ||
113 | |||
114 | .icon-people { | ||
115 | color: #40c9c6; | ||
116 | } | ||
117 | |||
118 | .icon-message { | ||
119 | color: #36a3f7; | ||
120 | } | ||
121 | |||
122 | .icon-money { | ||
123 | color: #f4516c; | ||
124 | } | ||
125 | |||
126 | .icon-shopping { | ||
127 | color: #34bfa3 | ||
128 | } | ||
129 | |||
130 | .card-panel-icon-wrapper { | ||
131 | float: left; | ||
132 | margin: 14px 0 0 14px; | ||
133 | padding: 16px; | ||
134 | transition: all 0.38s ease-out; | ||
135 | border-radius: 6px; | ||
136 | } | ||
137 | |||
138 | .card-panel-icon { | ||
139 | float: left; | ||
140 | font-size: 48px; | ||
141 | } | ||
142 | |||
143 | .card-panel-description { | ||
144 | float: right; | ||
145 | font-weight: bold; | ||
146 | margin: 26px; | ||
147 | margin-left: 0px; | ||
148 | |||
149 | .card-panel-text { | ||
150 | line-height: 18px; | ||
151 | color: rgba(0, 0, 0, 0.45); | ||
152 | font-size: 16px; | ||
153 | margin-bottom: 12px; | ||
154 | } | ||
155 | |||
156 | .card-panel-num { | ||
157 | font-size: 20px; | ||
158 | } | ||
159 | } | ||
160 | } | ||
161 | } | ||
162 | |||
163 | @media (max-width:550px) { | ||
164 | .card-panel-description { | ||
165 | display: none; | ||
166 | } | ||
167 | |||
168 | .card-panel-icon-wrapper { | ||
169 | float: none !important; | ||
170 | width: 100%; | ||
171 | height: 100%; | ||
172 | margin: 0 !important; | ||
173 | |||
174 | .svg-icon { | ||
175 | display: block; | ||
176 | margin: 14px auto !important; | ||
177 | float: none !important; | ||
178 | } | ||
179 | } | ||
180 | } | ||
181 | </style> | ||
182 |
src/views/dashboard/admin/components/PieChart.vue
File was created | 1 | <template> | |
2 | <div :class="className" :style="{height:height,width:width}" /> | ||
3 | </template> | ||
4 | |||
5 | <script> | ||
6 | import echarts from 'echarts' | ||
7 | require('echarts/theme/macarons') // echarts theme | ||
8 | import resize from './mixins/resize' | ||
9 | |||
10 | export default { | ||
11 | mixins: [resize], | ||
12 | props: { | ||
13 | className: { | ||
14 | type: String, | ||
15 | default: 'chart' | ||
16 | }, | ||
17 | width: { | ||
18 | type: String, | ||
19 | default: '100%' | ||
20 | }, | ||
21 | height: { | ||
22 | type: String, | ||
23 | default: '300px' | ||
24 | } | ||
25 | }, | ||
26 | data() { | ||
27 | return { | ||
28 | chart: null | ||
29 | } | ||
30 | }, | ||
31 | mounted() { | ||
32 | this.$nextTick(() => { | ||
33 | this.initChart() | ||
34 | }) | ||
35 | }, | ||
36 | beforeDestroy() { | ||
37 | if (!this.chart) { | ||
38 | return | ||
39 | } | ||
40 | this.chart.dispose() | ||
41 | this.chart = null | ||
42 | }, | ||
43 | methods: { | ||
44 | initChart() { | ||
45 | this.chart = echarts.init(this.$el, 'macarons') | ||
46 | |||
47 | this.chart.setOption({ | ||
48 | tooltip: { | ||
49 | trigger: 'item', | ||
50 | formatter: '{a} <br/>{b} : {c} ({d}%)' | ||
51 | }, | ||
52 | legend: { | ||
53 | left: 'center', | ||
54 | bottom: '10', | ||
55 | data: ['Industries', 'Technology', 'Forex', 'Gold', 'Forecasts'] | ||
56 | }, | ||
57 | series: [ | ||
58 | { | ||
59 | name: 'WEEKLY WRITE ARTICLES', | ||
60 | type: 'pie', | ||
61 | roseType: 'radius', | ||
62 | radius: [15, 95], | ||
63 | center: ['50%', '38%'], | ||
64 | data: [ | ||
65 | { value: 320, name: 'Industries' }, | ||
66 | { value: 240, name: 'Technology' }, | ||
67 | { value: 149, name: 'Forex' }, | ||
68 | { value: 100, name: 'Gold' }, | ||
69 | { value: 59, name: 'Forecasts' } | ||
70 | ], | ||
71 | animationEasing: 'cubicInOut', | ||
72 | animationDuration: 2600 | ||
73 | } | ||
74 | ] | ||
75 | }) | ||
76 | } | ||
77 | } | ||
78 | } | ||
79 | </script> | ||
80 |
src/views/dashboard/admin/components/RaddarChart.vue
File was created | 1 | <template> | |
2 | <div :class="className" :style="{height:height,width:width}" /> | ||
3 | </template> | ||
4 | |||
5 | <script> | ||
6 | import echarts from 'echarts' | ||
7 | require('echarts/theme/macarons') // echarts theme | ||
8 | import resize from './mixins/resize' | ||
9 | |||
10 | const animationDuration = 3000 | ||
11 | |||
12 | export default { | ||
13 | mixins: [resize], | ||
14 | props: { | ||
15 | className: { | ||
16 | type: String, | ||
17 | default: 'chart' | ||
18 | }, | ||
19 | width: { | ||
20 | type: String, | ||
21 | default: '100%' | ||
22 | }, | ||
23 | height: { | ||
24 | type: String, | ||
25 | default: '300px' | ||
26 | } | ||
27 | }, | ||
28 | data() { | ||
29 | return { | ||
30 | chart: null | ||
31 | } | ||
32 | }, | ||
33 | mounted() { | ||
34 | this.$nextTick(() => { | ||
35 | this.initChart() | ||
36 | }) | ||
37 | }, | ||
38 | beforeDestroy() { | ||
39 | if (!this.chart) { | ||
40 | return | ||
41 | } | ||
42 | this.chart.dispose() | ||
43 | this.chart = null | ||
44 | }, | ||
45 | methods: { | ||
46 | initChart() { | ||
47 | this.chart = echarts.init(this.$el, 'macarons') | ||
48 | |||
49 | this.chart.setOption({ | ||
50 | tooltip: { | ||
51 | trigger: 'axis', | ||
52 | axisPointer: { // 坐标轴指示器,坐标轴触发有效 | ||
53 | type: 'shadow' // 默认为直线,可选为:'line' | 'shadow' | ||
54 | } | ||
55 | }, | ||
56 | radar: { | ||
57 | radius: '66%', | ||
58 | center: ['50%', '42%'], | ||
59 | splitNumber: 8, | ||
60 | splitArea: { | ||
61 | areaStyle: { | ||
62 | color: 'rgba(127,95,132,.3)', | ||
63 | opacity: 1, | ||
64 | shadowBlur: 45, | ||
65 | shadowColor: 'rgba(0,0,0,.5)', | ||
66 | shadowOffsetX: 0, | ||
67 | shadowOffsetY: 15 | ||
68 | } | ||
69 | }, | ||
70 | indicator: [ | ||
71 | { name: 'Sales', max: 10000 }, | ||
72 | { name: 'Administration', max: 20000 }, | ||
73 | { name: 'Information Techology', max: 20000 }, | ||
74 | { name: 'Customer Support', max: 20000 }, | ||
75 | { name: 'Development', max: 20000 }, | ||
76 | { name: 'Marketing', max: 20000 } | ||
77 | ] | ||
78 | }, | ||
79 | legend: { | ||
80 | left: 'center', | ||
81 | bottom: '10', | ||
82 | data: ['Allocated Budget', 'Expected Spending', 'Actual Spending'] | ||
83 | }, | ||
84 | series: [{ | ||
85 | type: 'radar', | ||
86 | symbolSize: 0, | ||
87 | areaStyle: { | ||
88 | normal: { | ||
89 | shadowBlur: 13, | ||
90 | shadowColor: 'rgba(0,0,0,.2)', | ||
91 | shadowOffsetX: 0, | ||
92 | shadowOffsetY: 10, | ||
93 | opacity: 1 | ||
94 | } | ||
95 | }, | ||
96 | data: [ | ||
97 | { | ||
98 | value: [5000, 7000, 12000, 11000, 15000, 14000], | ||
99 | name: 'Allocated Budget' | ||
100 | }, | ||
101 | { | ||
102 | value: [4000, 9000, 15000, 15000, 13000, 11000], | ||
103 | name: 'Expected Spending' | ||
104 | }, | ||
105 | { | ||
106 | value: [5500, 11000, 12000, 15000, 12000, 12000], | ||
107 | name: 'Actual Spending' | ||
108 | } | ||
109 | ], | ||
110 | animationDuration: animationDuration | ||
111 | }] | ||
112 | }) | ||
113 | } | ||
114 | } | ||
115 | } | ||
116 | </script> | ||
117 |
src/views/dashboard/admin/components/TodoList/Todo.vue
File was created | 1 | <template> | |
2 | <li :class="{ completed: todo.done, editing: editing }" class="todo"> | ||
3 | <div class="view"> | ||
4 | <input | ||
5 | :checked="todo.done" | ||
6 | class="toggle" | ||
7 | type="checkbox" | ||
8 | @change="toggleTodo( todo)" | ||
9 | > | ||
10 | <label @dblclick="editing = true" v-text="todo.text" /> | ||
11 | <button class="destroy" @click="deleteTodo( todo )" /> | ||
12 | </div> | ||
13 | <input | ||
14 | v-show="editing" | ||
15 | v-focus="editing" | ||
16 | :value="todo.text" | ||
17 | class="edit" | ||
18 | @keyup.enter="doneEdit" | ||
19 | @keyup.esc="cancelEdit" | ||
20 | @blur="doneEdit" | ||
21 | > | ||
22 | </li> | ||
23 | </template> | ||
24 | |||
25 | <script> | ||
26 | export default { | ||
27 | name: 'Todo', | ||
28 | directives: { | ||
29 | focus(el, { value }, { context }) { | ||
30 | if (value) { | ||
31 | context.$nextTick(() => { | ||
32 | el.focus() | ||
33 | }) | ||
34 | } | ||
35 | } | ||
36 | }, | ||
37 | props: { | ||
38 | todo: { | ||
39 | type: Object, | ||
40 | default: function() { | ||
41 | return {} | ||
42 | } | ||
43 | } | ||
44 | }, | ||
45 | data() { | ||
46 | return { | ||
47 | editing: false | ||
48 | } | ||
49 | }, | ||
50 | methods: { | ||
51 | deleteTodo(todo) { | ||
52 | this.$emit('deleteTodo', todo) | ||
53 | }, | ||
54 | editTodo({ todo, value }) { | ||
55 | this.$emit('editTodo', { todo, value }) | ||
56 | }, | ||
57 | toggleTodo(todo) { | ||
58 | this.$emit('toggleTodo', todo) | ||
59 | }, | ||
60 | doneEdit(e) { | ||
61 | const value = e.target.value.trim() | ||
62 | const { todo } = this | ||
63 | if (!value) { | ||
64 | this.deleteTodo({ | ||
65 | todo | ||
66 | }) | ||
67 | } else if (this.editing) { | ||
68 | this.editTodo({ | ||
69 | todo, | ||
70 | value | ||
71 | }) | ||
72 | this.editing = false | ||
73 | } | ||
74 | }, | ||
75 | cancelEdit(e) { | ||
76 | e.target.value = this.todo.text | ||
77 | this.editing = false | ||
78 | } | ||
79 | } | ||
80 | } | ||
81 | </script> | ||
82 |
src/views/dashboard/admin/components/TodoList/index.scss
File was created | 1 | .todoapp { | |
2 | font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif; | ||
3 | line-height: 1.4em; | ||
4 | color: #4d4d4d; | ||
5 | min-width: 230px; | ||
6 | max-width: 550px; | ||
7 | margin: 0 auto ; | ||
8 | -webkit-font-smoothing: antialiased; | ||
9 | -moz-osx-font-smoothing: grayscale; | ||
10 | font-weight: 300; | ||
11 | background: #fff; | ||
12 | z-index: 1; | ||
13 | position: relative; | ||
14 | button { | ||
15 | margin: 0; | ||
16 | padding: 0; | ||
17 | border: 0; | ||
18 | background: none; | ||
19 | font-size: 100%; | ||
20 | vertical-align: baseline; | ||
21 | font-family: inherit; | ||
22 | font-weight: inherit; | ||
23 | color: inherit; | ||
24 | -webkit-appearance: none; | ||
25 | appearance: none; | ||
26 | -webkit-font-smoothing: antialiased; | ||
27 | -moz-osx-font-smoothing: grayscale; | ||
28 | } | ||
29 | :focus { | ||
30 | outline: 0; | ||
31 | } | ||
32 | .hidden { | ||
33 | display: none; | ||
34 | } | ||
35 | .todoapp { | ||
36 | background: #fff; | ||
37 | margin: 130px 0 40px 0; | ||
38 | position: relative; | ||
39 | box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1); | ||
40 | } | ||
41 | .todoapp input::-webkit-input-placeholder { | ||
42 | font-style: italic; | ||
43 | font-weight: 300; | ||
44 | color: #e6e6e6; | ||
45 | } | ||
46 | .todoapp input::-moz-placeholder { | ||
47 | font-style: italic; | ||
48 | font-weight: 300; | ||
49 | color: #e6e6e6; | ||
50 | } | ||
51 | .todoapp input::input-placeholder { | ||
52 | font-style: italic; | ||
53 | font-weight: 300; | ||
54 | color: #e6e6e6; | ||
55 | } | ||
56 | .todoapp h1 { | ||
57 | position: absolute; | ||
58 | top: -155px; | ||
59 | width: 100%; | ||
60 | font-size: 100px; | ||
61 | font-weight: 100; | ||
62 | text-align: center; | ||
63 | color: rgba(175, 47, 47, 0.15); | ||
64 | -webkit-text-rendering: optimizeLegibility; | ||
65 | -moz-text-rendering: optimizeLegibility; | ||
66 | text-rendering: optimizeLegibility; | ||
67 | } | ||
68 | .new-todo, | ||
69 | .edit { | ||
70 | position: relative; | ||
71 | margin: 0; | ||
72 | width: 100%; | ||
73 | font-size: 18px; | ||
74 | font-family: inherit; | ||
75 | font-weight: inherit; | ||
76 | line-height: 1.4em; | ||
77 | border: 0; | ||
78 | color: inherit; | ||
79 | padding: 6px; | ||
80 | border: 1px solid #999; | ||
81 | box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2); | ||
82 | box-sizing: border-box; | ||
83 | -webkit-font-smoothing: antialiased; | ||
84 | -moz-osx-font-smoothing: grayscale; | ||
85 | } | ||
86 | .new-todo { | ||
87 | padding: 10px 16px 16px 60px; | ||
88 | border: none; | ||
89 | background: rgba(0, 0, 0, 0.003); | ||
90 | box-shadow: inset 0 -2px 1px rgba(0, 0, 0, 0.03); | ||
91 | } | ||
92 | .main { | ||
93 | position: relative; | ||
94 | z-index: 2; | ||
95 | border-top: 1px solid #e6e6e6; | ||
96 | } | ||
97 | .toggle-all { | ||
98 | text-align: center; | ||
99 | border: none; | ||
100 | /* Mobile Safari */ | ||
101 | opacity: 0; | ||
102 | position: absolute; | ||
103 | } | ||
104 | .toggle-all+label { | ||
105 | width: 60px; | ||
106 | height: 34px; | ||
107 | font-size: 0; | ||
108 | position: absolute; | ||
109 | top: -52px; | ||
110 | left: -13px; | ||
111 | -webkit-transform: rotate(90deg); | ||
112 | transform: rotate(90deg); | ||
113 | } | ||
114 | .toggle-all+label:before { | ||
115 | content: '❯'; | ||
116 | font-size: 22px; | ||
117 | color: #e6e6e6; | ||
118 | padding: 10px 27px 10px 27px; | ||
119 | } | ||
120 | .toggle-all:checked+label:before { | ||
121 | color: #737373; | ||
122 | } | ||
123 | .todo-list { | ||
124 | margin: 0; | ||
125 | padding: 0; | ||
126 | list-style: none; | ||
127 | } | ||
128 | .todo-list li { | ||
129 | position: relative; | ||
130 | font-size: 24px; | ||
131 | border-bottom: 1px solid #ededed; | ||
132 | } | ||
133 | .todo-list li:last-child { | ||
134 | border-bottom: none; | ||
135 | } | ||
136 | .todo-list li.editing { | ||
137 | border-bottom: none; | ||
138 | padding: 0; | ||
139 | } | ||
140 | .todo-list li.editing .edit { | ||
141 | display: block; | ||
142 | width: 506px; | ||
143 | padding: 12px 16px; | ||
144 | margin: 0 0 0 43px; | ||
145 | } | ||
146 | .todo-list li.editing .view { | ||
147 | display: none; | ||
148 | } | ||
149 | .todo-list li .toggle { | ||
150 | text-align: center; | ||
151 | width: 40px; | ||
152 | /* auto, since non-WebKit browsers doesn't support input styling */ | ||
153 | height: auto; | ||
154 | position: absolute; | ||
155 | top: 0; | ||
156 | bottom: 0; | ||
157 | margin: auto 0; | ||
158 | border: none; | ||
159 | /* Mobile Safari */ | ||
160 | -webkit-appearance: none; | ||
161 | appearance: none; | ||
162 | } | ||
163 | .todo-list li .toggle { | ||
164 | opacity: 0; | ||
165 | } | ||
166 | .todo-list li .toggle+label { | ||
167 | /* | ||
168 | Firefox requires `#` to be escaped - https://bugzilla.mozilla.org/show_bug.cgi?id=922433 | ||
169 | IE and Edge requires *everything* to be escaped to render, so we do that instead of just the `#` - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/7157459/ | ||
170 | */ | ||
171 | background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23ededed%22%20stroke-width%3D%223%22/%3E%3C/svg%3E'); | ||
172 | background-repeat: no-repeat; | ||
173 | background-position: center left; | ||
174 | background-size: 36px; | ||
175 | } | ||
176 | .todo-list li .toggle:checked+label { | ||
177 | background-size: 36px; | ||
178 | background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23bddad5%22%20stroke-width%3D%223%22/%3E%3Cpath%20fill%3D%22%235dc2af%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22/%3E%3C/svg%3E'); | ||
179 | } | ||
180 | .todo-list li label { | ||
181 | word-break: break-all; | ||
182 | padding: 15px 15px 15px 50px; | ||
183 | display: block; | ||
184 | line-height: 1.0; | ||
185 | font-size: 14px; | ||
186 | transition: color 0.4s; | ||
187 | } | ||
188 | .todo-list li.completed label { | ||
189 | color: #d9d9d9; | ||
190 | text-decoration: line-through; | ||
191 | } | ||
192 | .todo-list li .destroy { | ||
193 | display: none; | ||
194 | position: absolute; | ||
195 | top: 0; | ||
196 | right: 10px; | ||
197 | bottom: 0; | ||
198 | width: 40px; | ||
199 | height: 40px; | ||
200 | margin: auto 0; | ||
201 | font-size: 30px; | ||
202 | color: #cc9a9a; | ||
203 | transition: color 0.2s ease-out; | ||
204 | cursor: pointer; | ||
205 | } | ||
206 | .todo-list li .destroy:hover { | ||
207 | color: #af5b5e; | ||
208 | } | ||
209 | .todo-list li .destroy:after { | ||
210 | content: '×'; | ||
211 | } | ||
212 | .todo-list li:hover .destroy { | ||
213 | display: block; | ||
214 | } | ||
215 | .todo-list li .edit { | ||
216 | display: none; | ||
217 | } | ||
218 | .todo-list li.editing:last-child { | ||
219 | margin-bottom: -1px; | ||
220 | } | ||
221 | .footer { | ||
222 | color: #777; | ||
223 | position: relative; | ||
224 | padding: 10px 15px; | ||
225 | height: 40px; | ||
226 | text-align: center; | ||
227 | border-top: 1px solid #e6e6e6; | ||
228 | } | ||
229 | .footer:before { | ||
230 | content: ''; | ||
231 | position: absolute; | ||
232 | right: 0; | ||
233 | bottom: 0; | ||
234 | left: 0; | ||
235 | height: 40px; | ||
236 | overflow: hidden; | ||
237 | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 0 8px 0 -3px #f6f6f6, 0 9px 1px -3px rgba(0, 0, 0, 0.2), 0 16px 0 -6px #f6f6f6, 0 17px 2px -6px rgba(0, 0, 0, 0.2); | ||
238 | } | ||
239 | .todo-count { | ||
240 | float: left; | ||
241 | text-align: left; | ||
242 | } | ||
243 | .todo-count strong { | ||
244 | font-weight: 300; | ||
245 | } | ||
246 | .filters { | ||
247 | margin: 0; | ||
248 | padding: 0; | ||
249 | position: relative; | ||
250 | z-index: 1; | ||
251 | list-style: none; | ||
252 | } | ||
253 | .filters li { | ||
254 | display: inline; | ||
255 | } | ||
256 | .filters li a { | ||
257 | color: inherit; | ||
258 | font-size: 12px; | ||
259 | padding: 3px 7px; | ||
260 | text-decoration: none; | ||
261 | border: 1px solid transparent; | ||
262 | border-radius: 3px; | ||
263 | } | ||
264 | .filters li a:hover { | ||
265 | border-color: rgba(175, 47, 47, 0.1); | ||
266 | } | ||
267 | .filters li a.selected { | ||
268 | border-color: rgba(175, 47, 47, 0.2); | ||
269 | } | ||
270 | .clear-completed, | ||
271 | html .clear-completed:active { | ||
272 | float: right; | ||
273 | position: relative; | ||
274 | line-height: 20px; | ||
275 | text-decoration: none; | ||
276 | cursor: pointer; | ||
277 | } | ||
278 | .clear-completed:hover { | ||
279 | text-decoration: underline; | ||
280 | } | ||
281 | .info { | ||
282 | margin: 65px auto 0; | ||
283 | color: #bfbfbf; | ||
284 | font-size: 10px; | ||
285 | text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); | ||
286 | text-align: center; | ||
287 | } | ||
288 | .info p { | ||
289 | line-height: 1; | ||
290 | } | ||
291 | .info a { | ||
292 | color: inherit; | ||
293 | text-decoration: none; | ||
294 | font-weight: 400; | ||
295 | } | ||
296 | .info a:hover { | ||
297 | text-decoration: underline; | ||
298 | } | ||
299 | /* | ||
300 | Hack to remove background from Mobile Safari. | ||
301 | Can't use it globally since it destroys checkboxes in Firefox | ||
302 | */ | ||
303 | @media screen and (-webkit-min-device-pixel-ratio:0) { | ||
304 | .toggle-all, | ||
305 | .todo-list li .toggle { | ||
306 | background: none; | ||
307 | } | ||
308 | .todo-list li .toggle { | ||
309 | height: 40px; | ||
310 | } | ||
311 | } | ||
312 | @media (max-width: 430px) { | ||
313 | .footer { | ||
314 | height: 50px; | ||
315 | } | ||
316 | .filters { | ||
317 | bottom: 10px; | ||
318 | } | ||
319 | } | ||
320 | } | ||
321 |
src/views/dashboard/admin/components/TodoList/index.vue
File was created | 1 | <template> | |
2 | <section class="todoapp"> | ||
3 | <!-- header --> | ||
4 | <header class="header"> | ||
5 | <input class="new-todo" autocomplete="off" placeholder="Todo List" @keyup.enter="addTodo"> | ||
6 | </header> | ||
7 | <!-- main section --> | ||
8 | <section v-show="todos.length" class="main"> | ||
9 | <input id="toggle-all" :checked="allChecked" class="toggle-all" type="checkbox" @change="toggleAll({ done: !allChecked })"> | ||
10 | <label for="toggle-all" /> | ||
11 | <ul class="todo-list"> | ||
12 | <todo | ||
13 | v-for="(todo, index) in filteredTodos" | ||
14 | :key="index" | ||
15 | :todo="todo" | ||
16 | @toggleTodo="toggleTodo" | ||
17 | @editTodo="editTodo" | ||
18 | @deleteTodo="deleteTodo" | ||
19 | /> | ||
20 | </ul> | ||
21 | </section> | ||
22 | <!-- footer --> | ||
23 | <footer v-show="todos.length" class="footer"> | ||
24 | <span class="todo-count"> | ||
25 | <strong>{{ remaining }}</strong> | ||
26 | {{ remaining | pluralize('item') }} left | ||
27 | </span> | ||
28 | <ul class="filters"> | ||
29 | <li v-for="(val, key) in filters" :key="key"> | ||
30 | <a :class="{ selected: visibility === key }" @click.prevent="visibility = key">{{ key | capitalize }}</a> | ||
31 | </li> | ||
32 | </ul> | ||
33 | <!-- <button class="clear-completed" v-show="todos.length > remaining" @click="clearCompleted"> | ||
34 | Clear completed | ||
35 | </button> --> | ||
36 | </footer> | ||
37 | </section> | ||
38 | </template> | ||
39 | |||
40 | <script> | ||
41 | import Todo from './Todo.vue' | ||
42 | |||
43 | const STORAGE_KEY = 'todos' | ||
44 | const filters = { | ||
45 | all: todos => todos, | ||
46 | active: todos => todos.filter(todo => !todo.done), | ||
47 | completed: todos => todos.filter(todo => todo.done) | ||
48 | } | ||
49 | const defalutList = [ | ||
50 | { text: 'star this repository', done: false }, | ||
51 | { text: 'fork this repository', done: false }, | ||
52 | { text: 'follow author', done: false }, | ||
53 | { text: 'vue-element-admin', done: true }, | ||
54 | { text: 'vue', done: true }, | ||
55 | { text: 'element-ui', done: true }, | ||
56 | { text: 'axios', done: true }, | ||
57 | { text: 'webpack', done: true } | ||
58 | ] | ||
59 | export default { | ||
60 | components: { Todo }, | ||
61 | filters: { | ||
62 | pluralize: (n, w) => n === 1 ? w : w + 's', | ||
63 | capitalize: s => s.charAt(0).toUpperCase() + s.slice(1) | ||
64 | }, | ||
65 | data() { | ||
66 | return { | ||
67 | visibility: 'all', | ||
68 | filters, | ||
69 | // todos: JSON.parse(window.localStorage.getItem(STORAGE_KEY)) || defalutList | ||
70 | todos: defalutList | ||
71 | } | ||
72 | }, | ||
73 | computed: { | ||
74 | allChecked() { | ||
75 | return this.todos.every(todo => todo.done) | ||
76 | }, | ||
77 | filteredTodos() { | ||
78 | return filters[this.visibility](this.todos) | ||
79 | }, | ||
80 | remaining() { | ||
81 | return this.todos.filter(todo => !todo.done).length | ||
82 | } | ||
83 | }, | ||
84 | methods: { | ||
85 | setLocalStorage() { | ||
86 | window.localStorage.setItem(STORAGE_KEY, JSON.stringify(this.todos)) | ||
87 | }, | ||
88 | addTodo(e) { | ||
89 | const text = e.target.value | ||
90 | if (text.trim()) { | ||
91 | this.todos.push({ | ||
92 | text, | ||
93 | done: false | ||
94 | }) | ||
95 | this.setLocalStorage() | ||
96 | } | ||
97 | e.target.value = '' | ||
98 | }, | ||
99 | toggleTodo(val) { | ||
100 | val.done = !val.done | ||
101 | this.setLocalStorage() | ||
102 | }, | ||
103 | deleteTodo(todo) { | ||
104 | this.todos.splice(this.todos.indexOf(todo), 1) | ||
105 | this.setLocalStorage() | ||
106 | }, | ||
107 | editTodo({ todo, value }) { | ||
108 | todo.text = value | ||
109 | this.setLocalStorage() | ||
110 | }, | ||
111 | clearCompleted() { | ||
112 | this.todos = this.todos.filter(todo => !todo.done) | ||
113 | this.setLocalStorage() | ||
114 | }, | ||
115 | toggleAll({ done }) { | ||
116 | this.todos.forEach(todo => { | ||
117 | todo.done = done | ||
118 | this.setLocalStorage() | ||
119 | }) | ||
120 | } | ||
121 | } | ||
122 | } | ||
123 | </script> | ||
124 | |||
125 | <style lang="scss"> | ||
126 | @import './index.scss'; | ||
127 | </style> | ||
128 |
src/views/dashboard/admin/components/TransactionTable.vue
File was created | 1 | <template> | |
2 | <el-table :data="list" style="width: 100%;padding-top: 15px;"> | ||
3 | <el-table-column label="Order_No" min-width="200"> | ||
4 | <template slot-scope="scope"> | ||
5 | {{ scope.row.order_no | orderNoFilter }} | ||
6 | </template> | ||
7 | </el-table-column> | ||
8 | <el-table-column label="Price" width="195" align="center"> | ||
9 | <template slot-scope="scope"> | ||
10 | ¥{{ scope.row.price | toThousandFilter }} | ||
11 | </template> | ||
12 | </el-table-column> | ||
13 | <el-table-column label="Status" width="100" align="center"> | ||
14 | <template slot-scope="{row}"> | ||
15 | <el-tag :type="row.status | statusFilter"> | ||
16 | {{ row.status }} | ||
17 | </el-tag> | ||
18 | </template> | ||
19 | </el-table-column> | ||
20 | </el-table> | ||
21 | </template> | ||
22 | |||
23 | <script> | ||
24 | import { transactionList } from '@/api/remote-search' | ||
25 | |||
26 | export default { | ||
27 | filters: { | ||
28 | statusFilter(status) { | ||
29 | const statusMap = { | ||
30 | success: 'success', | ||
31 | pending: 'danger' | ||
32 | } | ||
33 | return statusMap[status] | ||
34 | }, | ||
35 | orderNoFilter(str) { | ||
36 | return str.substring(0, 30) | ||
37 | } | ||
38 | }, | ||
39 | data() { | ||
40 | return { | ||
41 | list: null | ||
42 | } | ||
43 | }, | ||
44 | created() { | ||
45 | this.fetchData() | ||
46 | }, | ||
47 | methods: { | ||
48 | fetchData() { | ||
49 | transactionList().then(response => { | ||
50 | this.list = response.data.items.slice(0, 8) | ||
51 | }) | ||
52 | } | ||
53 | } | ||
54 | } | ||
55 | </script> | ||
56 |
src/views/dashboard/admin/components/mixins/resize.js
File was created | 1 | import { debounce } from '@/utils' | |
2 | |||
3 | export default { | ||
4 | data() { | ||
5 | return { | ||
6 | $_sidebarElm: null, | ||
7 | $_resizeHandler: null | ||
8 | } | ||
9 | }, | ||
10 | mounted() { | ||
11 | this.$_resizeHandler = debounce(() => { | ||
12 | if (this.chart) { | ||
13 | this.chart.resize() | ||
14 | } | ||
15 | }, 100) | ||
16 | this.$_initResizeEvent() | ||
17 | this.$_initSidebarResizeEvent() | ||
18 | }, | ||
19 | beforeDestroy() { | ||
20 | this.$_destroyResizeEvent() | ||
21 | this.$_destroySidebarResizeEvent() | ||
22 | }, | ||
23 | // to fixed bug when cached by keep-alive | ||
24 | // https://github.com/PanJiaChen/vue-element-admin/issues/2116 | ||
25 | activated() { | ||
26 | this.$_initResizeEvent() | ||
27 | this.$_initSidebarResizeEvent() | ||
28 | }, | ||
29 | deactivated() { | ||
30 | this.$_destroyResizeEvent() | ||
31 | this.$_destroySidebarResizeEvent() | ||
32 | }, | ||
33 | methods: { | ||
34 | // use $_ for mixins properties | ||
35 | // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential | ||
36 | $_initResizeEvent() { | ||
37 | window.addEventListener('resize', this.$_resizeHandler) | ||
38 | }, | ||
39 | $_destroyResizeEvent() { | ||
40 | window.removeEventListener('resize', this.$_resizeHandler) | ||
41 | }, | ||
42 | $_sidebarResizeHandler(e) { | ||
43 | if (e.propertyName === 'width') { | ||
44 | this.$_resizeHandler() | ||
45 | } | ||
46 | }, | ||
47 | $_initSidebarResizeEvent() { | ||
48 | this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0] | ||
49 | this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler) | ||
50 | }, | ||
51 | $_destroySidebarResizeEvent() { | ||
52 | this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler) | ||
53 | } | ||
54 | } | ||
55 | } | ||
56 |
src/views/dashboard/admin/index.vue
File was created | 1 | <template> | |
2 | <div class="dashboard-editor-container"> | ||
3 | <github-corner class="github-corner" /> | ||
4 | |||
5 | <panel-group @handleSetLineChartData="handleSetLineChartData" /> | ||
6 | |||
7 | <el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;"> | ||
8 | <line-chart :chart-data="lineChartData" /> | ||
9 | </el-row> | ||
10 | |||
11 | <el-row :gutter="32"> | ||
12 | <el-col :xs="24" :sm="24" :lg="8"> | ||
13 | <div class="chart-wrapper"> | ||
14 | <raddar-chart /> | ||
15 | </div> | ||
16 | </el-col> | ||
17 | <el-col :xs="24" :sm="24" :lg="8"> | ||
18 | <div class="chart-wrapper"> | ||
19 | <pie-chart /> | ||
20 | </div> | ||
21 | </el-col> | ||
22 | <el-col :xs="24" :sm="24" :lg="8"> | ||
23 | <div class="chart-wrapper"> | ||
24 | <bar-chart /> | ||
25 | </div> | ||
26 | </el-col> | ||
27 | </el-row> | ||
28 | |||
29 | <el-row :gutter="8"> | ||
30 | <el-col :xs="{span: 24}" :sm="{span: 24}" :md="{span: 24}" :lg="{span: 12}" :xl="{span: 12}" style="padding-right:8px;margin-bottom:30px;"> | ||
31 | <transaction-table /> | ||
32 | </el-col> | ||
33 | <el-col :xs="{span: 24}" :sm="{span: 12}" :md="{span: 12}" :lg="{span: 6}" :xl="{span: 6}" style="margin-bottom:30px;"> | ||
34 | <todo-list /> | ||
35 | </el-col> | ||
36 | <el-col :xs="{span: 24}" :sm="{span: 12}" :md="{span: 12}" :lg="{span: 6}" :xl="{span: 6}" style="margin-bottom:30px;"> | ||
37 | <box-card /> | ||
38 | </el-col> | ||
39 | </el-row> | ||
40 | </div> | ||
41 | </template> | ||
42 | |||
43 | <script> | ||
44 | import GithubCorner from '@/components/GithubCorner' | ||
45 | import PanelGroup from './components/PanelGroup' | ||
46 | import LineChart from './components/LineChart' | ||
47 | import RaddarChart from './components/RaddarChart' | ||
48 | import PieChart from './components/PieChart' | ||
49 | import BarChart from './components/BarChart' | ||
50 | import TransactionTable from './components/TransactionTable' | ||
51 | import TodoList from './components/TodoList' | ||
52 | import BoxCard from './components/BoxCard' | ||
53 | |||
54 | const lineChartData = { | ||
55 | newVisitis: { | ||
56 | expectedData: [100, 120, 161, 134, 105, 160, 165], | ||
57 | actualData: [120, 82, 91, 154, 162, 140, 145] | ||
58 | }, | ||
59 | messages: { | ||
60 | expectedData: [200, 192, 120, 144, 160, 130, 140], | ||
61 | actualData: [180, 160, 151, 106, 145, 150, 130] | ||
62 | }, | ||
63 | purchases: { | ||
64 | expectedData: [80, 100, 121, 104, 105, 90, 100], | ||
65 | actualData: [120, 90, 100, 138, 142, 130, 130] | ||
66 | }, | ||
67 | shoppings: { | ||
68 | expectedData: [130, 140, 141, 142, 145, 150, 160], | ||
69 | actualData: [120, 82, 91, 154, 162, 140, 130] | ||
70 | } | ||
71 | } | ||
72 | |||
73 | export default { | ||
74 | name: 'DashboardAdmin', | ||
75 | components: { | ||
76 | GithubCorner, | ||
77 | PanelGroup, | ||
78 | LineChart, | ||
79 | RaddarChart, | ||
80 | PieChart, | ||
81 | BarChart, | ||
82 | TransactionTable, | ||
83 | TodoList, | ||
84 | BoxCard | ||
85 | }, | ||
86 | data() { | ||
87 | return { | ||
88 | lineChartData: lineChartData.newVisitis | ||
89 | } | ||
90 | }, | ||
91 | methods: { | ||
92 | handleSetLineChartData(type) { | ||
93 | this.lineChartData = lineChartData[type] | ||
94 | } | ||
95 | } | ||
96 | } | ||
97 | </script> | ||
98 | |||
99 | <style lang="scss" scoped> | ||
100 | .dashboard-editor-container { | ||
101 | padding: 32px; | ||
102 | background-color: rgb(240, 242, 245); | ||
103 | position: relative; | ||
104 | |||
105 | .github-corner { | ||
106 | position: absolute; | ||
107 | top: 0px; | ||
108 | border: 0; | ||
109 | right: 0; | ||
110 | } | ||
111 | |||
112 | .chart-wrapper { | ||
113 | background: #fff; | ||
114 | padding: 16px 16px 0; | ||
115 | margin-bottom: 32px; | ||
116 | } | ||
117 | } | ||
118 | |||
119 | @media (max-width:1024px) { | ||
120 | .chart-wrapper { | ||
121 | padding: 8px; | ||
122 | } | ||
123 | } | ||
124 | </style> | ||
125 |
src/views/dashboard/editor/index.vue
File was created | 1 | <template> | |
2 | <div class="dashboard-editor-container"> | ||
3 | <div class=" clearfix"> | ||
4 | <pan-thumb :image="avatar" style="float: left"> | ||
5 | Your roles: | ||
6 | <span v-for="item in roles" :key="item" class="pan-info-roles">{{ item }}</span> | ||
7 | </pan-thumb> | ||
8 | <github-corner style="position: absolute; top: 0px; border: 0; right: 0;" /> | ||
9 | <div class="info-container"> | ||
10 | <span class="display_name">{{ name }}</span> | ||
11 | <span style="font-size:20px;padding-top:20px;display:inline-block;">Editor's Dashboard</span> | ||
12 | </div> | ||
13 | </div> | ||
14 | <div> | ||
15 | <img :src="emptyGif" class="emptyGif"> | ||
16 | </div> | ||
17 | </div> | ||
18 | </template> | ||
19 | |||
20 | <script> | ||
21 | import { mapGetters } from 'vuex' | ||
22 | import PanThumb from '@/components/PanThumb' | ||
23 | import GithubCorner from '@/components/GithubCorner' | ||
24 | |||
25 | export default { | ||
26 | name: 'DashboardEditor', | ||
27 | components: { PanThumb, GithubCorner }, | ||
28 | data() { | ||
29 | return { | ||
30 | emptyGif: 'https://wpimg.wallstcn.com/0e03b7da-db9e-4819-ba10-9016ddfdaed3' | ||
31 | } | ||
32 | }, | ||
33 | computed: { | ||
34 | ...mapGetters([ | ||
35 | 'name', | ||
36 | 'avatar', | ||
37 | 'roles' | ||
38 | ]) | ||
39 | } | ||
40 | } | ||
41 | </script> | ||
42 | |||
43 | <style lang="scss" scoped> | ||
44 | .emptyGif { | ||
45 | display: block; | ||
46 | width: 45%; | ||
47 | margin: 0 auto; | ||
48 | } | ||
49 | |||
50 | .dashboard-editor-container { | ||
51 | background-color: #e3e3e3; | ||
52 | min-height: 100vh; | ||
53 | padding: 50px 60px 0px; | ||
54 | .pan-info-roles { | ||
55 | font-size: 12px; | ||
56 | font-weight: 700; | ||
57 | color: #333; | ||
58 | display: block; | ||
59 | } | ||
60 | .info-container { | ||
61 | position: relative; | ||
62 | margin-left: 190px; | ||
63 | height: 150px; | ||
64 | line-height: 200px; | ||
65 | .display_name { | ||
66 | font-size: 48px; | ||
67 | line-height: 48px; | ||
68 | color: #212121; | ||
69 | position: absolute; | ||
70 | top: 25px; | ||
71 | } | ||
72 | } | ||
73 | } | ||
74 | </style> | ||
75 |
src/views/dashboard/index.vue
1 | <template> | 1 | <template> |
2 | <div> | 2 | <div class="dashboard-container"> |
3 | <el-row :gutter="20"> | 3 | <component :is="currentRole" /> |
4 | <el-col :span="8"> | ||
5 | <el-card shadow="hover" class="mgb20" style="height:252px;"> | ||
6 | <div class="user-info"> | ||
7 | <img src="../../assets/img/img.jpg" class="user-avator" alt /> | ||
8 | <div class="user-info-cont"> | ||
9 | <div class="user-info-name">{{name}}</div> | ||
10 | <div>{{role}}</div> | ||
11 | </div> | ||
12 | </div> | ||
13 | <div class="user-info-list"> | ||
14 | 上次登录时间: | ||
15 | <span>2019-11-01</span> | ||
16 | </div> | ||
17 | <div class="user-info-list"> | ||
18 | 上次登录地点: | ||
19 | <span>东莞</span> | ||
20 | </div> | ||
21 | </el-card> | ||
22 | <el-card shadow="hover" style="height:252px;"> | ||
23 | <div slot="header" class="clearfix"> | ||
24 | <span>语言详情</span> | ||
25 | </div>Vue | ||
26 | <el-progress :percentage="71.3" color="#42b983"></el-progress>JavaScript | ||
27 | <el-progress :percentage="24.1" color="#f1e05a"></el-progress>CSS | ||
28 | <el-progress :percentage="13.7"></el-progress>HTML | ||
29 | <el-progress :percentage="5.9" color="#f56c6c"></el-progress> | ||
30 | </el-card> | ||
31 | </el-col> | ||
32 | <el-col :span="16"> | ||
33 | <el-row :gutter="20" class="mgb20"> | ||
34 | <el-col :span="8"> | ||
35 | <el-card shadow="hover" :body-style="{padding: '0px'}"> | ||
36 | <div class="grid-content grid-con-1"> | ||
37 | <i class="el-icon-lx-people grid-con-icon"></i> | ||
38 | <div class="grid-cont-right"> | ||
39 | <div class="grid-num">1234</div> | ||
40 | <div>用户访问量</div> | ||
41 | </div> | ||
42 | </div> | ||
43 | </el-card> | ||
44 | </el-col> | ||
45 | <el-col :span="8"> | ||
46 | <el-card shadow="hover" :body-style="{padding: '0px'}"> | ||
47 | <div class="grid-content grid-con-2"> | ||
48 | <i class="el-icon-lx-notice grid-con-icon"></i> | ||
49 | <div class="grid-cont-right"> | ||
50 | <div class="grid-num">321</div> | ||
51 | <div>系统消息</div> | ||
52 | </div> | ||
53 | </div> | ||
54 | </el-card> | ||
55 | </el-col> | ||
56 | <el-col :span="8"> | ||
57 | <el-card shadow="hover" :body-style="{padding: '0px'}"> | ||
58 | <div class="grid-content grid-con-3"> | ||
59 | <i class="el-icon-lx-goods grid-con-icon"></i> | ||
60 | <div class="grid-cont-right"> | ||
61 | <div class="grid-num">5000</div> | ||
62 | <div>数量</div> | ||
63 | </div> | ||
64 | </div> | ||
65 | </el-card> | ||
66 | </el-col> | ||
67 | </el-row> | ||
68 | <el-card shadow="hover" style="height:403px;"> | ||
69 | <div slot="header" class="clearfix"> | ||
70 | <span>待办事项</span> | ||
71 | <el-button style="float: right; padding: 3px 0" type="text" @click="addAction">添加</el-button> | ||
72 | </div> | ||
73 | <el-table :show-header="false" :data="todoList" style="width:100%;"> | ||
74 | <el-table-column width="40"> | ||
75 | <template slot-scope="scope"> | ||
76 | <el-checkbox v-model="scope.row.status"></el-checkbox> | ||
77 | </template> | ||
78 | </el-table-column> | ||
79 | <el-table-column> | ||
80 | <template slot-scope="scope"> | ||
81 | <div | ||
82 | class="todo-item" | ||
83 | :class="{'todo-item-del': scope.row.status}" | ||
84 | >{{scope.row.title}}</div> | ||
85 | </template> | ||
86 | </el-table-column> | ||
87 | <el-table-column width="60"> | ||
88 | <template> | ||
89 | <i class="el-icon-edit" @click="modiAction"></i> | ||
90 | <i class="el-icon-delete" @click="delAction"></i> | ||
91 | </template> | ||
92 | </el-table-column> | ||
93 | </el-table> | ||
94 | </el-card> | ||
95 | </el-col> | ||
96 | </el-row> | ||
97 | <el-row :gutter="20"> | ||
98 | <el-col :span="12"> | ||
99 | <el-card shadow="hover"> | ||
100 | <schart ref="bar" class="schart" canvasId="bar" :options="options"></schart> | ||
101 | </el-card> | ||
102 | </el-col> | ||
103 | <el-col :span="12"> | ||
104 | <el-card shadow="hover"> | ||
105 | <schart ref="line" class="schart" canvasId="line" :options="options2"></schart> | ||
106 | </el-card> | ||
107 | </el-col> | ||
108 | </el-row> | ||
109 | </div> | 4 | </div> |
110 | </template> | 5 | </template> |
111 | 6 | ||
112 | <script> | 7 | <script> |
113 | import { mapGetters } from "vuex"; | 8 | import { mapGetters } from 'vuex' |
114 | import Vue from "vue"; | 9 | import adminDashboard from './admin' |
115 | import { | 10 | import editorDashboard from './editor' |
116 | Pagination, | ||
117 | Dialog, | ||
118 | Autocomplete, | ||
119 | Dropdown, | ||
120 | DropdownMenu, | ||
121 | DropdownItem, | ||
122 | Menu, | ||
123 | Submenu, | ||
124 | MenuItem, | ||
125 | MenuItemGroup, | ||
126 | Input, | ||
127 | InputNumber, | ||
128 | Radio, | ||
129 | RadioGroup, | ||
130 | RadioButton, | ||
131 | Checkbox, | ||
132 | CheckboxButton, | ||
133 | CheckboxGroup, | ||
134 | Switch, | ||
135 | Select, | ||
136 | Option, | ||
137 | OptionGroup, | ||
138 | Button, | ||
139 | ButtonGroup, | ||
140 | Table, | ||
141 | TableColumn, | ||
142 | DatePicker, | ||
143 | TimeSelect, | ||
144 | TimePicker, | ||
145 | Popover, | ||
146 | Tooltip, | ||
147 | Breadcrumb, | ||
148 | BreadcrumbItem, | ||
149 | Form, | ||
150 | FormItem, | ||
151 | Tabs, | ||
152 | TabPane, | ||
153 | Tag, | ||
154 | Tree, | ||
155 | Alert, | ||
156 | Slider, | ||
157 | Icon, | ||
158 | Row, | ||
159 | Col, | ||
160 | Upload, | ||
161 | Progress, | ||
162 | Spinner, | ||
163 | Badge, | ||
164 | Card, | ||
165 | Rate, | ||
166 | Steps, | ||
167 | Step, | ||
168 | Carousel, | ||
169 | CarouselItem, | ||
170 | Collapse, | ||
171 | CollapseItem, | ||
172 | Cascader, | ||
173 | ColorPicker, | ||
174 | Transfer, | ||
175 | Container, | ||
176 | Header, | ||
177 | Aside, | ||
178 | Main, | ||
179 | Footer, | ||
180 | Timeline, | ||
181 | TimelineItem, | ||
182 | Link, | ||
183 | Divider, | ||
184 | Image, | ||
185 | Calendar, | ||
186 | Backtop, | ||
187 | PageHeader, | ||
188 | CascaderPanel, | ||
189 | Loading, | ||
190 | MessageBox, | ||
191 | Message, | ||
192 | Notification | ||
193 | } from "element-ui"; | ||
194 | // import ElementUI from 'element-ui' | ||
195 | Vue.prototype.$ELEMENT = { size: "small", zIndex: 3000 }; | ||
196 | Vue.use(Pagination); | ||
197 | Vue.use(Dialog); | ||
198 | Vue.use(Autocomplete); | ||
199 | Vue.use(Dropdown); | ||
200 | Vue.use(DropdownMenu); | ||
201 | Vue.use(DropdownItem); | ||
202 | Vue.use(Menu); | ||
203 | Vue.use(Submenu); | ||
204 | Vue.use(MenuItem); | ||
205 | Vue.use(MenuItemGroup); | ||
206 | Vue.use(Input); | ||
207 | Vue.use(InputNumber); | ||
208 | Vue.use(Radio); | ||
209 | Vue.use(RadioGroup); | ||
210 | Vue.use(RadioButton); | ||
211 | Vue.use(Checkbox); | ||
212 | Vue.use(CheckboxButton); | ||
213 | Vue.use(CheckboxGroup); | ||
214 | Vue.use(Switch); | ||
215 | Vue.use(Select); | ||
216 | Vue.use(Option); | ||
217 | Vue.use(OptionGroup); | ||
218 | Vue.use(Button); | ||
219 | Vue.use(ButtonGroup); | ||
220 | Vue.use(Table); | ||
221 | Vue.use(TableColumn); | ||
222 | Vue.use(DatePicker); | ||
223 | Vue.use(TimeSelect); | ||
224 | Vue.use(TimePicker); | ||
225 | Vue.use(Popover); | ||
226 | Vue.use(Tooltip); | ||
227 | Vue.use(Breadcrumb); | ||
228 | Vue.use(BreadcrumbItem); | ||
229 | Vue.use(Form); | ||
230 | Vue.use(FormItem); | ||
231 | Vue.use(Tabs); | ||
232 | Vue.use(TabPane); | ||
233 | Vue.use(Tag); | ||
234 | Vue.use(Tree); | ||
235 | Vue.use(Alert); | ||
236 | Vue.use(Slider); | ||
237 | Vue.use(Icon); | ||
238 | Vue.use(Row); | ||
239 | Vue.use(Col); | ||
240 | Vue.use(Upload); | ||
241 | Vue.use(Progress); | ||
242 | Vue.use(Spinner); | ||
243 | Vue.use(Badge); | ||
244 | Vue.use(Card); | ||
245 | Vue.use(Rate); | ||
246 | Vue.use(Steps); | ||
247 | Vue.use(Step); | ||
248 | Vue.use(Carousel); | ||
249 | Vue.use(CarouselItem); | ||
250 | Vue.use(Collapse); | ||
251 | Vue.use(CollapseItem); | ||
252 | Vue.use(Cascader); | ||
253 | Vue.use(ColorPicker); | ||
254 | Vue.use(Transfer); | ||
255 | Vue.use(Container); | ||
256 | Vue.use(Header); | ||
257 | Vue.use(Aside); | ||
258 | Vue.use(Main); | ||
259 | Vue.use(Footer); | ||
260 | Vue.use(Timeline); | ||
261 | Vue.use(TimelineItem); | ||
262 | Vue.use(Link); | ||
263 | Vue.use(Divider); | ||
264 | Vue.use(Image); | ||
265 | Vue.use(Calendar); | ||
266 | Vue.use(Backtop); | ||
267 | Vue.use(PageHeader); | ||
268 | Vue.use(CascaderPanel); | ||
269 | Vue.use(Loading.directive); | ||
270 | |||
271 | import Schart from "vue-schart"; | ||
272 | import bus from "../../common/bus"; | ||
273 | |||
274 | // 按需引入 引入 ECharts 主模块 | ||
275 | // var echarts = require('echarts/lib/echarts') | ||
276 | // 引入柱状图 | ||
277 | // require('echarts/lib/chart/bar') | ||
278 | // 引入提示框和标题组件 | ||
279 | // require('echarts/lib/component/tooltip') | ||
280 | // require('echarts/lib/component/title') | ||
281 | // 全部引入 | ||
282 | // var echarts = require('echarts') | ||
283 | 11 | ||
284 | export default { | 12 | export default { |
285 | name: "Dashboard", | 13 | name: 'Dashboard', |
14 | components: { adminDashboard, editorDashboard }, | ||
286 | data() { | 15 | data() { |
287 | return { | 16 | return { |
288 | name: localStorage.getItem("ms_username"), | 17 | currentRole: 'adminDashboard' |
289 | todoList: [ | 18 | } |
290 | { | ||
291 | title: "今天要修复100个bug", | ||
292 | status: true | ||
293 | }, | ||
294 | { | ||
295 | title: "今天要写100行代码加几个bug吧", | ||
296 | status: true | ||
297 | } | ||
298 | ], | ||
299 | data: [ | ||
300 | { | ||
301 | name: "2018/09/04", | ||
302 | value: 1083 | ||
303 | }, | ||
304 | { | ||
305 | name: "2018/09/10", | ||
306 | value: 1065 | ||
307 | } | ||
308 | ], | ||
309 | options: { | ||
310 | type: "bar", | ||
311 | title: { | ||
312 | text: "最近一周各品类销售图" | ||
313 | }, | ||
314 | xRorate: 25, | ||
315 | labels: ["周一", "周二", "周三", "周四", "周五"], | ||
316 | datasets: [ | ||
317 | { | ||
318 | label: "百货", | ||
319 | data: [164, 178, 190, 135, 160] | ||
320 | }, | ||
321 | { | ||
322 | label: "食品", | ||
323 | data: [144, 198, 150, 235, 120] | ||
324 | } | ||
325 | ] | ||
326 | }, | ||
327 | options2: { | ||
328 | type: "line", | ||
329 | title: { | ||
330 | text: "最近几个月各品类销售趋势图" | ||
331 | }, | ||
332 | labels: ["6月", "7月", "8月", "9月", "10月"], | ||
333 | datasets: [ | ||
334 | { | ||
335 | label: "百货", | ||
336 | data: [164, 178, 150, 135, 160] | ||
337 | }, | ||
338 | { | ||
339 | label: "食品", | ||
340 | data: [74, 118, 200, 235, 90] | ||
341 | } | ||
342 | ] | ||
343 | } | ||
344 | }; | ||
345 | }, | ||
346 | components: { | ||
347 | Schart | ||
348 | }, | 19 | }, |
349 | computed: { | 20 | computed: { |
350 | // ...mapGetters(["name", "roles"]) | 21 | ...mapGetters([ |
351 | role() { | 22 | 'roles' |
352 | return this.name === "admin" ? "超级管理员" : "普通用户"; | 23 | ]) |
353 | } | ||
354 | }, | 24 | }, |
355 | methods: { | 25 | created() { |
356 | addAction(){ | 26 | if (!this.roles.includes('admin')) { |
357 | this.$prompt("请输入内容", "提示", { | 27 | this.currentRole = 'editorDashboard' |
358 | confirmButtonText: "确定", | ||
359 | cancelButtonText: "取消", | ||
360 | inputErrorMessage: "内容不能为空" | ||
361 | }) | ||
362 | .then(({ value }) => { | ||
363 | this.$message({ | ||
364 | type: "success", | ||
365 | message: "你的邮箱是: " + value | ||
366 | }); | ||
367 | }) | ||
368 | .catch(() => { | ||
369 | this.$message({ | ||
370 | type: "info", | ||
371 | message: "取消输入" | ||
372 | }); | ||
373 | }); | ||
374 | }, | ||
375 | modiAction() { | ||
376 | // this.$prompt("请输入邮箱", "提示", { | ||
377 | // confirmButtonText: "确定", | ||
378 | // cancelButtonText: "取消", | ||
379 | // inputPattern: /[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?/, | ||
380 | // inputErrorMessage: "邮箱格式不正确" | ||
381 | // }) | ||
382 | this.$prompt("请输入内容", "提示", { | ||
383 | confirmButtonText: "确定", | ||
384 | cancelButtonText: "取消", | ||
385 | inputErrorMessage: "内容不能为空" | ||
386 | }) | ||
387 | .then(({ value }) => { | ||
388 | this.$message({ | ||
389 | type: "success", | ||
390 | message: "你的邮箱是: " + value | ||
391 | }); | ||
392 | }) | ||
393 | .catch(() => { | ||
394 | this.$message({ | ||
395 | type: "info", | ||
396 | message: "取消输入" | ||
397 | }); | ||
398 | }); | ||
399 | }, | ||
400 | delAction() { | ||
401 | this.$confirm("此操作将永久删除该文件, 是否继续?", "提示", { | ||
402 | confirmButtonText: "确定", | ||
403 | cancelButtonText: "取消", | ||
404 | type: "warning" | ||
405 | }) | ||
406 | .then(() => { | ||
407 | this.$message({ | ||
408 | type: "success", | ||
409 | message: "删除成功!" | ||
410 | }); | ||
411 | }) | ||
412 | .catch(() => { | ||
413 | this.$message({ | ||
414 | type: "info", | ||
415 | message: "已取消删除" | ||
416 | }); | ||
417 | }); | ||
418 | }, | ||
419 | changeDate() { | ||
420 | const now = new Date().getTime(); | ||
421 | this.data.forEach((item, index) => { | ||
422 | const date = new Date(now - (6 - index) * 86400000); | ||
423 | item.name = `${date.getFullYear()}/${date.getMonth() + | ||
424 | 1}/${date.getDate()}`; | ||
425 | }); | ||
426 | } | 28 | } |
427 | } | 29 | } |
428 | }; | ||
429 | </script> | ||
430 | |||
431 | <style scoped> | ||
432 | .el-row { | ||
433 | margin-bottom: 20px; | ||
434 | } | ||
435 | .grid-content { | ||
436 | display: flex; | ||
437 | align-items: center; | ||
438 | height: 100px; | ||
439 | } | ||
440 | .grid-cont-right { | ||
441 | flex: 1; | ||
442 | text-align: center; | ||
443 | font-size: 14px; | ||
444 | color: #999; | ||
445 | } | ||
446 | .grid-num { | ||
447 | font-size: 30px; | ||
448 | font-weight: bold; | ||
449 | } | ||
450 | .grid-con-icon { | ||
451 | font-size: 50px; | ||
452 | width: 100px; | ||
453 | height: 100px; | ||
454 | text-align: center; | ||
455 | line-height: 100px; | ||
456 | color: #fff; | ||
457 | } | ||
458 | .grid-con-1 .grid-con-icon { | ||
459 | background: rgb(45, 140, 240); | ||
460 | } | ||
461 | .grid-con-1 .grid-num { | ||
462 | color: rgb(45, 140, 240); | ||
463 | } | ||
464 | .grid-con-2 .grid-con-icon { | ||
465 | background: rgb(100, 213, 114); | ||
466 | } | 30 | } |
467 | .grid-con-2 .grid-num { | 31 | </script> |
468 | color: rgb(45, 140, 240); | ||
469 | } | ||
470 | .grid-con-3 .grid-con-icon { | ||
471 | background: rgb(242, 94, 67); | ||
472 | } | ||
473 | .grid-con-3 .grid-num { | ||
474 | color: rgb(242, 94, 67); | ||
475 | } | ||
476 | .user-info { | ||
477 | display: flex; | ||
478 | align-items: center; | ||
479 | padding-bottom: 20px; | ||
480 | border-bottom: 2px solid #ccc; | ||
481 | margin-bottom: 20px; | ||
482 | } | ||
483 | .user-avator { | ||
484 | width: 120px; | ||
485 | height: 120px; | ||
486 | border-radius: 50%; | ||
487 | } | ||
488 | .user-info-cont { | ||
489 | padding-left: 50px; | ||
490 | flex: 1; | ||
491 | font-size: 14px; | ||
492 | color: #999; | ||
493 | } | ||
494 | .user-info-cont div:first-child { | ||
495 | font-size: 30px; | ||
496 | color: #222; | ||
497 | } | ||
498 | .user-info-list { | ||
499 | font-size: 14px; | ||
500 | color: #999; | ||
501 | line-height: 25px; | ||
502 | } | ||
503 | .user-info-list span { | ||
504 | margin-left: 70px; | ||
505 | } | ||
506 | .mgb20 { | ||
507 | margin-bottom: 20px; | ||
508 | } | ||
509 | .todo-item { | ||
510 | font-size: 14px; | ||
511 | } | ||
512 | .todo-item-del { | ||
513 | text-decoration: line-through; | ||
514 | color: #999; | ||
515 | } | ||
516 | .schart { | ||
517 | width: 100%; | ||
518 | height: 300px; | ||
519 | } | ||
520 | </style> |
src/views/documentation/index.vue
File was created | 1 | <template> | |
2 | <div class="app-container documentation-container"> | ||
3 | <a class="document-btn" target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/">Documentation</a> | ||
4 | <a class="document-btn" target="_blank" href="https://github.com/PanJiaChen/vue-element-admin/">Github Repository</a> | ||
5 | <a class="document-btn" target="_blank" href="https://panjiachen.gitee.io/vue-element-admin-site/zh/">国内文档</a> | ||
6 | <dropdown-menu class="document-btn" :items="articleList" title="系列文章" /> | ||
7 | <a class="document-btn" target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/zh/job/">内推招聘</a> | ||
8 | </div> | ||
9 | </template> | ||
10 | |||
11 | <script> | ||
12 | import DropdownMenu from '@/components/Share/DropdownMenu' | ||
13 | |||
14 | export default { | ||
15 | name: 'Documentation', | ||
16 | components: { DropdownMenu }, | ||
17 | data() { | ||
18 | return { | ||
19 | articleList: [ | ||
20 | { title: '基础篇', href: 'https://juejin.im/post/59097cd7a22b9d0065fb61d2' }, | ||
21 | { title: '登录权限篇', href: 'https://juejin.im/post/591aa14f570c35006961acac' }, | ||
22 | { title: '实战篇', href: 'https://juejin.im/post/593121aa0ce4630057f70d35' }, | ||
23 | { title: 'vue-admin-template 篇', href: 'https://juejin.im/post/595b4d776fb9a06bbe7dba56' }, | ||
24 | { title: 'v4.0 篇', href: 'https://juejin.im/post/5c92ff94f265da6128275a85' }, | ||
25 | { title: '自行封装 component', href: 'https://segmentfault.com/a/1190000009090836' }, | ||
26 | { title: '优雅的使用 icon', href: 'https://juejin.im/post/59bb864b5188257e7a427c09' }, | ||
27 | { title: 'webpack4(上)', href: 'https://juejin.im/post/59bb864b5188257e7a427c09' }, | ||
28 | { title: 'webpack4(下)', href: 'https://juejin.im/post/5b5d6d6f6fb9a04fea58aabc' } | ||
29 | ] | ||
30 | } | ||
31 | } | ||
32 | } | ||
33 | </script> | ||
34 | |||
35 | <style lang="scss" scoped> | ||
36 | .documentation-container { | ||
37 | margin: 50px; | ||
38 | display: flex; | ||
39 | flex-wrap: wrap; | ||
40 | justify-content: space-evenly; | ||
41 | |||
42 | .document-btn { | ||
43 | flex-shrink: 0; | ||
44 | display: block; | ||
45 | cursor: pointer; | ||
46 | background: black; | ||
47 | color: white; | ||
48 | height: 60px; | ||
49 | width: 200px; | ||
50 | margin-bottom: 16px; | ||
51 | line-height: 60px; | ||
52 | font-size: 20px; | ||
53 | text-align: center; | ||
54 | } | ||
55 | } | ||
56 | </style> | ||
57 |
src/views/error-log/components/ErrorTestA.vue
File was created | 1 | <template> | |
2 | <div> | ||
3 | <!--error code--> | ||
4 | {{ a.a }} | ||
5 | <!--error code--> | ||
6 | </div> | ||
7 | </template> | ||
8 | |||
9 | <script> | ||
10 | export default { | ||
11 | name: 'ErrorTestA' | ||
12 | } | ||
13 | </script> | ||
14 |
src/views/error-log/components/ErrorTestB.vue
File was created | 1 | <template> | |
2 | <div /> | ||
3 | </template> | ||
4 | |||
5 | <script> | ||
6 | export default { | ||
7 | created() { | ||
8 | this.b = b // eslint-disable-line | ||
9 | } | ||
10 | } | ||
11 | </script> | ||
12 |
src/views/error-log/index.vue
File was created | 1 | <template> | |
2 | <div class="errPage-container"> | ||
3 | <ErrorA /> | ||
4 | <ErrorB /> | ||
5 | <!-- $t is vue-i18n global function to translate lang --> | ||
6 | <h3>{{ $t('errorLog.tips') }}</h3> | ||
7 | <aside> | ||
8 | {{ $t('errorLog.description') }} | ||
9 | <a target="_blank" class="link-type" href="https://panjiachen.github.io/vue-element-admin-site/guide/advanced/error.html"> | ||
10 | {{ $t('errorLog.documentation') }} | ||
11 | </a> | ||
12 | </aside> | ||
13 | <a href="#"> | ||
14 | <img src="https://wpimg.wallstcn.com/360e4842-4db5-42d0-b078-f9a84a825546.gif"> | ||
15 | </a> | ||
16 | </div> | ||
17 | </template> | ||
18 | |||
19 | <script> | ||
20 | import ErrorA from './components/ErrorTestA' | ||
21 | import ErrorB from './components/ErrorTestB' | ||
22 | |||
23 | export default { | ||
24 | name: 'ErrorLog', | ||
25 | components: { ErrorA, ErrorB } | ||
26 | } | ||
27 | </script> | ||
28 | |||
29 | <style scoped> | ||
30 | .errPage-container { | ||
31 | padding: 30px; | ||
32 | } | ||
33 | </style> | ||
34 |
src/views/error-page/401.vue
File was created | 1 | <template> | |
2 | <div class="errPage-container"> | ||
3 | <el-button icon="el-icon-arrow-left" class="pan-back-btn" @click="back"> | ||
4 | 返回 | ||
5 | </el-button> | ||
6 | <el-row> | ||
7 | <el-col :span="12"> | ||
8 | <h1 class="text-jumbo text-ginormous"> | ||
9 | Oops! | ||
10 | </h1> | ||
11 | gif来源<a href="https://zh.airbnb.com/" target="_blank">airbnb</a> 页面 | ||
12 | <h2>你没有权限去该页面</h2> | ||
13 | <h6>如有不满请联系你领导</h6> | ||
14 | <ul class="list-unstyled"> | ||
15 | <li>或者你可以去:</li> | ||
16 | <li class="link-type"> | ||
17 | <router-link to="/dashboard"> | ||
18 | 回首页 | ||
19 | </router-link> | ||
20 | </li> | ||
21 | <li class="link-type"> | ||
22 | <a href="https://www.taobao.com/">随便看看</a> | ||
23 | </li> | ||
24 | <li><a href="#" @click.prevent="dialogVisible=true">点我看图</a></li> | ||
25 | </ul> | ||
26 | </el-col> | ||
27 | <el-col :span="12"> | ||
28 | <img :src="errGif" width="313" height="428" alt="Girl has dropped her ice cream."> | ||
29 | </el-col> | ||
30 | </el-row> | ||
31 | <el-dialog :visible.sync="dialogVisible" title="随便看"> | ||
32 | <img :src="ewizardClap" class="pan-img"> | ||
33 | </el-dialog> | ||
34 | </div> | ||
35 | </template> | ||
36 | |||
37 | <script> | ||
38 | import errGif from '@/assets/401_images/401.gif' | ||
39 | |||
40 | export default { | ||
41 | name: 'Page401', | ||
42 | data() { | ||
43 | return { | ||
44 | errGif: errGif + '?' + +new Date(), | ||
45 | ewizardClap: 'https://wpimg.wallstcn.com/007ef517-bafd-4066-aae4-6883632d9646', | ||
46 | dialogVisible: false | ||
47 | } | ||
48 | }, | ||
49 | methods: { | ||
50 | back() { | ||
51 | if (this.$route.query.noGoBack) { | ||
52 | this.$router.push({ path: '/dashboard' }) | ||
53 | } else { | ||
54 | this.$router.go(-1) | ||
55 | } | ||
56 | } | ||
57 | } | ||
58 | } | ||
59 | </script> | ||
60 | |||
61 | <style lang="scss" scoped> | ||
62 | .errPage-container { | ||
63 | width: 800px; | ||
64 | max-width: 100%; | ||
65 | margin: 100px auto; | ||
66 | .pan-back-btn { | ||
67 | background: #008489; | ||
68 | color: #fff; | ||
69 | border: none!important; | ||
70 | } | ||
71 | .pan-gif { | ||
72 | margin: 0 auto; | ||
73 | display: block; | ||
74 | } | ||
75 | .pan-img { | ||
76 | display: block; | ||
77 | margin: 0 auto; | ||
78 | width: 100%; | ||
79 | } | ||
80 | .text-jumbo { | ||
81 | font-size: 60px; | ||
82 | font-weight: 700; | ||
83 | color: #484848; | ||
84 | } | ||
85 | .list-unstyled { | ||
86 | font-size: 14px; | ||
87 | li { | ||
88 | padding-bottom: 5px; | ||
89 | } | ||
90 | a { | ||
91 | color: #008489; | ||
92 | text-decoration: none; | ||
93 | &:hover { | ||
94 | text-decoration: underline; | ||
95 | } | ||
96 | } | ||
97 | } | ||
98 | } | ||
99 | </style> | ||
100 |
src/views/error-page/404.vue
File was created | 1 | <template> | |
2 | <div class="wscn-http404-container"> | ||
3 | <div class="wscn-http404"> | ||
4 | <div class="pic-404"> | ||
5 | <img class="pic-404__parent" src="@/assets/404_images/404.png" alt="404"> | ||
6 | <img class="pic-404__child left" src="@/assets/404_images/404_cloud.png" alt="404"> | ||
7 | <img class="pic-404__child mid" src="@/assets/404_images/404_cloud.png" alt="404"> | ||
8 | <img class="pic-404__child right" src="@/assets/404_images/404_cloud.png" alt="404"> | ||
9 | </div> | ||
10 | <div class="bullshit"> | ||
11 | <div class="bullshit__oops">OOPS!</div> | ||
12 | <div class="bullshit__info">All rights reserved | ||
13 | <a style="color:#20a0ff" href="https://wallstreetcn.com" target="_blank">wallstreetcn</a> | ||
14 | </div> | ||
15 | <div class="bullshit__headline">{{ message }}</div> | ||
16 | <div class="bullshit__info">Please check that the URL you entered is correct, or click the button below to return to the homepage.</div> | ||
17 | <a href="" class="bullshit__return-home">Back to home</a> | ||
18 | </div> | ||
19 | </div> | ||
20 | </div> | ||
21 | </template> | ||
22 | |||
23 | <script> | ||
24 | |||
25 | export default { | ||
26 | name: 'Page404', | ||
27 | computed: { | ||
28 | message() { | ||
29 | return 'The webmaster said that you can not enter this page...' | ||
30 | } | ||
31 | } | ||
32 | } | ||
33 | </script> | ||
34 | |||
35 | <style lang="scss" scoped> | ||
36 | .wscn-http404-container{ | ||
37 | transform: translate(-50%,-50%); | ||
38 | position: absolute; | ||
39 | top: 40%; | ||
40 | left: 50%; | ||
41 | } | ||
42 | .wscn-http404 { | ||
43 | position: relative; | ||
44 | width: 1200px; | ||
45 | padding: 0 50px; | ||
46 | overflow: hidden; | ||
47 | .pic-404 { | ||
48 | position: relative; | ||
49 | float: left; | ||
50 | width: 600px; | ||
51 | overflow: hidden; | ||
52 | &__parent { | ||
53 | width: 100%; | ||
54 | } | ||
55 | &__child { | ||
56 | position: absolute; | ||
57 | &.left { | ||
58 | width: 80px; | ||
59 | top: 17px; | ||
60 | left: 220px; | ||
61 | opacity: 0; | ||
62 | animation-name: cloudLeft; | ||
63 | animation-duration: 2s; | ||
64 | animation-timing-function: linear; | ||
65 | animation-fill-mode: forwards; | ||
66 | animation-delay: 1s; | ||
67 | } | ||
68 | &.mid { | ||
69 | width: 46px; | ||
70 | top: 10px; | ||
71 | left: 420px; | ||
72 | opacity: 0; | ||
73 | animation-name: cloudMid; | ||
74 | animation-duration: 2s; | ||
75 | animation-timing-function: linear; | ||
76 | animation-fill-mode: forwards; | ||
77 | animation-delay: 1.2s; | ||
78 | } | ||
79 | &.right { | ||
80 | width: 62px; | ||
81 | top: 100px; | ||
82 | left: 500px; | ||
83 | opacity: 0; | ||
84 | animation-name: cloudRight; | ||
85 | animation-duration: 2s; | ||
86 | animation-timing-function: linear; | ||
87 | animation-fill-mode: forwards; | ||
88 | animation-delay: 1s; | ||
89 | } | ||
90 | @keyframes cloudLeft { | ||
91 | 0% { | ||
92 | top: 17px; | ||
93 | left: 220px; | ||
94 | opacity: 0; | ||
95 | } | ||
96 | 20% { | ||
97 | top: 33px; | ||
98 | left: 188px; | ||
99 | opacity: 1; | ||
100 | } | ||
101 | 80% { | ||
102 | top: 81px; | ||
103 | left: 92px; | ||
104 | opacity: 1; | ||
105 | } | ||
106 | 100% { | ||
107 | top: 97px; | ||
108 | left: 60px; | ||
109 | opacity: 0; | ||
110 | } | ||
111 | } | ||
112 | @keyframes cloudMid { | ||
113 | 0% { | ||
114 | top: 10px; | ||
115 | left: 420px; | ||
116 | opacity: 0; | ||
117 | } | ||
118 | 20% { | ||
119 | top: 40px; | ||
120 | left: 360px; | ||
121 | opacity: 1; | ||
122 | } | ||
123 | 70% { | ||
124 | top: 130px; | ||
125 | left: 180px; | ||
126 | opacity: 1; | ||
127 | } | ||
128 | 100% { | ||
129 | top: 160px; | ||
130 | left: 120px; | ||
131 | opacity: 0; | ||
132 | } | ||
133 | } | ||
134 | @keyframes cloudRight { | ||
135 | 0% { | ||
136 | top: 100px; | ||
137 | left: 500px; | ||
138 | opacity: 0; | ||
139 | } | ||
140 | 20% { | ||
141 | top: 120px; | ||
142 | left: 460px; | ||
143 | opacity: 1; | ||
144 | } | ||
145 | 80% { | ||
146 | top: 180px; | ||
147 | left: 340px; | ||
148 | opacity: 1; | ||
149 | } | ||
150 | 100% { | ||
151 | top: 200px; | ||
152 | left: 300px; | ||
153 | opacity: 0; | ||
154 | } | ||
155 | } | ||
156 | } | ||
157 | } | ||
158 | .bullshit { | ||
159 | position: relative; | ||
160 | float: left; | ||
161 | width: 300px; | ||
162 | padding: 30px 0; | ||
163 | overflow: hidden; | ||
164 | &__oops { | ||
165 | font-size: 32px; | ||
166 | font-weight: bold; | ||
167 | line-height: 40px; | ||
168 | color: #1482f0; | ||
169 | opacity: 0; | ||
170 | margin-bottom: 20px; | ||
171 | animation-name: slideUp; | ||
172 | animation-duration: 0.5s; | ||
173 | animation-fill-mode: forwards; | ||
174 | } | ||
175 | &__headline { | ||
176 | font-size: 20px; | ||
177 | line-height: 24px; | ||
178 | color: #222; | ||
179 | font-weight: bold; | ||
180 | opacity: 0; | ||
181 | margin-bottom: 10px; | ||
182 | animation-name: slideUp; | ||
183 | animation-duration: 0.5s; | ||
184 | animation-delay: 0.1s; | ||
185 | animation-fill-mode: forwards; | ||
186 | } | ||
187 | &__info { | ||
188 | font-size: 13px; | ||
189 | line-height: 21px; | ||
190 | color: grey; | ||
191 | opacity: 0; | ||
192 | margin-bottom: 30px; | ||
193 | animation-name: slideUp; | ||
194 | animation-duration: 0.5s; | ||
195 | animation-delay: 0.2s; | ||
196 | animation-fill-mode: forwards; | ||
197 | } | ||
198 | &__return-home { | ||
199 | display: block; | ||
200 | float: left; | ||
201 | width: 110px; | ||
202 | height: 36px; | ||
203 | background: #1482f0; | ||
204 | border-radius: 100px; | ||
205 | text-align: center; | ||
206 | color: #ffffff; | ||
207 | opacity: 0; | ||
208 | font-size: 14px; | ||
209 | line-height: 36px; | ||
210 | cursor: pointer; | ||
211 | animation-name: slideUp; | ||
212 | animation-duration: 0.5s; | ||
213 | animation-delay: 0.3s; | ||
214 | animation-fill-mode: forwards; | ||
215 | } | ||
216 | @keyframes slideUp { | ||
217 | 0% { | ||
218 | transform: translateY(60px); | ||
219 | opacity: 0; | ||
220 | } | ||
221 | 100% { | ||
222 | transform: translateY(0); | ||
223 | opacity: 1; | ||
224 | } | ||
225 | } | ||
226 | } | ||
227 | } | ||
228 | </style> | ||
229 |
src/views/example/components/ArticleDetail.vue
File was created | 1 | <template> | |
2 | <div class="createPost-container"> | ||
3 | <el-form ref="postForm" :model="postForm" :rules="rules" class="form-container"> | ||
4 | <sticky :z-index="10" :class-name="'sub-navbar '+postForm.status"> | ||
5 | <CommentDropdown v-model="postForm.comment_disabled" /> | ||
6 | <PlatformDropdown v-model="postForm.platforms" /> | ||
7 | <SourceUrlDropdown v-model="postForm.source_uri" /> | ||
8 | <el-button v-loading="loading" style="margin-left: 10px;" type="success" @click="submitForm"> | ||
9 | Publish | ||
10 | </el-button> | ||
11 | <el-button v-loading="loading" type="warning" @click="draftForm"> | ||
12 | Draft | ||
13 | </el-button> | ||
14 | </sticky> | ||
15 | |||
16 | <div class="createPost-main-container"> | ||
17 | <el-row> | ||
18 | <Warning /> | ||
19 | |||
20 | <el-col :span="24"> | ||
21 | <el-form-item style="margin-bottom: 40px;" prop="title"> | ||
22 | <MDinput v-model="postForm.title" :maxlength="100" name="name" required> | ||
23 | Title | ||
24 | </MDinput> | ||
25 | </el-form-item> | ||
26 | |||
27 | <div class="postInfo-container"> | ||
28 | <el-row> | ||
29 | <el-col :span="8"> | ||
30 | <el-form-item label-width="60px" label="Author:" class="postInfo-container-item"> | ||
31 | <el-select v-model="postForm.author" :remote-method="getRemoteUserList" filterable default-first-option remote placeholder="Search user"> | ||
32 | <el-option v-for="(item,index) in userListOptions" :key="item+index" :label="item" :value="item" /> | ||
33 | </el-select> | ||
34 | </el-form-item> | ||
35 | </el-col> | ||
36 | |||
37 | <el-col :span="10"> | ||
38 | <el-form-item label-width="120px" label="Publish Time:" class="postInfo-container-item"> | ||
39 | <el-date-picker v-model="displayTime" type="datetime" format="yyyy-MM-dd HH:mm:ss" placeholder="Select date and time" /> | ||
40 | </el-form-item> | ||
41 | </el-col> | ||
42 | |||
43 | <el-col :span="6"> | ||
44 | <el-form-item label-width="90px" label="Importance:" class="postInfo-container-item"> | ||
45 | <el-rate | ||
46 | v-model="postForm.importance" | ||
47 | :max="3" | ||
48 | :colors="['#99A9BF', '#F7BA2A', '#FF9900']" | ||
49 | :low-threshold="1" | ||
50 | :high-threshold="3" | ||
51 | style="display:inline-block" | ||
52 | /> | ||
53 | </el-form-item> | ||
54 | </el-col> | ||
55 | </el-row> | ||
56 | </div> | ||
57 | </el-col> | ||
58 | </el-row> | ||
59 | |||
60 | <el-form-item style="margin-bottom: 40px;" label-width="70px" label="Summary:"> | ||
61 | <el-input v-model="postForm.content_short" :rows="1" type="textarea" class="article-textarea" autosize placeholder="Please enter the content" /> | ||
62 | <span v-show="contentShortLength" class="word-counter">{{ contentShortLength }}words</span> | ||
63 | </el-form-item> | ||
64 | |||
65 | <el-form-item prop="content" style="margin-bottom: 30px;"> | ||
66 | <Tinymce ref="editor" v-model="postForm.content" :height="400" /> | ||
67 | </el-form-item> | ||
68 | |||
69 | <el-form-item prop="image_uri" style="margin-bottom: 30px;"> | ||
70 | <Upload v-model="postForm.image_uri" /> | ||
71 | </el-form-item> | ||
72 | </div> | ||
73 | </el-form> | ||
74 | </div> | ||
75 | </template> | ||
76 | |||
77 | <script> | ||
78 | import Tinymce from '@/components/Tinymce' | ||
79 | import Upload from '@/components/Upload/SingleImage3' | ||
80 | import MDinput from '@/components/MDinput' | ||
81 | import Sticky from '@/components/Sticky' // 粘性header组件 | ||
82 | import { validURL } from '@/utils/validate' | ||
83 | import { fetchArticle } from '@/api/article' | ||
84 | import { searchUser } from '@/api/remote-search' | ||
85 | import Warning from './Warning' | ||
86 | import { CommentDropdown, PlatformDropdown, SourceUrlDropdown } from './Dropdown' | ||
87 | |||
88 | const defaultForm = { | ||
89 | status: 'draft', | ||
90 | title: '', // 文章题目 | ||
91 | content: '', // 文章内容 | ||
92 | content_short: '', // 文章摘要 | ||
93 | source_uri: '', // 文章外链 | ||
94 | image_uri: '', // 文章图片 | ||
95 | display_time: undefined, // 前台展示时间 | ||
96 | id: undefined, | ||
97 | platforms: ['a-platform'], | ||
98 | comment_disabled: false, | ||
99 | importance: 0 | ||
100 | } | ||
101 | |||
102 | export default { | ||
103 | name: 'ArticleDetail', | ||
104 | components: { Tinymce, MDinput, Upload, Sticky, Warning, CommentDropdown, PlatformDropdown, SourceUrlDropdown }, | ||
105 | props: { | ||
106 | isEdit: { | ||
107 | type: Boolean, | ||
108 | default: false | ||
109 | } | ||
110 | }, | ||
111 | data() { | ||
112 | const validateRequire = (rule, value, callback) => { | ||
113 | if (value === '') { | ||
114 | this.$message({ | ||
115 | message: rule.field + '为必传项', | ||
116 | type: 'error' | ||
117 | }) | ||
118 | callback(new Error(rule.field + '为必传项')) | ||
119 | } else { | ||
120 | callback() | ||
121 | } | ||
122 | } | ||
123 | const validateSourceUri = (rule, value, callback) => { | ||
124 | if (value) { | ||
125 | if (validURL(value)) { | ||
126 | callback() | ||
127 | } else { | ||
128 | this.$message({ | ||
129 | message: '外链url填写不正确', | ||
130 | type: 'error' | ||
131 | }) | ||
132 | callback(new Error('外链url填写不正确')) | ||
133 | } | ||
134 | } else { | ||
135 | callback() | ||
136 | } | ||
137 | } | ||
138 | return { | ||
139 | postForm: Object.assign({}, defaultForm), | ||
140 | loading: false, | ||
141 | userListOptions: [], | ||
142 | rules: { | ||
143 | image_uri: [{ validator: validateRequire }], | ||
144 | title: [{ validator: validateRequire }], | ||
145 | content: [{ validator: validateRequire }], | ||
146 | source_uri: [{ validator: validateSourceUri, trigger: 'blur' }] | ||
147 | }, | ||
148 | tempRoute: {} | ||
149 | } | ||
150 | }, | ||
151 | computed: { | ||
152 | contentShortLength() { | ||
153 | return this.postForm.content_short.length | ||
154 | }, | ||
155 | lang() { | ||
156 | return this.$store.getters.language | ||
157 | }, | ||
158 | displayTime: { | ||
159 | // set and get is useful when the data | ||
160 | // returned by the back end api is different from the front end | ||
161 | // back end return => "2013-06-25 06:59:25" | ||
162 | // front end need timestamp => 1372114765000 | ||
163 | get() { | ||
164 | return (+new Date(this.postForm.display_time)) | ||
165 | }, | ||
166 | set(val) { | ||
167 | this.postForm.display_time = new Date(val) | ||
168 | } | ||
169 | } | ||
170 | }, | ||
171 | created() { | ||
172 | if (this.isEdit) { | ||
173 | const id = this.$route.params && this.$route.params.id | ||
174 | this.fetchData(id) | ||
175 | } | ||
176 | |||
177 | // Why need to make a copy of this.$route here? | ||
178 | // Because if you enter this page and quickly switch tag, may be in the execution of the setTagsViewTitle function, this.$route is no longer pointing to the current page | ||
179 | // https://github.com/PanJiaChen/vue-element-admin/issues/1221 | ||
180 | this.tempRoute = Object.assign({}, this.$route) | ||
181 | }, | ||
182 | methods: { | ||
183 | fetchData(id) { | ||
184 | fetchArticle(id).then(response => { | ||
185 | this.postForm = response.data | ||
186 | |||
187 | // just for test | ||
188 | this.postForm.title += ` Article Id:${this.postForm.id}` | ||
189 | this.postForm.content_short += ` Article Id:${this.postForm.id}` | ||
190 | |||
191 | // set tagsview title | ||
192 | this.setTagsViewTitle() | ||
193 | |||
194 | // set page title | ||
195 | this.setPageTitle() | ||
196 | }).catch(err => { | ||
197 | console.log(err) | ||
198 | }) | ||
199 | }, | ||
200 | setTagsViewTitle() { | ||
201 | const title = this.lang === 'zh' ? '编辑文章' : 'Edit Article' | ||
202 | const route = Object.assign({}, this.tempRoute, { title: `${title}-${this.postForm.id}` }) | ||
203 | this.$store.dispatch('tagsView/updateVisitedView', route) | ||
204 | }, | ||
205 | setPageTitle() { | ||
206 | const title = 'Edit Article' | ||
207 | document.title = `${title} - ${this.postForm.id}` | ||
208 | }, | ||
209 | submitForm() { | ||
210 | console.log(this.postForm) | ||
211 | this.$refs.postForm.validate(valid => { | ||
212 | if (valid) { | ||
213 | this.loading = true | ||
214 | this.$notify({ | ||
215 | title: '成功', | ||
216 | message: '发布文章成功', | ||
217 | type: 'success', | ||
218 | duration: 2000 | ||
219 | }) | ||
220 | this.postForm.status = 'published' | ||
221 | this.loading = false | ||
222 | } else { | ||
223 | console.log('error submit!!') | ||
224 | return false | ||
225 | } | ||
226 | }) | ||
227 | }, | ||
228 | draftForm() { | ||
229 | if (this.postForm.content.length === 0 || this.postForm.title.length === 0) { | ||
230 | this.$message({ | ||
231 | message: '请填写必要的标题和内容', | ||
232 | type: 'warning' | ||
233 | }) | ||
234 | return | ||
235 | } | ||
236 | this.$message({ | ||
237 | message: '保存成功', | ||
238 | type: 'success', | ||
239 | showClose: true, | ||
240 | duration: 1000 | ||
241 | }) | ||
242 | this.postForm.status = 'draft' | ||
243 | }, | ||
244 | getRemoteUserList(query) { | ||
245 | searchUser(query).then(response => { | ||
246 | if (!response.data.items) return | ||
247 | this.userListOptions = response.data.items.map(v => v.name) | ||
248 | }) | ||
249 | } | ||
250 | } | ||
251 | } | ||
252 | </script> | ||
253 | |||
254 | <style lang="scss" scoped> | ||
255 | @import "~@/styles/mixin.scss"; | ||
256 | |||
257 | .createPost-container { | ||
258 | position: relative; | ||
259 | |||
260 | .createPost-main-container { | ||
261 | padding: 40px 45px 20px 50px; | ||
262 | |||
263 | .postInfo-container { | ||
264 | position: relative; | ||
265 | @include clearfix; | ||
266 | margin-bottom: 10px; | ||
267 | |||
268 | .postInfo-container-item { | ||
269 | float: left; | ||
270 | } | ||
271 | } | ||
272 | } | ||
273 | |||
274 | .word-counter { | ||
275 | width: 40px; | ||
276 | position: absolute; | ||
277 | right: 10px; | ||
278 | top: 0px; | ||
279 | } | ||
280 | } | ||
281 | |||
282 | .article-textarea /deep/ { | ||
283 | textarea { | ||
284 | padding-right: 40px; | ||
285 | resize: none; | ||
286 | border: none; | ||
287 | border-radius: 0px; | ||
288 | border-bottom: 1px solid #bfcbd9; | ||
289 | } | ||
290 | } | ||
291 | </style> | ||
292 |
src/views/example/components/Dropdown/Comment.vue
File was created | 1 | <template> | |
2 | <el-dropdown :show-timeout="100" trigger="click"> | ||
3 | <el-button plain> | ||
4 | {{ !comment_disabled?'Comment: opened':'Comment: closed' }} | ||
5 | <i class="el-icon-caret-bottom el-icon--right" /> | ||
6 | </el-button> | ||
7 | <el-dropdown-menu slot="dropdown" class="no-padding"> | ||
8 | <el-dropdown-item> | ||
9 | <el-radio-group v-model="comment_disabled" style="padding: 10px;"> | ||
10 | <el-radio :label="true"> | ||
11 | Close comment | ||
12 | </el-radio> | ||
13 | <el-radio :label="false"> | ||
14 | Open comment | ||
15 | </el-radio> | ||
16 | </el-radio-group> | ||
17 | </el-dropdown-item> | ||
18 | </el-dropdown-menu> | ||
19 | </el-dropdown> | ||
20 | </template> | ||
21 | |||
22 | <script> | ||
23 | export default { | ||
24 | props: { | ||
25 | value: { | ||
26 | type: Boolean, | ||
27 | default: false | ||
28 | } | ||
29 | }, | ||
30 | computed: { | ||
31 | comment_disabled: { | ||
32 | get() { | ||
33 | return this.value | ||
34 | }, | ||
35 | set(val) { | ||
36 | this.$emit('input', val) | ||
37 | } | ||
38 | } | ||
39 | } | ||
40 | } | ||
41 | </script> | ||
42 |
src/views/example/components/Dropdown/Platform.vue
File was created | 1 | <template> | |
2 | <el-dropdown :hide-on-click="false" :show-timeout="100" trigger="click"> | ||
3 | <el-button plain> | ||
4 | Platfroms({{ platforms.length }}) | ||
5 | <i class="el-icon-caret-bottom el-icon--right" /> | ||
6 | </el-button> | ||
7 | <el-dropdown-menu slot="dropdown" class="no-border"> | ||
8 | <el-checkbox-group v-model="platforms" style="padding: 5px 15px;"> | ||
9 | <el-checkbox v-for="item in platformsOptions" :key="item.key" :label="item.key"> | ||
10 | {{ item.name }} | ||
11 | </el-checkbox> | ||
12 | </el-checkbox-group> | ||
13 | </el-dropdown-menu> | ||
14 | </el-dropdown> | ||
15 | </template> | ||
16 | |||
17 | <script> | ||
18 | export default { | ||
19 | props: { | ||
20 | value: { | ||
21 | required: true, | ||
22 | default: () => [], | ||
23 | type: Array | ||
24 | } | ||
25 | }, | ||
26 | data() { | ||
27 | return { | ||
28 | platformsOptions: [ | ||
29 | { key: 'a-platform', name: 'a-platform' }, | ||
30 | { key: 'b-platform', name: 'b-platform' }, | ||
31 | { key: 'c-platform', name: 'c-platform' } | ||
32 | ] | ||
33 | } | ||
34 | }, | ||
35 | computed: { | ||
36 | platforms: { | ||
37 | get() { | ||
38 | return this.value | ||
39 | }, | ||
40 | set(val) { | ||
41 | this.$emit('input', val) | ||
42 | } | ||
43 | } | ||
44 | } | ||
45 | } | ||
46 | </script> | ||
47 |
src/views/example/components/Dropdown/SourceUrl.vue
File was created | 1 | <template> | |
2 | <el-dropdown :show-timeout="100" trigger="click"> | ||
3 | <el-button plain> | ||
4 | Link | ||
5 | <i class="el-icon-caret-bottom el-icon--right" /> | ||
6 | </el-button> | ||
7 | <el-dropdown-menu slot="dropdown" class="no-padding no-border" style="width:400px"> | ||
8 | <el-form-item label-width="0px" style="margin-bottom: 0px" prop="source_uri"> | ||
9 | <el-input v-model="source_uri" placeholder="Please enter the content"> | ||
10 | <template slot="prepend"> | ||
11 | URL | ||
12 | </template> | ||
13 | </el-input> | ||
14 | </el-form-item> | ||
15 | </el-dropdown-menu> | ||
16 | </el-dropdown> | ||
17 | </template> | ||
18 | |||
19 | <script> | ||
20 | export default { | ||
21 | props: { | ||
22 | value: { | ||
23 | type: String, | ||
24 | default: '' | ||
25 | } | ||
26 | }, | ||
27 | computed: { | ||
28 | source_uri: { | ||
29 | get() { | ||
30 | return this.value | ||
31 | }, | ||
32 | set(val) { | ||
33 | this.$emit('input', val) | ||
34 | } | ||
35 | } | ||
36 | } | ||
37 | } | ||
38 | </script> | ||
39 |
src/views/example/components/Dropdown/index.js
File was created | 1 | export { default as CommentDropdown } from './Comment' | |
2 | export { default as PlatformDropdown } from './Platform' | ||
3 | export { default as SourceUrlDropdown } from './SourceUrl' | ||
4 |
src/views/example/components/Warning.vue
File was created | 1 | <template> | |
2 | <aside> | ||
3 | {{ $t('example.warning') }} | ||
4 | <a | ||
5 | href="https://panjiachen.github.io/vue-element-admin-site/guide/essentials/tags-view.html" | ||
6 | target="_blank" | ||
7 | >Document</a> | ||
8 | </aside> | ||
9 | </template> | ||
10 | |||
11 |
src/views/example/create.vue
File was created | 1 | <template> | |
2 | <article-detail :is-edit="false" /> | ||
3 | </template> | ||
4 | |||
5 | <script> | ||
6 | import ArticleDetail from './components/ArticleDetail' | ||
7 | |||
8 | export default { | ||
9 | name: 'CreateArticle', | ||
10 | components: { ArticleDetail } | ||
11 | } | ||
12 | </script> | ||
13 | |||
14 |
src/views/example/edit.vue
File was created | 1 | <template> | |
2 | <article-detail :is-edit="true" /> | ||
3 | </template> | ||
4 | |||
5 | <script> | ||
6 | import ArticleDetail from './components/ArticleDetail' | ||
7 | |||
8 | export default { | ||
9 | name: 'EditForm', | ||
10 | components: { ArticleDetail } | ||
11 | } | ||
12 | </script> | ||
13 | |||
14 |
src/views/example/list.vue
File was created | 1 | <template> | |
2 | <div class="app-container"> | ||
3 | <el-table v-loading="listLoading" :data="list" border fit highlight-current-row style="width: 100%"> | ||
4 | <el-table-column align="center" label="ID" width="80"> | ||
5 | <template slot-scope="scope"> | ||
6 | <span>{{ scope.row.id }}</span> | ||
7 | </template> | ||
8 | </el-table-column> | ||
9 | |||
10 | <el-table-column width="180px" align="center" label="Date"> | ||
11 | <template slot-scope="scope"> | ||
12 | <span>{{ scope.row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span> | ||
13 | </template> | ||
14 | </el-table-column> | ||
15 | |||
16 | <el-table-column width="120px" align="center" label="Author"> | ||
17 | <template slot-scope="scope"> | ||
18 | <span>{{ scope.row.author }}</span> | ||
19 | </template> | ||
20 | </el-table-column> | ||
21 | |||
22 | <el-table-column width="100px" label="Importance"> | ||
23 | <template slot-scope="scope"> | ||
24 | <svg-icon v-for="n in +scope.row.importance" :key="n" icon-class="star" class="meta-item__icon" /> | ||
25 | </template> | ||
26 | </el-table-column> | ||
27 | |||
28 | <el-table-column class-name="status-col" label="Status" width="110"> | ||
29 | <template slot-scope="{row}"> | ||
30 | <el-tag :type="row.status | statusFilter"> | ||
31 | {{ row.status }} | ||
32 | </el-tag> | ||
33 | </template> | ||
34 | </el-table-column> | ||
35 | |||
36 | <el-table-column min-width="300px" label="Title"> | ||
37 | <template slot-scope="{row}"> | ||
38 | <router-link :to="'/example/edit/'+row.id" class="link-type"> | ||
39 | <span>{{ row.title }}</span> | ||
40 | </router-link> | ||
41 | </template> | ||
42 | </el-table-column> | ||
43 | |||
44 | <el-table-column align="center" label="Actions" width="120"> | ||
45 | <template slot-scope="scope"> | ||
46 | <router-link :to="'/example/edit/'+scope.row.id"> | ||
47 | <el-button type="primary" size="small" icon="el-icon-edit"> | ||
48 | Edit | ||
49 | </el-button> | ||
50 | </router-link> | ||
51 | </template> | ||
52 | </el-table-column> | ||
53 | </el-table> | ||
54 | |||
55 | <pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getList" /> | ||
56 | </div> | ||
57 | </template> | ||
58 | |||
59 | <script> | ||
60 | import { fetchList } from '@/api/article' | ||
61 | import Pagination from '@/components/Pagination' // Secondary package based on el-pagination | ||
62 | |||
63 | export default { | ||
64 | name: 'ArticleList', | ||
65 | components: { Pagination }, | ||
66 | filters: { | ||
67 | statusFilter(status) { | ||
68 | const statusMap = { | ||
69 | published: 'success', | ||
70 | draft: 'info', | ||
71 | deleted: 'danger' | ||
72 | } | ||
73 | return statusMap[status] | ||
74 | } | ||
75 | }, | ||
76 | data() { | ||
77 | return { | ||
78 | list: null, | ||
79 | total: 0, | ||
80 | listLoading: true, | ||
81 | listQuery: { | ||
82 | page: 1, | ||
83 | limit: 20 | ||
84 | } | ||
85 | } | ||
86 | }, | ||
87 | created() { | ||
88 | this.getList() | ||
89 | }, | ||
90 | methods: { | ||
91 | getList() { | ||
92 | this.listLoading = true | ||
93 | fetchList(this.listQuery).then(response => { | ||
94 | this.list = response.data.items | ||
95 | this.total = response.data.total | ||
96 | this.listLoading = false | ||
97 | }) | ||
98 | } | ||
99 | } | ||
100 | } | ||
101 | </script> | ||
102 | |||
103 | <style scoped> | ||
104 | .edit-input { | ||
105 | padding-right: 100px; | ||
106 | } | ||
107 | .cancel-btn { | ||
108 | position: absolute; | ||
109 | right: 15px; | ||
110 | top: 10px; | ||
111 | } | ||
112 | </style> | ||
113 |
src/views/excel/components/AutoWidthOption.vue
File was created | 1 | <template> | |
2 | <div style="display:inline-block;"> | ||
3 | <label class="radio-label">Cell Auto-Width: </label> | ||
4 | <el-radio-group v-model="autoWidth"> | ||
5 | <el-radio :label="true" border> | ||
6 | True | ||
7 | </el-radio> | ||
8 | <el-radio :label="false" border> | ||
9 | False | ||
10 | </el-radio> | ||
11 | </el-radio-group> | ||
12 | </div> | ||
13 | </template> | ||
14 | |||
15 | <script> | ||
16 | export default { | ||
17 | props: { | ||
18 | value: { | ||
19 | type: Boolean, | ||
20 | default: true | ||
21 | } | ||
22 | }, | ||
23 | computed: { | ||
24 | autoWidth: { | ||
25 | get() { | ||
26 | return this.value | ||
27 | }, | ||
28 | set(val) { | ||
29 | this.$emit('input', val) | ||
30 | } | ||
31 | } | ||
32 | } | ||
33 | } | ||
34 | </script> | ||
35 |
src/views/excel/components/BookTypeOption.vue
File was created | 1 | <template> | |
2 | <div style="display:inline-block;"> | ||
3 | <label class="radio-label">Book Type: </label> | ||
4 | <el-select v-model="bookType" style="width:120px;"> | ||
5 | <el-option | ||
6 | v-for="item in options" | ||
7 | :key="item" | ||
8 | :label="item" | ||
9 | :value="item" | ||
10 | /> | ||
11 | </el-select> | ||
12 | </div> | ||
13 | </template> | ||
14 | |||
15 | <script> | ||
16 | export default { | ||
17 | props: { | ||
18 | value: { | ||
19 | type: String, | ||
20 | default: 'xlsx' | ||
21 | } | ||
22 | }, | ||
23 | data() { | ||
24 | return { | ||
25 | options: ['xlsx', 'csv', 'txt'] | ||
26 | } | ||
27 | }, | ||
28 | computed: { | ||
29 | bookType: { | ||
30 | get() { | ||
31 | return this.value | ||
32 | }, | ||
33 | set(val) { | ||
34 | this.$emit('input', val) | ||
35 | } | ||
36 | } | ||
37 | } | ||
38 | } | ||
39 | </script> | ||
40 |
src/views/excel/components/FilenameOption.vue
File was created | 1 | <template> | |
2 | <div style="display:inline-block;"> | ||
3 | <!-- $t is vue-i18n global function to translate lang --> | ||
4 | <label class="radio-label" style="padding-left:0;">Filename: </label> | ||
5 | <el-input v-model="filename" :placeholder="$t('excel.placeholder')" style="width:350px;" prefix-icon="el-icon-document" /> | ||
6 | </div> | ||
7 | </template> | ||
8 | |||
9 | <script> | ||
10 | export default { | ||
11 | props: { | ||
12 | value: { | ||
13 | type: String, | ||
14 | default: '' | ||
15 | } | ||
16 | }, | ||
17 | computed: { | ||
18 | filename: { | ||
19 | get() { | ||
20 | return this.value | ||
21 | }, | ||
22 | set(val) { | ||
23 | this.$emit('input', val) | ||
24 | } | ||
25 | } | ||
26 | } | ||
27 | } | ||
28 | </script> | ||
29 |
src/views/excel/export-excel.vue
File was created | 1 | <template> | |
2 | <!-- $t is vue-i18n global function to translate lang --> | ||
3 | <div class="app-container"> | ||
4 | <div> | ||
5 | <FilenameOption v-model="filename" /> | ||
6 | <AutoWidthOption v-model="autoWidth" /> | ||
7 | <BookTypeOption v-model="bookType" /> | ||
8 | <el-button :loading="downloadLoading" style="margin:0 0 20px 20px;" type="primary" icon="el-icon-document" @click="handleDownload"> | ||
9 | {{ $t('excel.export') }} Excel | ||
10 | </el-button> | ||
11 | <a href="https://panjiachen.github.io/vue-element-admin-site/feature/component/excel.html" target="_blank" style="margin-left:15px;"> | ||
12 | <el-tag type="info">Documentation</el-tag> | ||
13 | </a> | ||
14 | </div> | ||
15 | |||
16 | <el-table v-loading="listLoading" :data="list" element-loading-text="Loading..." border fit highlight-current-row> | ||
17 | <el-table-column align="center" label="Id" width="95"> | ||
18 | <template slot-scope="scope"> | ||
19 | {{ scope.$index }} | ||
20 | </template> | ||
21 | </el-table-column> | ||
22 | <el-table-column label="Title"> | ||
23 | <template slot-scope="scope"> | ||
24 | {{ scope.row.title }} | ||
25 | </template> | ||
26 | </el-table-column> | ||
27 | <el-table-column label="Author" width="110" align="center"> | ||
28 | <template slot-scope="scope"> | ||
29 | <el-tag>{{ scope.row.author }}</el-tag> | ||
30 | </template> | ||
31 | </el-table-column> | ||
32 | <el-table-column label="Readings" width="115" align="center"> | ||
33 | <template slot-scope="scope"> | ||
34 | {{ scope.row.pageviews }} | ||
35 | </template> | ||
36 | </el-table-column> | ||
37 | <el-table-column align="center" label="Date" width="220"> | ||
38 | <template slot-scope="scope"> | ||
39 | <i class="el-icon-time" /> | ||
40 | <span>{{ scope.row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span> | ||
41 | </template> | ||
42 | </el-table-column> | ||
43 | </el-table> | ||
44 | </div> | ||
45 | </template> | ||
46 | |||
47 | <script> | ||
48 | import { fetchList } from '@/api/article' | ||
49 | import { parseTime } from '@/utils' | ||
50 | // options components | ||
51 | import FilenameOption from './components/FilenameOption' | ||
52 | import AutoWidthOption from './components/AutoWidthOption' | ||
53 | import BookTypeOption from './components/BookTypeOption' | ||
54 | export default { | ||
55 | name: 'ExportExcel', | ||
56 | components: { FilenameOption, AutoWidthOption, BookTypeOption }, | ||
57 | data() { | ||
58 | return { | ||
59 | list: null, | ||
60 | listLoading: true, | ||
61 | downloadLoading: false, | ||
62 | filename: '', | ||
63 | autoWidth: true, | ||
64 | bookType: 'xlsx' | ||
65 | } | ||
66 | }, | ||
67 | created() { | ||
68 | this.fetchData() | ||
69 | }, | ||
70 | methods: { | ||
71 | fetchData() { | ||
72 | this.listLoading = true | ||
73 | fetchList().then(response => { | ||
74 | this.list = response.data.items | ||
75 | this.listLoading = false | ||
76 | }) | ||
77 | }, | ||
78 | handleDownload() { | ||
79 | this.downloadLoading = true | ||
80 | import('@/vendor/Export2Excel').then(excel => { | ||
81 | const tHeader = ['Id', 'Title', 'Author', 'Readings', 'Date'] | ||
82 | const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time'] | ||
83 | const list = this.list | ||
84 | const data = this.formatJson(filterVal, list) | ||
85 | excel.export_json_to_excel({ | ||
86 | header: tHeader, | ||
87 | data, | ||
88 | filename: this.filename, | ||
89 | autoWidth: this.autoWidth, | ||
90 | bookType: this.bookType | ||
91 | }) | ||
92 | this.downloadLoading = false | ||
93 | }) | ||
94 | }, | ||
95 | formatJson(filterVal, jsonData) { | ||
96 | return jsonData.map(v => filterVal.map(j => { | ||
97 | if (j === 'timestamp') { | ||
98 | return parseTime(v[j]) | ||
99 | } else { | ||
100 | return v[j] | ||
101 | } | ||
102 | })) | ||
103 | } | ||
104 | } | ||
105 | } | ||
106 | </script> | ||
107 | |||
108 | <style> | ||
109 | .radio-label { | ||
110 | font-size: 14px; | ||
111 | color: #606266; | ||
112 | line-height: 40px; | ||
113 | padding: 0 12px 0 30px; | ||
114 | } | ||
115 | </style> | ||
116 |
src/views/excel/merge-header.vue
File was created | 1 | <template> | |
2 | <div class="app-container"> | ||
3 | |||
4 | <el-button :loading="downloadLoading" style="margin-bottom:20px" type="primary" icon="el-icon-document" @click="handleDownload">Export</el-button> | ||
5 | |||
6 | <el-table | ||
7 | ref="multipleTable" | ||
8 | v-loading="listLoading" | ||
9 | :data="list" | ||
10 | element-loading-text="Loading" | ||
11 | border | ||
12 | fit | ||
13 | highlight-current-row | ||
14 | > | ||
15 | <el-table-column align="center" label="Id" width="95"> | ||
16 | <template slot-scope="scope"> | ||
17 | {{ scope.$index }} | ||
18 | </template> | ||
19 | </el-table-column> | ||
20 | <el-table-column label="Main Information" align="center"> | ||
21 | <el-table-column label="Title"> | ||
22 | <template slot-scope="scope"> | ||
23 | {{ scope.row.title }} | ||
24 | </template> | ||
25 | </el-table-column> | ||
26 | <el-table-column label="Author" width="110" align="center"> | ||
27 | <template slot-scope="scope"> | ||
28 | <el-tag>{{ scope.row.author }}</el-tag> | ||
29 | </template> | ||
30 | </el-table-column> | ||
31 | <el-table-column label="Readings" width="115" align="center"> | ||
32 | <template slot-scope="scope"> | ||
33 | {{ scope.row.pageviews }} | ||
34 | </template> | ||
35 | </el-table-column> | ||
36 | </el-table-column> | ||
37 | <el-table-column align="center" label="Date" width="220"> | ||
38 | <template slot-scope="scope"> | ||
39 | <i class="el-icon-time" /> | ||
40 | <span>{{ scope.row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span> | ||
41 | </template> | ||
42 | </el-table-column> | ||
43 | </el-table> | ||
44 | |||
45 | </div> | ||
46 | </template> | ||
47 | |||
48 | <script> | ||
49 | import { fetchList } from '@/api/article' | ||
50 | import { parseTime } from '@/utils' | ||
51 | |||
52 | export default { | ||
53 | name: 'MergeHeader', | ||
54 | data() { | ||
55 | return { | ||
56 | list: null, | ||
57 | listLoading: true, | ||
58 | downloadLoading: false | ||
59 | } | ||
60 | }, | ||
61 | created() { | ||
62 | this.fetchData() | ||
63 | }, | ||
64 | methods: { | ||
65 | fetchData() { | ||
66 | this.listLoading = true | ||
67 | fetchList(this.listQuery).then(response => { | ||
68 | this.list = response.data.items | ||
69 | this.listLoading = false | ||
70 | }) | ||
71 | }, | ||
72 | handleDownload() { | ||
73 | this.downloadLoading = true | ||
74 | import('@/vendor/Export2Excel').then(excel => { | ||
75 | const multiHeader = [['Id', 'Main Information', '', '', 'Date']] | ||
76 | const header = ['', 'Title', 'Author', 'Readings', ''] | ||
77 | const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time'] | ||
78 | const list = this.list | ||
79 | const data = this.formatJson(filterVal, list) | ||
80 | const merges = ['A1:A2', 'B1:D1', 'E1:E2'] | ||
81 | excel.export_json_to_excel({ | ||
82 | multiHeader, | ||
83 | header, | ||
84 | merges, | ||
85 | data | ||
86 | }) | ||
87 | this.downloadLoading = false | ||
88 | }) | ||
89 | }, | ||
90 | formatJson(filterVal, jsonData) { | ||
91 | return jsonData.map(v => filterVal.map(j => { | ||
92 | if (j === 'timestamp') { | ||
93 | return parseTime(v[j]) | ||
94 | } else { | ||
95 | return v[j] | ||
96 | } | ||
97 | })) | ||
98 | } | ||
99 | } | ||
100 | } | ||
101 | </script> | ||
102 |
src/views/excel/select-excel.vue
File was created | 1 | <template> | |
2 | <div class="app-container"> | ||
3 | <!-- $t is vue-i18n global function to translate lang --> | ||
4 | <el-input v-model="filename" :placeholder="$t('excel.placeholder')" style="width:350px;" prefix-icon="el-icon-document" /> | ||
5 | <el-button :loading="downloadLoading" style="margin-bottom:20px" type="primary" icon="el-icon-document" @click="handleDownload"> | ||
6 | {{ $t('excel.selectedExport') }} | ||
7 | </el-button> | ||
8 | <a href="https://panjiachen.github.io/vue-element-admin-site/feature/component/excel.html" target="_blank" style="margin-left:15px;"> | ||
9 | <el-tag type="info">Documentation</el-tag> | ||
10 | </a> | ||
11 | <el-table | ||
12 | ref="multipleTable" | ||
13 | v-loading="listLoading" | ||
14 | :data="list" | ||
15 | element-loading-text="拼命加载中" | ||
16 | border | ||
17 | fit | ||
18 | highlight-current-row | ||
19 | @selection-change="handleSelectionChange" | ||
20 | > | ||
21 | <el-table-column type="selection" align="center" /> | ||
22 | <el-table-column align="center" label="Id" width="95"> | ||
23 | <template slot-scope="scope"> | ||
24 | {{ scope.$index }} | ||
25 | </template> | ||
26 | </el-table-column> | ||
27 | <el-table-column label="Title"> | ||
28 | <template slot-scope="scope"> | ||
29 | {{ scope.row.title }} | ||
30 | </template> | ||
31 | </el-table-column> | ||
32 | <el-table-column label="Author" width="110" align="center"> | ||
33 | <template slot-scope="scope"> | ||
34 | <el-tag>{{ scope.row.author }}</el-tag> | ||
35 | </template> | ||
36 | </el-table-column> | ||
37 | <el-table-column label="Readings" width="115" align="center"> | ||
38 | <template slot-scope="scope"> | ||
39 | {{ scope.row.pageviews }} | ||
40 | </template> | ||
41 | </el-table-column> | ||
42 | <el-table-column align="center" label="PDate" width="220"> | ||
43 | <template slot-scope="scope"> | ||
44 | <i class="el-icon-time" /> | ||
45 | <span>{{ scope.row.display_time }}</span> | ||
46 | </template> | ||
47 | </el-table-column> | ||
48 | </el-table> | ||
49 | </div> | ||
50 | </template> | ||
51 | |||
52 | <script> | ||
53 | import { fetchList } from '@/api/article' | ||
54 | |||
55 | export default { | ||
56 | name: 'SelectExcel', | ||
57 | data() { | ||
58 | return { | ||
59 | list: null, | ||
60 | listLoading: true, | ||
61 | multipleSelection: [], | ||
62 | downloadLoading: false, | ||
63 | filename: '' | ||
64 | } | ||
65 | }, | ||
66 | created() { | ||
67 | this.fetchData() | ||
68 | }, | ||
69 | methods: { | ||
70 | fetchData() { | ||
71 | this.listLoading = true | ||
72 | fetchList(this.listQuery).then(response => { | ||
73 | this.list = response.data.items | ||
74 | this.listLoading = false | ||
75 | }) | ||
76 | }, | ||
77 | handleSelectionChange(val) { | ||
78 | this.multipleSelection = val | ||
79 | }, | ||
80 | handleDownload() { | ||
81 | if (this.multipleSelection.length) { | ||
82 | this.downloadLoading = true | ||
83 | import('@/vendor/Export2Excel').then(excel => { | ||
84 | const tHeader = ['Id', 'Title', 'Author', 'Readings', 'Date'] | ||
85 | const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time'] | ||
86 | const list = this.multipleSelection | ||
87 | const data = this.formatJson(filterVal, list) | ||
88 | excel.export_json_to_excel({ | ||
89 | header: tHeader, | ||
90 | data, | ||
91 | filename: this.filename | ||
92 | }) | ||
93 | this.$refs.multipleTable.clearSelection() | ||
94 | this.downloadLoading = false | ||
95 | }) | ||
96 | } else { | ||
97 | this.$message({ | ||
98 | message: 'Please select at least one item', | ||
99 | type: 'warning' | ||
100 | }) | ||
101 | } | ||
102 | }, | ||
103 | formatJson(filterVal, jsonData) { | ||
104 | return jsonData.map(v => filterVal.map(j => v[j])) | ||
105 | } | ||
106 | } | ||
107 | } | ||
108 | </script> | ||
109 |
src/views/excel/upload-excel.vue
File was created | 1 | <template> | |
2 | <div class="app-container"> | ||
3 | <upload-excel-component :on-success="handleSuccess" :before-upload="beforeUpload" /> | ||
4 | <el-table :data="tableData" border highlight-current-row style="width: 100%;margin-top:20px;"> | ||
5 | <el-table-column v-for="item of tableHeader" :key="item" :prop="item" :label="item" /> | ||
6 | </el-table> | ||
7 | </div> | ||
8 | </template> | ||
9 | |||
10 | <script> | ||
11 | import UploadExcelComponent from '@/components/UploadExcel/index.vue' | ||
12 | |||
13 | export default { | ||
14 | name: 'UploadExcel', | ||
15 | components: { UploadExcelComponent }, | ||
16 | data() { | ||
17 | return { | ||
18 | tableData: [], | ||
19 | tableHeader: [] | ||
20 | } | ||
21 | }, | ||
22 | methods: { | ||
23 | beforeUpload(file) { | ||
24 | const isLt1M = file.size / 1024 / 1024 < 1 | ||
25 | |||
26 | if (isLt1M) { | ||
27 | return true | ||
28 | } | ||
29 | |||
30 | this.$message({ | ||
31 | message: 'Please do not upload files larger than 1m in size.', | ||
32 | type: 'warning' | ||
33 | }) | ||
34 | return false | ||
35 | }, | ||
36 | handleSuccess({ results, header }) { | ||
37 | this.tableData = results | ||
38 | this.tableHeader = header | ||
39 | } | ||
40 | } | ||
41 | } | ||
42 | </script> | ||
43 |
src/views/form/index.vue
1 | <template> | File was deleted | |
2 | <div class="app-container"> | ||
3 | <el-form ref="form" :model="form" label-width="120px"> | ||
4 | <el-form-item label="Activity name"> | ||
5 | <el-input v-model="form.name" /> | ||
6 | </el-form-item> | ||
7 | <el-form-item label="Activity zone"> | ||
8 | <el-select v-model="form.region" placeholder="please select your zone"> | ||
9 | <el-option label="Zone one" value="shanghai" /> | ||
10 | <el-option label="Zone two" value="beijing" /> | ||
11 | </el-select> | ||
12 | </el-form-item> | ||
13 | <el-form-item label="Activity time"> | ||
14 | <el-col :span="11"> | ||
15 | <el-date-picker | ||
16 | v-model="form.date1" | ||
17 | type="date" | ||
18 | placeholder="Pick a date" | ||
19 | style="width: 100%;" | ||
20 | /> | ||
21 | </el-col> | ||
22 | <el-col :span="2" class="line">-</el-col> | ||
23 | <el-col :span="11"> | ||
24 | <el-time-picker | ||
25 | v-model="form.date2" | ||
26 | type="fixed-time" | ||
27 | placeholder="Pick a time" | ||
28 | style="width: 100%;" | ||
29 | /> | ||
30 | </el-col> | ||
31 | </el-form-item> | ||
32 | <el-form-item label="Instant delivery"> | ||
33 | <el-switch v-model="form.delivery" /> | ||
34 | </el-form-item> | ||
35 | <el-form-item label="Activity type"> | ||
36 | <el-checkbox-group v-model="form.type"> | ||
37 | <el-checkbox label="Online activities" name="type" /> | ||
38 | <el-checkbox label="Promotion activities" name="type" /> | ||
39 | <el-checkbox label="Offline activities" name="type" /> | ||
40 | <el-checkbox label="Simple brand exposure" name="type" /> | ||
41 | </el-checkbox-group> | ||
42 | </el-form-item> | ||
43 | <el-form-item label="Resources"> | ||
44 | <el-radio-group v-model="form.resource"> | ||
45 | <el-radio label="Sponsor" /> | ||
46 | <el-radio label="Venue" /> | ||
47 | </el-radio-group> | ||
48 | </el-form-item> | ||
49 | <el-form-item label="Activity form"> | ||
50 | <el-input v-model="form.desc" type="textarea" /> | ||
51 | </el-form-item> | ||
52 | <el-form-item> | ||
53 | <el-button type="primary" @click="onSubmit">Create</el-button> | ||
54 | <el-button @click="onCancel">Cancel</el-button> | ||
55 | </el-form-item> | ||
56 | </el-form> | ||
57 | </div> | ||
58 | </template> | ||
59 | |||
60 | <script> | ||
61 | export default { | ||
62 | data() { | ||
63 | return { | ||
64 | form: { | ||
65 | name: "", | ||
66 | region: "", | ||
67 | date1: "", | ||
68 | date2: "", | ||
69 | delivery: false, | ||
70 | type: [], | ||
71 | resource: "", | ||
72 | desc: "" | ||
73 | } | ||
74 | }; | ||
75 | }, | ||
76 | methods: { | ||
77 | onSubmit() { | ||
78 | this.$message("submit!"); | ||
79 | }, | ||
80 | onCancel() { | ||
81 | this.$message({ | ||
82 | message: "cancel!", | ||
83 | type: "warning" | ||
84 | }); | ||
85 | } | ||
86 | } | ||
87 | }; | ||
88 | </script> | ||
89 | |||
90 | <style scoped> | ||
91 | .line { | ||
92 | text-align: center; | ||
93 | } | ||
94 | </style> | ||
95 | |||
96 | 1 | <template> |
src/views/guide/index.vue
File was created | 1 | <template> | |
2 | <div class="app-container"> | ||
3 | <aside> | ||
4 | {{ $t('guide.description') }} | ||
5 | <a href="https://github.com/kamranahmedse/driver.js" target="_blank">driver.js.</a> | ||
6 | </aside> | ||
7 | <el-button icon="el-icon-question" type="primary" @click.prevent.stop="guide"> | ||
8 | {{ $t('guide.button') }} | ||
9 | </el-button> | ||
10 | </div> | ||
11 | </template> | ||
12 | |||
13 | <script> | ||
14 | import Driver from 'driver.js' // import driver.js | ||
15 | import 'driver.js/dist/driver.min.css' // import driver.js css | ||
16 | import steps from './steps' | ||
17 | |||
18 | export default { | ||
19 | name: 'Guide', | ||
20 | data() { | ||
21 | return { | ||
22 | driver: null | ||
23 | } | ||
24 | }, | ||
25 | mounted() { | ||
26 | this.driver = new Driver() | ||
27 | }, | ||
28 | methods: { | ||
29 | guide() { | ||
30 | this.driver.defineSteps(steps) | ||
31 | this.driver.start() | ||
32 | } | ||
33 | } | ||
34 | } | ||
35 | </script> | ||
36 |
src/views/guide/steps.js
File was created | 1 | const steps = [ | |
2 | { | ||
3 | element: '#hamburger-container', | ||
4 | popover: { | ||
5 | title: 'Hamburger', | ||
6 | description: 'Open && Close sidebar', | ||
7 | position: 'bottom' | ||
8 | } | ||
9 | }, | ||
10 | { | ||
11 | element: '#breadcrumb-container', | ||
12 | popover: { | ||
13 | title: 'Breadcrumb', | ||
14 | description: 'Indicate the current page location', | ||
15 | position: 'bottom' | ||
16 | } | ||
17 | }, | ||
18 | { | ||
19 | element: '#header-search', | ||
20 | popover: { | ||
21 | title: 'Page Search', | ||
22 | description: 'Page search, quick navigation', | ||
23 | position: 'left' | ||
24 | } | ||
25 | }, | ||
26 | { | ||
27 | element: '#screenfull', | ||
28 | popover: { | ||
29 | title: 'Screenfull', | ||
30 | description: 'Set the page into fullscreen', | ||
31 | position: 'left' | ||
32 | } | ||
33 | }, | ||
34 | { | ||
35 | element: '#size-select', | ||
36 | popover: { | ||
37 | title: 'Switch Size', | ||
38 | description: 'Switch the system size', | ||
39 | position: 'left' | ||
40 | } | ||
41 | }, | ||
42 | { | ||
43 | element: '#tags-view-container', | ||
44 | popover: { | ||
45 | title: 'Tags view', | ||
46 | description: 'The history of the page you visited', | ||
47 | position: 'bottom' | ||
48 | }, | ||
49 | padding: 0 | ||
50 | } | ||
51 | ] | ||
52 | |||
53 | export default steps | ||
54 |
src/views/i18n-demo/index.vue
File was created | 1 | <template> | |
2 | <div> | ||
3 | <el-card class="box-card" style="margin-top:40px;"> | ||
4 | <div slot="header" class="clearfix"> | ||
5 | <svg-icon icon-class="international" /> | ||
6 | <span style="margin-left:10px;">{{ $t('i18nView.title') }}</span> | ||
7 | </div> | ||
8 | <div> | ||
9 | <el-radio-group v-model="lang" size="small"> | ||
10 | <el-radio label="zh" border> | ||
11 | 简体中文 | ||
12 | </el-radio> | ||
13 | <el-radio label="en" border> | ||
14 | English | ||
15 | </el-radio> | ||
16 | <el-radio label="es" border> | ||
17 | Español | ||
18 | </el-radio> | ||
19 | <el-radio label="ja" border> | ||
20 | 日本語 | ||
21 | </el-radio> | ||
22 | </el-radio-group> | ||
23 | <el-tag style="margin-top:15px;display:block;" type="info"> | ||
24 | {{ $t('i18nView.note') }} | ||
25 | </el-tag> | ||
26 | </div> | ||
27 | </el-card> | ||
28 | |||
29 | <el-row :gutter="20" style="margin:100px 15px 50px;"> | ||
30 | <el-col :span="12" :xs="24"> | ||
31 | <div class="block"> | ||
32 | <el-date-picker v-model="date" :placeholder="$t('i18nView.datePlaceholder')" type="date" /> | ||
33 | </div> | ||
34 | <div class="block"> | ||
35 | <el-select v-model="value" :placeholder="$t('i18nView.selectPlaceholder')"> | ||
36 | <el-option | ||
37 | v-for="item in options" | ||
38 | :key="item.value" | ||
39 | :label="item.label" | ||
40 | :value="item.value" | ||
41 | /> | ||
42 | </el-select> | ||
43 | </div> | ||
44 | <div class="block"> | ||
45 | <el-button class="item-btn" size="small"> | ||
46 | {{ $t('i18nView.default') }} | ||
47 | </el-button> | ||
48 | <el-button class="item-btn" size="small" type="primary"> | ||
49 | {{ $t('i18nView.primary') }} | ||
50 | </el-button> | ||
51 | <el-button class="item-btn" size="small" type="success"> | ||
52 | {{ $t('i18nView.success') }} | ||
53 | </el-button> | ||
54 | <el-button class="item-btn" size="small" type="info"> | ||
55 | {{ $t('i18nView.info') }} | ||
56 | </el-button> | ||
57 | <el-button class="item-btn" size="small" type="warning"> | ||
58 | {{ $t('i18nView.warning') }} | ||
59 | </el-button> | ||
60 | <el-button class="item-btn" size="small" type="danger"> | ||
61 | {{ $t('i18nView.danger') }} | ||
62 | </el-button> | ||
63 | </div> | ||
64 | </el-col> | ||
65 | <el-col :span="12" :xs="24"> | ||
66 | <el-table :data="tableData" fit highlight-current-row border style="width: 100%"> | ||
67 | <el-table-column :label="$t('i18nView.tableName')" prop="name" width="100" align="center" /> | ||
68 | <el-table-column :label="$t('i18nView.tableDate')" prop="date" width="120" align="center" /> | ||
69 | <el-table-column :label="$t('i18nView.tableAddress')" prop="address" /> | ||
70 | </el-table> | ||
71 | </el-col> | ||
72 | </el-row> | ||
73 | </div> | ||
74 | </template> | ||
75 | |||
76 | <script> | ||
77 | import local from './local' | ||
78 | const viewName = 'i18nView' | ||
79 | |||
80 | export default { | ||
81 | name: 'I18n', | ||
82 | data() { | ||
83 | return { | ||
84 | date: '', | ||
85 | tableData: [{ | ||
86 | date: '2016-05-03', | ||
87 | name: 'Tom', | ||
88 | address: 'No. 189, Grove St, Los Angeles' | ||
89 | }, | ||
90 | { | ||
91 | date: '2016-05-02', | ||
92 | name: 'Tom', | ||
93 | address: 'No. 189, Grove St, Los Angeles' | ||
94 | }, | ||
95 | { | ||
96 | date: '2016-05-04', | ||
97 | name: 'Tom', | ||
98 | address: 'No. 189, Grove St, Los Angeles' | ||
99 | }, | ||
100 | { | ||
101 | date: '2016-05-01', | ||
102 | name: 'Tom', | ||
103 | address: 'No. 189, Grove St, Los Angeles' | ||
104 | }], | ||
105 | options: [], | ||
106 | value: '' | ||
107 | } | ||
108 | }, | ||
109 | computed: { | ||
110 | lang: { | ||
111 | get() { | ||
112 | return this.$store.state.app.language | ||
113 | }, | ||
114 | set(lang) { | ||
115 | this.$i18n.locale = lang | ||
116 | this.$store.dispatch('app/setLanguage', lang) | ||
117 | } | ||
118 | } | ||
119 | }, | ||
120 | watch: { | ||
121 | lang() { | ||
122 | this.setOptions() | ||
123 | } | ||
124 | }, | ||
125 | created() { | ||
126 | if (!this.$i18n.getLocaleMessage('en')[viewName]) { | ||
127 | this.$i18n.mergeLocaleMessage('en', local.en) | ||
128 | this.$i18n.mergeLocaleMessage('zh', local.zh) | ||
129 | this.$i18n.mergeLocaleMessage('es', local.es) | ||
130 | this.$i18n.mergeLocaleMessage('ja', local.ja) | ||
131 | } | ||
132 | this.setOptions() // set default select options | ||
133 | }, | ||
134 | methods: { | ||
135 | setOptions() { | ||
136 | this.options = [ | ||
137 | { | ||
138 | value: '1', | ||
139 | label: this.$t('i18nView.one') | ||
140 | }, | ||
141 | { | ||
142 | value: '2', | ||
143 | label: this.$t('i18nView.two') | ||
144 | }, | ||
145 | { | ||
146 | value: '3', | ||
147 | label: this.$t('i18nView.three') | ||
148 | } | ||
149 | ] | ||
150 | } | ||
151 | } | ||
152 | } | ||
153 | </script> | ||
154 | |||
155 | <style scoped> | ||
156 | .box-card { | ||
157 | width: 600px; | ||
158 | max-width: 100%; | ||
159 | margin: 20px auto; | ||
160 | } | ||
161 | .item-btn{ | ||
162 | margin-bottom: 15px; | ||
163 | margin-left: 0px; | ||
164 | } | ||
165 | .block { | ||
166 | padding: 25px; | ||
167 | } | ||
168 | </style> | ||
169 |
src/views/i18n-demo/local.js
File was created | 1 | ||
2 | export default { | ||
3 | zh: { | ||
4 | i18nView: { | ||
5 | title: '切换语言', | ||
6 | note: '本项目国际化基于 vue-i18n', | ||
7 | datePlaceholder: '请选择日期', | ||
8 | selectPlaceholder: '请选择', | ||
9 | tableDate: '日期', | ||
10 | tableName: '姓名', | ||
11 | tableAddress: '地址', | ||
12 | default: '默认按钮', | ||
13 | primary: '主要按钮', | ||
14 | success: '成功按钮', | ||
15 | info: '信息按钮', | ||
16 | warning: '警告按钮', | ||
17 | danger: '危险按钮', | ||
18 | one: '一', | ||
19 | two: '二', | ||
20 | three: '三' | ||
21 | } | ||
22 | }, | ||
23 | en: { | ||
24 | i18nView: { | ||
25 | title: 'Switch Language', | ||
26 | note: 'The internationalization of this project is based on vue-i18n', | ||
27 | datePlaceholder: 'Pick a day', | ||
28 | selectPlaceholder: 'Select', | ||
29 | tableDate: 'tableDate', | ||
30 | tableName: 'tableName', | ||
31 | tableAddress: 'tableAddress', | ||
32 | default: 'default:', | ||
33 | primary: 'primary', | ||
34 | success: 'success', | ||
35 | info: 'info', | ||
36 | warning: 'warning', | ||
37 | danger: 'danger', | ||
38 | one: 'One', | ||
39 | two: 'Two', | ||
40 | three: 'Three' | ||
41 | } | ||
42 | }, | ||
43 | es: { | ||
44 | i18nView: { | ||
45 | title: 'Switch Language', | ||
46 | note: 'The internationalization of this project is based on vue-i18n', | ||
47 | datePlaceholder: 'Pick a day', | ||
48 | selectPlaceholder: 'Select', | ||
49 | tableDate: 'tableDate', | ||
50 | tableName: 'tableName', | ||
51 | tableAddress: 'tableAddress', | ||
52 | default: 'default:', | ||
53 | primary: 'primary', | ||
54 | success: 'success', | ||
55 | info: 'info', | ||
56 | warning: 'warning', | ||
57 | danger: 'danger', | ||
58 | one: 'One', | ||
59 | two: 'Two', | ||
60 | three: 'Three' | ||
61 | } | ||
62 | }, | ||
63 | ja: { | ||
64 | i18nView: { | ||
65 | title: '言語切替', | ||
66 | note: 'vue-i18nを使っています', | ||
67 | datePlaceholder: '日時選択', | ||
68 | selectPlaceholder: '選択してください', | ||
69 | tableDate: '日時', | ||
70 | tableName: '姓名', | ||
71 | tableAddress: '住所', | ||
72 | default: 'default', | ||
73 | primary: 'primary', | ||
74 | success: 'success', | ||
75 | info: 'info', | ||
76 | warning: 'warning', | ||
77 | danger: 'danger', | ||
78 | one: '1', | ||
79 | two: '2', | ||
80 | three: '3' | ||
81 | } | ||
82 | } | ||
83 | } | ||
84 |
src/views/icons/element-icons.js
File was created | 1 | 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'] | |
2 | |||
3 | export default elementIcons | ||
4 |
src/views/icons/index.vue
File was created | 1 | <template> | |
2 | <div class="icons-container"> | ||
3 | <aside> | ||
4 | <a href="https://panjiachen.github.io/vue-element-admin-site/guide/advanced/icon.html" target="_blank">Add and use | ||
5 | </a> | ||
6 | </aside> | ||
7 | <el-tabs type="border-card"> | ||
8 | <el-tab-pane label="Icons"> | ||
9 | <div class="grid"> | ||
10 | <div v-for="item of svgIcons" :key="item" @click="handleClipboard(generateIconCode(item),$event)"> | ||
11 | <el-tooltip placement="top"> | ||
12 | <div slot="content"> | ||
13 | {{ generateIconCode(item) }} | ||
14 | </div> | ||
15 | <div class="icon-item"> | ||
16 | <svg-icon :icon-class="item" class-name="disabled" /> | ||
17 | <span>{{ item }}</span> | ||
18 | </div> | ||
19 | </el-tooltip> | ||
20 | </div> | ||
21 | </div> | ||
22 | </el-tab-pane> | ||
23 | <el-tab-pane label="Element-UI Icons"> | ||
24 | <div class="grid"> | ||
25 | <div v-for="item of elementIcons" :key="item" @click="handleClipboard(generateElementIconCode(item),$event)"> | ||
26 | <el-tooltip placement="top"> | ||
27 | <div slot="content"> | ||
28 | {{ generateElementIconCode(item) }} | ||
29 | </div> | ||
30 | <div class="icon-item"> | ||
31 | <i :class="'el-icon-' + item" /> | ||
32 | <span>{{ item }}</span> | ||
33 | </div> | ||
34 | </el-tooltip> | ||
35 | </div> | ||
36 | </div> | ||
37 | </el-tab-pane> | ||
38 | </el-tabs> | ||
39 | </div> | ||
40 | </template> | ||
41 | |||
42 | <script> | ||
43 | import clipboard from '@/utils/clipboard' | ||
44 | import svgIcons from './svg-icons' | ||
45 | import elementIcons from './element-icons' | ||
46 | |||
47 | export default { | ||
48 | name: 'Icons', | ||
49 | data() { | ||
50 | return { | ||
51 | svgIcons, | ||
52 | elementIcons | ||
53 | } | ||
54 | }, | ||
55 | methods: { | ||
56 | generateIconCode(symbol) { | ||
57 | return `<svg-icon icon-class="${symbol}" />` | ||
58 | }, | ||
59 | generateElementIconCode(symbol) { | ||
60 | return `<i class="el-icon-${symbol}" />` | ||
61 | }, | ||
62 | handleClipboard(text, event) { | ||
63 | clipboard(text, event) | ||
64 | } | ||
65 | } | ||
66 | } | ||
67 | </script> | ||
68 | |||
69 | <style lang="scss" scoped> | ||
70 | .icons-container { | ||
71 | margin: 10px 20px 0; | ||
72 | overflow: hidden; | ||
73 | |||
74 | .grid { | ||
75 | position: relative; | ||
76 | display: grid; | ||
77 | grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); | ||
78 | } | ||
79 | |||
80 | .icon-item { | ||
81 | margin: 20px; | ||
82 | height: 85px; | ||
83 | text-align: center; | ||
84 | width: 100px; | ||
85 | float: left; | ||
86 | font-size: 30px; | ||
87 | color: #24292e; | ||
88 | cursor: pointer; | ||
89 | } | ||
90 | |||
91 | span { | ||
92 | display: block; | ||
93 | font-size: 16px; | ||
94 | margin-top: 10px; | ||
95 | } | ||
96 | |||
97 | .disabled { | ||
98 | pointer-events: none; | ||
99 | } | ||
100 | } | ||
101 | </style> | ||
102 |
src/views/icons/svg-icons.js
File was created | 1 | const req = require.context('../../icons/svg', false, /\.svg$/) | |
2 | const requireAll = requireContext => requireContext.keys() | ||
3 | |||
4 | const re = /\.\/(.*)\.svg/ | ||
5 | |||
6 | const svgIcons = requireAll(req).map(i => { | ||
7 | return i.match(re)[1] | ||
8 | }) | ||
9 | |||
10 | export default svgIcons | ||
11 |
src/views/login/auth-redirect.vue
File was created | 1 | <script> | |
2 | export default { | ||
3 | name: 'AuthRedirect', | ||
4 | created() { | ||
5 | const hash = window.location.search.slice(1) | ||
6 | if (window.localStorage) { | ||
7 | window.localStorage.setItem('x-admin-oauth-code', hash) | ||
8 | window.close() | ||
9 | } | ||
10 | }, | ||
11 | render: function(h) { | ||
12 | return h() // avoid warning message | ||
13 | } | ||
14 | } | ||
15 | </script> | ||
16 |
src/views/login/components/SocialSignin.vue
File was created | 1 | <template> | |
2 | <div class="social-signup-container"> | ||
3 | <div class="sign-btn" @click="wechatHandleClick('wechat')"> | ||
4 | <span class="wx-svg-container"><svg-icon icon-class="wechat" class="icon" /></span> | ||
5 | |||
6 | </div> | ||
7 | <div class="sign-btn" @click="tencentHandleClick('tencent')"> | ||
8 | <span class="qq-svg-container"><svg-icon icon-class="qq" class="icon" /></span> | ||
9 | |||
10 | </div> | ||
11 | </div> | ||
12 | </template> | ||
13 | |||
14 | <script> | ||
15 | // import openWindow from '@/utils/open-window' | ||
16 | |||
17 | export default { | ||
18 | name: 'SocialSignin', | ||
19 | methods: { | ||
20 | wechatHandleClick(thirdpart) { | ||
21 | alert('ok') | ||
22 | // this.$store.commit('SET_AUTH_TYPE', thirdpart) | ||
23 | // const appid = 'xxxxx' | ||
24 | // const redirect_uri = encodeURIComponent('xxx/redirect?redirect=' + window.location.origin + '/auth-redirect') | ||
25 | // const url = 'https://open.weixin.qq.com/connect/qrconnect?appid=' + appid + '&redirect_uri=' + redirect_uri + '&response_type=code&scope=snsapi_login#wechat_redirect' | ||
26 | // openWindow(url, thirdpart, 540, 540) | ||
27 | }, | ||
28 | tencentHandleClick(thirdpart) { | ||
29 | alert('ok') | ||
30 | // this.$store.commit('SET_AUTH_TYPE', thirdpart) | ||
31 | // const client_id = 'xxxxx' | ||
32 | // const redirect_uri = encodeURIComponent('xxx/redirect?redirect=' + window.location.origin + '/auth-redirect') | ||
33 | // const url = 'https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=' + client_id + '&redirect_uri=' + redirect_uri | ||
34 | // openWindow(url, thirdpart, 540, 540) | ||
35 | } | ||
36 | } | ||
37 | } | ||
38 | </script> | ||
39 | |||
40 | <style lang="scss" scoped> | ||
41 | .social-signup-container { | ||
42 | margin: 20px 0; | ||
43 | .sign-btn { | ||
44 | display: inline-block; | ||
45 | cursor: pointer; | ||
46 | } | ||
47 | .icon { | ||
48 | color: #fff; | ||
49 | font-size: 24px; | ||
50 | margin-top: 8px; | ||
51 | } | ||
52 | .wx-svg-container, | ||
53 | .qq-svg-container { | ||
54 | display: inline-block; | ||
55 | width: 40px; | ||
56 | height: 40px; | ||
57 | line-height: 40px; | ||
58 | text-align: center; | ||
59 | padding-top: 1px; | ||
60 | border-radius: 4px; | ||
61 | margin-bottom: 20px; | ||
62 | margin-right: 5px; | ||
63 | } | ||
64 | .wx-svg-container { | ||
65 | background-color: #24da70; | ||
66 | } | ||
67 | .qq-svg-container { | ||
68 | background-color: #6BA2D6; | ||
69 | margin-left: 50px; | ||
70 | } | ||
71 | } | ||
72 | </style> | ||
73 |
src/views/login/index.vue
1 | <template> | 1 | <template> |
2 | <div class="login-container"> | 2 | <div class="login-container"> |
3 | <el-form | 3 | <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" autocomplete="on" label-position="left"> |
4 | ref="loginForm" | 4 | |
5 | :model="loginForm" | ||
6 | :rules="loginRules" | ||
7 | class="login-form" | ||
8 | auto-complete="on" | ||
9 | label-position="left" | ||
10 | > | ||
11 | <div class="title-container"> | 5 | <div class="title-container"> |
12 | <h3 class="title">鱼皮系统</h3> | 6 | <h3 class="title"> |
7 | {{ $t('login.title') }} | ||
8 | </h3> | ||
9 | <lang-select class="set-language" /> | ||
13 | </div> | 10 | </div> |
14 | 11 | ||
15 | <el-form-item prop="username"> | 12 | <el-form-item prop="username"> |
16 | <span class="svg-container"> | 13 | <span class="svg-container"> |
17 | <svg-icon icon-class="user" /> | 14 | <svg-icon icon-class="user" /> |
18 | </span> | 15 | </span> |
19 | <el-input | 16 | <el-input |
20 | ref="username" | 17 | ref="username" |
21 | v-model="loginForm.username" | 18 | v-model="loginForm.username" |
22 | placeholder="Username" | 19 | :placeholder="$t('login.username')" |
23 | name="username" | 20 | name="username" |
24 | type="text" | 21 | type="text" |
25 | tabindex="1" | 22 | tabindex="1" |
26 | auto-complete="on" | 23 | autocomplete="on" |
27 | /> | 24 | /> |
28 | </el-form-item> | 25 | </el-form-item> |
29 | 26 | ||
30 | <el-form-item prop="password"> | 27 | <el-tooltip v-model="capsTooltip" content="Caps lock is On" placement="right" manual> |
31 | <span class="svg-container"> | 28 | <el-form-item prop="password"> |
32 | <svg-icon icon-class="password" /> | 29 | <span class="svg-container"> |
33 | </span> | 30 | <svg-icon icon-class="password" /> |
34 | <el-input | 31 | </span> |
35 | :key="passwordType" | 32 | <el-input |
36 | ref="password" | 33 | :key="passwordType" |
37 | v-model="loginForm.password" | 34 | ref="password" |
38 | :type="passwordType" | 35 | v-model="loginForm.password" |
39 | placeholder="Password" | 36 | :type="passwordType" |
40 | name="password" | 37 | :placeholder="$t('login.password')" |
41 | tabindex="2" | 38 | name="password" |
42 | auto-complete="on" | 39 | tabindex="2" |
43 | @keyup.enter.native="handleLogin" | 40 | autocomplete="on" |
44 | /> | 41 | @keyup.native="checkCapslock" |
45 | <span class="show-pwd" @click="showPwd"> | 42 | @blur="capsTooltip = false" |
46 | <svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" /> | 43 | @keyup.enter.native="handleLogin" |
47 | </span> | 44 | /> |
48 | </el-form-item> | 45 | <span class="show-pwd" @click="showPwd"> |
49 | <!-- <el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">reg</el-button> --> | 46 | <svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" /> |
50 | <el-button | 47 | </span> |
51 | :loading="loading" | 48 | </el-form-item> |
52 | type="primary" | 49 | </el-tooltip> |
53 | style="width:100%;margin-bottom:30px;" | 50 | |
54 | @click.native.prevent="handleLogin" | 51 | <el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin"> |
55 | >Login</el-button> | 52 | {{ $t('login.logIn') }} |
53 | </el-button> | ||
56 | 54 | ||
57 | <div class="tips"> | 55 | <div style="position:relative"> |
58 | <span style="margin-right:20px;">username: admin</span> | 56 | <div class="tips"> |
59 | <span>password: any</span> | 57 | <span>{{ $t('login.username') }} : admin</span> |
58 | <span>{{ $t('login.password') }} : {{ $t('login.any') }}</span> | ||
59 | </div> | ||
60 | <div class="tips"> | ||
61 | <span style="margin-right:18px;"> | ||
62 | {{ $t('login.username') }} : editor | ||
63 | </span> | ||
64 | <span>{{ $t('login.password') }} : {{ $t('login.any') }}</span> | ||
65 | </div> | ||
66 | |||
67 | <el-button class="thirdparty-button" type="primary" @click="showDialog=true"> | ||
68 | {{ $t('login.thirdparty') }} | ||
69 | </el-button> | ||
60 | </div> | 70 | </div> |
61 | </el-form> | 71 | </el-form> |
72 | |||
73 | <el-dialog :title="$t('login.thirdparty')" :visible.sync="showDialog"> | ||
74 | {{ $t('login.thirdpartyTips') }} | ||
75 | <br> | ||
76 | <br> | ||
77 | <br> | ||
78 | <social-sign /> | ||
79 | </el-dialog> | ||
62 | </div> | 80 | </div> |
63 | </template> | 81 | </template> |
64 | 82 | ||
65 | <script> | 83 | <script> |
66 | import { validUsername } from "@/utils/validate"; | 84 | import { validUsername } from '@/utils/validate' |
85 | import LangSelect from '@/components/LangSelect' | ||
86 | import SocialSign from './components/SocialSignin' | ||
67 | 87 | ||
68 | export default { | 88 | export default { |
69 | name: "Login", | 89 | name: 'Login', |
90 | components: { LangSelect, SocialSign }, | ||
70 | data() { | 91 | data() { |
71 | const validateUsername = (rule, value, callback) => { | 92 | const validateUsername = (rule, value, callback) => { |
72 | if (!validUsername(value)) { | 93 | if (!validUsername(value)) { |
73 | callback(new Error("Please enter the correct user name")); | 94 | callback(new Error('Please enter the correct user name')) |
74 | } else { | 95 | } else { |
75 | callback(); | 96 | callback() |
76 | } | 97 | } |
77 | }; | 98 | } |
78 | const validatePassword = (rule, value, callback) => { | 99 | const validatePassword = (rule, value, callback) => { |
79 | if (value.length < 6) { | 100 | if (value.length < 6) { |
80 | callback(new Error("The password can not be less than 6 digits")); | 101 | callback(new Error('The password can not be less than 6 digits')) |
81 | } else { | 102 | } else { |
82 | callback(); | 103 | callback() |
83 | } | 104 | } |
84 | }; | 105 | } |
85 | return { | 106 | return { |
86 | loginForm: { | 107 | loginForm: { |
87 | username: "admin", | 108 | username: 'admin', |
88 | password: "111111" | 109 | password: '111111' |
89 | }, | 110 | }, |
90 | loginRules: { | 111 | loginRules: { |
91 | username: [ | 112 | username: [{ required: true, trigger: 'blur', validator: validateUsername }], |
92 | { required: true, trigger: "blur", validator: validateUsername } | 113 | password: [{ required: true, trigger: 'blur', validator: validatePassword }] |
93 | ], | ||
94 | password: [ | ||
95 | { required: true, trigger: "blur", validator: validatePassword } | ||
96 | ] | ||
97 | }, | 114 | }, |
115 | passwordType: 'password', | ||
116 | capsTooltip: false, | ||
98 | loading: false, | 117 | loading: false, |
99 | passwordType: "password", | 118 | showDialog: false, |
100 | redirect: undefined | 119 | redirect: undefined, |
101 | }; | 120 | otherQuery: {} |
121 | } | ||
102 | }, | 122 | }, |
103 | watch: { | 123 | watch: { |
104 | $route: { | 124 | $route: { |
105 | handler: function(route) { | 125 | handler: function(route) { |
106 | this.redirect = route.query && route.query.redirect; | 126 | const query = route.query |
127 | if (query) { | ||
128 | this.redirect = query.redirect | ||
129 | this.otherQuery = this.getOtherQuery(query) | ||
130 | } | ||
107 | }, | 131 | }, |
108 | immediate: true | 132 | immediate: true |
109 | } | 133 | } |
110 | }, | 134 | }, |
135 | created() { | ||
136 | // window.addEventListener('storage', this.afterQRScan) | ||
137 | }, | ||
138 | mounted() { | ||
139 | if (this.loginForm.username === '') { | ||
140 | this.$refs.username.focus() | ||
141 | } else if (this.loginForm.password === '') { | ||
142 | this.$refs.password.focus() | ||
143 | } | ||
144 | }, | ||
145 | destroyed() { | ||
146 | // window.removeEventListener('storage', this.afterQRScan) | ||
147 | }, | ||
111 | methods: { | 148 | methods: { |
149 | checkCapslock(e) { | ||
150 | const { key } = e | ||
151 | this.capsTooltip = key && key.length === 1 && (key >= 'A' && key <= 'Z') | ||
152 | }, | ||
112 | showPwd() { | 153 | showPwd() { |
113 | if (this.passwordType === "password") { | 154 | if (this.passwordType === 'password') { |
114 | this.passwordType = ""; | 155 | this.passwordType = '' |
115 | } else { | 156 | } else { |
116 | this.passwordType = "password"; | 157 | this.passwordType = 'password' |
117 | } | 158 | } |
118 | this.$nextTick(() => { | 159 | this.$nextTick(() => { |
119 | this.$refs.password.focus(); | 160 | this.$refs.password.focus() |
120 | }); | 161 | }) |
121 | }, | 162 | }, |
122 | handleLogin() { | 163 | handleLogin() { |
123 | this.$refs.loginForm.validate(valid => { | 164 | this.$refs.loginForm.validate(valid => { |
124 | if (valid) { | 165 | if (valid) { |
125 | this.loading = true; | 166 | this.loading = true |
126 | this.$store | 167 | this.$store.dispatch('user/login', this.loginForm) |
127 | .dispatch("user/login", this.loginForm) | ||
128 | .then(() => { | 168 | .then(() => { |
129 | this.$router.push({ path: this.redirect || "/" }); | 169 | this.$router.push({ path: this.redirect || '/', query: this.otherQuery }) |
130 | this.loading = false; | 170 | this.loading = false |
131 | console.log('this.redirect', this.$router); | 171 | }) |
172 | .catch(() => { | ||
173 | this.loading = false | ||
132 | }) | 174 | }) |
133 | .catch(res => { | ||
134 | console.log("res error------------>", res); | ||
135 | this.loading = false; | ||
136 | }); | ||
137 | } else { | 175 | } else { |
138 | console.log("error submit!!"); | 176 | console.log('error submit!!') |
139 | return false; | 177 | return false |
140 | } | 178 | } |
141 | }); | 179 | }) |
180 | }, | ||
181 | getOtherQuery(query) { | ||
182 | return Object.keys(query).reduce((acc, cur) => { | ||
183 | if (cur !== 'redirect') { | ||
184 | acc[cur] = query[cur] | ||
185 | } | ||
186 | return acc | ||
187 | }, {}) | ||
142 | } | 188 | } |
189 | // afterQRScan() { | ||
190 | // if (e.key === 'x-admin-oauth-code') { | ||
191 | // const code = getQueryObject(e.newValue) | ||
192 | // const codeMap = { | ||
193 | // wechat: 'code', | ||
194 | // tencent: 'code' | ||
195 | // } | ||
196 | // const type = codeMap[this.auth_type] | ||
197 | // const codeName = code[type] | ||
198 | // if (codeName) { | ||
199 | // this.$store.dispatch('LoginByThirdparty', codeName).then(() => { | ||
200 | // this.$router.push({ path: this.redirect || '/' }) | ||
201 | // }) | ||
202 | // } else { | ||
203 | // alert('第三方登录失败') | ||
204 | // } | ||
205 | // } | ||
206 | // } | ||
143 | } | 207 | } |
144 | }; | 208 | } |
145 | </script> | 209 | </script> |
146 | 210 | ||
147 | <style lang="scss"> | 211 | <style lang="scss"> |
148 | /* 修复input 背景不协调 和光标变色 */ | 212 | /* 修复input 背景不协调 和光标变色 */ |
149 | /* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */ | 213 | /* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */ |
150 | 214 | ||
151 | $bg: #283443; | 215 | $bg:#283443; |
152 | $light_gray: #fff; | 216 | $light_gray:#fff; |
153 | $cursor: #fff; | 217 | $cursor: #fff; |
154 | 218 | ||
155 | @supports (-webkit-mask: none) and (not (cater-color: $cursor)) { | 219 | @supports (-webkit-mask: none) and (not (cater-color: $cursor)) { |
156 | .login-container .el-input input { | 220 | .login-container .el-input input { |
157 | color: $cursor; | 221 | color: $cursor; |
158 | } | 222 | } |
159 | } | 223 | } |
160 | 224 | ||
161 | /* reset element-ui css */ | 225 | /* reset element-ui css */ |
162 | .login-container { | 226 | .login-container { |
163 | .el-input { | 227 | .el-input { |
164 | display: inline-block; | 228 | display: inline-block; |
165 | height: 47px; | 229 | height: 47px; |
166 | width: 85%; | 230 | width: 85%; |
167 | 231 | ||
168 | input { | 232 | input { |
169 | background: transparent; | 233 | background: transparent; |
170 | border: 0px; | 234 | border: 0px; |
171 | -webkit-appearance: none; | 235 | -webkit-appearance: none; |
172 | border-radius: 0px; | 236 | border-radius: 0px; |
173 | padding: 12px 5px 12px 15px; | 237 | padding: 12px 5px 12px 15px; |
174 | color: $light_gray; | 238 | color: $light_gray; |
175 | height: 47px; | 239 | height: 47px; |
176 | caret-color: $cursor; | 240 | caret-color: $cursor; |
177 | 241 | ||
178 | &:-webkit-autofill { | 242 | &:-webkit-autofill { |
179 | box-shadow: 0 0 0px 1000px $bg inset !important; | 243 | box-shadow: 0 0 0px 1000px $bg inset !important; |
180 | -webkit-text-fill-color: $cursor !important; | 244 | -webkit-text-fill-color: $cursor !important; |
181 | } | 245 | } |
182 | } | 246 | } |
183 | } | 247 | } |
184 | 248 | ||
185 | .el-form-item { | 249 | .el-form-item { |
186 | border: 1px solid rgba(255, 255, 255, 0.1); | 250 | border: 1px solid rgba(255, 255, 255, 0.1); |
187 | background: rgba(0, 0, 0, 0.1); | 251 | background: rgba(0, 0, 0, 0.1); |
188 | border-radius: 5px; | 252 | border-radius: 5px; |
189 | color: #454545; | 253 | color: #454545; |
190 | } | 254 | } |
191 | } | 255 | } |
192 | </style> | 256 | </style> |
193 | 257 | ||
194 | <style lang="scss" scoped> | 258 | <style lang="scss" scoped> |
195 | $bg: #2d3a4b; | 259 | $bg:#2d3a4b; |
196 | $dark_gray: #889aa4; | 260 | $dark_gray:#889aa4; |
197 | $light_gray: #eee; | 261 | $light_gray:#eee; |
198 | 262 | ||
199 | .login-container { | 263 | .login-container { |
200 | min-height: 100%; | 264 | min-height: 100%; |
201 | width: 100%; | 265 | width: 100%; |
202 | background-color: $bg; | 266 | background-color: $bg; |
203 | overflow: hidden; | 267 | overflow: hidden; |
204 | 268 | ||
205 | .login-form { | 269 | .login-form { |
206 | position: relative; | 270 | position: relative; |
207 | width: 520px; | 271 | width: 520px; |
208 | max-width: 100%; | 272 | max-width: 100%; |
209 | padding: 160px 35px 0; | 273 | padding: 160px 35px 0; |
210 | margin: 0 auto; | 274 | margin: 0 auto; |
211 | overflow: hidden; | 275 | overflow: hidden; |
212 | } | 276 | } |
213 | 277 | ||
214 | .tips { | 278 | .tips { |
215 | font-size: 14px; | 279 | font-size: 14px; |
216 | color: #fff; | 280 | color: #fff; |
217 | margin-bottom: 10px; | 281 | margin-bottom: 10px; |
218 | 282 | ||
219 | span { | 283 | span { |
220 | &:first-of-type { | 284 | &:first-of-type { |
221 | margin-right: 16px; | 285 | margin-right: 16px; |
222 | } | 286 | } |
223 | } | 287 | } |
224 | } | 288 | } |
225 | 289 | ||
226 | .svg-container { | 290 | .svg-container { |
227 | padding: 6px 5px 6px 15px; | 291 | padding: 6px 5px 6px 15px; |
228 | color: $dark_gray; | 292 | color: $dark_gray; |
229 | vertical-align: middle; | 293 | vertical-align: middle; |
230 | width: 30px; | 294 | width: 30px; |
231 | display: inline-block; | 295 | display: inline-block; |
232 | } | 296 | } |
233 | 297 | ||
234 | .title-container { | 298 | .title-container { |
235 | position: relative; | 299 | position: relative; |
236 | 300 | ||
237 | .title { | 301 | .title { |
238 | font-size: 26px; | 302 | font-size: 26px; |
239 | color: $light_gray; | 303 | color: $light_gray; |
240 | margin: 0px auto 40px auto; | 304 | margin: 0px auto 40px auto; |
241 | text-align: center; | 305 | text-align: center; |
242 | font-weight: bold; | 306 | font-weight: bold; |
243 | } | 307 | } |
308 | |||
309 | .set-language { | ||
310 | color: #fff; | ||
311 | position: absolute; | ||
312 | top: 3px; | ||
313 | font-size: 18px; | ||
314 | right: 0px; | ||
315 | cursor: pointer; | ||
316 | } | ||
244 | } | 317 | } |
245 | 318 | ||
246 | .show-pwd { | 319 | .show-pwd { |
247 | position: absolute; | 320 | position: absolute; |
248 | right: 10px; | 321 | right: 10px; |
249 | top: 7px; | 322 | top: 7px; |
250 | font-size: 16px; | 323 | font-size: 16px; |
251 | color: $dark_gray; | 324 | color: $dark_gray; |
252 | cursor: pointer; | 325 | cursor: pointer; |
253 | user-select: none; | 326 | user-select: none; |
254 | } | 327 | } |
1 | <template> | 1 | <template> |
2 | <div style="padding:30px;"> | 2 | <div style="padding:30px;"> |
3 | <el-alert :closable="false" title="menu 1"> | 3 | <el-alert :closable="false" title="menu 1"> |
4 | <router-view /> | 4 | <router-view /> |
5 | </el-alert> | 5 | </el-alert> |
6 | </div> | 6 | </div> |
7 | </template> | 7 | </template> |
8 | 8 |
src/views/nested/menu1/menu1-1/index.vue
1 | <template> | 1 | <template> |
2 | <div style="padding:30px;"> | 2 | <div style="padding:30px;"> |
3 | <el-alert :closable="false" title="menu 1-1" type="success"> | 3 | <el-alert :closable="false" title="menu 1-1" type="success"> |
4 | <router-view /> | 4 | <router-view /> |
5 | </el-alert> | 5 | </el-alert> |
6 | </div> | 6 | </div> |
7 | </template> | 7 | </template> |
8 | <template functional> | ||
9 | <div style="padding:30px;"> | ||
10 | <el-alert :closable="false" title="menu 1-2-1" type="warning" /> | ||
11 | </div> | ||
12 | </template> |
1 | <template> | 1 | <template> |
2 | <div style="padding:30px;"> | 2 | <div style="padding:30px;"> |
3 | <el-alert :closable="false" title="menu 1-2" type="success"> | 3 | <el-alert :closable="false" title="menu 1-2" type="success"> |
4 | <router-view /> | 4 | <router-view /> |
5 | </el-alert> | 5 | </el-alert> |
6 | </div> | 6 | </div> |
7 | </template> | 7 | </template> |
8 | 8 |
1 | <template functional> | 1 | <template functional> |
2 | <div style="padding:30px;"> | 2 | <div style="padding:30px;"> |
3 | <el-alert :closable="false" title="menu 1-2-1" type="warning" /> | 3 | <el-alert :closable="false" title="menu 1-2-1" type="warning" /> |
4 | </div> | 4 | </div> |
5 | </template> | 5 | </template> |
6 | 6 |
1 | <template functional> | 1 | <template functional> |
2 | <div style="padding:30px;"> | 2 | <div style="padding:30px;"> |
3 | <el-alert :closable="false" title="menu 1-2-2" type="warning" /> | 3 | <el-alert :closable="false" title="menu 1-2-2" type="warning" /> |
4 | </div> | 4 | </div> |
5 | </template> | 5 | </template> |
6 | 6 |
1 | <template functional> | 1 | <template functional> |
2 | <div style="padding:30px;"> | 2 | <div style="padding:30px;"> |
3 | <el-alert :closable="false" title="menu 1-3" type="success" /> | 3 | <el-alert :closable="false" title="menu 1-3" type="success" /> |
4 | </div> | 4 | </div> |
5 | </template> | 5 | </template> |
6 | 6 |
1 | <template> | 1 | <template> |
2 | <div style="padding:30px;"> | 2 | <div style="padding:30px;"> |
3 | <el-alert :closable="false" title="menu 2" /> | 3 | <el-alert :closable="false" title="menu 2" /> |
4 | </div> | 4 | </div> |
5 | </template> | 5 | </template> |
6 | 6 |
src/views/pdf/content.js
File was created | 1 | const title = 'Plans for the Next Iteration of Vue.js' | |
2 | |||
3 | const content = `<p>Last week at<a href="https://vuejs.london/summary" rel="nofollow">Vue.js London</a>I gave a brief sneak peek of what’s coming in the next major version of Vue. This post provides an in-depth overview of the plan.</p> | ||
4 | <p><img class=" wscnph" src="https://wpimg.wallstcn.com/b8a1d7be-0b73-41b8-be8c-7c01c93cab66.png" data-wscntype="image" data-wscnh="742" data-wscnw="692" /></p> | ||
5 | <h3>Why a new majorversion?</h3> | ||
6 | <p>Vue 2.0 was released<a href="https://medium.com/the-vue-point/vue-2-0-is-here-ef1f26acf4b8" rel="nofollow">exactly two years ago</a>(how time flies!). During this period, the core has remained backwards compatible with five minor releases. We’ve accumulated a number of ideas that would bring improvements, but they were held off because they would result in breaking changes. At the same time, the JavaScript ecosystem and the language itself has been evolving rapidly. There are greatly improved tools that could enhance our workflow, and many new language features that could unlock simpler, more complete, and more efficient solutions to the problems Vue is trying to solve. What’s more exciting is that we are seeing ES2015 support becoming a baseline for all major evergreen browsers. Vue 3.0 aims to leverage these new language features to make Vue core smaller, faster, and more powerful.</p> | ||
7 | <p>Vue 3.0 is currently in prototyping phase, and we have already implemented a runtime close to feature-parity with 2.x.<strong>Many of the items listed below are either already implemented, or confirmed to be feasible. Ones that are not yet implemented or still in exploration phase are marked with a *.</strong></p> | ||
8 | <h3>The Details</h3> | ||
9 | <h4>High-Level APIChanges</h4> | ||
10 | <blockquote>TL;DR: Everything except render function API and scoped-slots syntax will either remain the same or can be made 2.x compatible via a compatibility build.</blockquote> | ||
11 | <p>Since it’s a new major, there is going to be some breaking changes. However, we take backwards compatibility seriously, so we want to start communicating these changes as soon as possible. Here’s the currently planned public API changes:</p> | ||
12 | <ul><li>Template syntax will remain 99% the same. There may be small tweaks in scoped slots syntax, but other than that we have no plans to change anything else for templates.</li><li>3.0 will support class-based components natively, with the aim to provide an API that is pleasant to use in native ES2015 without requiring any transpilation or stage-x features. Most current options will have a reasonable mapping in the class-based API. Stage-x features such as class fields and decorators can still be used optionally to enhance the authoring experience. In addition, the API is designed with TypeScript type inference in mind. The 3.x codebase will itself be written in TypeScript, and providing improved TypeScript support. (That said, usage of TypeScript in an application is still entirely optional.)</li><li>The 2.x object-based component format will still be supported by internally transforming the object to a corresponding class.</li><li>Mixins will still be supported.*</li><li>Top level APIs will likely receive an overhaul to avoid globally mutating the Vue runtime when installing plugins. Instead, plugins will be applied and scoped to a component tree. This will make it easier to test components that rely on specific plugins, and also make it possible to mount multiple Vue applications on the same page with different plugins, but using the same Vue runtime.*</li><li>Functional components can finally be plain functions —however, async components will now need to be explicitly created via a helper function.</li><li>The part that will receive the most changes is the Virtual DOM format used in render functions. We are currently collecting feedback from major library authors and will be sharing more details as we are more confident of the changes, but as long as you don’t heavily rely on hand-written (non-JSX) render functions in your app, upgrading should be a reasonably straightforward process.</li></ul> | ||
13 | <h4>Source Code Architecture</h4> | ||
14 | <blockquote>TL;DR: better decoupled internal modules, TypeScript, and a codebase that is easier to contribute to.</blockquote> | ||
15 | <p>We are re-writing 3.0 from the ground up for a cleaner and more maintainable architecture, in particular trying to make it easier to contribute to. We are breaking some internal functionalities into individual packages in order to isolate the scope of complexity. For example, the observer module will become its own package, with its own public API and tests. Note this does not affect framework-level API— you will not have to manually import individual bits from multiple packages in order to use Vue. Instead, the final Vue package is assembled using these internal packages.</p> | ||
16 | <p>The codebase is also now written in TypeScript. Although this will make proficiency in TypeScript a pre-requisite for contributing to the new codebase, we believe the type information and IDE support will actually make it easier for a new contributor to make meaningful contributions.</p> | ||
17 | <p>Decoupling the observer and scheduler into separate packages also allows us to easily experiment with alternative implementations of these parts. For example, we can implement an IE11 compatible observer implementation with the same API, or an alternative scheduler that leverages<code>requestIdleCallback</code>to yield to the browser during long updates.*</p> | ||
18 | <p><img class=" wscnph" src="https://wpimg.wallstcn.com/4d0b5fb2-d7f9-48fd-8f1b-03362b534dd9.png" data-wscntype="image" data-wscnh="716" data-wscnw="460" /></p> | ||
19 | <h4>Observation Mechanism</h4> | ||
20 | <blockquote>TL;DR: more complete, precise, efficient and debuggable reactivity tracking & API for creating observables.</blockquote> | ||
21 | <p>3.0 will ship with a Proxy-based observer implementation that provides reactivity tracking with full language coverage. This eliminates a number of limitations of Vue 2’s current implementation based on<code>Object.defineProperty</code>:</p> | ||
22 | <p>The new observer also features the following:</p> | ||
23 | <p>Easily understand why a component is re-rendering</p> | ||
24 | <p><img class=" wscnph" src="https://wpimg.wallstcn.com/a0c9d811-1ef9-4628-8976-f7c1aaa66da0.png" data-wscntype="image" data-wscnh="540" data-wscnw="789" /></p> | ||
25 | <h4>Other Runtime Improvements</h4> | ||
26 | <blockquote>TL;DR: smaller, faster, tree-shakable features, fragments & portals, custom renderer API.</blockquote> | ||
27 | <h4>Compiler Improvements*</h4> | ||
28 | <blockquote>TL;DR: tree-shaking friendly output, more AOT optimizations, parser with better error info and source map support.</blockquote> | ||
29 | <h4>IE11 Support*</h4> | ||
30 | <blockquote>TL;DR: it will be supported, but in a separate build with the same reactivity limitations of Vue 2.x.</blockquote> | ||
31 | <p>The new codebase currently targets evergreen browsers only and assumes baseline native ES2015 support. But alas, we know a lot of our users still need to support IE11 for the foreseeable future. Most of the ES2015 features used can be transpiled / polyfilled for IE11, with the exception for Proxies. Our plan is to implement an alternative observer with the same API, but using the good old ES5<code>Object.defineProperty</code>API. A separate build of Vue 3.x will be distributed using this observer implementation. However, this build will be subject to the same change detection caveats of Vue 2.x and thus not fully compatible with the “modern” build of 3.x. We are aware that this imposes some inconvenience for library authors as they will need to be aware of compatibility for two different builds, but we will make sure to provide clear guidelines on this when we reach that stage.</p> | ||
32 | <h3>How Do We GetThere</h3> | ||
33 | <p>First of all, although we are announcing it today, we do not have a definitive timeline yet. What we do know at the moment is the steps we will be taking to get there:</p> | ||
34 | <h4>1. Internal Feedback for the Runtime Prototype</h4> | ||
35 | <p>This is the phase we are in right now. Currently, we already have a working runtime prototype that includes the new observer, Virtual DOM and component implementation. We have invited a group of authors of influential community projects to provide feedback for the internal changes, and would like to make sure they are comfortable with the changes before moving forward. We want to ensure that important libraries in the ecosystem will be ready at the same time when we release 3.0, so that users relying on those projects can upgrade easily.</p> | ||
36 | <h4>2. Public Feedback viaRFCs</h4> | ||
37 | <p>Once we gain a certain level of confidence in the new design, for each breaking change we will be opening a dedicated RFC issue which includes:</p> | ||
38 | <p>We will anticipate public feedback from the wider community to help us consolidate these ideas.</p> | ||
39 | <h4>3. Introduce Compatible Features in 2.x &2.x-next</h4> | ||
40 | <p>We are not forgetting about 2.x! In fact, we plan to use 2.x to progressively accustom users to the new changes. We will be gradually introducing confirmed API changes into 2.x via opt-in adaptors, and 2.x-next will allow users to try out the new Proxy-based observer.</p> | ||
41 | <p>The last minor release in 2.x will become LTS and continue to receive bug and security fixes for 18 months when 3.0 is released.</p> | ||
42 | <h4>4. AlphaPhase</h4> | ||
43 | <p>Next, we will finish up the compiler and server-side rendering parts of 3.0 and start making alpha releases. These will mostly be for stability testing purposes in small greenfield apps.</p> | ||
44 | <h4>5. BetaPhase</h4> | ||
45 | <p>During beta phase, our main goal is updating support libraries and tools like Vue Router, Vuex, Vue CLI, Vue DevTools and make sure they work smoothly with the new core. We will also be working with major library authors from the community to help them get ready for 3.0.</p> | ||
46 | <h4>6. RCPhase</h4> | ||
47 | <p>Once we consider the API and codebase stable, we will enter RC phase with API freeze. During this phase we will also work on a “compat build”: a build of 3.0 that includes compatibility layers for 2.x API. This build will also ship with a flag you can turn on to emit deprecation warnings for 2.x API usage in your app. The compat build can be used as a guide to upgrade your app to 3.0.</p> | ||
48 | <h4>7. IE11build</h4> | ||
49 | <p>The last task before the final release will be the IE11 compatibility build as mentioned above.</p> | ||
50 | <h4>8. FinalRelease</h4> | ||
51 | <p>In all honesty, we don’t know when this will happen yet, but likely in 2019. Again, we care more about shipping something that is solid and stable rather than hitting specific dates. There is a lot of work to be done, but we are excited for what’s coming next!</p>` | ||
52 | |||
53 | const data = { | ||
54 | title, | ||
55 | content | ||
56 | } | ||
57 | |||
58 | export default data | ||
59 |
src/views/pdf/download.vue
File was created | 1 | <template> | |
2 | <div v-loading.fullscreen.lock="fullscreenLoading" class="main-article" element-loading-text="Efforts to generate PDF"> | ||
3 | <div class="article__heading"> | ||
4 | <div class="article__heading__title"> | ||
5 | {{ article.title }} | ||
6 | </div> | ||
7 | </div> | ||
8 | <div style="color: #ccc;"> | ||
9 | This article is from Evan You on <a target="_blank" href="https://medium.com/the-vue-point/plans-for-the-next-iteration-of-vue-js-777ffea6fabf">medium</a> | ||
10 | </div> | ||
11 | <div ref="content" class="node-article-content" v-html="article.content" /> | ||
12 | </div> | ||
13 | </template> | ||
14 | |||
15 | <script> | ||
16 | |||
17 | export default { | ||
18 | data() { | ||
19 | return { | ||
20 | article: '', | ||
21 | fullscreenLoading: true | ||
22 | } | ||
23 | }, | ||
24 | mounted() { | ||
25 | this.fetchData() | ||
26 | }, | ||
27 | methods: { | ||
28 | fetchData() { | ||
29 | import('./content.js').then(data => { | ||
30 | const { title } = data.default | ||
31 | document.title = title | ||
32 | this.article = data.default | ||
33 | setTimeout(() => { | ||
34 | this.fullscreenLoading = false | ||
35 | this.$nextTick(() => { | ||
36 | window.print() | ||
37 | }) | ||
38 | }, 3000) | ||
39 | }) | ||
40 | } | ||
41 | } | ||
42 | } | ||
43 | </script> | ||
44 | |||
45 | <style lang="scss"> | ||
46 | @mixin clearfix { | ||
47 | &:before { | ||
48 | display: table; | ||
49 | content: ''; | ||
50 | clear: both; | ||
51 | } | ||
52 | |||
53 | &:after { | ||
54 | display: table; | ||
55 | content: ''; | ||
56 | clear: both; | ||
57 | } | ||
58 | } | ||
59 | |||
60 | .main-article { | ||
61 | padding: 20px; | ||
62 | margin: 0 auto; | ||
63 | display: block; | ||
64 | width: 740px; | ||
65 | background: #fff; | ||
66 | } | ||
67 | |||
68 | .article__heading { | ||
69 | position: relative; | ||
70 | padding: 0 0 20px; | ||
71 | overflow: hidden; | ||
72 | } | ||
73 | |||
74 | .article__heading__title { | ||
75 | display: block; | ||
76 | display: -webkit-box; | ||
77 | -webkit-box-orient: vertical; | ||
78 | -webkit-line-clamp: 2; | ||
79 | line-clamp: 2; | ||
80 | word-wrap: break-word; | ||
81 | overflow-wrap: break-word; | ||
82 | font-size: 32px; | ||
83 | line-height: 48px; | ||
84 | font-weight: 600; | ||
85 | color: #333; | ||
86 | overflow: hidden; | ||
87 | } | ||
88 | |||
89 | .node-article-content { | ||
90 | margin: 20px 0 0; | ||
91 | @include clearfix; | ||
92 | font-size: 16px; | ||
93 | color: #333; | ||
94 | letter-spacing: 0.5px; | ||
95 | line-height: 28px; | ||
96 | margin-bottom: 30px; | ||
97 | font-family: medium-content-serif-font, Georgia, Cambria, "Times New Roman", Times, serif; | ||
98 | |||
99 | &> :last-child { | ||
100 | margin-bottom: 0; | ||
101 | } | ||
102 | |||
103 | b, | ||
104 | strong { | ||
105 | font-weight: inherit; | ||
106 | font-weight: bolder; | ||
107 | } | ||
108 | |||
109 | img { | ||
110 | max-width: 100%; | ||
111 | display: block; | ||
112 | margin: 0 auto; | ||
113 | } | ||
114 | |||
115 | p { | ||
116 | font-weight: 400; | ||
117 | font-style: normal; | ||
118 | font-size: 21px; | ||
119 | line-height: 1.58; | ||
120 | letter-spacing: -.003em; | ||
121 | |||
122 | } | ||
123 | |||
124 | ul { | ||
125 | margin-bottom: 30px; | ||
126 | } | ||
127 | |||
128 | li { | ||
129 | --x-height-multiplier: 0.375; | ||
130 | --baseline-multiplier: 0.17; | ||
131 | |||
132 | letter-spacing: .01rem; | ||
133 | font-weight: 400; | ||
134 | font-style: normal; | ||
135 | font-size: 21px; | ||
136 | line-height: 1.58; | ||
137 | letter-spacing: -.003em; | ||
138 | margin-left: 30px; | ||
139 | margin-bottom: 14px; | ||
140 | } | ||
141 | |||
142 | a { | ||
143 | text-decoration: none; | ||
144 | background-repeat: repeat-x; | ||
145 | background-image: linear-gradient(to right, rgba(0, 0, 0, .84) 100%, rgba(0, 0, 0, 0) 0); | ||
146 | background-size: 1px 1px; | ||
147 | background-position: 0 calc(1em + 1px); | ||
148 | padding: 0 6px; | ||
149 | } | ||
150 | |||
151 | code { | ||
152 | background: rgba(0, 0, 0, .05); | ||
153 | padding: 3px 4px; | ||
154 | margin: 0 2px; | ||
155 | font-size: 16px; | ||
156 | display: inline-block; | ||
157 | } | ||
158 | |||
159 | img { | ||
160 | border: 0; | ||
161 | } | ||
162 | |||
163 | /* 解决 IE6-7 图片缩放锯齿问题 */ | ||
164 | img { | ||
165 | -ms-interpolation-mode: bicubic; | ||
166 | } | ||
167 | |||
168 | blockquote { | ||
169 | --x-height-multiplier: 0.375; | ||
170 | --baseline-multiplier: 0.17; | ||
171 | font-family: medium-content-serif-font, Georgia, Cambria, "Times New Roman", Times, serif; | ||
172 | letter-spacing: .01rem; | ||
173 | font-weight: 400; | ||
174 | font-style: italic; | ||
175 | font-size: 21px; | ||
176 | line-height: 1.58; | ||
177 | letter-spacing: -.003em; | ||
178 | border-left: 3px solid rgba(0, 0, 0, .84); | ||
179 | padding-left: 20px; | ||
180 | margin-left: -23px; | ||
181 | padding-bottom: 2px; | ||
182 | } | ||
183 | |||
184 | a { | ||
185 | text-decoration: none; | ||
186 | } | ||
187 | |||
188 | h2, | ||
189 | h3, | ||
190 | h4 { | ||
191 | font-size: 34px; | ||
192 | line-height: 1.15; | ||
193 | letter-spacing: -.015em; | ||
194 | margin: 53px 0 0; | ||
195 | } | ||
196 | |||
197 | h4 { | ||
198 | font-size: 26px; | ||
199 | } | ||
200 | } | ||
201 | </style> | ||
202 |
src/views/pdf/index.vue
File was created | 1 | <template> | |
2 | <div class="app-container"> | ||
3 | <aside style="margin-top:15px;">{{ $t('pdf.tips') }}</aside> | ||
4 | <router-link target="_blank" to="/pdf/download"> | ||
5 | <el-button type="primary"> | ||
6 | Click to download PDF | ||
7 | </el-button> | ||
8 | </router-link> | ||
9 | </div> | ||
10 | </template> | ||
11 | |||
12 |
src/views/permission/components/SwitchRoles.vue
File was created | 1 | <template> | |
2 | <div> | ||
3 | <div style="margin-bottom:15px;"> | ||
4 | {{ $t('permission.roles') }}: {{ roles }} | ||
5 | </div> | ||
6 | {{ $t('permission.switchRoles') }}: | ||
7 | <el-radio-group v-model="switchRoles"> | ||
8 | <el-radio-button label="editor" /> | ||
9 | <el-radio-button label="admin" /> | ||
10 | </el-radio-group> | ||
11 | </div> | ||
12 | </template> | ||
13 | |||
14 | <script> | ||
15 | export default { | ||
16 | computed: { | ||
17 | roles() { | ||
18 | return this.$store.getters.roles | ||
19 | }, | ||
20 | switchRoles: { | ||
21 | get() { | ||
22 | return this.roles[0] | ||
23 | }, | ||
24 | set(val) { | ||
25 | this.$store.dispatch('user/changeRoles', val).then(() => { | ||
26 | this.$emit('change') | ||
27 | }) | ||
28 | } | ||
29 | } | ||
30 | } | ||
31 | } | ||
32 | </script> | ||
33 |
src/views/permission/directive.vue
File was created | 1 | <template> | |
2 | <div class="app-container"> | ||
3 | <switch-roles @change="handleRolesChange" /> | ||
4 | <div :key="key" style="margin-top:30px;"> | ||
5 | <div> | ||
6 | <span v-permission="['admin']" class="permission-alert"> | ||
7 | Only | ||
8 | <el-tag class="permission-tag" size="small">admin</el-tag> can see this | ||
9 | </span> | ||
10 | <el-tag v-permission="['admin']" class="permission-sourceCode" type="info"> | ||
11 | v-permission="['admin']" | ||
12 | </el-tag> | ||
13 | </div> | ||
14 | |||
15 | <div> | ||
16 | <span v-permission="['editor']" class="permission-alert"> | ||
17 | Only | ||
18 | <el-tag class="permission-tag" size="small">editor</el-tag> can see this | ||
19 | </span> | ||
20 | <el-tag v-permission="['editor']" class="permission-sourceCode" type="info"> | ||
21 | v-permission="['editor']" | ||
22 | </el-tag> | ||
23 | </div> | ||
24 | |||
25 | <div> | ||
26 | <span v-permission="['admin','editor']" class="permission-alert"> | ||
27 | Both | ||
28 | <el-tag class="permission-tag" size="small">admin</el-tag> and | ||
29 | <el-tag class="permission-tag" size="small">editor</el-tag> can see this | ||
30 | </span> | ||
31 | <el-tag v-permission="['admin','editor']" class="permission-sourceCode" type="info"> | ||
32 | v-permission="['admin','editor']" | ||
33 | </el-tag> | ||
34 | </div> | ||
35 | </div> | ||
36 | |||
37 | <div :key="'checkPermission'+key" style="margin-top:60px;"> | ||
38 | <aside> | ||
39 | {{ $t('permission.tips') }} | ||
40 | <br> e.g. | ||
41 | </aside> | ||
42 | |||
43 | <el-tabs type="border-card" style="width:550px;"> | ||
44 | <el-tab-pane v-if="checkPermission(['admin'])" label="Admin"> | ||
45 | Admin can see this | ||
46 | <el-tag class="permission-sourceCode" type="info"> | ||
47 | v-if="checkPermission(['admin'])" | ||
48 | </el-tag> | ||
49 | </el-tab-pane> | ||
50 | |||
51 | <el-tab-pane v-if="checkPermission(['editor'])" label="Editor"> | ||
52 | Editor can see this | ||
53 | <el-tag class="permission-sourceCode" type="info"> | ||
54 | v-if="checkPermission(['editor'])" | ||
55 | </el-tag> | ||
56 | </el-tab-pane> | ||
57 | |||
58 | <el-tab-pane v-if="checkPermission(['admin','editor'])" label="Admin-OR-Editor"> | ||
59 | Both admin or editor can see this | ||
60 | <el-tag class="permission-sourceCode" type="info"> | ||
61 | v-if="checkPermission(['admin','editor'])" | ||
62 | </el-tag> | ||
63 | </el-tab-pane> | ||
64 | </el-tabs> | ||
65 | </div> | ||
66 | </div> | ||
67 | </template> | ||
68 | |||
69 | <script> | ||
70 | import permission from '@/directive/permission/index.js' // 权限判断指令 | ||
71 | import checkPermission from '@/utils/permission' // 权限判断函数 | ||
72 | import SwitchRoles from './components/SwitchRoles' | ||
73 | |||
74 | export default { | ||
75 | name: 'DirectivePermission', | ||
76 | components: { SwitchRoles }, | ||
77 | directives: { permission }, | ||
78 | data() { | ||
79 | return { | ||
80 | key: 1 // 为了能每次切换权限的时候重新初始化指令 | ||
81 | } | ||
82 | }, | ||
83 | methods: { | ||
84 | checkPermission, | ||
85 | handleRolesChange() { | ||
86 | this.key++ | ||
87 | } | ||
88 | } | ||
89 | } | ||
90 | </script> | ||
91 | |||
92 | <style lang="scss" scoped> | ||
93 | .app-container { | ||
94 | /deep/ .permission-alert { | ||
95 | width: 320px; | ||
96 | margin-top: 15px; | ||
97 | background-color: #f0f9eb; | ||
98 | color: #67c23a; | ||
99 | padding: 8px 16px; | ||
100 | border-radius: 4px; | ||
101 | display: inline-block; | ||
102 | } | ||
103 | /deep/ .permission-sourceCode { | ||
104 | margin-left: 15px; | ||
105 | } | ||
106 | /deep/ .permission-tag { | ||
107 | background-color: #ecf5ff; | ||
108 | } | ||
109 | } | ||
110 | </style> | ||
111 | |||
112 |
src/views/permission/page.vue
File was created | 1 | <template> | |
2 | <div class="app-container"> | ||
3 | <switch-roles @change="handleRolesChange" /> | ||
4 | </div> | ||
5 | </template> | ||
6 | |||
7 | <script> | ||
8 | import SwitchRoles from './components/SwitchRoles' | ||
9 | |||
10 | export default { | ||
11 | name: 'PagePermission', | ||
12 | components: { SwitchRoles }, | ||
13 | methods: { | ||
14 | handleRolesChange() { | ||
15 | this.$router.push({ path: '/permission/index?' + +new Date() }) | ||
16 | } | ||
17 | } | ||
18 | } | ||
19 | </script> | ||
20 |
src/views/permission/role.vue
File was created | 1 | <template> | |
2 | <div class="app-container"> | ||
3 | <el-button type="primary" @click="handleAddRole"> | ||
4 | {{ $t('permission.addRole') }} | ||
5 | </el-button> | ||
6 | |||
7 | <el-table :data="rolesList" style="width: 100%;margin-top:30px;" border> | ||
8 | <el-table-column align="center" label="Role Key" width="220"> | ||
9 | <template slot-scope="scope"> | ||
10 | {{ scope.row.key }} | ||
11 | </template> | ||
12 | </el-table-column> | ||
13 | <el-table-column align="center" label="Role Name" width="220"> | ||
14 | <template slot-scope="scope"> | ||
15 | {{ scope.row.name }} | ||
16 | </template> | ||
17 | </el-table-column> | ||
18 | <el-table-column align="header-center" label="Description"> | ||
19 | <template slot-scope="scope"> | ||
20 | {{ scope.row.description }} | ||
21 | </template> | ||
22 | </el-table-column> | ||
23 | <el-table-column align="center" label="Operations"> | ||
24 | <template slot-scope="scope"> | ||
25 | <el-button type="primary" size="small" @click="handleEdit(scope)"> | ||
26 | {{ $t('permission.editPermission') }} | ||
27 | </el-button> | ||
28 | <el-button type="danger" size="small" @click="handleDelete(scope)"> | ||
29 | {{ $t('permission.delete') }} | ||
30 | </el-button> | ||
31 | </template> | ||
32 | </el-table-column> | ||
33 | </el-table> | ||
34 | |||
35 | <el-dialog :visible.sync="dialogVisible" :title="dialogType==='edit'?'Edit Role':'New Role'"> | ||
36 | <el-form :model="role" label-width="80px" label-position="left"> | ||
37 | <el-form-item label="Name"> | ||
38 | <el-input v-model="role.name" placeholder="Role Name" /> | ||
39 | </el-form-item> | ||
40 | <el-form-item label="Desc"> | ||
41 | <el-input | ||
42 | v-model="role.description" | ||
43 | :autosize="{ minRows: 2, maxRows: 4}" | ||
44 | type="textarea" | ||
45 | placeholder="Role Description" | ||
46 | /> | ||
47 | </el-form-item> | ||
48 | <el-form-item label="Menus"> | ||
49 | <el-tree ref="tree" :check-strictly="checkStrictly" :data="routesData" :props="defaultProps" show-checkbox node-key="path" class="permission-tree" /> | ||
50 | </el-form-item> | ||
51 | </el-form> | ||
52 | <div style="text-align:right;"> | ||
53 | <el-button type="danger" @click="dialogVisible=false"> | ||
54 | {{ $t('permission.cancel') }} | ||
55 | </el-button> | ||
56 | <el-button type="primary" @click="confirmRole"> | ||
57 | {{ $t('permission.confirm') }} | ||
58 | </el-button> | ||
59 | </div> | ||
60 | </el-dialog> | ||
61 | </div> | ||
62 | </template> | ||
63 | |||
64 | <script> | ||
65 | import path from 'path' | ||
66 | import { deepClone } from '@/utils' | ||
67 | import { getRoutes, getRoles, addRole, deleteRole, updateRole } from '@/api/role' | ||
68 | import i18n from '@/lang' | ||
69 | |||
70 | const defaultRole = { | ||
71 | key: '', | ||
72 | name: '', | ||
73 | description: '', | ||
74 | routes: [] | ||
75 | } | ||
76 | |||
77 | export default { | ||
78 | data() { | ||
79 | return { | ||
80 | role: Object.assign({}, defaultRole), | ||
81 | routes: [], | ||
82 | rolesList: [], | ||
83 | dialogVisible: false, | ||
84 | dialogType: 'new', | ||
85 | checkStrictly: false, | ||
86 | defaultProps: { | ||
87 | children: 'children', | ||
88 | label: 'title' | ||
89 | } | ||
90 | } | ||
91 | }, | ||
92 | computed: { | ||
93 | routesData() { | ||
94 | return this.routes | ||
95 | } | ||
96 | }, | ||
97 | created() { | ||
98 | // Mock: get all routes and roles list from server | ||
99 | this.getRoutes() | ||
100 | this.getRoles() | ||
101 | }, | ||
102 | methods: { | ||
103 | async getRoutes() { | ||
104 | const res = await getRoutes() | ||
105 | this.serviceRoutes = res.data | ||
106 | const routes = this.generateRoutes(res.data) | ||
107 | this.routes = this.i18n(routes) | ||
108 | }, | ||
109 | async getRoles() { | ||
110 | const res = await getRoles() | ||
111 | this.rolesList = res.data | ||
112 | }, | ||
113 | i18n(routes) { | ||
114 | const app = routes.map(route => { | ||
115 | route.title = i18n.t(`route.${route.title}`) | ||
116 | if (route.children) { | ||
117 | route.children = this.i18n(route.children) | ||
118 | } | ||
119 | return route | ||
120 | }) | ||
121 | return app | ||
122 | }, | ||
123 | // Reshape the routes structure so that it looks the same as the sidebar | ||
124 | generateRoutes(routes, basePath = '/') { | ||
125 | const res = [] | ||
126 | |||
127 | for (let route of routes) { | ||
128 | // skip some route | ||
129 | if (route.hidden) { continue } | ||
130 | |||
131 | const onlyOneShowingChild = this.onlyOneShowingChild(route.children, route) | ||
132 | |||
133 | if (route.children && onlyOneShowingChild && !route.alwaysShow) { | ||
134 | route = onlyOneShowingChild | ||
135 | } | ||
136 | |||
137 | const data = { | ||
138 | path: path.resolve(basePath, route.path), | ||
139 | title: route.meta && route.meta.title | ||
140 | |||
141 | } | ||
142 | |||
143 | // recursive child routes | ||
144 | if (route.children) { | ||
145 | data.children = this.generateRoutes(route.children, data.path) | ||
146 | } | ||
147 | res.push(data) | ||
148 | } | ||
149 | return res | ||
150 | }, | ||
151 | generateArr(routes) { | ||
152 | let data = [] | ||
153 | routes.forEach(route => { | ||
154 | data.push(route) | ||
155 | if (route.children) { | ||
156 | const temp = this.generateArr(route.children) | ||
157 | if (temp.length > 0) { | ||
158 | data = [...data, ...temp] | ||
159 | } | ||
160 | } | ||
161 | }) | ||
162 | return data | ||
163 | }, | ||
164 | handleAddRole() { | ||
165 | this.role = Object.assign({}, defaultRole) | ||
166 | if (this.$refs.tree) { | ||
167 | this.$refs.tree.setCheckedNodes([]) | ||
168 | } | ||
169 | this.dialogType = 'new' | ||
170 | this.dialogVisible = true | ||
171 | }, | ||
172 | handleEdit(scope) { | ||
173 | this.dialogType = 'edit' | ||
174 | this.dialogVisible = true | ||
175 | this.checkStrictly = true | ||
176 | this.role = deepClone(scope.row) | ||
177 | this.$nextTick(() => { | ||
178 | const routes = this.generateRoutes(this.role.routes) | ||
179 | this.$refs.tree.setCheckedNodes(this.generateArr(routes)) | ||
180 | // set checked state of a node not affects its father and child nodes | ||
181 | this.checkStrictly = false | ||
182 | }) | ||
183 | }, | ||
184 | handleDelete({ $index, row }) { | ||
185 | this.$confirm('Confirm to remove the role?', 'Warning', { | ||
186 | confirmButtonText: 'Confirm', | ||
187 | cancelButtonText: 'Cancel', | ||
188 | type: 'warning' | ||
189 | }) | ||
190 | .then(async() => { | ||
191 | await deleteRole(row.key) | ||
192 | this.rolesList.splice($index, 1) | ||
193 | this.$message({ | ||
194 | type: 'success', | ||
195 | message: 'Delete succed!' | ||
196 | }) | ||
197 | }) | ||
198 | .catch(err => { console.error(err) }) | ||
199 | }, | ||
200 | generateTree(routes, basePath = '/', checkedKeys) { | ||
201 | const res = [] | ||
202 | |||
203 | for (const route of routes) { | ||
204 | const routePath = path.resolve(basePath, route.path) | ||
205 | |||
206 | // recursive child routes | ||
207 | if (route.children) { | ||
208 | route.children = this.generateTree(route.children, routePath, checkedKeys) | ||
209 | } | ||
210 | |||
211 | if (checkedKeys.includes(routePath) || (route.children && route.children.length >= 1)) { | ||
212 | res.push(route) | ||
213 | } | ||
214 | } | ||
215 | return res | ||
216 | }, | ||
217 | async confirmRole() { | ||
218 | const isEdit = this.dialogType === 'edit' | ||
219 | |||
220 | const checkedKeys = this.$refs.tree.getCheckedKeys() | ||
221 | this.role.routes = this.generateTree(deepClone(this.serviceRoutes), '/', checkedKeys) | ||
222 | |||
223 | if (isEdit) { | ||
224 | await updateRole(this.role.key, this.role) | ||
225 | for (let index = 0; index < this.rolesList.length; index++) { | ||
226 | if (this.rolesList[index].key === this.role.key) { | ||
227 | this.rolesList.splice(index, 1, Object.assign({}, this.role)) | ||
228 | break | ||
229 | } | ||
230 | } | ||
231 | } else { | ||
232 | const { data } = await addRole(this.role) | ||
233 | this.role.key = data.key | ||
234 | this.rolesList.push(this.role) | ||
235 | } | ||
236 | |||
237 | const { description, key, name } = this.role | ||
238 | this.dialogVisible = false | ||
239 | this.$notify({ | ||
240 | title: 'Success', | ||
241 | dangerouslyUseHTMLString: true, | ||
242 | message: ` | ||
243 | <div>Role Key: ${key}</div> | ||
244 | <div>Role Name: ${name}</div> | ||
245 | <div>Description: ${description}</div> | ||
246 | `, | ||
247 | type: 'success' | ||
248 | }) | ||
249 | }, | ||
250 | // reference: src/view/layout/components/Sidebar/SidebarItem.vue | ||
251 | onlyOneShowingChild(children = [], parent) { | ||
252 | let onlyOneChild = null | ||
253 | const showingChildren = children.filter(item => !item.hidden) | ||
254 | |||
255 | // When there is only one child route, the child route is displayed by default | ||
256 | if (showingChildren.length === 1) { | ||
257 | onlyOneChild = showingChildren[0] | ||
258 | onlyOneChild.path = path.resolve(parent.path, onlyOneChild.path) | ||
259 | return onlyOneChild | ||
260 | } | ||
261 | |||
262 | // Show parent if there are no child route to display | ||
263 | if (showingChildren.length === 0) { | ||
264 | onlyOneChild = { ... parent, path: '', noShowingChildren: true } | ||
265 | return onlyOneChild | ||
266 | } | ||
267 | |||
268 | return false | ||
269 | } | ||
270 | } | ||
271 | } | ||
272 | </script> | ||
273 | |||
274 | <style lang="scss" scoped> | ||
275 | .app-container { | ||
276 | .roles-table { | ||
277 | margin-top: 30px; | ||
278 | } | ||
279 | .permission-tree { | ||
280 | margin-bottom: 30px; | ||
281 | } | ||
282 | } | ||
283 | </style> | ||
284 |
src/views/profile/components/Account.vue
File was created | 1 | <template> | |
2 | <el-form> | ||
3 | <el-form-item label="Name"> | ||
4 | <el-input v-model.trim="user.name" /> | ||
5 | </el-form-item> | ||
6 | <el-form-item label="Email"> | ||
7 | <el-input v-model.trim="user.email" /> | ||
8 | </el-form-item> | ||
9 | <el-form-item> | ||
10 | <el-button type="primary" @click="submit">Update</el-button> | ||
11 | </el-form-item> | ||
12 | </el-form> | ||
13 | </template> | ||
14 | |||
15 | <script> | ||
16 | export default { | ||
17 | props: { | ||
18 | user: { | ||
19 | type: Object, | ||
20 | default: () => { | ||
21 | return { | ||
22 | name: '', | ||
23 | email: '' | ||
24 | } | ||
25 | } | ||
26 | } | ||
27 | }, | ||
28 | methods: { | ||
29 | submit() { | ||
30 | this.$message({ | ||
31 | message: 'User information has been updated successfully', | ||
32 | type: 'success', | ||
33 | duration: 5 * 1000 | ||
34 | }) | ||
35 | } | ||
36 | } | ||
37 | } | ||
38 | </script> | ||
39 |
src/views/profile/components/Activity.vue
File was created | 1 | <template> | |
2 | <div class="user-activity"> | ||
3 | <div class="post"> | ||
4 | <div class="user-block"> | ||
5 | <img class="img-circle" :src="'https://wpimg.wallstcn.com/57ed425a-c71e-4201-9428-68760c0537c4.jpg'+avatarPrefix"> | ||
6 | <span class="username text-muted">Iron Man</span> | ||
7 | <span class="description">Shared publicly - 7:30 PM today</span> | ||
8 | </div> | ||
9 | <p> | ||
10 | Lorem ipsum represents a long-held tradition for designers, | ||
11 | typographers and the like. Some people hate it and argue for | ||
12 | its demise, but others ignore the hate as they create awesome | ||
13 | tools to help create filler text for everyone from bacon lovers | ||
14 | to Charlie Sheen fans. | ||
15 | </p> | ||
16 | <ul class="list-inline"> | ||
17 | <li> | ||
18 | <span class="link-black text-sm"> | ||
19 | <i class="el-icon-share" /> | ||
20 | Share | ||
21 | </span> | ||
22 | </li> | ||
23 | <li> | ||
24 | <span class="link-black text-sm"> | ||
25 | <svg-icon icon-class="like" /> | ||
26 | Like | ||
27 | </span> | ||
28 | </li> | ||
29 | </ul> | ||
30 | </div> | ||
31 | <div class="post"> | ||
32 | <div class="user-block"> | ||
33 | <img class="img-circle" :src="'https://wpimg.wallstcn.com/9e2a5d0a-bd5b-457f-ac8e-86554616c87b.jpg'+avatarPrefix"> | ||
34 | <span class="username text-muted">Captain American</span> | ||
35 | <span class="description">Sent you a message - yesterday</span> | ||
36 | </div> | ||
37 | <p> | ||
38 | Lorem ipsum represents a long-held tradition for designers, | ||
39 | typographers and the like. Some people hate it and argue for | ||
40 | its demise, but others ignore the hate as they create awesome | ||
41 | tools to help create filler text for everyone from bacon lovers | ||
42 | to Charlie Sheen fans. | ||
43 | </p> | ||
44 | <ul class="list-inline"> | ||
45 | <li> | ||
46 | <span class="link-black text-sm"> | ||
47 | <i class="el-icon-share" /> | ||
48 | Share | ||
49 | </span> | ||
50 | </li> | ||
51 | <li> | ||
52 | <span class="link-black text-sm"> | ||
53 | <svg-icon icon-class="like" /> | ||
54 | Like | ||
55 | </span> | ||
56 | </li> | ||
57 | </ul> | ||
58 | </div> | ||
59 | <div class="post"> | ||
60 | <div class="user-block"> | ||
61 | <img class="img-circle" :src="'https://wpimg.wallstcn.com/fb57f689-e1ab-443c-af12-8d4066e202e2.jpg'+avatarPrefix"> | ||
62 | <span class="username">Spider Man</span> | ||
63 | <span class="description">Posted 4 photos - 2 days ago</span> | ||
64 | </div> | ||
65 | <div class="user-images"> | ||
66 | <el-carousel :interval="6000" type="card" height="220px"> | ||
67 | <el-carousel-item v-for="item in carouselImages" :key="item"> | ||
68 | <img :src="item+carouselPrefix" class="image"> | ||
69 | </el-carousel-item> | ||
70 | </el-carousel> | ||
71 | </div> | ||
72 | <ul class="list-inline"> | ||
73 | <li><span class="link-black text-sm"><i class="el-icon-share" /> Share</span></li> | ||
74 | <li> | ||
75 | <span class="link-black text-sm"> | ||
76 | <svg-icon icon-class="like" /> Like</span> | ||
77 | </li> | ||
78 | </ul> | ||
79 | </div> | ||
80 | </div> | ||
81 | </template> | ||
82 | |||
83 | <script> | ||
84 | const avatarPrefix = '?imageView2/1/w/80/h/80' | ||
85 | const carouselPrefix = '?imageView2/2/h/440' | ||
86 | |||
87 | export default { | ||
88 | data() { | ||
89 | return { | ||
90 | carouselImages: [ | ||
91 | 'https://wpimg.wallstcn.com/9679ffb0-9e0b-4451-9916-e21992218054.jpg', | ||
92 | 'https://wpimg.wallstcn.com/bcce3734-0837-4b9f-9261-351ef384f75a.jpg', | ||
93 | 'https://wpimg.wallstcn.com/d1d7b033-d75e-4cd6-ae39-fcd5f1c0a7c5.jpg', | ||
94 | 'https://wpimg.wallstcn.com/50530061-851b-4ca5-9dc5-2fead928a939.jpg' | ||
95 | ], | ||
96 | avatarPrefix, | ||
97 | carouselPrefix | ||
98 | } | ||
99 | } | ||
100 | } | ||
101 | </script> | ||
102 | |||
103 | <style lang="scss" scoped> | ||
104 | .user-activity { | ||
105 | .user-block { | ||
106 | |||
107 | .username, | ||
108 | .description { | ||
109 | display: block; | ||
110 | margin-left: 50px; | ||
111 | padding: 2px 0; | ||
112 | } | ||
113 | |||
114 | .username{ | ||
115 | font-size: 16px; | ||
116 | color: #000; | ||
117 | } | ||
118 | |||
119 | :after { | ||
120 | clear: both; | ||
121 | } | ||
122 | |||
123 | .img-circle { | ||
124 | border-radius: 50%; | ||
125 | width: 40px; | ||
126 | height: 40px; | ||
127 | float: left; | ||
128 | } | ||
129 | |||
130 | span { | ||
131 | font-weight: 500; | ||
132 | font-size: 12px; | ||
133 | } | ||
134 | } | ||
135 | |||
136 | .post { | ||
137 | font-size: 14px; | ||
138 | border-bottom: 1px solid #d2d6de; | ||
139 | margin-bottom: 15px; | ||
140 | padding-bottom: 15px; | ||
141 | color: #666; | ||
142 | |||
143 | .image { | ||
144 | width: 100%; | ||
145 | height: 100%; | ||
146 | |||
147 | } | ||
148 | |||
149 | .user-images { | ||
150 | padding-top: 20px; | ||
151 | } | ||
152 | } | ||
153 | |||
154 | .list-inline { | ||
155 | padding-left: 0; | ||
156 | margin-left: -5px; | ||
157 | list-style: none; | ||
158 | |||
159 | li { | ||
160 | display: inline-block; | ||
161 | padding-right: 5px; | ||
162 | padding-left: 5px; | ||
163 | font-size: 13px; | ||
164 | } | ||
165 | |||
166 | .link-black { | ||
167 | |||
168 | &:hover, | ||
169 | &:focus { | ||
170 | color: #999; | ||
171 | } | ||
172 | } | ||
173 | } | ||
174 | |||
175 | } | ||
176 | |||
177 | .box-center { | ||
178 | margin: 0 auto; | ||
179 | display: table; | ||
180 | } | ||
181 | |||
182 | .text-muted { | ||
183 | color: #777; | ||
184 | } | ||
185 | </style> | ||
186 |
src/views/profile/components/Timeline.vue
File was created | 1 | <template> | |
2 | <div class="block"> | ||
3 | <el-timeline> | ||
4 | <el-timeline-item v-for="(item,index) of timeline" :key="index" :timestamp="item.timestamp" placement="top"> | ||
5 | <el-card> | ||
6 | <h4>{{ item.title }}</h4> | ||
7 | <p>{{ item.content }}</p> | ||
8 | </el-card> | ||
9 | </el-timeline-item> | ||
10 | </el-timeline> | ||
11 | </div> | ||
12 | </template> | ||
13 | |||
14 | <script> | ||
15 | export default { | ||
16 | data() { | ||
17 | return { | ||
18 | timeline: [ | ||
19 | { | ||
20 | timestamp: '2019/4/20', | ||
21 | title: 'Update Github template', | ||
22 | content: 'PanJiaChen committed 2019/4/20 20:46' | ||
23 | }, | ||
24 | { | ||
25 | timestamp: '2019/4/21', | ||
26 | title: 'Update Github template', | ||
27 | content: 'PanJiaChen committed 2019/4/21 20:46' | ||
28 | }, | ||
29 | { | ||
30 | timestamp: '2019/4/22', | ||
31 | title: 'Build Template', | ||
32 | content: 'PanJiaChen committed 2019/4/22 20:46' | ||
33 | }, | ||
34 | { | ||
35 | timestamp: '2019/4/23', | ||
36 | title: 'Release New Version', | ||
37 | content: 'PanJiaChen committed 2019/4/23 20:46' | ||
38 | } | ||
39 | ] | ||
40 | } | ||
41 | } | ||
42 | } | ||
43 | </script> | ||
44 |
src/views/profile/components/UserCard.vue
File was created | 1 | <template> | |
2 | <el-card style="margin-bottom:20px;"> | ||
3 | <div slot="header" class="clearfix"> | ||
4 | <span>About me</span> | ||
5 | </div> | ||
6 | |||
7 | <div class="user-profile"> | ||
8 | <div class="box-center"> | ||
9 | <pan-thumb :image="user.avatar" :height="'100px'" :width="'100px'" :hoverable="false"> | ||
10 | <div>Hello</div> | ||
11 | {{ user.role }} | ||
12 | </pan-thumb> | ||
13 | </div> | ||
14 | <div class="box-center"> | ||
15 | <div class="user-name text-center">{{ user.name }}</div> | ||
16 | <div class="user-role text-center text-muted">{{ user.role | uppercaseFirst }}</div> | ||
17 | </div> | ||
18 | </div> | ||
19 | |||
20 | <div class="user-bio"> | ||
21 | <div class="user-education user-bio-section"> | ||
22 | <div class="user-bio-section-header"><svg-icon icon-class="education" /><span>Education</span></div> | ||
23 | <div class="user-bio-section-body"> | ||
24 | <div class="text-muted"> | ||
25 | JS in Computer Science from the University of Technology | ||
26 | </div> | ||
27 | </div> | ||
28 | </div> | ||
29 | |||
30 | <div class="user-skills user-bio-section"> | ||
31 | <div class="user-bio-section-header"><svg-icon icon-class="skill" /><span>Skills</span></div> | ||
32 | <div class="user-bio-section-body"> | ||
33 | <div class="progress-item"> | ||
34 | <span>Vue</span> | ||
35 | <el-progress :percentage="70" /> | ||
36 | </div> | ||
37 | <div class="progress-item"> | ||
38 | <span>JavaScript</span> | ||
39 | <el-progress :percentage="18" /> | ||
40 | </div> | ||
41 | <div class="progress-item"> | ||
42 | <span>Css</span> | ||
43 | <el-progress :percentage="12" /> | ||
44 | </div> | ||
45 | <div class="progress-item"> | ||
46 | <span>ESLint</span> | ||
47 | <el-progress :percentage="100" status="success" /> | ||
48 | </div> | ||
49 | </div> | ||
50 | </div> | ||
51 | </div> | ||
52 | </el-card> | ||
53 | </template> | ||
54 | |||
55 | <script> | ||
56 | import PanThumb from '@/components/PanThumb' | ||
57 | |||
58 | export default { | ||
59 | components: { PanThumb }, | ||
60 | props: { | ||
61 | user: { | ||
62 | type: Object, | ||
63 | default: () => { | ||
64 | return { | ||
65 | name: '', | ||
66 | email: '', | ||
67 | avatar: '', | ||
68 | roles: '' | ||
69 | } | ||
70 | } | ||
71 | } | ||
72 | } | ||
73 | } | ||
74 | </script> | ||
75 | |||
76 | <style lang="scss" scoped> | ||
77 | .box-center { | ||
78 | margin: 0 auto; | ||
79 | display: table; | ||
80 | } | ||
81 | |||
82 | .text-muted { | ||
83 | color: #777; | ||
84 | } | ||
85 | |||
86 | .user-profile { | ||
87 | .user-name { | ||
88 | font-weight: bold; | ||
89 | } | ||
90 | |||
91 | .box-center { | ||
92 | padding-top: 10px; | ||
93 | } | ||
94 | |||
95 | .user-role { | ||
96 | padding-top: 10px; | ||
97 | font-weight: 400; | ||
98 | font-size: 14px; | ||
99 | } | ||
100 | |||
101 | .box-social { | ||
102 | padding-top: 30px; | ||
103 | |||
104 | .el-table { | ||
105 | border-top: 1px solid #dfe6ec; | ||
106 | } | ||
107 | } | ||
108 | |||
109 | .user-follow { | ||
110 | padding-top: 20px; | ||
111 | } | ||
112 | } | ||
113 | |||
114 | .user-bio { | ||
115 | margin-top: 20px; | ||
116 | color: #606266; | ||
117 | |||
118 | span { | ||
119 | padding-left: 4px; | ||
120 | } | ||
121 | |||
122 | .user-bio-section { | ||
123 | font-size: 14px; | ||
124 | padding: 15px 0; | ||
125 | |||
126 | .user-bio-section-header { | ||
127 | border-bottom: 1px solid #dfe6ec; | ||
128 | padding-bottom: 10px; | ||
129 | margin-bottom: 10px; | ||
130 | font-weight: bold; | ||
131 | } | ||
132 | } | ||
133 | } | ||
134 | </style> | ||
135 |
src/views/profile/index.vue
File was created | 1 | <template> | |
2 | <div class="app-container"> | ||
3 | <div v-if="user"> | ||
4 | <el-row :gutter="20"> | ||
5 | |||
6 | <el-col :span="6" :xs="24"> | ||
7 | <user-card :user="user" /> | ||
8 | </el-col> | ||
9 | |||
10 | <el-col :span="18" :xs="24"> | ||
11 | <el-card> | ||
12 | <el-tabs v-model="activeTab"> | ||
13 | <el-tab-pane label="Activity" name="activity"> | ||
14 | <activity /> | ||
15 | </el-tab-pane> | ||
16 | <el-tab-pane label="Timeline" name="timeline"> | ||
17 | <timeline /> | ||
18 | </el-tab-pane> | ||
19 | <el-tab-pane label="Account" name="account"> | ||
20 | <account :user="user" /> | ||
21 | </el-tab-pane> | ||
22 | </el-tabs> | ||
23 | </el-card> | ||
24 | </el-col> | ||
25 | |||
26 | </el-row> | ||
27 | </div> | ||
28 | </div> | ||
29 | </template> | ||
30 | |||
31 | <script> | ||
32 | import { mapGetters } from 'vuex' | ||
33 | import UserCard from './components/UserCard' | ||
34 | import Activity from './components/Activity' | ||
35 | import Timeline from './components/Timeline' | ||
36 | import Account from './components/Account' | ||
37 | |||
38 | export default { | ||
39 | name: 'Profile', | ||
40 | components: { UserCard, Activity, Timeline, Account }, | ||
41 | data() { | ||
42 | return { | ||
43 | user: {}, | ||
44 | activeTab: 'activity' | ||
45 | } | ||
46 | }, | ||
47 | computed: { | ||
48 | ...mapGetters([ | ||
49 | 'name', | ||
50 | 'avatar', | ||
51 | 'roles' | ||
52 | ]) | ||
53 | }, | ||
54 | created() { | ||
55 | this.getUser() | ||
56 | }, | ||
57 | methods: { | ||
58 | getUser() { | ||
59 | this.user = { | ||
60 | name: this.name, | ||
61 | role: this.roles.join(' | '), | ||
62 | email: 'admin@test.com', | ||
63 | avatar: this.avatar | ||
64 | } | ||
65 | } | ||
66 | } | ||
67 | } | ||
68 | </script> | ||
69 |
src/views/qiniu/upload.vue
File was created | 1 | <template> | |
2 | <el-upload :data="dataObj" :multiple="true" :before-upload="beforeUpload" action="https://upload.qbox.me" drag> | ||
3 | <i class="el-icon-upload" /> | ||
4 | <div class="el-upload__text"> | ||
5 | 将文件拖到此处,或<em>点击上传</em> | ||
6 | </div> | ||
7 | </el-upload> | ||
8 | </template> | ||
9 | |||
10 | <script> | ||
11 | import { getToken } from '@/api/qiniu' | ||
12 | // 获取七牛token 后端通过Access Key,Secret Key,bucket等生成token | ||
13 | // 七牛官方sdk https://developer.qiniu.com/sdk#official-sdk | ||
14 | |||
15 | export default { | ||
16 | data() { | ||
17 | return { | ||
18 | dataObj: { token: '', key: '' }, | ||
19 | image_uri: [], | ||
20 | fileList: [] | ||
21 | } | ||
22 | }, | ||
23 | methods: { | ||
24 | beforeUpload() { | ||
25 | const _self = this | ||
26 | return new Promise((resolve, reject) => { | ||
27 | getToken().then(response => { | ||
28 | const key = response.data.qiniu_key | ||
29 | const token = response.data.qiniu_token | ||
30 | _self._data.dataObj.token = token | ||
31 | _self._data.dataObj.key = key | ||
32 | resolve(true) | ||
33 | }).catch(err => { | ||
34 | console.log(err) | ||
35 | reject(false) | ||
36 | }) | ||
37 | }) | ||
38 | } | ||
39 | } | ||
40 | } | ||
41 | </script> | ||
42 |
src/views/redirect/index.vue
File was created | 1 | <script> | |
2 | export default { | ||
3 | created() { | ||
4 | const { params, query } = this.$route | ||
5 | const { path } = params | ||
6 | this.$router.replace({ path: '/' + path, query }) | ||
7 | }, | ||
8 | render: function(h) { | ||
9 | return h() // avoid warning message | ||
10 | } | ||
11 | } | ||
12 | </script> | ||
13 |
src/views/tab/components/TabPane.vue
File was created | 1 | <template> | |
2 | <el-table :data="list" border fit highlight-current-row style="width: 100%"> | ||
3 | <el-table-column | ||
4 | v-loading="loading" | ||
5 | align="center" | ||
6 | label="ID" | ||
7 | width="65" | ||
8 | element-loading-text="请给我点时间!" | ||
9 | > | ||
10 | <template slot-scope="scope"> | ||
11 | <span>{{ scope.row.id }}</span> | ||
12 | </template> | ||
13 | </el-table-column> | ||
14 | |||
15 | <el-table-column width="180px" align="center" label="Date"> | ||
16 | <template slot-scope="scope"> | ||
17 | <span>{{ scope.row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span> | ||
18 | </template> | ||
19 | </el-table-column> | ||
20 | |||
21 | <el-table-column min-width="300px" label="Title"> | ||
22 | <template slot-scope="{row}"> | ||
23 | <span>{{ row.title }}</span> | ||
24 | <el-tag>{{ row.type }}</el-tag> | ||
25 | </template> | ||
26 | </el-table-column> | ||
27 | |||
28 | <el-table-column width="110px" align="center" label="Author"> | ||
29 | <template slot-scope="scope"> | ||
30 | <span>{{ scope.row.author }}</span> | ||
31 | </template> | ||
32 | </el-table-column> | ||
33 | |||
34 | <el-table-column width="120px" label="Importance"> | ||
35 | <template slot-scope="scope"> | ||
36 | <svg-icon v-for="n in +scope.row.importance" :key="n" icon-class="star" /> | ||
37 | </template> | ||
38 | </el-table-column> | ||
39 | |||
40 | <el-table-column align="center" label="Readings" width="95"> | ||
41 | <template slot-scope="scope"> | ||
42 | <span>{{ scope.row.pageviews }}</span> | ||
43 | </template> | ||
44 | </el-table-column> | ||
45 | |||
46 | <el-table-column class-name="status-col" label="Status" width="110"> | ||
47 | <template slot-scope="{row}"> | ||
48 | <el-tag :type="row.status | statusFilter"> | ||
49 | {{ row.status }} | ||
50 | </el-tag> | ||
51 | </template> | ||
52 | </el-table-column> | ||
53 | </el-table> | ||
54 | </template> | ||
55 | |||
56 | <script> | ||
57 | import { fetchList } from '@/api/article' | ||
58 | |||
59 | export default { | ||
60 | filters: { | ||
61 | statusFilter(status) { | ||
62 | const statusMap = { | ||
63 | published: 'success', | ||
64 | draft: 'info', | ||
65 | deleted: 'danger' | ||
66 | } | ||
67 | return statusMap[status] | ||
68 | } | ||
69 | }, | ||
70 | props: { | ||
71 | type: { | ||
72 | type: String, | ||
73 | default: 'CN' | ||
74 | } | ||
75 | }, | ||
76 | data() { | ||
77 | return { | ||
78 | list: null, | ||
79 | listQuery: { | ||
80 | page: 1, | ||
81 | limit: 5, | ||
82 | type: this.type, | ||
83 | sort: '+id' | ||
84 | }, | ||
85 | loading: false | ||
86 | } | ||
87 | }, | ||
88 | created() { | ||
89 | this.getList() | ||
90 | }, | ||
91 | methods: { | ||
92 | getList() { | ||
93 | this.loading = true | ||
94 | this.$emit('create') // for test | ||
95 | fetchList(this.listQuery).then(response => { | ||
96 | this.list = response.data.items | ||
97 | this.loading = false | ||
98 | }) | ||
99 | } | ||
100 | } | ||
101 | } | ||
102 | </script> | ||
103 | |||
104 |
src/views/tab/index.vue
File was created | 1 | <template> | |
2 | <div class="tab-container"> | ||
3 | <el-tag>mounted times :{{ createdTimes }}</el-tag> | ||
4 | <el-alert :closable="false" style="width:200px;display:inline-block;vertical-align: middle;margin-left:30px;" title="Tab with keep-alive" type="success" /> | ||
5 | <el-tabs v-model="activeName" style="margin-top:15px;" type="border-card"> | ||
6 | <el-tab-pane v-for="item in tabMapOptions" :key="item.key" :label="item.label" :name="item.key"> | ||
7 | <keep-alive> | ||
8 | <tab-pane v-if="activeName==item.key" :type="item.key" @create="showCreatedTimes" /> | ||
9 | </keep-alive> | ||
10 | </el-tab-pane> | ||
11 | </el-tabs> | ||
12 | </div> | ||
13 | </template> | ||
14 | |||
15 | <script> | ||
16 | import tabPane from './components/TabPane' | ||
17 | |||
18 | export default { | ||
19 | name: 'Tab', | ||
20 | components: { tabPane }, | ||
21 | data() { | ||
22 | return { | ||
23 | tabMapOptions: [ | ||
24 | { label: 'China', key: 'CN' }, | ||
25 | { label: 'USA', key: 'US' }, | ||
26 | { label: 'Japan', key: 'JP' }, | ||
27 | { label: 'Eurozone', key: 'EU' } | ||
28 | ], | ||
29 | activeName: 'CN', | ||
30 | createdTimes: 0 | ||
31 | } | ||
32 | }, | ||
33 | watch: { | ||
34 | activeName(val) { | ||
35 | this.$router.push(`${this.$route.path}?tab=${val}`) | ||
36 | } | ||
37 | }, | ||
38 | created() { | ||
39 | // init the default selected tab | ||
40 | const tab = this.$route.query.tab | ||
41 | if (tab) { | ||
42 | this.activeName = tab | ||
43 | } | ||
44 | }, | ||
45 | methods: { | ||
46 | showCreatedTimes() { | ||
47 | this.createdTimes = this.createdTimes + 1 | ||
48 | } | ||
49 | } | ||
50 | } | ||
51 | </script> | ||
52 | |||
53 | <style scoped> | ||
54 | .tab-container { | ||
55 | margin: 30px; | ||
56 | } | ||
57 | </style> | ||
58 |
src/views/table/complex-table.vue
File was created | 1 | <template> | |
2 | <div class="app-container"> | ||
3 | <div class="filter-container"> | ||
4 | <el-input v-model="listQuery.title" :placeholder="$t('table.title')" style="width: 200px;" class="filter-item" @keyup.enter.native="handleFilter" /> | ||
5 | <el-select v-model="listQuery.importance" :placeholder="$t('table.importance')" clearable style="width: 90px" class="filter-item"> | ||
6 | <el-option v-for="item in importanceOptions" :key="item" :label="item" :value="item" /> | ||
7 | </el-select> | ||
8 | <el-select v-model="listQuery.type" :placeholder="$t('table.type')" clearable class="filter-item" style="width: 130px"> | ||
9 | <el-option v-for="item in calendarTypeOptions" :key="item.key" :label="item.display_name+'('+item.key+')'" :value="item.key" /> | ||
10 | </el-select> | ||
11 | <el-select v-model="listQuery.sort" style="width: 140px" class="filter-item" @change="handleFilter"> | ||
12 | <el-option v-for="item in sortOptions" :key="item.key" :label="item.label" :value="item.key" /> | ||
13 | </el-select> | ||
14 | <el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter"> | ||
15 | {{ $t('table.search') }} | ||
16 | </el-button> | ||
17 | <el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-edit" @click="handleCreate"> | ||
18 | {{ $t('table.add') }} | ||
19 | </el-button> | ||
20 | <el-button v-waves :loading="downloadLoading" class="filter-item" type="primary" icon="el-icon-download" @click="handleDownload"> | ||
21 | {{ $t('table.export') }} | ||
22 | </el-button> | ||
23 | <el-checkbox v-model="showReviewer" class="filter-item" style="margin-left:15px;" @change="tableKey=tableKey+1"> | ||
24 | {{ $t('table.reviewer') }} | ||
25 | </el-checkbox> | ||
26 | </div> | ||
27 | |||
28 | <el-table | ||
29 | :key="tableKey" | ||
30 | v-loading="listLoading" | ||
31 | :data="list" | ||
32 | border | ||
33 | fit | ||
34 | highlight-current-row | ||
35 | style="width: 100%;" | ||
36 | @sort-change="sortChange" | ||
37 | > | ||
38 | <el-table-column :label="$t('table.id')" prop="id" sortable="custom" align="center" width="80" :class-name="getSortClass('id')"> | ||
39 | <template slot-scope="{row}"> | ||
40 | <span>{{ row.id }}</span> | ||
41 | </template> | ||
42 | </el-table-column> | ||
43 | <el-table-column :label="$t('table.date')" width="150px" align="center"> | ||
44 | <template slot-scope="{row}"> | ||
45 | <span>{{ row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span> | ||
46 | </template> | ||
47 | </el-table-column> | ||
48 | <el-table-column :label="$t('table.title')" min-width="150px"> | ||
49 | <template slot-scope="{row}"> | ||
50 | <span class="link-type" @click="handleUpdate(row)">{{ row.title }}</span> | ||
51 | <el-tag>{{ row.type | typeFilter }}</el-tag> | ||
52 | </template> | ||
53 | </el-table-column> | ||
54 | <el-table-column :label="$t('table.author')" width="110px" align="center"> | ||
55 | <template slot-scope="{row}"> | ||
56 | <span>{{ row.author }}</span> | ||
57 | </template> | ||
58 | </el-table-column> | ||
59 | <el-table-column v-if="showReviewer" :label="$t('table.reviewer')" width="110px" align="center"> | ||
60 | <template slot-scope="{row}"> | ||
61 | <span style="color:red;">{{ row.reviewer }}</span> | ||
62 | </template> | ||
63 | </el-table-column> | ||
64 | <el-table-column :label="$t('table.importance')" width="80px"> | ||
65 | <template slot-scope="{row}"> | ||
66 | <svg-icon v-for="n in +row.importance" :key="n" icon-class="star" class="meta-item__icon" /> | ||
67 | </template> | ||
68 | </el-table-column> | ||
69 | <el-table-column :label="$t('table.readings')" align="center" width="95"> | ||
70 | <template slot-scope="{row}"> | ||
71 | <span v-if="row.pageviews" class="link-type" @click="handleFetchPv(row.pageviews)">{{ row.pageviews }}</span> | ||
72 | <span v-else>0</span> | ||
73 | </template> | ||
74 | </el-table-column> | ||
75 | <el-table-column :label="$t('table.status')" class-name="status-col" width="100"> | ||
76 | <template slot-scope="{row}"> | ||
77 | <el-tag :type="row.status | statusFilter"> | ||
78 | {{ row.status }} | ||
79 | </el-tag> | ||
80 | </template> | ||
81 | </el-table-column> | ||
82 | <el-table-column :label="$t('table.actions')" align="center" width="230" class-name="small-padding fixed-width"> | ||
83 | <template slot-scope="{row,$index}"> | ||
84 | <el-button type="primary" size="mini" @click="handleUpdate(row)"> | ||
85 | {{ $t('table.edit') }} | ||
86 | </el-button> | ||
87 | <el-button v-if="row.status!='published'" size="mini" type="success" @click="handleModifyStatus(row,'published')"> | ||
88 | {{ $t('table.publish') }} | ||
89 | </el-button> | ||
90 | <el-button v-if="row.status!='draft'" size="mini" @click="handleModifyStatus(row,'draft')"> | ||
91 | {{ $t('table.draft') }} | ||
92 | </el-button> | ||
93 | <el-button v-if="row.status!='deleted'" size="mini" type="danger" @click="handleDelete(row,$index)"> | ||
94 | {{ $t('table.delete') }} | ||
95 | </el-button> | ||
96 | </template> | ||
97 | </el-table-column> | ||
98 | </el-table> | ||
99 | |||
100 | <pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getList" /> | ||
101 | |||
102 | <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible"> | ||
103 | <el-form ref="dataForm" :rules="rules" :model="temp" label-position="left" label-width="70px" style="width: 400px; margin-left:50px;"> | ||
104 | <el-form-item :label="$t('table.type')" prop="type"> | ||
105 | <el-select v-model="temp.type" class="filter-item" placeholder="Please select"> | ||
106 | <el-option v-for="item in calendarTypeOptions" :key="item.key" :label="item.display_name" :value="item.key" /> | ||
107 | </el-select> | ||
108 | </el-form-item> | ||
109 | <el-form-item :label="$t('table.date')" prop="timestamp"> | ||
110 | <el-date-picker v-model="temp.timestamp" type="datetime" placeholder="Please pick a date" /> | ||
111 | </el-form-item> | ||
112 | <el-form-item :label="$t('table.title')" prop="title"> | ||
113 | <el-input v-model="temp.title" /> | ||
114 | </el-form-item> | ||
115 | <el-form-item :label="$t('table.status')"> | ||
116 | <el-select v-model="temp.status" class="filter-item" placeholder="Please select"> | ||
117 | <el-option v-for="item in statusOptions" :key="item" :label="item" :value="item" /> | ||
118 | </el-select> | ||
119 | </el-form-item> | ||
120 | <el-form-item :label="$t('table.importance')"> | ||
121 | <el-rate v-model="temp.importance" :colors="['#99A9BF', '#F7BA2A', '#FF9900']" :max="3" style="margin-top:8px;" /> | ||
122 | </el-form-item> | ||
123 | <el-form-item :label="$t('table.remark')"> | ||
124 | <el-input v-model="temp.remark" :autosize="{ minRows: 2, maxRows: 4}" type="textarea" placeholder="Please input" /> | ||
125 | </el-form-item> | ||
126 | </el-form> | ||
127 | <div slot="footer" class="dialog-footer"> | ||
128 | <el-button @click="dialogFormVisible = false"> | ||
129 | {{ $t('table.cancel') }} | ||
130 | </el-button> | ||
131 | <el-button type="primary" @click="dialogStatus==='create'?createData():updateData()"> | ||
132 | {{ $t('table.confirm') }} | ||
133 | </el-button> | ||
134 | </div> | ||
135 | </el-dialog> | ||
136 | |||
137 | <el-dialog :visible.sync="dialogPvVisible" title="Reading statistics"> | ||
138 | <el-table :data="pvData" border fit highlight-current-row style="width: 100%"> | ||
139 | <el-table-column prop="key" label="Channel" /> | ||
140 | <el-table-column prop="pv" label="Pv" /> | ||
141 | </el-table> | ||
142 | <span slot="footer" class="dialog-footer"> | ||
143 | <el-button type="primary" @click="dialogPvVisible = false">{{ $t('table.confirm') }}</el-button> | ||
144 | </span> | ||
145 | </el-dialog> | ||
146 | </div> | ||
147 | </template> | ||
148 | |||
149 | <script> | ||
150 | import { fetchList, fetchPv, createArticle, updateArticle } from '@/api/article' | ||
151 | import waves from '@/directive/waves' // waves directive | ||
152 | import { parseTime } from '@/utils' | ||
153 | import Pagination from '@/components/Pagination' // secondary package based on el-pagination | ||
154 | |||
155 | const calendarTypeOptions = [ | ||
156 | { key: 'CN', display_name: 'China' }, | ||
157 | { key: 'US', display_name: 'USA' }, | ||
158 | { key: 'JP', display_name: 'Japan' }, | ||
159 | { key: 'EU', display_name: 'Eurozone' } | ||
160 | ] | ||
161 | |||
162 | // arr to obj, such as { CN : "China", US : "USA" } | ||
163 | const calendarTypeKeyValue = calendarTypeOptions.reduce((acc, cur) => { | ||
164 | acc[cur.key] = cur.display_name | ||
165 | return acc | ||
166 | }, {}) | ||
167 | |||
168 | export default { | ||
169 | name: 'ComplexTable', | ||
170 | components: { Pagination }, | ||
171 | directives: { waves }, | ||
172 | filters: { | ||
173 | statusFilter(status) { | ||
174 | const statusMap = { | ||
175 | published: 'success', | ||
176 | draft: 'info', | ||
177 | deleted: 'danger' | ||
178 | } | ||
179 | return statusMap[status] | ||
180 | }, | ||
181 | typeFilter(type) { | ||
182 | return calendarTypeKeyValue[type] | ||
183 | } | ||
184 | }, | ||
185 | data() { | ||
186 | return { | ||
187 | tableKey: 0, | ||
188 | list: null, | ||
189 | total: 0, | ||
190 | listLoading: true, | ||
191 | listQuery: { | ||
192 | page: 1, | ||
193 | limit: 20, | ||
194 | importance: undefined, | ||
195 | title: undefined, | ||
196 | type: undefined, | ||
197 | sort: '+id' | ||
198 | }, | ||
199 | importanceOptions: [1, 2, 3], | ||
200 | calendarTypeOptions, | ||
201 | sortOptions: [{ label: 'ID Ascending', key: '+id' }, { label: 'ID Descending', key: '-id' }], | ||
202 | statusOptions: ['published', 'draft', 'deleted'], | ||
203 | showReviewer: false, | ||
204 | temp: { | ||
205 | id: undefined, | ||
206 | importance: 1, | ||
207 | remark: '', | ||
208 | timestamp: new Date(), | ||
209 | title: '', | ||
210 | type: '', | ||
211 | status: 'published' | ||
212 | }, | ||
213 | dialogFormVisible: false, | ||
214 | dialogStatus: '', | ||
215 | textMap: { | ||
216 | update: 'Edit', | ||
217 | create: 'Create' | ||
218 | }, | ||
219 | dialogPvVisible: false, | ||
220 | pvData: [], | ||
221 | rules: { | ||
222 | type: [{ required: true, message: 'type is required', trigger: 'change' }], | ||
223 | timestamp: [{ type: 'date', required: true, message: 'timestamp is required', trigger: 'change' }], | ||
224 | title: [{ required: true, message: 'title is required', trigger: 'blur' }] | ||
225 | }, | ||
226 | downloadLoading: false | ||
227 | } | ||
228 | }, | ||
229 | created() { | ||
230 | this.getList() | ||
231 | }, | ||
232 | methods: { | ||
233 | getList() { | ||
234 | this.listLoading = true | ||
235 | fetchList(this.listQuery).then(response => { | ||
236 | this.list = response.data.items | ||
237 | this.total = response.data.total | ||
238 | |||
239 | // Just to simulate the time of the request | ||
240 | setTimeout(() => { | ||
241 | this.listLoading = false | ||
242 | }, 1.5 * 1000) | ||
243 | }) | ||
244 | }, | ||
245 | handleFilter() { | ||
246 | this.listQuery.page = 1 | ||
247 | this.getList() | ||
248 | }, | ||
249 | handleModifyStatus(row, status) { | ||
250 | this.$message({ | ||
251 | message: '操作成功', | ||
252 | type: 'success' | ||
253 | }) | ||
254 | row.status = status | ||
255 | }, | ||
256 | sortChange(data) { | ||
257 | const { prop, order } = data | ||
258 | if (prop === 'id') { | ||
259 | this.sortByID(order) | ||
260 | } | ||
261 | }, | ||
262 | sortByID(order) { | ||
263 | if (order === 'ascending') { | ||
264 | this.listQuery.sort = '+id' | ||
265 | } else { | ||
266 | this.listQuery.sort = '-id' | ||
267 | } | ||
268 | this.handleFilter() | ||
269 | }, | ||
270 | resetTemp() { | ||
271 | this.temp = { | ||
272 | id: undefined, | ||
273 | importance: 1, | ||
274 | remark: '', | ||
275 | timestamp: new Date(), | ||
276 | title: '', | ||
277 | status: 'published', | ||
278 | type: '' | ||
279 | } | ||
280 | }, | ||
281 | handleCreate() { | ||
282 | this.resetTemp() | ||
283 | this.dialogStatus = 'create' | ||
284 | this.dialogFormVisible = true | ||
285 | this.$nextTick(() => { | ||
286 | this.$refs['dataForm'].clearValidate() | ||
287 | }) | ||
288 | }, | ||
289 | createData() { | ||
290 | this.$refs['dataForm'].validate((valid) => { | ||
291 | if (valid) { | ||
292 | this.temp.id = parseInt(Math.random() * 100) + 1024 // mock a id | ||
293 | this.temp.author = 'vue-element-admin' | ||
294 | createArticle(this.temp).then(() => { | ||
295 | this.list.unshift(this.temp) | ||
296 | this.dialogFormVisible = false | ||
297 | this.$notify({ | ||
298 | title: '成功', | ||
299 | message: '创建成功', | ||
300 | type: 'success', | ||
301 | duration: 2000 | ||
302 | }) | ||
303 | }) | ||
304 | } | ||
305 | }) | ||
306 | }, | ||
307 | handleUpdate(row) { | ||
308 | this.temp = Object.assign({}, row) // copy obj | ||
309 | this.temp.timestamp = new Date(this.temp.timestamp) | ||
310 | this.dialogStatus = 'update' | ||
311 | this.dialogFormVisible = true | ||
312 | this.$nextTick(() => { | ||
313 | this.$refs['dataForm'].clearValidate() | ||
314 | }) | ||
315 | }, | ||
316 | updateData() { | ||
317 | this.$refs['dataForm'].validate((valid) => { | ||
318 | if (valid) { | ||
319 | const tempData = Object.assign({}, this.temp) | ||
320 | tempData.timestamp = +new Date(tempData.timestamp) // change Thu Nov 30 2017 16:41:05 GMT+0800 (CST) to 1512031311464 | ||
321 | updateArticle(tempData).then(() => { | ||
322 | const index = this.list.findIndex(v => v.id === this.temp.id) | ||
323 | this.list.splice(index, 1, this.temp) | ||
324 | this.dialogFormVisible = false | ||
325 | this.$notify({ | ||
326 | title: '成功', | ||
327 | message: '更新成功', | ||
328 | type: 'success', | ||
329 | duration: 2000 | ||
330 | }) | ||
331 | }) | ||
332 | } | ||
333 | }) | ||
334 | }, | ||
335 | handleDelete(row, index) { | ||
336 | this.$notify({ | ||
337 | title: '成功', | ||
338 | message: '删除成功', | ||
339 | type: 'success', | ||
340 | duration: 2000 | ||
341 | }) | ||
342 | this.list.splice(index, 1) | ||
343 | }, | ||
344 | handleFetchPv(pv) { | ||
345 | fetchPv(pv).then(response => { | ||
346 | this.pvData = response.data.pvData | ||
347 | this.dialogPvVisible = true | ||
348 | }) | ||
349 | }, | ||
350 | handleDownload() { | ||
351 | this.downloadLoading = true | ||
352 | import('@/vendor/Export2Excel').then(excel => { | ||
353 | const tHeader = ['timestamp', 'title', 'type', 'importance', 'status'] | ||
354 | const filterVal = ['timestamp', 'title', 'type', 'importance', 'status'] | ||
355 | const data = this.formatJson(filterVal) | ||
356 | excel.export_json_to_excel({ | ||
357 | header: tHeader, | ||
358 | data, | ||
359 | filename: 'table-list' | ||
360 | }) | ||
361 | this.downloadLoading = false | ||
362 | }) | ||
363 | }, | ||
364 | formatJson(filterVal) { | ||
365 | return this.list.map(v => filterVal.map(j => { | ||
366 | if (j === 'timestamp') { | ||
367 | return parseTime(v[j]) | ||
368 | } else { | ||
369 | return v[j] | ||
370 | } | ||
371 | })) | ||
372 | }, | ||
373 | getSortClass: function(key) { | ||
374 | const sort = this.listQuery.sort | ||
375 | return sort === `+${key}` ? 'ascending' : 'descending' | ||
376 | } | ||
377 | } | ||
378 | } | ||
379 | </script> | ||
380 |
src/views/table/drag-table.vue
File was created | 1 | <template> | |
2 | <div class="app-container"> | ||
3 | <!-- Note that row-key is necessary to get a correct row order. --> | ||
4 | <el-table ref="dragTable" v-loading="listLoading" :data="list" row-key="id" border fit highlight-current-row style="width: 100%"> | ||
5 | <el-table-column align="center" label="ID" width="65"> | ||
6 | <template slot-scope="{row}"> | ||
7 | <span>{{ row.id }}</span> | ||
8 | </template> | ||
9 | </el-table-column> | ||
10 | |||
11 | <el-table-column width="180px" align="center" label="Date"> | ||
12 | <template slot-scope="{row}"> | ||
13 | <span>{{ row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span> | ||
14 | </template> | ||
15 | </el-table-column> | ||
16 | |||
17 | <el-table-column min-width="300px" label="Title"> | ||
18 | <template slot-scope="{row}"> | ||
19 | <span>{{ row.title }}</span> | ||
20 | </template> | ||
21 | </el-table-column> | ||
22 | |||
23 | <el-table-column width="110px" align="center" label="Author"> | ||
24 | <template slot-scope="{row}"> | ||
25 | <span>{{ row.author }}</span> | ||
26 | </template> | ||
27 | </el-table-column> | ||
28 | |||
29 | <el-table-column width="100px" label="Importance"> | ||
30 | <template slot-scope="{row}"> | ||
31 | <svg-icon v-for="n in + row.importance" :key="n" icon-class="star" class="icon-star" /> | ||
32 | </template> | ||
33 | </el-table-column> | ||
34 | |||
35 | <el-table-column align="center" label="Readings" width="95"> | ||
36 | <template slot-scope="{row}"> | ||
37 | <span>{{ row.pageviews }}</span> | ||
38 | </template> | ||
39 | </el-table-column> | ||
40 | |||
41 | <el-table-column class-name="status-col" label="Status" width="110"> | ||
42 | <template slot-scope="{row}"> | ||
43 | <el-tag :type="row.status | statusFilter"> | ||
44 | {{ row.status }} | ||
45 | </el-tag> | ||
46 | </template> | ||
47 | </el-table-column> | ||
48 | |||
49 | <el-table-column align="center" label="Drag" width="80"> | ||
50 | <template slot-scope="{}"> | ||
51 | <svg-icon class="drag-handler" icon-class="drag" /> | ||
52 | </template> | ||
53 | </el-table-column> | ||
54 | </el-table> | ||
55 | <!-- $t is vue-i18n global function to translate lang (lang in @/lang) --> | ||
56 | <div class="show-d"> | ||
57 | <el-tag style="margin-right:12px;">{{ $t('table.dragTips1') }} :</el-tag> {{ oldList }} | ||
58 | </div> | ||
59 | <div class="show-d"> | ||
60 | <el-tag>{{ $t('table.dragTips2') }} :</el-tag> {{ newList }} | ||
61 | </div> | ||
62 | </div> | ||
63 | </template> | ||
64 | |||
65 | <script> | ||
66 | import { fetchList } from '@/api/article' | ||
67 | import Sortable from 'sortablejs' | ||
68 | |||
69 | export default { | ||
70 | name: 'DragTable', | ||
71 | filters: { | ||
72 | statusFilter(status) { | ||
73 | const statusMap = { | ||
74 | published: 'success', | ||
75 | draft: 'info', | ||
76 | deleted: 'danger' | ||
77 | } | ||
78 | return statusMap[status] | ||
79 | } | ||
80 | }, | ||
81 | data() { | ||
82 | return { | ||
83 | list: null, | ||
84 | total: null, | ||
85 | listLoading: true, | ||
86 | listQuery: { | ||
87 | page: 1, | ||
88 | limit: 10 | ||
89 | }, | ||
90 | sortable: null, | ||
91 | oldList: [], | ||
92 | newList: [] | ||
93 | } | ||
94 | }, | ||
95 | created() { | ||
96 | this.getList() | ||
97 | }, | ||
98 | methods: { | ||
99 | async getList() { | ||
100 | this.listLoading = true | ||
101 | const { data } = await fetchList(this.listQuery) | ||
102 | this.list = data.items | ||
103 | this.total = data.total | ||
104 | this.listLoading = false | ||
105 | this.oldList = this.list.map(v => v.id) | ||
106 | this.newList = this.oldList.slice() | ||
107 | this.$nextTick(() => { | ||
108 | this.setSort() | ||
109 | }) | ||
110 | }, | ||
111 | setSort() { | ||
112 | const el = this.$refs.dragTable.$el.querySelectorAll('.el-table__body-wrapper > table > tbody')[0] | ||
113 | this.sortable = Sortable.create(el, { | ||
114 | ghostClass: 'sortable-ghost', // Class name for the drop placeholder, | ||
115 | setData: function(dataTransfer) { | ||
116 | // to avoid Firefox bug | ||
117 | // Detail see : https://github.com/RubaXa/Sortable/issues/1012 | ||
118 | dataTransfer.setData('Text', '') | ||
119 | }, | ||
120 | onEnd: evt => { | ||
121 | const targetRow = this.list.splice(evt.oldIndex, 1)[0] | ||
122 | this.list.splice(evt.newIndex, 0, targetRow) | ||
123 | |||
124 | // for show the changes, you can delete in you code | ||
125 | const tempIndex = this.newList.splice(evt.oldIndex, 1)[0] | ||
126 | this.newList.splice(evt.newIndex, 0, tempIndex) | ||
127 | } | ||
128 | }) | ||
129 | } | ||
130 | } | ||
131 | } | ||
132 | </script> | ||
133 | |||
134 | <style> | ||
135 | .sortable-ghost{ | ||
136 | opacity: .8; | ||
137 | color: #fff!important; | ||
138 | background: #42b983!important; | ||
139 | } | ||
140 | </style> | ||
141 | |||
142 | <style scoped> | ||
143 | .icon-star{ | ||
144 | margin-right:2px; | ||
145 | } | ||
146 | .drag-handler{ | ||
147 | width: 20px; | ||
148 | height: 20px; | ||
149 | cursor: pointer; | ||
150 | } | ||
151 | .show-d{ | ||
152 | margin-top: 15px; | ||
153 | } | ||
154 | </style> | ||
155 |
src/views/table/dynamic-table/components/FixedThead.vue
File was created | 1 | <template> | |
2 | <div class="app-container"> | ||
3 | <div class="filter-container"> | ||
4 | <el-checkbox-group v-model="checkboxVal"> | ||
5 | <el-checkbox label="apple"> | ||
6 | apple | ||
7 | </el-checkbox> | ||
8 | <el-checkbox label="banana"> | ||
9 | banana | ||
10 | </el-checkbox> | ||
11 | <el-checkbox label="orange"> | ||
12 | orange | ||
13 | </el-checkbox> | ||
14 | </el-checkbox-group> | ||
15 | </div> | ||
16 | |||
17 | <el-table :key="key" :data="tableData" border fit highlight-current-row style="width: 100%"> | ||
18 | <el-table-column prop="name" label="fruitName" width="180" /> | ||
19 | <el-table-column v-for="fruit in formThead" :key="fruit" :label="fruit"> | ||
20 | <template slot-scope="scope"> | ||
21 | {{ scope.row[fruit] }} | ||
22 | </template> | ||
23 | </el-table-column> | ||
24 | </el-table> | ||
25 | </div> | ||
26 | </template> | ||
27 | |||
28 | <script> | ||
29 | const defaultFormThead = ['apple', 'banana'] | ||
30 | |||
31 | export default { | ||
32 | data() { | ||
33 | return { | ||
34 | tableData: [ | ||
35 | { | ||
36 | name: 'fruit-1', | ||
37 | apple: 'apple-10', | ||
38 | banana: 'banana-10', | ||
39 | orange: 'orange-10' | ||
40 | }, | ||
41 | { | ||
42 | name: 'fruit-2', | ||
43 | apple: 'apple-20', | ||
44 | banana: 'banana-20', | ||
45 | orange: 'orange-20' | ||
46 | } | ||
47 | ], | ||
48 | key: 1, // table key | ||
49 | formTheadOptions: ['apple', 'banana', 'orange'], | ||
50 | checkboxVal: defaultFormThead, // checkboxVal | ||
51 | formThead: defaultFormThead // 默认表头 Default header | ||
52 | } | ||
53 | }, | ||
54 | watch: { | ||
55 | checkboxVal(valArr) { | ||
56 | this.formThead = this.formTheadOptions.filter(i => valArr.indexOf(i) >= 0) | ||
57 | this.key = this.key + 1// 为了保证table 每次都会重渲 In order to ensure the table will be re-rendered each time | ||
58 | } | ||
59 | } | ||
60 | } | ||
61 | </script> | ||
62 | |||
63 |
src/views/table/dynamic-table/components/UnfixedThead.vue
File was created | 1 | <template> | |
2 | <div class="app-container"> | ||
3 | <div class="filter-container"> | ||
4 | <el-checkbox-group v-model="formThead"> | ||
5 | <el-checkbox label="apple"> | ||
6 | apple | ||
7 | </el-checkbox> | ||
8 | <el-checkbox label="banana"> | ||
9 | banana | ||
10 | </el-checkbox> | ||
11 | <el-checkbox label="orange"> | ||
12 | orange | ||
13 | </el-checkbox> | ||
14 | </el-checkbox-group> | ||
15 | </div> | ||
16 | |||
17 | <el-table :data="tableData" border fit highlight-current-row style="width: 100%"> | ||
18 | <el-table-column prop="name" label="fruitName" width="180" /> | ||
19 | <el-table-column v-for="fruit in formThead" :key="fruit" :label="fruit"> | ||
20 | <template slot-scope="scope"> | ||
21 | {{ scope.row[fruit] }} | ||
22 | </template> | ||
23 | </el-table-column> | ||
24 | </el-table> | ||
25 | </div> | ||
26 | </template> | ||
27 | |||
28 | <script> | ||
29 | export default { | ||
30 | data() { | ||
31 | return { | ||
32 | tableData: [ | ||
33 | { | ||
34 | name: 'fruit-1', | ||
35 | apple: 'apple-10', | ||
36 | banana: 'banana-10', | ||
37 | orange: 'orange-10' | ||
38 | }, | ||
39 | { | ||
40 | name: 'fruit-2', | ||
41 | apple: 'apple-20', | ||
42 | banana: 'banana-20', | ||
43 | orange: 'orange-20' | ||
44 | } | ||
45 | ], | ||
46 | formThead: ['apple', 'banana'] | ||
47 | } | ||
48 | } | ||
49 | } | ||
50 | </script> | ||
51 |
src/views/table/dynamic-table/index.vue
File was created | 1 | <template> | |
2 | <div class="app-container"> | ||
3 | <div style="margin:0 0 5px 20px"> | ||
4 | {{ $t('table.dynamicTips1') }} | ||
5 | </div> | ||
6 | <fixed-thead /> | ||
7 | |||
8 | <div style="margin:30px 0 5px 20px"> | ||
9 | {{ $t('table.dynamicTips2') }} | ||
10 | </div> | ||
11 | <unfixed-thead /> | ||
12 | </div> | ||
13 | </template> | ||
14 | |||
15 | <script> | ||
16 | import FixedThead from './components/FixedThead' | ||
17 | import UnfixedThead from './components/UnfixedThead' | ||
18 | |||
19 | export default { | ||
20 | name: 'DynamicTable', | ||
21 | components: { FixedThead, UnfixedThead } | ||
22 | } | ||
23 | </script> | ||
24 | |||
25 |
src/views/table/index.vue
1 | <template> | File was deleted | |
2 | <div class="app-container"> | ||
3 | <el-table | ||
4 | v-loading="listLoading" | ||
5 | :data="list" | ||
6 | element-loading-text="Loading" | ||
7 | border | ||
8 | fit | ||
9 | highlight-current-row | ||
10 | > | ||
11 | <el-table-column align="center" label="用户id"> | ||
12 | <template slot-scope="scope">{{ scope.$index }}</template> | ||
13 | </el-table-column> | ||
14 | |||
15 | <el-table-column label="openid"> | ||
16 | <template slot-scope="scope">{{ scope.row.openid }}</template> | ||
17 | </el-table-column> | ||
18 | |||
19 | <el-table-column label="昵称" width="110" align="center"> | ||
20 | <template slot-scope="scope"> | ||
21 | <span>{{ scope.row.username }}</span> | ||
22 | </template> | ||
23 | </el-table-column> | ||
24 | |||
25 | <el-table-column label="头像" width="110" align="center"> | ||
26 | <template slot-scope="scope">{{ scope.row.avatar }}</template> | ||
27 | </el-table-column> | ||
28 | |||
29 | <el-table-column class-name="status-col" label="状态" align="center"> | ||
30 | <template slot-scope="scope"> | ||
31 | <el-tag :type="scope.row.status | statusFilter">{{ scope.row.status }}</el-tag> | ||
32 | </template> | ||
33 | </el-table-column> | ||
34 | |||
35 | <el-table-column align="center" prop="created_at" label="注册时间"> | ||
36 | <template slot-scope="scope"> | ||
37 | <i class="el-icon-time" /> | ||
38 | <span>{{ scope.row.create_at }}</span> | ||
39 | </template> | ||
40 | </el-table-column> | ||
41 | <el-table-column align="center" prop="created_at" label="成交记录"> | ||
42 | <template slot-scope="scope"> | ||
43 | <i class="el-icon-time" /> | ||
44 | <span>{{ scope.row.pageviews }}</span> | ||
45 | </template> | ||
46 | </el-table-column> | ||
47 | <el-table-column align="center" prop="created_at" label="引流图"> | ||
48 | <template slot-scope="scope"> | ||
49 | <span> | ||
50 | <el-button type="primary">子用户{{scope.row.pageviews}}</el-button> | ||
51 | </span> | ||
52 | </template> | ||
53 | </el-table-column> | ||
54 | </el-table> | ||
55 | <el-pagination background layout="prev, pager, next" :total="100"></el-pagination> | ||
56 | </div> | ||
57 | </template> | ||
58 | |||
59 | <script> | ||
60 | import { getList } from "@/api/table"; | ||
61 | |||
62 | export default { | ||
63 | filters: { | ||
64 | statusFilter(status) { | ||
65 | const statusMap = { | ||
66 | published: "success", | ||
67 | draft: "gray", | ||
68 | deleted: "danger" | ||
69 | }; | ||
70 | return statusMap[status]; | ||
71 | } | ||
72 | }, | ||
73 | data() { | ||
74 | return { | ||
75 | list: null, | ||
76 | listLoading: true | ||
77 | }; | ||
78 | }, | ||
79 | created() { | ||
80 | this.fetchData(); | ||
81 | }, | ||
82 | methods: { | ||
83 | fetchData() { | ||
84 | this.listLoading = true; | ||
85 | getList().then(response => { | ||
86 | console.log("----getList---", response); | ||
87 | this.list = response.items; | ||
88 | this.listLoading = false; | ||
89 | }); | ||
90 | } | ||
91 | } | ||
92 | }; | ||
93 | </script> | ||
94 | 1 | <template> |
src/views/table/inline-edit-table.vue
File was created | 1 | <template> | |
2 | <div class="app-container"> | ||
3 | <el-table v-loading="listLoading" :data="list" border fit highlight-current-row style="width: 100%"> | ||
4 | <el-table-column align="center" label="ID" width="80"> | ||
5 | <template slot-scope="{row}"> | ||
6 | <span>{{ row.id }}</span> | ||
7 | </template> | ||
8 | </el-table-column> | ||
9 | |||
10 | <el-table-column width="180px" align="center" label="Date"> | ||
11 | <template slot-scope="{row}"> | ||
12 | <span>{{ row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span> | ||
13 | </template> | ||
14 | </el-table-column> | ||
15 | |||
16 | <el-table-column width="120px" align="center" label="Author"> | ||
17 | <template slot-scope="{row}"> | ||
18 | <span>{{ row.author }}</span> | ||
19 | </template> | ||
20 | </el-table-column> | ||
21 | |||
22 | <el-table-column width="100px" label="Importance"> | ||
23 | <template slot-scope="{row}"> | ||
24 | <svg-icon v-for="n in + row.importance" :key="n" icon-class="star" class="meta-item__icon" /> | ||
25 | </template> | ||
26 | </el-table-column> | ||
27 | |||
28 | <el-table-column class-name="status-col" label="Status" width="110"> | ||
29 | <template slot-scope="{row}"> | ||
30 | <el-tag :type="row.status | statusFilter"> | ||
31 | {{ row.status }} | ||
32 | </el-tag> | ||
33 | </template> | ||
34 | </el-table-column> | ||
35 | |||
36 | <el-table-column min-width="300px" label="Title"> | ||
37 | <template slot-scope="{row}"> | ||
38 | <template v-if="row.edit"> | ||
39 | <el-input v-model="row.title" class="edit-input" size="small" /> | ||
40 | <el-button | ||
41 | class="cancel-btn" | ||
42 | size="small" | ||
43 | icon="el-icon-refresh" | ||
44 | type="warning" | ||
45 | @click="cancelEdit(row)" | ||
46 | > | ||
47 | cancel | ||
48 | </el-button> | ||
49 | </template> | ||
50 | <span v-else>{{ row.title }}</span> | ||
51 | </template> | ||
52 | </el-table-column> | ||
53 | |||
54 | <el-table-column align="center" label="Actions" width="120"> | ||
55 | <template slot-scope="{row}"> | ||
56 | <el-button | ||
57 | v-if="row.edit" | ||
58 | type="success" | ||
59 | size="small" | ||
60 | icon="el-icon-circle-check-outline" | ||
61 | @click="confirmEdit(row)" | ||
62 | > | ||
63 | Ok | ||
64 | </el-button> | ||
65 | <el-button | ||
66 | v-else | ||
67 | type="primary" | ||
68 | size="small" | ||
69 | icon="el-icon-edit" | ||
70 | @click="row.edit=!row.edit" | ||
71 | > | ||
72 | Edit | ||
73 | </el-button> | ||
74 | </template> | ||
75 | </el-table-column> | ||
76 | </el-table> | ||
77 | </div> | ||
78 | </template> | ||
79 | |||
80 | <script> | ||
81 | import { fetchList } from '@/api/article' | ||
82 | |||
83 | export default { | ||
84 | name: 'InlineEditTable', | ||
85 | filters: { | ||
86 | statusFilter(status) { | ||
87 | const statusMap = { | ||
88 | published: 'success', | ||
89 | draft: 'info', | ||
90 | deleted: 'danger' | ||
91 | } | ||
92 | return statusMap[status] | ||
93 | } | ||
94 | }, | ||
95 | data() { | ||
96 | return { | ||
97 | list: null, | ||
98 | listLoading: true, | ||
99 | listQuery: { | ||
100 | page: 1, | ||
101 | limit: 10 | ||
102 | } | ||
103 | } | ||
104 | }, | ||
105 | created() { | ||
106 | this.getList() | ||
107 | }, | ||
108 | methods: { | ||
109 | async getList() { | ||
110 | this.listLoading = true | ||
111 | const { data } = await fetchList(this.listQuery) | ||
112 | const items = data.items | ||
113 | this.list = items.map(v => { | ||
114 | this.$set(v, 'edit', false) // https://vuejs.org/v2/guide/reactivity.html | ||
115 | v.originalTitle = v.title // will be used when user click the cancel botton | ||
116 | return v | ||
117 | }) | ||
118 | this.listLoading = false | ||
119 | }, | ||
120 | cancelEdit(row) { | ||
121 | row.title = row.originalTitle | ||
122 | row.edit = false | ||
123 | this.$message({ | ||
124 | message: 'The title has been restored to the original value', | ||
125 | type: 'warning' | ||
126 | }) | ||
127 | }, | ||
128 | confirmEdit(row) { | ||
129 | row.edit = false | ||
130 | row.originalTitle = row.title | ||
131 | this.$message({ | ||
132 | message: 'The title has been edited', | ||
133 | type: 'success' | ||
134 | }) | ||
135 | } | ||
136 | } | ||
137 | } | ||
138 | </script> | ||
139 | |||
140 | <style scoped> | ||
141 | .edit-input { | ||
142 | padding-right: 100px; | ||
143 | } | ||
144 | .cancel-btn { | ||
145 | position: absolute; | ||
146 | right: 15px; | ||
147 | top: 10px; | ||
148 | } | ||
149 | </style> | ||
150 |
src/views/theme/index.vue
File was created | 1 | <template> | |
2 | <div class="app-container"> | ||
3 | <el-card class="box-card"> | ||
4 | <div slot="header"> | ||
5 | <a class="link-type link-title" target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/guide/advanced/theme.html"> | ||
6 | {{ $t('theme.documentation') }} | ||
7 | </a> | ||
8 | </div> | ||
9 | <div class="box-item"> | ||
10 | <span class="field-label">{{ $t('theme.change') }} : </span> | ||
11 | <el-switch v-model="theme" /> | ||
12 | <aside style="margin-top:15px;">{{ $t('theme.tips') }}</aside> | ||
13 | </div> | ||
14 | </el-card> | ||
15 | |||
16 | <div class="block"> | ||
17 | <el-button type="primary"> | ||
18 | Primary | ||
19 | </el-button> | ||
20 | <el-button type="success"> | ||
21 | Success | ||
22 | </el-button> | ||
23 | <el-button type="info"> | ||
24 | Info | ||
25 | </el-button> | ||
26 | <el-button type="warning"> | ||
27 | Warning | ||
28 | </el-button> | ||
29 | <el-button type="danger"> | ||
30 | Danger | ||
31 | </el-button> | ||
32 | </div> | ||
33 | |||
34 | <div class="block"> | ||
35 | <el-button type="primary" icon="el-icon-edit" /> | ||
36 | <el-button type="primary" icon="el-icon-share" /> | ||
37 | <el-button type="primary" icon="el-icon-delete" /> | ||
38 | <el-button type="primary" icon="el-icon-search"> | ||
39 | Search | ||
40 | </el-button> | ||
41 | <el-button type="primary"> | ||
42 | Upload | ||
43 | <i class="el-icon-upload el-icon-right" /> | ||
44 | </el-button> | ||
45 | </div> | ||
46 | |||
47 | <div class="block"> | ||
48 | <el-tag v-for="tag in tags" :key="tag.type" :type="tag.type" class="tag-item"> | ||
49 | {{ tag.name }} | ||
50 | </el-tag> | ||
51 | </div> | ||
52 | |||
53 | <div class="block"> | ||
54 | <el-radio-group v-model="radio"> | ||
55 | <el-radio :label="3"> | ||
56 | Option A | ||
57 | </el-radio> | ||
58 | <el-radio :label="6"> | ||
59 | Option B | ||
60 | </el-radio> | ||
61 | <el-radio :label="9"> | ||
62 | Option C | ||
63 | </el-radio> | ||
64 | </el-radio-group> | ||
65 | </div> | ||
66 | |||
67 | <div class="block"> | ||
68 | <el-slider v-model="slideValue" /> | ||
69 | </div> | ||
70 | </div> | ||
71 | </template> | ||
72 | |||
73 | <script> | ||
74 | import { toggleClass } from '@/utils' | ||
75 | import '@/assets/custom-theme/index.css' // the theme changed version element-ui css | ||
76 | |||
77 | export default { | ||
78 | name: 'Theme', | ||
79 | data() { | ||
80 | return { | ||
81 | theme: false, | ||
82 | tags: [ | ||
83 | { name: 'Tag One', type: '' }, | ||
84 | { name: 'Tag Two', type: 'info' }, | ||
85 | { name: 'Tag Three', type: 'success' }, | ||
86 | { name: 'Tag Four', type: 'warning' }, | ||
87 | { name: 'Tag Five', type: 'danger' } | ||
88 | ], | ||
89 | slideValue: 50, | ||
90 | radio: 3 | ||
91 | } | ||
92 | }, | ||
93 | watch: { | ||
94 | theme() { | ||
95 | toggleClass(document.body, 'custom-theme') | ||
96 | } | ||
97 | } | ||
98 | } | ||
99 | </script> | ||
100 | |||
101 | <style scoped> | ||
102 | .field-label{ | ||
103 | vertical-align: middle; | ||
104 | } | ||
105 | .box-card { | ||
106 | width: 400px; | ||
107 | max-width: 100%; | ||
108 | margin: 20px auto; | ||
109 | } | ||
110 | |||
111 | .block { | ||
112 | padding: 30px 24px; | ||
113 | } | ||
114 | |||
115 | .tag-item { | ||
116 | margin-right: 15px; | ||
117 | } | ||
118 | </style> | ||
119 |
src/views/tree/index.vue
1 | <template> | File was deleted | |
2 | <div class="app-container"> | ||
3 | <el-input v-model="filterText" placeholder="Filter keyword" style="margin-bottom:30px;" /> | ||
4 | |||
5 | <el-tree | ||
6 | ref="tree2" | ||
7 | :data="data2" | ||
8 | :props="defaultProps" | ||
9 | :filter-node-method="filterNode" | ||
10 | class="filter-tree" | ||
11 | default-expand-all | ||
12 | /> | ||
13 | |||
14 | </div> | ||
15 | </template> | ||
16 | |||
17 | <script> | ||
18 | export default { | ||
19 | |||
20 | data() { | ||
21 | return { | ||
22 | filterText: '', | ||
23 | data2: [{ | ||
24 | id: 1, | ||
25 | label: 'Level one 1', | ||
26 | children: [{ | ||
27 | id: 4, | ||
28 | label: 'Level two 1-1', | ||
29 | children: [{ | ||
30 | id: 9, | ||
31 | label: 'Level three 1-1-1' | ||
32 | }, { | ||
33 | id: 10, | ||
34 | label: 'Level three 1-1-2' | ||
35 | }] | ||
36 | }] | ||
37 | }, { | ||
38 | id: 2, | ||
39 | label: 'Level one 2', | ||
40 | children: [{ | ||
41 | id: 5, | ||
42 | label: 'Level two 2-1' | ||
43 | }, { | ||
44 | id: 6, | ||
45 | label: 'Level two 2-2' | ||
46 | }] | ||
47 | }, { | ||
48 | id: 3, | ||
49 | label: 'Level one 3', | ||
50 | children: [{ | ||
51 | id: 7, | ||
52 | label: 'Level two 3-1' | ||
53 | }, { | ||
54 | id: 8, | ||
55 | label: 'Level two 3-2' | ||
56 | }] | ||
57 | }], | ||
58 | defaultProps: { | ||
59 | children: 'children', | ||
60 | label: 'label' | ||
61 | } | ||
62 | } | ||
63 | }, | ||
64 | watch: { | ||
65 | filterText(val) { | ||
66 | this.$refs.tree2.filter(val) | ||
67 | } | ||
68 | }, | ||
69 | |||
70 | methods: { | ||
71 | filterNode(value, data) { | ||
72 | if (!value) return true | ||
73 | return data.label.indexOf(value) !== -1 | ||
74 | } | ||
75 | } | ||
76 | } | ||
77 | </script> | ||
78 | |||
79 | 1 | <template> |
src/views/zip/index.vue
File was created | 1 | <template> | |
2 | <div class="app-container"> | ||
3 | <!-- $t is vue-i18n global function to translate lang --> | ||
4 | <el-input v-model="filename" :placeholder="$t('zip.placeholder')" style="width:300px;" prefix-icon="el-icon-document" /> | ||
5 | <el-button :loading="downloadLoading" style="margin-bottom:20px;" type="primary" icon="el-icon-document" @click="handleDownload"> | ||
6 | {{ $t('zip.export') }} Zip | ||
7 | </el-button> | ||
8 | <el-table v-loading="listLoading" :data="list" element-loading-text="拼命加载中" border fit highlight-current-row> | ||
9 | <el-table-column align="center" label="ID" width="95"> | ||
10 | <template slot-scope="scope"> | ||
11 | {{ scope.$index }} | ||
12 | </template> | ||
13 | </el-table-column> | ||
14 | <el-table-column label="Title"> | ||
15 | <template slot-scope="scope"> | ||
16 | {{ scope.row.title }} | ||
17 | </template> | ||
18 | </el-table-column> | ||
19 | <el-table-column label="Author" width="95" align="center"> | ||
20 | <template slot-scope="scope"> | ||
21 | <el-tag>{{ scope.row.author }}</el-tag> | ||
22 | </template> | ||
23 | </el-table-column> | ||
24 | <el-table-column label="Readings" width="115" align="center"> | ||
25 | <template slot-scope="scope"> | ||
26 | {{ scope.row.pageviews }} | ||
27 | </template> | ||
28 | </el-table-column> | ||
29 | <el-table-column align="center" label="Date" width="220"> | ||
30 | <template slot-scope="scope"> | ||
31 | <i class="el-icon-time" /> | ||
32 | <span>{{ scope.row.display_time }}</span> | ||
33 | </template> | ||
34 | </el-table-column> | ||
35 | </el-table> | ||
36 | </div> | ||
37 | </template> | ||
38 | |||
39 | <script> | ||
40 | import { fetchList } from '@/api/article' | ||
41 | |||
42 | export default { | ||
43 | name: 'ExportZip', | ||
44 | data() { | ||
45 | return { | ||
46 | list: null, | ||
47 | listLoading: true, | ||
48 | downloadLoading: false, | ||
49 | filename: '' | ||
50 | } | ||
51 | }, | ||
52 | created() { | ||
53 | this.fetchData() | ||
54 | }, | ||
55 | methods: { | ||
56 | async fetchData() { | ||
57 | this.listLoading = true | ||
58 | const { data } = await fetchList() | ||
59 | this.list = data.items | ||
60 | this.listLoading = false | ||
61 | }, | ||
62 | handleDownload() { | ||
63 | this.downloadLoading = true | ||
64 | import('@/vendor/Export2Zip').then(zip => { | ||
65 | const tHeader = ['Id', 'Title', 'Author', 'Readings', 'Date'] | ||
66 | const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time'] | ||
67 | const list = this.list | ||
68 | const data = this.formatJson(filterVal, list) | ||
69 | zip.export_txt_to_zip(tHeader, data, this.filename, this.filename) | ||
70 | this.downloadLoading = false | ||
71 | }) | ||
72 | }, | ||
73 | formatJson(filterVal, jsonData) { | ||
74 | return jsonData.map(v => filterVal.map(j => v[j])) | ||
75 | } | ||
76 | } | ||
77 | } | ||
78 | </script> | ||
79 |
1 | module.exports = { | 1 | module.exports = { |
2 | env: { | 2 | env: { |
3 | jest: true | 3 | jest: true |
4 | } | 4 | } |
5 | } | 5 | } |
6 | 6 |
tests/unit/components/Breadcrumb.spec.js
1 | import { mount, createLocalVue } from '@vue/test-utils' | File was deleted | |
2 | import VueRouter from 'vue-router' | ||
3 | import ElementUI from 'element-ui' | ||
4 | import Breadcrumb from '@/components/Breadcrumb/index.vue' | ||
5 | |||
6 | const localVue = createLocalVue() | ||
7 | localVue.use(VueRouter) | ||
8 | localVue.use(ElementUI) | ||
9 | |||
10 | const routes = [ | ||
11 | { | ||
12 | path: '/', | ||
13 | name: 'home', | ||
14 | children: [{ | ||
15 | path: 'dashboard', | ||
16 | name: 'dashboard' | ||
17 | }] | ||
18 | }, | ||
19 | { | ||
20 | path: '/menu', | ||
21 | name: 'menu', | ||
22 | children: [{ | ||
23 | path: 'menu1', | ||
24 | name: 'menu1', | ||
25 | meta: { title: 'menu1' }, | ||
26 | children: [{ | ||
27 | path: 'menu1-1', | ||
28 | name: 'menu1-1', | ||
29 | meta: { title: 'menu1-1' } | ||
30 | }, | ||
31 | { | ||
32 | path: 'menu1-2', | ||
33 | name: 'menu1-2', | ||
34 | redirect: 'noredirect', | ||
35 | meta: { title: 'menu1-2' }, | ||
36 | children: [{ | ||
37 | path: 'menu1-2-1', | ||
38 | name: 'menu1-2-1', | ||
39 | meta: { title: 'menu1-2-1' } | ||
40 | }, | ||
41 | { | ||
42 | path: 'menu1-2-2', | ||
43 | name: 'menu1-2-2' | ||
44 | }] | ||
45 | }] | ||
46 | }] | ||
47 | }] | ||
48 | |||
49 | const router = new VueRouter({ | ||
50 | routes | ||
51 | }) | ||
52 | |||
53 | describe('Breadcrumb.vue', () => { | ||
54 | const wrapper = mount(Breadcrumb, { | ||
55 | localVue, | ||
56 | router | ||
57 | }) | ||
58 | it('dashboard', () => { | ||
59 | router.push('/dashboard') | ||
60 | const len = wrapper.findAll('.el-breadcrumb__inner').length | ||
61 | expect(len).toBe(1) | ||
62 | }) | ||
63 | it('normal route', () => { | ||
64 | router.push('/menu/menu1') | ||
65 | const len = wrapper.findAll('.el-breadcrumb__inner').length | ||
66 | expect(len).toBe(2) | ||
67 | }) | ||
68 | it('nested route', () => { | ||
69 | router.push('/menu/menu1/menu1-2/menu1-2-1') | ||
70 | const len = wrapper.findAll('.el-breadcrumb__inner').length | ||
71 | expect(len).toBe(4) | ||
72 | }) | ||
73 | it('no meta.title', () => { | ||
74 | router.push('/menu/menu1/menu1-2/menu1-2-2') | ||
75 | const len = wrapper.findAll('.el-breadcrumb__inner').length | ||
76 | expect(len).toBe(3) | ||
77 | }) | ||
78 | // it('click link', () => { | ||
79 | // router.push('/menu/menu1/menu1-2/menu1-2-2') | ||
80 | // const breadcrumbArray = wrapper.findAll('.el-breadcrumb__inner') | ||
81 | // const second = breadcrumbArray.at(1) | ||
82 | // console.log(breadcrumbArray) | ||
83 | // const href = second.find('a').attributes().href | ||
84 | // expect(href).toBe('#/menu/menu1') | ||
85 | // }) | ||
86 | // it('noRedirect', () => { | ||
87 | // router.push('/menu/menu1/menu1-2/menu1-2-1') | ||
88 | // const breadcrumbArray = wrapper.findAll('.el-breadcrumb__inner') | ||
89 | // const redirectBreadcrumb = breadcrumbArray.at(2) | ||
90 | // expect(redirectBreadcrumb.contains('a')).toBe(false) | ||
91 | // }) | ||
92 | it('last breadcrumb', () => { | ||
93 | router.push('/menu/menu1/menu1-2/menu1-2-1') | ||
94 | const breadcrumbArray = wrapper.findAll('.el-breadcrumb__inner') | ||
95 | const redirectBreadcrumb = breadcrumbArray.at(3) | ||
96 | expect(redirectBreadcrumb.contains('a')).toBe(false) | ||
97 | }) | ||
98 | }) | ||
99 | 1 | import { mount, createLocalVue } from '@vue/test-utils' |
1 | import { shallowMount } from '@vue/test-utils' | 1 | import { shallowMount } from '@vue/test-utils' |
2 | import Hamburger from '@/components/Hamburger/index.vue' | 2 | import Hamburger from '@/components/Hamburger/index.vue' |
3 | describe('Hamburger.vue', () => { | 3 | describe('Hamburger.vue', () => { |
4 | it('toggle click', () => { | 4 | it('toggle click', () => { |
5 | const wrapper = shallowMount(Hamburger) | 5 | const wrapper = shallowMount(Hamburger) |
6 | const mockFn = jest.fn() | 6 | const mockFn = jest.fn() |
7 | wrapper.vm.$on('toggleClick', mockFn) | 7 | wrapper.vm.$on('toggleClick', mockFn) |
8 | wrapper.find('.hamburger').trigger('click') | 8 | wrapper.find('.hamburger').trigger('click') |
9 | expect(mockFn).toBeCalled() | 9 | expect(mockFn).toBeCalled() |
10 | }) | 10 | }) |
11 | it('prop isActive', () => { | 11 | it('prop isActive', () => { |
12 | const wrapper = shallowMount(Hamburger) | 12 | const wrapper = shallowMount(Hamburger) |
13 | wrapper.setProps({ isActive: true }) | 13 | wrapper.setProps({ isActive: true }) |
14 | expect(wrapper.contains('.is-active')).toBe(true) | 14 | expect(wrapper.contains('.is-active')).toBe(true) |
15 | wrapper.setProps({ isActive: false }) | 15 | wrapper.setProps({ isActive: false }) |
16 | expect(wrapper.contains('.is-active')).toBe(false) | 16 | expect(wrapper.contains('.is-active')).toBe(false) |
17 | }) | 17 | }) |
18 | }) | 18 | }) |
19 | 19 |
1 | import { shallowMount } from '@vue/test-utils' | 1 | import { shallowMount } from '@vue/test-utils' |
2 | import SvgIcon from '@/components/SvgIcon/index.vue' | 2 | import SvgIcon from '@/components/SvgIcon/index.vue' |
3 | describe('SvgIcon.vue', () => { | 3 | describe('SvgIcon.vue', () => { |
4 | it('iconClass', () => { | 4 | it('iconClass', () => { |
5 | const wrapper = shallowMount(SvgIcon, { | 5 | const wrapper = shallowMount(SvgIcon, { |
6 | propsData: { | 6 | propsData: { |
7 | iconClass: 'test' | 7 | iconClass: 'test' |
8 | } | 8 | } |
9 | }) | 9 | }) |
10 | expect(wrapper.find('use').attributes().href).toBe('#icon-test') | 10 | expect(wrapper.find('use').attributes().href).toBe('#icon-test') |
11 | }) | 11 | }) |
12 | it('className', () => { | 12 | it('className', () => { |
13 | const wrapper = shallowMount(SvgIcon, { | 13 | const wrapper = shallowMount(SvgIcon, { |
14 | propsData: { | 14 | propsData: { |
15 | iconClass: 'test' | 15 | iconClass: 'test' |
16 | } | 16 | } |
17 | }) | 17 | }) |
18 | expect(wrapper.classes().length).toBe(1) | 18 | expect(wrapper.classes().length).toBe(1) |
19 | wrapper.setProps({ className: 'test' }) | 19 | wrapper.setProps({ className: 'test' }) |
20 | expect(wrapper.classes().includes('test')).toBe(true) | 20 | expect(wrapper.classes().includes('test')).toBe(true) |
21 | }) | 21 | }) |
22 | }) | 22 | }) |
23 | 23 |
tests/unit/utils/formatTime.spec.js
1 | import { formatTime } from '@/utils/index.js' | 1 | import { formatTime } from '@/utils/index.js' |
2 | |||
3 | describe('Utils:formatTime', () => { | 2 | describe('Utils:formatTime', () => { |
4 | const d = new Date('2018-07-13 17:54:01') // "2018-07-13 17:54:01" | 3 | const d = new Date('2018-07-13 17:54:01') // "2018-07-13 17:54:01" |
5 | const retrofit = 5 * 1000 | 4 | const retrofit = 5 * 1000 |
6 | 5 | ||
7 | it('ten digits timestamp', () => { | 6 | it('ten digits timestamp', () => { |
8 | expect(formatTime((d / 1000).toFixed(0))).toBe('7月13日17时54分') | 7 | expect(formatTime((d / 1000).toFixed(0))).toBe('7月13日17时54分') |
9 | }) | 8 | }) |
10 | it('test now', () => { | 9 | it('test now', () => { |
11 | expect(formatTime(+new Date() - 1)).toBe('刚刚') | 10 | expect(formatTime(+new Date() - 1)).toBe('刚刚') |
12 | }) | 11 | }) |
13 | it('less two minute', () => { | 12 | it('less two minute', () => { |
14 | expect(formatTime(+new Date() - 60 * 2 * 1000 + retrofit)).toBe('2分钟前') | 13 | expect(formatTime(+new Date() - 60 * 2 * 1000 + retrofit)).toBe('2分钟前') |
15 | }) | 14 | }) |
16 | it('less two hour', () => { | 15 | it('less two hour', () => { |
17 | expect(formatTime(+new Date() - 60 * 60 * 2 * 1000 + retrofit)).toBe('2小时前') | 16 | expect(formatTime(+new Date() - 60 * 60 * 2 * 1000 + retrofit)).toBe('2小时前') |
18 | }) | 17 | }) |
19 | it('less one day', () => { | 18 | it('less one day', () => { |
20 | expect(formatTime(+new Date() - 60 * 60 * 24 * 1 * 1000)).toBe('1天前') | 19 | expect(formatTime(+new Date() - 60 * 60 * 24 * 1 * 1000)).toBe('1天前') |
21 | }) | 20 | }) |
22 | it('more than one day', () => { | 21 | it('more than one day', () => { |
23 | expect(formatTime(d)).toBe('7月13日17时54分') | 22 | expect(formatTime(d)).toBe('7月13日17时54分') |
24 | }) | 23 | }) |
25 | it('format', () => { | 24 | it('format', () => { |
26 | expect(formatTime(d, '{y}-{m}-{d} {h}:{i}')).toBe('2018-07-13 17:54') | 25 | expect(formatTime(d, '{y}-{m}-{d} {h}:{i}')).toBe('2018-07-13 17:54') |
27 | expect(formatTime(d, '{y}-{m}-{d}')).toBe('2018-07-13') | 26 | expect(formatTime(d, '{y}-{m}-{d}')).toBe('2018-07-13') |
28 | expect(formatTime(d, '{y}/{m}/{d} {h}-{i}')).toBe('2018/07/13 17-54') | 27 | expect(formatTime(d, '{y}/{m}/{d} {h}-{i}')).toBe('2018/07/13 17-54') |
29 | }) | 28 | }) |
30 | }) | 29 | }) |
31 | 30 |
tests/unit/utils/parseTime.spec.js
1 | import { parseTime } from '@/utils/index.js' | 1 | import { parseTime } from '@/utils/index.js' |
2 | |||
3 | describe('Utils:parseTime', () => { | 2 | describe('Utils:parseTime', () => { |
4 | const d = new Date('2018-07-13 17:54:01') // "2018-07-13 17:54:01" | 3 | const d = new Date('2018-07-13 17:54:01') // "2018-07-13 17:54:01" |
5 | it('timestamp', () => { | 4 | it('timestamp', () => { |
6 | expect(parseTime(d)).toBe('2018-07-13 17:54:01') | 5 | expect(parseTime(d)).toBe('2018-07-13 17:54:01') |
7 | }) | 6 | }) |
8 | it('ten digits timestamp', () => { | 7 | it('ten digits timestamp', () => { |
9 | expect(parseTime((d / 1000).toFixed(0))).toBe('2018-07-13 17:54:01') | 8 | expect(parseTime((d / 1000).toFixed(0))).toBe('2018-07-13 17:54:01') |
10 | }) | 9 | }) |
11 | it('new Date', () => { | 10 | it('new Date', () => { |
12 | expect(parseTime(new Date(d))).toBe('2018-07-13 17:54:01') | 11 | expect(parseTime(new Date(d))).toBe('2018-07-13 17:54:01') |
13 | }) | 12 | }) |
14 | it('format', () => { | 13 | it('format', () => { |
15 | expect(parseTime(d, '{y}-{m}-{d} {h}:{i}')).toBe('2018-07-13 17:54') | 14 | expect(parseTime(d, '{y}-{m}-{d} {h}:{i}')).toBe('2018-07-13 17:54') |
16 | expect(parseTime(d, '{y}-{m}-{d}')).toBe('2018-07-13') | 15 | expect(parseTime(d, '{y}-{m}-{d}')).toBe('2018-07-13') |
17 | expect(parseTime(d, '{y}/{m}/{d} {h}-{i}')).toBe('2018/07/13 17-54') | 16 | expect(parseTime(d, '{y}/{m}/{d} {h}-{i}')).toBe('2018/07/13 17-54') |
18 | }) | 17 | }) |
19 | it('get the day of the week', () => { | 18 | it('get the day of the week', () => { |
20 | expect(parseTime(d, '{a}')).toBe('五') // 星期五 | 19 | expect(parseTime(d, '{a}')).toBe('五') // 星期五 |
21 | }) | 20 | }) |
22 | it('get the day of the week', () => { | 21 | it('get the day of the week', () => { |
23 | expect(parseTime(+d + 1000 * 60 * 60 * 24 * 2, '{a}')).toBe('日') // 星期日 | 22 | expect(parseTime(+d + 1000 * 60 * 60 * 24 * 2, '{a}')).toBe('日') // 星期日 |
24 | }) | 23 | }) |
25 | it('empty argument', () => { | 24 | it('empty argument', () => { |
26 | expect(parseTime()).toBeNull() | 25 | expect(parseTime()).toBeNull() |
27 | }) | 26 | }) |
28 | }) | 27 | }) |
29 | 28 |
tests/unit/utils/validate.spec.js
1 | import { validUsername, isExternal } from '@/utils/validate.js' | 1 | import { validUsername, validURL, validLowerCase, validUpperCase, validAlphabets } from '@/utils/validate.js' |
2 | |||
3 | describe('Utils:validate', () => { | 2 | describe('Utils:validate', () => { |
4 | it('validUsername', () => { | 3 | it('validUsername', () => { |
5 | expect(validUsername('admin')).toBe(true) | 4 | expect(validUsername('admin')).toBe(true) |
6 | expect(validUsername('editor')).toBe(true) | 5 | expect(validUsername('editor')).toBe(true) |
7 | expect(validUsername('xxxx')).toBe(false) | 6 | expect(validUsername('xxxx')).toBe(false) |
8 | }) | 7 | }) |
9 | it('isExternal', () => { | 8 | it('validURL', () => { |
10 | expect(isExternal('https://github.com/PanJiaChen/vue-element-admin')).toBe(true) | 9 | expect(validURL('https://github.com/PanJiaChen/vue-element-admin')).toBe(true) |
11 | expect(isExternal('http://github.com/PanJiaChen/vue-element-admin')).toBe(true) | 10 | expect(validURL('http://github.com/PanJiaChen/vue-element-admin')).toBe(true) |
12 | expect(isExternal('github.com/PanJiaChen/vue-element-admin')).toBe(false) | 11 | expect(validURL('github.com/PanJiaChen/vue-element-admin')).toBe(false) |
13 | expect(isExternal('/dashboard')).toBe(false) | 12 | }) |
14 | expect(isExternal('./dashboard')).toBe(false) | 13 | it('validLowerCase', () => { |
15 | expect(isExternal('dashboard')).toBe(false) | 14 | expect(validLowerCase('abc')).toBe(true) |
15 | expect(validLowerCase('Abc')).toBe(false) | ||
16 | expect(validLowerCase('123abc')).toBe(false) | ||
17 | }) | ||
18 | it('validUpperCase', () => { | ||
19 | expect(validUpperCase('ABC')).toBe(true) | ||
20 | expect(validUpperCase('Abc')).toBe(false) | ||
21 | expect(validUpperCase('123ABC')).toBe(false) | ||
22 | }) | ||
23 | it('validAlphabets', () => { | ||
24 | expect(validAlphabets('ABC')).toBe(true) | ||
25 | expect(validAlphabets('Abc')).toBe(true) | ||
26 | expect(validAlphabets('123aBC')).toBe(false) | ||
16 | }) | 27 | }) |
17 | }) | 28 | }) |
vue.config.js
1 | 'use strict' | 1 | 'use strict' |
2 | const path = require('path') | 2 | const path = require('path') |
3 | const defaultSettings = require('./src/settings.js') | 3 | const defaultSettings = require('./src/settings.js') |
4 | 4 | ||
5 | function resolve(dir) { | 5 | function resolve(dir) { |
6 | return path.join(__dirname, dir) | 6 | return path.join(__dirname, dir) |
7 | } | 7 | } |
8 | 8 | ||
9 | const name = defaultSettings.title || 'vue Admin Template' // page title | 9 | const name = defaultSettings.title || 'vue Element Admin' // page title |
10 | 10 | ||
11 | // If your port is set to 80, | 11 | // If your port is set to 80, |
12 | // use administrator privileges to execute the command line. | 12 | // use administrator privileges to execute the command line. |
13 | // For example, Mac: sudo npm run | 13 | // For example, Mac: sudo npm run |
14 | // You can change the port by the following methods: | 14 | // You can change the port by the following method: |
15 | // port = 9528 npm run dev OR npm run dev --port = 9528 | 15 | // port = 9527 npm run dev OR npm run dev --port = 9527 |
16 | const port = process.env.port || process.env.npm_config_port || 9528 // dev port | 16 | const port = process.env.port || process.env.npm_config_port || 9527 // dev port |
17 | 17 | ||
18 | // All configuration item explanations can be find in https://cli.vuejs.org/config/ | 18 | // All configuration item explanations can be find in https://cli.vuejs.org/config/ |
19 | module.exports = { | 19 | module.exports = { |
20 | /** | 20 | /** |
21 | * You will need to set publicPath if you plan to deploy your site under a sub path, | 21 | * You will need to set publicPath if you plan to deploy your site under a sub path, |
22 | * for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/, | 22 | * for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/, |
23 | * then publicPath should be set to "/bar/". | 23 | * then publicPath should be set to "/bar/". |
24 | * In most cases please use '/' !!! | 24 | * In most cases please use '/' !!! |
25 | * Detail: https://cli.vuejs.org/config/#publicpath | 25 | * Detail: https://cli.vuejs.org/config/#publicpath |
26 | */ | 26 | */ |
27 | publicPath: '/', | 27 | publicPath: '/', |
28 | outputDir: 'dist', | 28 | outputDir: 'dist', |
29 | assetsDir: 'static', | 29 | assetsDir: 'static', |
30 | lintOnSave: process.env.NODE_ENV === 'development', | 30 | lintOnSave: process.env.NODE_ENV === 'development', |
31 | productionSourceMap: false, | 31 | productionSourceMap: false, |
32 | devServer: { | 32 | devServer: { |
33 | port: port, | 33 | port: port, |
34 | open: true, | 34 | open: true, |
35 | overlay: { | 35 | overlay: { |
36 | warnings: false, | 36 | warnings: false, |
37 | errors: true | 37 | errors: true |
38 | }, | 38 | }, |
39 | //线下API测试时,可以去掉这个Mock数据。 | ||
40 | before: require('./mock/mock-server.js') | 39 | before: require('./mock/mock-server.js') |
41 | }, | 40 | }, |
42 | configureWebpack: { | 41 | configureWebpack: { |
43 | // provide the app's title in webpack's name field, so that | 42 | // provide the app's title in webpack's name field, so that |
44 | // it can be accessed in index.html to inject the correct title. | 43 | // it can be accessed in index.html to inject the correct title. |
45 | name: name, | 44 | name: name, |
46 | resolve: { | 45 | resolve: { |
47 | alias: { | 46 | alias: { |
48 | '@': resolve('src') | 47 | '@': resolve('src') |
49 | } | 48 | } |
50 | } | 49 | } |
51 | }, | 50 | }, |
52 | chainWebpack(config) { | 51 | chainWebpack(config) { |
53 | config.plugins.delete('preload') // TODO: need test | 52 | config.plugins.delete('preload') // TODO: need test |
54 | config.plugins.delete('prefetch') // TODO: need test | 53 | config.plugins.delete('prefetch') // TODO: need test |
55 | 54 | ||
56 | // set svg-sprite-loader | 55 | // set svg-sprite-loader |
57 | config.module | 56 | config.module |
58 | .rule('svg') | 57 | .rule('svg') |
59 | .exclude.add(resolve('src/icons')) | 58 | .exclude.add(resolve('src/icons')) |
60 | .end() | 59 | .end() |
61 | config.module | 60 | config.module |
62 | .rule('icons') | 61 | .rule('icons') |
63 | .test(/\.svg$/) | 62 | .test(/\.svg$/) |
64 | .include.add(resolve('src/icons')) | 63 | .include.add(resolve('src/icons')) |
65 | .end() | 64 | .end() |
66 | .use('svg-sprite-loader') | 65 | .use('svg-sprite-loader') |
67 | .loader('svg-sprite-loader') | 66 | .loader('svg-sprite-loader') |
68 | .options({ | 67 | .options({ |
69 | symbolId: 'icon-[name]' | 68 | symbolId: 'icon-[name]' |
70 | }) | 69 | }) |
71 | .end() | 70 | .end() |
72 | 71 | ||
73 | // set preserveWhitespace | 72 | // set preserveWhitespace |
74 | config.module | 73 | config.module |
75 | .rule('vue') | 74 | .rule('vue') |
76 | .use('vue-loader') | 75 | .use('vue-loader') |
77 | .loader('vue-loader') | 76 | .loader('vue-loader') |
78 | .tap(options => { | 77 | .tap(options => { |
79 | options.compilerOptions.preserveWhitespace = true | 78 | options.compilerOptions.preserveWhitespace = true |
80 | return options | 79 | return options |
81 | }) | 80 | }) |
82 | .end() | 81 | .end() |
83 | 82 | ||
84 | config | 83 | config |
85 | // https://webpack.js.org/configuration/devtool/#development | 84 | // https://webpack.js.org/configuration/devtool/#development |
86 | .when(process.env.NODE_ENV === 'development', | 85 | .when(process.env.NODE_ENV === 'development', |
87 | config => config.devtool('cheap-source-map') | 86 | config => config.devtool('cheap-source-map') |
88 | ) | 87 | ) |
89 | 88 | ||
90 | config | 89 | config |
91 | .when(process.env.NODE_ENV !== 'development', | 90 | .when(process.env.NODE_ENV !== 'development', |
92 | config => { | 91 | config => { |
93 | config | 92 | config |
94 | .plugin('ScriptExtHtmlWebpackPlugin') | 93 | .plugin('ScriptExtHtmlWebpackPlugin') |
95 | .after('html') | 94 | .after('html') |
96 | .use('script-ext-html-webpack-plugin', [{ | 95 | .use('script-ext-html-webpack-plugin', [{ |
97 | // `runtime` must same as runtimeChunk name. default is `runtime` | 96 | // `runtime` must same as runtimeChunk name. default is `runtime` |
98 | inline: /runtime\..*\.js$/ | 97 | inline: /runtime\..*\.js$/ |
99 | }]) | 98 | }]) |
100 | .end() | 99 | .end() |
101 | config | 100 | config |
102 | .optimization.splitChunks({ | 101 | .optimization.splitChunks({ |
103 | chunks: 'all', | 102 | chunks: 'all', |
104 | cacheGroups: { | 103 | cacheGroups: { |
105 | libs: { | 104 | libs: { |
106 | name: 'chunk-libs', | 105 | name: 'chunk-libs', |
107 | test: /[\\/]node_modules[\\/]/, | 106 | test: /[\\/]node_modules[\\/]/, |
108 | priority: 10, | 107 | priority: 10, |
109 | chunks: 'initial' // only package third parties that are initially dependent | 108 | chunks: 'initial' // only package third parties that are initially dependent |
110 | }, | 109 | }, |
111 | elementUI: { | 110 | elementUI: { |
112 | name: 'chunk-elementUI', // split elementUI into a single package | 111 | name: 'chunk-elementUI', // split elementUI into a single package |
113 | priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app | 112 | priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app |
114 | test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm | 113 | test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm |
115 | }, | 114 | }, |
116 | commons: { | 115 | commons: { |
117 | name: 'chunk-commons', | 116 | name: 'chunk-commons', |
118 | test: resolve('src/components'), // can customize your rules | 117 | test: resolve('src/components'), // can customize your rules |
119 | minChunks: 3, // minimum common number | 118 | minChunks: 3, // minimum common number |
120 | priority: 5, | 119 | priority: 5, |
121 | reuseExistingChunk: true | 120 | reuseExistingChunk: true |
122 | } | 121 | } |
123 | } | 122 | } |
124 | }) | 123 | }) |
125 | config.optimization.runtimeChunk('single') | 124 | config.optimization.runtimeChunk('single') |
126 | } | 125 | } |
127 | ) | 126 | ) |
128 | } | 127 | } |
129 | } | 128 | } |
130 | 129 |