Browse Source

first commit

钞小赢 3 years ago
commit
4fb998c3a1
100 changed files with 18868 additions and 0 deletions
  1. 2 0
      .browserslistrc
  2. 5 0
      .editorconfig
  3. 17 0
      .env
  4. 5 0
      .env.development
  5. 13 0
      .env.preview
  6. 14 0
      .eslintignore
  7. 28 0
      .eslintrc.js
  8. 21 0
      .gitignore
  9. 5 0
      .postcssrc.js
  10. 21 0
      LICENSE
  11. 24 0
      README.md
  12. 26 0
      README.zh.md
  13. 7 0
      babel.config.js
  14. 165 0
      d2-admin.babel
  15. 24 0
      dependencies-cdn.js
  16. 3 0
      jest.config.js
  17. 11 0
      jsconfig.json
  18. 15919 0
      package-lock.json
  19. 74 0
      package.json
  20. BIN
      public/icon.ico
  21. BIN
      public/image/baidu-pan-logo.png
  22. 6 0
      public/image/loading/loading-spin.svg
  23. BIN
      public/image/theme/chester/logo/all.png
  24. BIN
      public/image/theme/chester/logo/icon-only.png
  25. BIN
      public/image/theme/chester/preview@2x.png
  26. BIN
      public/image/theme/d2/logo/all.png
  27. BIN
      public/image/theme/d2/logo/icon-only.png
  28. BIN
      public/image/theme/d2/preview@2x.png
  29. BIN
      public/image/theme/element/logo/all.png
  30. BIN
      public/image/theme/element/logo/icon-only.png
  31. BIN
      public/image/theme/element/preview@2x.png
  32. BIN
      public/image/theme/line/bg.jpg
  33. BIN
      public/image/theme/line/logo/all.png
  34. BIN
      public/image/theme/line/logo/icon-only.png
  35. BIN
      public/image/theme/line/preview@2x.png
  36. BIN
      public/image/theme/star/bg.jpg
  37. BIN
      public/image/theme/star/logo/all.png
  38. BIN
      public/image/theme/star/logo/icon-only.png
  39. BIN
      public/image/theme/star/preview@2x.png
  40. BIN
      public/image/theme/tomorrow-night-blue/logo/all.png
  41. BIN
      public/image/theme/tomorrow-night-blue/logo/icon-only.png
  42. BIN
      public/image/theme/tomorrow-night-blue/preview@2x.png
  43. BIN
      public/image/theme/violet/logo/all.png
  44. BIN
      public/image/theme/violet/logo/icon-only.png
  45. BIN
      public/image/theme/violet/preview@2x.png
  46. 60 0
      public/index.html
  47. 33 0
      src/App.vue
  48. 17 0
      src/api/index.js
  49. 31 0
      src/api/modules/sys.user.api.js
  50. 102 0
      src/api/service.js
  51. 86 0
      src/api/tools.js
  52. BIN
      src/assets/images/bg.png
  53. BIN
      src/assets/images/logo.png
  54. BIN
      src/assets/images/nav-bg.png
  55. 27 0
      src/assets/style/animate/vue-transition.scss
  56. 12 0
      src/assets/style/fixed/base.scss
  57. 31 0
      src/assets/style/fixed/element.scss
  58. 9 0
      src/assets/style/fixed/markdown.scss
  59. 8 0
      src/assets/style/fixed/n-progress.scss
  60. 5 0
      src/assets/style/fixed/tree-view.scss
  61. 9 0
      src/assets/style/fixed/vue-grid-layout.scss
  62. 5 0
      src/assets/style/fixed/vue-splitpane.scss
  63. 67 0
      src/assets/style/public-class.scss
  64. 44 0
      src/assets/style/public.scss
  65. 2 0
      src/assets/style/theme/chester/index.scss
  66. 64 0
      src/assets/style/theme/chester/setting.scss
  67. 2 0
      src/assets/style/theme/d2/index.scss
  68. 64 0
      src/assets/style/theme/d2/setting.scss
  69. 2 0
      src/assets/style/theme/element/index.scss
  70. 64 0
      src/assets/style/theme/element/setting.scss
  71. 2 0
      src/assets/style/theme/line/index.scss
  72. 64 0
      src/assets/style/theme/line/setting.scss
  73. 9 0
      src/assets/style/theme/register.scss
  74. 2 0
      src/assets/style/theme/star/index.scss
  75. 64 0
      src/assets/style/theme/star/setting.scss
  76. 455 0
      src/assets/style/theme/theme-base.scss
  77. 422 0
      src/assets/style/theme/theme.scss
  78. 2 0
      src/assets/style/theme/tomorrow-night-blue/index.scss
  79. 64 0
      src/assets/style/theme/tomorrow-night-blue/setting.scss
  80. 10 0
      src/assets/style/theme/violet/index.scss
  81. 64 0
      src/assets/style/theme/violet/setting.scss
  82. 24 0
      src/assets/style/unit/color.scss
  83. 19 0
      src/assets/svg-icons/icons/d2-admin-text.svg
  84. 13 0
      src/assets/svg-icons/icons/d2-admin.svg
  85. 7 0
      src/assets/svg-icons/index.js
  86. 27 0
      src/components/d2-container/components/d2-container-card-bs.vue
  87. 33 0
      src/components/d2-container/components/d2-container-card.vue
  88. 25 0
      src/components/d2-container/components/d2-container-full-bs.vue
  89. 31 0
      src/components/d2-container/components/d2-container-full.vue
  90. 26 0
      src/components/d2-container/components/d2-container-ghost-bs.vue
  91. 31 0
      src/components/d2-container/components/d2-container-ghost.vue
  92. 79 0
      src/components/d2-container/components/d2-source.vue
  93. 62 0
      src/components/d2-container/components/mixins/bs.js
  94. 67 0
      src/components/d2-container/components/mixins/normal.js
  95. 106 0
      src/components/d2-container/index.js
  96. 22 0
      src/components/d2-icon-svg/index.vue
  97. 4 0
      src/components/d2-icon/font-awesome-4.7.0/css/font-awesome.min.css
  98. BIN
      src/components/d2-icon/font-awesome-4.7.0/fonts/FontAwesome.otf
  99. BIN
      src/components/d2-icon/font-awesome-4.7.0/fonts/fontawesome-webfont.eot
  100. 0 0
      src/components/d2-icon/font-awesome-4.7.0/fonts/fontawesome-webfont.svg

+ 2 - 0
.browserslistrc

@@ -0,0 +1,2 @@
1
+> 1%
2
+last 2 versions

+ 5 - 0
.editorconfig

@@ -0,0 +1,5 @@
1
+[*.{js,jsx,ts,tsx,vue}]
2
+indent_style = space
3
+indent_size = 2
4
+trim_trailing_whitespace = true
5
+insert_final_newline = true

+ 17 - 0
.env

@@ -0,0 +1,17 @@
1
+# 所有环境默认
2
+
3
+# 页面 title 前缀
4
+VUE_APP_TITLE=D2Admin
5
+
6
+# 网络请求公用地址
7
+VUE_APP_API=/api/
8
+
9
+# 仓库地址
10
+VUE_APP_REPO=https://github.com/d2-projects/d2-admin-start-kit
11
+
12
+# 国际化配置
13
+VUE_APP_I18N_LOCALE=zh-chs
14
+VUE_APP_I18N_FALLBACK_LOCALE=en
15
+
16
+# element 颜色
17
+VUE_APP_ELEMENT_COLOR=#409EFF

+ 5 - 0
.env.development

@@ -0,0 +1,5 @@
1
+# 开发环境
2
+
3
+# 页面 title 前缀
4
+VUE_APP_TITLE=粮食数量监测
5
+

+ 13 - 0
.env.preview

@@ -0,0 +1,13 @@
1
+# 构建预览页面
2
+
3
+# 指定构建模式
4
+NODE_ENV=production
5
+
6
+# 标记当前构建方式
7
+VUE_APP_BUILD_MODE=PREVIEW
8
+
9
+# 显示源码按钮
10
+VUE_APP_SCOURCE_LINK=TRUE
11
+
12
+# 部署路径
13
+VUE_APP_PUBLIC_PATH=/

+ 14 - 0
.eslintignore

@@ -0,0 +1,14 @@
1
+# 忽略目录
2
+build/
3
+tests/
4
+node_modules/
5
+
6
+# D2CRUD 演示
7
+src/views/demo/d2-crud/
8
+
9
+# node 覆盖率文件
10
+coverage/
11
+
12
+# 忽略文件
13
+**/*-min.js
14
+**/*.min.js

+ 28 - 0
.eslintrc.js

@@ -0,0 +1,28 @@
1
+module.exports = {
2
+  root: true,
3
+  env: {
4
+    node: true
5
+  },
6
+  'extends': [
7
+    'plugin:vue/essential',
8
+    '@vue/standard'
9
+  ],
10
+  rules: {
11
+    'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
12
+    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
13
+  },
14
+  parserOptions: {
15
+    parser: 'babel-eslint'
16
+  },
17
+  overrides: [
18
+    {
19
+      files: [
20
+        '**/__tests__/*.{j,t}s?(x)',
21
+        '**/tests/unit/**/*.spec.{j,t}s?(x)'
22
+      ],
23
+      env: {
24
+        jest: true
25
+      }
26
+    }
27
+  ]
28
+}

+ 21 - 0
.gitignore

@@ -0,0 +1,21 @@
1
+.DS_Store
2
+node_modules
3
+/dist
4
+
5
+# local env files
6
+.env.local
7
+.env.*.local
8
+
9
+# Log files
10
+npm-debug.log*
11
+yarn-debug.log*
12
+yarn-error.log*
13
+
14
+# Editor directories and files
15
+.idea
16
+.vscode
17
+*.suo
18
+*.ntvs*
19
+*.njsproj
20
+*.sln
21
+*.sw?

+ 5 - 0
.postcssrc.js

@@ -0,0 +1,5 @@
1
+module.exports = {
2
+  plugins: {
3
+    autoprefixer: {}
4
+  }
5
+}

+ 21 - 0
LICENSE

@@ -0,0 +1,21 @@
1
+MIT License
2
+
3
+Copyright (c) 2018 李杨
4
+
5
+Permission is hereby granted, free of charge, to any person obtaining a copy
6
+of this software and associated documentation files (the "Software"), to deal
7
+in the Software without restriction, including without limitation the rights
8
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+copies of the Software, and to permit persons to whom the Software is
10
+furnished to do so, subject to the following conditions:
11
+
12
+The above copyright notice and this permission notice shall be included in all
13
+copies or substantial portions of the Software.
14
+
15
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+SOFTWARE.

+ 24 - 0
README.md

