diff --git a/.gitignore b/.gitignore index 15681b3..c0d40f2 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,6 @@ yshop.tar.gz /routers/commentsRouter___________________Users_zhangxianwei_GolandProjects_beego-vue-admin_controllers.go /routers/commentsRouter___________________Users_zhangxianwei_GolandProjects_bee-vue-demo_controllers.go /desc/ -/web/node_modules/ \ No newline at end of file +/web/node_modules/ +go.sum +lastupdate.tmp \ No newline at end of file diff --git a/web/.editorconfig b/web/.editorconfig new file mode 100644 index 0000000..271822f --- /dev/null +++ b/web/.editorconfig @@ -0,0 +1,13 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +insert_final_newline = false +trim_trailing_whitespace = false diff --git a/web/.env.development b/web/.env.development new file mode 100644 index 0000000..d232d24 --- /dev/null +++ b/web/.env.development @@ -0,0 +1,9 @@ +ENV = 'development' + +# 接口地址 +VUE_APP_BASE_API = 'http://localhost:8080' +VUE_APP_WS_API = 'ws://localhost:8001' + + +# 是否启用 babel-plugin-dynamic-import-node插件 +VUE_CLI_BABEL_TRANSPILE_MODULES = true diff --git a/web/.env.production b/web/.env.production new file mode 100644 index 0000000..e0d775f --- /dev/null +++ b/web/.env.production @@ -0,0 +1,6 @@ +ENV = 'production' + +# 接口地址 +VUE_APP_BASE_API = 'https://goapi.yixiang.co' +VUE_APP_WS_API = 'ws:///127.0.0.1:8001' + diff --git a/web/.eslintignore b/web/.eslintignore new file mode 100644 index 0000000..a1bbc96 --- /dev/null +++ b/web/.eslintignore @@ -0,0 +1,8 @@ +build/*.js +src/assets +public +dist +src/views + + + diff --git a/web/.eslintrc.js b/web/.eslintrc.js new file mode 100644 index 0000000..0c290b7 --- /dev/null +++ b/web/.eslintrc.js @@ -0,0 +1,197 @@ +module.exports = { + root: true, + parserOptions: { + parser: 'babel-eslint', + sourceType: 'module' + }, + env: { + browser: true, + node: true, + es6: true, + }, + extends: ['plugin:vue/recommended', 'eslint:recommended'], + + + rules: { + "vue/max-attributes-per-line": [2, { + "singleline": 10, + "multiline": { + "max": 1, + "allowFirstLine": false + } + }], + "vue/singleline-html-element-content-newline": "off", + "vue/multiline-html-element-content-newline":"off", + "vue/name-property-casing": ["error", "PascalCase"], + "vue/no-v-html": "off", + 'accessor-pairs': 2, + 'arrow-spacing': [2, { + 'before': true, + 'after': true + }], + 'block-spacing': [2, 'always'], + 'brace-style': [2, '1tbs', { + 'allowSingleLine': true + }], + 'camelcase': [0, { + 'properties': 'always' + }], + 'comma-dangle': [2, 'never'], + 'comma-spacing': [2, { + 'before': false, + 'after': true + }], + 'comma-style': [2, 'last'], + 'constructor-super': 2, + 'curly': [2, 'multi-line'], + 'dot-location': [2, 'property'], + 'eol-last': 2, + 'eqeqeq': ["error", "always", {"null": "ignore"}], + 'generator-star-spacing': [2, { + 'before': true, + 'after': true + }], + 'handle-callback-err': [2, '^(err|error)$'], + 'indent': [2, 2, { + 'SwitchCase': 1 + }], + 'jsx-quotes': [2, 'prefer-single'], + 'key-spacing': [2, { + 'beforeColon': false, + 'afterColon': true + }], + 'keyword-spacing': [2, { + 'before': true, + 'after': true + }], + 'new-cap': [2, { + 'newIsCap': true, + 'capIsNew': false + }], + 'new-parens': 2, + 'no-array-constructor': 2, + 'no-caller': 2, + 'no-console': 'off', + 'no-class-assign': 2, + 'no-cond-assign': 2, + 'no-const-assign': 2, + 'no-control-regex': 0, + 'no-delete-var': 2, + 'no-dupe-args': 2, + 'no-dupe-class-members': 2, + 'no-dupe-keys': 2, + 'no-duplicate-case': 2, + 'no-empty-character-class': 2, + 'no-empty-pattern': 2, + 'no-eval': 2, + 'no-ex-assign': 2, + 'no-extend-native': 2, + 'no-extra-bind': 2, + 'no-extra-boolean-cast': 2, + 'no-extra-parens': [2, 'functions'], + 'no-fallthrough': 2, + 'no-floating-decimal': 2, + 'no-func-assign': 2, + 'no-implied-eval': 2, + 'no-inner-declarations': [2, 'functions'], + 'no-invalid-regexp': 2, + 'no-irregular-whitespace': 2, + 'no-iterator': 2, + 'no-label-var': 2, + 'no-labels': [2, { + 'allowLoop': false, + 'allowSwitch': false + }], + 'no-lone-blocks': 2, + 'no-mixed-spaces-and-tabs': 2, + 'no-multi-spaces': 2, + 'no-multi-str': 2, + 'no-multiple-empty-lines': [2, { + 'max': 1 + }], + 'no-native-reassign': 2, + 'no-negated-in-lhs': 2, + 'no-new-object': 2, + 'no-new-require': 2, + 'no-new-symbol': 2, + 'no-new-wrappers': 2, + 'no-obj-calls': 2, + 'no-octal': 2, + 'no-octal-escape': 2, + 'no-path-concat': 2, + 'no-proto': 2, + 'no-redeclare': 2, + 'no-regex-spaces': 2, + 'no-return-assign': [2, 'except-parens'], + 'no-self-assign': 2, + 'no-self-compare': 2, + 'no-sequences': 2, + 'no-shadow-restricted-names': 2, + 'no-spaced-func': 2, + 'no-sparse-arrays': 2, + 'no-this-before-super': 2, + 'no-throw-literal': 2, + 'no-trailing-spaces': 2, + 'no-undef': 2, + 'no-undef-init': 2, + 'no-unexpected-multiline': 2, + 'no-unmodified-loop-condition': 2, + 'no-unneeded-ternary': [2, { + 'defaultAssignment': false + }], + 'no-unreachable': 2, + 'no-unsafe-finally': 2, + 'no-unused-vars': [2, { + 'vars': 'all', + 'args': 'none' + }], + 'no-useless-call': 2, + 'no-useless-computed-key': 2, + 'no-useless-constructor': 2, + 'no-useless-escape': 0, + 'no-whitespace-before-property': 2, + 'no-with': 2, + 'one-var': [2, { + 'initialized': 'never' + }], + 'operator-linebreak': [2, 'after', { + 'overrides': { + '?': 'before', + ':': 'before' + } + }], + 'padded-blocks': [2, 'never'], + 'quotes': [2, 'single', { + 'avoidEscape': true, + 'allowTemplateLiterals': true + }], + 'semi': [2, 'never'], + 'semi-spacing': [2, { + 'before': false, + 'after': true + }], + 'space-before-blocks': [2, 'always'], + 'space-before-function-paren': [2, 'never'], + 'space-in-parens': [2, 'never'], + 'space-infix-ops': 2, + 'space-unary-ops': [2, { + 'words': true, + 'nonwords': false + }], + 'spaced-comment': [2, 'always', { + 'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ','] + }], + 'template-curly-spacing': [2, 'never'], + 'use-isnan': 2, + 'valid-typeof': 2, + 'wrap-iife': [2, 'any'], + 'yield-star-spacing': [2, 'both'], + 'yoda': [2, 'never'], + 'prefer-const': 2, + 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, + 'object-curly-spacing': [2, 'always', { + objectsInObjects: false + }], + 'array-bracket-spacing': [2, 'never'] + } +} diff --git a/web/.gitignore b/web/.gitignore new file mode 100644 index 0000000..38801a4 --- /dev/null +++ b/web/.gitignore @@ -0,0 +1,24 @@ +.DS_Store +node_modules/ +dist/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +**/*.log + +tests/**/coverage/ +tests/e2e/reports +selenium-debug.log + +# directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.local + + +package-lock.json +yarn.lock diff --git a/web/.travis.yml b/web/.travis.yml new file mode 100644 index 0000000..8c37787 --- /dev/null +++ b/web/.travis.yml @@ -0,0 +1,7 @@ +language: node_js +node_js: 10 +script: npm run test +notifications: + email: false + + diff --git a/web/LICENSE b/web/LICENSE new file mode 100644 index 0000000..471dcc8 --- /dev/null +++ b/web/LICENSE @@ -0,0 +1,191 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "{}" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same "printed page" as the copyright notice for easier identification within +third-party archives. + + Copyright 2021 hu peng + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/web/README.md b/web/README.md new file mode 100644 index 0000000..affeb02 --- /dev/null +++ b/web/README.md @@ -0,0 +1,66 @@ +

