├── .browserslistrc ├── .gitignore ├── README.md ├── babel.config.js ├── dll ├── vendors.dll.js ├── vendors.manifest.json ├── vue.dll.js └── vue.manifest.json ├── package-lock.json ├── package.json ├── public ├── favicon.ico └── index.html ├── src ├── App.vue ├── assets │ ├── citydata.js │ ├── css │ │ └── global.css │ ├── fonts │ │ ├── demo.css │ │ ├── demo_index.html │ │ ├── iconfont.css │ │ ├── iconfont.eot │ │ ├── iconfont.js │ │ ├── iconfont.json │ │ ├── iconfont.svg │ │ ├── iconfont.ttf │ │ ├── iconfont.woff │ │ └── iconfont.woff2 │ ├── images │ │ ├── logo.png │ │ └── touxiang.jpg │ └── kuaidi.js ├── components │ ├── Home.vue │ ├── Login.vue │ ├── Welcome.vue │ ├── commons │ │ ├── CommonModal.vue │ │ ├── CommonTable.vue │ │ └── crumb.vue │ ├── goods │ │ ├── Add.vue │ │ ├── Cate.vue │ │ ├── List.vue │ │ └── Params.vue │ ├── order │ │ └── Order.vue │ ├── power │ │ ├── Rights.vue │ │ └── Roles.vue │ ├── report │ │ └── Report.vue │ └── user │ │ └── User.vue ├── main-dev.js ├── main-prod.js ├── plugins │ └── element.js ├── router │ └── index.js └── store │ └── index.js ├── vue.config.js └── webpack.dll.js /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not dead 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # Editor directories and files 17 | .idea 18 | .vscode 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw? 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 项目总结 2 | 3 | 整理不易,若对您有帮助,请给个star,您的支持是我更新的动力 👇 4 | 5 | [🚩在线体验地址1](http://118.31.171.210/#/welcome)体验账号:admin 密码:123456 已经默认设置啦,可以直接登录。 6 | 7 | [🚩在线体验地址2](http://8.136.180.108/#/login) 8 | 9 | 📖[开发全过程博客记录](https://blog.csdn.net/weixin_43786756/category_10716603.html) 10 | 11 | 🐱 [GitHub笔记](https://github.com/ruoruochen/front-end-note/tree/master/Vue%E7%94%B5%E5%95%86%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F%E9%A1%B9%E7%9B%AE) 12 | 13 | 14 | ### 项目使用指南: 15 | 16 | 1. 希望能给本项目一个`star`~,感谢。 17 | 2. 点击绿色按钮`Code`,DownLoad Zip并解压。 18 | 3. 在该项目下执行`npm install`安装依赖 19 | 4. 执行`npm run serve`打开本地服务 20 | 21 | ### 部署上线指南 22 | 各位看官老爷们,希望能给我的Github一个star~为了整理这个纯小白部署上线教程,我又重新购买了一个服务器,从头弄了一遍,看在这个份上可怜可怜小人把呜呜呜呜。 23 | 24 | 📖[【超详细小白教学】Vue+nodejs电商项目部署指南](https://blog.csdn.net/weixin_43786756/article/details/112982951) 25 | 26 | ## 项目概述 27 | 28 | ### 1.1 电商项目基本业务概述 29 | 30 | 根据不同的应用场景,电商系统一般都提供了 PC 端、移动 APP、移动 Web、微信小程序等多种终端访问方式,我们主要是实现PC后台管理系统。 31 | 32 | ![image-20210309122856022](http://ruoruochen-img-bed.oss-cn-beijing.aliyuncs.com/img/image-20210309122856022.png) 33 | 34 | ### 1.2 电商后台管理系统的功能 35 | 36 | 电商后台管理系统用于管理用户账号、商品分类、商品信息、订单、数据统计等业务功能。 37 | 38 | ![image-20210309122919582](http://ruoruochen-img-bed.oss-cn-beijing.aliyuncs.com/img/image-20210309122919582.png) 39 | 40 | ### 1.3 电商后台管理系统的开发模式(前后端分离) 41 | 42 | 电商后台管理系统整体采用前后端分离的开发模式,其中前端项目是**基于 Vue 技术栈的 SPA 项目。** 43 | ![image-20210309122931478](http://ruoruochen-img-bed.oss-cn-beijing.aliyuncs.com/img/image-20210309122931478.png) 44 | 45 | ## 电商后台管理系统的技术选型 46 | 47 | ### 前端用到的技术栈 48 | 49 | - Vue 50 | - Vue-router 51 | - Element-UI 52 | - Axios 53 | - Echarts 54 | 55 | ### 后端项目技术栈 56 | 57 | - Node.js 58 | - Express 59 | - Jwt 60 | - Mysql 61 | - Sequelize 62 | 63 | ## 项目效果: 64 | 65 | 贴上几张图,具体效果请在在线体验地址中体验哦~ 66 | 67 | ![image-20210120221628801](http://ruoruochen-img-bed.oss-cn-beijing.aliyuncs.com/img/image-20210120221628801.png) 68 | 69 | ![image-20210120221647333](http://ruoruochen-img-bed.oss-cn-beijing.aliyuncs.com/img/image-20210120221647333.png) 70 | 71 | ![image-20210120221706705](http://ruoruochen-img-bed.oss-cn-beijing.aliyuncs.com/img/image-20210120221706705.png) 72 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | // 项目发布阶段用到的babel插件 2 | // const prodPlugins = [] 3 | // if (process.env.NOME_ENV === 'production') { 4 | // prodPlugins.push("transform-remove-console") 5 | // } 6 | 7 | module.exports = { 8 | "presets": [ 9 | "@vue/cli-plugin-babel/preset" 10 | ], 11 | "plugins": [ 12 | [ 13 | "component", 14 | { 15 | "libraryName": "element-ui", 16 | "styleLibraryName": "theme-chalk" 17 | } 18 | ], 19 | //发布产品时候的插件数组 20 | // ...prodPlugins, 21 | "transform-remove-console", 22 | "@babel/plugin-syntax-dynamic-import" 23 | ] 24 | } -------------------------------------------------------------------------------- /dll/vue.manifest.json: -------------------------------------------------------------------------------- 1 | {"name":"vue","content":{"./node_modules/webpack/buildin/global.js":{"id":135,"buildMeta":{"providedExports":true}},"./node_modules/process/browser.js":{"id":221,"buildMeta":{"providedExports":true}},"./node_modules/vue/dist/vue.runtime.esm.js":{"id":583,"buildMeta":{"exportsType":"namespace","providedExports":["default"]}},"./node_modules/timers-browserify/main.js":{"id":584,"buildMeta":{"providedExports":true}},"./node_modules/setimmediate/setImmediate.js":{"id":585,"buildMeta":{"providedExports":true}},"./node_modules/vue-router/dist/vue-router.esm.js":{"id":586,"buildMeta":{"exportsType":"namespace","providedExports":["default"]}}}} -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-manage", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "build:dll": "webpack --config ./webpack.dll.js" 9 | }, 10 | "dependencies": { 11 | "add-asset-html-webpack-plugin": "^3.2.0", 12 | "axios": "^0.21.1", 13 | "babel-loader": "^8.2.2", 14 | "babel-plugin-transform-remove-console": "^6.9.4", 15 | "core-js": "^3.6.5", 16 | "echarts": "^5.0.0", 17 | "element-ui": "^2.4.5", 18 | "lodash": "^4.17.20", 19 | "nprogress": "^0.2.0", 20 | "speed-measure-webpack-plugin": "^1.5.0", 21 | "thread-loader": "^3.0.1", 22 | "uglifyjs-webpack-plugin": "^2.2.0", 23 | "vue": "^2.6.11", 24 | "vue-quill-editor": "^3.0.6", 25 | "vue-router": "^3.2.0", 26 | "vue-table-with-tree-grid": "^0.2.4", 27 | "vuex": "^3.4.0", 28 | "webpack-parallel-uglify-plugin": "^2.0.0" 29 | }, 30 | "devDependencies": { 31 | "@babel/plugin-syntax-dynamic-import": "^7.8.3", 32 | "@vue/cli-plugin-babel": "~4.5.0", 33 | "@vue/cli-plugin-router": "~4.5.0", 34 | "@vue/cli-plugin-vuex": "~4.5.0", 35 | "@vue/cli-service": "~4.5.0", 36 | "babel-plugin-component": "^1.1.1", 37 | "less": "^4.1.0", 38 | "less-loader": "^7.2.1", 39 | "vue-cli-plugin-element": "^1.0.1", 40 | "vue-template-compiler": "^2.6.11", 41 | "webpack-cli": "^4.6.0" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruoruochen/vue-manage/08bbfeb17e2145343aba30f303a67bcb779001d5/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | <%= htmlWebpackPlugin.options.isProd? '':'dev -' %>电商管理系统 10 | 11 | <% if(htmlWebpackPlugin.options.isProd) { %> 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | <% } %> 38 | 39 | 40 | 41 | 45 |
46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 15 | -------------------------------------------------------------------------------- /src/assets/css/global.css: -------------------------------------------------------------------------------- 1 | /* 100%高度 */ 2 | html,body,#app{ 3 | min-width: 1366px; 4 | height: 100%; 5 | margin: 0 ; 6 | padding: 0; 7 | } 8 | 9 | .el-breadcrumb{ 10 | margin-bottom: 15px; 11 | font-size: 12px; 12 | } 13 | 14 | .el-card{ 15 | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15) !important; 16 | } 17 | 18 | .el-table,.zk-table{ 19 | margin-top: 15px; 20 | font-size: 12px; 21 | } 22 | 23 | .el-pagination{ 24 | margin-top: 20px; 25 | } 26 | 27 | .el-steps{ 28 | margin: 15px auto; 29 | } 30 | 31 | .el-step__title{ 32 | font-size: 13px; 33 | } 34 | 35 | .el-tabs{ 36 | margin: 20px 0 ; 37 | } 38 | 39 | .ql-editor{ 40 | min-height: 300px; 41 | } -------------------------------------------------------------------------------- /src/assets/fonts/demo.css: -------------------------------------------------------------------------------- 1 | /* Logo 字体 */ 2 | @font-face { 3 | font-family: "iconfont logo"; 4 | src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834'); 5 | src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'), 6 | url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'), 7 | url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'), 8 | url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg'); 9 | } 10 | 11 | .logo { 12 | font-family: "iconfont logo"; 13 | font-size: 160px; 14 | font-style: normal; 15 | -webkit-font-smoothing: antialiased; 16 | -moz-osx-font-smoothing: grayscale; 17 | } 18 | 19 | /* tabs */ 20 | .nav-tabs { 21 | position: relative; 22 | } 23 | 24 | .nav-tabs .nav-more { 25 | position: absolute; 26 | right: 0; 27 | bottom: 0; 28 | height: 42px; 29 | line-height: 42px; 30 | color: #666; 31 | } 32 | 33 | #tabs { 34 | border-bottom: 1px solid #eee; 35 | } 36 | 37 | #tabs li { 38 | cursor: pointer; 39 | width: 100px; 40 | height: 40px; 41 | line-height: 40px; 42 | text-align: center; 43 | font-size: 16px; 44 | border-bottom: 2px solid transparent; 45 | position: relative; 46 | z-index: 1; 47 | margin-bottom: -1px; 48 | color: #666; 49 | } 50 | 51 | 52 | #tabs .active { 53 | border-bottom-color: #f00; 54 | color: #222; 55 | } 56 | 57 | .tab-container .content { 58 | display: none; 59 | } 60 | 61 | /* 页面布局 */ 62 | .main { 63 | padding: 30px 100px; 64 | width: 960px; 65 | margin: 0 auto; 66 | } 67 | 68 | .main .logo { 69 | color: #333; 70 | text-align: left; 71 | margin-bottom: 30px; 72 | line-height: 1; 73 | height: 110px; 74 | margin-top: -50px; 75 | overflow: hidden; 76 | *zoom: 1; 77 | } 78 | 79 | .main .logo a { 80 | font-size: 160px; 81 | color: #333; 82 | } 83 | 84 | .helps { 85 | margin-top: 40px; 86 | } 87 | 88 | .helps pre { 89 | padding: 20px; 90 | margin: 10px 0; 91 | border: solid 1px #e7e1cd; 92 | background-color: #fffdef; 93 | overflow: auto; 94 | } 95 | 96 | .icon_lists { 97 | width: 100% !important; 98 | overflow: hidden; 99 | *zoom: 1; 100 | } 101 | 102 | .icon_lists li { 103 | width: 100px; 104 | margin-bottom: 10px; 105 | margin-right: 20px; 106 | text-align: center; 107 | list-style: none !important; 108 | cursor: default; 109 | } 110 | 111 | .icon_lists li .code-name { 112 | line-height: 1.2; 113 | } 114 | 115 | .icon_lists .icon { 116 | display: block; 117 | height: 100px; 118 | line-height: 100px; 119 | font-size: 42px; 120 | margin: 10px auto; 121 | color: #333; 122 | -webkit-transition: font-size 0.25s linear, width 0.25s linear; 123 | -moz-transition: font-size 0.25s linear, width 0.25s linear; 124 | transition: font-size 0.25s linear, width 0.25s linear; 125 | } 126 | 127 | .icon_lists .icon:hover { 128 | font-size: 100px; 129 | } 130 | 131 | .icon_lists .svg-icon { 132 | /* 通过设置 font-size 来改变图标大小 */ 133 | width: 1em; 134 | /* 图标和文字相邻时,垂直对齐 */ 135 | vertical-align: -0.15em; 136 | /* 通过设置 color 来改变 SVG 的颜色/fill */ 137 | fill: currentColor; 138 | /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示 139 | normalize.css 中也包含这行 */ 140 | overflow: hidden; 141 | } 142 | 143 | .icon_lists li .name, 144 | .icon_lists li .code-name { 145 | color: #666; 146 | } 147 | 148 | /* markdown 样式 */ 149 | .markdown { 150 | color: #666; 151 | font-size: 14px; 152 | line-height: 1.8; 153 | } 154 | 155 | .highlight { 156 | line-height: 1.5; 157 | } 158 | 159 | .markdown img { 160 | vertical-align: middle; 161 | max-width: 100%; 162 | } 163 | 164 | .markdown h1 { 165 | color: #404040; 166 | font-weight: 500; 167 | line-height: 40px; 168 | margin-bottom: 24px; 169 | } 170 | 171 | .markdown h2, 172 | .markdown h3, 173 | .markdown h4, 174 | .markdown h5, 175 | .markdown h6 { 176 | color: #404040; 177 | margin: 1.6em 0 0.6em 0; 178 | font-weight: 500; 179 | clear: both; 180 | } 181 | 182 | .markdown h1 { 183 | font-size: 28px; 184 | } 185 | 186 | .markdown h2 { 187 | font-size: 22px; 188 | } 189 | 190 | .markdown h3 { 191 | font-size: 16px; 192 | } 193 | 194 | .markdown h4 { 195 | font-size: 14px; 196 | } 197 | 198 | .markdown h5 { 199 | font-size: 12px; 200 | } 201 | 202 | .markdown h6 { 203 | font-size: 12px; 204 | } 205 | 206 | .markdown hr { 207 | height: 1px; 208 | border: 0; 209 | background: #e9e9e9; 210 | margin: 16px 0; 211 | clear: both; 212 | } 213 | 214 | .markdown p { 215 | margin: 1em 0; 216 | } 217 | 218 | .markdown>p, 219 | .markdown>blockquote, 220 | .markdown>.highlight, 221 | .markdown>ol, 222 | .markdown>ul { 223 | width: 80%; 224 | } 225 | 226 | .markdown ul>li { 227 | list-style: circle; 228 | } 229 | 230 | .markdown>ul li, 231 | .markdown blockquote ul>li { 232 | margin-left: 20px; 233 | padding-left: 4px; 234 | } 235 | 236 | .markdown>ul li p, 237 | .markdown>ol li p { 238 | margin: 0.6em 0; 239 | } 240 | 241 | .markdown ol>li { 242 | list-style: decimal; 243 | } 244 | 245 | .markdown>ol li, 246 | .markdown blockquote ol>li { 247 | margin-left: 20px; 248 | padding-left: 4px; 249 | } 250 | 251 | .markdown code { 252 | margin: 0 3px; 253 | padding: 0 5px; 254 | background: #eee; 255 | border-radius: 3px; 256 | } 257 | 258 | .markdown strong, 259 | .markdown b { 260 | font-weight: 600; 261 | } 262 | 263 | .markdown>table { 264 | border-collapse: collapse; 265 | border-spacing: 0px; 266 | empty-cells: show; 267 | border: 1px solid #e9e9e9; 268 | width: 95%; 269 | margin-bottom: 24px; 270 | } 271 | 272 | .markdown>table th { 273 | white-space: nowrap; 274 | color: #333; 275 | font-weight: 600; 276 | } 277 | 278 | .markdown>table th, 279 | .markdown>table td { 280 | border: 1px solid #e9e9e9; 281 | padding: 8px 16px; 282 | text-align: left; 283 | } 284 | 285 | .markdown>table th { 286 | background: #F7F7F7; 287 | } 288 | 289 | .markdown blockquote { 290 | font-size: 90%; 291 | color: #999; 292 | border-left: 4px solid #e9e9e9; 293 | padding-left: 0.8em; 294 | margin: 1em 0; 295 | } 296 | 297 | .markdown blockquote p { 298 | margin: 0; 299 | } 300 | 301 | .markdown .anchor { 302 | opacity: 0; 303 | transition: opacity 0.3s ease; 304 | margin-left: 8px; 305 | } 306 | 307 | .markdown .waiting { 308 | color: #ccc; 309 | } 310 | 311 | .markdown h1:hover .anchor, 312 | .markdown h2:hover .anchor, 313 | .markdown h3:hover .anchor, 314 | .markdown h4:hover .anchor, 315 | .markdown h5:hover .anchor, 316 | .markdown h6:hover .anchor { 317 | opacity: 1; 318 | display: inline-block; 319 | } 320 | 321 | .markdown>br, 322 | .markdown>p>br { 323 | clear: both; 324 | } 325 | 326 | 327 | .hljs { 328 | display: block; 329 | background: white; 330 | padding: 0.5em; 331 | color: #333333; 332 | overflow-x: auto; 333 | } 334 | 335 | .hljs-comment, 336 | .hljs-meta { 337 | color: #969896; 338 | } 339 | 340 | .hljs-string, 341 | .hljs-variable, 342 | .hljs-template-variable, 343 | .hljs-strong, 344 | .hljs-emphasis, 345 | .hljs-quote { 346 | color: #df5000; 347 | } 348 | 349 | .hljs-keyword, 350 | .hljs-selector-tag, 351 | .hljs-type { 352 | color: #a71d5d; 353 | } 354 | 355 | .hljs-literal, 356 | .hljs-symbol, 357 | .hljs-bullet, 358 | .hljs-attribute { 359 | color: #0086b3; 360 | } 361 | 362 | .hljs-section, 363 | .hljs-name { 364 | color: #63a35c; 365 | } 366 | 367 | .hljs-tag { 368 | color: #333333; 369 | } 370 | 371 | .hljs-title, 372 | .hljs-attr, 373 | .hljs-selector-id, 374 | .hljs-selector-class, 375 | .hljs-selector-attr, 376 | .hljs-selector-pseudo { 377 | color: #795da3; 378 | } 379 | 380 | .hljs-addition { 381 | color: #55a532; 382 | background-color: #eaffea; 383 | } 384 | 385 | .hljs-deletion { 386 | color: #bd2c00; 387 | background-color: #ffecec; 388 | } 389 | 390 | .hljs-link { 391 | text-decoration: underline; 392 | } 393 | 394 | /* 代码高亮 */ 395 | /* PrismJS 1.15.0 396 | https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */ 397 | /** 398 | * prism.js default theme for JavaScript, CSS and HTML 399 | * Based on dabblet (http://dabblet.com) 400 | * @author Lea Verou 401 | */ 402 | code[class*="language-"], 403 | pre[class*="language-"] { 404 | color: black; 405 | background: none; 406 | text-shadow: 0 1px white; 407 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; 408 | text-align: left; 409 | white-space: pre; 410 | word-spacing: normal; 411 | word-break: normal; 412 | word-wrap: normal; 413 | line-height: 1.5; 414 | 415 | -moz-tab-size: 4; 416 | -o-tab-size: 4; 417 | tab-size: 4; 418 | 419 | -webkit-hyphens: none; 420 | -moz-hyphens: none; 421 | -ms-hyphens: none; 422 | hyphens: none; 423 | } 424 | 425 | pre[class*="language-"]::-moz-selection, 426 | pre[class*="language-"] ::-moz-selection, 427 | code[class*="language-"]::-moz-selection, 428 | code[class*="language-"] ::-moz-selection { 429 | text-shadow: none; 430 | background: #b3d4fc; 431 | } 432 | 433 | pre[class*="language-"]::selection, 434 | pre[class*="language-"] ::selection, 435 | code[class*="language-"]::selection, 436 | code[class*="language-"] ::selection { 437 | text-shadow: none; 438 | background: #b3d4fc; 439 | } 440 | 441 | @media print { 442 | 443 | code[class*="language-"], 444 | pre[class*="language-"] { 445 | text-shadow: none; 446 | } 447 | } 448 | 449 | /* Code blocks */ 450 | pre[class*="language-"] { 451 | padding: 1em; 452 | margin: .5em 0; 453 | overflow: auto; 454 | } 455 | 456 | :not(pre)>code[class*="language-"], 457 | pre[class*="language-"] { 458 | background: #f5f2f0; 459 | } 460 | 461 | /* Inline code */ 462 | :not(pre)>code[class*="language-"] { 463 | padding: .1em; 464 | border-radius: .3em; 465 | white-space: normal; 466 | } 467 | 468 | .token.comment, 469 | .token.prolog, 470 | .token.doctype, 471 | .token.cdata { 472 | color: slategray; 473 | } 474 | 475 | .token.punctuation { 476 | color: #999; 477 | } 478 | 479 | .namespace { 480 | opacity: .7; 481 | } 482 | 483 | .token.property, 484 | .token.tag, 485 | .token.boolean, 486 | .token.number, 487 | .token.constant, 488 | .token.symbol, 489 | .token.deleted { 490 | color: #905; 491 | } 492 | 493 | .token.selector, 494 | .token.attr-name, 495 | .token.string, 496 | .token.char, 497 | .token.builtin, 498 | .token.inserted { 499 | color: #690; 500 | } 501 | 502 | .token.operator, 503 | .token.entity, 504 | .token.url, 505 | .language-css .token.string, 506 | .style .token.string { 507 | color: #9a6e3a; 508 | background: hsla(0, 0%, 100%, .5); 509 | } 510 | 511 | .token.atrule, 512 | .token.attr-value, 513 | .token.keyword { 514 | color: #07a; 515 | } 516 | 517 | .token.function, 518 | .token.class-name { 519 | color: #DD4A68; 520 | } 521 | 522 | .token.regex, 523 | .token.important, 524 | .token.variable { 525 | color: #e90; 526 | } 527 | 528 | .token.important, 529 | .token.bold { 530 | font-weight: bold; 531 | } 532 | 533 | .token.italic { 534 | font-style: italic; 535 | } 536 | 537 | .token.entity { 538 | cursor: help; 539 | } 540 | -------------------------------------------------------------------------------- /src/assets/fonts/demo_index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IconFont Demo 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 |