@@ -0,0 +1,24 @@
1
+[D2Admin](https://github.com/d2-projects/d2-admin) is a fully open source and free enterprise back-end product front-end integration solution, using the latest front-end technology stack, javascript files loading of local first screen less than 60kb, has prepared most of the project preparations, and with a lot of sample code to help the management system agile development.
2
+
3
+[中文](https://github.com/d2-projects/d2-admin-start-kit/blob/master/README.zh.md) | **English**
4
+
5
+## Preview
6
+
7
+![Deploy preview](https://github.com/d2-projects/d2-admin-start-kit/workflows/Deploy%20preview/badge.svg)
8
+[![Netlify Status](https://api.netlify.com/api/v1/badges/08ff8c93-f0a8-497a-a081-440b31fb3aa4/deploy-status)](https://app.netlify.com/sites/d2-admin-start-kit/deploys)
9
+
10
+The following access addresses are built and deployed by the latest master branch code at the same time. The access effect is completely consistent. Please select the appropriate access link according to your own network situation.
11
+
12
+| server | link | server |
13
+| --- | --- | --- |
14
+| d2.pub | [d2.pub/d2-admin-start-kit/preview](https://d2.pub/d2-admin-start-kit/preview) | China server |
15
+| cdn.d2.pub | [cdn.d2.pub/d2-admin-start-kit/preview](https://cdn.d2.pub/d2-admin-start-kit/preview) | qiniu CDN |
16
+| github | [d2-projects.github.io/d2-admin-start-kit](https://d2-projects.github.io/d2-admin-start-kit) | GitHub pages |
17
+| netlify | [d2-admin-start-kit.netlify.com](https://d2-admin-start-kit.netlify.com) | Netlify CDN |
18
+
19
+## Other synchronous repositories
20
+
21
+| type | link |
22
+| --- | --- |
23
+| gitee | [https://gitee.com/d2-projects/d2-admin](https://gitee.com/d2-projects/d2-admin) |
24
+| coding | [https://d2-projects.coding.net/p/d2-projects/d/d2-admin/git](https://d2-projects.coding.net/p/d2-projects/d/d2-admin/git) |

+ 26 - 0
README.zh.md

@@ -0,0 +1,26 @@
1
+[D2Admin](https://github.com/d2-projects/d2-admin) 是一个完全 **开源免费** 的企业中后台产品前端集成方案,使用最新的前端技术栈,小于 60kb 的本地首屏 js 加载,已经做好大部分项目前期准备工作,并且带有大量示例代码,助力管理系统敏捷开发。
2
+
3
+**中文** | [English](https://github.com/d2-projects/d2-admin-start-kit)
4
+
5
+## 预览
6
+
7
+![Deploy preview](https://github.com/d2-projects/d2-admin-start-kit/workflows/Deploy%20preview/badge.svg)
8
+[![Netlify Status](https://api.netlify.com/api/v1/badges/08ff8c93-f0a8-497a-a081-440b31fb3aa4/deploy-status)](https://app.netlify.com/sites/d2-admin-start-kit/deploys)
9
+
10
+下列访问地址均由最新的 master 分支代码同时构建部署,访问效果完全一致,请根据自身网络情况选择合适的访问链接。
11
+
12
+| 位置 | 链接 | 部署位置 |
13
+| --- | --- | --- |
14
+| d2.pub | [preview](https://d2.pub/d2-admin-start-kit/preview) | 中国服务器 |
15
+| cdn.d2.pub | [preview](https://cdn.d2.pub/d2-admin-start-kit/preview) | 七牛云 CDN |
16
+| github | [preview](https://d2-projects.github.io/d2-admin-start-kit) | GitHub pages |
17
+| netlify | [preview](https://d2-admin-start-kit.netlify.com) | Netlify CDN |
18
+
19
+## 其它同步仓库
20
+
21
+| 位置 | 链接 |
22
+| --- | --- |
23
+| 码云 | [https://gitee.com/d2-projects/d2-admin-start-kit](https://gitee.com/d2-projects/d2-admin-start-kit) |
24
+| coding | [https://d2-projects.coding.net/p/d2-projects/d/d2-admin-start-kit/git](https://d2-projects.coding.net/p/d2-projects/d/d2-admin-start-kit/git) |
25
+
26
+> 如果您在 github 仓库下载很慢,可以尝试使用我们的码云仓库克隆代码

+ 7 - 0
babel.config.js

@@ -0,0 +1,7 @@
1
+module.exports = {
2
+  presets: [
3
+    '@vue/cli-plugin-babel/preset'
4
+  ],
5
+  // 允许两种编码引入方式共存,也就是 common 规范与 es6 规范的共存处理
6
+  sourceType: 'unambiguous'
7
+}

+ 165 - 0
d2-admin.babel

@@ -0,0 +1,165 @@
1
+<babeledit_project version="1.2">
2
+    <!--
3
+
4
+    BabelEdit project file
5
+    https://www.codeandweb.com/babeledit
6
+
7
+    This file contains meta data for all translations, but not the translation texts itself.
8
+    They are stored in framework-specific message files (.json / .vue / .yaml / .properties)
9
+
10
+    -->
11
+    <preset_collections/>
12
+    <framework>vue-json</framework>
13
+    <filename>d2-admin.babel</filename>
14
+    <source_root_dir></source_root_dir>
15
+    <folder_node>
16
+        <name></name>
17
+        <children>
18
+            <concept_node>
19
+                <name>_element</name>
20
+                <definition_loaded>false</definition_loaded>
21
+                <description></description>
22
+                <comment></comment>
23
+                <default_text></default_text>
24
+                <translations>
25
+                    <translation>
26
+                        <language>en-US</language>
27
+                        <approved>false</approved>
28
+                    </translation>
29
+                    <translation>
30
+                        <language>ja-JP</language>
31
+                        <approved>false</approved>
32
+                    </translation>
33
+                    <translation>
34
+                        <language>zh-CHS</language>
35
+                        <approved>false</approved>
36
+                    </translation>
37
+                    <translation>
38
+                        <language>zh-CHT</language>
39
+                        <approved>false</approved>
40
+                    </translation>
41
+                </translations>
42
+            </concept_node>
43
+            <concept_node>
44
+                <name>_name</name>
45
+                <definition_loaded>false</definition_loaded>
46
+                <description></description>
47
+                <comment></comment>
48
+                <default_text></default_text>
49
+                <translations>
50
+                    <translation>
51
+                        <language>en-US</language>
52
+                        <approved>false</approved>
53
+                    </translation>
54
+                    <translation>
55
+                        <language>ja-JP</language>
56
+                        <approved>false</approved>
57
+                    </translation>
58
+                    <translation>
59
+                        <language>zh-CHS</language>
60
+                        <approved>false</approved>
61
+                    </translation>
62
+                    <translation>
63
+                        <language>zh-CHT</language>
64
+                        <approved>false</approved>
65
+                    </translation>
66
+                </translations>
67
+            </concept_node>
68
+            <folder_node>
69
+                <name>page</name>
70
+                <children>
71
+                    <folder_node>
72
+                        <name>demo</name>
73
+                        <children>
74
+                            <folder_node>
75
+                                <name>playground</name>
76
+                                <children>
77
+                                    <folder_node>
78
+                                        <name>locales</name>
79
+                                        <children>
80
+                                            <concept_node>
81
+                                                <name>text</name>
82
+                                                <definition_loaded>false</definition_loaded>
83
+                                                <description></description>
84
+                                                <comment></comment>
85
+                                                <default_text></default_text>
86
+                                                <translations>
87
+                                                    <translation>
88
+                                                        <language>en-US</language>
89
+                                                        <approved>false</approved>
90
+                                                    </translation>
91
+                                                    <translation>
92
+                                                        <language>ja-JP</language>
93
+                                                        <approved>false</approved>
94
+                                                    </translation>
95
+                                                    <translation>
96
+                                                        <language>zh-CHS</language>
97
+                                                        <approved>false</approved>
98
+                                                    </translation>
99
+                                                    <translation>
100
+                                                        <language>zh-CHT</language>
101
+                                                        <approved>false</approved>
102
+                                                    </translation>
103
+                                                </translations>
104
+                                            </concept_node>
105
+                                        </children>
106
+                                    </folder_node>
107
+                                </children>
108
+                            </folder_node>
109
+                        </children>
110
+                    </folder_node>
111
+                </children>
112
+            </folder_node>
113
+        </children>
114
+    </folder_node>
115
+    <isTemplateProject>false</isTemplateProject>
116
+    <languages>
117
+        <language>
118
+            <code>en-US</code>
119
+            <source_id></source_id>
120
+            <source_file>src/locales/en.json</source_file>
121
+        </language>
122
+        <language>
123
+            <code>ja-JP</code>
124
+            <source_id></source_id>
125
+            <source_file>src/locales/ja.json</source_file>
126
+        </language>
127
+        <language>
128
+            <code>zh-CHS</code>
129
+            <source_id></source_id>
130
+            <source_file>src/locales/zh-chs.json</source_file>
131
+        </language>
132
+        <language>
133
+            <code>zh-CHT</code>
134
+            <source_id></source_id>
135
+            <source_file>src/locales/zh-cht.json</source_file>
136
+        </language>
137
+    </languages>
138
+    <translation_files>
139
+        <translation_file>
140
+            <file>src/locales/en.json</file>
141
+        </translation_file>
142
+        <translation_file>
143
+            <file>src/locales/ja.json</file>
144
+        </translation_file>
145
+        <translation_file>
146
+            <file>src/locales/zh-chs.json</file>
147
+        </translation_file>
148
+        <translation_file>
149
+            <file>src/locales/zh-cht.json</file>
150
+        </translation_file>
151
+    </translation_files>
152
+    <editor_configuration>
153
+        <save_empty_translations>true</save_empty_translations>
154
+        <copy_templates>
155
+            <copy_template>$t('%1')</copy_template>
156
+            <copy_template>{{ $t('%1') }}</copy_template>
157
+            <copy_template>this.$t('%1')</copy_template>
158
+        </copy_templates>
159
+    </editor_configuration>
160
+    <primary_language>zh-CHS</primary_language>
161
+    <configuration>
162
+        <indent>tab</indent>
163
+        <format>namespaced-json</format>
164
+    </configuration>
165
+</babeledit_project>

+ 24 - 0
dependencies-cdn.js

@@ -0,0 +1,24 @@
1
+// If you want to re enable these configurations, please make sure that the version number of each package is the latest
2
+
3
+module.exports = [
4
+  // { name: 'vue', library: 'Vue', js: 'https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.min.js', css: '' },
5
+  // { name: 'vue-i18n', library: 'VueI18n', js: 'https://cdn.jsdelivr.net/npm/vue-i18n@8.15.1/dist/vue-i18n.min.js', css: '' },
6
+  // { name: 'vue-router', library: 'VueRouter', js: 'https://cdn.jsdelivr.net/npm/vue-router@3.1.3/dist/vue-router.min.js', css: '' },
7
+  // { name: 'vuex', library: 'Vuex', js: 'https://cdn.jsdelivr.net/npm/vuex@3.1.2/dist/vuex.min.js', css: '' },
8
+  // { name: 'axios', library: 'axios', js: 'https://cdn.jsdelivr.net/npm/axios@0.19.0/dist/axios.min.js', css: '' },
9
+  // { name: 'better-scroll', library: 'BScroll', js: 'https://cdn.jsdelivr.net/npm/better-scroll@1.15.2/dist/bscroll.min.js', css: '' },
10
+  // { name: 'axios-mock-adapter', library: 'AxiosMockAdapter', js: 'https://cdn.jsdelivr.net/npm/axios-mock-adapter@1.18.1/dist/axios-mock-adapter.min.js', css: '' },
11
+  // { name: 'element-ui', library: 'ELEMENT', js: 'https://cdn.jsdelivr.net/npm/element-ui@2.15.6/lib/index.js', css: 'https://cdn.jsdelivr.net/npm/element-ui@2.15.6/lib/theme-chalk/index.css' },
12
+  // { name: 'lodash', library: '_', js: 'https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js', css: '' },
13
+  // { name: 'ua-parser-js', library: 'UAParser', js: 'https://cdn.jsdelivr.net/npm/ua-parser-js@0.7.20/dist/ua-parser.min.js', css: '' },
14
+  // { name: 'js-cookie', library: 'Cookies', js: 'https://cdn.jsdelivr.net/npm/js-cookie@2.2.1/src/js.cookie.min.js', css: '' },
15
+  // { name: 'nprogress', library: 'NProgress', js: 'https://cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.min.js', css: 'https://cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.css' },
16
+  // { name: 'dayjs', library: 'dayjs', js: 'https://cdn.jsdelivr.net/npm/dayjs@1.8.17/dayjs.min.js', css: '' },
17
+  // { name: 'fuse.js', library: 'Fuse', js: 'https://cdn.jsdelivr.net/npm/fuse.js@5.2.3/dist/fuse.min.js', css: '' },
18
+  // { name: 'hotkeys-js', library: 'hotkeys', js: 'https://cdn.jsdelivr.net/npm/hotkeys-js@3.7.3/dist/hotkeys.min.js', css: '' },
19
+  // { name: 'qs', library: 'Qs', js: 'https://cdn.jsdelivr.net/npm/qs@6.9.1/dist/qs.js', css: '' },
20
+  // { name: 'lowdb', library: 'low', js: 'https://cdn.jsdelivr.net/npm/lowdb@1.0.0/dist/low.min.js', css: '' },
21
+  // { name: 'lowdb/adapters/LocalStorage', library: 'LocalStorage', js: 'https://cdn.jsdelivr.net/npm/lowdb@1.0.0/dist/LocalStorage.min.js', css: '' },
22
+  // { name: 'screenfull', library: 'screenfull', js: 'https://cdn.jsdelivr.net/npm/screenfull@5.0.2/dist/screenfull.min.js', css: '' },
23
+  // { name: 'sortablejs', library: 'Sortable', js: 'https://cdn.jsdelivr.net/npm/sortablejs@1.10.1/Sortable.min.js', css: '' }
24
+]

+ 3 - 0
jest.config.js

@@ -0,0 +1,3 @@
1
+module.exports = {
2
+  preset: '@vue/cli-plugin-unit-jest'
3
+}

+ 11 - 0
jsconfig.json

@@ -0,0 +1,11 @@
1
+{
2
+  "compilerOptions": {
3
+    "target": "es2017",
4
+    "allowSyntheticDefaultImports": false,
5
+    "baseUrl": "./",
6
+    "paths": {
7
+      "@/*": ["src/*"]
8
+    }
9
+  },
10
+  "exclude": ["node_modules", "dist"]
11
+}

File diff suppressed because it is too large
+ 15919 - 0
package-lock.json


+ 74 - 0
package.json

@@ -0,0 +1,74 @@
1
+{
2
+  "name": "d2-admin",
3
+  "version": "1.20.1",
4
+  "scripts": {
5
+    "serve": "vue-cli-service serve --open",
6
+    "start": "npm run serve",
7
+    "dev": "npm run serve",
8
+    "build": "vue-cli-service build",
9
+    "build:preview": "NODE_OPTIONS=--max_old_space_size=4096 vue-cli-service build --mode preview",
10
+    "lint": "vue-cli-service lint --fix",
11
+    "test:unit": "vue-cli-service test:unit"
12
+  },
13
+  "dependencies": {
14
+    "axios": "^0.19.0",
15
+    "axios-mock-adapter": "^1.18.1",
16
+    "better-scroll": "^1.15.2",
17
+    "core-js": "^3.4.3",
18
+    "dayjs": "^1.8.17",
19
+    "element-ui": "^2.15.6",
20
+    "faker": "^4.1.0",
21
+    "flex.css": "^1.1.7",
22
+    "fuse.js": "^5.2.3",
23
+    "hotkeys-js": "^3.7.3",
24
+    "js-cookie": "^2.2.1",
25
+    "lodash": "^4.17.19",
26
+    "lowdb": "^1.0.0",
27
+    "nprogress": "^0.2.0",
28
+    "screenfull": "^5.0.2",
29
+    "sortablejs": "^1.10.1",
30
+    "ua-parser-js": "^0.7.20",
31
+    "vue": "^2.6.11",
32
+    "vue-i18n": "^8.15.1",
33
+    "vue-router": "^3.1.3",
34
+    "vuex": "^3.1.2"
35
+  },
36
+  "devDependencies": {
37
+    "@d2-projects/vue-filename-injector": "^1.1.0",
38
+    "@kazupon/vue-i18n-loader": "^0.5.0",
39
+    "@vue/cli-plugin-babel": "^4.1.0",
40
+    "@vue/cli-plugin-eslint": "^4.1.0",
41
+    "@vue/cli-plugin-router": "^4.1.0",
42
+    "@vue/cli-plugin-unit-jest": "^4.1.0",
43
+    "@vue/cli-plugin-vuex": "^4.1.0",
44
+    "@vue/cli-service": "^4.1.0",
45
+    "@vue/eslint-config-standard": "^5.1.2",
46
+    "@vue/test-utils": "^1.0.2",
47
+    "babel-eslint": "^10.0.3",
48
+    "compression-webpack-plugin": "^3.0.1",
49
+    "cz-conventional-changelog": "^3.2.0",
50
+    "eslint": "^6.8.0",
51
+    "eslint-plugin-import": "^2.20.2",
52
+    "eslint-plugin-node": "^11.1.0",
53
+    "eslint-plugin-promise": "^4.2.1",
54
+    "eslint-plugin-standard": "^4.0.1",
55
+    "eslint-plugin-vue": "^6.2.2",
56
+    "sass": "^1.23.7",
57
+    "sass-loader": "^8.0.0",
58
+    "svg-sprite-loader": "^4.1.6",
59
+    "text-loader": "^0.0.1",
60
+    "vue-cli-plugin-i18n": "^1.0.1",
61
+    "vue-template-compiler": "^2.6.10",
62
+    "webpack-bundle-analyzer": "^3.6.0",
63
+    "webpack-theme-color-replacer": "^1.3.3"
64
+  },
65
+  "config": {
66
+    "commitizen": {
67
+      "path": "./node_modules/cz-conventional-changelog"
68
+    }
69
+  },
70
+  "repository": {
71
+    "type": "git",
72
+    "url": "https://github.com/d2-projects/d2-admin.git"
73
+  }
74
+}

BIN
public/icon.ico


BIN
public/image/baidu-pan-logo.png


+ 6 - 0
public/image/loading/loading-spin.svg

@@ -0,0 +1,6 @@
1
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="32" height="32" fill="white">
2
+  <path opacity=".25" d="M16 0 A16 16 0 0 0 16 32 A16 16 0 0 0 16 0 M16 4 A12 12 0 0 1 16 28 A12 12 0 0 1 16 4"/>
3
+  <path d="M16 0 A16 16 0 0 1 32 16 L28 16 A12 12 0 0 0 16 4z">
4
+    <animateTransform attributeName="transform" type="rotate" from="0 16 16" to="360 16 16" dur="0.8s" repeatCount="indefinite" />
5
+  </path>
6
+</svg>

BIN
public/image/theme/chester/logo/all.png


BIN
public/image/theme/chester/logo/icon-only.png


BIN
public/image/theme/chester/preview@2x.png


BIN
public/image/theme/d2/logo/all.png


BIN
public/image/theme/d2/logo/icon-only.png


BIN
public/image/theme/d2/preview@2x.png


BIN
public/image/theme/element/logo/all.png


BIN
public/image/theme/element/logo/icon-only.png


BIN
public/image/theme/element/preview@2x.png


BIN
public/image/theme/line/bg.jpg


BIN
public/image/theme/line/logo/all.png


BIN
public/image/theme/line/logo/icon-only.png


BIN
public/image/theme/line/preview@2x.png


BIN
public/image/theme/star/bg.jpg


BIN
public/image/theme/star/logo/all.png


BIN
public/image/theme/star/logo/icon-only.png


BIN
public/image/theme/star/preview@2x.png


BIN
public/image/theme/tomorrow-night-blue/logo/all.png


BIN
public/image/theme/tomorrow-night-blue/logo/icon-only.png


BIN
public/image/theme/tomorrow-night-blue/preview@2x.png


BIN
public/image/theme/violet/logo/all.png


BIN
public/image/theme/violet/logo/icon-only.png


BIN
public/image/theme/violet/preview@2x.png


+ 60 - 0
public/index.html

@@ -0,0 +1,60 @@
1
+<!DOCTYPE html>
2
+<html>
3
+  <head>
4
+    <meta charset="utf-8">
5
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
+    <meta name="viewport" content="width=device-width,initial-scale=1.0">
7
+    <link rel="icon" href="<%= BASE_URL %>icon.ico">
8
+    <!-- 使用 CDN 加速的 CSS 文件,配置在 vue.config.js 下 -->
9
+    <% for (var i in htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.css) { %>
10
+    <link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="preload" as="style">
11
+    <link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="stylesheet">
12
+    <% } %>
13
+    <!-- 使用 CDN 加速的 JS 文件,配置在 vue.config.js 下 -->
14
+    <% for (var i in htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.js) { %>
15
+    <link href="<%= htmlWebpackPlugin.options.cdn.js[i] %>" rel="preload" as="script">
16
+    <% } %>
17
+    <title><%= VUE_APP_TITLE %></title>
18
+    <style>
19
+      html, body, #app { height: 100%; margin: 0px; padding: 0px; width: 100%; }
20
+      .d2-home { background-color: #303133; height: 100%; display: flex; flex-direction: column; }
21
+      .d2-home__main { user-select: none; width: 100%; flex-grow: 1; display: flex; justify-content: center; align-items: center; flex-direction: column; }
22
+      .d2-home__footer { width: 100%; flex-grow: 0; text-align: center; padding: 1em 0; }
23
+      .d2-home__footer > a { font-size: 12px; color: #ABABAB; text-decoration: none; }
24
+      .d2-home__loading { height: 32px; width: 32px; margin-bottom: 20px; }
25
+    </style>
26
+    <script>
27
+      var _hmt = _hmt || [];
28
+      var hmid = "bc38887aa5588add05a38704342ad7e8";
29
+      (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?" + hmid; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s);})();
30
+    </script>
31
+  </head>
32
+  <body>
33
+    <noscript>
34
+      <strong>
35
+        Sorry, D2Admin will not work properly without JavaScript support. Enable JavaScript for browsers and continue.
36
+      </strong>
37
+    </noscript>
38
+    <div id="app">
39
+      <div class="d2-home">
40
+        <div class="d2-home__main">
41
+          <img
42
+            class="d2-home__loading"
43
+            src="./image/loading/loading-spin.svg"
44
+            alt="loading">
45
+        </div>
46
+        <div class="d2-home__footer">
47
+          <a
48
+            href="https://github.com/d2-projects/d2-admin"
49
+            target="_blank">
50
+            https://github.com/d2-projects/d2-admin
51
+          </a>
52
+        </div>
53
+      </div>
54
+    </div>
55
+    <!-- 使用 CDN 加速的 JS 文件,配置在 vue.config.js 下 -->
56
+    <% for (var i in htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.js) { %>
57
+    <script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
58
+    <% } %>
59
+  </body>
60
+</html>

+ 33 - 0
src/App.vue

@@ -0,0 +1,33 @@
1
+<template>
2
+  <div id="app">
3
+    <router-view/>
4
+  </div>
5
+</template>
6
+
7
+<script>
8
+import util from '@/libs/util'
9
+export default {
10
+  name: 'app',
11
+  watch: {
12
+    '$i18n.locale': 'i18nHandle'
13
+  },
14
+  created () {
15
+    this.i18nHandle(this.$i18n.locale)
16
+  },
17
+  methods: {
18
+    i18nHandle (val, oldVal) {
19
+      util.cookies.set('lang', val)
20
+      document.querySelector('html').setAttribute('lang', val)
21
+    }
22
+  }
23
+}
24
+</script>
25
+
26
+<style lang="scss">
27
+@import '~@/assets/style/public-class.scss';
28
+.el-pagination{
29
+  margin-top: 20px;
30
+  display:flex;
31
+justify-content: flex-end;
32
+}
33
+</style>

+ 17 - 0
src/api/index.js

@@ -0,0 +1,17 @@
1
+import { assign, map } from 'lodash'
2
+import faker from 'faker/locale/zh_CN'
3
+import { service, request, serviceForMock, requestForMock, mock } from './service'
4
+import * as tools from './tools'
5
+
6
+const files = require.context('./modules', true, /\.api\.js$/)
7
+const generators = files.keys().map(key => files(key).default)
8
+
9
+export default assign({}, ...map(generators, generator => generator({
10
+  service,
11
+  request,
12
+  serviceForMock,
13
+  requestForMock,
14
+  mock,
15
+  faker,
16
+  tools
17
+})))

+ 31 - 0
src/api/modules/sys.user.api.js

@@ -0,0 +1,31 @@
1
+import { find, assign } from 'lodash'
2
+
3
+const users = [
4
+  { username: 'admin', password: 'admin', uuid: 'admin-uuid', name: 'Admin' },
5
+  { username: 'editor', password: 'editor', uuid: 'editor-uuid', name: 'Editor' },
6
+  { username: 'user1', password: 'user1', uuid: 'user1-uuid', name: 'User1' }
7
+]
8
+
9
+export default ({ service, request, serviceForMock, requestForMock, mock, faker, tools }) => ({
10
+  /**
11
+   * @description 登录
12
+   * @param {Object} data 登录携带的信息
13
+   */
14
+  SYS_USER_LOGIN (data = {}) {
15
+    // 模拟数据
16
+    mock
17
+      .onAny('/login')
18
+      .reply(config => {
19
+        const user = find(users, tools.parse(config.data))
20
+        return user
21
+          ? tools.responseSuccess(assign({}, user, { token: faker.random.uuid() }))
22
+          : tools.responseError({}, '账号或密码不正确')
23
+      })
24
+    // 接口请求
25
+    return requestForMock({
26
+      url: '/login',
27
+      method: 'post',
28
+      data
29
+    })
30
+  }
31
+})

+ 102 - 0
src/api/service.js

@@ -0,0 +1,102 @@
1
+import axios from 'axios'
2
+import Adapter from 'axios-mock-adapter'
3
+import { get } from 'lodash'
4
+import util from '@/libs/util'
5
+import { errorLog, errorCreate } from './tools'
6
+
7
+/**
8
+ * @description 创建请求实例
9
+ */
10
+function createService () {
11
+  // 创建一个 axios 实例
12
+  const service = axios.create()
13
+  // 请求拦截
14
+  service.interceptors.request.use(
15
+    config => config,
16
+    error => {
17
+      // 发送失败
18
+      console.log(error)
19
+      return Promise.reject(error)
20
+    }
21
+  )
22
+  // 响应拦截
23
+  service.interceptors.response.use(
24
+    response => {
25
+      // dataAxios 是 axios 返回数据中的 data
26
+      const dataAxios = response.data
27
+      // 这个状态码是和后端约定的
28
+      const { code } = dataAxios
29
+      // 根据 code 进行判断
30
+      if (code === undefined) {
31
+        // 如果没有 code 代表这不是项目后端开发的接口 比如可能是 D2Admin 请求最新版本
32
+        return dataAxios
33
+      } else {
34
+        // 有 code 代表这是一个后端接口 可以进行进一步的判断
35
+        switch (code) {
36
+          case 0:
37
+            // [ 示例 ] code === 0 代表没有错误
38
+            return dataAxios.data
39
+          case 'xxx':
40
+            // [ 示例 ] 其它和后台约定的 code
41
+            errorCreate(`[ code: xxx ] ${dataAxios.msg}: ${response.config.url}`)
42
+            break
43
+          default:
44
+            // 不是正确的 code
45
+            errorCreate(`${dataAxios.msg}: ${response.config.url}`)
46
+            break
47
+        }
48
+      }
49
+    },
50
+    error => {
51
+      const status = get(error, 'response.status')
52
+      switch (status) {
53
+        case 400: error.message = '请求错误'; break
54
+        case 401: error.message = '未授权,请登录'; break
55
+        case 403: error.message = '拒绝访问'; break
56
+        case 404: error.message = `请求地址出错: ${error.response.config.url}`; break
57
+        case 408: error.message = '请求超时'; break
58
+        case 500: error.message = '服务器内部错误'; break
59
+        case 501: error.message = '服务未实现'; break
60
+        case 502: error.message = '网关错误'; break
61
+        case 503: error.message = '服务不可用'; break
62
+        case 504: error.message = '网关超时'; break
63
+        case 505: error.message = 'HTTP版本不受支持'; break
64
+        default: break
65
+      }
66
+      errorLog(error)
67
+      return Promise.reject(error)
68
+    }
69
+  )
70
+  return service
71
+}
72
+
73
+/**
74
+ * @description 创建请求方法
75
+ * @param {Object} service axios 实例
76
+ */
77
+function createRequestFunction (service) {
78
+  return function (config) {
79
+    const token = util.cookies.get('token')
80
+    const configDefault = {
81
+      headers: {
82
+        Authorization: token,
83
+        'Content-Type': get(config, 'headers.Content-Type', 'application/json')
84
+      },
85
+      timeout: 5000,
86
+      baseURL: process.env.VUE_APP_API,
87
+      data: {}
88
+    }
89
+    return service(Object.assign(configDefault, config))
90
+  }
91
+}
92
+
93
+// 用于真实网络请求的实例和请求方法
94
+export const service = createService()
95
+export const request = createRequestFunction(service)
96
+
97
+// 用于模拟网络请求的实例和请求方法
98
+export const serviceForMock = createService()
99
+export const requestForMock = createRequestFunction(serviceForMock)
100
+
101
+// 网络请求数据模拟工具
102
+export const mock = new Adapter(serviceForMock)

+ 86 - 0
src/api/tools.js

@@ -0,0 +1,86 @@
1
+import { Message } from 'element-ui'
2
+import store from '@/store'
3
+import util from '@/libs/util'
4
+
5
+/**
6
+ * @description 安全地解析 json 字符串
7
+ * @param {String} jsonString 需要解析的 json 字符串
8
+ * @param {String} defaultValue 默认值
9
+ */
10
+export function parse (jsonString = '{}', defaultValue = {}) {
11
+  let result = defaultValue
12
+  try {
13
+    result = JSON.parse(jsonString)
14
+  } catch (error) {
15
+    console.log(error)
16
+  }
17
+  return result
18
+}
19
+
20
+/**
21
+ * @description 接口请求返回
22
+ * @param {Any} data 返回值
23
+ * @param {String} msg 状态信息
24
+ * @param {Number} code 状态码
25
+ */
26
+export function response (data = {}, msg = '', code = 0) {
27
+  return [
28
+    200,
29
+    { code, msg, data }
30
+  ]
31
+}
32
+
33
+/**
34
+ * @description 接口请求返回 正确返回
35
+ * @param {Any} data 返回值
36
+ * @param {String} msg 状态信息
37
+ */
38
+export function responseSuccess (data = {}, msg = '成功') {
39
+  return response(data, msg)
40
+}
41
+
42
+/**
43
+ * @description 接口请求返回 错误返回
44
+ * @param {Any} data 返回值
45
+ * @param {String} msg 状态信息
46
+ * @param {Number} code 状态码
47
+ */
48
+export function responseError (data = {}, msg = '请求失败', code = 500) {
49
+  return response(data, msg, code)
50
+}
51
+
52
+/**
53
+ * @description 记录和显示错误
54
+ * @param {Error} error 错误对象
55
+ */
56
+export function errorLog (error) {
57
+  // 添加到日志
58
+  store.dispatch('d2admin/log/push', {
59
+    message: '数据请求异常',
60
+    type: 'danger',
61
+    meta: {
62
+      error
63
+    }
64
+  })
65
+  // 打印到控制台
66
+  if (process.env.NODE_ENV === 'development') {
67
+    util.log.danger('>>>>>> Error >>>>>>')
68
+    console.log(error)
69
+  }
70
+  // 显示提示
71
+  Message({
72
+    message: error.message,
73
+    type: 'error',
74
+    duration: 5 * 1000
75
+  })
76
+}
77
+
78
+/**
79
+ * @description 创建一个错误
80
+ * @param {String} msg 错误信息
81
+ */
82
+export function errorCreate (msg) {
83
+  const error = new Error(msg)
84
+  errorLog(error)
85
+  throw error
86
+}

BIN
src/assets/images/bg.png


BIN
src/assets/images/logo.png


BIN
src/assets/images/nav-bg.png


+ 27 - 0
src/assets/style/animate/vue-transition.scss

@@ -0,0 +1,27 @@
1
+// 过渡动画 横向渐变
2
+.fade-transverse-leave-active,
3
+.fade-transverse-enter-active {
4
+  transition: all .5s;
5
+}
6
+.fade-transverse-enter {
7
+  opacity: 0;
8
+  transform: translateX(-30px);
9
+}
10
+.fade-transverse-leave-to {
11
+  opacity: 0;
12
+  transform: translateX(30px);
13
+}
14
+
15
+// 过渡动画 缩放渐变
16
+.fade-scale-leave-active,
17
+.fade-scale-enter-active {
18
+  transition: all .3s;
19
+}
20
+.fade-scale-enter {
21
+  opacity: 0;
22
+  transform: scale(1.2);
23
+}
24
+.fade-scale-leave-to {
25
+  opacity: 0;
26
+  transform: scale(0.8);
27
+}

+ 12 - 0
src/assets/style/fixed/base.scss

@@ -0,0 +1,12 @@
1
+// 优化显示
2
+html, body {
3
+  margin: 0px;
4
+  height: 100%;
5
+  font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
6
+  #app {
7
+    @extend %full;
8
+    a {
9
+      text-decoration: none;
10
+    }
11
+  }
12
+}

+ 31 - 0
src/assets/style/fixed/element.scss

@@ -0,0 +1,31 @@
1
+// element 样式补丁
2
+.el-card {
3
+  &.is-always-shadow {
4
+    box-shadow: 0 0 8px 0 rgba(232,237,250,.6), 0 2px 4px 0 rgba(232,237,250,.5);
5
+  }
6
+  &.is-hover-shadow {
7
+    &:hover {
8
+      box-shadow: 0 0 8px 0 rgba(232,237,250,.6), 0 2px 4px 0 rgba(232,237,250,.5);
9
+    }
10
+  }
11
+}
12
+
13
+.el-menu--horizontal {
14
+  border-bottom: none !important;
15
+}
16
+
17
+.el-tabs__item:focus.is-active.is-focus:not(:active) {
18
+  box-shadow: none !important;
19
+}
20
+
21
+// 修复IE宽度不能撑满
22
+.el-table__body,
23
+.el-table__header {
24
+  width: 100% !important;
25
+}
26
+
27
+// Chrome下表格头部错位修复
28
+.el-table th.gutter,
29
+.el-table colgroup.gutter {
30
+  display: table-cell !important;
31
+}

+ 9 - 0
src/assets/style/fixed/markdown.scss

@@ -0,0 +1,9 @@
1
+// markdown 样式补丁
2
+.markdown-body {
3
+  ul {
4
+    list-style: disc;
5
+  }
6
+  h1, h2 {
7
+    border-bottom: none;
8
+  }
9
+}

+ 8 - 0
src/assets/style/fixed/n-progress.scss

@@ -0,0 +1,8 @@
1
+#nprogress {
2
+  .bar {
3
+    background: $color-primary !important;
4
+  }
5
+  .peg {
6
+    box-shadow: 0 0 10px $color-primary, 0 0 5px $color-primary !important;
7
+  }
8
+}

+ 5 - 0
src/assets/style/fixed/tree-view.scss

@@ -0,0 +1,5 @@
1
+.tree-view-wrapper.tree-view-small {
2
+  .tree-view-item {
3
+    font-size: 10px;
4
+  }
5
+}

+ 9 - 0
src/assets/style/fixed/vue-grid-layout.scss

@@ -0,0 +1,9 @@
1
+// vue-splitpane 样式补丁
2
+.vue-grid-item {
3
+  &.vue-grid-placeholder {
4
+    border: 1px solid $color-border-1;
5
+    background-color: rgba(#FFF, .3);
6
+    opacity: 1;
7
+    border-radius: 4px;
8
+  }
9
+}

+ 5 - 0
src/assets/style/fixed/vue-splitpane.scss

@@ -0,0 +1,5 @@
1
+// vue-splitpane 样式补丁
2
+.splitter-pane-resizer {
3
+  background-color: $color-border-1 !important;
4
+  opacity: 1 !important;
5
+}

+ 67 - 0
src/assets/style/public-class.scss

@@ -0,0 +1,67 @@
1
+@import 'public';
2
+
3
+// 补丁 base
4
+@import '~@/assets/style/fixed/base.scss';
5
+// 补丁 element
6
+@import '~@/assets/style/fixed/element.scss';
7
+// 补丁 markdown
8
+@import '~@/assets/style/fixed/markdown.scss';
9
+// 补丁 n-progress
10
+@import '~@/assets/style/fixed/n-progress.scss';
11
+// 补丁 vue-splitpane
12
+@import '~@/assets/style/fixed/vue-splitpane.scss';
13
+// 补丁 vue-grid-layout
14
+@import '~@/assets/style/fixed/vue-grid-layout.scss';
15
+// 补丁 tree-view
16
+@import '~@/assets/style/fixed/tree-view.scss';
17
+
18
+// 动画
19
+@import '~@/assets/style/animate/vue-transition.scss';
20
+
21
+// 在这里写公用的class
22
+// 注意 这个文件里只写class
23
+// mixin等内容请在 public.scss 里书写
24
+
25
+// 文字相关
26
+.#{$prefix}-text-center {
27
+  text-align: center;
28
+}
29
+
30
+// 浮动相关
31
+.#{$prefix}-fl {
32
+  float: left;
33
+}
34
+.#{$prefix}-fr {
35
+  float: right;
36
+}
37
+
38
+// 边距相关
39
+$sizes: (0, 5, 10, 15, 20);
40
+
41
+@for $index from 1 to 6 {
42
+  .#{$prefix}-m-#{nth($sizes, $index)} { margin: #{nth($sizes, $index)}px !important; }
43
+  .#{$prefix}-mt-#{nth($sizes, $index)} { margin-top: #{nth($sizes, $index)}px !important; }
44
+  .#{$prefix}-mr-#{nth($sizes, $index)} { margin-right: #{nth($sizes, $index)}px !important; }
45
+  .#{$prefix}-mb-#{nth($sizes, $index)} { margin-bottom: #{nth($sizes, $index)}px !important; }
46
+  .#{$prefix}-ml-#{nth($sizes, $index)} { margin-left: #{nth($sizes, $index)}px !important; }
47
+
48
+  .#{$prefix}-p-#{nth($sizes, $index)} { padding: #{nth($sizes, $index)}px !important; }
49
+  .#{$prefix}-pt-#{nth($sizes, $index)} { padding-top: #{nth($sizes, $index)}px !important; }
50
+  .#{$prefix}-pr-#{nth($sizes, $index)} { padding-right: #{nth($sizes, $index)}px !important; }
51
+  .#{$prefix}-pb-#{nth($sizes, $index)} { padding-bottom: #{nth($sizes, $index)}px !important; }
52
+  .#{$prefix}-pl-#{nth($sizes, $index)} { padding-left: #{nth($sizes, $index)}px !important; }
53
+}
54
+
55
+// 快速使用
56
+
57
+.#{$prefix}-m { margin: 20px !important; }
58
+.#{$prefix}-mt { margin-top: 20px !important; }
59
+.#{$prefix}-mr { margin-right: 20px !important; }
60
+.#{$prefix}-mb { margin-bottom: 20px !important; }
61
+.#{$prefix}-ml { margin-left: 20px !important; }
62
+
63
+.#{$prefix}-p { padding: 20px !important; }
64
+.#{$prefix}-pt { padding-top: 20px !important; }
65
+.#{$prefix}-pr { padding-right: 20px !important; }
66
+.#{$prefix}-pb { padding-bottom: 20px !important; }
67
+.#{$prefix}-pl { padding-left: 20px !important; }

+ 44 - 0
src/assets/style/public.scss

@@ -0,0 +1,44 @@
1
+@import '~@/assets/style/unit/color.scss';
2
+
3
+// 工具类名统一前缀
4
+$prefix: d2;
5
+
6
+// 禁止用户选中 鼠标变为手形
7
+%unable-select {
8
+  user-select: none;
9
+  cursor: pointer;
10
+}
11
+
12
+// 填满父元素
13
+// 组要父元素 position: relative | absolute;
14
+%full {
15
+  position: absolute;
16
+  top: 0px;
17
+  right: 0px;
18
+  bottom: 0px;
19
+  left: 0px;
20
+}
21
+
22
+// flex 垂直水平居中
23
+%flex-center-row {
24
+  display: flex;
25
+  justify-content: center;
26
+  align-items: center;
27
+  flex-direction: row;
28
+}
29
+%flex-center-col {
30
+  display: flex;
31
+  justify-content: center;
32
+  align-items: center;
33
+  flex-direction: column;
34
+}
35
+
36
+// 将元素模拟成卡片外观
37
+%card {
38
+  border: 1px solid #dddee1;
39
+  border-color: #e9eaec;
40
+  background: #fff;
41
+  border-radius: 4px;
42
+  font-size: 14px;
43
+  position: relative;
44
+}

+ 2 - 0
src/assets/style/theme/chester/index.scss

@@ -0,0 +1,2 @@
1
+@import './setting.scss';
2
+@import '../theme.scss';

+ 64 - 0
src/assets/style/theme/chester/setting.scss

@@ -0,0 +1,64 @@
1
+// 主题名称
2
+$theme-name: 'chester';
3
+// 主题背景颜色
4
+$theme-bg-color: #2C3643;
5
+// 主题背景图片遮罩
6
+$theme-bg-mask: rgba(#000, 0);
7
+
8
+// 消息提示
9
+$theme-message-info-background-color: #FFFFFF;
10
+$theme-message-info-text-color: #222A34;
11
+$theme-message-info-border-color: #222A34;
12
+
13
+// container组件
14
+$theme-container-background-color: rgba(#FFF, 1);
15
+$theme-container-header-footer-background-color: #FFF;
16
+$theme-container-border-inner: 1px solid #CFD7E5;
17
+$theme-container-border-outer: 1px solid #2A2D2E;
18
+
19
+$theme-multiple-page-control-color: #CCCCCC;
20
+$theme-multiple-page-control-color-active: #242D38;
21
+$theme-multiple-page-control-nav-prev-color: #CCCCCC;
22
+$theme-multiple-page-control-nav-next-color: #CCCCCC;
23
+$theme-multiple-page-control-border-color: #2A2D2E;
24
+$theme-multiple-page-control-border-color-active: #FFFFFF;
25
+$theme-multiple-page-control-background-color: #242D38;
26
+$theme-multiple-page-control-background-color-active: #FFFFFF;
27
+
28
+// 顶栏和侧边栏中展开的菜单 hover 状态下
29
+$theme-menu-item-color-hover: #CCCCCC;
30
+$theme-menu-item-background-color-hover: #2A2D2E;
31
+
32
+// 顶栏上的文字颜色
33
+$theme-header-item-color: #CCCCCC;
34
+$theme-header-item-background-color: transparent;
35
+// 顶栏上的项目在 hover 时
36
+$theme-header-item-color-hover: #CCCCCC;
37
+$theme-header-item-background-color-hover: #2A2D2E;
38
+// 顶栏上的项目在 focus 时
39
+$theme-header-item-color-focus: #CCCCCC;
40
+$theme-header-item-background-color-focus: #222A34;
41
+// 顶栏上的项目在 active 时
42
+$theme-header-item-color-active: #FFFFFF;
43
+$theme-header-item-background-color-active: #222A34;
44
+
45
+// 侧边栏上的文字颜色
46
+$theme-aside-item-color: #CCCCCC;
47
+$theme-aside-item-background-color: transparent;
48
+// 侧边栏上的项目在 hover 时
49
+$theme-aside-item-color-hover: #CCCCCC;
50
+$theme-aside-item-background-color-hover: #2A2D2E;
51
+// 侧边栏上的项目在 focus 时
52
+$theme-aside-item-color-focus: #CCCCCC;
53
+$theme-aside-item-background-color-focus: #222A34;
54
+// 侧边栏上的项目在 active 时
55
+$theme-aside-item-color-active: #FFFFFF;
56
+$theme-aside-item-background-color-active: #222A34;
57
+
58
+// 侧边栏菜单为空的时候显示的元素
59
+$theme-aside-menu-empty-icon-color: #CCCCCC;
60
+$theme-aside-menu-empty-text-color: #CCCCCC;
61
+$theme-aside-menu-empty-background-color: #242D38;
62
+$theme-aside-menu-empty-icon-color-hover: #FFFFFF;
63
+$theme-aside-menu-empty-text-color-hover: #FFFFFF;
64
+$theme-aside-menu-empty-background-color-hover: #242D38;

+ 2 - 0
src/assets/style/theme/d2/index.scss

@@ -0,0 +1,2 @@
1
+@import './setting.scss';
2
+@import '../theme.scss';

+ 64 - 0
src/assets/style/theme/d2/setting.scss

@@ -0,0 +1,64 @@
1
+// 主题名称
2
+$theme-name: 'd2';
3
+// 主题背景颜色
4
+$theme-bg-color: #ebf1f6;
5
+// 主题背景图片遮罩
6
+$theme-bg-mask: rgba(#000, 0);
7
+
8
+// 消息提示
9
+$theme-message-info-background-color: $color-bg;
10
+$theme-message-info-text-color: $color-text-normal;
11
+$theme-message-info-border-color: $color-border-1;
12
+
13
+// container组件
14
+$theme-container-background-color: rgba(#FFF, 1);
15
+$theme-container-header-footer-background-color: #FFF;
16
+$theme-container-border-inner: 1px solid #cfd7e5;
17
+$theme-container-border-outer: 1px solid #cfd7e5;
18
+
19
+$theme-multiple-page-control-color: $color-text-normal;
20
+$theme-multiple-page-control-color-active: #2f74ff;
21
+$theme-multiple-page-control-nav-prev-color: #cfd7e5;
22
+$theme-multiple-page-control-nav-next-color: #cfd7e5;
23
+$theme-multiple-page-control-border-color: #cfd7e5;
24
+$theme-multiple-page-control-border-color-active: #FFF;
25
+$theme-multiple-page-control-background-color: rgba(#000, .03);
26
+$theme-multiple-page-control-background-color-active: #FFF;
27
+
28
+// 顶栏和侧边栏中展开的菜单 hover 状态下
29
+$theme-menu-item-color-hover: #293849;
30
+$theme-menu-item-background-color-hover: #ecf5ff;
31
+
32
+// 顶栏上的文字颜色
33
+$theme-header-item-color: $color-text-normal;
34
+$theme-header-item-background-color: transparent;
35
+// 顶栏上的项目在 hover 时
36
+$theme-header-item-color-hover: #2f74ff;
37
+$theme-header-item-background-color-hover: rgba(#FFF, .5);
38
+// 顶栏上的项目在 focus 时
39
+$theme-header-item-color-focus: #2f74ff;
40
+$theme-header-item-background-color-focus: rgba(#FFF, .5);
41
+// 顶栏上的项目在 active 时
42
+$theme-header-item-color-active: #2f74ff;
43
+$theme-header-item-background-color-active: rgba(#FFF, .5);
44
+
45
+// 侧边栏上的文字颜色
46
+$theme-aside-item-color: $color-text-normal;
47
+$theme-aside-item-background-color: transparent;
48
+// 侧边栏上的项目在 hover 时
49
+$theme-aside-item-color-hover: #2f74ff;
50
+$theme-aside-item-background-color-hover: rgba(#FFF, .5);
51
+// 侧边栏上的项目在 focus 时
52
+$theme-aside-item-color-focus: #2f74ff;
53
+$theme-aside-item-background-color-focus: rgba(#FFF, .5);
54
+// 侧边栏上的项目在 active 时
55
+$theme-aside-item-color-active: #2f74ff;
56
+$theme-aside-item-background-color-active: rgba(#FFF, .5);
57
+
58
+// 侧边栏菜单为空的时候显示的元素
59
+$theme-aside-menu-empty-icon-color: $color-text-normal;
60
+$theme-aside-menu-empty-text-color: $color-text-normal;
61
+$theme-aside-menu-empty-background-color: rgba(#000, .03);
62
+$theme-aside-menu-empty-icon-color-hover: $color-text-main;
63
+$theme-aside-menu-empty-text-color-hover: $color-text-main;
64
+$theme-aside-menu-empty-background-color-hover: rgba(#000, .05);

+ 2 - 0
src/assets/style/theme/element/index.scss

@@ -0,0 +1,2 @@
1
+@import './setting.scss';
2
+@import '../theme.scss';

+ 64 - 0
src/assets/style/theme/element/setting.scss

@@ -0,0 +1,64 @@
1
+// 主题名称
2
+$theme-name: 'element';
3
+// 主题背景颜色
4
+$theme-bg-color: #314255;
5
+// 主题背景图片遮罩
6
+$theme-bg-mask: rgba(#000, 0);
7
+
8
+// 消息提示
9
+$theme-message-info-background-color: #FFFFFF;
10
+$theme-message-info-text-color: #202D3D;
11
+$theme-message-info-border-color: #202D3D;
12
+
13
+// container组件
14
+$theme-container-background-color: rgba(#FFF, 1);
15
+$theme-container-header-footer-background-color: #FFF;
16
+$theme-container-border-inner: 1px solid #CFD7E5;
17
+$theme-container-border-outer: 1px solid #011527;
18
+
19
+$theme-multiple-page-control-color: #BFCBD9;
20
+$theme-multiple-page-control-color-active: #46A0FC;
21
+$theme-multiple-page-control-nav-prev-color: #BFCBD9;
22
+$theme-multiple-page-control-nav-next-color: #BFCBD9;
23
+$theme-multiple-page-control-border-color: #011527;
24
+$theme-multiple-page-control-border-color-active: #FFFFFF;
25
+$theme-multiple-page-control-background-color: #212D3D;
26
+$theme-multiple-page-control-background-color-active: #FFFFFF;
27
+
28
+// 顶栏和侧边栏中展开的菜单 hover 状态下
29
+$theme-menu-item-color-hover: #BFCBD9;
30
+$theme-menu-item-background-color-hover: #011527;
31
+
32
+// 顶栏上的文字颜色
33
+$theme-header-item-color: #BFCBD9;
34
+$theme-header-item-background-color: transparent;
35
+// 顶栏上的项目在 hover 时
36
+$theme-header-item-color-hover: #BFCBD9;
37
+$theme-header-item-background-color-hover: #011527;
38
+// 顶栏上的项目在 focus 时
39
+$theme-header-item-color-focus: #BFCBD9;
40
+$theme-header-item-background-color-focus: #202D3D;
41
+// 顶栏上的项目在 active 时
42
+$theme-header-item-color-active: #46A0FC;
43
+$theme-header-item-background-color-active: #202D3D;
44
+
45
+// 侧边栏上的文字颜色
46
+$theme-aside-item-color: #BFCBD9;
47
+$theme-aside-item-background-color: transparent;
48
+// 侧边栏上的项目在 hover 时
49
+$theme-aside-item-color-hover: #BFCBD9;
50
+$theme-aside-item-background-color-hover: #011527;
51
+// 侧边栏上的项目在 focus 时
52
+$theme-aside-item-color-focus: #BFCBD9;
53
+$theme-aside-item-background-color-focus: #202D3D;
54
+// 侧边栏上的项目在 active 时
55
+$theme-aside-item-color-active: #46A0FC;
56
+$theme-aside-item-background-color-active: #202D3D;
57
+
58
+// 侧边栏菜单为空的时候显示的元素
59
+$theme-aside-menu-empty-icon-color: #BFCBD9;
60
+$theme-aside-menu-empty-text-color: #BFCBD9;
61
+$theme-aside-menu-empty-background-color: #202D3D;
62
+$theme-aside-menu-empty-icon-color-hover: #46A0FC;
63
+$theme-aside-menu-empty-text-color-hover: #46A0FC;
64
+$theme-aside-menu-empty-background-color-hover: #202D3D;

+ 2 - 0
src/assets/style/theme/line/index.scss

@@ -0,0 +1,2 @@
1
+@import './setting.scss';
2
+@import '../theme.scss';

+ 64 - 0
src/assets/style/theme/line/setting.scss

@@ -0,0 +1,64 @@
1
+// 主题名称
2
+$theme-name: 'line';
3
+// 主题背景颜色
4
+$theme-bg-color: #f8f8f9;
5
+// 主题背景图片遮罩
6
+$theme-bg-mask: rgba(#000, 0);
7
+
8
+// 消息提示
9
+$theme-message-info-background-color: $color-bg;
10
+$theme-message-info-text-color: $color-text-normal;
11
+$theme-message-info-border-color: $color-border-1;
12
+
13
+// container组件
14
+$theme-container-background-color: rgba(#FFF, .8);
15
+$theme-container-header-footer-background-color: #FFF;
16
+$theme-container-border-inner: 1px solid $color-border-2;
17
+$theme-container-border-outer: 1px solid #cfd7e5;
18
+
19
+$theme-multiple-page-control-color: #FFF;
20
+$theme-multiple-page-control-color-active: $color-text-normal;
21
+$theme-multiple-page-control-nav-prev-color: #cfd7e5;
22
+$theme-multiple-page-control-nav-next-color: #cfd7e5;
23
+$theme-multiple-page-control-border-color: #cfd7e5;
24
+$theme-multiple-page-control-border-color-active: #FFF;
25
+$theme-multiple-page-control-background-color: #cfd7e5;
26
+$theme-multiple-page-control-background-color-active: #FFF;
27
+
28
+// 顶栏和侧边栏中展开的菜单 hover 状态下
29
+$theme-menu-item-color-hover: #293849;
30
+$theme-menu-item-background-color-hover: #EFEFEF;
31
+
32
+// 顶栏上的文字颜色
33
+$theme-header-item-color: $color-text-normal;
34
+$theme-header-item-background-color: transparent;
35
+// 顶栏上的项目在 hover 时
36
+$theme-header-item-color-hover: $color-text-main;
37
+$theme-header-item-background-color-hover: rgba(#000, .02);
38
+// 顶栏上的项目在 focus 时
39
+$theme-header-item-color-focus: $color-text-main;
40
+$theme-header-item-background-color-focus: rgba(#000, .02);
41
+// 顶栏上的项目在 active 时
42
+$theme-header-item-color-active: $color-text-main;
43
+$theme-header-item-background-color-active: rgba(#000, .03);
44
+
45
+// 侧边栏上的文字颜色
46
+$theme-aside-item-color: $color-text-normal;
47
+$theme-aside-item-background-color: transparent;
48
+// 侧边栏上的项目在 hover 时
49
+$theme-aside-item-color-hover: $color-text-main;
50
+$theme-aside-item-background-color-hover: rgba(#000, .02);
51
+// 侧边栏上的项目在 focus 时
52
+$theme-aside-item-color-focus: $color-text-main;
53
+$theme-aside-item-background-color-focus: rgba(#000, .02);
54
+// 侧边栏上的项目在 active 时
55
+$theme-aside-item-color-active: $color-text-main;
56
+$theme-aside-item-background-color-active: rgba(#000, .03);
57
+
58
+// 侧边栏菜单为空的时候显示的元素
59
+$theme-aside-menu-empty-icon-color: $color-text-normal;
60
+$theme-aside-menu-empty-text-color: $color-text-normal;
61
+$theme-aside-menu-empty-background-color: rgba(#000, .03);
62
+$theme-aside-menu-empty-icon-color-hover: $color-text-main;
63
+$theme-aside-menu-empty-text-color-hover: $color-text-main;
64
+$theme-aside-menu-empty-background-color-hover: rgba(#000, .05);

+ 9 - 0
src/assets/style/theme/register.scss

@@ -0,0 +1,9 @@
1
+@import '~@/assets/style/theme/theme-base.scss';
2
+
3
+@import '~@/assets/style/theme/d2/index.scss';
4
+@import '~@/assets/style/theme/chester/index.scss';
5
+@import '~@/assets/style/theme/element/index.scss';
6
+@import '~@/assets/style/theme/line/index.scss';
7
+@import '~@/assets/style/theme/star/index.scss';
8
+@import '~@/assets/style/theme/tomorrow-night-blue/index.scss';
9
+@import '~@/assets/style/theme/violet/index.scss';

+ 2 - 0
src/assets/style/theme/star/index.scss

@@ -0,0 +1,2 @@
1
+@import './setting.scss';
2
+@import '../theme.scss';

+ 64 - 0
src/assets/style/theme/star/setting.scss

@@ -0,0 +1,64 @@
1
+// 主题名称
2
+$theme-name: 'star';
3
+// 主题背景颜色
4
+$theme-bg-color: #EFF4F8;
5
+// 主题背景图片遮罩
6
+$theme-bg-mask: rgba(#000, .3);
7
+
8
+// 消息提示
9
+$theme-message-info-background-color: $color-bg;
10
+$theme-message-info-text-color: $color-text-normal;
11
+$theme-message-info-border-color: $color-border-1;
12
+
13
+// container组件
14
+$theme-container-background-color: rgba(#FFF, .9);
15
+$theme-container-header-footer-background-color: #FFF;
16
+$theme-container-border-inner: 1px solid $color-border-1;
17
+$theme-container-border-outer: 1px solid #114450;
18
+
19
+$theme-multiple-page-control-color: #FFF;
20
+$theme-multiple-page-control-color-active: $color-text-normal;
21
+$theme-multiple-page-control-nav-prev-color: #FFF;
22
+$theme-multiple-page-control-nav-next-color: #FFF;
23
+$theme-multiple-page-control-border-color: #114450;
24
+$theme-multiple-page-control-border-color-active: #FFF;
25
+$theme-multiple-page-control-background-color: rgba(#FFF, .5);
26
+$theme-multiple-page-control-background-color-active: #FFF;
27
+
28
+// 顶栏和侧边栏中展开的菜单 hover 状态下
29
+$theme-menu-item-color-hover: #293849;
30
+$theme-menu-item-background-color-hover: #ecf5ff;
31
+
32
+// 顶栏上的文字颜色
33
+$theme-header-item-color: #FFF;
34
+$theme-header-item-background-color: transparent;
35
+// 顶栏上的项目在 hover 时
36
+$theme-header-item-color-hover: #FFF;
37
+$theme-header-item-background-color-hover: rgba(#000, .2);
38
+// 顶栏上的项目在 focus 时
39
+$theme-header-item-color-focus: #FFF;
40
+$theme-header-item-background-color-focus: rgba(#000, .2);
41
+// 顶栏上的项目在 active 时
42
+$theme-header-item-color-active: #FFF;
43
+$theme-header-item-background-color-active: rgba(#000, .3);
44
+
45
+// 侧边栏上的文字颜色
46
+$theme-aside-item-color: #FFF;
47
+$theme-aside-item-background-color: transparent;
48
+// 侧边栏上的项目在 hover 时
49
+$theme-aside-item-color-hover: #FFF;
50
+$theme-aside-item-background-color-hover: rgba(#000, .2);
51
+// 侧边栏上的项目在 focus 时
52
+$theme-aside-item-color-focus: #FFF;
53
+$theme-aside-item-background-color-focus: rgba(#000, .2);
54
+// 侧边栏上的项目在 active 时
55
+$theme-aside-item-color-active: #FFF;
56
+$theme-aside-item-background-color-active: rgba(#000, .3);
57
+
58
+// 侧边栏菜单为空的时候显示的元素
59
+$theme-aside-menu-empty-icon-color: #FFF;
60
+$theme-aside-menu-empty-text-color: #FFF;
61
+$theme-aside-menu-empty-background-color: rgba(#FFF, .2);
62
+$theme-aside-menu-empty-icon-color-hover: #FFF;
63
+$theme-aside-menu-empty-text-color-hover: #FFF;
64
+$theme-aside-menu-empty-background-color-hover: rgba(#FFF, .3);

+ 455 - 0
src/assets/style/theme/theme-base.scss

@@ -0,0 +1,455 @@
1
+// 减小弹出菜单的项目高度
2
+.el-menu--popup {
3
+  .el-menu-item {
4
+    height: 36px;
5
+    line-height: 36px;
6
+  }
7
+  .el-submenu__title {
8
+    height: 36px;
9
+    line-height: 36px;
10
+  }
11
+}
12
+
13
+// 整体框架结构
14
+.d2-layout-header-aside-group {
15
+  height: 100%;
16
+  width: 100%;
17
+  min-width: 900px;
18
+  background-size: cover;
19
+  background-position: center;
20
+  overflow: hidden;
21
+  position: relative;
22
+  // 背景上面的半透明遮罩
23
+  .d2-layout-header-aside-mask {
24
+    @extend %full;
25
+  }
26
+  // 内容层
27
+  .d2-layout-header-aside-content {
28
+    @extend %full;
29
+    .d2-theme-header {
30
+      height: 60px;
31
+      .d2-theme-header-menu {
32
+        overflow: hidden;
33
+        margin-left:20px;
34
+        &.is-scrollable {
35
+          position: relative;
36
+          padding: 0 20px;
37
+          .d2-theme-header-menu__prev, .d2-theme-header-menu__next {
38
+            display: -webkit-box;
39
+            display: -ms-flexbox;
40
+            display: flex;
41
+          }
42
+        }
43
+        .d2-theme-header-menu__content {
44
+          overflow: hidden;
45
+          .d2-theme-header-menu__scroll {
46
+            white-space: nowrap;
47
+            position: relative;
48
+            -webkit-transition: -webkit-transform .3s;
49
+            transition: -webkit-transform .3s;
50
+            transition: transform .3s;
51
+            transition: transform .3s, -webkit-transform .3s;
52
+            transition: transform .3s,-webkit-transform .3s;
53
+            float: left;
54
+          }
55
+        }
56
+        .d2-theme-header-menu__prev, .d2-theme-header-menu__next {
57
+          height: 60px;
58
+          position: absolute;
59
+          top: 0;
60
+          font-size: 20px;
61
+          cursor: pointer;
62
+          display: none;
63
+        }
64
+        .d2-theme-header-menu__prev {
65
+          left: 0;
66
+          border-top-left-radius: 2px;
67
+          border-bottom-left-radius: 2px;
68
+        }
69
+        .d2-theme-header-menu__next {
70
+          right: 0;
71
+          border-top-right-radius: 2px;
72
+          border-bottom-right-radius: 2px;
73
+        }
74
+      }
75
+    }
76
+    .d2-theme-container {
77
+      .d2-theme-container-aside {
78
+        position: relative;
79
+        .d2-layout-header-aside-menu-side {
80
+          @extend %full;
81
+          overflow: hidden;
82
+        }
83
+      }
84
+      .d2-theme-container-transition {
85
+        transition: width .3s;
86
+      }
87
+      .d2-theme-container-main {
88
+        padding: 0px;
89
+        position: relative;
90
+        overflow: hidden;
91
+        .d2-theme-container-main-layer {
92
+          position: absolute;
93
+          top: 0px;
94
+          bottom: 0px;
95
+          left: 0px;
96
+          right: 0px;
97
+        }
98
+        .d2-theme-container-main-body {
99
+          position: relative;
100
+        }
101
+      }
102
+    }
103
+  }
104
+}
105
+
106
+// 主题公用
107
+.d2-layout-header-aside-group {
108
+  &.grayMode {
109
+    -webkit-filter: grayscale(100%);
110
+    -moz-filter: grayscale(100%);
111
+    -ms-filter: grayscale(100%);
112
+    -o-filter: grayscale(100%);
113
+    filter: grayscale(100%);
114
+    filter: gray;
115
+  }
116
+  // 主体
117
+  .d2-layout-header-aside-content {
118
+    // [布局] 顶栏
119
+    .d2-theme-header {
120
+      // logo区域
121
+      .logo-group {
122
+        float: left;
123
+        text-align: center;
124
+        img {
125
+          height: 60px;
126
+        }
127
+      }
128
+      .logo-transition {
129
+        transition: width .3s;
130
+      }
131
+      // 折叠侧边栏切换按钮
132
+      .toggle-aside-btn {
133
+        float: left;
134
+        height: 60px;
135
+        width: 60px;
136
+        display: flex;
137
+        justify-content: center;
138
+        align-items: center;
139
+        @extend %unable-select;
140
+        i {
141
+          font-size: 20px;
142
+          margin-top: 4px;
143
+        }
144
+      }
145
+      // [菜单] 顶栏
146
+      .el-menu {
147
+        float: left;
148
+        border-bottom: none;
149
+        background-color: transparent;
150
+        %header-menu-item {
151
+          @extend %unable-select;
152
+          i.fa {
153
+            font-size: 16px;
154
+            margin-right: 4px;
155
+          }
156
+        }
157
+        .el-menu-item {
158
+          @extend %header-menu-item;
159
+          border-bottom: none;
160
+        }
161
+        .el-submenu {
162
+          @extend %header-menu-item;
163
+          .el-submenu__title {
164
+            border-bottom: none;
165
+          }
166
+        }
167
+      }
168
+      // 顶栏右侧的按钮
169
+      .d2-header-right {
170
+        float: right;
171
+        height: 60px;
172
+        display: flex;
173
+        align-items: center;
174
+        .btn-text {
175
+          padding: 14px 12px;
176
+          border-radius: 4px;
177
+          margin: 0px !important;
178
+          &.el-color-picker.el-color-picker--mini {
179
+            padding: 9px 6px;
180
+          }
181
+        }
182
+        .el-dropdown {
183
+          @extend %unable-select;
184
+        }
185
+      }
186
+    }
187
+    // [布局] 顶栏下面
188
+    .d2-theme-container {
189
+      // 侧边栏
190
+      .d2-theme-container-aside {
191
+        %d2-theme-container-aside-menu-icon {
192
+          width: 20px;
193
+          text-align: center;
194
+          font-size: 16px;
195
+        }
196
+        // [菜单] 正常状态
197
+        .el-menu {
198
+          @extend %unable-select;
199
+          background-color: transparent;
200
+          border-right: none;
201
+          .el-menu-item {
202
+            i {
203
+              @extend %d2-theme-container-aside-menu-icon;
204
+            }
205
+          }
206
+        }
207
+        .el-submenu {
208
+          @extend %unable-select;
209
+          .el-submenu__title {
210
+            i {
211
+              @extend %d2-theme-container-aside-menu-icon;
212
+            }
213
+            .el-submenu__icon-arrow {
214
+              margin-top: -10px;
215
+            }
216
+          }
217
+        }
218
+        // 菜单为空的时候显示的信息
219
+        .d2-layout-header-aside-menu-empty {
220
+          height: 160px;
221
+          margin: 10px;
222
+          margin-top: 0px;
223
+          border-radius: 4px;
224
+          @extend %unable-select;
225
+          i {
226
+            font-size: 30px;
227
+            margin-bottom: 10px;
228
+          }
229
+          span {
230
+            font-size: 14px;
231
+          }
232
+        }
233
+        // [菜单] 折叠状态
234
+        .el-menu--collapse {
235
+          background-color: transparent;
236
+          .el-submenu__title {
237
+            text-align: center;
238
+          }
239
+        }
240
+      }
241
+      // 右下 主体
242
+      .d2-theme-container-main {
243
+        // 主体部分分为多页面控制器 和主体
244
+        .d2-theme-container-main-header {
245
+          height: 41px;
246
+          // 多页面控制器
247
+          .d2-multiple-page-control-group {
248
+            padding-right: 20px;
249
+            .d2-multiple-page-control-content {
250
+              overflow: auto;
251
+              position: relative;
252
+              .d2-multiple-page-control-content-inner {
253
+                .d2-multiple-page-control {
254
+                  .el-tabs__header.is-top {
255
+                    margin: 0px;
256
+                  }
257
+                  .el-tabs__nav {
258
+                    overflow: hidden;
259
+                  }
260
+                }
261
+              }
262
+            }
263
+            .d2-multiple-page-control-btn {
264
+              position: relative;
265
+              bottom: -1px;
266
+              .el-dropdown {
267
+                .el-button-group {
268
+                  .el-button:first-child {
269
+                    border-bottom-left-radius: 0px;
270
+                  }
271
+                  .el-button:last-child {
272
+                    border-bottom-right-radius: 0px;
273
+                  }
274
+                }
275
+              }
276
+            }
277
+          }
278
+        }
279
+        // 主体
280
+        .d2-theme-container-main-body {
281
+          // 布局组件
282
+          .container-component {
283
+            @extend %full;
284
+            overflow: hidden;
285
+            // 填充式布局组件
286
+            .d2-container-full {
287
+              position: absolute;
288
+              top: 0px;
289
+              right: 20px;
290
+              bottom: 20px;
291
+              left: 20px;
292
+              display: flex;
293
+              flex-direction: column;
294
+              overflow: hidden;
295
+              .d2-container-full__header {
296
+                padding: 20px;
297
+              }
298
+              .d2-container-full__body {
299
+                flex-grow: 1;
300
+                height: 100%;
301
+                padding: 20px 20px;
302
+                overflow: auto;
303
+                position: relative;
304
+              }
305
+              .d2-container-full__footer {
306
+                padding: 20px;
307
+              }
308
+            }
309
+            // 填充式布局组件 - 滚动优化
310
+            .d2-container-full-bs {
311
+              position: absolute;
312
+              top: 0px;
313
+              right: 20px;
314
+              bottom: 0px;
315
+              left: 0px;
316
+              display: flex;
317
+              flex-direction: column;
318
+              overflow: hidden;
319
+              .d2-container-full-bs__header {
320
+                padding: 20px;
321
+              }
322
+              .d2-container-full-bs__body {
323
+                flex-grow: 1;
324
+                overflow: hidden;
325
+                position: relative;
326
+                .d2-container-full-bs__body-wrapper-inner {
327
+                  padding: 20px;
328
+                  position: relative;
329
+                }
330
+              }
331
+              .d2-container-full-bs__footer {
332
+                padding: 20px;
333
+              }
334
+            }
335
+            // 隐形布局组件
336
+            .d2-container-ghost {
337
+              position: absolute;
338
+              top: 0px;
339
+              right: 20px;
340
+              bottom: 0px;
341
+              left: 0px;
342
+              display: flex;
343
+              flex-direction: column;
344
+              overflow: hidden;
345
+              .d2-container-ghost__header {
346
+                padding: 20px;
347
+                border-bottom-left-radius: 4px;
348
+                border-bottom-right-radius: 4px;
349
+              }
350
+              .d2-container-ghost__body {
351
+                flex-grow: 1;
352
+                overflow: auto;
353
+                position: relative;
354
+              }
355
+              .d2-container-ghost__footer {
356
+                padding: 20px;
357
+                border-top-left-radius: 4px;
358
+                border-top-right-radius: 4px;
359
+              }
360
+            }
361
+            // 隐形布局组件 - 滚动优化
362
+            .d2-container-ghost-bs {
363
+              position: absolute;
364
+              top: 0px;
365
+              right: 20px;
366
+              bottom: 0px;
367
+              left: 0px;
368
+              display: flex;
369
+              flex-direction: column;
370
+              overflow: hidden;
371
+              .d2-container-ghost-bs__header {
372
+                padding: 20px;
373
+                border-bottom-left-radius: 4px;
374
+                border-bottom-right-radius: 4px;
375
+              }
376
+              .d2-container-ghost-bs__body {
377
+                flex-grow: 1;
378
+                overflow: hidden;
379
+                position: relative;
380
+              }
381
+              .d2-container-ghost-bs__footer {
382
+                padding: 20px;
383
+                border-top-left-radius: 4px;
384
+                border-top-right-radius: 4px;
385
+              }
386
+            }
387
+            // 卡片式布局组件
388
+            .d2-container-card {
389
+              position: absolute;
390
+              top: 0px;
391
+              right: 20px;
392
+              bottom: 0px;
393
+              left: 0px;
394
+              display: flex;
395
+              flex-direction: column;
396
+              overflow: hidden;
397
+              .d2-container-card__header {
398
+                padding: 20px;
399
+              }
400
+              .d2-container-card__body {
401
+                flex-grow: 1;
402
+                overflow: auto;
403
+                .d2-container-card__body-card {
404
+                  position: relative;
405
+                  margin-bottom: 20px;
406
+                  padding: 20px;
407
+                  border-bottom-left-radius: 4px;
408
+                  border-bottom-right-radius: 4px;
409
+                }
410
+              }
411
+              .d2-container-card__footer {
412
+                padding: 20px;
413
+                border-top-left-radius: 4px;
414
+                border-top-right-radius: 4px;
415
+              }
416
+            }
417
+            // 卡片式布局组件 - 滚动优化
418
+            .d2-container-card-bs {
419
+              position: absolute;
420
+              top: 0px;
421
+              right: 20px;
422
+              bottom: 0px;
423
+              left: 0px;
424
+              display: flex;
425
+              flex-direction: column;
426
+              overflow: hidden;
427
+              .d2-container-card-bs__header {
428
+                padding: 20px;
429
+              }
430
+              .d2-container-card-bs__body {
431
+                position: relative;
432
+                flex-grow: 1;
433
+                overflow: hidden;
434
+                .d2-container-card-bs__body-wrapper-inner {
435
+                  padding-bottom: 20px;
436
+                }
437
+                .d2-container-card-bs__body-card {
438
+                  position: relative;
439
+                  padding: 20px;
440
+                  border-bottom-left-radius: 4px;
441
+                  border-bottom-right-radius: 4px;
442
+                }
443
+              }
444
+              .d2-container-card-bs__footer {
445
+                padding: 20px;
446
+                border-top-left-radius: 4px;
447
+                border-top-right-radius: 4px;
448
+              }
449
+            }
450
+          }
451
+        }
452
+      }
453
+    }
454
+  }
455
+}

+ 422 - 0
src/assets/style/theme/theme.scss

@@ -0,0 +1,422 @@
1
+// 每个主题特有的设置
2
+.theme-#{$theme-name} {
3
+
4
+  .el-message {
5
+    &.el-message--info {
6
+      background-color: $theme-message-info-background-color;
7
+      color: $theme-message-info-text-color;
8
+      border-color: $theme-message-info-border-color;
9
+    }
10
+  }
11
+
12
+  .el-card {
13
+    &.d2-card {
14
+      border: $theme-container-border-outer;
15
+      .el-card__header {
16
+        border-bottom: $theme-container-border-outer;
17
+      }
18
+    }
19
+  }
20
+
21
+  // 背景图片和遮罩
22
+  .d2-layout-header-aside-group {
23
+    // background-color: $theme-bg-color;
24
+    
25
+    .d2-layout-header-aside-mask {
26
+      background: $theme-bg-mask;
27
+    }
28
+  }
29
+
30
+  // 菜单项目
31
+  @mixin theme-menu-hover-style {
32
+    color: $theme-menu-item-color-hover;
33
+    i.fa {
34
+      color: $theme-menu-item-color-hover;
35
+    }
36
+    background: $theme-menu-item-background-color-hover;
37
+  }
38
+  %el-menu-icon {
39
+    i {
40
+      display: inline-block;
41
+      width: 14px;
42
+      text-align: center;
43
+      margin-right: 5px;
44
+    }
45
+    svg {
46
+      margin: 0px;
47
+      height: 14px;
48
+      width: 14px;
49
+      margin-right: 5px;
50
+    }
51
+  }
52
+  .el-submenu__title {
53
+    @extend %unable-select;
54
+    @extend %el-menu-icon;
55
+  }
56
+  .el-menu-item {
57
+    @extend %unable-select;
58
+    @extend %el-menu-icon;
59
+  }
60
+  .el-submenu__title:hover {
61
+    @include theme-menu-hover-style;
62
+  }
63
+  .el-menu-item:hover {
64
+    @include theme-menu-hover-style;
65
+  }
66
+  .el-menu--horizontal .el-menu-item:not(.is-disabled):hover {
67
+    @include theme-menu-hover-style;
68
+  }
69
+  .el-menu--horizontal .el-menu .el-submenu__title:hover {
70
+    @include theme-menu-hover-style;
71
+  }
72
+  
73
+  // 顶栏
74
+  .d2-theme-header {
75
+    // 顶栏菜单空间不足时显示的滚动控件
76
+    .d2-theme-header-menu {
77
+      .d2-theme-header-menu__prev, .d2-theme-header-menu__next {
78
+        color: $theme-header-item-color;
79
+        background: $theme-header-item-background-color;
80
+        &:hover {
81
+          color: $theme-header-item-color-hover;
82
+          background: $theme-header-item-background-color-hover;
83
+        }
84
+      }
85
+    }
86
+    // 切换按钮
87
+    .toggle-aside-btn {
88
+      i {
89
+        color: $theme-header-item-color;
90
+        background: $theme-header-item-background-color;
91
+        &:hover {
92
+          color: $theme-header-item-color-hover;
93
+        }
94
+      }
95
+    }
96
+    // 顶栏菜单
97
+    .el-menu {
98
+      .el-menu-item {
99
+        transition: border-top-color 0s;
100
+        color: $theme-header-item-color;
101
+        background: $theme-header-item-background-color;
102
+        i.fa { color: inherit; }
103
+        &:hover {
104
+          color: $theme-header-item-color-hover;
105
+          background: $theme-header-item-background-color-hover;
106
+          i.fa { color: inherit; }
107
+        }
108
+        &:focus {
109
+          color: $theme-header-item-color-focus;
110
+          background: $theme-header-item-background-color-focus;
111
+          i.fa { color: inherit; }
112
+        }
113
+        &.is-active {
114
+          color: $theme-header-item-color-active;
115
+          background: $theme-header-item-background-color-active;
116
+          i.fa { color: inherit; }
117
+        }
118
+      }
119
+      .el-submenu {
120
+        &.is-active {
121
+          .el-submenu__title {
122
+            color: $theme-header-item-color-active;
123
+            background: $theme-header-item-background-color-active;
124
+            i.fa { color: inherit; }
125
+          }
126
+        }
127
+        .el-submenu__title {
128
+          transition: border-top-color 0s;
129
+          color: $theme-header-item-color;
130
+          background: $theme-header-item-background-color;
131
+          i.fa { color: inherit; }
132
+          .el-submenu__icon-arrow {
133
+            color: $theme-header-item-color;
134
+          }
135
+          &:hover {
136
+            color: $theme-header-item-color-hover;
137
+            background: $theme-header-item-background-color-hover;
138
+            i.fa { color: inherit; }
139
+            .el-submenu__icon-arrow {
140
+              color: $theme-header-item-color-hover;
141
+            }
142
+          }
143
+          &:focus {
144
+            color: $theme-header-item-color-focus;
145
+            background: $theme-header-item-background-color-focus;
146
+            i.fa { color: inherit; }
147
+            .el-submenu__icon-arrow {
148
+              color: $theme-header-item-color-focus;
149
+            }
150
+          }
151
+        }
152
+      }
153
+    }
154
+    // 顶栏右侧
155
+    .d2-header-right {
156
+      .btn-text {
157
+        color: $theme-header-item-color;
158
+        &.can-hover {
159
+          &:hover {
160
+            color: $theme-header-item-color-hover;
161
+            background: $theme-header-item-background-color-hover;
162
+          }
163
+        }
164
+      }
165
+    }
166
+  }
167
+  // [布局] 顶栏下面
168
+  .d2-theme-container {
169
+    // 侧边栏
170
+    .d2-theme-container-aside {
171
+      // 菜单为空的时候显示的信息
172
+      .d2-layout-header-aside-menu-empty {
173
+        background: $theme-aside-menu-empty-background-color;
174
+        i {
175
+          color: $theme-aside-menu-empty-icon-color;
176
+        }
177
+        span {
178
+          color: $theme-aside-menu-empty-text-color;
179
+        }
180
+        &:hover {
181
+          background: $theme-aside-menu-empty-background-color-hover;
182
+          i {
183
+            color: $theme-aside-menu-empty-icon-color-hover;
184
+          }
185
+          span {
186
+            color: $theme-aside-menu-empty-text-color-hover;
187
+          }
188
+        }
189
+      }
190
+      // [菜单] 正常状态
191
+      .el-menu {
192
+        .el-menu-item {
193
+          color: $theme-aside-item-color;
194
+          background: $theme-aside-item-background-color;
195
+          i {
196
+            color: $theme-aside-item-color;
197
+          }
198
+          &:hover {
199
+            color: $theme-aside-item-color-hover;
200
+            fill: $theme-aside-item-color-hover;
201
+            background: $theme-aside-item-background-color-hover;
202
+            i {
203
+              color: $theme-aside-item-color-hover;
204
+            }
205
+          }
206
+          &:focus {
207
+            color: $theme-aside-item-color-focus;
208
+            fill: $theme-aside-item-color-focus;
209
+            background: $theme-aside-item-background-color-focus;
210
+            i {
211
+              color: $theme-aside-item-color-focus;
212
+            }
213
+          }
214
+          &.is-active {
215
+            color: $theme-aside-item-color-active;
216
+            fill: $theme-aside-item-color-active;
217
+            background: $theme-aside-item-background-color-active;
218
+            i {
219
+              color: $theme-aside-item-color-active;
220
+            }
221
+          }
222
+        }
223
+      }
224
+      .el-submenu {
225
+        .el-submenu__title {
226
+          color: $theme-aside-item-color;
227
+          background: $theme-aside-item-background-color;
228
+          i {
229
+            color: $theme-aside-item-color;
230
+          }
231
+          .el-submenu__icon-arrow {
232
+            color: $theme-aside-item-color;
233
+          }
234
+          &:hover {
235
+            color: $theme-aside-item-color-hover;
236
+            background: $theme-aside-item-background-color-hover;
237
+            i {
238
+              color: $theme-aside-item-color-hover;
239
+            }
240
+            .el-submenu__icon-arrow {
241
+              color: $theme-aside-item-color-hover;
242
+            }
243
+          }
244
+        }
245
+      }
246
+    }
247
+    .d2-theme-container-main {
248
+      // 主体部分分为多页面控制器 和主体
249
+      .d2-theme-container-main-header {
250
+        // 多页面控制器
251
+        .d2-multiple-page-control {
252
+          .el-tabs__header.is-top {
253
+            border-bottom-color: $theme-multiple-page-control-border-color;
254
+          }
255
+          .el-tabs__nav {
256
+            border-color: $theme-multiple-page-control-border-color;
257
+            .el-tabs__item {
258
+              @extend %unable-select;
259
+              color: $theme-multiple-page-control-color;
260
+              background-color: $theme-multiple-page-control-background-color;
261
+              border-left-color: $theme-multiple-page-control-border-color;
262
+              &:first-child {
263
+                border-left: none;
264
+                &:hover {
265
+                  padding: 0px 20px;
266
+                }
267
+              }
268
+            }
269
+            .el-tabs__item.is-active {
270
+              color: $theme-multiple-page-control-color-active;
271
+              background-color: $theme-multiple-page-control-background-color-active;
272
+              border-bottom-color: $theme-multiple-page-control-border-color-active;
273
+            }
274
+          }
275
+          %el-tabs__nav {
276
+            font-size: 20px;
277
+          }
278
+          .el-tabs__nav-prev {
279
+            @extend %el-tabs__nav;
280
+            color: $theme-multiple-page-control-nav-prev-color;
281
+          }
282
+          .el-tabs__nav-next {
283
+            @extend %el-tabs__nav;
284
+            color: $theme-multiple-page-control-nav-next-color;
285
+          }
286
+        }
287
+        // 多页控制器的关闭控制
288
+        .d2-multiple-page-control-btn {
289
+          .el-dropdown {
290
+            .el-button-group {
291
+              .el-button {
292
+                border-color: $theme-multiple-page-control-border-color;
293
+              }
294
+            }
295
+          }
296
+        }
297
+      }
298
+      // 主体
299
+      .d2-theme-container-main-body {
300
+        // 布局组件
301
+        .container-component {
302
+          // [组件]
303
+          // d2-container-full 填充型
304
+          .d2-container-full {
305
+            border: $theme-container-border-outer;
306
+            border-top: none;
307
+            border-bottom: none;
308
+            .d2-container-full__header {
309
+              border-bottom: $theme-container-border-inner;
310
+              background: $theme-container-header-footer-background-color;
311
+            }
312
+            .d2-container-full__body {
313
+              background: $theme-container-background-color;
314
+            }
315
+            .d2-container-full__footer {
316
+              border-top: $theme-container-border-inner;
317
+              background: $theme-container-header-footer-background-color;
318
+            }
319
+          }
320
+          // [组件]
321
+          // d2-container-full-bs 填充型 滚动优化
322
+          .d2-container-full-bs {
323
+            border: $theme-container-border-outer;
324
+            border-top: none;
325
+            border-bottom: none;
326
+            .d2-container-full-bs__header {
327
+              border-bottom: $theme-container-border-inner;
328
+              background: $theme-container-header-footer-background-color;
329
+            }
330
+            .d2-container-full-bs__body {
331
+              background: $theme-container-background-color;
332
+            }
333
+            .d2-container-full-bs__footer {
334
+              border-top: $theme-container-border-inner;
335
+              background: $theme-container-header-footer-background-color;
336
+            }
337
+          }
338
+          // [组件]
339
+          // d2-container-ghost 隐形布局组件
340
+          .d2-container-ghost {
341
+            .d2-container-ghost__header {
342
+              border-bottom: $theme-container-border-outer;
343
+              border-left: $theme-container-border-outer;
344
+              border-right: $theme-container-border-outer;
345
+              background: $theme-container-header-footer-background-color;
346
+            }
347
+            .d2-container-ghost__footer {
348
+              border-top: $theme-container-border-outer;
349
+              border-left: $theme-container-border-outer;
350
+              border-right: $theme-container-border-outer;
351
+              background: $theme-container-header-footer-background-color;
352
+            }
353
+          }
354
+          // [组件]
355
+          // d2-container-ghost-bs 隐形布局组件 滚动优化
356
+          .d2-container-ghost-bs {
357
+            .d2-container-ghost-bs__header {
358
+              border-bottom: $theme-container-border-outer;
359
+              border-left: $theme-container-border-outer;
360
+              border-right: $theme-container-border-outer;
361
+              background: $theme-container-header-footer-background-color;
362
+            }
363
+            .d2-container-ghost-bs__footer {
364
+              border-top: $theme-container-border-outer;
365
+              border-left: $theme-container-border-outer;
366
+              border-right: $theme-container-border-outer;
367
+              background: $theme-container-header-footer-background-color;
368
+            }
369
+          }
370
+          // [组件]
371
+          // d2-container-card 卡片型
372
+          .d2-container-card {
373
+            .d2-container-card__header {
374
+              border-bottom: $theme-container-border-inner;
375
+              border-left: $theme-container-border-outer;
376
+              border-right: $theme-container-border-outer;
377
+              background: $theme-container-header-footer-background-color;
378
+            }
379
+            .d2-container-card__body {
380
+              .d2-container-card__body-card {
381
+                background: $theme-container-background-color;
382
+                border-left: $theme-container-border-outer;
383
+                border-right: $theme-container-border-outer;
384
+                border-bottom: $theme-container-border-outer;
385
+              }
386
+            }
387
+            .d2-container-card__footer {
388
+              border-top: $theme-container-border-outer;
389
+              border-left: $theme-container-border-outer;
390
+              border-right: $theme-container-border-outer;
391
+              background: $theme-container-header-footer-background-color;
392
+            }
393
+          }
394
+          // [组件]
395
+          // d2-container-card-bs 卡片型 滚动优化
396
+          .d2-container-card-bs {
397
+            .d2-container-card-bs__header {
398
+              border-bottom: $theme-container-border-inner;
399
+              border-left: $theme-container-border-outer;
400
+              border-right: $theme-container-border-outer;
401
+              background: $theme-container-header-footer-background-color;
402
+            }
403
+            .d2-container-card-bs__body {
404
+              .d2-container-card-bs__body-card {
405
+                background: $theme-container-background-color;
406
+                border-left: $theme-container-border-outer;
407
+                border-right: $theme-container-border-outer;
408
+                border-bottom: $theme-container-border-outer;
409
+              }
410
+            }
411
+            .d2-container-card-bs__footer {
412
+              border-top: $theme-container-border-outer;
413
+              border-left: $theme-container-border-outer;
414
+              border-right: $theme-container-border-outer;
415
+              background: $theme-container-header-footer-background-color;
416
+            }
417
+          }
418
+        }
419
+      }
420
+    }
421
+  }
422
+}

+ 2 - 0
src/assets/style/theme/tomorrow-night-blue/index.scss

@@ -0,0 +1,2 @@
1
+@import './setting.scss';
2
+@import '../theme.scss';

+ 64 - 0
src/assets/style/theme/tomorrow-night-blue/setting.scss

@@ -0,0 +1,64 @@
1
+// 主题名称
2
+$theme-name: 'tomorrow-night-blue';
3
+// 主题背景颜色
4
+$theme-bg-color: #002253;
5
+// 主题背景图片遮罩
6
+$theme-bg-mask: rgba(#000, 0);
7
+
8
+// 消息提示
9
+$theme-message-info-background-color: $color-bg;
10
+$theme-message-info-text-color: $color-text-normal;
11
+$theme-message-info-border-color: $color-border-1;
12
+
13
+// container组件
14
+$theme-container-background-color: rgba(#FFF, 1);
15
+$theme-container-header-footer-background-color: #FFF;
16
+$theme-container-border-inner: 1px solid $color-border-1;
17
+$theme-container-border-outer: 1px solid #002253;
18
+
19
+$theme-multiple-page-control-color: #FFF;
20
+$theme-multiple-page-control-color-active: $color-text-normal;
21
+$theme-multiple-page-control-nav-prev-color: #FFF;
22
+$theme-multiple-page-control-nav-next-color: #FFF;
23
+$theme-multiple-page-control-border-color: #002253;
24
+$theme-multiple-page-control-border-color-active: #FFF;
25
+$theme-multiple-page-control-background-color: rgba(#FFF, .2);
26
+$theme-multiple-page-control-background-color-active: #FFF;
27
+
28
+// 顶栏和侧边栏中展开的菜单 hover 状态下
29
+$theme-menu-item-color-hover: #293849;
30
+$theme-menu-item-background-color-hover: #ecf5ff;
31
+
32
+// 顶栏上的文字颜色
33
+$theme-header-item-color: #FF929A;
34
+$theme-header-item-background-color: transparent;
35
+// 顶栏上的项目在 hover 时
36
+$theme-header-item-color-hover: #FFEBA4;
37
+$theme-header-item-background-color-hover: rgba(#FFF, .05);
38
+// 顶栏上的项目在 focus 时
39
+$theme-header-item-color-focus: #FFB870;
40
+$theme-header-item-background-color-focus: rgba(#FFF, .05);
41
+// 顶栏上的项目在 active 时
42
+$theme-header-item-color-active: #FFB870;
43
+$theme-header-item-background-color-active: rgba(#FFF, .05);
44
+
45
+// 侧边栏上的文字颜色
46
+$theme-aside-item-color: #FF929A;
47
+$theme-aside-item-background-color: transparent;
48
+// 侧边栏上的项目在 hover 时
49
+$theme-aside-item-color-hover: #FFEBA4;
50
+$theme-aside-item-background-color-hover: rgba(#FFF, .05);
51
+// 侧边栏上的项目在 focus 时
52
+$theme-aside-item-color-focus: #FFB870;
53
+$theme-aside-item-background-color-focus: rgba(#FFF, .05);
54
+// 侧边栏上的项目在 active 时
55
+$theme-aside-item-color-active: #FFB870;
56
+$theme-aside-item-background-color-active: rgba(#FFF, .05);
57
+
58
+// 侧边栏菜单为空的时候显示的元素
59
+$theme-aside-menu-empty-icon-color: #FFB870;
60
+$theme-aside-menu-empty-text-color: #FFB870;
61
+$theme-aside-menu-empty-background-color: rgba(#FFF, .1);
62
+$theme-aside-menu-empty-icon-color-hover: #FFEBA4;
63
+$theme-aside-menu-empty-text-color-hover: #FFEBA4;
64
+$theme-aside-menu-empty-background-color-hover: rgba(#FFF, .2);

+ 10 - 0
src/assets/style/theme/violet/index.scss

@@ -0,0 +1,10 @@
1
+@import './setting.scss';
2
+@import '../theme.scss';
3
+
4
+.theme-#{$theme-name} {
5
+  .d2-layout-header-aside-group {
6
+    background: #bc00e3;
7
+    background: linear-gradient(120deg, #bc00e3 0%, #4EFFFB 100%);
8
+   
9
+  }
10
+}

+ 64 - 0
src/assets/style/theme/violet/setting.scss

@@ -0,0 +1,64 @@
1
+// 主题名称
2
+$theme-name: 'violet';
3
+// 主题背景颜色
4
+$theme-bg-color: #000;
5
+// 主题背景图片遮罩
6
+$theme-bg-mask: rgba(#000, 0);
7
+
8
+// 消息提示
9
+$theme-message-info-background-color: $color-bg;
10
+$theme-message-info-text-color: $color-text-normal;
11
+$theme-message-info-border-color: $color-border-1;
12
+
13
+// container组件
14
+$theme-container-background-color: #FFF;
15
+$theme-container-header-footer-background-color: #FFF;
16
+$theme-container-border-inner: 1px solid $color-border-2;
17
+$theme-container-border-outer: 1px solid #8C40E2;
18
+
19
+$theme-multiple-page-control-color: #FFF;
20
+$theme-multiple-page-control-color-active: $color-text-normal;
21
+$theme-multiple-page-control-nav-prev-color: #FFF;
22
+$theme-multiple-page-control-nav-next-color: #FFF;
23
+$theme-multiple-page-control-border-color: #8C40E2;
24
+$theme-multiple-page-control-border-color-active: #FFF;
25
+$theme-multiple-page-control-background-color: rgba(#FFF, .3);
26
+$theme-multiple-page-control-background-color-active: #FFF;
27
+
28
+// 顶栏和侧边栏中展开的菜单 hover 状态下
29
+$theme-menu-item-color-hover: #293849;
30
+$theme-menu-item-background-color-hover: #ecf5ff;
31
+
32
+// 顶栏上的文字颜色
33
+$theme-header-item-color: #FFF;
34
+$theme-header-item-background-color: transparent;
35
+// 顶栏上的项目在 hover 时
36
+$theme-header-item-color-hover: #FFF;
37
+$theme-header-item-background-color-hover: linear-gradient(-180deg, rgba(255,255,255,0.18) 0%, rgba(255,255,255,0.12) 100%);
38
+// 顶栏上的项目在 focus 时
39
+$theme-header-item-color-focus: #FFF;
40
+$theme-header-item-background-color-focus: linear-gradient(-180deg, rgba(255,255,255,0.18) 0%, rgba(255,255,255,0.12) 100%);
41
+// 顶栏上的项目在 active 时
42
+$theme-header-item-color-active: #FFF;
43
+$theme-header-item-background-color-active: linear-gradient(-180deg, rgba(255,255,255,0.18) 0%, rgba(255,255,255,0.12) 100%);
44
+
45
+// 侧边栏上的文字颜色
46
+$theme-aside-item-color: #FFF;
47
+$theme-aside-item-background-color: transparent;
48
+// 侧边栏上的项目在 hover 时
49
+$theme-aside-item-color-hover: #FFF;
50
+$theme-aside-item-background-color-hover: linear-gradient(90deg, rgba(255,255,255,0.28) 0%, rgba(255,255,255,0.00) 100%);
51
+// 侧边栏上的项目在 focus 时
52
+$theme-aside-item-color-focus: #FFF;
53
+$theme-aside-item-background-color-focus: linear-gradient(90deg, rgba(255,255,255,0.28) 0%, rgba(255,255,255,0.00) 100%);
54
+// 侧边栏上的项目在 active 时
55
+$theme-aside-item-color-active: #FFF;
56
+$theme-aside-item-background-color-active: linear-gradient(90deg, rgba(255,255,255,0.28) 0%, rgba(255,255,255,0.00) 100%);
57
+
58
+// 侧边栏菜单为空的时候显示的元素
59
+$theme-aside-menu-empty-icon-color: #FFF;
60
+$theme-aside-menu-empty-text-color: #FFF;
61
+$theme-aside-menu-empty-background-color: rgba(#000, .1);
62
+$theme-aside-menu-empty-icon-color-hover: #FFF;
63
+$theme-aside-menu-empty-text-color-hover: #FFF;
64
+$theme-aside-menu-empty-background-color-hover: rgba(#000, .15);

+ 24 - 0
src/assets/style/unit/color.scss

@@ -0,0 +1,24 @@
1
+// 主色
2
+$color-primary: #409EFF;
3
+
4
+// 辅助色
5
+$color-info: #909399;
6
+$color-success: #67C23A;
7
+$color-warning: #E6A23C;
8
+$color-danger: #F56C6C;
9
+
10
+// 文字
11
+$color-text-main: #303133;
12
+// $color-text-normal: #606266;
13
+$color-text-normal: #fff;
14
+$color-text-sub: #909399;
15
+$color-text-placehoder: #C0C4CC;
16
+
17
+// 边框
18
+$color-border-1: #DCDFE6;
19
+$color-border-2: #E4E7ED;
20
+$color-border-3: #EBEEF5;
21
+$color-border-4: #F2F6FC;
22
+
23
+// 背景
24
+$color-bg: #f8f8f9;

File diff suppressed because it is too large
+ 19 - 0
src/assets/svg-icons/icons/d2-admin-text.svg


File diff suppressed because it is too large
+ 13 - 0
src/assets/svg-icons/icons/d2-admin.svg


+ 7 - 0
src/assets/svg-icons/index.js

@@ -0,0 +1,7 @@
1
+import Vue from 'vue'
2
+
3
+const requireAll = requireContext => requireContext.keys().map(requireContext)
4
+const req = require.context('./icons', false, /\.svg$/)
5
+const iconMap = requireAll(req)
6
+
7
+Vue.prototype.$IconSvg = iconMap.map(e => e.default.id.slice(3))

+ 27 - 0
src/components/d2-container/components/d2-container-card-bs.vue

@@ -0,0 +1,27 @@
1
+<template>
2
+  <div class="d2-container-card-bs">
3
+    <div v-if="$slots.header" class="d2-container-card-bs__header" ref="header">
4
+      <slot name="header"/>
5
+    </div>
6
+    <div class="d2-container-card-bs__body" ref="wrapper">
7
+      <div class="d2-container-card-bs__body-wrapper-inner">
8
+        <div class="d2-container-card-bs__body-card">
9
+          <slot/>
10
+        </div>
11
+      </div>
12
+    </div>
13
+    <div v-if="$slots.footer" class="d2-container-card-bs__footer" ref="footer">
14
+      <slot name="footer"/>
15
+    </div>
16
+  </div>
17
+</template>
18
+
19
+<script>
20
+import bs from './mixins/bs'
21
+export default {
22
+  name: 'd2-container-card-bs',
23
+  mixins: [
24
+    bs
25
+  ]
26
+}
27
+</script>

+ 33 - 0
src/components/d2-container/components/d2-container-card.vue

@@ -0,0 +1,33 @@
1
+<template>
2
+  <div class="d2-container-card">
3
+    <div v-if="$slots.header" class="d2-container-card__header" ref="header">
4
+      <slot name="header"/>
5
+    </div>
6
+    <div class="d2-container-card__body" ref="body">
7
+      <div class="d2-container-card__body-card">
8
+        <slot/>
9
+      </div>
10
+    </div>
11
+    <div v-if="$slots.footer" class="d2-container-card__footer" ref="footer">
12
+      <slot name="footer"/>
13
+    </div>
14
+  </div>
15
+</template>
16
+
17
+<script>
18
+import scroll from './mixins/normal'
19
+export default {
20
+  name: 'd2-container-card',
21
+  mixins: [
22
+    scroll
23
+  ],
24
+  mounted () {
25
+    // 增加滚动事件监听
26
+    this.addScrollListener()
27
+  },
28
+  beforeDestroy () {
29
+    // 移除滚动事件监听
30
+    this.removeScrollListener()
31
+  }
32
+}
33
+</script>

+ 25 - 0
src/components/d2-container/components/d2-container-full-bs.vue

@@ -0,0 +1,25 @@
1
+<template>
2
+  <div class="d2-container-full-bs">
3
+    <div v-if="$slots.header" class="d2-container-full-bs__header" ref="header">
4
+      <slot name="header"/>
5
+    </div>
6
+    <div class="d2-container-full-bs__body" ref="wrapper">
7
+      <div class="d2-container-full-bs__body-wrapper-inner">
8
+        <slot/>
9
+      </div>
10
+    </div>
11
+    <div v-if="$slots.footer" class="d2-container-full-bs__footer" ref="footer">
12
+      <slot name="footer"/>
13
+    </div>
14
+  </div>
15
+</template>
16
+
17
+<script>
18
+import bs from './mixins/bs'
19
+export default {
20
+  name: 'd2-container-card-bs',
21
+  mixins: [
22
+    bs
23
+  ]
24
+}
25
+</script>

+ 31 - 0
src/components/d2-container/components/d2-container-full.vue

@@ -0,0 +1,31 @@
1
+<template>
2
+  <div class="d2-container-full">
3
+    <div v-if="$slots.header" class="d2-container-full__header" ref="header">
4
+      <slot name="header"/>
5
+    </div>
6
+    <div class="d2-container-full__body" ref="body">
7
+      <slot/>
8
+    </div>
9
+    <div v-if="$slots.footer" class="d2-container-full__footer" ref="footer">
10
+      <slot name="footer"/>
11
+    </div>
12
+  </div>
13
+</template>
14
+
15
+<script>
16
+import scroll from './mixins/normal'
17
+export default {
18
+  name: 'd2-container-full',
19
+  mixins: [
20
+    scroll
21
+  ],
22
+  mounted () {
23
+    // 增加滚动事件监听
24
+    this.addScrollListener()
25
+  },
26
+  beforeDestroy () {
27
+    // 移除滚动事件监听
28
+    this.removeScrollListener()
29
+  }
30
+}
31
+</script>

+ 26 - 0
src/components/d2-container/components/d2-container-ghost-bs.vue

@@ -0,0 +1,26 @@
1
+<template>
2
+  <div class="d2-container-ghost-bs">
3
+    <div v-if="$slots.header" class="d2-container-ghost-bs__header" ref="header">
4
+      <slot name="header"/>
5
+    </div>
6
+    <div class="d2-container-ghost-bs__body" ref="wrapper">
7
+      <!-- https://github.com/d2-projects/d2-admin/issues/181 -->
8
+      <div>
9
+        <slot/>
10
+      </div>
11
+    </div>
12
+    <div v-if="$slots.footer" class="d2-container-ghost-bs__footer" ref="footer">
13
+      <slot name="footer"/>
14
+    </div>
15
+  </div>
16
+</template>
17
+
18
+<script>
19
+import bs from './mixins/bs'
20
+export default {
21
+  name: 'd2-container-card-bs',
22
+  mixins: [
23
+    bs
24
+  ]
25
+}
26
+</script>

+ 31 - 0
src/components/d2-container/components/d2-container-ghost.vue

@@ -0,0 +1,31 @@
1
+<template>
2
+  <div class="d2-container-ghost">
3
+    <div v-if="$slots.header" class="d2-container-ghost__header" ref="header">
4
+      <slot name="header"/>
5
+    </div>
6
+    <div class="d2-container-ghost__body" ref="body">
7
+      <slot/>
8
+    </div>
9
+    <div v-if="$slots.footer" class="d2-container-ghost__footer" ref="footer">
10
+      <slot name="footer"/>
11
+    </div>
12
+  </div>
13
+</template>
14
+
15
+<script>
16
+import scroll from './mixins/normal'
17
+export default {
18
+  name: 'd2-container-ghost',
19
+  mixins: [
20
+    scroll
21
+  ],
22
+  mounted () {
23
+    // 增加滚动事件监听
24
+    this.addScrollListener()
25
+  },
26
+  beforeDestroy () {
27
+    // 移除滚动事件监听
28
+    this.removeScrollListener()
29
+  }
30
+}
31
+</script>

+ 79 - 0
src/components/d2-container/components/d2-source.vue

@@ -0,0 +1,79 @@
1
+<template>
2
+  <div
3
+    v-if="show"
4
+    class="d2-source"
5
+    :class="{ 'd2-source--active': isActive }"
6
+    @click="handleClick">
7
+    <d2-icon name="code"/> 本页源码
8
+  </div>
9
+</template>
10
+
11
+<script>
12
+import { last, get } from 'lodash'
13
+export default {
14
+  data () {
15
+    return {
16
+      isActive: false,
17
+      path: ''
18
+    }
19
+  },
20
+  computed: {
21
+    show () {
22
+      return process.env.VUE_APP_SCOURCE_LINK === 'TRUE'
23
+    }
24
+  },
25
+  watch: {
26
+    $route: {
27
+      handler (to) {
28
+        this.path = get(last(to.matched), 'components.default.__source')
29
+      },
30
+      immediate: true
31
+    }
32
+  },
33
+  mounted () {
34
+    // 一秒后显示按钮
35
+    setTimeout(() => {
36
+      this.isActive = true
37
+    }, 500)
38
+  },
39
+  methods: {
40
+    // 点击按钮的时候跳转到源代码
41
+    handleClick () {
42
+      this.$open(`${process.env.VUE_APP_REPO}/blob/master/${this.path}`)
43
+    }
44
+  }
45
+}
46
+</script>
47
+
48
+<style lang="scss" scoped>
49
+.d2-source {
50
+  $borderRadius: 4px;
51
+  $paddingLR: 15px;
52
+  $paddingTB: 7px;
53
+  $fontSize: 12px;
54
+  $rightOuter: $paddingLR / 2;
55
+  opacity: 0;
56
+  position: fixed;
57
+  z-index: 9999;
58
+  right: - $borderRadius - $rightOuter;
59
+  bottom: 20px;
60
+  font-size: $fontSize;
61
+  line-height: $fontSize;
62
+  font-weight: bold;
63
+  border-radius: $borderRadius;
64
+  padding: $paddingTB $paddingLR;
65
+  padding-right: $borderRadius + $paddingLR;
66
+  background-color: rgba(#000, .7);
67
+  border: 1px solid #000;
68
+  color: #FFF;
69
+  transition: all .3s;
70
+  @extend %unable-select;
71
+  &.d2-source--active {
72
+    opacity: 1;
73
+  }
74
+  &:hover {
75
+    right: - $borderRadius;
76
+    background-color: rgba(#000, .9);
77
+  }
78
+}
79
+</style>

+ 62 - 0
src/components/d2-container/components/mixins/bs.js

@@ -0,0 +1,62 @@
1
+import BScroll from 'better-scroll'
2
+export default {
3
+  props: {
4
+    // 滚动优化的选项
5
+    betterScrollOptions: {
6
+      type: Object,
7
+      required: false,
8
+      default: () => ({})
9
+    }
10
+  },
11
+  data () {
12
+    return {
13
+      BS: null
14
+    }
15
+  },
16
+  mounted () {
17
+    this.scrollInit()
18
+  },
19
+  beforeDestroy () {
20
+    this.scrollDestroy()
21
+  },
22
+  methods: {
23
+    scrollInit () {
24
+      // 初始化 bs
25
+      this.BS = new BScroll(this.$refs.wrapper, Object.assign({
26
+        mouseWheel: true,
27
+        click: true,
28
+        scrollbar: {
29
+          fade: true,
30
+          interactive: false
31
+        }
32
+      }, this.betterScrollOptions))
33
+      // 滚动时发出事件 并且统一返回的数据格式
34
+      this.BS.on('scroll', ({ x, y }) => this.$emit('scroll', {
35
+        x: -x,
36
+        y: -y
37
+      }))
38
+    },
39
+    scrollDestroy () {
40
+      // https://github.com/d2-projects/d2-admin/issues/75
41
+      try {
42
+        this.BS.destroy()
43
+      } catch (e) {
44
+        delete this.BS
45
+        this.BS = null
46
+      }
47
+    },
48
+    // 外部调用的方法 返回顶部
49
+    scrollToTop () {
50
+      if (this.BS) this.BS.scrollTo(0, 0, 300)
51
+    },
52
+    // 手动发出滚动事件
53
+    scroll () {
54
+      if (this.BS) {
55
+        this.$emit('scroll', {
56
+          x: -this.BS.x,
57
+          y: -this.BS.y
58
+        })
59
+      }
60
+    }
61
+  }
62
+}

+ 67 - 0
src/components/d2-container/components/mixins/normal.js

@@ -0,0 +1,67 @@
1
+// 提供滚动方面的功能
2
+// 非滚动优化模式通用
3
+
4
+import { throttle } from 'lodash'
5
+
6
+// 生成滚动事件的 handler
7
+function handleMaker (wait) {
8
+  return throttle(e => {
9
+    this.$emit('scroll', {
10
+      x: e.target.scrollLeft,
11
+      y: e.target.scrollTop
12
+    })
13
+  }, wait)
14
+}
15
+
16
+export default {
17
+  props: {
18
+    // 滚动事件节流间隔
19
+    scrollDelay: {
20
+      type: Number,
21
+      required: false,
22
+      default: 10
23
+    }
24
+  },
25
+  data () {
26
+    return {
27
+      handleScroll: null
28
+    }
29
+  },
30
+  watch: {
31
+    scrollDelay (val) {
32
+      // 移除旧的监听
33
+      this.removeScrollListener()
34
+      // 生成新的 handle 方法
35
+      this.handleScroll = handleMaker.call(this, val)
36
+      // 添加新的监听
37
+      this.addScrollListener()
38
+    }
39
+  },
40
+  methods: {
41
+    // 增加滚动事件监听
42
+    addScrollListener () {
43
+      if (typeof this.handleScroll !== 'function') {
44
+        // mounted 生命周期内调用这个方法的时候会进入这里的判断
45
+        this.handleScroll = handleMaker.call(this, this.scrollDelay)
46
+      }
47
+      // 添加监听
48
+      this.$refs.body.addEventListener('scroll', this.handleScroll)
49
+    },
50
+    // 移除滚动事件监听
51
+    removeScrollListener () {
52
+      this.$refs.body.removeEventListener('scroll', this.handleScroll)
53
+    },
54
+    // 外部调用的方法 返回顶部
55
+    scrollToTop () {
56
+      const smoothscroll = () => {
57
+        const body = this.$refs.body
58
+        const currentScroll = body.scrollTop
59
+        if (currentScroll > 0) {
60
+          window.requestAnimationFrame(smoothscroll)
61
+          body.scrollTo(0, currentScroll - (currentScroll / 5))
62
+        }
63
+      }
64
+      smoothscroll()
65
+    }
66
+  }
67
+}

+ 106 - 0
src/components/d2-container/index.js

@@ -0,0 +1,106 @@
1
+// 组件
2
+import d2ContainerFull from './components/d2-container-full.vue'
3
+import d2ContainerFullBs from './components/d2-container-full-bs.vue'
4
+import d2ContainerGhost from './components/d2-container-ghost.vue'
5
+import d2ContainerGhostBs from './components/d2-container-ghost-bs.vue'
6
+import d2ContainerCard from './components/d2-container-card.vue'
7
+import d2ContainerCardBs from './components/d2-container-card-bs.vue'
8
+import d2Source from './components/d2-source.vue'
9
+
10
+export default {
11
+  name: 'd2-container',
12
+  props: {
13
+    // 容器样式
14
+    type: {
15
+      type: String,
16
+      required: false,
17
+      default: 'full'
18
+    },
19
+    // 滚动优化
20
+    betterScroll: {
21
+      type: Boolean,
22
+      required: false,
23
+      default: false
24
+    }
25
+  },
26
+  computed: {
27
+    // 始终返回渲染组件
28
+    component () {
29
+      if (this.type === 'card' && !this.betterScroll) return d2ContainerCard
30
+      if (this.type === 'card' && this.betterScroll) return d2ContainerCardBs
31
+      if (this.type === 'ghost' && !this.betterScroll) return d2ContainerGhost
32
+      if (this.type === 'ghost' && this.betterScroll) return d2ContainerGhostBs
33
+      if (this.type === 'full' && !this.betterScroll) return d2ContainerFull
34
+      if (this.type === 'full' && this.betterScroll) return d2ContainerFullBs
35
+      else {
36
+        return 'div'
37
+      }
38
+    }
39
+  },
40
+  render (h) {
41
+    const slots = [
42
+      this.$slots.default,
43
+      this.$slots.header ? <template slot="header">{ this.$slots.header }</template> : null,
44
+      this.$slots.footer ? <template slot="footer">{ this.$slots.footer }</template> : null
45
+    ]
46
+    return <div
47
+      ref="container"
48
+      class="container-component">
49
+      <this.component
50
+        ref="component"
51
+        { ...{ attrs: this.$attrs } }
52
+        onScroll={ e => this.$emit('scroll', e) }>
53
+        { slots }
54
+      </this.component>
55
+      <d2Source/>
56
+    </div>
57
+  },
58
+  methods: {
59
+    // 返回顶部
60
+    scrollToTop () {
61
+      this.$refs.component.scrollToTop()
62
+      // 如果开启了 better scroll 还需要手动触发一遍 scroll 事件
63
+      const bs = this.$refs.component.BS
64
+      if (bs) this.$refs.component.scroll()
65
+    },
66
+    // 用法同原生方法 scrollBy
67
+    scrollBy (x = 0, y = 0, time = 300) {
68
+      if (this.betterScroll) {
69
+        const bs = this.$refs.component.BS
70
+        if (bs) {
71
+          bs.scrollBy(-x, -y, time)
72
+          // 手动触发一遍 scroll 事件
73
+          this.$refs.component.scroll()
74
+        }
75
+      } else {
76
+        this.$refs.component.$refs.body.scrollBy(x, y)
77
+      }
78
+    },
79
+    // 用法同原生方法 scrollTo
80
+    scrollTo (x = 0, y = 0, time = 300) {
81
+      if (this.betterScroll) {
82
+        const bs = this.$refs.component.BS
83
+        if (bs) {
84
+          bs.scrollTo(-x, -y, time)
85
+          // 手动触发一遍 scroll 事件
86
+          this.$refs.component.scroll()
87
+        }
88
+      } else {
89
+        this.$refs.component.$refs.body.scrollTo(x, y)
90
+      }
91
+    },
92
+    // 用法同原生方法 scrollTop
93
+    scrollTop (top = 0, time = 300) {
94
+      if (this.betterScroll) {
95
+        const bs = this.$refs.component.BS
96
+        if (bs) {
97
+          bs.scrollTo(bs.x, -top, time)
98
+          // 手动触发一遍 scroll 事件
99
+          this.$refs.component.scroll()
100
+        }
101
+      } else {
102
+        this.$refs.component.$refs.body.scrollTop = top
103
+      }
104
+    }
105
+  }
106
+}

+ 22 - 0
src/components/d2-icon-svg/index.vue

@@ -0,0 +1,22 @@
1
+<template>
2
+  <svg aria-hidden="true">
3
+    <use :xlink:href="icon"></use>
4
+  </svg>
5
+</template>
6
+
7
+<script>
8
+export default {
9
+  name: 'd2-icon-svg',
10
+  props: {
11
+    name: {
12
+      type: String,
13
+      required: true
14
+    }
15
+  },
16
+  computed: {
17
+    icon () {
18
+      return `#d2-${this.name}`
19
+    }
20
+  }
21
+}
22
+</script>

File diff suppressed because it is too large
+ 4 - 0
src/components/d2-icon/font-awesome-4.7.0/css/font-awesome.min.css


BIN
src/components/d2-icon/font-awesome-4.7.0/fonts/FontAwesome.otf


BIN
src/components/d2-icon/font-awesome-4.7.0/fonts/fontawesome-webfont.eot


+ 0 - 0
src/components/d2-icon/font-awesome-4.7.0/fonts/fontawesome-webfont.svg


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