Compare commits

...

145 Commits

Author SHA1 Message Date
Pan
e5ed2a39a5 [release] 3.0.0 2017-11-29 10:41:02 +08:00
Pan
39d26068ec doc:update readme 2017-11-29 10:33:39 +08:00
Pan
d68d464142 Merge branch 'refacor/style' 2017-11-29 10:07:28 +08:00
Pan
d476e32032 Merge branch 'master' into refacor/style 2017-11-29 10:05:09 +08:00
Pan
8f2b0c94ba fix:fixed case-sensitive bug 2017-11-28 22:28:01 +08:00
Pan
e00f2aedc7 fix:fixed case-sensitive bug 2017-11-28 18:35:27 +08:00
Pan
df28ad7078 fix:fixed case-sensitive bug 2017-11-28 18:34:57 +08:00
Pan
4feb89c94e bump:update vue version 2017-11-28 15:46:57 +08:00
Pan
a56d6f0cbd rm:remove redundant code 2017-11-27 13:58:42 +08:00
Pan
bee26561aa feat:add share demo 2017-11-27 11:47:13 +08:00
Pan
2ec9fe74a8 fix:fixed view tags bug 2017-11-27 11:11:28 +08:00
Pan
dec160fd1e chore: change inject package dependencies 2017-11-27 10:51:54 +08:00
Pan
c06baffb17 perf:format code 2017-11-27 10:46:08 +08:00
Pan
f876b9b678 perf:refine breadcrumb 2017-11-24 15:35:38 +08:00
Pan
061fa1f2a5 style:refien css 2017-11-24 14:34:19 +08:00
Pan
e0b8f09a9e perf:ignore package-lock.json 2017-11-23 16:32:02 +08:00
Pan
ede541e2f5 rm:package-lock.json 2017-11-23 16:31:33 +08:00
Pan
e0f6248d0e fix:postcss-loader sourceMap 2017-11-23 16:30:51 +08:00
Pan
1c4c3380e6 perf:change favicon 2017-11-23 10:35:54 +08:00
Pan
073b7219ff chore:refine build:prod 2017-11-23 10:33:29 +08:00
Pan
98604af104 style:refine tagsview css 2017-11-22 16:16:12 +08:00
Pan
3cb1e321d3 refactor:change tabs-view to tags-view 2017-11-22 11:21:09 +08:00
Pan
f2fcdee815 perf:format code&&fix typo 2017-11-22 11:01:19 +08:00
Pan
497b96f931 Merge branch 'refacor/style' of https://github.com/PanJiaChen/vue-element-admin into refacor/style 2017-11-22 10:01:55 +08:00
Pan
ed34ea3e07 perf:replace favicon 2017-11-22 10:01:53 +08:00
花裤衩
47a373803e Update README.md 2017-11-21 16:15:34 +08:00
花裤衩
e8ad1f835c Update README.md 2017-11-21 16:10:22 +08:00
Pan
43a51148fe refactor:dropdown menu 2017-11-21 10:37:33 +08:00
Pan
3f9df15c30 refactor:refine sidebar css 2017-11-21 10:14:20 +08:00
Pan
a9363ce541 bump:update vue 2017-11-21 09:38:43 +08:00
Pan
690c779c64 refactor:add documentation 2017-11-20 17:37:58 +08:00
Pan
f6279077de fix:handleSetLineChartData bug 2017-11-17 18:45:40 +08:00
Pan
6b9e89055d update:package.json 2017-11-17 18:27:55 +08:00
Pan
6b13ffce66 fix:fix tinymce destroy bug 2017-11-17 17:57:17 +08:00
Pan
d20585a3f9 refactor:foramt views/component-demo 2017-11-17 17:51:41 +08:00
Pan
46b4f74969 rm:remove chart/index 2017-11-17 15:10:09 +08:00
Pan
8c204b9837 rm:remove keyboard2 demo 2017-11-17 15:07:21 +08:00
Pan
339d760771 refactor:format code 2017-11-17 14:57:39 +08:00
Pan
6d6a9df5b8 refactor:views/components 2017-11-17 11:36:49 +08:00
Pan
1286324214 refactor:layout 2017-11-16 18:50:59 +08:00
Pan
372c4489f0 style:refine 404 2017-11-16 17:55:42 +08:00
Pan
1511fe3778 fix:remove semi 2017-11-16 17:26:34 +08:00
Pan
122f7cafa6 Merge branch 'refacor/style' of https://github.com/PanJiaChen/vue-element-admin into refacor/style 2017-11-16 17:25:32 +08:00
Pan
6d1059f6a8 refactor:dashboard 2017-11-16 17:25:28 +08:00
Reza Haidari .A
1d4f12187f add validate email method 2017-11-15 01:37:50 -06:00
花裤衩
925dbeb045 Update README.md 2017-11-14 00:37:12 -06:00
Pan
35055c5e51 style:breadcrumb add transition 2017-11-14 10:09:32 +08:00
Pan
e0a1e249ee update:update echarts version&&element-ui 2017-11-13 18:42:47 +08:00
Pan
a0d83e2ffc update:update echarts version 2017-11-10 13:59:52 +08:00
Pan
53059d5ccf add package-lock.json 2017-11-10 13:54:43 +08:00
Pan
fa5e6d9ecf Add postcss-loader && update echarts 2017-11-10 13:52:38 +08:00
Pan
4e25a17bff fix:fix postcss config 2017-11-09 18:27:00 +08:00
Pan
61095a9f2c refactor:refine webpack.prod.conf.js 2017-11-09 18:17:08 +08:00
Pan
61deec548c refactor:change name=> fetch.js to request.js 2017-11-07 13:55:57 +08:00
Pan
5eda0685ed add: add transition.css 2017-11-07 11:41:59 +08:00
Pan
11beefdb44 add: add variables.scss 2017-11-06 18:18:14 +08:00
Pan
7e1ba16d12 refactor:add scroll-bar to sidebar 2017-11-06 16:02:13 +08:00
Pan
7451ed6299 style:refine sidebar css 2017-11-06 15:24:04 +08:00
Pan
71aa416d71 style:refine css 2017-11-06 13:52:13 +08:00
Pan
4723a02a4b refine: refine i18n 2017-11-06 13:46:29 +08:00
Pan
e05da2650b feature:add i18n 2017-11-03 18:37:49 +08:00
Pan
bb1d939a94 reactor:refine code&&demo 2017-11-02 17:58:35 +08:00
Pan
ac5d087ea4 style:refine sidebar css 2017-11-02 15:55:56 +08:00
Pan
c53fb7fbb1 style:refine sidebar css 2017-11-02 15:51:29 +08:00
Pan
660ff765f5 fix:fix tabsView path bug 2017-11-01 18:43:06 +08:00
Pan
aaf24b4654 fix:levelbar&&tabsview bug 2017-11-01 17:55:11 +08:00
Pan
8211016078 refactor:replace custom-theme 2017-11-01 17:03:17 +08:00
Pan
374fd3ffeb feature:change theme online 2017-11-01 15:48:30 +08:00
Pan
e8b34bbc0d refactor:update element-ui 2017-11-01 11:26:57 +08:00
花裤衩
74cbb26209 Update README.md 2017-10-31 21:05:31 -05:00
Pan
fe31c88193 refactor:update element 2017-11-01 10:03:28 +08:00
Pan
3b89cde53a refactor: echarts addEventListener about resize 2017-10-31 17:25:57 +08:00
Pan
59e240eb9a upload:upload vue && change scope to slot-scope 2017-10-31 16:25:19 +08:00
Pan
98d5f9a247 lint:format code style 2017-10-31 16:04:30 +08:00
Pan
3666148ddc refactor:update package.json 2017-10-31 15:55:59 +08:00
Pan
d56831679e style:refine tabsview css 2017-10-31 14:42:58 +08:00
Pan
2c868f47d9 fix:fix tinymce bug in <keep-alive> 2017-10-31 11:06:41 +08:00
Pan
1ae31fdd45 refactor:add keep-alive && component add name 2017-10-31 10:49:24 +08:00
Pan
a932272b8f refactor:router 2017-10-26 18:27:39 +08:00
Pan
577e4dc17e refactor: case sensitive 2017-10-26 14:21:21 +08:00
Pan
0d9188b206 refactor: case sensitive 2017-10-26 14:21:03 +08:00
Pan
5b3b8b87d1 refactor:change MdEditor to MarkdownEditor 2017-10-26 14:06:32 +08:00
Pan
2c82d0a28e refactor: set markdown autoDownloadFontAwesome to false 2017-10-26 11:07:51 +08:00
Pan
913f6c8bec [release] 2.2.1 2017-10-25 17:14:57 +08:00
Pan
76f4017470 fix: fix getUserInfo by cookie bug 2017-10-25 17:12:36 +08:00
Pan
feb6785654 refactor: refine form example 2017-10-25 09:54:21 +08:00
Pan
59073fb013 refactor: add keep-alive 2017-10-25 09:54:06 +08:00
Pan
c82ed3fcbf refactor: change icon-svg to svg-icon 2017-10-24 17:43:55 +08:00
Pan
f99b97d9f1 refactor: change DndList name 2017-10-24 17:37:14 +08:00
Pan
99417081ed refactor: case sensitive 2017-10-24 17:29:32 +08:00
Pan
88d1338f29 refactor: case sensitive 2017-10-24 17:29:11 +08:00
Pan
3ded46cf23 refactor: case sensitive 2017-10-24 16:38:11 +08:00
Pan
5857db3393 refactor: case sensitive 2017-10-24 16:37:38 +08:00
Pan
a465652be6 refactor: components name 2017-10-24 16:30:46 +08:00
Pan
a8459fa572 style: refactor styles 2017-10-24 14:49:29 +08:00
Pan
cddace507d style: refine screenful style 2017-10-23 14:26:07 +08:00
Pan
e762056e80 refactor: tabsview 2017-10-23 13:45:09 +08:00
Pan
18ec63d238 style: change hamburger default style 2017-10-23 11:01:38 +08:00
Pan
ccddfe87bc refactor: refine layout directory structure 2017-10-23 10:53:39 +08:00
Pan
87a44ae7f5 doc: add note for NProgress.done 2017-10-23 10:28:19 +08:00
dingyi1993
1c852db0ef fix:fix undone NProgress. 2017-10-22 21:22:43 -05:00
Pan
9463c50e06 feature: tinymce add setContent && getContent method 2017-10-18 17:02:35 +08:00
Pan
658abf664d refine: add parseTime timestamp demo 2017-10-16 10:16:44 +08:00
spiritree
4940dd4040 fix:fix undefined bug in export excel 2017-10-12 03:46:49 -05:00
spiritree
91bd31e1e2 refine:refine code 2017-10-12 02:36:56 -05:00
spiritree
a8602e78f0 refine:export adaptive colwidth in excel 2017-10-12 02:36:56 -05:00
Pan
516897b97a Fix:fix autoprefixer explanation 2017-10-08 11:19:20 +08:00
Pan
2725285d26 fix build_config bug 2017-09-29 16:31:44 +08:00
Pan
a842a4b451 refine:refine build_config 2017-09-29 16:31:44 +08:00
Pan
be0606ebbc update echarts 2017-09-28 15:31:49 +08:00
Pan
a10de2e8d8 [release] 2.2.0 2017-09-27 10:43:53 +08:00
Pan
2282135b44 refine:refine directive waves 2017-09-27 10:34:48 +08:00
Pan
329f3b3714 refine:rm export selected to zip example 2017-09-27 10:29:32 +08:00
Pan
065eaa93a2 refine:icon demo add clipboard 2017-09-27 10:18:40 +08:00
Pan
4f2f136dd0 add:add clipboard example 2017-09-27 10:18:40 +08:00
Pan
8d53ae1259 add:add clipboard 2017-09-27 10:18:40 +08:00
spiritree
a185412446 add Export2Zip demo 2017-09-27 10:18:23 +08:00
spiritree
3cf048e80b add Export2Zip vendor 2017-09-27 10:18:23 +08:00
spiritree
fcf7c0ba50 ignore package-lock.json 2017-09-27 10:18:23 +08:00
Pan
807aa548b2 refine:rm duplicate code && split xlsx 2017-09-26 16:08:20 +08:00
Pan
db61251d89 [release] 2.1.1 2017-09-25 17:41:03 +08:00
Pan
582c6f4ae4 refine:set icon-class to english 2017-09-25 17:31:23 +08:00
Pan
9c2a7e9485 refine : format code 2017-09-25 14:21:42 +08:00
lei.jiang
fde12e8ef9 修改MdInput的demo,使之能展现验证功能 2017-09-25 11:11:37 +08:00
lei.jiang
8945476c22 修改MDinput组件
1.使之能兼容elementui的表单验证功能
2.增加icon属性,能够使用elementui的图标
3.优化显示效果
2017-09-25 11:11:37 +08:00
lei.jiang
14ff09a414 修改MDinput组件
1.使之能兼容elementui的表单验证功能
2.增加icon属性,能够使用elementui的图标
3.优化显示效果
2017-09-25 11:11:37 +08:00
Pan
a14547aaf9 add tips 2017-09-12 10:39:03 +08:00
Pan
b1311322ad [release] 2.1.0 2017-09-11 14:45:55 +08:00
Pan
ffec6b6df7 add:upload excel 2017-09-11 14:43:12 +08:00
Pan
f0afbf7ea5 refine:set page=1 when table filter 2017-09-11 11:17:29 +08:00
Pan
a4f8e0b805 Update README.md 2017-09-11 10:56:28 +08:00
花裤衩
2d72df3605 Update README.md 2017-09-08 20:10:54 +08:00
花裤衩
e9f92a7d3d Update README.md 2017-09-08 18:32:48 +08:00
花裤衩
ee362f22b2 Update README.md 2017-09-08 18:32:15 +08:00
花裤衩
11426c8494 add donate 2017-09-08 18:24:43 +08:00
Hex
fa5f5e9d26 与 vue-cli webpack 模板不一致 2017-09-08 15:53:09 +08:00
dongsuo
cda292dec1 fix blocked by AdBlock 2017-09-07 10:35:35 +08:00
Svend
877b73cd67 📝 typing fix 2017-09-06 10:20:31 +08:00
maemo
53d7243316 fix a typo 2017-09-05 13:53:24 +08:00
Pan
5379510013 refine tabsview 2017-09-01 10:59:45 +08:00
Pan
f712d4682e add:when active tabs closed will go to last path 2017-09-01 10:46:20 +08:00
Pan
cb0e889829 fix tinymce bug 2017-09-01 10:12:50 +08:00
Pan
6a8a02f839 refine tinymce 2017-09-01 10:04:08 +08:00
Pan
d56cd59474 refine code 2017-08-30 18:22:32 +08:00
Pan
a10cfcc837 add tinymce upload demo 2017-08-30 14:41:10 +08:00
198 changed files with 4568 additions and 2708 deletions

View File