19 | 27 |
28 |
29 |
    30 | 31 |
  • 32 | 33 |
    34 |
    &#xe644;
    35 |
  • 36 | 37 |
  • 38 | 39 |
    25单据
    40 |
    &#xe89b;
    41 |
  • 42 | 43 |
  • 44 | 45 |
    28体积、空间
    46 |
    &#xe89f;
    47 |
  • 48 | 49 |
  • 50 | 51 |
    225默认头像
    52 |
    &#xe8c9;
    53 |
  • 54 | 55 |
  • 56 | 57 |
    406报表
    58 |
    &#xe902;
    59 |
  • 60 | 61 |
  • 62 | 63 |
    商品创建
    64 |
    &#xe61e;
    65 |
  • 66 | 67 |
  • 68 | 69 |
    用户名
    70 |
    &#xe612;
    71 |
  • 72 | 73 |
  • 74 | 75 |
    lock-fill
    76 |
    &#xe75a;
    77 |
  • 78 | 79 |
  • 80 | 81 |
    密码
    82 |
    &#xe66c;
    83 |
  • 84 | 85 |
  • 86 | 87 |
    用户
    88 |
    &#xe646;
    89 |
  • 90 | 91 |
92 |
93 |

Unicode 引用

94 |
95 | 96 |

Unicode 是字体在网页端最原始的应用方式,特点是:

97 |
    98 |
  • 兼容性最好,支持 IE6+,及所有现代浏览器。
  • 99 |
  • 支持按字体的方式去动态调整图标大小,颜色等等。
  • 100 |
  • 但是因为是字体,所以不支持多色。只能使用平台里单色的图标,就算项目里有多色图标也会自动去色。
  • 101 |
102 |
103 |

注意:新版 iconfont 支持多色图标,这些多色图标在 Unicode 模式下将不能使用,如果有需求建议使用symbol 的引用方式

104 |
105 |

Unicode 使用步骤如下:

106 |

第一步:拷贝项目下面生成的 @font-face

107 |
@font-face {
109 |   font-family: 'iconfont';
110 |   src: url('iconfont.eot');
111 |   src: url('iconfont.eot?#iefix') format('embedded-opentype'),
112 |       url('iconfont.woff2') format('woff2'),
113 |       url('iconfont.woff') format('woff'),
114 |       url('iconfont.ttf') format('truetype'),
115 |       url('iconfont.svg#iconfont') format('svg');
116 | }
117 | 
118 |

第二步:定义使用 iconfont 的样式

119 |
.iconfont {
121 |   font-family: "iconfont" !important;
122 |   font-size: 16px;
123 |   font-style: normal;
124 |   -webkit-font-smoothing: antialiased;
125 |   -moz-osx-font-smoothing: grayscale;
126 | }
127 | 
128 |