beego-vue-admin 后台管理系统

+ + +#### 项目简介 +beego-vue-admin基于当前流行技术组合的前后端RBAC管理系统:Go1.15.x+Beego2.x+Jwt+Redis+Mysql8+Vue +的前后端分离系统,权限控制采用 RBAC,支持数据字典与数据权限管理,支持动态路由等 + +**体验地址:** [https://go.yixiang.co](https://go.yixiang.co) + +**账号密码:** `admin / 123456` + +#### 项目源码 + +| | 后端源码 | 前端源码 | +|--- |--- | --- | +| 码云 | https://gitee.com/guchengwuyue/beego-vue-admin | https://gitee.com/guchengwuyue/beego-vue-admin-web | +| github | https://github.com/guchengwuyue/beego-vue-admin | https://github.com/guchengwuyue/beego-vue-admin-web | + + +#### 系统功能 +- 用户管理:提供用户的相关配置 +- 角色管理:对权限与菜单进行分配,可根据部门设置角色的数据权限 +- 菜单管理:已实现菜单动态路由,后端可配置化 +- 部门管理:可配置系统组织架构,树形表格展示 +- 岗位管理:配置各个部门的职位 +- 字典管理:可维护常用一些固定的数据,如:状态,性别等 + + +#### 详细结构 + +``` +- common 公共模块 + - constant.go 常量 +- conf 公共配置 +- controllers 控制器模块 + - admin 管理后台 + - app app模块 + - base.go 公共控制器 +- dto dto模块 +- jwt jwt模块 +- logs 日志存放 +- models 公共模型 +- redis redis模块 + - pool.go 连接池 + - redis.go 常用操作 +- routers 路由 +- static 上传图片资源目录 +- swagger swagger +- tests tests +- untils 工具模块 +- vo vo模块 +``` +#### 前端启动与部署 +``` +1、npm install 安装所需依赖 +2、修改.env.development 里api配置 +3、npm run dev 启动即可 +4、线上部署: npm run build 打包然后上传服务器 +5、配置nginx 即可 +``` +#### 特别鸣谢 + +- beego:https://github.com/beego/beego/ +- vue:https://github.com/vuejs/vue +- element:https://github.com/ElemeFE/element + diff --git a/web/babel.config.js b/web/babel.config.js new file mode 100644 index 0000000..1e8b2ce --- /dev/null +++ b/web/babel.config.js @@ -0,0 +1,11 @@ +const plugins = ['@vue/babel-plugin-transform-vue-jsx'] +// 生产环境移除 +if (process.env.NODE_ENV === 'production') { + plugins.push('transform-remove-console') +} +module.exports = { + plugins: plugins, + presets: [ + '@vue/app' + ] +} diff --git a/web/jest.config.js b/web/jest.config.js new file mode 100644 index 0000000..0412da8 --- /dev/null +++ b/web/jest.config.js @@ -0,0 +1,23 @@ +module.exports = { + moduleFileExtensions: ['js', 'jsx', 'json', 'vue'], + transform: { + '^.+\\.vue$': 'vue-jest', + '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': + 'jest-transform-stub', + '^.+\\.jsx?$': 'babel-jest' + }, + moduleNameMapper: { + '^@/(.*)$': '/src/$1' + }, + snapshotSerializers: ['jest-serializer-vue'], + testMatch: [ + '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)' + ], + collectCoverageFrom: ['src/utils/**/*.{js,vue}', '!src/utils/auth.js', '!src/utils/request.js', 'src/components/**/*.{js,vue}'], + coverageDirectory: '/tests/unit/coverage', + 'coverageReporters': [ + 'lcov', + 'text-summary' + ], + testURL: 'http://localhost/' +} diff --git a/web/package.json b/web/package.json new file mode 100644 index 0000000..a7b6b66 --- /dev/null +++ b/web/package.json @@ -0,0 +1,109 @@ +{ + "name": "VIVIB", + "version": "1.0.0", + "description": "VIVIB 前端", + "author": "viviman", + "license": "Apache-2.0", + "scripts": { + "dev": "vue-cli-service serve", + "build": "vue-cli-service build", + "build:stage": "vue-cli-service build --mode staging", + "preview": "node build/index.js --preview", + "lint": "eslint --fix --ext .js,.vue src", + "test:unit": "jest --clearCache && vue-cli-service test:unit", + "svgo": "svgo -f src/assets/icons/svg --config=src/assets/icons/svgo.yml", + "new": "plop" + }, + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "src/**/*.{js,vue}": [ + "eslint --fix", + "git add" + ] + }, + "dependencies": { + "@riophae/vue-treeselect": "0.1.0", + "axios": "0.18.1", + "clipboard": "2.0.4", + "codemirror": "^5.49.2", + "connect": "3.6.6", + "echarts": "4.2.1", + "echarts-gl": "^1.1.1", + "echarts-wordcloud": "^1.1.3", + "element-ui": "^2.12.0", + "file-saver": "1.3.8", + "fuse.js": "3.4.4", + "js-cookie": "2.2.0", + "jsencrypt": "^3.0.0-rc.1", + "jszip": "3.1.5", + "mavon-editor": "^2.7.0", + "normalize.css": "7.0.0", + "nprogress": "0.2.0", + "path-to-regexp": "2.4.0", + "qs": "^6.9.1", + "screenfull": "4.2.0", + "vue": "2.6.10", + "vue-count-to": "1.0.13", + "vue-cropper": "0.4.9", + "vue-highlightjs": "^1.3.3", + "vue-router": "3.0.2", + "vue-splitpane": "1.0.4", + "vuex": "3.1.0", + "wangeditor": ">=3.0.0", + "xlsx": "^0.11.16", + "js-beautify": "^1.10.2", + "sortablejs": "1.8.4", + "vuedraggable": "2.20.0", + "vue-ueditor-wrap": "^2.4.1" + }, + "devDependencies": { + "@babel/core": "7.0.0", + "@babel/parser": "^7.7.4", + "@babel/register": "7.0.0", + "@vue/cli-plugin-babel": "3.5.3", + "@vue/cli-plugin-eslint": "^3.9.1", + "@vue/cli-plugin-unit-jest": "3.5.3", + "@vue/cli-service": "3.5.3", + "@vue/test-utils": "1.0.0-beta.29", + "autoprefixer": "^9.5.1", + "babel-core": "7.0.0-bridge.0", + "babel-eslint": "10.0.1", + "babel-jest": "23.6.0", + "babel-plugin-dynamic-import-node": "2.3.0", + "babel-plugin-transform-remove-console": "^6.9.4", + "chalk": "2.4.2", + "chokidar": "2.1.5", + "connect": "3.6.6", + "eslint": "5.15.3", + "eslint-plugin-vue": "5.2.2", + "html-webpack-plugin": "3.2.0", + "http-proxy-middleware": "^0.19.1", + "husky": "1.3.1", + "lint-staged": "8.1.5", + "node-sass": "^4.9.0", + "plop": "2.3.0", + "runjs": "^4.3.2", + "sass-loader": "^7.1.0", + "script-ext-html-webpack-plugin": "2.1.3", + "script-loader": "0.7.2", + "serve-static": "^1.13.2", + "stylus": "^0.54.7", + "stylus-loader": "^3.0.2", + "svg-sprite-loader": "4.1.3", + "svgo": "1.2.0", + "vue-jsonp": "^2.0.0", + "vue-template-compiler": "2.6.10" + }, + "engines": { + "node": ">=8.9", + "npm": ">= 3.0.0" + }, + "browserslist": [ + "> 1%", + "last 2 versions" + ] +} diff --git a/web/plopfile.js b/web/plopfile.js new file mode 100644 index 0000000..26eda24 --- /dev/null +++ b/web/plopfile.js @@ -0,0 +1,8 @@ +const viewGenerator = require('./plop-templates/view/prompt') +const componentGenerator = require('./plop-templates/component/prompt') + +module.exports = function(plop) { + plop.setGenerator('view', viewGenerator) + plop.setGenerator('component', componentGenerator) +} + diff --git a/web/postcss.config.js b/web/postcss.config.js new file mode 100644 index 0000000..c4f8e98 --- /dev/null +++ b/web/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + autoprefixer: {} + } +} + diff --git a/web/vue.config.js b/web/vue.config.js new file mode 100644 index 0000000..f7cb31f --- /dev/null +++ b/web/vue.config.js @@ -0,0 +1,130 @@ +'use strict' +const path = require('path') +const defaultSettings = require('./src/settings.js') + +function resolve(dir) { + return path.join(__dirname, dir) +} + +const name = defaultSettings.title // 网址标题 +const port = 8013 // 端口配置 + +module.exports = { + publicPath: '/', + outputDir: 'dist', + assetsDir: 'static', + lintOnSave: false, + productionSourceMap: false, + devServer: { + port: port, + open: true, + overlay: { + warnings: false, + errors: true + }, + proxy: { + '/admin': { + target: process.env.VUE_APP_BASE_API, + changeOrigin: true, + pathRewrite: { + '^/admin': 'admin' + } + }, + '/auth': { + target: process.env.VUE_APP_BASE_API, + changeOrigin: true, + pathRewrite: { + '^/auth': 'auth' + } + } + } + }, + configureWebpack: { + // provide the app's title in webpack's name field, so that + // it can be accessed in index.html to inject the correct title. + name: name, + resolve: { + alias: { + '@': resolve('src'), + '@crud': resolve('src/components/Crud') + } + } + }, + chainWebpack(config) { + config.plugins.delete('preload') // TODO: need test + config.plugins.delete('prefetch') // TODO: need test + + // set svg-sprite-loader + config.module + .rule('svg') + .exclude.add(resolve('src/assets/icons')) + .end() + config.module + .rule('icons') + .test(/\.svg$/) + .include.add(resolve('src/assets/icons')) + .end() + .use('svg-sprite-loader') + .loader('svg-sprite-loader') + .options({ + symbolId: 'icon-[name]' + }) + .end() + + // set preserveWhitespace + config.module + .rule('vue') + .use('vue-loader') + .loader('vue-loader') + .tap(options => { + options.compilerOptions.preserveWhitespace = true + return options + }) + .end() + + config + // https://webpack.js.org/configuration/devtool/#development + .when(process.env.NODE_ENV === 'development', + config => config.devtool('cheap-source-map') + ) + + config + .when(process.env.NODE_ENV !== 'development', + config => { + config + .plugin('ScriptExtHtmlWebpackPlugin') + .after('html') + .use('script-ext-html-webpack-plugin', [{ + // `runtime` must same as runtimeChunk name. default is `runtime` + inline: /runtime\..*\.js$/ + }]) + .end() + config + .optimization.splitChunks({ + chunks: 'all', + cacheGroups: { + libs: { + name: 'chunk-libs', + test: /[\\/]node_modules[\\/]/, + priority: 10, + chunks: 'initial' // only package third parties that are initially dependent + }, + elementUI: { + name: 'chunk-elementUI', // split elementUI into a single package + priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app + test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm + }, + commons: { + name: 'chunk-commons', + test: resolve('src/components'), // can customize your rules + minChunks: 3, // minimum common number + priority: 5, + reuseExistingChunk: true + } + } + }) + config.optimization.runtimeChunk('single') + } + ) + } +}