@@ -1,6 +1,8 @@
{
"presets": [
["env", { "modules": false }],
["env", {
"modules": false
}],
"stage-2"
],
"plugins": ["transform-runtime"],

View File

@@ -52,7 +52,7 @@ module.exports = {
'no-class-assign': 2,
'no-cond-assign': 2,
'no-const-assign': 2,
'no-control-regex': 2,
'no-control-regex': 0,
'no-delete-var': 2,
'no-dupe-args': 2,
'no-dupe-class-members': 2,

2
.gitignore vendored
View File

@@ -1,10 +1,10 @@
.DS_Store
node_modules/
dist/
static/ckeditor
gifs/
npm-debug.log
test/unit/coverage
test/e2e/reports
selenium-debug.log
.idea
package-lock.json

View File

@@ -2,7 +2,7 @@
module.exports = {
"plugins": {
// to edit target browsers: use "browserlist" field in package.json
// to edit target browsers: use "browserslist" field in package.json
"autoprefixer": {}
}
}

View File

@@ -1,29 +1,19 @@
[![vue](https://img.shields.io/badge/vue-2.4.2-brightgreen.svg)](https://github.com/vuejs/vue)
[![element-ui](https://img.shields.io/badge/element--ui-1.4.2-brightgreen.svg)](https://github.com/ElemeFE/element)
[![license](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE)
[![GitHub release](https://img.shields.io/github/release/PanJiaChen/vue-element-admin.svg)]()
## Intro
> In the past half year, I have been building a backend for management dashboard using Vue. Though the backend has contained greater than 70 pages and over 10 permissions, it still takes insignificant effort to maintain the project. So I decide to make it open source so as to share my development experience and progress on backend. The tech stack is mainly [Vue.js](https://github.com/vuejs/vue)+[Element](https://github.com/ElemeFE/element)+[axios](https://github.com/mzabriskie/axios). Since it's a personal project, all data requests are simulated with [Mock.js](https://github.com/nuysoft/Mock). **Note:** if anyone wants to modify or develop based on this project, please remove the mock files.
**Live demo:** http://panjiachen.github.io/vue-element-admin
**Note: element-ui@1.3.3 is used in the project, so vue 2.3.0+ is required.**
**Note: element-ui@1.4.2 is used in the project, so vue 2.3.0+ is required.**
More tutorials incoming. Including articles on:
- How to build structure of a backend dashboard project from scratch
- How to make a complete user system (e.g. permission authentication, two-factor authentication)
- How to package components (e.g. rich text)
- How to integrate with [Qiniu](https://www.qiniu.com/)
- Other development experience on backend
Join the group on QQ 591724180.
**Tutorials:**
- [Wiki](https://github.com/PanJiaChen/vue-element-admin/wiki)
- [Step by step instructions on playing with backend using Vue Part 1 - Fundamentals](https://juejin.im/post/59097cd7a22b9d0065fb61d2)
- [Step by step instructions on playing with backend using Vue Part 2 - Login permission](https://juejin.im/post/591aa14f570c35006961acac)
- [Step by step instructions on packaging a Vue component](https://segmentfault.com/a/1190000009090836)
**Please read the Wiki and articles above before creating any issue. Feel free to contribute by making a pull request.**
- vueAdmin-template: [vueAdmin-template](https://github.com/PanJiaChen/vueAdmin-template)  
- electron-vue-admin: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
- Donate:[donate](https://github.com/PanJiaChen/vue-element-admin/blob/master/README-en.md#donate)
## Features
@@ -42,7 +32,9 @@ Join the group on QQ 591724180.
- ECharts
- 401, 404 error page
- Error log
- Exporting to Excel
- Export Excel
- Upload Excel
- Export Zip
- Table example
- Interactive table example
- Drag & drop table example
@@ -56,6 +48,7 @@ Join the group on QQ 591724180.
- screenfull
- markdown2html
- views-tab
- clipboard
## Development
@@ -117,6 +110,10 @@ npm run build:prod
## Changelog
Detailed changes for each release are documented in the [release notes](https://github.com/PanJiaChen/vue-element-admin/releases).
## Donate
If you find this project useful, you can buy me a cup of coffee
![donate](https://panjiachen.github.io/donate/donation.png)
## State Management
Only status of user and app configuration is managed by Vuex. Other data are managed by their own business pages.
@@ -174,3 +171,7 @@ Only status of user and app configuration is managed by Vuex. Other data are man
#### More
http://panjiachen.github.io/vue-element-admin
## License
MIT

164
README.md
View File

@@ -1,30 +1,40 @@
# vue-element-admin #
<p align="center">
<img width="320" src="https://wpimg.wallstcn.com/ecc53a42-d79b-42e2-8852-5126b810a4c8.svg">
</p>
[![vue](https://img.shields.io/badge/vue-2.4.2-brightgreen.svg)](https://github.com/vuejs/vue)
[![element-ui](https://img.shields.io/badge/element--ui-1.4.1-brightgreen.svg)](https://github.com/ElemeFE/element)
# vue-element-admin
[![vue](https://img.shields.io/badge/vue-2.5.9-brightgreen.svg)](https://github.com/vuejs/vue)
[![element-ui](https://img.shields.io/badge/element--ui-2.0.5-brightgreen.svg)](https://github.com/ElemeFE/element)
[![license](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE)
[![GitHub release](https://img.shields.io/github/release/PanJiaChen/vue-element-admin.svg)]()
A magical vue admin.
[线上地址](http://panjiachen.github.io/vue-element-admin)
- [线上地址](http://panjiachen.github.io/vue-element-admin)
[English Document](https://github.com/PanJiaChen/vue-element-admin/blob/master/README-en.md)
- [文档地址](https://panjiachen.github.io/vue-element-admin-site/#/)
[wiki](https://github.com/PanJiaChen/vue-element-admin/wiki)
- [English Document](https://github.com/PanJiaChen/vue-element-admin/blob/master/README-en.md)
**本项目的定位是后台集成方案,不适合当基础模板来开发,模板建议使用 [vueAdmin-template](https://github.com/PanJiaChen/vueAdmin-template) 桌面端 [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)**
- [wiki](https://github.com/PanJiaChen/vue-element-admin/wiki)
- [donate](https://panjiachen.github.io/vue-element-admin-site/#/donate)
**本项目的定位是后台集成方案,不适合当基础模板来开发。**
- 模板建议使用: [vueAdmin-template](https://github.com/PanJiaChen/vueAdmin-template)  
- 桌面端: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
**注意该项目目前使用element-ui@2.0.5版本,所以最低兼容 Vue 2.5.0**
**注意该项目目前使用element-ui@1.4.1版本,所以最低兼容 Vue 2.3.0**
楼主这里有一份调查[问卷](https://www.wjx.cn/m/16866569.aspx) 有空请填写一下,以表对本项目的支持~ps:不是给这个调查问卷网站做广告,所以填完问卷不用点上面抽奖有的没的那些东西
## 前
> 这半年来一直在用vue写管理后台目前后台已经有百来个页面十几种权限但维护成本依然很低所以准备开源分享一下后台开发的经验和成果。目前的技术栈主要的采用vue+element+axios由webpack2打包。由于是个人项目所以数据请求都是用了mockjs模拟。注意在此项目基础上改造开发时请移除mock文件。
## 前序准备
你的本地环境需要安装 [node](http://nodejs.org/) 和 [git](https://git-scm.com/)。我们的技术栈基于 [ES2015+](http://es6.ruanyifeng.com/)、[vue](https://cn.vuejs.org/index.html)、[vuex](https://vuex.vuejs.org/zh-cn/)、[vue-router](https://router.vuejs.org/zh-cn/) 和 [element-ui](https://github.com/ElemeFE/element),提前了解和学习这些知识会对使用本项目有很大的帮助。
写了一个系列的教程配套文章,如何从零构建后一个完整的后台项目:
- [wiki](https://github.com/PanJiaChen/vue-element-admin/wiki)
同时配套一个系列的教程文章,如何从零构建后一个完整的后台项目,建议大家先看完这些文章再来实践本项目
- [手摸手,带你用 vue 撸后台 系列一(基础篇)](https://juejin.im/post/59097cd7a22b9d0065fb61d2)
- [手摸手,带你用 vue 撸后台 系列二(登录权限篇)](https://juejin.im/post/591aa14f570c35006961acac)
- [手摸手,带你用 vue 撸后台 系列三 (实战篇)](https://juejin.im/post/593121aa0ce4630057f70d35)
@@ -33,44 +43,50 @@
相应需求开了一个qq群 `591724180` 方便大家交流
**如有问题请先看上述文章和Wiki若不能满足欢迎 issue 和 pr ~**
或者可以加入该 **[圈子](https://jianshiapp.com/circles/1209)** 讨论问题
**该项目并不是一个脚手架,更倾向于是一个集成解决方案**
**如有问题请先看上述文章和Wiki若不能满足欢迎 issue 和 pr**
**项目不支持低版本游览器有需求请自行添加polyfill [详情](https://github.com/PanJiaChen/vue-element-admin/wiki#babel-polyfill)**
**项目并不是一个脚手架,更倾向于是一个集成解决方案**
**该项目不支持低版本游览器(如ie)有需求请自行添加polyfill [详情](https://github.com/PanJiaChen/vue-element-admin/wiki#babel-polyfill)**
## 功能
- 登录/注销
- 权限验证
- 侧边栏
- 面包屑
- 多环境发布
- 动态侧边栏(支持多级路由)
- 动态面包屑
- 国际化多语言
- 多种动态换肤
- 快捷导航(标签页)
- 富文本编辑器
- Markdown编辑器
- JSON编辑器
- Screenfull全屏
- 列表拖拽
- plitPane
- Dropzone
- Sticky
- CountTo
- echarts图表
- 401404错误页面
- Svg Sprite 图标
- Dashboard
- 本地mock数据
- Echarts 图表
- Clipboard(剪贴复制)
- 401/404错误页面
- 错误日志
- 导出excel
- table example
- 导出zip
- 前端可视化excel
- Table example
- 动态table example
- 拖拽table example
- 内联编辑table example
- form example
- 多环境发布
- dashboard
- 二次登录
- 动态侧边栏(支持多级路由)
- mock数据
- cache tabs example
- screenfull
- markdown2html
- views-tab
- Form example
- 二步登录
- SplitPane
- Dropzone
- Sticky
- CountTo
- Markdown2html
## 开发
@@ -106,15 +122,19 @@
│   ├── assets // 主题 字体等静态资源
│   ├── components // 全局公用组件
│   ├── directive // 全局指令
│   ├── filtres // 全局filter
│   ├── mock // mock数据
│   ├── filtres // 全局 filter
│   ├── icons // 项目所有 svg icons
│   ├── lang // 国际化 language
│   ├── mock // 项目mock 模拟数据
│   ├── router // 路由
│   ├── store // 全局store管理
│   ├── store // 全局 store管理
│   ├── styles // 全局样式
│   ├── utils // 全局公用方法
│   ├── view // view
│   ├── vendor // 公用vendor
│   ├── views // view
│   ├── App.vue // 入口页面
│   ── main.js // 入口 加载组件 初始化等
│   ── main.js // 入口 加载组件 初始化等
│ └── permission.js // 权限管理
├── static // 第三方不打包资源
│   └── Tinymce // 富文本
├── .babelrc // babel-loader 配置
@@ -132,66 +152,12 @@ Detailed changes for each release are documented in the [release notes](https://
## 状态管理
后台只有user和app配置相关状态使用vuex存在全局其它数据都由每个业务页面自己管理。
## 效果图
#### 两步验证登录 支持微信和qq
![两步验证 here](https://github.com/PanJiaChen/vue-element-admin/blob/master/gifs/2login.gif)
#### 真正的动态换肤
![真正的动态换肤](https://github.com/PanJiaChen/vue-element-admin/blob/master/gifs/theme.gif)<br />
#### tabs
![tabs](https://github.com/PanJiaChen/vue-element-admin/blob/master/gifs/tabs.gif)<br />
#### 可收起侧边栏
![enter image description here](https://github.com/PanJiaChen/vue-element-admin/blob/master/gifs/leftmenu.gif)
#### table拖拽排序
![enter image description here](https://github.com/PanJiaChen/vue-element-admin/blob/master/gifs/order.gif)
#### 动态table
![enter image description here](https://github.com/PanJiaChen/vue-element-admin/blob/master/gifs/dynamictable.gif)
#### 上传裁剪头像
![enter image description here](https://github.com/PanJiaChen/vue-element-admin/blob/master/gifs/uploadAvatar.gif)
#### 错误统计
![enter image description here](https://github.com/PanJiaChen/vue-element-admin/blob/master/gifs/errorlog.gif)
#### 富文本(整合七牛 打水印等个性化功能)
![enter image description here](https://github.com/PanJiaChen/vue-element-admin/blob/master/gifs/editor.gif)
#### 封装table组件
![enter image description here](https://github.com/PanJiaChen/vue-element-admin/blob/master/gifs/table.gif)
#### 图表
![enter image description here](https://github.com/PanJiaChen/vue-element-admin/blob/master/gifs/echarts.gif)
#### 导出excel
![enter image description here](https://github.com/PanJiaChen/vue-element-admin/blob/master/gifs/excel.png)
## [查看更多demo](http://panjiachen.github.io/vue-element-admin)
![](https://wpimg.wallstcn.com/1bc334a6-32a8-4f29-a037-ac3f5ce32588.png)
## Donate
If you find this project useful, you can buy me a cup of coffee
![donate](https://panjiachen.github.io/donate/donation.png)
## License

View File

@@ -9,9 +9,7 @@ var webpack = require('webpack');
var config = require('../config');
var webpackConfig = require('./webpack.prod.conf');
console.log(process.env.NODE_ENV)
var spinner = ora('building for ' + process.env.NODE_ENV + '...')
var spinner = ora('building for ' + process.env.NODE_ENV + ' of ' + process.env.env_config+ ' mode...' )
spinner.start()

View File

@@ -1,4 +1,5 @@
require('./check-versions')(); // 检查 Node 和 npm 版本
var config = require('../config');
if (!process.env.NODE_ENV) {
process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
@@ -28,19 +29,19 @@ var devMiddleware = require('webpack-dev-middleware')(compiler, {
});
var hotMiddleware = require('webpack-hot-middleware')(compiler, {
log: () => {
}
log: false,
heartbeat: 2000
});
// force page reload when html-webpack-plugin template changes
compiler.plugin('compilation', function (compilation) {
compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
hotMiddleware.publish({action: 'reload'});
cb()
})
});
// compiler.apply(new DashboardPlugin());
// currently disabled until this is resolved:
// https://github.com/jantimon/html-webpack-plugin/issues/680
// compiler.plugin('compilation', function (compilation) {
// compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
// hotMiddleware.publish({ action: 'reload' })
// cb()
// })
// })
// proxy api requests
Object.keys(proxyTable).forEach(function (context) {
@@ -67,18 +68,26 @@ app.use(staticPath, express.static('./static'));
var uri = 'http://localhost:' + port
devMiddleware.waitUntilValid(function () {
console.log('> Listening at ' + uri + '\n')
});
var _resolve
var readyPromise = new Promise(resolve => {
_resolve = resolve
})
module.exports = app.listen(port, function (err) {
if (err) {
console.log(err);
return
}
console.log('> Starting dev server...')
devMiddleware.waitUntilValid(() => {
console.log('> Listening at ' + uri + '\n')
// when env is testing, don't need open it
if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {
opn(uri)
}
_resolve()
})
// when env is testing, don't need open it
if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {
opn(uri)
}
});
var server = app.listen(port)
module.exports = {
ready: readyPromise,
close: () => {
server.close()
}
}

View File

@@ -20,9 +20,16 @@ exports.cssLoaders = function (options) {
}
}
var postcssLoader = {
loader: 'postcss-loader',
options: {
sourceMap: true
}
}
// generate loader string to be used with extract text plugin
function generateLoaders (loader, loaderOptions) {
var loaders = [cssLoader]
var loaders = options.usePostCSS !== false ? [cssLoader, postcssLoader] : [cssLoader]
if (loader) {
loaders.push({
loader: loader + '-loader',

View File

@@ -14,7 +14,7 @@ module.exports = {
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV !== 'development' ? config.build.assetsPublicPath : config.dev.assetsPublicPath
publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath
},
resolve: {
extensions: ['.js', '.vue', '.json'],
@@ -38,13 +38,13 @@ module.exports = {
module: {
rules: [
{
test: /\.(js|vue)$/,
loader: 'eslint-loader',
enforce: "pre",
include: [resolve('src'), resolve('test')],
options: {
formatter: require('eslint-friendly-formatter')
}
test: /\.(js|vue)$/,
loader: 'eslint-loader',
enforce: "pre",
include: [resolve('src'), resolve('test')],
options: {
formatter: require('eslint-friendly-formatter')
}
},
{
test: /\.vue$/,
@@ -68,7 +68,7 @@ module.exports = {
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
exclude: [resolve('src/icons')],
query: {
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
@@ -76,7 +76,7 @@ module.exports = {
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
query: {
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}

View File

@@ -18,9 +18,7 @@ function resolveApp(relativePath) {
module.exports = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({
sourceMap: config.dev.cssSourceMap
})
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
},
// cheap-source-map is faster for development
devtool: '#cheap-source-map',

View File

@@ -9,7 +9,7 @@ var HtmlWebpackPlugin = require('html-webpack-plugin')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
var env = process.env.NODE_ENV === 'production' ? config.build.prodEnv : config.build.sitEnv
var env = config.build[process.env.env_config+'Env']
function resolveApp(relativePath) {
return path.resolve(relativePath);
@@ -19,7 +19,8 @@ var webpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: true
extract: true,
usePostCSS: true
})
},
devtool: config.build.productionSourceMap ? '#source-map' : false,
@@ -38,7 +39,8 @@ var webpackConfig = merge(baseWebpackConfig, {
compress: {
warnings: false
},
sourceMap: true
sourceMap: true,
parallel: true
}),
// extract css into its own file
new ExtractTextPlugin({
@@ -73,10 +75,12 @@ var webpackConfig = merge(baseWebpackConfig, {
}),
// cache Module Identifiers
new webpack.HashedModuleIdsPlugin(),
// enable scope hoisting
new webpack.optimize.ModuleConcatenationPlugin(),
// split vendor js into its own file
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function (module, count) {
minChunks: function (module) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
@@ -87,6 +91,12 @@ var webpackConfig = merge(baseWebpackConfig, {
)
}
}),
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
minChunks: Infinity
}),
// split echarts into its own file
new webpack.optimize.CommonsChunkPlugin({
async: 'echarts',
@@ -95,12 +105,24 @@ var webpackConfig = merge(baseWebpackConfig, {
return context && (context.indexOf('echarts') >= 0 || context.indexOf('zrender') >= 0);
}
}),
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
// split xlsx into its own file
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
chunks: ['vendor']
async: 'xlsx',
minChunks(module) {
var context = module.context;
return context && (context.indexOf('xlsx') >= 0);
}
}),
// This instance extracts shared chunks from code splitted chunks and bundles them
// in a separate chunk, similar to the vendor chunk
// see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
new webpack.optimize.CommonsChunkPlugin({
name: 'app',
async: 'vendor-async',
children: true,
minChunks: 3
}),
// copy custom static assets
new CopyWebpackPlugin([{
from: path.resolve(__dirname, '../static'),
@@ -109,9 +131,11 @@ var webpackConfig = merge(baseWebpackConfig, {
}])
]
})
if (config.build.bundleAnalyzerReport) {
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}
module.exports = webpackConfig

View File

@@ -1,5 +1,6 @@
module.exports = {
NODE_ENV: '"development"',
ENV_CONFIG: '"dev"',
BASE_API: '"https://api-dev"',
APP_ORIGIN: '"https://wallstreetcn.com"'
}

View File

@@ -3,37 +3,37 @@ var path = require('path')
module.exports = {
build: {
sitEnv: require('./sit.env'),
prodEnv: require('./prod.env'),
index: path.resolve(__dirname, '../dist/index.html'),
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
assetsPublicPath: './', //请根据自己路径配置更改
productionSourceMap: false,
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: false,
productionGzipExtensions: ['js', 'css'],
// Run the build command with an extra argument to
// View the bundle analyzer report after build finishes:
// `npm run build --report`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report
sitEnv: require('./sit.env'),
prodEnv: require('./prod.env'),
index: path.resolve(__dirname, '../dist/index.html'),
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
assetsPublicPath: './', //请根据自己路径配置更改
productionSourceMap: false,
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: false,
productionGzipExtensions: ['js', 'css'],
// Run the build command with an extra argument to
// View the bundle analyzer report after build finishes:
// `npm run build --report`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report
},
dev: {
env: require('./dev.env'),
port: 9527,
autoOpenBrowser: true,
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {},
// CSS Sourcemaps off by default because relative paths are "buggy"
// with this option, according to the CSS-Loader README
// (https://github.com/webpack/css-loader#sourcemaps)
// In our experience, they generally work as expected,
// just be aware of this issue when enabling this option.
cssSourceMap: false
env: require('./dev.env'),
port: 9527,
autoOpenBrowser: true,
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {},
// CSS Sourcemaps off by default because relative paths are "buggy"
// with this option, according to the CSS-Loader README
// (https://github.com/webpack/css-loader#sourcemaps)
// In our experience, they generally work as expected,
// just be aware of this issue when enabling this option.
cssSourceMap: false
}
}

View File

@@ -1,5 +1,6 @@
module.exports = {
NODE_ENV: '"production"',
ENV_CONFIG: '"prod"',
BASE_API: '"https://api-prod"',
APP_ORIGIN: '"https://wallstreetcn.com"'
};

View File

@@ -1,5 +1,6 @@
module.exports = {
NODE_ENV: '"production"',
ENV_CONFIG: '"sit"',
BASE_API: '"https://api-sit"',
APP_ORIGIN: '"https://wallstreetcn.com"'
};

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB

View File

@@ -1,15 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>Juicy</title>
</head>
<body>
<script src=<%= htmlWebpackPlugin.options.path %>/tinymce/tinymce.min.js></script>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>vue-element-admin</title>
</head>
<script src=<%= htmlWebpackPlugin.options.path %>/tinymce/tinymce.min.js></script>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

View File

@@ -1,96 +1,101 @@
{
"name": "juicy",
"version": "2.0.0",
"name": "vue-element-admin",
"version": "3.0.0",
"description": "A Vue.js admin",
"author": "Pan <panfree23@gmail.com>",
"license": "MIT",
"private": true,
"scripts": {
"dev": "node build/dev-server.js",
"build:prod": "cross-env NODE_ENV=production node build/build.js",
"build:sit": "cross-env NODE_ENV=sit node build/build.js",
"build:sit-preview": "cross-env NODE_ENV=sit npm_config_preview=true npm_config_report=true node build/build.js",
"build:prod": "cross-env NODE_ENV=production env_config=prod node build/build.js",
"build:sit": "cross-env NODE_ENV=production env_config=sit node build/build.js",
"build:sit-preview": "cross-env NODE_ENV=production env_config=sit npm_config_preview=true npm_config_report=true node build/build.js",
"lint": "eslint --ext .js,.vue src"
},
"dependencies": {
"axios": "0.16.2",
"codemirror": "5.26.0",
"dropzone": "5.1.0",
"echarts": "3.6.2",
"element-ui": "1.4.2",
"axios": "0.17.1",
"clipboard": "1.7.1",
"codemirror": "5.31.0",
"dropzone": "5.2.0",
"echarts": "3.8.5",
"element-ui": "2.0.5",
"file-saver": "1.3.3",
"js-cookie": "2.1.4",
"font-awesome": "4.7.0",
"js-cookie": "2.2.0",
"jsonlint": "1.6.2",
"jszip": "3.1.4",
"mockjs": "1.0.1-beta3",
"normalize.css": "7.0.0",
"nprogress": "0.2.0",
"screenfull": "3.2.2",
"showdown": "1.7.1",
"screenfull": "3.3.2",
"showdown": "1.8.2",
"simplemde": "1.11.2",
"sortablejs": "1.5.1",
"vue": "2.4.2",
"vue-count-to": "1.0.5",
"vue-multiselect": "2.0.2",
"vue-router": "2.7.0",
"vue-splitpane": "^1.0.0",
"vuedraggable": "2.14.1",
"vuex": "2.3.1",
"xlsx": "^0.10.8"
"sortablejs": "1.6.1",
"vue": "2.5.9",
"vue-count-to": "1.0.10",
"vue-i18n": "7.3.2",
"vue-multiselect": "2.0.6",
"vue-router": "3.0.1",
"vue-splitpane": "1.0.0",
"vuedraggable": "2.15.0",
"vuex": "3.0.1",
"xlsx": "^0.11.7"
},
"devDependencies": {
"autoprefixer": "7.1.1",
"babel-core": "6.25.0",
"babel-eslint": "7.2.3",
"babel-loader": "7.0.0",
"autoprefixer": "7.1.6",
"babel-core": "6.26.0",
"babel-eslint": "8.0.2",
"babel-loader": "7.1.2",
"babel-plugin-transform-runtime": "6.23.0",
"babel-preset-env": "1.5.2",
"babel-preset-env": "1.6.1",
"babel-preset-stage-2": "6.24.1",
"babel-register": "6.24.1",
"chalk": "1.1.3",
"connect-history-api-fallback": "1.3.0",
"copy-webpack-plugin": "4.0.1",
"cross-env": "5.0.1",
"css-loader": "0.28.4",
"eslint": "3.19.0",
"babel-register": "6.26.0",
"chalk": "2.3.0",
"connect-history-api-fallback": "1.4.0",
"copy-webpack-plugin": "4.2.0",
"cross-env": "5.1.1",
"css-loader": "0.28.7",
"eslint": "4.11.0",
"eslint-friendly-formatter": "3.0.0",
"eslint-import-resolver-webpack": "0.8.1",
"eslint-loader": "1.7.1",
"eslint-plugin-html": "3.0.0",
"eslint-plugin-import": "2.3.0",
"eslint-import-resolver-webpack": "0.8.3",
"eslint-loader": "1.9.0",
"eslint-plugin-html": "3.2.2",
"eslint-plugin-import": "2.8.0",
"eventsource-polyfill": "0.9.6",
"express": "4.15.3",
"extract-text-webpack-plugin": "2.1.2",
"express": "4.16.2",
"extract-text-webpack-plugin": "3.0.2",
"file-loader": "0.11.2",
"friendly-errors-webpack-plugin": "1.6.1",
"function-bind": "1.1.0",
"html-webpack-plugin": "2.28.0",
"html-webpack-plugin": "2.30.0",
"http-proxy-middleware": "0.17.4",
"node-sass": "^4.5.0",
"opn": "4.0.2",
"optimize-css-assets-webpack-plugin": "1.3.0",
"optimize-css-assets-webpack-plugin": "3.2.0",
"ora": "1.1.0",
"postcss-loader": "^2.0.8",
"pushstate-server": "2.1.0",
"rimraf": "2.6.0",
"sass-loader": "6.0.5",
"script-loader": "0.7.0",
"sass-loader": "6.0.6",
"script-loader": "0.7.2",
"semver": "5.3.0",
"style-loader": "0.17.0",
"svg-sprite-loader": "3.2.4",
"url-loader": "0.5.8",
"vue-loader": "13.0.4",
"vue-style-loader": "3.0.1",
"vue-template-compiler": "2.4.2",
"webpack": "2.6.1",
"webpack-bundle-analyzer": "2.8.2",
"webpack-dev-middleware": "1.10.2",
"webpack-hot-middleware": "2.18.0",
"style-loader": "0.19.0",
"svg-sprite-loader": "3.4.1",
"url-loader": "0.6.2",
"vue-loader": "13.5.0",
"vue-style-loader": "3.0.3",
"vue-template-compiler": "2.5.9",
"webpack": "3.8.1",
"webpack-bundle-analyzer": "2.9.0",
"webpack-dev-middleware": "1.12.0",
"webpack-hot-middleware": "2.20.0",
"webpack-merge": "4.1.0"
},
"engines": {
"node": ">= 4.0.0",
"npm": ">= 3.0.0"
},
"browserlist": [
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"

View File

@@ -11,6 +11,6 @@
</script>
<style lang="scss">
@import '~normalize.css/normalize.css';// normalize.css 样式格式化
@import './styles/index.scss'; // 全局自定义的css样式
@import '~normalize.css/normalize.css'; // normalize.css 样式格式化
@import './styles/index.scss'; // 全局自定义样式
</style>

View File

@@ -1,7 +1,7 @@
import fetch from '@/utils/fetch'
import request from '@/utils/request'
export function fetchList(query) {
return fetch({
return request({
url: '/article/list',
method: 'get',
params: query
@@ -9,14 +9,14 @@ export function fetchList(query) {
}
export function fetchArticle() {
return fetch({
return request({
url: '/article/detail',
method: 'get'
})
}
export function fetchPv(pv) {
return fetch({
return request({
url: '/article/pv',
method: 'get',
params: { pv }

View File

@@ -1,11 +1,11 @@
import fetch from '@/utils/fetch'
import request from '@/utils/request'
export function loginByUsername(username, password) {
const data = {
username,
password
}
return fetch({
return request({
url: '/login/login',
method: 'post',
data
@@ -13,14 +13,14 @@ export function loginByUsername(username, password) {
}
export function logout() {
return fetch({
return request({
url: '/login/logout',
method: 'post'
})
}
export function getUserInfo(token) {
return fetch({
return request({
url: '/user/info',
method: 'get',
params: { token }

View File

@@ -1,7 +1,7 @@
import fetch from '@/utils/fetch'
import request from '@/utils/request'
export function getToken() {
return fetch({
return request({
url: '/qiniu/upload/token', // 假地址 自行替换
method: 'get'
})

View File

@@ -1,7 +1,7 @@
import fetch from '@/utils/fetch'
import request from '@/utils/request'
export function userSearch(name) {
return fetch({
return request({
url: '/search/user',
method: 'get',
params: { name }

9
src/api/transaction.js Normal file
View File

@@ -0,0 +1,9 @@
import request from '@/utils/request'
export function fetchList(query) {
return request({
url: '/transaction/list',
method: 'get',
params: query
})
}

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,6 @@
<template>
<transition :name="transitionName">
<div class="back-to-top" @click="backToTop" v-show="visible" :style="customStyle">
<div class="back-to-ceiling" @click="backToTop" v-show="visible" :style="customStyle">
<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;">
<title>回到顶部</title>
<g>
@@ -82,14 +82,14 @@ export default {
</script>
<style scoped>
.back-to-top {
.back-to-ceiling {
position: fixed;
display: inline-block;
text-align: center;
cursor: pointer;
}
.back-to-top:hover {
.back-to-ceiling:hover {
background: #d5dbe7;
}
@@ -103,7 +103,7 @@ export default {
opacity: 0
}
.back-to-top .Icon {
.back-to-ceiling .Icon {
fill: #9aaabf;
background: none;
}

View File

@@ -0,0 +1,54 @@
<template>
<el-breadcrumb class="app-breadcrumb" separator="/">
<transition-group name="breadcrumb">
<el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path" v-if='item.meta.title'>
<span v-if='item.redirect==="noredirect"||index==levelList.length-1' class="no-redirect">{{generateTitle(item.meta.title)}}</span>
<router-link v-else :to="item.redirect||item.path">{{generateTitle(item.meta.title)}}</router-link>
</el-breadcrumb-item>
</transition-group>
</el-breadcrumb>
</template>
<script>
export default {
created() {
this.getBreadcrumb()
},
data() {
return {
levelList: null
}
},
watch: {
$route() {
this.getBreadcrumb()
}
},
methods: {
getBreadcrumb() {
let matched = this.$route.matched.filter(item => item.name)
const first = matched[0]
if (first && first.name !== 'dashboard') {
matched = [{ path: '/dashboard', meta: { title: 'dashboard' }}].concat(matched)
}
this.levelList = matched
},
generateTitle(title) {
return this.$t('route.' + title)
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.app-breadcrumb.el-breadcrumb {
display: inline-block;
font-size: 14px;
line-height: 50px;
margin-left: 10px;
.no-redirect {
color: #97a8be;
cursor: text;
}
}
</style>

View File

@@ -45,21 +45,22 @@ export default {
const xAxisData = []
const data = []
for (let i = 0; i < 30; i++) {
xAxisData.push(i + '号')
data.push(Math.round(Math.random() * 2 + 3))
const data2 = []
for (let i = 0; i < 50; i++) {
xAxisData.push(i)
data.push((Math.sin(i / 5) * (i / 5 - 10) + i / 6) * 5)
data2.push((Math.sin(i / 5) * (i / 5 + 10) + i / 6) * 3)
}
this.chart.setOption(
{
backgroundColor: '#08263a',
tooltip: {
trigger: 'axis'
},
xAxis: {
xAxis: [{
show: false,
data: xAxisData
},
}, {
show: false,
data: xAxisData
}],
visualMap: {
show: false,
min: 0,
@@ -84,28 +85,64 @@ export default {
color: '#08263f'
}
},
axisTick: {}
axisTick: {
show: false
}
},
series: [{
name: 'back',
type: 'bar',
data,
name: '撸文数',
data: data2,
z: 1,
itemStyle: {
normal: {
opacity: 0.4,
barBorderRadius: 5,
shadowBlur: 10,
shadowBlur: 3,
shadowColor: '#111'
}
},
animationEasing: 'elasticOut',
animationEasingUpdate: 'elasticOut',
animationDelay(idx) {
return idx * 20
},
animationDelayUpdate(idx) {
return idx * 20
}
}]
}, {
name: 'Simulate Shadow',
type: 'line',
data,
z: 2,
showSymbol: false,
animationDelay: 0,
animationEasing: 'linear',
animationDuration: 1200,
lineStyle: {
normal: {
color: 'transparent'
}
},
areaStyle: {
normal: {
color: '#08263a',
shadowBlur: 50,
shadowColor: '#000'
}
}
}, {
name: 'front',
type: 'bar',
data,
xAxisIndex: 1,
z: 3,
itemStyle: {
normal: {
barBorderRadius: 5
}
}
}],
animationEasing: 'elasticOut',
animationEasingUpdate: 'elasticOut',
animationDelay(idx) {
return idx * 20
},
animationDelayUpdate(idx) {
return idx * 20
}
})
}
}

View File

@@ -1,150 +0,0 @@
<template>
<div :class="className" :id="id" :style="{height:height,width:width}"></div>
</template>
<script>
import echarts from 'echarts'
export default {
props: {
className: {
type: String,
default: 'chart'
},
id: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '200px'
},
height: {
type: String,
default: '200px'
}
},
data() {
return {
chart: null
}
},
mounted() {
this.initChart()
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(document.getElementById(this.id))
const xAxisData = []
const data = []
const data2 = []
for (let i = 0; i < 50; i++) {
xAxisData.push(i)
data.push((Math.sin(i / 5) * (i / 5 - 10) + i / 6) * 5)
data2.push((Math.sin(i / 5) * (i / 5 + 10) + i / 6) * 3)
}
this.chart.setOption(
{
backgroundColor: '#08263a',
xAxis: [{
show: false,
data: xAxisData
}, {
show: false,
data: xAxisData
}],
visualMap: {
show: false,
min: 0,
max: 50,
dimension: 0,
inRange: {
color: ['#4a657a', '#308e92', '#b1cfa5', '#f5d69f', '#f5898b', '#ef5055']
}
},
yAxis: {
axisLine: {
show: false
},
axisLabel: {
textStyle: {
color: '#4a657a'
}
},
splitLine: {
show: true,
lineStyle: {
color: '#08263f'
}
},
axisTick: {
show: false
}
},
series: [{
name: 'back',
type: 'bar',
data: data2,
z: 1,
itemStyle: {
normal: {
opacity: 0.4,
barBorderRadius: 5,
shadowBlur: 3,
shadowColor: '#111'
}
}
}, {
name: 'Simulate Shadow',
type: 'line',
data,
z: 2,
showSymbol: false,
animationDelay: 0,
animationEasing: 'linear',
animationDuration: 1200,
lineStyle: {
normal: {
color: 'transparent'
}
},
areaStyle: {
normal: {
color: '#08263a',
shadowBlur: 50,
shadowColor: '#000'
}
}
}, {
name: 'front',
type: 'bar',
data,
xAxisIndex: 1,
z: 3,
itemStyle: {
normal: {
barBorderRadius: 5
}
}
}],
animationEasing: 'elasticOut',
animationEasingUpdate: 'elasticOut',
animationDelay(idx) {
return idx * 20
},
animationDelayUpdate(idx) {
return idx * 20
}
})
}
}
}
</script>

View File

@@ -1,6 +1,6 @@
<template>
<div class="twoDndList">
<div class="twoDndList-list" :style="{width:width1}">
<div class="dndList">
<div class="dndList-list" :style="{width:width1}">
<h3>{{list1Title}}</h3>
<draggable :list="list1" class="dragArea" :options="{group:'article'}">
<div class="list-complete-item" v-for="element in list1" :key='element.id'>
@@ -13,7 +13,7 @@
</div>
</draggable>
</div>
<div class="twoDndList-list" :style="{width:width2}">
<div class="dndList-list" :style="{width:width2}">
<h3>{{list2Title}}</h3>
<draggable :list="filterList2" class="dragArea" :options="{group:'article'}">
<div class="list-complete-item" v-for="element in filterList2" :key='element.id'>
@@ -28,7 +28,7 @@
import draggable from 'vuedraggable'
export default {
name: 'twoDndList',
name: 'DndList',
components: { draggable },
computed: {
filterList2() {
@@ -97,7 +97,7 @@ export default {
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.twoDndList {
.dndList {
background: #fff;
padding-bottom: 40px;
&:after {
@@ -105,7 +105,7 @@ export default {
display: table;
clear: both;
}
.twoDndList-list {
.dndList-list {
float: left;
padding-bottom: 30px;
&:first-of-type {

View File

@@ -7,7 +7,7 @@
<script>
import Dropzone from 'dropzone'
import 'dropzone/dist/dropzone.css'
// import { getToken } from 'api/qiniu';
// import { getToken } from 'api/qiniu';
Dropzone.autoDiscover = false
@@ -59,18 +59,18 @@ export default {
},
accept: (file, done) => {
/* 七牛*/
// const token = this.$store.getters.token;
// getToken(token).then(response => {
// file.token = response.data.qiniu_token;
// file.key = response.data.qiniu_key;
// file.url = response.data.qiniu_url;
// done();
// })
// const token = this.$store.getters.token;
// getToken(token).then(response => {
// file.token = response.data.qiniu_token;
// file.key = response.data.qiniu_key;
// file.url = response.data.qiniu_url;
// done();
// })
done()
},
sending: (file, xhr, formData) => {
// formData.append('token', file.token);
// formData.append('key', file.key);
// formData.append('token', file.token);
// formData.append('key', file.key);
vm.initOnce = false
}
})

View File

@@ -12,14 +12,14 @@
<el-dialog title="bug日志" :visible.sync="dialogTableVisible">
<el-table :data="logsList">
<el-table-column label="message">
<template scope="scope">
<template slot-scope="scope">
<div>msg:{{ scope.row.err.message }}</div>
<br/>
<div>url: {{scope.row.url}}</div>
</template>
</el-table-column>
<el-table-column label="stack">
<template scope="scope">
<template slot-scope="scope">
{{ scope.row.err.stack}}
</template>
</el-table-column>

View File

@@ -1,6 +1,6 @@
<template>
<a href="https://github.com/PanJiaChen/vue-element-admin" target="_blank" class="github-corner" aria-label="View source on Github">
<svg width="80" height="80" viewBox="0 0 250 250" style="fill:#4AB7BD; color:#fff; position: absolute; top: 50px; border: 0; right: 0;"
<svg width="80" height="80" viewBox="0 0 250 250" style="fill:#40c9c6; color:#fff; position: absolute; top: 84px; border: 0; right: 0;"
aria-hidden="true">
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
<path 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"
@@ -11,3 +11,32 @@
</a>
</template>
<style scoped>
.github-corner:hover .octo-arm {
animation: octocat-wave 560ms ease-in-out
}
@keyframes octocat-wave {
0%,
100% {
transform: rotate(0)
}
20%,
60% {
transform: rotate(-25deg)
}
40%,
80% {
transform: rotate(10deg)
}
}
@media (max-width:500px) {
.github-corner:hover .octo-arm {
animation: none
}
.github-corner .octo-arm {
animation: octocat-wave 560ms ease-in-out
}
}
</style>

View File

@@ -1,15 +1,15 @@
<template>
<div>
<svg t="1492500959545" @click="toggleClick" class="wscn-icon hamburger" :class="{'is-active':isActive}" style="" viewBox="0 0 1024 1024"
version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1691" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64">
<path d="M966.8023 568.849776 57.196677 568.849776c-31.397081 0-56.850799-25.452695-56.850799-56.850799l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 543.397081 998.200404 568.849776 966.8023 568.849776z"
p-id="1692"></path>
<path d="M966.8023 881.527125 57.196677 881.527125c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 856.07443 998.200404 881.527125 966.8023 881.527125z"
p-id="1693"></path>
<path d="M966.8023 256.17345 57.196677 256.17345c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.850799 56.850799-56.850799l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.850799l0 0C1023.653099 230.720755 998.200404 256.17345 966.8023 256.17345z"
p-id="1694"></path>
</svg>
</div>
<div>
<svg t="1492500959545" @click="toggleClick" class="wscn-icon hamburger" :class="{'is-active':isActive}" style="" viewBox="0 0 1024 1024"
version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1691" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64">
<path d="M966.8023 568.849776 57.196677 568.849776c-31.397081 0-56.850799-25.452695-56.850799-56.850799l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 543.397081 998.200404 568.849776 966.8023 568.849776z"
p-id="1692"></path>
<path d="M966.8023 881.527125 57.196677 881.527125c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 856.07443 998.200404 881.527125 966.8023 881.527125z"
p-id="1693"></path>
<path d="M966.8023 256.17345 57.196677 256.17345c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.850799 56.850799-56.850799l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.850799l0 0C1023.653099 230.720755 998.200404 256.17345 966.8023 256.17345z"
p-id="1694"></path>
</svg>
</div>
</template>
<script>
@@ -34,13 +34,12 @@ export default {
cursor: pointer;
width: 20px;
height: 20px;
transform: rotate(0deg);
transform: rotate(90deg);
transition: .38s;
transform-origin: 50% 50%;
}
.hamburger.is-active {
transform: rotate(90deg);
transform: rotate(0deg);
}
</style>

View File

@@ -1,22 +0,0 @@
<template>
<svg class="svg-icon" aria-hidden="true">
<use :xlink:href="iconName"></use>
</svg>
</template>
<script>
export default {
name: 'icon-svg',
props: {
iconClass: {
type: String,
required: true
}
},
computed: {
iconName() {
return `#icon-${this.iconClass}`
}
}
}
</script>

View File

@@ -105,7 +105,7 @@
<script>
/* eslint-disable */
import {effectRipple, data2blob} from './utils';
import fetch from 'utils/fetch';
import request from 'utils/request';
import langBag from './lang';
const mimes = {
'jpg': 'image/jpeg',
@@ -672,7 +672,7 @@
that.loading = 1;
that.setStep(3);
that.$emit('crop-success', createImgUrl, field, ki);
fetch({
request({
url,
method: 'post',
data: fmData

View File

@@ -1,6 +1,6 @@
<template>
<div class='json-editor'>
<textarea ref='textarea'></textarea>
<div class="json-editor">
<textarea ref="textarea"></textarea>
</div>
</template>
@@ -57,7 +57,6 @@ export default {
.CodeMirror {
height: 100%;
}
.json-editor .cm-s-rubyblue span.cm-string {
color: #F08047;
}

View File

@@ -1,297 +1,278 @@
<template>
<div class="material-input__component" :class="computedClasses">
<input v-if="type === 'email'" type="email" class="material-input" :name="name" :id="id" :placeholder="placeholder" v-model="valueCopy"
:readonly="readonly" :disabled="disabled" :autocomplete="autocomplete" :required="required" @focus="handleFocus(true)"
@blur="handleFocus(false)" @input="handleModelInput">
<input v-if="type === 'url'" type="url" class="material-input" :name="name" :id="id" :placeholder="placeholder" v-model="valueCopy"
:readonly="readonly" :disabled="disabled" :autocomplete="autocomplete" :required="required" @focus="handleFocus(true)"
@blur="handleFocus(false)" @input="handleModelInput">
<input v-if="type === 'number'" type="number" class="material-input" :name="name" :id="id" :placeholder="placeholder" v-model="valueCopy"
:readonly="readonly" :disabled="disabled" :autocomplete="autocomplete" :max="max" :min="min" :minlength="minlength" :maxlength="maxlength"
:required="required" @focus="handleFocus(true)" @blur="handleFocus(false)" @input="handleModelInput">
<input v-if="type === 'password'" type="password" class="material-input" :name="name" :id="id" :placeholder="placeholder"
v-model="valueCopy" :readonly="readonly" :disabled="disabled" :autocomplete="autocomplete" :max="max" :min="min" :required="required"
@focus="handleFocus(true)" @blur="handleFocus(false)" @input="handleModelInput">
<input v-if="type === 'tel'" type="tel" class="material-input" :name="name" :id="id" :placeholder="placeholder" v-model="valueCopy"
:readonly="readonly" :disabled="disabled" :autocomplete="autocomplete" :required="required" @focus="handleFocus(true)"
@blur="handleFocus(false)" @input="handleModelInput">
<input v-if="type === 'text'" type="text" class="material-input" :name="name" :id="id" :placeholder="placeholder" v-model="valueCopy"
:readonly="readonly" :disabled="disabled" :autocomplete="autocomplete" :minlength="minlength" :maxlength="maxlength"
:required="required" @focus="handleFocus(true)" @blur="handleFocus(false)" @input="handleModelInput">
<span class="material-input-bar"></span>
<label class="material-label">
<slot></slot>
</label>
<div v-if="errorMessages" class="material-errors">
<div v-for="error in computedErrors" class="material-error" :key='error'>
{{ error }}
</div>
<div :class="{iconClass:icon}">
<i class="el-input__icon material-input__icon" :class="['el-icon-' + icon]" v-if="icon"></i>
<input v-if="type === 'email'" type="email" class="material-input" :name="name" :placeholder="fillPlaceHolder" v-model="currentValue"
:readonly="readonly" :disabled="disabled" :autoComplete="autoComplete" :required="required" @focus="handleMdFocus"
@blur="handleMdBlur" @input="handleModelInput">
<input v-if="type === 'url'" type="url" class="material-input" :name="name" :placeholder="fillPlaceHolder" v-model="currentValue"
:readonly="readonly" :disabled="disabled" :autoComplete="autoComplete" :required="required" @focus="handleMdFocus"
@blur="handleMdBlur" @input="handleModelInput">
<input v-if="type === 'number'" type="number" class="material-input" :name="name" :placeholder="fillPlaceHolder" v-model="currentValue"
:step="step" :readonly="readonly" :disabled="disabled" :autoComplete="autoComplete" :max="max" :min="min" :minlength="minlength"
:maxlength="maxlength" :required="required" @focus="handleMdFocus" @blur="handleMdBlur" @input="handleModelInput">
<input v-if="type === 'password'" type="password" class="material-input" :name="name" :placeholder="fillPlaceHolder" v-model="currentValue"
:readonly="readonly" :disabled="disabled" :autoComplete="autoComplete" :max="max" :min="min" :required="required" @focus="handleMdFocus"
@blur="handleMdBlur" @input="handleModelInput">
<input v-if="type === 'tel'" type="tel" class="material-input" :name="name" :placeholder="fillPlaceHolder" v-model="currentValue"
:readonly="readonly" :disabled="disabled" :autoComplete="autoComplete" :required="required" @focus="handleMdFocus"
@blur="handleMdBlur" @input="handleModelInput">
<input v-if="type === 'text'" type="text" class="material-input" :name="name" :placeholder="fillPlaceHolder" v-model="currentValue"
:readonly="readonly" :disabled="disabled" :autoComplete="autoComplete" :minlength="minlength" :maxlength="maxlength"
:required="required" @focus="handleMdFocus" @blur="handleMdBlur" @input="handleModelInput">
<span class="material-input-bar"></span>
<label class="material-label">
<slot></slot>
</label>
</div>
</div>
</template>
<script>
// source:https://github.com/wemake-services/vue-material-input/blob/master/src/components/MaterialInput.vue
// source:https://github.com/wemake-services/vue-material-input/blob/master/src/components/MaterialInput.vue
export default {
name: 'material-input',
computed: {
computedErrors() {
return typeof this.errorMessages === 'string'
? [this.errorMessages] : this.errorMessages
},
computedClasses() {
return {
'material--active': this.focus,
'material--disabled': this.disabled,
'material--has-errors': Boolean(!this.valid || (this.errorMessages && this.errorMessages.length)),
'material--raised': Boolean(this.focus || this.valueCopy || // has value
(this.placeholder && !this.valueCopy)) // has placeholder
}
}
},
data() {
return {
valueCopy: null,
focus: false,
valid: true
}
},
beforeMount() {
// Here we are following the Vue2 convention on custom v-model:
// https://github.com/vuejs/vue/issues/2873#issuecomment-223759341
this.copyValue(this.value)
},
methods: {
handleModelInput(event) {
this.$emit('input', event.target.value, event)
this.handleValidation()
},
handleFocus(focused) {
this.focus = focused
},
handleValidation() {
this.valid = this.$el ? this.$el.querySelector('.material-input').validity.valid : this.valid
},
copyValue(value) {
this.valueCopy = value
this.handleValidation()
}
},
watch: {
value(newValue) {
this.copyValue(newValue)
}
},
name: 'md-input',
props: {
id: {
type: String,
default: null
},
name: {
type: String,
default: null
},
icon: String,
name: String,
type: {
type: String,
default: 'text'
},
value: {
default: null
},
placeholder: {
type: String,
default: null
},
readonly: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
},
min: {
type: String,
default: null
},
max: {
type: String,
default: null
},
minlength: {
type: Number,
default: null
},
maxlength: {
type: Number,
default: null
},
value: [String, Number],
placeholder: String,
readonly: Boolean,
disabled: Boolean,
min: String,
max: String,
step: String,
minlength: Number,
maxlength: Number,
required: {
type: Boolean,
default: true
},
autocomplete: {
autoComplete: {
type: String,
default: 'off'
},
errorMessages: {
type: [Array, String],
default: null
validateEvent: {
type: Boolean,
default: true
}
},
computed: {
computedClasses() {
return {
'material--active': this.focus,
'material--disabled': this.disabled,
'material--raised': Boolean(this.focus || this.currentValue) // has value
}
}
},
watch: {
value(newValue) {
this.currentValue = newValue
}
},
data() {
return {
currentValue: this.value,
focus: false,
fillPlaceHolder: null
}
},
methods: {
handleModelInput(event) {
const value = event.target.value
this.$emit('input', value)
if (this.$parent.$options.componentName === 'ElFormItem') {
if (this.validateEvent) {
this.$parent.$emit('el.form.change', [value])
}
}
this.$emit('change', value)
},
handleMdFocus(event) {
this.focus = true
this.$emit('focus', event)
if (this.placeholder && this.placeholder !== '') {
this.fillPlaceHolder = this.placeholder
}
},
handleMdBlur(event) {
this.focus = false
this.$emit('blur', event)
this.fillPlaceHolder = null
if (this.$parent.$options.componentName === 'ElFormItem') {
if (this.validateEvent) {
this.$parent.$emit('el.form.blur', [this.currentValue])
}
}
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
// Fonts:
$font-size-base: 16px;
$font-size-small: 18px;
$font-size-smallest: 12px;
$font-weight-normal: normal;
// Utils
$spacer: 12px;
$transition: 0.2s ease all;
// Base clases:
%base-bar-pseudo {
content: '';
height: 1px;
width: 0;
bottom: 0;
// Fonts:
$font-size-base: 16px;
$font-size-small: 18px;
$font-size-smallest: 12px;
$font-weight-normal: normal;
$font-weight-bold: bold;
$apixel: 1px;
// Utils
$spacer: 12px;
$transition: 0.2s ease all;
$index: 0px;
$index-has-icon: 30px;
// Theme:
$color-white: white;
$color-grey: #9E9E9E;
$color-grey-light: #E0E0E0;
$color-blue: #2196F3;
$color-red: #F44336;
$color-black: black;
// Base clases:
%base-bar-pseudo {
content: '';
height: 1px;
width: 0;
bottom: 0;
position: absolute;
transition: $transition;
}
// Mixins:
@mixin slided-top() {
top: - ($font-size-base + $spacer);
left: 0;
font-size: $font-size-base;
font-weight: $font-weight-bold;
}
// Component:
.material-input__component {
margin-top: 36px;
position: relative;
* {
box-sizing: border-box;
}
.iconClass {
.material-input__icon {
position: absolute;
transition: $transition;
left: 0;
line-height: $font-size-base;
color: $color-blue;
top: $spacer;
width: $index-has-icon;
height: $font-size-base;
font-size: $font-size-base;
font-weight: $font-weight-normal;
pointer-events: none;
}
.material-label {
left: $index-has-icon;
}
.material-input {
text-indent: $index-has-icon;
}
}
.material-input {
font-size: $font-size-base;
padding: $spacer $spacer $spacer - $apixel * 10 $spacer / 2;
display: block;
width: 100%;
border: none;
line-height: 1;
border-radius: 0;
&:focus {
outline: none;
border: none;
border-bottom: 1px solid transparent; // fixes the height issue
}
}
.material-label {
font-weight: $font-weight-normal;
position: absolute;
pointer-events: none;
left: $index;
top: 0;
transition: $transition;
font-size: $font-size-small;
}
.material-input-bar {
position: relative;
display: block;
width: 100%;
&:before {
@extend %base-bar-pseudo;
left: 50%;
}
&:after {
@extend %base-bar-pseudo;
right: 50%;
}
}
// Disabled state:
&.material--disabled {
.material-input {
border-bottom-style: dashed;
}
}
// Raised state:
&.material--raised {
.material-label {
@include slided-top();
}
}
// Active state:
&.material--active {
.material-input-bar {
&:before,
&:after {
width: 50%;
}
}
}
}
// Mixins:
@mixin slided-top() {
top: -2 * $spacer;
font-size: $font-size-small;
.material-input__component {
background: $color-white;
.material-input {
background: none;
color: $color-black;
text-indent: $index;
border-bottom: 1px solid $color-grey-light;
}
// Component:
.material-input__component {
/*margin-top: 30px;*/
position: relative;
* {
box-sizing: border-box;
}
.material-input {
font-size: $font-size-base;
padding: $spacer $spacer $spacer $spacer / 2;
display: block;
width: 100%;
border: none;
border-radius: 0;
&:focus {
outline: none;
border: none;
border-bottom: 1px solid transparent; // fixes the height issue
}
}
.material-label {
font-size: $font-size-base;
font-weight: $font-weight-normal;
position: absolute;
pointer-events: none;
left: 0;
top: $spacer;
transition: $transition;
}
.material-input-bar {
position: relative;
display: block;
width: 100%;
&:before {
@extend %base-bar-pseudo;
left: 50%;
}
&:after {
@extend %base-bar-pseudo;
right: 50%;
}
}
// Disabled state:
&.material--disabled {
.material-input {
border-bottom-style: dashed;
}
}
// Raised state:
&.material--raised {
.material-label {
@include slided-top();
}
}
// Active state:
&.material--active {
.material-input-bar {
&:before,
&:after {
width: 50%;
}
}
}
// Errors:
.material-errors {
position: relative;
overflow: hidden;
.material-error {
font-size: $font-size-smallest;
line-height: $font-size-smallest + 2px;
overflow: hidden;
margin-top: 0;
padding-top: $spacer / 2;
padding-right: $spacer / 2;
padding-left: 0;
}
}
.material-label {
color: $color-grey;
}
// Theme:
$color-white: white;
$color-grey: #9E9E9E;
$color-grey-light: #E0E0E0;
$color-blue: #2196F3;
$color-red: #F44336;
$color-black: black;
.material-input__component {
background: $color-white;
.material-input {
background: none;
color: $color-black;
text-indent: 30px;
border-bottom: 1px solid $color-grey-light;
}
.material-label {
color: $color-grey;
}
.material-input-bar {
&:before,
&:after {
background: $color-blue;
}
}
// Active state:
&.material--active {
.material-label {
color: $color-blue;
}
}
// Errors:
&.material--has-errors {
&.material--active .material-label {
color: $color-red;
}
.material-input-bar {
&:before,
&:after {
background: $color-red;
}
}
.material-errors {
color: $color-red;
}
}
.material-input-bar {
&:before,
&:after {
background: $color-blue;
}
}
// Active state:
&.material--active {
.material-label {
color: $color-blue;
}
}
// Errors:
&.material--has-errors {
&.material--active .material-label {
color: $color-red;
}
.material-input-bar {
&:before,
&:after {
background: transparent;
}
}
}
}
</style>

View File

@@ -1,11 +1,12 @@
<template>
<div class='simplemde-container' :style="{height:height+'px',zIndex:zIndex}">
<textarea :id='id'>
<div class="simplemde-container" :style="{height:height+'px',zIndex:zIndex}">
<textarea :id="id">
</textarea>
</div>
</template>
<script>
import 'font-awesome/css/font-awesome.min.css'
import 'simplemde/dist/simplemde.min.css'
import SimpleMDE from 'simplemde'
@@ -14,8 +15,7 @@ export default {
props: {
value: String,
id: {
type: String,
default: 'markdown-editor'
type: String
},
autofocus: {
type: Boolean,
@@ -51,7 +51,8 @@ export default {
},
mounted() {
this.simplemde = new SimpleMDE({
element: document.getElementById(this.id),
element: document.getElementById(this.id || 'markdown-editor-' + +new Date()),
autoDownloadFontAwesome: false,
autofocus: this.autofocus,
toolbar: this.toolbar,
spellChecker: false,
@@ -79,7 +80,6 @@ export default {
<style>
.simplemde-container .CodeMirror {
/*height: 150px;*/
min-height: 150px;
}
@@ -109,6 +109,11 @@ export default {
font-weight: bold;
color: #E61E1E;
}
.simplemde-container .editor-toolbar.fullscreen,
.simplemde-container .CodeMirror-fullscreen {
z-index: 1003;
}
</style>

View File

@@ -1,16 +1,24 @@
<template>
<svg @click='click' class="icon screenfull" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
t="1497503607356" viewBox="0 0 1024 1024" version="1.1" p-id="4109" :fill='fill' :width="width" :height="height">
<path d="M604.157933 512l204.484208 204.484208 82.942037-82.942037c10.364045-10.952446 26.498514-13.83817 40.309054-8.067746 13.249769 5.742794 22.465664 18.99154 22.465664 33.977859l0 258.042008c0 20.168342-16.695241 36.863582-36.863582 36.863582L659.452283 954.357873c-14.986319 0-28.236088-9.215896-33.977859-23.025413-5.770424-13.249769-2.885723-29.384237 8.067746-39.748283l82.942037-82.942037L512 604.157933 307.515792 808.642141l82.942037 82.942037c10.952446 10.364045 13.83817 26.498514 8.067746 39.748283-5.742794 13.809517-18.99154 23.025413-33.977859 23.025413L106.504686 954.357873c-20.168342 0-36.863582-16.695241-36.863582-36.863582L69.641103 659.452283c0-14.986319 9.215896-28.236088 23.025413-33.977859 13.249769-5.770424 29.384237-2.8847 39.748283 8.067746l82.942037 82.942037 204.484208-204.484208L215.357859 307.515792l-82.942037 82.942037c-6.890944 6.918573-16.10684 10.952446-25.911136 10.952446-4.593622 0-9.804297-1.14815-13.83817-2.8847-13.809517-5.742794-23.025413-18.99154-23.025413-33.977859L69.641103 106.504686c0-20.168342 16.695241-36.863582 36.863582-36.863582L364.546693 69.641103c14.986319 0 28.236088 9.215896 33.977859 23.025413 5.770424 13.249769 2.8847 29.384237-8.067746 39.748283l-82.942037 82.942037 204.484208 204.484208L716.484208 215.357859l-82.942037-82.942037c-10.952446-10.364045-13.83817-26.498514-8.067746-39.748283 5.742794-13.809517 18.99154-23.025413 33.977859-23.025413l258.042008 0c20.168342 0 36.863582 16.695241 36.863582 36.863582l0 258.042008c0 14.986319-9.215896 28.236088-22.465664 33.977859-4.593622 1.736551-9.804297 2.8847-14.397918 2.8847-9.804297 0-19.020192-4.033873-25.911136-10.952446l-82.942037-82.942037L604.157933 512z"
p-id="4110" />
</svg>
<div>
<svg t="1508738709248" @click='click' class="screenfull-svg" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
p-id="2069" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32">
<path d="M333.493443 428.647617 428.322206 333.832158 262.572184 168.045297 366.707916 64.444754 64.09683 64.444754 63.853283 366.570793 167.283957 262.460644Z"
p-id="2070"></path>
<path d="M854.845439 760.133334 688.61037 593.95864 593.805144 688.764889 759.554142 854.56096 655.44604 958.161503 958.055079 958.161503 958.274066 656.035464Z"
p-id="2071"></path>
<path d="M688.535669 428.550403 854.31025 262.801405 957.935352 366.921787 957.935352 64.34754 655.809313 64.081481 759.919463 167.535691 593.70793 333.731874Z"
p-id="2072"></path>
<path d="M333.590658 594.033341 167.8171 759.804852 64.218604 655.67219 64.218604 958.270996 366.342596 958.502263 262.234493 855.071589 428.421466 688.86108Z"
p-id="2073"></path>
</svg>
</div>
</template>
<script>
import screenfull from 'screenfull'
export default {
name: 'hamburger',
name: 'screenfull',
props: {
width: {
type: Number,
@@ -46,9 +54,12 @@ export default {
</script>
<style scoped>
.screenfull {
.screenfull-svg {
display: inline-block;
cursor: pointer;
vertical-align: -0.15em;
fill: #5a5e66;;
width: 20px;
height: 20px;
vertical-align: 10px;
}
</style>

View File

@@ -0,0 +1,56 @@
<template>
<div class="scroll-container" ref="scrollContainer" @mousewheel="handleScroll">
<div class="scroll-wrapper" ref="scrollWrapper" :style="{top: top + 'px'}">
<slot></slot>
</div>
</div>
</template>
<script>
const delta = 15
export default {
name: 'scrollBar',
data() {
return {
top: 0
}
},
methods: {
handleScroll(e) {
e.preventDefault()
const $container = this.$refs.scrollContainer
const $containerHeight = $container.offsetHeight
const $wrapper = this.$refs.scrollWrapper
const $wrapperHeight = $wrapper.offsetHeight
if (e.wheelDelta > 0) {
this.top = Math.min(0, this.top + e.wheelDelta)
} else {
if ($containerHeight - delta < $wrapperHeight) {
if (this.top < -($wrapperHeight - $containerHeight + delta)) {
this.top = this.top
} else {
this.top = Math.max(this.top + e.wheelDelta, $containerHeight - $wrapperHeight - delta)
}
} else {
this.top = 0
}
}
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
@import '../../styles/variables.scss';
.scroll-container {
position: relative;
width: 100%;
height: 100%;
background-color: $menuBg;
.scroll-wrapper {
position: absolute;
width: 100%!important;
}
}
</style>

View File

@@ -0,0 +1,50 @@
<template>
<div class="scroll-container" ref="scrollContainer" @mousewheel="handleScroll">
<div class="scroll-wrapper" ref="scrollWrapper" :style="{left: left + 'px'}">
<slot></slot>
</div>
</div>
</template>
<script>
export default {
name: 'scrollPane',
data() {
return {
left: 0
}
},
methods: {
handleScroll(e) {
e.preventDefault()
const $container = this.$refs.scrollContainer
const $containerWidth = $container.offsetWidth
const $wrapper = this.$refs.scrollWrapper
const $wrapperWidth = $wrapper.offsetWidth
if (e.wheelDelta > 0) {
this.left = Math.min(0, this.left + e.wheelDelta)
} else {
if ($containerWidth - 100 < $wrapperWidth) {
if (this.left < -($wrapperWidth - $containerWidth + 100)) {
this.left = this.left
} else {
this.left = Math.max(this.left + e.wheelDelta, $containerWidth - $wrapperWidth - 100)
}
} else {
this.left = 0
}
}
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.scroll-container {
white-space: nowrap;
position: relative;
.scroll-wrapper {
position: absolute;
}
}
</style>

View File

@@ -0,0 +1,97 @@
<template>
<div class="share-dropdown-menu" :class="{active:isActive}">
<div class="share-dropdown-menu-wrapper">
<span class="share-dropdown-menu-title" @click.self="clickTitle">{{title}}</span>
<div class="share-dropdown-menu-item" v-for="(item,index) of items" :key='index'>
<a v-if="item.href" :href="item.href" target="_blank">{{item.title}}</a>
<span v-else>{{item.title}}</span>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
items: {
type: Array
},
title: {
type: String,
default: 'vue'
}
},
data() {
return {
isActive: false
}
},
methods: {
clickTitle() {
this.isActive = !this.isActive
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" >
$n: 5; //和items.length 相同
$t: .1s;
.share-dropdown-menu {
width: 250px;
position: relative;
z-index: 1;
&-title {
width: 100%;
display: block;
cursor: pointer;
background: black;
color: white;
height: 60px;
line-height: 60px;
font-size: 20px;
text-align: center;
z-index: 2;
transform: translate3d(0,0,0);
}
&-wrapper {
position: relative;
}
&-item {
text-align: center;
position: absolute;
width: 100%;
background: #e0e0e0;
line-height: 60px;
height: 60px;
cursor: pointer;
font-size: 20px;
opacity: 1;
transition: transform 0.28s ease;
&:hover {
background: black;
color: white;
}
@for $i from 1 through $n {
&:nth-of-type(#{$i}) {
z-index: -1;
transition-delay: $i*$t;
transform: translate3d(0, -60px, 0);
}
}
}
&.active {
.share-dropdown-menu-wrapper {
z-index: 1;
}
.share-dropdown-menu-item {
@for $i from 1 through $n {
&:nth-of-type(#{$i}) {
transition-delay: ($n - $i)*$t;
transform: translate3d(0, ($i - 1)*60px, 0);
}
}
}
}
}
</style>

View File

@@ -1,44 +0,0 @@
<template>
<div :class="classes">
<slot></slot>
</div>
</template>
<script>
export default {
name: 'Pane',
data() {
const classes = ['Pane', this.$parent.split, 'className']
return {
classes: classes.join(' '),
percent: 50
}
}
}
</script>
<style scoped>
.splitter-pane.vertical.splitter-paneL {
position: absolute;
left: 0px;
height: 100%;
}
.splitter-pane.vertical.splitter-paneR {
position: absolute;
right: 0px;
height: 100%;
}
.splitter-pane.horizontal.splitter-paneL {
position: absolute;
top: 0px;
width: 100%;
}
.splitter-pane.horizontal.splitter-paneR {
position: absolute;
bottom: 0px;
width: 100%;
}
</style>

View File

@@ -1,72 +0,0 @@
<template>
<div :class="classes" @mousedown="onMouseDown"></div>
</template>
<script>
export default {
props: {
split: {
validator(value) {
return ['vertical', 'horizontal'].indexOf(value) >= 0
},
required: true
},
onMouseDown: {
type: Function,
required: true
}
},
data() {
const classes = ['Resizer', this.split, 'className']
return {
classes: classes.join(' ')
}
}
}
</script>
<style scoped>
.Resizer {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
background: #000;
position: absolute;
opacity: .2;
z-index: 1;
/*-moz-background-clip: padding;*/
/*-webkit-background-clip: padding;*/
/*background-clip: padding-box;*/
}
/*.Resizer:hover {*/
/*-webkit-transition: all 2s ease;*/
/*transition: all 2s ease;*/
/*}*/
.Resizer.horizontal {
height: 11px;
margin: -5px 0;
border-top: 5px solid rgba(255, 255, 255, 0);
border-bottom: 5px solid rgba(255, 255, 255, 0);
cursor: row-resize;
width: 100%;
}
.Resizer.horizontal:hover {
border-top: 5px solid rgba(0, 0, 0, 0.5);
border-bottom: 5px solid rgba(0, 0, 0, 0.5);
}
.Resizer.vertical {
width: 11px;
height: 100%;
border-left: 5px solid rgba(255, 255, 255, 0);
border-right: 5px solid rgba(255, 255, 255, 0);
cursor: col-resize;
}
.Resizer.vertical:hover {
border-left: 5px solid rgba(0, 0, 0, 0.5);
border-right: 5px solid rgba(0, 0, 0, 0.5);
}
</style>

View File

@@ -1,111 +0,0 @@
<template>
<div ref :style="{ cursor, userSelect}" class="vue-splitter-container clearfix" @mouseup="onMouseUp" @mousemove="onMouseMove">
<pane class="splitter-pane splitter-paneL" :split="split" :style="{ [type]: percent+'%'}">
<slot name="paneL"></slot>
</pane>
<resizer :style="{ [resizeType]: percent+'%'}" :split="split" :onMouseDown="onMouseDown" @click="onClick"></resizer>
<pane class="splitter-pane splitter-paneR" :split="split" :style="{ [type]: 100-percent+'%'}">
<slot name="paneR"></slot>
</pane>
</div>
</template>
<script>
import Resizer from './Resizer'
import Pane from './Pane'
export default {
name: 'splitPane',
components: { Resizer, Pane },
props: {
margin: {
type: Number,
default: 10
},
split: {
validator(value) {
return ['vertical', 'horizontal'].indexOf(value) >= 0
},
required: true
}
},
data() {
return {
active: false,
hasMoved: false,
height: null,
percent: 50,
type: this.split === 'vertical' ? 'width' : 'height',
resizeType: this.split === 'vertical' ? 'left' : 'top'
}
},
computed: {
userSelect() {
return this.active ? 'none' : ''
},
cursor() {
return this.active ? 'col-resize' : ''
}
},
methods: {
onClick() {
if (!this.hasMoved) {
this.percent = 50
this.$emit('resize')
}
},
onMouseDown() {
this.active = true
this.hasMoved = false
},
onMouseUp() {
this.active = false
},
onMouseMove(e) {
if (e.buttons === 0 || e.which === 0) {
this.active = false
}
if (this.active) {
let offset = 0
let target = e.currentTarget
if (this.split === 'vertical') {
while (target) {
offset += target.offsetLeft
target = target.offsetParent
}
} else {
while (target) {
offset += target.offsetTop
target = target.offsetParent
}
}
const currentPage = this.split === 'vertical' ? e.pageX : e.pageY
const targetOffset = this.split === 'vertical' ? e.currentTarget.offsetWidth : e.currentTarget.offsetHeight
const percent = Math.floor(((currentPage - offset) / targetOffset) * 10000) / 100
if (percent > this.margin && percent < 100 - this.margin) {
this.percent = percent
}
this.$emit('resize')
this.hasMoved = true
}
}
}
}
</script>
<style scoped>
.clearfix:after {
visibility: hidden;
display: block;
font-size: 0;
content: " ";
clear: both;
height: 0;
}
.vue-splitter-container {
height: 100%;
/*display: flex;*/
position: relative;
}
</style>

View File

@@ -0,0 +1,42 @@
<template>
<svg :class="svgClass" aria-hidden="true">
<use :xlink:href="iconName"></use>
</svg>
</template>
<script>
export default {
name: 'svg-icon',
props: {
iconClass: {
type: String,
required: true
},
className: {
type: String
}
},
computed: {
iconName() {
return `#icon-${this.iconClass}`
},
svgClass() {
if (this.className) {
return 'svg-icon ' + this.className
} else {
return 'svg-icon'
}
}
}
}
</script>
<style scoped>
.svg-icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style>

View File

@@ -0,0 +1,113 @@
<template>
<a class="link--mallki" :class="className" href="#">
{{text}}
<span :data-letters="text"></span>
<span :data-letters="text"></span>
</a>
</template>
<script>
export default {
props: {
className: {
type: String
},
text: {
type: String,
default: 'vue-element-admin'
}
}
}
</script>
<style>
/* Mallki */
.link--mallki {
font-weight: 800;
color: #4dd9d5;
font-family: 'Dosis', sans-serif;
-webkit-transition: color 0.5s 0.25s;
transition: color 0.5s 0.25s;
overflow: hidden;
position: relative;
display: inline-block;
line-height: 1;
outline: none;
text-decoration: none;
}
.link--mallki:hover {
-webkit-transition: none;
transition: none;
color: transparent;
}
.link--mallki::before {
content: '';
width: 100%;
height: 6px;
margin: -3px 0 0 0;
background: #3888fa;
position: absolute;
left: 0;
top: 50%;
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
-webkit-transition: -webkit-transform 0.4s;
transition: transform 0.4s;
-webkit-transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1);
transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1);
}
.link--mallki:hover::before {
-webkit-transform: translate3d(100%, 0, 0);
transform: translate3d(100%, 0, 0);
}
.link--mallki span {
position: absolute;
height: 50%;
width: 100%;
left: 0;
top: 0;
overflow: hidden;
}
.link--mallki span::before {
content: attr(data-letters);
color: red;
position: absolute;
left: 0;
width: 100%;
color: #3888fa;
-webkit-transition: -webkit-transform 0.5s;
transition: transform 0.5s;
}
.link--mallki span:nth-child(2) {
top: 50%;
}
.link--mallki span:first-child::before {
top: 0;
-webkit-transform: translate3d(0, 100%, 0);
transform: translate3d(0, 100%, 0);
}
.link--mallki span:nth-child(2)::before {
bottom: 0;
-webkit-transform: translate3d(0, -100%, 0);
transform: translate3d(0, -100%, 0);
}
.link--mallki:hover span::before {
-webkit-transition-delay: 0.3s;
transition-delay: 0.3s;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
-webkit-transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1);
transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1);
}
</style>

View File

@@ -0,0 +1,144 @@
<template>
<el-color-picker
class="theme-picker"
popper-class="theme-picker-dropdown"
v-model="theme"></el-color-picker>
</template>
<script>
import { getVersion } from '@/utils/index.js'
const version = getVersion('element-ui') // element-ui version from package.json
const ORIGINAL_THEME = '#409EFF' // default color
export default {
data() {
return {
chalk: '', // content of theme-chalk css
theme: ORIGINAL_THEME
}
},
watch: {
theme(val, oldVal) {
if (typeof val !== 'string') return
const themeCluster = this.getThemeCluster(val.replace('#', ''))
const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))
console.log(themeCluster, originalCluster)
const getHandler = (variable, id) => {
return () => {
const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', ''))
const newStyle = this.updateStyle(this[variable], originalCluster, themeCluster)
let styleTag = document.getElementById(id)
if (!styleTag) {
styleTag = document.createElement('style')
styleTag.setAttribute('id', id)
document.head.appendChild(styleTag)
}
styleTag.innerText = newStyle
}
}
const chalkHandler = getHandler('chalk', 'chalk-style')
if (!this.chalk) {
const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css`
this.getCSSString(url, chalkHandler, 'chalk')
} else {
chalkHandler()
}
const styles = [].slice.call(document.querySelectorAll('style'))
.filter(style => {
const text = style.innerText
return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text)
})
styles.forEach(style => {
const { innerText } = style
if (typeof innerText !== 'string') return
style.innerText = this.updateStyle(innerText, originalCluster, themeCluster)
})
this.$message({
message: '换肤成功',
type: 'success'
})
}
},
methods: {
updateStyle(style, oldCluster, newCluster) {
let newStyle = style
oldCluster.forEach((color, index) => {
newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
})
return newStyle
},
getCSSString(url, callback, variable) {
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')
callback()
}
}
xhr.open('GET', url)
xhr.send()
},
getThemeCluster(theme) {
const tintColor = (color, tint) => {
let red = parseInt(color.slice(0, 2), 16)
let green = parseInt(color.slice(2, 4), 16)
let blue = parseInt(color.slice(4, 6), 16)
if (tint === 0) { // when primary color is in its rgb space
return [red, green, blue].join(',')
} else {
red += Math.round(tint * (255 - red))
green += Math.round(tint * (255 - green))
blue += Math.round(tint * (255 - blue))
red = red.toString(16)
green = green.toString(16)
blue = blue.toString(16)
return `#${red}${green}${blue}`
}
}
const shadeColor = (color, shade) => {
let red = parseInt(color.slice(0, 2), 16)
let green = parseInt(color.slice(2, 4), 16)
let blue = parseInt(color.slice(4, 6), 16)
red = Math.round((1 - shade) * red)
green = Math.round((1 - shade) * green)
blue = Math.round((1 - shade) * blue)
red = red.toString(16)
green = green.toString(16)
blue = blue.toString(16)
return `#${red}${green}${blue}`
}
const clusters = [theme]
for (let i = 0; i <= 9; i++) {
clusters.push(tintColor(theme, Number((i / 10).toFixed(2))))
}
clusters.push(shadeColor(theme, 0.1))
return clusters
}
}
}
</script>
<style>
.theme-picker .el-color-picker__trigger {
vertical-align: middle;
}
.theme-picker-dropdown .el-color-dropdown__link-btn {
display: none;
}
</style>

View File

@@ -0,0 +1,95 @@
<template>
<div class="upload-container">
<el-button icon='upload' :style="{background:color,borderColor:color}" @click=" dialogVisible=true" type="primary">上传图片
</el-button>
<el-dialog :visible.sync="dialogVisible">
<el-upload class="editor-slide-upload" action="https://httpbin.org/post" :multiple="true" :file-list="fileList" :show-file-list="true"
list-type="picture-card" :on-remove="handleRemove" :on-success="handleSuccess" :before-upload="beforeUpload">
<el-button size="small" type="primary">点击上传</el-button>
</el-upload>
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="handleSubmit"> </el-button>
</el-dialog>
</div>
</template>
<script>
// import { getToken } from 'api/qiniu'
export default {
name: 'editorSlideUpload',
props: {
color: {
type: String,
default: '#20a0ff'
}
},
data() {
return {
dialogVisible: false,
listObj: {},
fileList: []
}
},
methods: {
checkAllSuccess() {
return Object.keys(this.listObj).every(item => this.listObj[item].hasSuccess)
},
handleSubmit() {
const arr = Object.keys(this.listObj).map(v => this.listObj[v])
if (!this.checkAllSuccess()) {
this.$message('请等待所有图片上传成功 或 出现了网络问题,请刷新页面重新上传!')
return
}
console.log(arr)
this.$emit('successCBK', arr)
this.listObj = {}
this.fileList = []
this.dialogVisible = false
},
handleSuccess(response, file) {
const uid = file.uid
const objKeyArr = Object.keys(this.listObj)
for (let i = 0, len = objKeyArr.length; i < len; i++) {
if (this.listObj[objKeyArr[i]].uid === uid) {
this.listObj[objKeyArr[i]].url = response.files.file
this.listObj[objKeyArr[i]].hasSuccess = true
return
}
}
},
handleRemove(file) {
const uid = file.uid
const objKeyArr = Object.keys(this.listObj)
for (let i = 0, len = objKeyArr.length; i < len; i++) {
if (this.listObj[objKeyArr[i]].uid === uid) {
delete this.listObj[objKeyArr[i]]
return
}
}
},
beforeUpload(file) {
const _self = this
const _URL = window.URL || window.webkitURL
const fileName = file.uid
this.listObj[fileName] = {}
return new Promise((resolve, reject) => {
const img = new Image()
img.src = _URL.createObjectURL(file)
img.onload = function() {
_self.listObj[fileName] = { hasSuccess: false, uid: file.uid, width: this.width, height: this.height }
}
resolve(true)
})
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.upload-container {
.editor-slide-upload {
margin-bottom: 20px;
}
}
</style>

View File

@@ -1,16 +1,21 @@
<template>
<div class='tinymce-container editor-container'>
<textarea class='tinymce-textarea' :id="id"></textarea>
<div class="tinymce-container editor-container">
<textarea class="tinymce-textarea" :id="tinymceId"></textarea>
<div class="editor-custom-btn-container">
<editorImage color="#20a0ff" class="editor-upload-btn" @successCBK="imageSuccessCBK"></editorImage>
</div>
</div>
</template>
<script>
import editorImage from './components/editorImage'
export default {
name: 'tinymce',
components: { editorImage },
props: {
id: {
type: String,
default: 'tinymceEditor'
type: String
},
value: {
type: String,
@@ -23,12 +28,6 @@ export default {
return ['removeformat undo redo | bullist numlist | outdent indent | forecolor | fullscreen code', 'bold italic blockquote | h2 p media link | alignleft aligncenter alignright']
}
},
data() {
return {
hasChange: false,
hasInit: false
}
},
menubar: {
default: ''
},
@@ -38,113 +37,115 @@ export default {
default: 360
}
},
data() {
return {
hasChange: false,
hasInit: false,
tinymceId: this.id || 'vue-tinymce-' + +new Date()
}
},
watch: {
value(val) {
if (!this.hasChange && this.hasInit) {
this.$nextTick(() => window.tinymce.get(this.id).setContent(val))
this.$nextTick(() => window.tinymce.get(this.tinymceId).setContent(val))
}
}
},
mounted() {
const _this = this
window.tinymce.init({
selector: `#${this.id}`,
height: this.height,
body_class: 'panel-body ',
object_resizing: false,
toolbar: this.toolbar,
menubar: this.menubar,
plugins: 'advlist,autolink,code,paste,textcolor, colorpicker,fullscreen,link,lists,media,wordcount, imagetools',
end_container_on_empty_block: true,
powerpaste_word_import: 'clean',
code_dialog_height: 450,
code_dialog_width: 1000,
advlist_bullet_styles: 'square',
advlist_number_styles: 'default',
block_formats: '普通标签=p;小标题=h2;',
imagetools_cors_hosts: ['wpimg.wallstcn.com', 'wallstreetcn.com'],
imagetools_toolbar: 'watermark',
default_link_target: '_blank',
link_title: false,
init_instance_callback: editor => {
if (_this.value) {
editor.setContent(_this.value)
this.initTinymce()
},
activated() {
this.initTinymce()
},
deactivated() {
this.destroyTinymce()
},
methods: {
initTinymce() {
const _this = this
window.tinymce.init({
selector: `#${this.tinymceId}`,
height: this.height,
body_class: 'panel-body ',
object_resizing: false,
toolbar: this.toolbar,
menubar: this.menubar,
plugins: 'advlist,autolink,code,paste,textcolor, colorpicker,fullscreen,link,lists,media,wordcount, imagetools',
end_container_on_empty_block: true,
powerpaste_word_import: 'clean',
code_dialog_height: 450,
code_dialog_width: 1000,
advlist_bullet_styles: 'square',
advlist_number_styles: 'default',
imagetools_cors_hosts: ['wpimg.wallstcn.com', 'wallstreetcn.com'],
imagetools_toolbar: 'watermark',
default_link_target: '_blank',
link_title: false,
init_instance_callback: editor => {
if (_this.value) {
editor.setContent(_this.value)
}
_this.hasInit = true
editor.on('NodeChange Change KeyUp', () => {
this.hasChange = true
this.$emit('input', editor.getContent({ format: 'raw' }))
})
}
_this.hasInit = true
editor.on('NodeChange Change KeyUp', () => {
this.hasChange = true
this.$emit('input', editor.getContent({ format: 'raw' }))
})
},
// 整合七牛上传
// images_dataimg_filter(img) {
// setTimeout(() => {
// const $image = $(img);
// $image.removeAttr('width');
// $image.removeAttr('height');
// if ($image[0].height && $image[0].width) {
// $image.attr('data-wscntype', 'image');
// $image.attr('data-wscnh', $image[0].height);
// $image.attr('data-wscnw', $image[0].width);
// $image.addClass('wscnph');
// }
// }, 0);
// return img
// },
// images_upload_handler(blobInfo, success, failure, progress) {
// progress(0);
// const token = _this.$store.getters.token;
// getToken(token).then(response => {
// const url = response.data.qiniu_url;
// const formData = new FormData();
// formData.append('token', response.data.qiniu_token);
// formData.append('key', response.data.qiniu_key);
// formData.append('file', blobInfo.blob(), url);
// upload(formData).then(() => {
// success(url);
// progress(100);
// })
// }).catch(err => {
// failure('出现未知问题,刷新页面,或者联系程序员')
// console.log(err);
// });
// },
setup(editor) {
editor.addButton('h2', {
title: '小标题', // tooltip text seen on mouseover
text: '小标题',
onclick() {
editor.execCommand('mceToggleFormat', false, 'h2')
},
onPostRender() {
const btn = this
editor.on('init', () => {
editor.formatter.formatChanged('h2', state => {
btn.active(state)
})
})
}
})
editor.addButton('p', {
title: '正文',
text: '正文',
onclick() {
editor.execCommand('mceToggleFormat', false, 'p')
},
onPostRender() {
const btn = this
editor.on('init', () => {
editor.formatter.formatChanged('p', state => {
btn.active(state)
})
})
}
})
// 整合七牛上传
// images_dataimg_filter(img) {
// setTimeout(() => {
// const $image = $(img);
// $image.removeAttr('width');
// $image.removeAttr('height');
// if ($image[0].height && $image[0].width) {
// $image.attr('data-wscntype', 'image');
// $image.attr('data-wscnh', $image[0].height);
// $image.attr('data-wscnw', $image[0].width);
// $image.addClass('wscnph');
// }
// }, 0);
// return img
// },
// images_upload_handler(blobInfo, success, failure, progress) {
// progress(0);
// const token = _this.$store.getters.token;
// getToken(token).then(response => {
// const url = response.data.qiniu_url;
// const formData = new FormData();
// formData.append('token', response.data.qiniu_token);
// formData.append('key', response.data.qiniu_key);
// formData.append('file', blobInfo.blob(), url);
// upload(formData).then(() => {
// success(url);
// progress(100);
// })
// }).catch(err => {
// failure('出现未知问题,刷新页面,或者联系程序员')
// console.log(err);
// });
// },
})
},
destroyTinymce() {
if (window.tinymce.get(this.tinymceId)) {
window.tinymce.get(this.tinymceId).destroy()
}
})
},
setContent(value) {
window.tinymce.get(this.tinymceId).setContent(value)
},
getContent() {
window.tinymce.get(this.tinymceId).getContent()
},
imageSuccessCBK(arr) {
const _this = this
arr.forEach(v => {
window.tinymce.get(_this.tinymceId).insertContent(`<img class="wscnph" src="${v.url}" >`)
})
}
},
destroyed() {
window.tinymce.get(this.id).destroy()
this.destroyTinymce()
}
}
</script>
@@ -153,9 +154,17 @@ export default {
.tinymce-container {
position: relative
}
.tinymce-textarea {
visibility: hidden;
z-index: -1;
}
.editor-custom-btn-container {
position: absolute;
right: 15px;
/*z-index: 2005;*/
top: 18px;
}
.editor-upload-btn {
display: inline-block;
}
</style>

View File

@@ -0,0 +1,78 @@
<template>
<div>
<el-button :loading="loading" type="primary" @click="handleUpload">select excel file</el-button>
<input id="excel-upload-input" type="file" accept=".xlsx, .xls" class="c-hide" @change="handkeFileChange">
</div>
</template>
<script>
import XLSX from 'xlsx'
export default {
data() {
return {
loading: false,
excelData: {
header: null,
results: null
}
}
},
methods: {
generateDate({ header, results }) {
this.excelData.header = header
this.excelData.results = results
this.loading = false
this.$emit('on-selected-file', this.excelData)
},
handleUpload() {
document.getElementById('excel-upload-input').click()
},
handkeFileChange(e) {
this.loading = true
const files = e.target.files
const itemFile = files[0] // only use files[0]
const reader = new FileReader()
reader.onload = e => {
const data = e.target.result
const fixedData = this.fixdata(data)
const workbook = XLSX.read(btoa(fixedData), { type: 'base64' })
const firstSheetName = workbook.SheetNames[0]
const worksheet = workbook.Sheets[firstSheetName]
const header = this.get_header_row(worksheet)
const results = XLSX.utils.sheet_to_json(worksheet)
this.generateDate({ header, results })
}
reader.readAsArrayBuffer(itemFile)
},
fixdata(data) {
let o = ''
let l = 0
const w = 10240
for (; l < data.byteLength / w; ++l) o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w, l * w + w)))
o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w)))
return o
},
get_header_row(sheet) {
const headers = []
const range = XLSX.utils.decode_range(sheet['!ref'])
let C
const R = range.s.r /* start in the first row */
for (C = range.s.c; C <= range.e.c; ++C) { /* walk every column in the range */
var cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })] /* find the cell in the first row */
var hdr = 'UNKNOWN ' + C // <-- replace with your desired default
if (cell && cell.t) hdr = XLSX.utils.format_cell(cell)
headers.push(hdr)
}
return headers
}
}
}
</script>
<style scoped>
#excel-upload-input{
display: none;
z-index: -9999;
}
</style>

View File

@@ -0,0 +1,49 @@
// Inspired by https://github.com/Inndy/vue-clipboard2
const Clipboard = require('clipboard')
if (!Clipboard) {
throw new Error('you shold npm install `clipboard` --save at first ')
}
export default {
bind(el, binding) {
if (binding.arg === 'success') {
el._v_clipboard_success = binding.value
} else if (binding.arg === 'error') {
el._v_clipboard_error = binding.value
} else {
const clipboard = new Clipboard(el, {
text() { return binding.value },
action() { return binding.arg === 'cut' ? 'cut' : 'copy' }
})
clipboard.on('success', e => {
const callback = el._v_clipboard_success
callback && callback(e) // eslint-disable-line
})
clipboard.on('error', e => {
const callback = el._v_clipboard_error
callback && callback(e) // eslint-disable-line
})
el._v_clipboard = clipboard
}
},
update(el, binding) {
if (binding.arg === 'success') {
el._v_clipboard_success = binding.value
} else if (binding.arg === 'error') {
el._v_clipboard_error = binding.value
} else {
el._v_clipboard.text = function() { return binding.value }
el._v_clipboard.action = function() { return binding.arg === 'cut' ? 'cut' : 'copy' }
}
},
unbind(el, binding) {
if (binding.arg === 'success') {
delete el._v_clipboard_success
} else if (binding.arg === 'error') {
delete el._v_clipboard_error
} else {
el._v_clipboard.destroy()
delete el._v_clipboard
}
}
}

View File

@@ -0,0 +1,13 @@
import Clipboard from './clipboard'
const install = function(Vue) {
Vue.directive('Clipboard', Clipboard)
}
if (window.Vue) {
window.clipboard = Clipboard
Vue.use(install); // eslint-disable-line
}
Clipboard.install = install
export default Clipboard

View File

@@ -10,12 +10,12 @@ vueSticky.install = Vue => {
elStyle.position = '-webkit-sticky'
elStyle.position = 'sticky'
// if the browser support css stickyCurrently Safari, Firefox and Chrome Canary
// if (~elStyle.position.indexOf('sticky')) {
// elStyle.top = `${stickyTop}px`;
// elStyle.zIndex = zIndex;
// return
// }
// if the browser support css stickyCurrently Safari, Firefox and Chrome Canary
// if (~elStyle.position.indexOf('sticky')) {
// elStyle.top = `${stickyTop}px`;
// elStyle.zIndex = zIndex;
// return
// }
const elHeight = el.getBoundingClientRect().height
const elWidth = el.getBoundingClientRect().width
elStyle.cssText = `top: ${stickyTop}px; z-index: ${zIndex}`

View File

@@ -0,0 +1,13 @@
import waves from './waves'
const install = function(Vue) {
Vue.directive('waves', waves)
}
if (window.Vue) {
window.waves = waves
Vue.use(install); // eslint-disable-line
}
waves.install = install
export default waves

View File

@@ -4,6 +4,7 @@ function pluralize(time, label) {
}
return time + label + 's'
}
export function timeAgo(time) {
const between = Date.now() / 1000 - Number(time)
if (between < 3600) {
@@ -77,12 +78,12 @@ export function formatTime(time, option) {
/* 数字 格式化*/
export function nFormatter(num, digits) {
const si = [
{ value: 1E18, symbol: 'E' },
{ value: 1E15, symbol: 'P' },
{ value: 1E12, symbol: 'T' },
{ value: 1E9, symbol: 'G' },
{ value: 1E6, symbol: 'M' },
{ value: 1E3, symbol: 'k' }
{ value: 1E18, symbol: 'E' },
{ value: 1E15, symbol: 'P' },
{ value: 1E12, symbol: 'T' },
{ value: 1E9, symbol: 'G' },
{ value: 1E6, symbol: 'M' },
{ value: 1E3, symbol: 'k' }
]
for (let i = 0; i < si.length; i++) {
if (num >= si[i].value) {

View File

@@ -1,12 +1,12 @@
import Vue from 'vue'
import IconSvg from '@/components/Icon-svg'// svg组件
import generateIconsView from '@/views/svg-icons/generateIconsView.js'// just for views/icons , you can delete it
// register globally
import SvgIcon from '@/components/SvgIcon'// svg组件
import generateIconsView from '@/views/svg-icons/generateIconsView.js'// just for @/views/icons , you can delete it
Vue.component('icon-svg', IconSvg)
// register globally
Vue.component('svg-icon', SvgIcon)
const requireAll = requireContext => requireContext.keys().map(requireContext)
const req = require.context('./svg', false, /\.svg$/)
const iconMap = requireAll(req)
generateIconsView.generate(iconMap) // just for views/icons , you can delete it
generateIconsView.generate(iconMap) // just for @/views/icons , you can delete it

View File

Before

Width:  |  Height:  |  Size: 552 B

After

Width:  |  Height:  |  Size: 552 B

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1506419860538" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4662" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M438.857143 950.857143l512 0 0-365.714286-237.714286 0q-22.820571 0-38.838857-16.018286t-16.018286-38.838857l0-237.714286-219.428571 0 0 658.285714zM585.142857 128l0-36.571429q0-7.460571-5.412571-12.873143t-12.873143-5.412571l-402.285714 0q-7.460571 0-12.873143 5.412571t-5.412571 12.873143l0 36.571429q0 7.460571 5.412571 12.873143t12.873143 5.412571l402.285714 0q7.460571 0 12.873143-5.412571t5.412571-12.873143zM731.428571 512l170.861714 0-170.861714-170.861714 0 170.861714zM1024 585.142857l0 384q0 22.820571-16.018286 38.838857t-38.838857 16.018286l-548.571429 0q-22.820571 0-38.838857-16.018286t-16.018286-38.838857l0-91.428571-310.857143 0q-22.820571 0-38.838857-16.018286t-16.018286-38.838857l0-768q0-22.820571 16.018286-38.838857t38.838857-16.018286l621.714286 0q22.820571 0 38.838857 16.018286t16.018286 38.838857l0 187.465143q11.995429 7.460571 20.553143 16.018286l233.179429 233.179429q16.018286 16.018286 27.428571 43.446857t11.410286 50.322286z" p-id="4663"></path></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1506329916765" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1661" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M64 64 448 64 448 448 64 448 64 64ZM64 576 448 576 448 960 64 960 64 576ZM576 576 960 576 960 960 576 960 576 576ZM768 448C874.038669 448 960 362.038672 960 256 960 149.961328 874.038669 64 768 64 661.961328 64 576 149.961328 576 256 576 362.038672 661.961328 448 768 448Z" p-id="1662"></path></svg>

After

Width:  |  Height:  |  Size: 683 B

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1509611822979" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10379" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><defs><style type="text/css"></style></defs><path d="M219.428571 658.285714q0-30.285714-21.428571-51.714285T146.285714 585.142857t-51.714285 21.428572T73.142857 658.285714t21.428572 51.714286T146.285714 731.428571t51.714286-21.428571T219.428571 658.285714z m109.714286-256q0-30.285714-21.428571-51.714285T256 329.142857t-51.714286 21.428572T182.857143 402.285714t21.428571 51.714286T256 475.428571t51.714286-21.428571T329.142857 402.285714z m244.571429 274.857143l57.714285-218.285714q3.428571-14.857143-4.285714-27.714286T605.142857 414.285714t-27.428571 3.714286-17.142857 22.571429l-57.714286 218.285714q-34.285714 2.857143-61.142857 24.857143t-36 56.285714q-11.428571 44 11.428571 83.428571t66.857143 50.857143 83.428571-11.428571 50.857143-66.857143q9.142857-34.285714-3.428571-66.857143t-41.142857-52z m377.142857-18.857143q0-30.285714-21.428572-51.714285T877.714286 585.142857t-51.714286 21.428572-21.428571 51.714285 21.428571 51.714286 51.714286 21.428571 51.714285-21.428571 21.428572-51.714286z m-365.714286-365.714285q0-30.285714-21.428571-51.714286T512 219.428571t-51.714286 21.428572T438.857143 292.571429t21.428571 51.714285T512 365.714286t51.714286-21.428572T585.142857 292.571429z m256 109.714285q0-30.285714-21.428571-51.714285T768 329.142857t-51.714286 21.428572T694.857143 402.285714t21.428571 51.714286T768 475.428571t51.714286-21.428571T841.142857 402.285714z m182.857143 256q0 149.142857-80.571429 276-10.857143 16.571429-30.857142 16.571429H111.428571q-20 0-30.857142-16.571429Q0 808 0 658.285714q0-104 40.571429-198.857143t109.142857-163.428571 163.428571-109.142857 198.857143-40.571429 198.857143 40.571429 163.428571 109.142857 109.142857 163.428571 40.571429 198.857143z" p-id="10380"></path></svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1510826638494" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1669" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M743.253333 144.184889H374.499556v734.378667H743.253333a92.017778 92.017778 0 0 0 92.16-91.818667V235.975111a91.989333 91.989333 0 0 0-92.16-91.790222z m-0.398222 293.888c0.398222 20.48-1.507556 26.794667-9.756444 26.794667-3.612444 0.597333-9.415111-1.621333-17.863111-8.874667-12.657778-8.931556-21.504-16.753778-29.155556-21.617778-6.798222-5.888-17.550222-5.205333-24.291556 0-8.874667 4.949333-21.532444 15.872-28.814222 21.617778-8.988444 7.907556-15.018667 8.874667-17.180444 8.874667-8.618667 0-10.837333-7.424-10.496-26.794667l-0.312889-223.601778c0-21.162667 8.561778-24.376889 17.265778-24.376889h103.708444c10.552889 0 17.294222 4.835556 17.294222 24.376889l-0.398222 223.601778zM190.122667 235.975111V786.773333a92.046222 92.046222 0 0 0 92.188444 91.818667h46.08V144.184889h-46.08a92.017778 92.017778 0 0 0-92.188444 91.790222z" fill="" p-id="1670"></path></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 983 B

After

Width:  |  Height:  |  Size: 983 B

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 866 B

After

Width:  |  Height:  |  Size: 866 B

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

1
src/icons/svg/form.svg Normal file
View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1506330387278" class="icon" style="" viewBox="0 0 1069 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1447" xmlns:xlink="http://www.w3.org/1999/xlink" width="66.8125" height="64"><defs><style type="text/css"></style></defs><path d="M746.027944 190.083832q-11.241517 0-18.906188-7.664671t-12.774451-17.884232-7.664671-20.9501-2.55489-17.884232l0-125.700599 2.043912 0q9.197605 0 17.373253 2.043912t19.928144 9.708583 28.61477 21.461078 42.411178 36.279441q27.592814 24.526946 43.944112 41.389222t25.037924 28.61477 10.730539 19.928144 2.043912 14.307385l0 16.351297-150.227545 0zM1063.856287 671.42515q3.065868 8.175649 4.087824 20.439122t-10.219561 23.50499q-5.10978 5.10978-9.197605 9.708583t-7.153693 7.664671q-4.087824 4.087824-7.153693 6.131737l-86.866267-85.844311q6.131737-5.10978 13.796407-12.263473t12.774451-11.241517q12.263473-11.241517 26.570858-9.708583t23.50499 6.642715q10.219561 5.10978 21.972056 17.884232t17.884232 27.081836zM703.105788 766.467066q22.483034 0 37.812375-12.263473l-198.259481 206.43513-282.05988 0q-19.417166 0-42.411178-11.241517t-42.922156-29.636727-33.213573-42.411178-13.285429-49.56487l0-695.952096q0-21.461078 9.708583-44.966068t26.570858-42.411178 38.323353-31.680639 44.966068-12.774451l391.409182 0 0 127.744511q0 19.417166 6.131737 41.9002t18.906188 41.389222 33.213573 31.680639 49.053892 12.774451l149.205589 0 0 338.267465-140.007984 145.117764q11.241517-16.351297 11.241517-35.768463 0-26.570858-18.906188-45.477046t-45.477046-18.906188l-383.233533 0q-26.570858 0-44.966068 18.906188t-18.39521 45.477046 18.39521 44.966068 44.966068 18.39521l383.233533 0zM319.872255 383.233533q-26.570858 0-44.966068 18.906188t-18.39521 45.477046 18.39521 44.966068 44.966068 18.39521l383.233533 0q26.570858 0 45.477046-18.39521t18.906188-44.966068-18.906188-45.477046-45.477046-18.906188l-383.233533 0zM705.149701 895.233533l13.285429-13.285429 25.548902-25.548902q15.329341-15.329341 33.724551-34.235529t36.790419-37.301397q43.944112-43.944112 99.129741-98.107784l85.844311 85.844311-99.129741 99.129741-36.790419 36.790419-33.724551 33.724551q-14.307385 14.307385-24.015968 24.526946t-10.730539 11.241517q-5.10978 4.087824-11.241517 8.686627t-12.263473 7.664671-18.906188 7.664671-26.05988 8.686627-25.548902 7.153693-18.39521 4.087824q-12.263473 2.043912-16.351297-3.065868t-2.043912-17.373253q1.021956-6.131737 4.087824-18.39521t7.153693-25.037924 7.664671-24.015968 5.620758-15.329341q6.131737-13.285429 16.351297-23.50499z" p-id="1448"></path></svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1503993937334" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8099" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M960 256v64H64v-64c0-35.2 28.8-64 64-64h768c35.2 0 64 28.8 64 64z m0 128v384c0 35.2-28.8 64-64 64H128c-35.2 0-64-28.8-64-64V384h896zM256 640H128v32h128v-32z m128-64H128v32h256v-32z" p-id="8100"></path></svg>

Before

Width:  |  Height:  |  Size: 591 B

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1509677746926" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1419" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><defs><style type="text/css"></style></defs><path d="M666.298182 824.087273c-12.567273-30.72-54.225455-83.316364-123.578182-156.392728-18.618182-19.549091-17.454545-34.443636-10.705455-78.894545v-5.12c4.421818-30.487273 12.101818-48.407273 114.501819-64.698182 52.130909-8.145455 65.629091 12.567273 84.712727 41.425455l6.283636 9.541818a101.003636 101.003636 0 0 0 51.432728 41.658182c9.076364 4.189091 20.247273 9.309091 35.374545 17.92C861.090909 649.774545 861.090909 672.814545 861.090909 723.549091v5.818182a215.272727 215.272727 0 0 1-41.425454 139.636363 472.436364 472.436364 0 0 1-152.203637 88.203637c27.927273-52.363636 6.516364-114.501818 0-132.421818zM512 40.96a468.014545 468.014545 0 0 1 203.869091 46.545455 434.501818 434.501818 0 0 0-102.865455 82.618181c-7.447273 10.24-13.730909 19.781818-19.781818 28.625455-19.549091 29.556364-29.090909 42.821818-46.545454 44.916364a200.843636 200.843636 0 0 1-33.745455 0c-34.210909-2.327273-80.756364-5.12-95.650909 35.374545-9.541818 25.832727-11.170909 95.650909 19.549091 131.956364a32.349091 32.349091 0 0 1 2.56 28.625454 56.087273 56.087273 0 0 1-16.523636 25.832727 151.505455 151.505455 0 0 1-23.272728-23.272727 151.272727 151.272727 0 0 0-66.56-52.829091c-10.007273-2.792727-21.178182-5.12-31.883636-7.447272-30.254545-6.283636-64.232727-13.498182-72.145455-30.487273a119.156364 119.156364 0 0 1-5.818181-46.545455 175.476364 175.476364 0 0 0-11.17091-74.007272 70.981818 70.981818 0 0 0-44.450909-39.563637A469.643636 469.643636 0 0 1 512 40.96zM0 512A512 512 0 1 0 512 0 512 512 0 0 0 0 512z" p-id="1420"></path></svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1509704884729" class="icon" style="" viewBox="0 0 1088 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6279" xmlns:xlink="http://www.w3.org/1999/xlink" width="34" height="32"><defs><style type="text/css"></style></defs><path d="M729.6 294.4c19.2 57.6 44.8 102.4 89.6 147.2 38.4-38.4 64-89.6 83.2-147.2h-172.8zM307.2 614.4h166.4L390.4 390.4z" p-id="6280"></path><path d="M947.2 0h-768C108.8 0 51.2 57.6 51.2 128v768c0 70.4 57.6 128 128 128h768c70.4 0 128-57.6 128-128V128c0-70.4-51.2-128-128-128zM633.6 825.6c-12.8 12.8-25.6 12.8-38.4 12.8-6.4 0-19.2 0-25.6-6.4s-12.8 0-12.8-6.4-6.4-12.8-12.8-25.6-6.4-19.2-12.8-32l-25.6-70.4H281.6L256 768c-12.8 25.6-19.2 44.8-25.6 57.6-6.4 12.8-19.2 12.8-38.4 12.8-12.8 0-25.6-6.4-38.4-12.8-12.8-12.8-19.2-19.2-19.2-32 0-6.4 0-12.8 6.4-25.6s6.4-19.2 12.8-32l140.8-358.4c6.4-12.8 6.4-25.6 12.8-38.4s12.8-25.6 19.2-32 12.8-19.2 25.6-25.6c12.8-6.4 25.6-6.4 38.4-6.4 12.8 0 25.6 0 38.4 6.4 12.8 6.4 19.2 12.8 25.6 25.6 6.4 6.4 12.8 19.2 19.2 32 6.4 12.8 12.8 25.6 19.2 44.8l140.8 352c12.8 25.6 19.2 44.8 19.2 57.6-6.4 6.4-12.8 19.2-19.2 32zM985.6 576c-70.4-25.6-121.6-57.6-166.4-96-44.8 44.8-102.4 76.8-172.8 96l-19.2-32c70.4-19.2 128-44.8 172.8-89.6-44.8-44.8-83.2-102.4-96-166.4h-64v-25.6h172.8c-12.8-19.2-25.6-44.8-38.4-64l19.2-6.4c12.8 19.2 32 44.8 44.8 70.4h160v32h-64c-19.2 64-51.2 121.6-89.6 160 44.8 38.4 96 70.4 166.4 89.6l-25.6 32z" p-id="6281"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1510727568680" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2026" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><defs><style type="text/css"></style></defs><path d="M0 202.7V631c0 83.3 68.3 150.7 152.6 150.7h228.9l8 190.3 224.9-190.3h257c84.3 0 152.6-67.4 152.6-150.7V202.7C1024 119.4 955.7 52 871.4 52H152.6C68.3 52 0 119.4 0 202.7z m658.6 237.9c0-39.7 32.1-71.4 72.3-71.4 40.2 0 72.3 31.7 72.3 71.4S771 512 730.9 512c-40.2 0-72.3-31.7-72.3-71.4z m-220.9 0c0-39.7 32.1-71.4 72.3-71.4 40.2 0 72.3 31.7 72.3 71.4S550.1 512 510 512c-40.2 0-72.3-31.7-72.3-71.4z m-216.8 0c0-39.7 32.1-71.4 72.3-71.4 40.2 0 72.3 31.7 72.3 71.4S333.3 512 293.1 512c-40.1 0-72.2-31.7-72.2-71.4z" p-id="2027"></path></svg>

After

Width:  |  Height:  |  Size: 917 B

1
src/icons/svg/money.svg Normal file
View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1510727546462" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1764" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><defs><style type="text/css"></style></defs><path d="M463.3 958.3V772.1H228.8v-77.5h234.5v-80.5H228.8v-83.5H420L191.5 128h113.7L469 420.6c18.2 33.4 32.4 62.4 42.7 86.9 9-19.8 24.6-50.5 46.8-92.1L713.9 128h120.8L605.5 530.6h192.9v83.5H564.9v80.5h233.5v77.5H564.9v186.2H463.3z" p-id="1765"></path></svg>

After

Width:  |  Height:  |  Size: 632 B

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1510727502091" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1640" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><defs><style type="text/css"></style></defs><path d="M765.184 873.941333c0 33.28-28.501333 60.288-63.829333 60.288L63.829333 934.229333C28.501333 934.229333 0 907.221333 0 873.941333c0-120.576 123.264-233.258667 249.216-277.674667-72.789333-42.496-121.728-118.058667-121.728-204.8L127.488 331.136c0-133.248 114.346667-241.365333 255.146667-241.365333s255.146667 108.117333 255.146667 241.365333l0 60.288c0 86.826667-48.981333 162.304-121.728 204.842667C641.962667 640.725333 765.184 753.365333 765.184 873.941333L765.184 873.941333z" p-id="1641"></path><path d="M848.256 870.570667l126.933333 0c27.008 0 48.810667-20.650667 48.810667-46.08 0-92.245333-94.293333-178.346667-190.549333-212.309333 55.637333-32.512 93.098667-90.282667 93.098667-156.672L926.549333 409.344c0-101.888-87.424-184.576-195.114667-184.576-13.397333 0-26.453333 1.28-39.125333 3.712 15.488 31.146667 24.149333 65.92 24.149333 102.613333l0 60.288c0 86.826667-24.448 152.746667-88.533333 204.842667C746.666667 625.365333 846.421333 751.018667 848.256 870.570667z" p-id="1642"></path></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1510727582324" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2288" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><defs><style type="text/css"></style></defs><path d="M347.136 783.36q19.456 0 36.864 7.168t30.72 19.968 20.48 30.208 7.168 36.864-7.168 36.864-20.48 30.208-30.72 20.48-36.864 7.68q-20.48 0-37.376-7.68t-30.208-20.48-20.48-30.208-7.168-36.864 7.168-36.864 20.48-30.208 30.208-19.968 37.376-7.168zM773.12 785.408q19.456 0 37.376 7.168t30.72 19.968 20.48 30.208 7.68 36.864-7.68 36.864-20.48 30.208-30.72 20.48-37.376 7.68-36.864-7.68-30.208-20.48-20.48-30.208-7.68-36.864 7.68-36.864 20.48-30.208 30.208-19.968 36.864-7.168zM945.152 203.776q28.672 0 44.544 7.68t22.528 18.944 6.144 24.064-3.584 22.016-12.8 37.888-22.016 62.976-24.064 68.096-17.92 53.248q-13.312 40.96-33.792 56.832t-50.176 15.872l-34.816 0-66.56 0-87.04 0-95.232 0-253.952 0 15.36 92.16 516.096 0q49.152 0 49.152 41.984 0 20.48-9.728 35.328t-38.4 14.848l-49.152 0-95.232 0-117.76 0-119.808 0-98.304 0-56.32 0q-20.48 0-34.304-9.216t-23.04-24.064-14.848-32.256-8.704-32.768q-1.024-6.144-5.632-29.696t-11.264-58.88-14.848-78.848-16.384-87.552q-19.456-103.424-44.032-230.4l-76.8 0q-15.36 0-25.6-7.68t-16.896-18.432-9.216-23.04-2.56-22.528q0-20.48 13.824-33.792t37.376-13.312l22.528 0 20.48 0 25.6 0 34.816 0q20.48 0 32.768 6.144t19.456 15.36 10.24 19.456 5.12 17.408q2.048 8.192 4.096 23.04t4.096 30.208q3.072 18.432 6.144 38.912l700.416 0z" p-id="2289"></path></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1503994075075" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8325" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M896 192v704H256.8c-71.2 0-128.8-57.6-128.8-128.8V256.8C128 185.6 185.6 128 256.8 128H768v512H257.6c-36 0-65.6 29.6-65.6 65.6v60.8c0 36 29.6 65.6 65.6 65.6H832V192h64zM768 704H256v64h512v-64z" p-id="8326"></path></svg>

Before

Width:  |  Height:  |  Size: 602 B

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -1 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1503994012480" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8212" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M896 320H128V160c0-17.6 14.4-32 32-32h704c17.6 0 32 14.4 32 32v160zM320 896H160c-17.6 0-32-14.4-32-32V384h192v512zM864 896H384V384h512v480c0 17.6-14.4 32-32 32z" p-id="8213"></path></svg>
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1506329761546" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1384" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M622.276923 39.384615H401.723077c-13.784615 0-23.630769 11.815385-23.630769 25.6v49.23077c0 13.784615 11.815385 25.6 23.630769 25.6h220.553846c13.784615 0 23.630769-11.815385 23.630769-25.6V64.984615c1.969231-13.784615-9.846154-25.6-23.630769-25.6z m336.738462 0H738.461538c-13.784615 0-25.6 11.815385-25.6 25.6v49.23077c0 13.784615 11.815385 25.6 25.6 25.6h220.553847c13.784615-1.969231 25.6-11.815385 25.6-25.6V64.984615c0-13.784615-11.815385-25.6-25.6-25.6z m0 165.415385H334.769231c-13.784615 0-25.6-11.815385-25.6-25.6V64.984615c0-13.784615-11.815385-25.6-25.6-25.6H64.984615C51.2 39.384615 39.384615 51.2 39.384615 64.984615v896c0 11.815385 11.815385 23.630769 25.6 23.63077h894.03077c13.784615 0 25.6-11.815385 25.6-25.6v-728.615385c0-13.784615-11.815385-25.6-25.6-25.6z" p-id="1385"></path></svg>

Before

Width:  |  Height:  |  Size: 571 B

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 678 B

After

Width:  |  Height:  |  Size: 678 B

View File

Before

Width:  |  Height:  |  Size: 678 B

After

Width:  |  Height:  |  Size: 678 B

View File

Before

Width:  |  Height:  |  Size: 673 B

After

Width:  |  Height:  |  Size: 673 B

View File

Before

Width:  |  Height:  |  Size: 777 B

After

Width:  |  Height:  |  Size: 777 B

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

1
src/icons/svg/zip.svg Normal file
View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1506326020470" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2561" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M619.364365 933.396352c1.372783 0.06385 2.681715 0.191551 4.054497 0.191551h309.291099a65.670086 65.670086 0 0 0 65.606235-65.606235V150.974154a65.670086 65.670086 0 0 0-65.606235-65.606235H623.418862c-1.372783 0-2.71364 0.127701-4.054497 0.191551V-0.031925L15.691224 80.547217v858.404116l603.673141 82.654279v-88.20926z m0-810.101325c1.340857-0.191551 2.681715-0.415027 4.054497-0.415027h309.291099c15.515635 0 28.12608 12.610444 28.12608 28.12608v717.007513a28.158005 28.158005 0 0 1-28.12608 28.12608H623.418862c-1.372783 0-2.71364-0.223476-4.054497-0.415028V123.326952zM248.329977 605.429026l-143.918691-3.671395v-23.401154l86.868402-133.255682v-1.181231l-78.919033 1.308932v-36.043523l134.564614-3.51177v26.082869l-87.506906 133.734559v1.149307l88.911614 1.404707v37.352456z m72.406297 1.85166l-44.759096-1.149306v-201.192456l44.759096-1.149306v203.491068z m171.087015-92.966111c-16.664942 15.356009-41.151551 22.060296-69.341481 21.868745a113.81325 113.81325 0 0 1-16.122213-1.05353v74.353733l-46.099954-1.181231v-202.788714c14.238628-2.809415 34.383414-5.171878 63.179923-5.938083 29.498862-0.766204 50.792954 4.309899 65.191208 15.292159 13.887451 10.439532 23.305378 27.966454 23.305378 48.845518s-7.119314 38.629462-20.080936 50.601403z m-65.925487-79.174435a80.13219 80.13219 0 0 0-19.538207 2.202837v61.392113c4.022572 0.92583 8.970974 1.213157 15.834887 1.213156 25.380514-0.031925 41.215401-12.897771 41.215401-34.479189 0-19.378581-13.63205-30.712019-37.480156-30.296992z m306.322058-296.233702h73.523679v30.328917h-73.523679v-30.328917z m-73.555604 45.397599h73.523679v30.360842h-73.523679v-30.360842z m73.555604 49.675573h73.523679v30.360842h-73.523679v-30.360842z m0 95.903227h73.523679v30.328917h-73.523679v-30.328917z m-73.555604-48.717818h73.523679v30.328917h-73.523679v-30.328917z m72.821325 376.142417a72.7894 72.7894 0 0 0 72.7894-72.821325l-13.440499-121.986095c0-40.225721-19.155105-72.821325-59.380827-72.821325s-59.348901 32.595604-59.348901 72.821325l-13.472424 121.986095a72.7894 72.7894 0 0 0 72.821325 72.821325z m-24.103508-133.862261h48.207015v101.84131h-48.207015v-101.84131z" p-id="2562"></path></svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1503994912370" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10530" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M568.6 0h454.9v454.9H568.6V0z m0 568.6h454.9v454.9H568.6V568.6zM0 568.6h454.9v454.9H0V568.6zM0 0h454.9v454.9H0V0z" fill="" p-id="10531"></path></svg>

Before

Width:  |  Height:  |  Size: 534 B

48
src/lang/en.js Normal file
View File

@@ -0,0 +1,48 @@
export default {
route: {
dashboard: 'Dashboard',
introduction: 'Introduction',
documentation: 'Documentation',
permission: 'Permission',
icons: 'Icons',
components: 'Components',
componentIndex: 'Introduction',
tinymce: 'Tinymce',
markdown: 'Markdown',
jsonEditor: 'JSON Editor',
dndList: 'Dnd List',
splitPane: 'SplitPane',
avatarUpload: 'Avatar Upload',
dropzone: 'Dropzone',
sticky: 'Sticky',
countTo: 'CountTo',
componentMixin: 'Mixin',
backToTop: 'BackToTop',
charts: 'Charts',
keyboardChart: 'Keyboard Chart',
lineChart: 'Line chart',
mixChart: 'Mix Chart',
example: 'Example',
Table: 'Table',
dynamicTable: 'Dynamic Table',
dragTable: 'Drag Table',
inlineEditTable: 'Inline Edit',
complexTable: 'Complex Table',
tab: 'Tab',
form: 'Form',
createForm: 'Create Form',
editForm: 'Edit Form',
errorPages: 'Error Pages',
page401: '401',
page404: '404',
errorLog: 'Error Log',
excel: 'Excel',
exportExcel: 'Export Excel',
selectExcel: 'Export Selected',
uploadExcel: 'Upload Excel',
exportZip: 'Zip',
theme: 'Theme',
clipboardDemo: 'Clipboard',
i18n: 'I18n'
}
}

27
src/lang/index.js Normal file
View File

@@ -0,0 +1,27 @@
import Vue from 'vue'
import VueI18n from 'vue-i18n'
import Cookies from 'js-cookie'
import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang
import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang
import enLocale from './en'
import zhLocale from './zh'
Vue.use(VueI18n)
const messages = {
en: {
...enLocale,
...elementEnLocale
},
zh: {
...zhLocale,
...elementZhLocale
}
}
const i18n = new VueI18n({
locale: Cookies.get('language') || 'zh', // set locale
messages // set locale messages
})
export default i18n

48
src/lang/zh.js Normal file
View File

@@ -0,0 +1,48 @@
export default {
route: {
dashboard: '首页',
introduction: '简述',
documentation: '文档',
permission: '权限测试页',
icons: '图标',
components: '组件',
componentIndex: '介绍',
tinymce: '富文本编辑器',
markdown: 'Markdown',
jsonEditor: 'JSON编辑器',
dndList: '列表拖拽',
splitPane: 'Splitpane',
avatarUpload: '头像上传',
dropzone: 'Dropzone',
sticky: 'Sticky',
countTo: 'CountTo',
componentMixin: '小组件',
backToTop: '返回顶部',
charts: '图表',
keyboardChart: '键盘图表',
lineChart: '折线图',
mixChart: '混合图表',
example: '综合实例',
Table: 'Table',
dynamicTable: '动态table',
dragTable: '拖拽table',
inlineEditTable: 'table内编辑',
complexTable: '综合table',
tab: 'Tab',
form: '表单',
createForm: '创建表单',
editForm: '编辑表单',
errorPages: '错误页面',
page401: '401',
page404: '404',
errorLog: '错误日志',
excel: 'excel',
exportExcel: 'export excel',
selectExcel: 'export selected',
uploadExcel: 'upload excel',
exportZip: 'zip',
theme: '换肤',
clipboardDemo: 'clipboard',
i18n: '国际化'
}
}

View File

@@ -1,16 +1,19 @@
import Vue from 'vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-default/index.css'
import Element from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import i18n from './lang' // 国际化
import App from './App'
import router from './router'
import store from './store'
import * as filters from '@/filters' // 全局filter
import '@/icons' // icon
import '@/errorLog'// error log
import '@/permission' // 权限
import '@/mock' // 该项目所有请求使用mockjs模拟
import * as filters from './filters' // 全局filter
import './icons' // icon
import './errorLog'// error log
import './permission' // 权限
import './mock' // 该项目所有请求使用mockjs模拟
Vue.use(ElementUI)
Vue.use(Element, {
i18n: (key, value) => i18n.t(key, value)
})
// register global utility filters.
Object.keys(filters).forEach(key => {
@@ -23,6 +26,7 @@ new Vue({
el: '#app',
router,
store,
i18n,
template: '<App/>',
components: { App }
})

View File

@@ -50,7 +50,7 @@ export default {
author: { key: 'mockPan' },
source_name: '原创作者',
category_item: [{ key: 'global', name: '全球' }],
comment_disabled: false,
comment_disabled: true,
content: '<p>我是测试数据我是测试数据</p><p><img class="wscnph" src="https://wpimg.wallstcn.com/4c69009c-0fd4-4153-b112-6cb53d1cf943" data-wscntype="image" data-wscnh="300" data-wscnw="400" data-mce-src="https://wpimg.wallstcn.com/4c69009c-0fd4-4153-b112-6cb53d1cf943"></p>"',
content_short: '我是测试数据',
display_time: +new Date(),
@@ -59,6 +59,6 @@ export default {
source_uri: 'https://github.com/PanJiaChen/vue-element-admin',
status: 'published',
tags: [],
title: ''
title: 'vue-element-admin'
})
}

Some files were not shown because too many files have changed in this diff Show More