第三步:挑选相应图标并获取字体编码,应用于页面

129 |
130 | <span class="iconfont">&#x33;</span>
132 | 
133 |
134 |

"iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。

135 |
136 |
137 |
138 |
139 |
    140 | 141 |
  • 142 | 143 |
    144 | 锁 145 |
    146 |
    .icon-suo 147 |
    148 |
  • 149 | 150 |
  • 151 | 152 |
    153 | 25单据 154 |
    155 |
    .icon-danju 156 |
    157 |
  • 158 | 159 |
  • 160 | 161 |
    162 | 28体积、空间 163 |
    164 |
    .icon-tijikongjian 165 |
    166 |
  • 167 | 168 |
  • 169 | 170 |
    171 | 225默认头像 172 |
    173 |
    .icon-morentouxiang 174 |
    175 |
  • 176 | 177 |
  • 178 | 179 |
    180 | 406报表 181 |
    182 |
    .icon-baobiao 183 |
    184 |
  • 185 | 186 |
  • 187 | 188 |
    189 | 商品创建 190 |
    191 |
    .icon-shangpinchuangjian 192 |
    193 |
  • 194 | 195 |
  • 196 | 197 |
    198 | 用户名 199 |
    200 |
    .icon-yonghuming 201 |
    202 |
  • 203 | 204 |
  • 205 | 206 |
    207 | lock-fill 208 |
    209 |
    .icon-lock-fill 210 |
    211 |
  • 212 | 213 |
  • 214 | 215 |
    216 | 密码 217 |
    218 |
    .icon-mima 219 |
    220 |
  • 221 | 222 |
  • 223 | 224 |
    225 | 用户 226 |
    227 |
    .icon-ziyuan 228 |
    229 |
  • 230 | 231 |
232 |
233 |

font-class 引用

234 |
235 | 236 |

font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。

237 |

与 Unicode 使用方式相比,具有如下特点:

238 |
    239 |
  • 兼容性良好,支持 IE8+,及所有现代浏览器。
  • 240 |
  • 相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。
  • 241 |
  • 因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。
  • 242 |
  • 不过因为本质上还是使用的字体,所以多色图标还是不支持的。
  • 243 |
244 |

使用步骤如下:

245 |

第一步:引入项目下面生成的 fontclass 代码:

246 |
<link rel="stylesheet" href="./iconfont.css">
247 | 
248 |

第二步:挑选相应图标并获取类名,应用于页面:

249 |
<span class="iconfont icon-xxx"></span>
250 | 
251 |
252 |

" 253 | iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。

254 |
255 |
256 |
257 |
258 |
    259 | 260 |
  • 261 | 264 |
    265 |
    #icon-suo
    266 |
  • 267 | 268 |
  • 269 | 272 |
    25单据
    273 |
    #icon-danju
    274 |
  • 275 | 276 |
  • 277 | 280 |
    28体积、空间
    281 |
    #icon-tijikongjian
    282 |
  • 283 | 284 |
  • 285 | 288 |
    225默认头像
    289 |
    #icon-morentouxiang
    290 |
  • 291 | 292 |
  • 293 | 296 |
    406报表
    297 |
    #icon-baobiao
    298 |
  • 299 | 300 |
  • 301 | 304 |
    商品创建
    305 |
    #icon-shangpinchuangjian
    306 |
  • 307 | 308 |
  • 309 | 312 |
    用户名
    313 |
    #icon-yonghuming
    314 |
  • 315 | 316 |
  • 317 | 320 |
    lock-fill
    321 |
    #icon-lock-fill
    322 |
  • 323 | 324 |
  • 325 | 328 |
    密码
    329 |
    #icon-mima
    330 |
  • 331 | 332 |
  • 333 | 336 |
    用户
    337 |
    #icon-ziyuan
    338 |
  • 339 | 340 |
341 |
342 |

Symbol 引用

343 |
344 | 345 |

这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇文章 346 | 这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:

347 |
    348 |
  • 支持多色图标了,不再受单色限制。
  • 349 |
  • 通过一些技巧,支持像字体那样,通过 font-size, color 来调整样式。
  • 350 |
  • 兼容性较差,支持 IE9+,及现代浏览器。
  • 351 |
  • 浏览器渲染 SVG 的性能一般,还不如 png。
  • 352 |
353 |

使用步骤如下:

354 |

第一步:引入项目下面生成的 symbol 代码:

355 |
<script src="./iconfont.js"></script>
356 | 
357 |

第二步:加入通用 CSS 代码(引入一次就行):

358 |
<style>
359 | .icon {
360 |   width: 1em;
361 |   height: 1em;
362 |   vertical-align: -0.15em;
363 |   fill: currentColor;
364 |   overflow: hidden;
365 | }
366 | </style>
367 | 
368 |

第三步:挑选相应图标并获取类名,应用于页面:

369 |
<svg class="icon" aria-hidden="true">
370 |   <use xlink:href="#icon-xxx"></use>
371 | </svg>
372 | 
373 |
374 |
375 | 376 |
377 |
378 | 397 | 398 | 399 | -------------------------------------------------------------------------------- /src/assets/fonts/iconfont.css: -------------------------------------------------------------------------------- 1 | @font-face {font-family: "iconfont"; 2 | src: url('iconfont.eot?t=1610097102754'); /* IE9 */ 3 | src: url('iconfont.eot?t=1610097102754#iefix') format('embedded-opentype'), /* IE6-IE8 */ 4 | url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'), 5 | url('iconfont.woff?t=1610097102754') format('woff'), 6 | url('iconfont.ttf?t=1610097102754') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ 7 | url('iconfont.svg?t=1610097102754#iconfont') format('svg'); /* iOS 4.1- */ 8 | } 9 | 10 | .iconfont { 11 | font-family: "iconfont" !important; 12 | font-size: 16px; 13 | font-style: normal; 14 | -webkit-font-smoothing: antialiased; 15 | -moz-osx-font-smoothing: grayscale; 16 | } 17 | 18 | .icon-suo:before { 19 | content: "\e644"; 20 | } 21 | 22 | .icon-danju:before { 23 | content: "\e89b"; 24 | } 25 | 26 | .icon-tijikongjian:before { 27 | content: "\e89f"; 28 | } 29 | 30 | .icon-morentouxiang:before { 31 | content: "\e8c9"; 32 | } 33 | 34 | .icon-baobiao:before { 35 | content: "\e902"; 36 | } 37 | 38 | .icon-shangpinchuangjian:before { 39 | content: "\e61e"; 40 | } 41 | 42 | .icon-yonghuming:before { 43 | content: "\e612"; 44 | } 45 | 46 | .icon-lock-fill:before { 47 | content: "\e75a"; 48 | } 49 | 50 | .icon-mima:before { 51 | content: "\e66c"; 52 | } 53 | 54 | .icon-ziyuan:before { 55 | content: "\e646"; 56 | } 57 | 58 | -------------------------------------------------------------------------------- /src/assets/fonts/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruoruochen/vue-manage/08bbfeb17e2145343aba30f303a67bcb779001d5/src/assets/fonts/iconfont.eot -------------------------------------------------------------------------------- /src/assets/fonts/iconfont.js: -------------------------------------------------------------------------------- 1 | !function(t){var e,c,o,n,i,a,h='',l=(l=document.getElementsByTagName("script"))[l.length-1].getAttribute("data-injectcss");if(l&&!t.__iconfont__svg__cssinject__){t.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(t){console&&console.log(t)}}function s(){i||(i=!0,o())}e=function(){var t,e,c,o;(o=document.createElement("div")).innerHTML=h,h=null,(c=o.getElementsByTagName("svg")[0])&&(c.setAttribute("aria-hidden","true"),c.style.position="absolute",c.style.width=0,c.style.height=0,c.style.overflow="hidden",t=c,(e=document.body).firstChild?(o=t,(c=e.firstChild).parentNode.insertBefore(o,c)):e.appendChild(t))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(e,0):(c=function(){document.removeEventListener("DOMContentLoaded",c,!1),e()},document.addEventListener("DOMContentLoaded",c,!1)):document.attachEvent&&(o=e,n=t.document,i=!1,(a=function(){try{n.documentElement.doScroll("left")}catch(t){return void setTimeout(a,50)}s()})(),n.onreadystatechange=function(){"complete"==n.readyState&&(n.onreadystatechange=null,s())})}(window); -------------------------------------------------------------------------------- /src/assets/fonts/iconfont.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "", 3 | "name": "", 4 | "font_family": "iconfont", 5 | "css_prefix_text": "icon-", 6 | "description": "", 7 | "glyphs": [ 8 | { 9 | "icon_id": "1621660", 10 | "name": "锁", 11 | "font_class": "suo", 12 | "unicode": "e644", 13 | "unicode_decimal": 58948 14 | }, 15 | { 16 | "icon_id": "1727362", 17 | "name": "25单据", 18 | "font_class": "danju", 19 | "unicode": "e89b", 20 | "unicode_decimal": 59547 21 | }, 22 | { 23 | "icon_id": "1727367", 24 | "name": "28体积、空间", 25 | "font_class": "tijikongjian", 26 | "unicode": "e89f", 27 | "unicode_decimal": 59551 28 | }, 29 | { 30 | "icon_id": "1727461", 31 | "name": "225默认头像", 32 | "font_class": "morentouxiang", 33 | "unicode": "e8c9", 34 | "unicode_decimal": 59593 35 | }, 36 | { 37 | "icon_id": "1727589", 38 | "name": "406报表", 39 | "font_class": "baobiao", 40 | "unicode": "e902", 41 | "unicode_decimal": 59650 42 | }, 43 | { 44 | "icon_id": "4948990", 45 | "name": "商品创建", 46 | "font_class": "shangpinchuangjian", 47 | "unicode": "e61e", 48 | "unicode_decimal": 58910 49 | }, 50 | { 51 | "icon_id": "7677917", 52 | "name": "用户名", 53 | "font_class": "yonghuming", 54 | "unicode": "e612", 55 | "unicode_decimal": 58898 56 | }, 57 | { 58 | "icon_id": "8555554", 59 | "name": "lock-fill", 60 | "font_class": "lock-fill", 61 | "unicode": "e75a", 62 | "unicode_decimal": 59226 63 | }, 64 | { 65 | "icon_id": "10605731", 66 | "name": "密码", 67 | "font_class": "mima", 68 | "unicode": "e66c", 69 | "unicode_decimal": 58988 70 | }, 71 | { 72 | "icon_id": "11177997", 73 | "name": "用户", 74 | "font_class": "ziyuan", 75 | "unicode": "e646", 76 | "unicode_decimal": 58950 77 | } 78 | ] 79 | } 80 | -------------------------------------------------------------------------------- /src/assets/fonts/iconfont.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | Created by iconfont 9 | 10 | 11 | 12 | 13 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /src/assets/fonts/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruoruochen/vue-manage/08bbfeb17e2145343aba30f303a67bcb779001d5/src/assets/fonts/iconfont.ttf -------------------------------------------------------------------------------- /src/assets/fonts/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruoruochen/vue-manage/08bbfeb17e2145343aba30f303a67bcb779001d5/src/assets/fonts/iconfont.woff -------------------------------------------------------------------------------- /src/assets/fonts/iconfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruoruochen/vue-manage/08bbfeb17e2145343aba30f303a67bcb779001d5/src/assets/fonts/iconfont.woff2 -------------------------------------------------------------------------------- /src/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruoruochen/vue-manage/08bbfeb17e2145343aba30f303a67bcb779001d5/src/assets/images/logo.png -------------------------------------------------------------------------------- /src/assets/images/touxiang.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruoruochen/vue-manage/08bbfeb17e2145343aba30f303a67bcb779001d5/src/assets/images/touxiang.jpg -------------------------------------------------------------------------------- /src/assets/kuaidi.js: -------------------------------------------------------------------------------- 1 | export default { 2 | "data": [ 3 | { 4 | "time": "2018-05-10 09:39:00", 5 | "ftime": "2018-05-10 09:39:00", 6 | "context": "已签收,感谢使用顺丰,期待再次为您服务", 7 | "location": "" 8 | }, 9 | { 10 | "time": "2018-05-10 08:23:00", 11 | "ftime": "2018-05-10 08:23:00", 12 | "context": "[北京市]北京海淀育新小区营业点派件员 顺丰速运 95338正在为您派件", 13 | "location": "" 14 | }, 15 | { 16 | "time": "2018-05-10 07:32:00", 17 | "ftime": "2018-05-10 07:32:00", 18 | "context": "快件到达 [北京海淀育新小区营业点]", 19 | "location": "" 20 | }, 21 | { 22 | "time": "2018-05-10 02:03:00", 23 | "ftime": "2018-05-10 02:03:00", 24 | "context": "快件在[北京顺义集散中心]已装车,准备发往 [北京海淀育新小区营业点]", 25 | "location": "" 26 | }, 27 | { 28 | "time": "2018-05-09 23:05:00", 29 | "ftime": "2018-05-09 23:05:00", 30 | "context": "快件到达 [北京顺义集散中心]", 31 | "location": "" 32 | }, 33 | { 34 | "time": "2018-05-09 21:21:00", 35 | "ftime": "2018-05-09 21:21:00", 36 | "context": "快件在[北京宝胜营业点]已装车,准备发往 [北京顺义集散中心]", 37 | "location": "" 38 | }, 39 | { 40 | "time": "2018-05-09 13:07:00", 41 | "ftime": "2018-05-09 13:07:00", 42 | "context": "顺丰速运 已收取快件", 43 | "location": "" 44 | }, 45 | { 46 | "time": "2018-05-09 12:25:03", 47 | "ftime": "2018-05-09 12:25:03", 48 | "context": "卖家发货", 49 | "location": "" 50 | }, 51 | { 52 | "time": "2018-05-09 12:22:24", 53 | "ftime": "2018-05-09 12:22:24", 54 | "context": "您的订单将由HLA(北京海淀区清河中街店)门店安排发货。", 55 | "location": "" 56 | }, 57 | { 58 | "time": "2018-05-08 21:36:04", 59 | "ftime": "2018-05-08 21:36:04", 60 | "context": "商品已经下单", 61 | "location": "" 62 | } 63 | ], 64 | "meta": { "status": 200, "message": "获取物流信息成功!" } 65 | } 66 | -------------------------------------------------------------------------------- /src/components/Home.vue: -------------------------------------------------------------------------------- 1 | 54 | 55 | 93 | 94 | -------------------------------------------------------------------------------- /src/components/Login.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 96 | 97 | -------------------------------------------------------------------------------- /src/components/Welcome.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | 11 | -------------------------------------------------------------------------------- /src/components/commons/CommonModal.vue: -------------------------------------------------------------------------------- 1 | 41 | 42 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /src/components/commons/CommonTable.vue: -------------------------------------------------------------------------------- 1 | 68 | 69 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /src/components/commons/crumb.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 27 | 28 | -------------------------------------------------------------------------------- /src/components/goods/Add.vue: -------------------------------------------------------------------------------- 1 | 94 | 95 | 280 | 281 | -------------------------------------------------------------------------------- /src/components/goods/Cate.vue: -------------------------------------------------------------------------------- 1 | 115 | 116 | 314 | 315 | -------------------------------------------------------------------------------- /src/components/goods/List.vue: -------------------------------------------------------------------------------- 1 | 70 | 71 | 241 | 242 | 247 | -------------------------------------------------------------------------------- /src/components/goods/Params.vue: -------------------------------------------------------------------------------- 1 | 168 | 169 | 396 | 397 | -------------------------------------------------------------------------------- /src/components/order/Order.vue: -------------------------------------------------------------------------------- 1 | 101 | 102 | 196 | 197 | -------------------------------------------------------------------------------- /src/components/power/Rights.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 45 | 46 | -------------------------------------------------------------------------------- /src/components/power/Roles.vue: -------------------------------------------------------------------------------- 1 | 146 | 147 | 361 | 362 | -------------------------------------------------------------------------------- /src/components/report/Report.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 60 | 61 | -------------------------------------------------------------------------------- /src/components/user/User.vue: -------------------------------------------------------------------------------- 1 | 91 | 92 | 371 | 372 | 383 | -------------------------------------------------------------------------------- /src/main-dev.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import router from './router' 4 | import store from './store' 5 | import './plugins/element.js' 6 | import './assets/fonts/iconfont.css' 7 | import axios from "axios" 8 | import TreeTable from "vue-table-with-tree-grid" 9 | import Crumb from "./components/commons/crumb" 10 | //导入富文本编辑器 11 | import VueQuillEditor from 'vue-quill-editor' 12 | 13 | import 'quill/dist/quill.core.css' // import styles 14 | import 'quill/dist/quill.snow.css' // for snow theme 15 | import 'quill/dist/quill.bubble.css' // for bubble theme 16 | 17 | // 导入包 18 | import NProgress from "nprogress" 19 | // 导入样式 20 | import 'nprogress/nprogress.css' 21 | 22 | 23 | 24 | Vue.prototype.$http = axios 25 | // 配置请求根路径 26 | axios.defaults.baseURL = "http://118.31.171.210:8801/api/private/v1/" 27 | 28 | // 在request拦截器中,展示进度条 NProgress.start() 29 | axios.interceptors.request.use(config => { 30 | // console.log(config); 31 | NProgress.start() 32 | config.headers.Authorization = window.sessionStorage.getItem('token'); 33 | return config 34 | }) 35 | 36 | // 在response拦截器中,隐藏进度条 .....done() 37 | axios.interceptors.response.use(config => { 38 | NProgress.done() 39 | return config 40 | }) 41 | 42 | Vue.component('tree-table', TreeTable); 43 | Vue.component('crumb', Crumb); 44 | // 将富文本编辑器注册成全局可用 45 | Vue.use(VueQuillEditor) 46 | 47 | Vue.filter('dateFormat', function (originVal) { 48 | const dt = new Date(originVal); 49 | 50 | const y = dt.getFullYear(); 51 | const m = (dt.getMonth() + 1 + '').padStart(2, '0'); 52 | const d = (dt.getDate() + '').padStart(2, '0'); 53 | 54 | const hh = (dt.getHours() + '').padStart(2, '0'); 55 | const mm = (dt.getMinutes() + '').padStart(2, '0'); 56 | const ss = (dt.getSeconds() + '').padStart(2, '0'); 57 | return `${y}-${m}-${d} ${hh}:${mm}:${ss}`; 58 | }) 59 | Vue.config.productionTip = false 60 | 61 | new Vue({ 62 | router, 63 | store, 64 | render: h => h(App) 65 | }).$mount('#app') 66 | 67 | Vue.config.devtools = true; 68 | // 引入公共样式 69 | require('./assets/css/global.css') -------------------------------------------------------------------------------- /src/main-prod.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import router from './router' 4 | import store from './store' 5 | import './assets/fonts/iconfont.css' 6 | import axios from "axios" 7 | import TreeTable from "vue-table-with-tree-grid" 8 | //导入富文本编辑器 9 | import VueQuillEditor from 'vue-quill-editor' 10 | 11 | // import 'quill/dist/quill.core.css' // import styles 12 | // import 'quill/dist/quill.snow.css' // for snow theme 13 | // import 'quill/dist/quill.bubble.css' // for bubble theme 14 | 15 | // 导入包 16 | import NProgress from "nprogress" 17 | // 导入样式 18 | // import 'nprogress/nprogress.css' 19 | 20 | 21 | 22 | Vue.prototype.$http = axios 23 | // 配置请求根路径 24 | axios.defaults.baseURL = "http://118.31.171.210:8801/api/private/v1/" 25 | 26 | // 在request拦截器中,展示进度条 NProgress.start() 27 | axios.interceptors.request.use(config => { 28 | // console.log(config); 29 | NProgress.start() 30 | config.headers.Authorization = window.sessionStorage.getItem('token'); 31 | return config 32 | }) 33 | 34 | // 在response拦截器中,隐藏进度条 .....done() 35 | axios.interceptors.response.use(config => { 36 | NProgress.done() 37 | return config 38 | }) 39 | 40 | Vue.component('tree-table', TreeTable); 41 | // 将富文本编辑器注册成全局可用 42 | Vue.use(VueQuillEditor) 43 | 44 | Vue.filter('dateFormat', function (originVal) { 45 | const dt = new Date(originVal); 46 | 47 | const y = dt.getFullYear(); 48 | const m = (dt.getMonth() + 1 + '').padStart(2, '0'); 49 | const d = (dt.getDate() + '').padStart(2, '0'); 50 | 51 | const hh = (dt.getHours() + '').padStart(2, '0'); 52 | const mm = (dt.getMinutes() + '').padStart(2, '0'); 53 | const ss = (dt.getSeconds() + '').padStart(2, '0'); 54 | return `${y}-${m}-${d} ${hh}:${mm}:${ss}`; 55 | }) 56 | Vue.config.productionTip = false 57 | 58 | new Vue({ 59 | router, 60 | store, 61 | render: h => h(App) 62 | }).$mount('#app') 63 | 64 | // 引入公共样式 65 | require('./assets/css/global.css') -------------------------------------------------------------------------------- /src/plugins/element.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import { Button, Form, FormItem, Input, Message, Container, Header, Aside, Main, Menu, Submenu, MenuItemGroup, MenuItem, Breadcrumb, BreadcrumbItem, Card, Row, Col, Table, TableColumn, Switch, Tooltip, Pagination, Dialog, MessageBox, Tag, Tree, Select, Option, Cascader, Alert, Tabs, TabPane, Steps, Step, Checkbox, CheckboxGroup, Upload, Timeline, TimelineItem } from 'element-ui' 3 | Vue.use(Button) 4 | Vue.use(Form) 5 | Vue.use(FormItem) 6 | Vue.use(Input) 7 | Vue.use(Container) 8 | Vue.use(Header) 9 | Vue.use(Aside) 10 | Vue.use(Main) 11 | Vue.use(Menu) 12 | Vue.use(Submenu) 13 | Vue.use(MenuItemGroup) 14 | Vue.use(MenuItem) 15 | Vue.use(Breadcrumb) 16 | Vue.use(BreadcrumbItem) 17 | Vue.use(Card) 18 | Vue.use(Row) 19 | Vue.use(Col) 20 | Vue.use(Table) 21 | Vue.use(TableColumn) 22 | Vue.use(Switch) 23 | Vue.use(Tooltip) 24 | Vue.use(Pagination) 25 | Vue.use(Dialog) 26 | Vue.use(Tag) 27 | Vue.use(Tree) 28 | Vue.use(Select) 29 | Vue.use(Option) 30 | Vue.use(Cascader) 31 | Vue.use(Alert) 32 | Vue.use(Tabs) 33 | Vue.use(TabPane) 34 | Vue.use(Steps) 35 | Vue.use(Step) 36 | Vue.use(Checkbox) 37 | Vue.use(CheckboxGroup) 38 | Vue.use(Upload) 39 | Vue.use(Timeline) 40 | Vue.use(TimelineItem) 41 | Vue.prototype.$message = Message 42 | Vue.prototype.$confirm = MessageBox.confirm -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueRouter from 'vue-router' 3 | 4 | const Login = () => import(/* webpackChunkName: "login_home_welcome" */ '../components/Login') 5 | const Home = () => import(/* webpackChunkName: "login_home_welcome" */ '../components/Home') 6 | const Welcome = () => import(/* webpackChunkName: "login_home_welcome" */ '../components/Welcome') 7 | 8 | const User = () => import(/* webpackChunkName: "user_rights_roles" */ '../components/user/User') 9 | const Rights = () => import(/* webpackChunkName: "user_rights_roles" */ '../components/power/Rights') 10 | const Roles = () => import(/* webpackChunkName: "user_rights_roles" */ '../components/power/Roles') 11 | 12 | const Cate = () => import(/* webpackChunkName: "cate_params" */ '../components/goods/Cate') 13 | const Params = () => import(/* webpackChunkName: "cate_params" */ '../components/goods/Params') 14 | 15 | const GoodsList = () => import(/* webpackChunkName: "goodslist_addgoods" */ '../components/goods/List') 16 | const AddGoods = () => import(/* webpackChunkName: "goodslist_addgoods" */ '../components/goods/Add') 17 | 18 | const Order = () => import(/* webpackChunkName: "order_report" */ '../components/order/Order') 19 | const Report = () => import(/* webpackChunkName: "order_report" */ '../components/report/Report') 20 | 21 | Vue.use(VueRouter) 22 | 23 | const routes = [ 24 | { 25 | path: '', 26 | redirect: '/login' 27 | 28 | }, 29 | { 30 | path: '/login', 31 | component: Login 32 | }, 33 | { 34 | path: '/home', 35 | component: Home, 36 | children: [ 37 | { path: "", redirect: '/welcome' }, 38 | { path: "/welcome", component: Welcome }, 39 | { path: "/users", component: User }, 40 | { path: "/rights", component: Rights }, 41 | { path: "/roles", component: Roles }, 42 | { path: "/categories", component: Cate }, 43 | { path: "/params", component: Params }, 44 | { path: "/goods", component: GoodsList }, 45 | { path: "/goods/add", component: AddGoods }, 46 | { path: "/orders", component: Order }, 47 | { path: "/reports", component: Report } 48 | ] 49 | } 50 | ] 51 | 52 | const router = new VueRouter({ 53 | routes 54 | }) 55 | 56 | router.beforeEach((to, form, next) => { 57 | if (to.path === '/login') return next(); 58 | const token = window.sessionStorage.getItem('token'); 59 | if (!token) return next('/login'); 60 | next(); 61 | }) 62 | export default router 63 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | 4 | Vue.use(Vuex) 5 | 6 | export default new Vuex.Store({ 7 | state: { 8 | }, 9 | mutations: { 10 | }, 11 | actions: { 12 | }, 13 | modules: { 14 | } 15 | }) 16 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const fs = require('fs'); 3 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); 4 | const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin'); 5 | const webpack = require('webpack'); 6 | function resolve(dir) { 7 | return path.join(__dirname, dir); 8 | } 9 | const plugins = [ 10 | new UglifyJsPlugin({ 11 | uglifyOptions: { 12 | warnings: false, 13 | parse: {}, 14 | compress: {}, 15 | ie8: false 16 | }, 17 | parallel: true 18 | }) 19 | ] 20 | //预编译模块 21 | const files = fs.readdirSync(path.resolve(__dirname, './dll')); 22 | files.forEach(file => { 23 | if (/.*\.dll.js/.test(file)) { 24 | plugins.push(new AddAssetHtmlWebpackPlugin({ 25 | filepath: path.resolve(__dirname, './dll', file) 26 | })) 27 | } 28 | if (/.*\.manifest.json/.test(file)) { 29 | plugins.push(new webpack.DllReferencePlugin({ 30 | manifest: path.resolve(__dirname, './dll', file) 31 | })) 32 | } 33 | }) 34 | 35 | module.exports = { 36 | chainWebpack: (config) => { 37 | config.resolve.alias 38 | .set('@', resolve('src')) 39 | .set('@assets', resolve('src/assets')) 40 | //发布模式 41 | config.when(process.env.NODE_ENV === 'production', config => { 42 | config.entry('app').clear().add('./src/main-prod.js') 43 | 44 | config.set('externals', { 45 | vue: 'Vue', 'vue-router': 'VueRouter', 46 | axios: 'axios', 47 | lodash: '_', 48 | echarts: 'echarts', 49 | nprogress: 'NProgress', 'vue-quill-editor': 'VueQuillEditor' 50 | }) 51 | 52 | config.plugin('html').tap(args => { 53 | args[0].isProd = true; 54 | return args 55 | }) 56 | 57 | config.module.rule('thread').test('/\.js$/,').use('thread-loader').loader('thread-loader').end(); 58 | config.module.rule('babel').test('/\.js$/').use('babel-loader').loader('babel-loader').options({ 59 | cacheDirectory: true 60 | }).end(); 61 | }) 62 | 63 | config.when(process.env.NODE_ENV === 'development', config => { 64 | config.entry('app').clear().add('./src/main-dev.js') 65 | 66 | config.plugin('html').tap(args => { 67 | args[0].isProd = false; 68 | return args 69 | }) 70 | }) 71 | }, 72 | configureWebpack: { 73 | plugins 74 | } 75 | } 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /webpack.dll.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | 4 | module.exports = { 5 | mode: 'production', 6 | entry: { 7 | vendors: ['axios', 'lodash', 'echarts', 'NProgress', 'vue-quill-editor'], 8 | vue: ['vue', 'vue-router'] 9 | }, 10 | output: { 11 | filename: '[name].dll.js', 12 | path: path.resolve(__dirname, './dll'), 13 | library: '[name]' 14 | }, 15 | plugins: [ 16 | new webpack.DllPlugin({ 17 | name: '[name]', 18 | path: path.resolve(__dirname, './dll/[name].manifest.json') 19 | }) 20 | ] 21 | } --------------------------------------------------------------------------------