@ -0,0 +1,17 @@
|
||||
{ |
||||
"presets": [ |
||||
["env", { |
||||
"modules": false, |
||||
"targets": { |
||||
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"] |
||||
} |
||||
}], |
||||
"stage-2" |
||||
], |
||||
"plugins":["transform-vue-jsx", "transform-runtime"], |
||||
"env": { |
||||
"development":{ |
||||
"plugins": ["dynamic-import-node"] |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,14 @@
|
||||
# http://editorconfig.org |
||||
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 |
@ -0,0 +1,196 @@
|
||||
module.exports = { |
||||
root: true, |
||||
parserOptions: { |
||||
parser: 'babel-eslint', |
||||
sourceType: 'module' |
||||
}, |
||||
env: { |
||||
browser: true, |
||||
node: true, |
||||
es6: true, |
||||
}, |
||||
extends: ['plugin:vue/recommended', 'eslint:recommended'], |
||||
|
||||
// add your custom rules here
|
||||
//it is base on https://github.com/vuejs/eslint-config-vue
|
||||
rules: { |
||||
"vue/max-attributes-per-line": [2, { |
||||
"singleline": 10, |
||||
"multiline": { |
||||
"max": 1, |
||||
"allowFirstLine": false |
||||
} |
||||
}], |
||||
"vue/name-property-casing": ["error", "PascalCase"], |
||||
'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': [2, 'allow-null'], |
||||
'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': 2, |
||||
'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'] |
||||
} |
||||
} |
||||
|
@ -0,0 +1,16 @@
|
||||
.DS_Store |
||||
node_modules/ |
||||
dist/ |
||||
npm-debug.log* |
||||
yarn-debug.log* |
||||
yarn-error.log* |
||||
package-lock.json |
||||
yarn.lock |
||||
|
||||
# Editor directories and files |
||||
.idea |
||||
.vscode |
||||
*.suo |
||||
*.ntvs* |
||||
*.njsproj |
||||
*.sln |
@ -0,0 +1,10 @@
|
||||
// https://github.com/michael-ciniawsky/postcss-load-config
|
||||
|
||||
module.exports = { |
||||
"plugins": { |
||||
"postcss-import": {}, |
||||
"postcss-url": {}, |
||||
// to edit target browsers: use "browserslist" field in package.json
|
||||
"autoprefixer": {} |
||||
} |
||||
} |
@ -0,0 +1,5 @@
|
||||
language: node_js |
||||
node_js: stable |
||||
script: npm run test |
||||
notifications: |
||||
email: false |
@ -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 2018 Elune |
||||
|
||||
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. |
@ -0,0 +1,145 @@
|
||||
<h1 style="text-align: center">yshop意象商城系统</h1> |
||||
|
||||
|
||||
#### 项目简介 |
||||
yshop基于当前流行技术组合: SpringBoot2+Jpa+MybatisPlus+SpringSecurity+jwt+redis+Vue的前后端分离的商城系统, 包含商城、拼团、砍价、 |
||||
秒杀、优惠券、积分、分销等功能,更适合企业或个人二次开发; |
||||
|
||||
**开发文档** 【[查看文档](https://gitee.com/guchengwuyue/yshopmall/wikis/%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83?sort_id=1718722)】 |
||||
|
||||
#### 体验地址 |
||||
|
||||
| | 后台系统 | 前端(公众号) | |
||||
|--- |--- | --- | |
||||
| | https://yshop.dayouqiantu.cn |g公众号:YshopMall | |
||||
| | 后台体验账号/密码:admin/123456 | 公众号:![输入图片说明](https://images.gitee.com/uploads/images/2019/1116/060936_fd73496c_477893.jpeg "qrcode_for_gh_95df5a2881cc_258.jpg") | |
||||
|
||||
|
||||
#### 项目源码 |
||||
|
||||
| | 后台系统源码 | 后台系统前端源码 | |
||||
|--- |--- | --- | |
||||
| 码云 | https://gitee.com/guchengwuyue/yshopmall | https://gitee.com/guchengwuyue/yshopmall_qd | |
||||
| github | https://github.com/guchengwuyue/yshopmall |https://github.com/guchengwuyue/yshopmall_qd | |
||||
|
||||
#### 开源版本与VIP版本说明 |
||||
|
||||
|
||||
### 开源版 |
||||
1.包括整个商城系统后台、数据库、api(只是简单的配置好模块); |
||||
|
||||
2.本版本本身属于独立后台商城管理系统、可独立作为cms、商城等等后台使用; |
||||
|
||||
3.可以个人、企业直接使用。 |
||||
|
||||
### VIP版 |
||||
1.包括整个商城系统后台、数据库、API、H5; |
||||
|
||||
2.本版本是演示的所有功能代码; |
||||
|
||||
3.加入VIP、享有后续所有功能免费升级及其技术支持等。 |
||||
|
||||
4、VIP为终身,【[详情请查看](https://gitee.com/guchengwuyue/yshopmall/wikis/pages?sort_id=1715823&doc_id=441578)】 |
||||
|
||||
|
||||
## 商城功能 |
||||
|
||||
* 一:商品模块:商品添加、规格设置,商品上下架等 |
||||
* 二:订单模块:下单、购物车、支付,发货、收货、评价、退款等 |
||||
* 三:营销模块:积分、优惠券、分销、砍价、拼团、秒杀(、到店核销等 |
||||
* 四:微信模块:自定义菜单、自动回复、微信授权、图文管理、模板消息推送 |
||||
* 五:配置模块:各种配置 |
||||
* 六:用户模块:登陆、注册、会员卡等 |
||||
* 七:其他等 |
||||
|
||||
|
||||
#### 已经完成功能 |
||||
- 可以具体查看演示地址查看当前版本已经完成的功能,不再絮叨啦 |
||||
|
||||
|
||||
|
||||
#### 项目结构 |
||||
项目采用分模块开发方式 |
||||
- yshop-api 公众号(H5)API模块 |
||||
- yshop-mp 微信相关模块 |
||||
- yshop-common 公共模块 |
||||
- yshop-system 商城系统模块 |
||||
- yshop-logging 日志模块 |
||||
- yshop-tools 第三方工具模块 |
||||
- yshop-generator 代码生成模块 |
||||
|
||||
#### 系统预览 |
||||
<table> |
||||
<tr> |
||||
<td><img src="https://images.gitee.com/uploads/images/2019/1107/194017_9207632f_477893.png"/></td> |
||||
<td><img src="https://images.gitee.com/uploads/images/2019/1107/194030_70f5ce92_477893.png"/></td> |
||||
</tr> |
||||
<tr> |
||||
<td><img src="https://images.gitee.com/uploads/images/2019/1107/194114_cd0b06ce_477893.png"/></td> |
||||
<td><img src="https://images.gitee.com/uploads/images/2019/1107/194130_abb4f788_477893.png"/></td> |
||||
</tr> |
||||
<tr> |
||||
<td><img src="https://images.gitee.com/uploads/images/2019/1107/194147_63de73f4_477893.png"/></td> |
||||
<td><img src="https://images.gitee.com/uploads/images/2019/1107/194207_7b3b1f53_477893.png"/></td> |
||||
</tr> |
||||
<tr> |
||||
<td><img src="https://images.gitee.com/uploads/images/2019/1107/194217_3f47214f_477893.png"/></td> |
||||
<td></td> |
||||
</tr> |
||||
</table> |
||||
<table> |
||||
<tr> |
||||
<td><img src="https://images.gitee.com/uploads/images/2019/1107/201443_df1cc3a6_477893.png"/></td> |
||||
<td><img src="https://images.gitee.com/uploads/images/2019/1107/201540_ef6123a9_477893.png"/></td> |
||||
</tr> |
||||
<tr> |
||||
<td><img src="https://images.gitee.com/uploads/images/2019/1107/201601_acd0ccd3_477893.png"/></td> |
||||
<td><img src="https://images.gitee.com/uploads/images/2019/1107/201622_f913b59c_477893.png"/></td> |
||||
</tr> |
||||
<tr> |
||||
<td><img src="https://images.gitee.com/uploads/images/2019/1107/201646_5bc6df48_477893.png"/></td> |
||||
<td><img src="https://images.gitee.com/uploads/images/2019/1107/201706_32ee305c_477893.png"/></td> |
||||
</tr> |
||||
</table> |
||||
|
||||
## 技术选型 |
||||
* 1 后端使用技术 |
||||
* 1.1 SpringBoot |
||||
* 1.2 mybatis、MyBatis-Plus |
||||
* 1.3 SpringSecurity |
||||
* 1.4 JAP |
||||
* 1.5 Druid1 |
||||
* 1.6 Slf4j |
||||
* 1.7 Fastjson |
||||
* 1.8 JWT |
||||
* 1.9 Redis |
||||
* 1.10 Quartz |
||||
* 1.11 Mysql |
||||
* 1.12 swagger |
||||
* 1.13 WxJava |
||||
* 1.14 Lombok |
||||
* 1.15 Hutool |
||||
* 1.16 Mapstruct |
||||
|
||||
* 前端使用技术 |
||||
* 2.1 Vue 全家桶 |
||||
* 2.2 Element |
||||
|
||||
|
||||
#### 项目发布明细 |
||||
1.0版本 |
||||
1.1版本新增积分与优惠券抵扣 |
||||
1.2版本分销功能已经发布 |
||||
1.2.1增加了未付款订单取消功能库存销量退出、优惠券、积分功能,个人中心增加了积分流水 |
||||
|
||||
#### 反馈交流 |
||||
- QQ交流群:907721261 |
||||
- 喜欢这个商城后台的小伙伴留下你的小星星啦,star,star哦! |
||||
|
||||
#### 特别鸣谢 |
||||
- eladmin:https://github.com/elunez/eladmin |
||||
- mybaitsplus:https://github.com/baomidou/mybatis-plus |
||||
- hutool:https://github.com/looly/hutool |
||||
- wxjava:https://github.com/Wechat-Group/WxJava |
||||
- vue:https://github.com/vuejs/vue |
||||
- element:https://github.com/ElemeFE/element |
@ -0,0 +1,67 @@
|
||||
'use strict' |
||||
require('./check-versions')() |
||||
|
||||
const ora = require('ora') |
||||
const rm = require('rimraf') |
||||
const path = require('path') |
||||
const chalk = require('chalk') |
||||
const webpack = require('webpack') |
||||
const config = require('../config') |
||||
const webpackConfig = require('./webpack.prod.conf') |
||||
var connect = require('connect') |
||||
var serveStatic = require('serve-static') |
||||
|
||||
const spinner = ora( |
||||
'building for ' + process.env.env_config + ' environment...' |
||||
) |
||||
spinner.start() |
||||
|
||||
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { |
||||
if (err) throw err |
||||
webpack(webpackConfig, (err, stats) => { |
||||
spinner.stop() |
||||
if (err) throw err |
||||
process.stdout.write( |
||||
stats.toString({ |
||||
colors: true, |
||||
modules: false, |
||||
children: false, |
||||
chunks: false, |
||||
chunkModules: false |
||||
}) + '\n\n' |
||||
) |
||||
|
||||
if (stats.hasErrors()) { |
||||
console.log(chalk.red(' Build failed with errors.\n')) |
||||
process.exit(1) |
||||
} |
||||
|
||||
console.log(chalk.cyan(' Build complete.\n')) |
||||
console.log( |
||||
chalk.yellow( |
||||
' Tip: built files are meant to be served over an HTTP server.\n' + |
||||
" Opening index.html over file:// won't work.\n" |
||||
) |
||||
) |
||||
|
||||
if (process.env.npm_config_preview) { |
||||
const port = 9526 |
||||
const host = 'http://localhost:' + port |
||||
const basePath = config.build.assetsPublicPath |
||||
const app = connect() |
||||
|
||||
app.use( |
||||
basePath, |
||||
serveStatic('./dist', { |
||||
index: ['index.html', '/'] |
||||
}) |
||||
) |
||||
|
||||
app.listen(port, function() { |
||||
console.log( |
||||
chalk.green(`> Listening at http://localhost:${port}${basePath}`) |
||||
) |
||||
}) |
||||
} |
||||
}) |
||||
}) |
@ -0,0 +1,62 @@
|
||||
'use strict' |
||||
const chalk = require('chalk') |
||||
const semver = require('semver') |
||||
const packageConfig = require('../package.json') |
||||
const shell = require('shelljs') |
||||
|
||||
function exec(cmd) { |
||||
return require('child_process') |
||||
.execSync(cmd) |
||||
.toString() |
||||
.trim() |
||||
} |
||||
|
||||
const versionRequirements = [ |
||||
{ |
||||
name: 'node', |
||||
currentVersion: semver.clean(process.version), |
||||
versionRequirement: packageConfig.engines.node |
||||
} |
||||
] |
||||
|
||||
if (shell.which('npm')) { |
||||
versionRequirements.push({ |
||||
name: 'npm', |
||||
currentVersion: exec('npm --version'), |
||||
versionRequirement: packageConfig.engines.npm |
||||
}) |
||||
} |
||||
|
||||
module.exports = function() { |
||||
const warnings = [] |
||||
|
||||
for (let i = 0; i < versionRequirements.length; i++) { |
||||
const mod = versionRequirements[i] |
||||
|
||||
if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { |
||||
warnings.push( |
||||
mod.name + |
||||
': ' + |
||||
chalk.red(mod.currentVersion) + |
||||
' should be ' + |
||||
chalk.green(mod.versionRequirement) |
||||
) |
||||
} |
||||
} |
||||
|
||||
if (warnings.length) { |
||||
console.log('') |
||||
console.log( |
||||
chalk.yellow( |
||||
'To use this template, you must update following to modules:' |
||||
) |
||||
) |
||||
|
||||
for (let i = 0; i < warnings.length; i++) { |
||||
const warning = warnings[i] |
||||
console.log(' ' + warning) |
||||
} |
||||
|
||||
process.exit(1) |
||||
} |
||||
} |
@ -0,0 +1,108 @@
|
||||
'use strict' |
||||
const path = require('path') |
||||
const config = require('../config') |
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin') |
||||
const packageConfig = require('../package.json') |
||||
|
||||
exports.assetsPath = function(_path) { |
||||
const assetsSubDirectory = |
||||
process.env.NODE_ENV === 'production' |
||||
? config.build.assetsSubDirectory |
||||
: config.dev.assetsSubDirectory |
||||
|
||||
return path.posix.join(assetsSubDirectory, _path) |
||||
} |
||||
|
||||
exports.cssLoaders = function(options) { |
||||
options = options || {} |
||||
|
||||
const cssLoader = { |
||||
loader: 'css-loader', |
||||
options: { |
||||
sourceMap: options.sourceMap |
||||
} |
||||
} |
||||
|
||||
const postcssLoader = { |
||||
loader: 'postcss-loader', |
||||
options: { |
||||
sourceMap: options.sourceMap |
||||
} |
||||
} |
||||
|
||||
// generate loader string to be used with extract text plugin
|
||||
function generateLoaders(loader, loaderOptions) { |
||||
const loaders = [] |
||||
|
||||
// Extract CSS when that option is specified
|
||||
// (which is the case during production build)
|
||||
if (options.extract) { |
||||
loaders.push(MiniCssExtractPlugin.loader) |
||||
} else { |
||||
loaders.push('vue-style-loader') |
||||
} |
||||
|
||||
loaders.push(cssLoader) |
||||
|
||||
if (options.usePostCSS) { |
||||
loaders.push(postcssLoader) |
||||
} |
||||
|
||||
if (loader) { |
||||
loaders.push({ |
||||
loader: loader + '-loader', |
||||
options: Object.assign({}, loaderOptions, { |
||||
sourceMap: options.sourceMap |
||||
}) |
||||
}) |
||||
} |
||||
|
||||
return loaders |
||||
} |
||||
// https://vue-loader.vuejs.org/en/configurations/extract-css.html
|
||||
return { |
||||
css: generateLoaders(), |
||||
postcss: generateLoaders(), |
||||
less: generateLoaders('less'), |
||||
sass: generateLoaders('sass', { |
||||
indentedSyntax: true |
||||
}), |
||||
scss: generateLoaders('sass'), |
||||
stylus: generateLoaders('stylus'), |
||||
styl: generateLoaders('stylus') |
||||
} |
||||
} |
||||
|
||||
// Generate loaders for standalone style files (outside of .vue)
|
||||
exports.styleLoaders = function(options) { |
||||
const output = [] |
||||
const loaders = exports.cssLoaders(options) |
||||
|
||||
for (const extension in loaders) { |
||||
const loader = loaders[extension] |
||||
output.push({ |
||||
test: new RegExp('\\.' + extension + '$'), |
||||
use: loader |
||||
}) |
||||
} |
||||
|
||||
return output |
||||
} |
||||
|
||||
exports.createNotifierCallback = () => { |
||||
const notifier = require('node-notifier') |
||||
|
||||
return (severity, errors) => { |
||||
if (severity !== 'error') return |
||||
|
||||
const error = errors[0] |
||||
const filename = error.file && error.file.split('!').pop() |
||||
|
||||
notifier.notify({ |
||||
title: packageConfig.name, |
||||
message: severity + ': ' + error.name, |
||||
subtitle: filename || '', |
||||
icon: path.join(__dirname, 'logo.png') |
||||
}) |
||||
} |
||||
} |
@ -0,0 +1,5 @@
|
||||
'use strict' |
||||
|
||||
module.exports = { |
||||
//You can set the vue-loader configuration by yourself.
|
||||
} |
@ -0,0 +1,122 @@
|
||||
'use strict' |
||||
const path = require('path') |
||||
const utils = require('./utils') |
||||
const config = require('../config') |
||||
const { VueLoaderPlugin } = require('vue-loader') |
||||
|
||||
const os = require('os'); |
||||
const HappyPack = require('happypack'); |
||||
const happThreadPool = HappyPack.ThreadPool({size: os.cpus().length}); |
||||
|
||||
function resolve(dir) { |
||||
return path.join(__dirname, '..', dir) |
||||
} |
||||
|
||||
const createLintingRule = () => ({ |
||||
// test: /\.(js|vue)$/,
|
||||
// loader: 'eslint-loader',
|
||||
// enforce: 'pre',
|
||||
// include: [resolve('src'), resolve('test')],
|
||||
// options: {
|
||||
// formatter: require('eslint-friendly-formatter'),
|
||||
// emitWarning: !config.dev.showEslintErrorsInOverlay
|
||||
// }
|
||||
}) |
||||
|
||||
module.exports = { |
||||
cache: true, |
||||
context: path.resolve(__dirname, '../'), |
||||
entry:["babel-polyfill","./src/main.js"], |
||||
output: { |
||||
path: config.build.assetsRoot, |
||||
filename: '[name].js', |
||||
publicPath: |
||||
process.env.NODE_ENV === 'production' |
||||
? config.build.assetsPublicPath |
||||
: config.dev.assetsPublicPath |
||||
}, |
||||
resolve: { |
||||
modules: [path.resolve(__dirname, '../node_modules')], |
||||
extensions: ['.js', '.vue', '.json'], |
||||
alias: { |
||||
'@': resolve('src'), |
||||
api: path.resolve(__dirname, '../src/api') |
||||
} |
||||
}, |
||||
module: { |
||||
rules: [ |
||||
...(config.dev.useEslint ? [createLintingRule()] : []), |
||||
{ |
||||
test: /\.vue$/, |
||||
loader: 'vue-loader', |
||||
options: { |
||||
loaders: { |
||||
js: 'happypack/loader?id=js' // 将loader换成happypack
|
||||
} |
||||
} |
||||
}, |
||||
{ |
||||
test: /\.js$/, |
||||
loader: ['happypack/loader?id=js'], // 将loader换成happypack
|
||||
include: [ |
||||
resolve('src') |
||||
], // src是项目开发的目录
|
||||
exclude: [path.resolve('../node_modules')] // 不需要编译node_modules下的js
|
||||
}, |
||||
{ |
||||
test: /\.svg$/, |
||||
loader: 'svg-sprite-loader', |
||||
include: [resolve('src/icons')], |
||||
options: { |
||||
symbolId: 'icon-[name]' |
||||
} |
||||
}, |
||||
{ |
||||
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, |
||||
loader: 'url-loader', |
||||
exclude: [resolve('src/icons')], |
||||
options: { |
||||
limit: 10000, |
||||
name: utils.assetsPath('img/[name].[hash:7].[ext]') |
||||
} |
||||
}, |
||||
{ |
||||
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, |
||||
loader: 'url-loader', |
||||
options: { |
||||
limit: 10000, |
||||
name: utils.assetsPath('media/[name].[hash:7].[ext]') |
||||
} |
||||
}, |
||||
{ |
||||
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, |
||||
loader: 'url-loader', |
||||
options: { |
||||
limit: 10000, |
||||
name: utils.assetsPath('fonts/[name].[hash:7].[ext]') |
||||
} |
||||
} |
||||
] |
||||
}, |
||||
plugins: [ |
||||
new VueLoaderPlugin(), |
||||
new HappyPack({ |
||||
id: 'js', |
||||
cache: true, |
||||
loaders: ['babel-loader?cacheDirectory=true'], |
||||
threadPool: happThreadPool |
||||
}) |
||||
], |
||||
node: { |
||||
// prevent webpack from injecting useless setImmediate polyfill because Vue
|
||||
// source contains it (although only uses it if it's native).
|
||||
setImmediate: false, |
||||
// prevent webpack from injecting mocks to Node native modules
|
||||
// that does not make sense for the client
|
||||
dgram: 'empty', |
||||
fs: 'empty', |
||||
net: 'empty', |
||||
tls: 'empty', |
||||
child_process: 'empty' |
||||
} |
||||
} |
@ -0,0 +1,98 @@
|
||||
'use strict' |
||||
const path = require('path') |
||||
const utils = require('./utils') |
||||
const webpack = require('webpack') |
||||
const config = require('../config') |
||||
const merge = require('webpack-merge') |
||||
const baseWebpackConfig = require('./webpack.base.conf') |
||||
const HtmlWebpackPlugin = require('html-webpack-plugin') |
||||
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') |
||||
const portfinder = require('portfinder') |
||||
|
||||
function resolve(dir) { |
||||
return path.join(__dirname, '..', dir) |
||||
} |
||||
|
||||
const HOST = process.env.HOST |
||||
const PORT = process.env.PORT && Number(process.env.PORT) |
||||
|
||||
const devWebpackConfig = merge(baseWebpackConfig, { |
||||
mode: 'development', |
||||
module: { |
||||
rules: utils.styleLoaders({ |
||||
sourceMap: config.dev.cssSourceMap, |
||||
usePostCSS: true |
||||
}) |
||||
}, |
||||
// cheap-module-eval-source-map is faster for development
|
||||
devtool: config.dev.devtool, |
||||
|
||||
// these devServer options should be customized in /config/index.js
|
||||
devServer: { |
||||
clientLogLevel: 'warning', |
||||
historyApiFallback: true, |
||||
hot: true, |
||||
compress: true, |
||||
host: HOST || config.dev.host, |
||||
port: PORT || config.dev.port, |
||||
open: config.dev.autoOpenBrowser, |
||||
overlay: config.dev.errorOverlay |
||||
? { warnings: false, errors: true } |
||||
: false, |
||||
publicPath: config.dev.assetsPublicPath, |
||||
proxy: config.dev.proxyTable, |
||||
quiet: true, // necessary for FriendlyErrorsPlugin
|
||||
watchOptions: { |
||||
poll: config.dev.poll |
||||
} |
||||
}, |
||||
plugins: [ |
||||
new webpack.DefinePlugin({ |
||||
'process.env': require('../config/dev.env') |
||||
}), |
||||
new webpack.HotModuleReplacementPlugin(), |
||||
// https://github.com/ampedandwired/html-webpack-plugin
|
||||
new HtmlWebpackPlugin({ |
||||
filename: 'index.html', |
||||
template: 'index.html', |
||||
inject: true, |
||||
favicon: resolve('favicon.ico'), |
||||
title: 'vue-element-admin', |
||||
templateParameters: { |
||||
BASE_URL: config.dev.assetsPublicPath + config.dev.assetsSubDirectory, |
||||
}, |
||||
}), |
||||
] |
||||
}) |
||||
|
||||
module.exports = new Promise((resolve, reject) => { |
||||
portfinder.basePort = process.env.PORT || config.dev.port |
||||
portfinder.getPort((err, port) => { |
||||
if (err) { |
||||
reject(err) |
||||
} else { |
||||
// publish the new Port, necessary for e2e tests
|
||||
process.env.PORT = port |
||||
// add port to devServer config
|
||||
devWebpackConfig.devServer.port = port |
||||
|
||||
// Add FriendlyErrorsPlugin
|
||||
devWebpackConfig.plugins.push( |
||||
new FriendlyErrorsPlugin({ |
||||
compilationSuccessInfo: { |
||||
messages: [ |
||||
`Your application is running here: http://${ |
||||
devWebpackConfig.devServer.host |
||||
}:${port}` |
||||
] |
||||
}, |
||||
onErrors: config.dev.notifyOnErrors |
||||
? utils.createNotifierCallback() |
||||
: undefined |
||||
}) |
||||
) |
||||
|
||||
resolve(devWebpackConfig) |
||||
} |
||||
}) |
||||
}) |
@ -0,0 +1,188 @@
|
||||
'use strict' |
||||
const path = require('path') |
||||
const utils = require('./utils') |
||||
const webpack = require('webpack') |
||||
const config = require('../config') |
||||
const merge = require('webpack-merge') |
||||
const baseWebpackConfig = require('./webpack.base.conf') |
||||
const CopyWebpackPlugin = require('copy-webpack-plugin') |
||||
const HtmlWebpackPlugin = require('html-webpack-plugin') |
||||
const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin') |
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin') |
||||
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin') |
||||
const UglifyJsPlugin = require('uglifyjs-webpack-plugin') |
||||
|
||||
function resolve(dir) { |
||||
return path.join(__dirname, '..', dir) |
||||
} |
||||
|
||||
const env = require('../config/' + process.env.env_config + '.env') |
||||
|
||||
// For NamedChunksPlugin
|
||||
const seen = new Set() |
||||
const nameLength = 4 |
||||
|
||||
const webpackConfig = merge(baseWebpackConfig, { |
||||
mode: 'production', |
||||
module: { |
||||
rules: utils.styleLoaders({ |
||||
sourceMap: config.build.productionSourceMap, |
||||
extract: true, |
||||
usePostCSS: true |
||||
}) |
||||
}, |
||||
devtool: config.build.productionSourceMap ? config.build.devtool : false, |
||||
output: { |
||||
path: config.build.assetsRoot, |
||||
filename: utils.assetsPath('js/[name].[chunkhash:8].js'), |
||||
chunkFilename: utils.assetsPath('js/[name].[chunkhash:8].js') |
||||
}, |
||||
plugins: [ |
||||
// http://vuejs.github.io/vue-loader/en/workflow/production.html
|
||||
new webpack.DefinePlugin({ |
||||
'process.env': env |
||||
}), |
||||
// extract css into its own file
|
||||
new MiniCssExtractPlugin({ |
||||
filename: utils.assetsPath('css/[name].[contenthash:8].css'), |
||||
chunkFilename: utils.assetsPath('css/[name].[contenthash:8].css') |
||||
}), |
||||
// generate dist index.html with correct asset hash for caching.
|
||||
// you can customize output by editing /index.html
|
||||
// see https://github.com/ampedandwired/html-webpack-plugin
|
||||
new HtmlWebpackPlugin({ |
||||
filename: config.build.index, |
||||
template: 'index.html', |
||||
inject: true, |
||||
favicon: resolve('favicon.ico'), |
||||
title: 'vue-element-admin', |
||||
templateParameters: { |
||||
BASE_URL: config.build.assetsPublicPath + config.build.assetsSubDirectory, |
||||
}, |
||||
minify: { |
||||
removeComments: true, |
||||
collapseWhitespace: true, |
||||
removeAttributeQuotes: true |
||||
// more options:
|
||||
// https://github.com/kangax/html-minifier#options-quick-reference
|
||||
} |
||||
// default sort mode uses toposort which cannot handle cyclic deps
|
||||
// in certain cases, and in webpack 4, chunk order in HTML doesn't
|
||||
// matter anyway
|
||||
}), |
||||
new ScriptExtHtmlWebpackPlugin({ |
||||
//`runtime` must same as runtimeChunk name. default is `runtime`
|
||||
inline: /runtime\..*\.js$/ |
||||
}), |
||||
// keep chunk.id stable when chunk has no name
|
||||
new webpack.NamedChunksPlugin(chunk => { |
||||
if (chunk.name) { |
||||
return chunk.name |
||||
} |
||||
const modules = Array.from(chunk.modulesIterable) |
||||
if (modules.length > 1) { |
||||
const hash = require('hash-sum') |
||||
const joinedHash = hash(modules.map(m => m.id).join('_')) |
||||
let len = nameLength |
||||
while (seen.has(joinedHash.substr(0, len))) len++ |
||||
seen.add(joinedHash.substr(0, len)) |
||||
return `chunk-${joinedHash.substr(0, len)}` |
||||
} else { |
||||
return modules[0].id |
||||
} |
||||
}), |
||||
// keep module.id stable when vender modules does not change
|
||||
new webpack.HashedModuleIdsPlugin(), |
||||
// copy custom static assets
|
||||
new CopyWebpackPlugin([ |
||||
{ |
||||
from: path.resolve(__dirname, '../static'), |
||||
to: config.build.assetsSubDirectory, |
||||
ignore: ['.*'] |
||||
} |
||||
]) |
||||
], |
||||
optimization: { |
||||
splitChunks: { |
||||
chunks: 'all', |
||||
cacheGroups: { |
||||
libs: { |
||||
name: 'chunk-libs', |
||||
test: /[\\/]node_modules[\\/]/, |
||||
priority: 10, |
||||
chunks: 'initial' // 只打包初始时依赖的第三方
|
||||
}, |
||||
elementUI: { |
||||
name: 'chunk-elementUI', // 单独将 elementUI 拆包
|
||||
priority: 20, // 权重要大于 libs 和 app 不然会被打包进 libs 或者 app
|
||||
test: /[\\/]node_modules[\\/]element-ui[\\/]/ |
||||
}, |
||||
commons: { |
||||
name: 'chunk-commons', |
||||
test: resolve('src/components'), // 可自定义拓展你的规则
|
||||
minChunks: 3, // 最小公用次数
|
||||
priority: 5, |
||||
reuseExistingChunk: true |
||||
} |
||||
} |
||||
}, |
||||
runtimeChunk: 'single', |
||||
minimizer: [ |
||||
new UglifyJsPlugin({ |
||||
uglifyOptions: { |
||||
mangle: { |
||||
safari10: true |
||||
} |
||||
}, |
||||
sourceMap: config.build.productionSourceMap, |
||||
cache: true, |
||||
parallel: true |
||||
}), |
||||
// Compress extracted CSS. We are using this plugin so that possible
|
||||
// duplicated CSS from different components can be deduped.
|
||||
new OptimizeCSSAssetsPlugin() |
||||
] |
||||
} |
||||
}) |
||||
|
||||
if (config.build.productionGzip) { |
||||
const CompressionWebpackPlugin = require('compression-webpack-plugin') |
||||
|
||||
webpackConfig.plugins.push( |
||||
new CompressionWebpackPlugin({ |
||||
asset: '[path].gz[query]', |
||||
algorithm: 'gzip', |
||||
test: new RegExp( |
||||
'\\.(' + config.build.productionGzipExtensions.join('|') + ')$' |
||||
), |
||||
threshold: 10240, |
||||
minRatio: 0.8 |
||||
}) |
||||
) |
||||
} |
||||
|
||||
if (config.build.generateAnalyzerReport || config.build.bundleAnalyzerReport) { |
||||
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer') |
||||
.BundleAnalyzerPlugin |
||||
|
||||
if (config.build.bundleAnalyzerReport) { |
||||
webpackConfig.plugins.push( |
||||
new BundleAnalyzerPlugin({ |
||||
analyzerPort: 8080, |
||||
generateStatsFile: false |
||||
}) |
||||
) |
||||
} |
||||
|
||||
if (config.build.generateAnalyzerReport) { |
||||
webpackConfig.plugins.push( |
||||
new BundleAnalyzerPlugin({ |
||||
analyzerMode: 'static', |
||||
reportFilename: 'bundle-report.html', |
||||
openAnalyzer: false |
||||
}) |
||||
) |
||||
} |
||||
} |
||||
|
||||
module.exports = webpackConfig |
@ -0,0 +1,9 @@
|
||||
'use strict' |
||||
const merge = require('webpack-merge') |
||||
const prodEnv = require('./prod.env') |
||||
|
||||
module.exports = merge(prodEnv, { |
||||
NODE_ENV: '"development"', |
||||
BASE_API: '"http://localhost:8000"' |
||||
// BASE_API: '"https://api.auauz.net"'
|
||||
}) |
@ -0,0 +1,106 @@
|
||||
'use strict' |
||||
// Template version: 1.2.6
|
||||
const devEnv = require('./dev.env') |
||||
// 获取接口地址
|
||||
const base_url = devEnv.BASE_API.replace(/"/g,'') |
||||
const path = require('path') |
||||
module.exports = { |
||||
dev: { |
||||
// Paths
|
||||
assetsSubDirectory: 'static', |
||||
assetsPublicPath: '/', |
||||
// 配置代理
|
||||
proxyTable: { |
||||
'/auth': { |
||||
// 测试环境
|
||||
target: base_url, |
||||
secure: true, |
||||
changeOrigin: true, |
||||
pathRewrite: { |
||||
'^/auth': 'auth' |
||||
} |
||||
}, |
||||
'/api': { |
||||
// 测试环境
|
||||
target: base_url, |
||||
secure: true, |
||||
changeOrigin: true, |
||||
pathRewrite: { |
||||
'^/api': 'api' |
||||
} |
||||
} |
||||
}, |
||||
|
||||
// Various Dev Server settings
|
||||
host: 'localhost', // can be overwritten by process.env.HOST
|
||||
port: 8013, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
|
||||
autoOpenBrowser: true, |
||||
errorOverlay: true, |
||||
notifyOnErrors: false, |
||||
poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
|
||||
|
||||
// Use Eslint Loader?
|
||||
// If true, your code will be linted during bundling and
|
||||
// linting errors and warnings will be shown in the console.
|
||||
useEslint: true, |
||||
// If true, eslint errors and warnings will also be shown in the error overlay
|
||||
// in the browser.
|
||||
showEslintErrorsInOverlay: false, |
||||
|
||||
/** |
||||
* Source Maps |
||||
*/ |
||||
|
||||
// https://webpack.js.org/configuration/devtool/#development
|
||||
devtool: 'cheap-source-map', |
||||
|
||||
// CSS Sourcemaps off by default because relative paths are "buggy"
|
||||
// with this option, according to the CSS-Loader README
|
||||
// (https://github.com/webpack/css-loader#sourcemaps)
|
||||
// In our experience, they generally work as expected,
|
||||
// just be aware of this issue when enabling this option.
|
||||
cssSourceMap: false |
||||
}, |
||||
|
||||
build: { |
||||
// Template for index.html
|
||||
index: path.resolve(__dirname, '../dist/index.html'), |
||||
|
||||
// Paths
|
||||
assetsRoot: path.resolve(__dirname, '../dist'), |
||||
assetsSubDirectory: 'static', |
||||
|
||||
/** |
||||
* You can set by youself according to actual condition |
||||
* You will need to set this if you plan to deploy your site under a sub path, |
||||
* for example GitHub pages. If you plan to deploy your site to https://foo.github.io/bar/,
|
||||
* then assetsPublicPath should be set to "/bar/". |
||||
* In most cases please use '/' !!! |
||||
*/ |
||||
assetsPublicPath: '/', |
||||
|
||||
/** |
||||
* Source Maps |
||||
*/ |
||||
|
||||
productionSourceMap: false, |
||||
// https://webpack.js.org/configuration/devtool/#production
|
||||
devtool: 'source-map', |
||||
|
||||
// Gzip off by default as many popular static hosts such as
|
||||
// Surge or Netlify already gzip all static assets for you.
|
||||
// Before setting to `true`, make sure to:
|
||||
// npm install --save-dev compression-webpack-plugin
|
||||
productionGzip: false, |
||||
productionGzipExtensions: ['js', 'css'], |
||||
|
||||
// Run the build command with an extra argument to
|
||||
// View the bundle analyzer report after build finishes:
|
||||
// `npm run build --report`
|
||||
// Set to `true` or `false` to always turn it on or off
|
||||
bundleAnalyzerReport: process.env.npm_config_report || false, |
||||
|
||||
// `npm run build:prod --generate_report`
|
||||
generateAnalyzerReport: process.env.npm_config_generate_report || false |
||||
} |
||||
} |
@ -0,0 +1,5 @@
|
||||
'use strict' |
||||
module.exports = { |
||||
NODE_ENV: '"production"', |
||||
BASE_API: '"https://yshopapi.dayouqiantu.cn"' |
||||
} |
@ -0,0 +1 @@
|
||||
[1110/193651.524:ERROR:crashpad_client_win.cc(491)] CreateProcess: 页面文件太小,无法完成操作。 (0x5AF) |
After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<meta charset="utf-8"> |
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0"> |
||||
<style> |
||||
.sampleContainer{position:fixed;top:50%;left:50%;-webkit-transform:translateX(-50%) translateY(-50%);width:75px;height:100px}.loader{position:relative;width:44px;height:8px;margin:12px auto}.dot{display:inline-block;width:8px;height:8px;border-radius:4px;background:#ccc;position:absolute}.dot_1{animation:animateDot1 1.5s linear infinite;left:12px;background:#e579b8}.dot_2{animation:animateDot2 1.5s linear infinite;animation-delay:.5s;left:24px}.dot_3{animation:animateDot3 1.5s linear infinite;left:12px}.dot_4{animation:animateDot4 1.5s linear infinite;animation-delay:.5s;left:24px}@keyframes animateDot1{0%{transform:rotate(0) translateX(-12px)}25%{transform:rotate(180deg) translateX(-12px)}75%{transform:rotate(180deg) translateX(-12px)}100%{transform:rotate(360deg) translateX(-12px)}}@keyframes animateDot2{0%{transform:rotate(0) translateX(-12px)}25%{transform:rotate(-180deg) translateX(-12px)}75%{transform:rotate(-180deg) translateX(-12px)}100%{transform:rotate(-360deg) translateX(-12px)}}@keyframes animateDot3{0%{transform:rotate(0) translateX(12px)}25%{transform:rotate(180deg) translateX(12px)}75%{transform:rotate(180deg) translateX(12px)}100%{transform:rotate(360deg) translateX(12px)}}@keyframes animateDot4{0%{transform:rotate(0) translateX(12px)}25%{transform:rotate(-180deg) translateX(12px)}75%{transform:rotate(-180deg) translateX(12px)}100%{transform:rotate(-360deg) translateX(12px)}} |
||||
</style> |
||||
</head> |
||||
<body> |
||||
<div id="app"> |
||||
<div class="sampleContainer"> |
||||
<div class="loader"> |
||||
<span class="dot dot_1"></span> |
||||
<span class="dot dot_2"></span> |
||||
<span class="dot dot_3"></span> |
||||
<span class="dot dot_4"></span> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</body> |
||||
</html> |
@ -0,0 +1,106 @@
|
||||
{ |
||||
"name": "YSHOP", |
||||
"version": "2.2.0", |
||||
"license": "Apache-2.0", |
||||
"description": "YSHOP 前端代码", |
||||
"author": "hupeng <610796224@qq.com>", |
||||
"scripts": { |
||||
"dev": "cross-env BABEL_ENV=development webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", |
||||
"build": "cross-env NODE_ENV=production env_config=prod node build/build.js", |
||||
"lint": "eslint --ext .js,.vue src", |
||||
"test": "npm run lint", |
||||
"precommit": "lint-staged", |
||||
"svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml" |
||||
}, |
||||
"repository": { |
||||
"type": "git", |
||||
"url": "https://github.com/elunez/eladmin-qd" |
||||
}, |
||||
"dependencies": { |
||||
"@riophae/vue-treeselect": "0.0.38", |
||||
"axios": "^0.19.0", |
||||
"clipboard": "1.7.1", |
||||
"codemirror": "^5.38.0", |
||||
"connect": "3.6.6", |
||||
"echarts": "4.1.0", |
||||
"element-ui": "^2.12.0", |
||||
"file-saver": "1.3.8", |
||||
"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", |
||||
"screenfull": "3.3.3", |
||||
"vue": "2.5.17", |
||||
"vue-count-to": "1.0.13", |
||||
"vue-router": "3.1.3", |
||||
"vuex": "3.0.1", |
||||
"wangeditor": ">=3.0.0", |
||||
"xlsx": "^0.11.16" |
||||
}, |
||||
"devDependencies": { |
||||
"autoprefixer": "8.5.0", |
||||
"babel-core": "6.26.3", |
||||
"babel-eslint": "8.2.6", |
||||
"babel-helper-vue-jsx-merge-props": "2.0.3", |
||||
"babel-loader": "7.1.5", |
||||
"babel-plugin-dynamic-import-node": "2.0.0", |
||||
"babel-plugin-syntax-jsx": "6.18.0", |
||||
"babel-plugin-transform-runtime": "6.23.0", |
||||
"babel-plugin-transform-vue-jsx": "3.7.0", |
||||
"babel-polyfill": "^6.26.0", |
||||
"babel-preset-env": "1.7.0", |
||||
"babel-preset-stage-2": "6.24.1", |
||||
"chalk": "2.4.1", |
||||
"copy-webpack-plugin": "4.5.2", |
||||
"cross-env": "5.2.0", |
||||
"css-loader": "1.0.0", |
||||
"eslint": "4.19.1", |
||||
"eslint-friendly-formatter": "4.0.1", |
||||
"eslint-loader": "2.0.0", |
||||
"eslint-plugin-vue": "4.7.1", |
||||
"eventsource-polyfill": "0.9.6", |
||||
"file-loader": "1.1.11", |
||||
"friendly-errors-webpack-plugin": "1.7.0", |
||||
"happypack": "^5.0.1", |
||||
"html-webpack-plugin": "4.0.0-alpha", |
||||
"mini-css-extract-plugin": "0.4.1", |
||||
"node-notifier": "5.2.1", |
||||
"node-sass": "^4.7.2", |
||||
"optimize-css-assets-webpack-plugin": "5.0.0", |
||||
"ora": "3.0.0", |
||||
"portfinder": "1.0.16", |
||||
"postcss-import": "12.0.0", |
||||
"postcss-loader": "2.1.6", |
||||
"postcss-url": "7.3.2", |
||||
"rimraf": "2.6.2", |
||||
"sass-loader": "7.0.3", |
||||
"script-ext-html-webpack-plugin": "2.0.1", |
||||
"script-loader": "0.7.2", |
||||
"semver": "5.5.0", |
||||
"shelljs": "^0.8.3", |
||||
"svg-sprite-loader": "3.8.0", |
||||
"svgo": "1.2.2", |
||||
"uglifyjs-webpack-plugin": "1.2.7", |
||||
"url-loader": "1.0.1", |
||||
"vue-loader": "15.3.0", |
||||
"vue-style-loader": "4.1.2", |
||||
"vue-template-compiler": "2.5.17", |
||||
"webpack": "4.16.5", |
||||
"webpack-bundle-analyzer": "3.3.2", |
||||
"webpack-cli": "3.1.0", |
||||
"webpack-dev-server": "3.3.1", |
||||
"webpack-merge": "4.1.4" |
||||
}, |
||||
"engines": { |
||||
"node": ">= 6.0.0", |
||||
"npm": ">= 3.0.0" |
||||
}, |
||||
"browserslist": [ |
||||
"> 1%", |
||||
"last 2 versions", |
||||
"not ie <= 8" |
||||
] |
||||
} |
@ -0,0 +1,11 @@
|
||||
<template> |
||||
<div id="app"> |
||||
<router-view/> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
name: 'App' |
||||
} |
||||
</script> |
@ -0,0 +1,25 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function get() { |
||||
return request({ |
||||
url: 'api/aliPay', |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
export function update(data) { |
||||
return request({ |
||||
url: 'api/aliPay', |
||||
data, |
||||
method: 'put' |
||||
}) |
||||
} |
||||
|
||||
// 支付
|
||||
export function toAliPay(url, data) { |
||||
return request({ |
||||
url: 'api/' + url, |
||||
data, |
||||
method: 'post' |
||||
}) |
||||
} |
@ -0,0 +1,16 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function resetEmail(data) { |
||||
return request({ |
||||
url: 'api/code/resetEmail', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function updatePass(pass) { |
||||
return request({ |
||||
url: 'api/users/updatePass/' + pass, |
||||
method: 'get' |
||||
}) |
||||
} |
@ -0,0 +1,9 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function initData(url, params) { |
||||
return request({ |
||||
url: url, |
||||
method: 'get', |
||||
params |
||||
}) |
||||
} |
@ -0,0 +1,32 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function getDepts(params) { |
||||
return request({ |
||||
url: 'api/dept', |
||||
method: 'get', |
||||
params |
||||
}) |
||||
} |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/dept', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/dept/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/dept', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
@ -0,0 +1,24 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/dict', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/dict/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/dict', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
@ -0,0 +1,50 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function get(dictName) { |
||||
const params = { |
||||
dictName, |
||||
page: 0, |
||||
size: 9999 |
||||
} |
||||
return request({ |
||||
url: 'api/dictDetail', |
||||
method: 'get', |
||||
params |
||||
}) |
||||
} |
||||
|
||||
export function getDictMap(dictName) { |
||||
const params = { |
||||
dictName, |
||||
page: 0, |
||||
size: 9999 |
||||
} |
||||
return request({ |
||||
url: 'api/dictDetail/map', |
||||
method: 'get', |
||||
params |
||||
}) |
||||
} |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/dictDetail', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/dictDetail/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/dictDetail', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
@ -0,0 +1,24 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function get() { |
||||
return request({ |
||||
url: 'api/email', |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
export function update(data) { |
||||
return request({ |
||||
url: 'api/email', |
||||
data, |
||||
method: 'put' |
||||
}) |
||||
} |
||||
|
||||
export function send(data) { |
||||
return request({ |
||||
url: 'api/email', |
||||
data, |
||||
method: 'post' |
||||
}) |
||||
} |
@ -0,0 +1,16 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function get() { |
||||
return request({ |
||||
url: 'api/genConfig', |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
export function update(data) { |
||||
return request({ |
||||
url: 'api/genConfig', |
||||
data, |
||||
method: 'put' |
||||
}) |
||||
} |
@ -0,0 +1,9 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function generator(data, tableName) { |
||||
return request({ |
||||
url: 'api/generator?tableName=' + tableName, |
||||
data, |
||||
method: 'post' |
||||
}) |
||||
} |
@ -0,0 +1,37 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function getAllJob(deptId) { |
||||
const params = { |
||||
deptId, |
||||
page: 0, |
||||
size: 9999 |
||||
} |
||||
return request({ |
||||
url: 'api/job', |
||||
method: 'get', |
||||
params |
||||
}) |
||||
} |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/job', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/job/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/job', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
@ -0,0 +1,32 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/localStorage', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/localStorage/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function delAll(ids) { |
||||
return request({ |
||||
url: 'api/localStorage/', |
||||
method: 'delete', |
||||
data: ids |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/localStorage', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
@ -0,0 +1,8 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function getErrDetail(id) { |
||||
return request({ |
||||
url: 'api/logs/error/' + id, |
||||
method: 'get' |
||||
}) |
||||
} |
@ -0,0 +1,28 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function login(username, password, code, uuid) { |
||||
return request({ |
||||
url: 'auth/login', |
||||
method: 'post', |
||||
data: { |
||||
username, |
||||
password, |
||||
code, |
||||
uuid |
||||
} |
||||
}) |
||||
} |
||||
|
||||
export function getInfo() { |
||||
return request({ |
||||
url: 'auth/info', |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
export function getCodeImg() { |
||||
return request({ |
||||
url: 'auth/vCode', |
||||
method: 'get' |
||||
}) |
||||
} |
@ -0,0 +1,39 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
// 获取所有的菜单树
|
||||
export function getMenusTree() { |
||||
return request({ |
||||
url: 'api/menus/tree', |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
export function buildMenus() { |
||||
return request({ |
||||
url: 'api/menus/build', |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/menus', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/menus/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/menus', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
@ -0,0 +1,32 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
// 获取所有的权限树
|
||||
export function getPermissionTree() { |
||||
return request({ |
||||
url: 'api/permissions/tree', |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/permissions', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/permissions/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/permissions', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
@ -0,0 +1,16 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/pictures/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function delAll(ids) { |
||||
return request({ |
||||
url: 'api/pictures/', |
||||
method: 'delete', |
||||
data: ids |
||||
}) |
||||
} |
@ -0,0 +1,45 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function get() { |
||||
return request({ |
||||
url: 'api/qiNiuConfig', |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
export function update(data) { |
||||
return request({ |
||||
url: 'api/qiNiuConfig', |
||||
data, |
||||
method: 'put' |
||||
}) |
||||
} |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/qiNiuContent/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function download(id) { |
||||
return request({ |
||||
url: 'api/qiNiuContent/download/' + id, |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
export function sync() { |
||||
return request({ |
||||
url: 'api/qiNiuContent/synchronize', |
||||
method: 'post' |
||||
}) |
||||
} |
||||
|
||||
export function delAll(ids) { |
||||
return request({ |
||||
url: 'api/qiNiuContent/', |
||||
method: 'delete', |
||||
data: ids |
||||
}) |
||||
} |
@ -0,0 +1,35 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/redis', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function del(key) { |
||||
const data = { |
||||
key |
||||
} |
||||
return request({ |
||||
url: 'api/redis/', |
||||
method: 'delete', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function delAll() { |
||||
return request({ |
||||
url: 'api/redis/all', |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/redis', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
@ -0,0 +1,62 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
// 获取所有的Role
|
||||
export function getAll() { |
||||
return request({ |
||||
url: 'api/roles/all', |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/roles', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function get(id) { |
||||
return request({ |
||||
url: 'api/roles/' + id, |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
export function getLevel() { |
||||
return request({ |
||||
url: 'api/roles/level', |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/roles/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/roles', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function editPermission(data) { |
||||
return request({ |
||||
url: 'api/roles/permission', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function editMenu(data) { |
||||
return request({ |
||||
url: 'api/roles/menu', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
@ -0,0 +1,38 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/jobs', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/jobs/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/jobs', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function updateIsPause(id) { |
||||
return request({ |
||||
url: 'api/jobs/' + id, |
||||
method: 'put' |
||||
}) |
||||
} |
||||
|
||||
export function execution(id) { |
||||
return request({ |
||||
url: 'api/jobs/exec/' + id, |
||||
method: 'put' |
||||
}) |
||||
} |
@ -0,0 +1,52 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/users', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
export function downloadUser() { |
||||
return request({ |
||||
url: 'api/users/download', |
||||
method: 'get', |
||||
responseType: 'blob' |
||||
}) |
||||
} |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/users/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/users', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function updatePass(user) { |
||||
const data = { |
||||
oldPass: user.oldPass, |
||||
newPass: user.newPass |
||||
} |
||||
return request({ |
||||
url: 'api/users/updatePass/', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function updateEmail(code, data) { |
||||
return request({ |
||||
url: 'api/users/updateEmail/' + code, |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
@ -0,0 +1,22 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function count() { |
||||
return request({ |
||||
url: 'api/visits', |
||||
method: 'post' |
||||
}) |
||||
} |
||||
|
||||
export function get() { |
||||
return request({ |
||||
url: 'api/visits', |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
export function getChartData() { |
||||
return request({ |
||||
url: 'api/visits/chartData', |
||||
method: 'get' |
||||
}) |
||||
} |
@ -0,0 +1,31 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/yxArticle', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/yxArticle/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/yxArticle', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function publish(id) { |
||||
return request({ |
||||
url: 'api/yxArticle/publish/' + id, |
||||
method: 'get' |
||||
}) |
||||
} |
@ -0,0 +1,31 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/yxCache', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function del(key) { |
||||
return request({ |
||||
url: 'api/yxCache/' + key, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/yxCache', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function get() { |
||||
return request({ |
||||
url: 'api/yxCache', |
||||
method: 'get', |
||||
}) |
||||
} |
@ -0,0 +1,32 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function getCates(params) { |
||||
return request({ |
||||
url: 'api/yxStoreCategory', |
||||
method: 'get', |
||||
params |
||||
}) |
||||
} |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/yxStoreCategory', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/yxStoreCategory/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/yxStoreCategory', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
@ -0,0 +1,32 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/yxStoreCombination', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/yxStoreCombination/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/yxStoreCombination', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function onsale(id, data) { |
||||
return request({ |
||||
url: 'api/yxStoreCombination/onsale/' + id, |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
@ -0,0 +1,24 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/yxStoreCoupon', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/yxStoreCoupon/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/yxStoreCoupon', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
@ -0,0 +1,24 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/yxStoreCouponIssue', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/yxStoreCouponIssue/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/yxStoreCouponIssue', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
@ -0,0 +1,24 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/yxStoreCouponIssueUser', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/yxStoreCouponIssueUser/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/yxStoreCouponIssueUser', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
@ -0,0 +1,24 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/yxStoreCouponUser', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/yxStoreCouponUser/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/yxStoreCouponUser', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
@ -0,0 +1,32 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/yxStoreOrder', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/yxStoreOrder/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/yxStoreOrder', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function refund(data) { |
||||
return request({ |
||||
url: 'api/yxStoreOrder/refund', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
@ -0,0 +1,24 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/yxStoreOrderStatus', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/yxStoreOrderStatus/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/yxStoreOrderStatus', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
@ -0,0 +1,24 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/yxStorePink', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/yxStorePink/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/yxStorePink', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
@ -0,0 +1,72 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/yxStoreProduct', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/yxStoreProduct/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/yxStoreProduct', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function onsale(id, data) { |
||||
return request({ |
||||
url: 'api/yxStoreProduct/onsale/' + id, |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function recovery(id) { |
||||
return request({ |
||||
url: 'api/yxStoreProduct/recovery/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function isFormatAttr(id,data) { |
||||
return request({ |
||||
url: 'api/yxStoreProduct/isFormatAttr/' + id, |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function setAttr(id,data) { |
||||
return request({ |
||||
url: 'api/yxStoreProduct/setAttr/' + id, |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
|
||||
export function clearAttr(id) { |
||||
return request({ |
||||
url: 'api/yxStoreProduct/clearAttr/' + id, |
||||
method: 'post', |
||||
}) |
||||
} |
||||
|
||||
export function getAttr(id) { |
||||
return request({ |
||||
url: 'api/yxStoreProduct/attr/' + id, |
||||
method: 'get', |
||||
}) |
||||
} |
||||
|
||||
|
@ -0,0 +1,24 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/yxStoreProductReply', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/yxStoreProductReply/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/yxStoreProductReply', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
@ -0,0 +1,24 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/yxStoreVisit', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/yxStoreVisit/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/yxStoreVisit', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
@ -0,0 +1,32 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/yxSystemConfig', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/yxSystemConfig/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/yxSystemConfig', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function get() { |
||||
return request({ |
||||
url: 'api/yxSystemConfig', |
||||
method: 'get', |
||||
}) |
||||
} |
||||
|
@ -0,0 +1,24 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/yxSystemGroupData', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/yxSystemGroupData/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/yxSystemGroupData', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
@ -0,0 +1,32 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/yxUser', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function del(uid) { |
||||
return request({ |
||||
url: 'api/yxUser/' + uid, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/yxUser', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function onStatus(id, data) { |
||||
return request({ |
||||
url: 'api/yxUser/onStatus/' + id, |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
@ -0,0 +1,24 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/yxUserBill', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/yxUserBill/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/yxUserBill', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
@ -0,0 +1,24 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/yxUserExtract', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/yxUserExtract/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/yxUserExtract', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
@ -0,0 +1,32 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function add(data) { |
||||
return request({ |
||||
url: 'api/yxWechatReply', |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function del(id) { |
||||
return request({ |
||||
url: 'api/yxWechatReply/' + id, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
export function edit(data) { |
||||
return request({ |
||||
url: 'api/yxWechatReply', |
||||
method: 'put', |
||||
data |
||||
}) |
||||
} |
||||
|
||||
export function get() { |
||||
return request({ |
||||
url: 'api/yxWechatReply', |
||||
method: 'get', |
||||
}) |
||||
} |
||||
|
After Width: | Height: | Size: 160 KiB |
After Width: | Height: | Size: 96 KiB |
After Width: | Height: | Size: 4.7 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 126 KiB |
After Width: | Height: | Size: 231 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 12 KiB |
@ -0,0 +1,74 @@
|
||||
<template> |
||||
<el-breadcrumb class="app-breadcrumb" separator="/"> |
||||
<transition-group name="breadcrumb"> |
||||
<el-breadcrumb-item v-for="(item,index) in levelList" v-if="item.meta.title" :key="item.path"> |
||||
<span v-if="item.redirect==='noredirect'||index==levelList.length-1" class="no-redirect">{{ item.meta.title }}</span> |
||||
<a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a> |
||||
</el-breadcrumb-item> |
||||
</transition-group> |
||||
</el-breadcrumb> |
||||
</template> |
||||
|
||||
<script> |
||||
import pathToRegexp from 'path-to-regexp' |
||||
|
||||
export default { |
||||
data() { |
||||
return { |
||||
levelList: null |
||||
} |
||||
}, |
||||
watch: { |
||||
$route() { |
||||
this.getBreadcrumb() |
||||
} |
||||
}, |
||||
created() { |
||||
this.getBreadcrumb() |
||||
}, |
||||
methods: { |
||||
getBreadcrumb() { |
||||
let matched = this.$route.matched.filter(item => { |
||||
if (item.name) { |
||||
return true |
||||
} |
||||
}) |
||||
const first = matched[0] |
||||
if (first && first.name !== '首页') { |
||||
matched = [{ path: '/dashboard', meta: { title: '首页' }}].concat(matched) |
||||
} |
||||
if (matched.length >= 4) { |
||||
matched.splice(1, 1) |
||||
} |
||||
this.levelList = matched |
||||
}, |
||||
pathCompile(path) { |
||||
// To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561 |
||||
const { params } = this.$route |
||||
var toPath = pathToRegexp.compile(path) |
||||
return toPath(params) |
||||
}, |
||||
handleLink(item) { |
||||
const { redirect, path } = item |
||||
if (redirect) { |
||||
this.$router.push(redirect) |
||||
return |
||||
} |
||||
this.$router.push(this.pathCompile(path)) |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped> |
||||
.app-breadcrumb.el-breadcrumb { |
||||
display: inline-block; |
||||
font-size: 14px; |
||||
line-height: 50px; |
||||
margin-left: 10px; |
||||
.no-redirect { |
||||
color: #97a8be; |
||||
cursor: text; |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,47 @@
|
||||
<template> |
||||
<div> |
||||
<svg |
||||
:class="{'is-active':isActive}" |
||||
t="1492500959545" |
||||
class="hamburger" |
||||
viewBox="0 0 1024 1024" |
||||
xmlns="http://www.w3.org/2000/svg" |
||||
version="1.1" |
||||
p-id="1691" |
||||
width="64" |
||||
height="64" |
||||
@click="toggleClick"> |
||||
<path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" /> |
||||
</svg> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
name: 'Hamburger', |
||||
props: { |
||||
isActive: { |
||||
type: Boolean, |
||||
default: false |
||||
}, |
||||
toggleClick: { |
||||
type: Function, |
||||
default: null |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style scoped> |
||||
.hamburger { |
||||
display: inline-block; |
||||
cursor: pointer; |
||||
width: 20px; |
||||
height: 20px; |
||||
transition: .38s; |
||||
transform-origin: 50% 50%; |
||||
} |
||||
.hamburger.is-active { |
||||
transform: rotate(180deg); |
||||
} |
||||
</style> |
@ -0,0 +1,69 @@
|
||||
<!-- @author zhengjie --> |
||||
<template> |
||||
<div class="icon-body"> |
||||
<el-input v-model="name" style="position: relative;" clearable placeholder="请输入图标名称" @clear="filterIcons" @input.native="filterIcons"> |
||||
<i slot="suffix" class="el-icon-search el-input__icon"/> |
||||
</el-input> |
||||
<div class="icon-list"> |
||||
<div v-for="(item, index) in iconList" :key="index" @click="selectedIcon(item)"> |
||||
<svg-icon :icon-class="item" style="height: 30px;width: 16px;" /> |
||||
<span>{{ item }}</span> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import icons from './requireIcons' |
||||
export default { |
||||
name: 'IconSelect', |
||||
data() { |
||||
return { |
||||
name: '', |
||||
iconList: icons |
||||
} |
||||
}, |
||||
methods: { |
||||
filterIcons() { |
||||
if (this.name) { |
||||
this.iconList = this.iconList.filter(item => item.includes(this.name)) |
||||
} else { |
||||
this.iconList = icons |
||||
} |
||||
}, |
||||
selectedIcon(name) { |
||||
this.$emit('selected', name) |
||||
document.body.click() |
||||
}, |
||||
reset() { |
||||
this.name = '' |
||||
this.iconList = icons |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped> |
||||
.icon-body { |
||||
width: 100%; |
||||
padding: 10px; |
||||
.icon-list { |
||||
height: 200px; |
||||
overflow-y: scroll; |
||||
div { |
||||
height: 30px; |
||||
line-height: 30px; |
||||
margin-bottom: -5px; |
||||
cursor: pointer; |
||||
width: 33%; |
||||
float: left; |
||||
} |
||||
span { |
||||
display: inline-block; |
||||
vertical-align: -0.15em; |
||||
fill: currentColor; |
||||
overflow: hidden; |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,11 @@
|
||||
|
||||
const req = require.context('../../icons/svg', false, /\.svg$/) |
||||
const requireAll = requireContext => requireContext.keys() |
||||
|
||||
const re = /\.\/(.*)\.svg/ |
||||
|
||||
const icons = requireAll(req).map(i => { |
||||
return i.match(re)[1] |
||||
}) |
||||
|
||||
export default icons |
@ -0,0 +1,140 @@
|
||||
<template> |
||||
<div :style="{zIndex:zIndex,height:height,width:width}" class="pan-item"> |
||||
<div class="pan-info"> |
||||
<div class="pan-info-roles-container"> |
||||
<slot/> |
||||
</div> |
||||
</div> |
||||
<img :src="image" class="pan-thumb"> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
name: 'PanThumb', |
||||
props: { |
||||
image: { |
||||
type: String, |
||||
required: true |
||||
}, |
||||
zIndex: { |
||||
type: Number, |
||||
default: 1 |
||||
}, |
||||
width: { |
||||
type: String, |
||||
default: '150px' |
||||
}, |
||||
height: { |
||||
type: String, |
||||
default: '150px' |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style scoped> |
||||
.pan-item { |
||||
width: 200px; |
||||
height: 200px; |
||||
border-radius: 50%; |
||||
display: inline-block; |
||||
position: relative; |
||||
cursor: default; |
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); |
||||
} |
||||
|
||||
.pan-info-roles-container { |
||||
padding: 20px; |
||||
text-align: center; |
||||
} |
||||
|
||||
.pan-thumb { |
||||
width: 100%; |
||||
height: 100%; |
||||
background-size: 100%; |
||||
border-radius: 50%; |
||||
overflow: hidden; |
||||
position: absolute; |
||||
transform-origin: 95% 40%; |
||||
transition: all 0.3s ease-in-out; |
||||
} |
||||
|
||||
.pan-thumb:after { |
||||
content: ''; |
||||
width: 8px; |
||||
height: 8px; |
||||
position: absolute; |
||||
border-radius: 50%; |
||||
top: 40%; |
||||
left: 95%; |
||||
margin: -4px 0 0 -4px; |
||||
background: radial-gradient(ellipse at center, rgba(14, 14, 14, 1) 0%, rgba(125, 126, 125, 1) 100%); |
||||
box-shadow: 0 0 1px rgba(255, 255, 255, 0.9); |
||||
} |
||||
|
||||
.pan-info { |
||||
position: absolute; |
||||
width: inherit; |
||||
height: inherit; |
||||
border-radius: 50%; |
||||
overflow: hidden; |
||||
box-shadow: inset 0 0 0 5px rgba(0, 0, 0, 0.05); |
||||
} |
||||
|
||||
.pan-info h3 { |
||||
color: #fff; |
||||
text-transform: uppercase; |
||||
position: relative; |
||||
letter-spacing: 2px; |
||||
font-size: 18px; |
||||
margin: 0 60px; |
||||
padding: 22px 0 0 0; |
||||
height: 85px; |
||||
font-family: 'Open Sans', Arial, sans-serif; |
||||
text-shadow: 0 0 1px #fff, 0 1px 2px rgba(0, 0, 0, 0.3); |
||||
} |
||||
|
||||
.pan-info p { |
||||
color: #fff; |
||||
padding: 10px 5px; |
||||
font-style: italic; |
||||
margin: 0 30px; |
||||
font-size: 12px; |
||||
border-top: 1px solid rgba(255, 255, 255, 0.5); |
||||
} |
||||
|
||||
.pan-info p a { |
||||
display: block; |
||||
color: #333; |
||||
width: 80px; |
||||
height: 80px; |
||||
background: rgba(255, 255, 255, 0.3); |
||||
border-radius: 50%; |
||||
color: #fff; |
||||
font-style: normal; |
||||
font-weight: 700; |
||||
text-transform: uppercase; |
||||
font-size: 9px; |
||||
letter-spacing: 1px; |
||||
padding-top: 24px; |
||||
margin: 7px auto 0; |
||||
font-family: 'Open Sans', Arial, sans-serif; |
||||
opacity: 0; |
||||
transition: transform 0.3s ease-in-out 0.2s, opacity 0.3s ease-in-out 0.2s, background 0.2s linear 0s; |
||||
transform: translateX(60px) rotate(90deg); |
||||
} |
||||
|
||||
.pan-info p a:hover { |
||||
background: rgba(255, 255, 255, 0.5); |
||||
} |
||||
|
||||
.pan-item:hover .pan-thumb { |
||||
transform: rotate(-110deg); |
||||
} |
||||
|
||||
.pan-item:hover .pan-info p a { |
||||
opacity: 1; |
||||
transform: translateX(0px) rotate(0deg); |
||||
} |
||||
</style> |
@ -0,0 +1,165 @@
|
||||
<template> |
||||
<div ref="rightPanel" :class="{show:show}" class="rightPanel-container"> |
||||
<div class="rightPanel-background" /> |
||||
<div class="rightPanel"> |
||||
<div v-if="settingBtn" :style="{'top':buttonTop+'px','background-color':theme}" class="handle-button" @click="show=!show"> |
||||
<i :class="show?'el-icon-close':'el-icon-setting'" /> |
||||
</div> |
||||
<div v-else :style="{'top':buttonTop+'px'}" @click="show=!show"/> |
||||
<div class="rightPanel-items"> |
||||
<slot /> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import { addClass, removeClass } from '@/utils' |
||||
|
||||
export default { |
||||
name: 'RightPanel', |
||||
props: { |
||||
clickNotClose: { |
||||
default: false, |
||||
type: Boolean |
||||
}, |
||||
buttonTop: { |
||||
default: 250, |
||||
type: Number |
||||
} |
||||
}, |
||||
computed: { |
||||
show: { |
||||
get() { |
||||
return this.$store.state.settings.showRightPanel |
||||
}, |
||||
set(val) { |
||||
this.$store.dispatch('changeSetting', { |
||||
key: 'showRightPanel', |
||||
value: val |
||||
}) |
||||
} |
||||
}, |
||||
theme: { |
||||
get() { |
||||
return this.$store.state.settings.theme |
||||
} |
||||
}, |
||||
settingBtn: { |
||||
get() { |
||||
return this.$store.state.settings.settingBtn |
||||
} |
||||
} |
||||
}, |
||||
watch: { |
||||
show(value) { |
||||
if (value && !this.clickNotClose) { |
||||
this.addEventClick() |
||||
} |
||||
if (value) { |
||||
addClass(document.body, 'showRightPanel') |
||||
} else { |
||||
removeClass(document.body, 'showRightPanel') |
||||
} |
||||
} |
||||
}, |
||||
mounted() { |
||||
this.insertToBody() |
||||
}, |
||||
beforeDestroy() { |
||||
const elx = this.$refs.rightPanel |
||||
elx.remove() |
||||
}, |
||||
methods: { |
||||
addEventClick() { |
||||
window.addEventListener('click', this.closeSidebar) |
||||
}, |
||||
closeSidebar(evt) { |
||||
const parent = evt.target.closest('.rightPanel') |
||||
if (!parent) { |
||||
this.show = false |
||||
window.removeEventListener('click', this.closeSidebar) |
||||
} |
||||
}, |
||||
insertToBody() { |
||||
const elx = this.$refs.rightPanel |
||||
const body = document.querySelector('body') |
||||
body.insertBefore(elx, body.firstChild) |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style> |
||||
.showRightPanel { |
||||
overflow: hidden; |
||||
position: relative; |
||||
width: calc(100% - 15px); |
||||
} |
||||
</style> |
||||
|
||||
<style lang="scss" scoped> |
||||
.rightPanel-background { |
||||
opacity: 0; |
||||
transition: opacity .3s cubic-bezier(.7, .3, .1, 1); |
||||
background: rgba(0, 0, 0, .2); |
||||
width: 0; |
||||
height: 0; |
||||
top: 0; |
||||
left: 0; |
||||
position: fixed; |
||||
z-index: -1; |
||||
} |
||||
|
||||
.rightPanel { |
||||
background: #fff; |
||||
position: fixed; |
||||
height: 100vh; |
||||
width: 100%; |
||||
max-width: 260px; |
||||
top: 0px; |
||||
left: 0px; |
||||
box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, .05); |
||||
transition: all .25s cubic-bezier(.7, .3, .1, 1); |
||||
transform: translate(100%); |
||||
z-index: 40000; |
||||
left: auto; |
||||
right: 0px; |
||||
} |
||||
|
||||
.show { |
||||
transition: all .3s cubic-bezier(.7, .3, .1, 1); |
||||
|
||||
.rightPanel-background { |
||||
z-index: 20000; |
||||
opacity: 1; |
||||
width: 100%; |
||||
height: 100%; |
||||
} |
||||
|
||||
.rightPanel { |
||||
transform: translate(0); |
||||
} |
||||
} |
||||
|
||||
.handle-button { |
||||
position: absolute; |
||||
left: -48px; |
||||
border-radius: 6px 0 0 6px !important; |
||||
width: 48px; |
||||
height: 48px; |
||||
pointer-events: auto; |
||||
z-index: 0; |
||||
cursor: pointer; |
||||
pointer-events: auto; |
||||
font-size: 24px; |
||||
text-align: center; |
||||
color: #fff; |
||||
line-height: 48px; |
||||
|
||||
i { |
||||
font-size: 24px; |
||||
line-height: 48px; |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,78 @@
|
||||
<template> |
||||
<div> |
||||
<svg |
||||
t="1508738709248" |
||||
class="screenfull-svg" |
||||
viewBox="0 0 1024 1024" |
||||
version="1.1" |
||||
xmlns="http://www.w3.org/2000/svg" |
||||
p-id="2069" |
||||
xmlns:xlink="http://www.w3.org/1999/xlink" |
||||
width="32" |
||||
height="32" |
||||
@click="click"> |
||||
<path |
||||
d="M333.493443 428.647617 428.322206 333.832158 262.572184 168.045297 366.707916 64.444754 64.09683 64.444754 63.853283 366.570793 167.283957 262.460644Z" |
||||
p-id="2070"/> |
||||
<path |
||||
d="M854.845439 760.133334 688.61037 593.95864 593.805144 688.764889 759.554142 854.56096 655.44604 958.161503 958.055079 958.161503 958.274066 656.035464Z" |
||||
p-id="2071"/> |
||||
<path |
||||
d="M688.535669 428.550403 854.31025 262.801405 957.935352 366.921787 957.935352 64.34754 655.809313 64.081481 759.919463 167.535691 593.70793 333.731874Z" |
||||
p-id="2072"/> |
||||
<path |
||||
d="M333.590658 594.033341 167.8171 759.804852 64.218604 655.67219 64.218604 958.270996 366.342596 958.502263 262.234493 855.071589 428.421466 688.86108Z" |
||||
p-id="2073"/> |
||||
</svg> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import screenfull from 'screenfull' |
||||
|
||||
export default { |
||||
name: 'Screenfull', |
||||
props: { |
||||
width: { |
||||
type: Number, |
||||
default: 22 |
||||
}, |
||||
height: { |
||||
type: Number, |
||||
default: 22 |
||||
}, |
||||
fill: { |
||||
type: String, |
||||
default: '#48576a' |
||||
} |
||||
}, |
||||
data() { |
||||
return { |
||||
isFullscreen: false |
||||
} |
||||
}, |
||||
methods: { |
||||
click() { |
||||
if (!screenfull.enabled) { |
||||
this.$message({ |
||||
message: 'you browser can not work', |
||||
type: 'warning' |
||||
}) |
||||
return false |
||||
} |
||||
screenfull.toggle() |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style scoped> |
||||
.screenfull-svg { |
||||
display: inline-block; |
||||
cursor: pointer; |
||||
fill: #5a5e66;; |
||||
width: 20px; |
||||
height: 20px; |
||||
vertical-align: 10px; |
||||
} |
||||
</style> |
@ -0,0 +1,92 @@
|
||||
<template> |
||||
<el-scrollbar ref="scrollContainer" :vertical="false" class="scroll-container" @wheel.native.prevent="handleScroll"> |
||||
<slot/> |
||||
</el-scrollbar> |
||||
</template> |
||||
|
||||
<script> |
||||
const tagAndTagSpacing = 4 // tagAndTagSpacing |
||||
|
||||
export default { |
||||
name: 'ScrollPane', |
||||
data() { |
||||
return { |
||||
left: 0 |
||||
} |
||||
}, |
||||
methods: { |
||||
handleScroll(e) { |
||||
const eventDelta = e.wheelDelta || -e.deltaY * 40 |
||||
const $scrollWrapper = this.$refs.scrollContainer.$refs.wrap |
||||
$scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4 |
||||
}, |
||||
moveToTarget(currentTag) { |
||||
const $container = this.$refs.scrollContainer.$el |
||||
const $containerWidth = $container.offsetWidth |
||||
const $scrollWrapper = this.$refs.scrollContainer.$refs.wrap |
||||
const tagList = this.$parent.$refs.tag |
||||
|
||||
let firstTag = null |
||||
let lastTag = null |
||||
let prevTag = null |
||||
let nextTag = null |
||||
|
||||
// find first tag and last tag |
||||
if (tagList.length > 0) { |
||||
firstTag = tagList[0] |
||||
lastTag = tagList[tagList.length - 1] |
||||
} |
||||
|
||||
// find preTag and nextTag |
||||
for (let i = 0; i < tagList.length; i++) { |
||||
if (tagList[i] === currentTag) { |
||||
if (i === 0) { |
||||
nextTag = tagList[i].length > 1 && tagList[i + 1] |
||||
} else if (i === tagList.length - 1) { |
||||
prevTag = tagList[i].length > 1 && tagList[i - 1] |
||||
} else { |
||||
prevTag = tagList[i - 1] |
||||
nextTag = tagList[i + 1] |
||||
} |
||||
break |
||||
} |
||||
} |
||||
|
||||
if (firstTag === currentTag) { |
||||
$scrollWrapper.scrollLeft = 0 |
||||
} else if (lastTag === currentTag) { |
||||
$scrollWrapper.scrollLeft = $scrollWrapper.scrollWidth - $containerWidth |
||||
} else { |
||||
// the tag's offsetLeft after of nextTag |
||||
const afterNextTagOffsetLeft = nextTag.$el.offsetLeft + nextTag.$el.offsetWidth + tagAndTagSpacing |
||||
|
||||
// the tag's offsetLeft before of prevTag |
||||
const beforePrevTagOffsetLeft = prevTag.$el.offsetLeft - tagAndTagSpacing |
||||
|
||||
if (afterNextTagOffsetLeft > $scrollWrapper.scrollLeft + $containerWidth) { |
||||
$scrollWrapper.scrollLeft = afterNextTagOffsetLeft - $containerWidth |
||||
} else if (beforePrevTagOffsetLeft < $scrollWrapper.scrollLeft) { |
||||
$scrollWrapper.scrollLeft = beforePrevTagOffsetLeft |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped> |
||||
.scroll-container { |
||||
white-space: nowrap; |
||||
position: relative; |
||||
overflow: hidden; |
||||
width: 100%; |
||||
/deep/ { |
||||
.el-scrollbar__bar { |
||||
bottom: 0px; |
||||
} |
||||
.el-scrollbar__wrap { |
||||
height: 49px; |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,43 @@
|
||||
<template> |
||||
<svg :class="svgClass" aria-hidden="true"> |
||||
<use :xlink:href="iconName"/> |
||||
</svg> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
name: 'SvgIcon', |
||||
props: { |
||||
iconClass: { |
||||
type: String, |
||||
required: true |
||||
}, |
||||
className: { |
||||
type: String, |
||||
default: '' |
||||
} |
||||
}, |
||||
computed: { |
||||
iconName() { |
||||
return `#icon-${this.iconClass}` |
||||
}, |
||||
svgClass() { |
||||
if (this.className) { |
||||
return 'svg-icon ' + this.className |
||||
} else { |
||||
return 'svg-icon' |
||||
} |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style scoped> |
||||
.svg-icon { |
||||
width: 1em; |
||||
height: 1em; |
||||
vertical-align: -0.15em; |
||||
fill: currentColor; |
||||
overflow: hidden; |
||||
} |
||||
</style> |
@ -0,0 +1,113 @@
|
||||
<template> |
||||
<a :class="className" class="link--mallki" href="#"> |
||||
{{ text }} |
||||
<span :data-letters="text"/> |
||||
<span :data-letters="text"/> |
||||
</a> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
props: { |
||||
className: { |
||||
type: String, |
||||
default: '' |
||||
}, |
||||
text: { |
||||
type: String, |
||||
default: 'vue-element-admin' |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style> |
||||
/* Mallki */ |
||||
|
||||
.link--mallki { |
||||
font-weight: 800; |
||||
color: #4dd9d5; |
||||
font-family: 'Dosis', sans-serif; |
||||
-webkit-transition: color 0.5s 0.25s; |
||||
transition: color 0.5s 0.25s; |
||||
overflow: hidden; |
||||
position: relative; |
||||
display: inline-block; |
||||
line-height: 1; |
||||
outline: none; |
||||
text-decoration: none; |
||||
} |
||||
|
||||
.link--mallki:hover { |
||||
-webkit-transition: none; |
||||
transition: none; |
||||
color: transparent; |
||||
} |
||||
|
||||
.link--mallki::before { |
||||
content: ''; |
||||
width: 100%; |
||||
height: 6px; |
||||
margin: -3px 0 0 0; |
||||
background: #3888fa; |
||||
position: absolute; |
||||
left: 0; |
||||
top: 50%; |
||||
-webkit-transform: translate3d(-100%, 0, 0); |
||||
transform: translate3d(-100%, 0, 0); |
||||
-webkit-transition: -webkit-transform 0.4s; |
||||
transition: transform 0.4s; |
||||
-webkit-transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); |
||||
transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); |
||||
} |
||||
|
||||
.link--mallki:hover::before { |
||||
-webkit-transform: translate3d(100%, 0, 0); |
||||
transform: translate3d(100%, 0, 0); |
||||
} |
||||
|
||||
.link--mallki span { |
||||
position: absolute; |
||||
height: 50%; |
||||
width: 100%; |
||||
left: 0; |
||||
top: 0; |
||||
overflow: hidden; |
||||
} |
||||
|
||||
.link--mallki span::before { |
||||
content: attr(data-letters); |
||||
color: red; |
||||
position: absolute; |
||||
left: 0; |
||||
width: 100%; |
||||
color: #3888fa; |
||||
-webkit-transition: -webkit-transform 0.5s; |
||||
transition: transform 0.5s; |
||||
} |
||||
|
||||
.link--mallki span:nth-child(2) { |
||||
top: 50%; |
||||
} |
||||
|
||||
.link--mallki span:first-child::before { |
||||
top: 0; |
||||
-webkit-transform: translate3d(0, 100%, 0); |
||||
transform: translate3d(0, 100%, 0); |
||||
} |
||||
|
||||
.link--mallki span:nth-child(2)::before { |
||||
bottom: 0; |
||||
-webkit-transform: translate3d(0, -100%, 0); |
||||
transform: translate3d(0, -100%, 0); |
||||
} |
||||
|
||||
.link--mallki:hover span::before { |
||||
-webkit-transition-delay: 0.3s; |
||||
transition-delay: 0.3s; |
||||
-webkit-transform: translate3d(0, 0, 0); |
||||
transform: translate3d(0, 0, 0); |
||||
-webkit-transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1); |
||||
transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1); |
||||
} |
||||
</style> |
@ -0,0 +1,29 @@
|
||||
/** |
||||
* @Author: jianglei |
||||
* @Date: 2017-10-12 12:06:49 |
||||
*/ |
||||
'use strict' |
||||
import Vue from 'vue' |
||||
export default function treeToArray(data, expandAll, parent = null, level = null) { |
||||
let tmp = [] |
||||
Array.from(data).forEach(function(record) { |
||||
if (record._expanded === undefined) { |
||||
Vue.set(record, '_expanded', expandAll) |
||||
} |
||||
let _level = 1 |
||||
if (level !== undefined && level !== null) { |
||||
_level = level + 1 |
||||
} |
||||
Vue.set(record, '_level', _level) |
||||
// 如果有父元素
|
||||
if (parent) { |
||||
Vue.set(record, 'parent', parent) |
||||
} |
||||
tmp.push(record) |
||||
if (record.children && record.children.length > 0) { |
||||
const children = treeToArray(record.children, expandAll, record, _level) |
||||
tmp = tmp.concat(children) |
||||
} |
||||
}) |
||||
return tmp |
||||
} |
@ -0,0 +1,127 @@
|
||||
<template> |
||||
<el-table :data="formatData" :row-style="showRow" v-bind="$attrs"> |
||||
<el-table-column v-if="columns.length===0" width="150"> |
||||
<template slot-scope="scope"> |
||||
<span v-for="space in scope.row._level" :key="space" class="ms-tree-space"/> |
||||
<span v-if="iconShow(0,scope.row)" class="tree-ctrl" @click="toggleExpanded(scope.$index)"> |
||||
<i v-if="!scope.row._expanded" class="el-icon-plus"/> |
||||
<i v-else class="el-icon-minus"/> |
||||
</span> |
||||
{{ scope.$index }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column v-for="(column, index) in columns" v-else :key="column.value" :label="column.text" :width="column.width"> |
||||
<template slot-scope="scope"> |
||||
<!-- Todo --> |
||||
<!-- eslint-disable-next-line vue/no-confusing-v-for-v-if --> |
||||
<span v-for="space in scope.row._level" v-if="index === 0" :key="space" class="ms-tree-space"/> |
||||
<span v-if="iconShow(index,scope.row)" class="tree-ctrl" @click="toggleExpanded(scope.$index)"> |
||||
<i v-if="!scope.row._expanded" class="el-icon-plus"/> |
||||
<i v-else class="el-icon-minus"/> |
||||
</span> |
||||
{{ scope.row[column.value] }} |
||||
</template> |
||||
</el-table-column> |
||||
<slot/> |
||||
</el-table> |
||||
</template> |
||||
|
||||
<script> |
||||
/** |
||||
Auth: Lei.j1ang |
||||
Created: 2018/1/19-13:59 |
||||
*/ |
||||
import treeToArray from './eval' |
||||
export default { |
||||
name: 'TreeTable', |
||||
props: { |
||||
/* eslint-disable */ |
||||
data: { |
||||
type: [Array, Object], |
||||
required: true |
||||
}, |
||||
columns: { |
||||
type: Array, |
||||
default: () => [] |
||||
}, |
||||
evalFunc: Function, |
||||
evalArgs: Array, |
||||
expandAll: { |
||||
type: Boolean, |
||||
default: false |
||||
} |
||||
}, |
||||
computed: { |
||||
// 格式化数据源 |
||||
formatData: function() { |
||||
let tmp |
||||
if (!Array.isArray(this.data)) { |
||||
tmp = [this.data] |
||||
} else { |
||||
tmp = this.data |
||||
} |
||||
const func = this.evalFunc || treeToArray |
||||
const args = this.evalArgs ? Array.concat([tmp, this.expandAll], this.evalArgs) : [tmp, this.expandAll] |
||||
return func.apply(null, args) |
||||
} |
||||
}, |
||||
methods: { |
||||
showRow: function(row) { |
||||
const show = (row.row.parent ? (row.row.parent._expanded && row.row.parent._show) : true) |
||||
row.row._show = show |
||||
return show ? 'animation:treeTableShow 1s;-webkit-animation:treeTableShow 1s;' : 'display:none;' |
||||
}, |
||||
// 切换下级是否展开 |
||||
toggleExpanded: function(trIndex) { |
||||
const record = this.formatData[trIndex] |
||||
record._expanded = !record._expanded |
||||
}, |
||||
// 图标显示 |
||||
iconShow(index, record) { |
||||
return (index === 0 && record.children && record.children.length > 0) |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
<style rel="stylesheet/css"> |
||||
@keyframes treeTableShow { |
||||
from {opacity: 0;} |
||||
to {opacity: 1;} |
||||
} |
||||
@-webkit-keyframes treeTableShow { |
||||
from {opacity: 0;} |
||||
to {opacity: 1;} |
||||
} |
||||
</style> |
||||
|
||||
<style lang="scss" rel="stylesheet/scss" scoped> |
||||
$color-blue: #2196F3; |
||||
$space-width: 18px; |
||||
.ms-tree-space { |
||||
position: relative; |
||||
top: 1px; |
||||
display: inline-block; |
||||
font-style: normal; |
||||
font-weight: 400; |
||||
line-height: 1; |
||||
width: $space-width; |
||||
height: 14px; |
||||
&::before { |
||||
content: "" |
||||
} |
||||
} |
||||
.processContainer{ |
||||
width: 100%; |
||||
height: 100%; |
||||
} |
||||
table td { |
||||
line-height: 26px; |
||||
} |
||||
|
||||
.tree-ctrl{ |
||||
position: relative; |
||||
cursor: pointer; |
||||
color: $color-blue; |
||||
margin-left: -$space-width; |
||||
} |
||||
</style> |
@ -0,0 +1,89 @@
|
||||
## 写在前面 |
||||
此组件仅提供一个创建TreeTable的解决思路 |
||||
|
||||
## prop说明 |
||||
#### *data* |
||||
**必填** |
||||
|
||||
原始数据,要求是一个数组或者对象 |
||||
```javascript |
||||
[{ |
||||
key1: value1, |
||||
key2: value2, |
||||
children: [{ |
||||
key1: value1 |
||||
}, |
||||
{ |
||||
key1: value1 |
||||
}] |
||||
}, |
||||
{ |
||||
key1: value1 |
||||
}] |
||||
``` |
||||
或者 |
||||
```javascript |
||||
{ |
||||
key1: value1, |
||||
key2: value2, |
||||
children: [{ |
||||
key1: value1 |
||||
}, |
||||
{ |
||||
key1: value1 |
||||
}] |
||||
} |
||||
``` |
||||
|
||||
#### columns |
||||
列属性,要求是一个数组 |
||||
|
||||
1. text: 显示在表头的文字 |
||||
2. value: 对应data的key。treeTable将显示相应的value |
||||
3. width: 每列的宽度,为一个数字(可选) |
||||
|
||||
如果你想要每个字段都有自定义的样式或者嵌套其他组件,columns可不提供,直接像在el-table一样写即可,如果没有自定义内容,提供columns将更加的便捷方便 |
||||
|
||||
如果你有几个字段是需要自定义的,几个不需要,那么可以将不需要自定义的字段放入columns,将需要自定义的内容放入到slot中,详情见后文 |
||||
```javascript |
||||
[{ |
||||
value:string, |
||||
text:string, |
||||
width:number |
||||
},{ |
||||
value:string, |
||||
text:string, |
||||
width:number |
||||
}] |
||||
``` |
||||
|
||||
#### expandAll |
||||
是否默认全部展开,boolean值,默认为false |
||||
|
||||
#### evalFunc |
||||
解析函数,function,非必须 |
||||
|
||||
如果不提供,将使用默认的[evalFunc](./eval.js) |
||||
|
||||
如果提供了evalFunc,那么会用提供的evalFunc去解析data,并返回treeTable渲染所需要的值。如何编写一个evalFunc,请参考[*eval.js*](https://github.com/PanJiaChen/vue-element-admin/blob/master/src/components/TreeTable/eval.js)或[*customEval.js*](https://github.com/PanJiaChen/vue-element-admin/blob/master/src/views/table/treeTable/customEval.js) |
||||
|
||||
#### evalArgs |
||||
解析函数的参数,是一个数组 |
||||
|
||||
**请注意,自定义的解析函数参数第一个为this.data,第二个参数为, this.expandAll,你不需要在evalArgs填写。一定记住,这两个参数是强制性的,并且位置不可颠倒** *this.data为需要解析的数据,this.expandAll为是否默认展开* |
||||
|
||||
如你的解析函数需要的参数为`(this.data, this.expandAll,1,2,3,4)`,那么你只需要将`[1,2,3,4]`赋值给`evalArgs`就可以了 |
||||
|
||||
如果你的解析函数参数只有`(this.data, this.expandAll)`,那么就可以不用填写evalArgs了 |
||||
|
||||
具体可参考[*customEval.js*](https://github.com/PanJiaChen/vue-element-admin/blob/master/src/views/table/treeTable/customEval.js)的函数参数和[customTreeTable](https://github.com/PanJiaChen/vue-element-admin/blob/master/src/views/table/treeTable/customTreeTable.vue)的`evalArgs`属性值 |
||||
|
||||
## slot |
||||
这是一个自定义列的插槽。 |
||||
|
||||
默认情况下,treeTable只有一行行展示数据的功能。但是一般情况下,我们会要给行加上一个操作按钮或者根据当行数据展示不同的样式,这时我们就需要自定义列了。请参考[customTreeTable](https://github.com/PanJiaChen/vue-element-admin/blob/master/src/views/table/treeTable/customTreeTable.vue),[实例效果](https://panjiachen.github.io/vue-element-admin/#/table/tree-table) |
||||
|
||||
`slot`和`columns属性`可同时存在,columns里面的数据列会在slot自定义列的左边展示 |
||||
|
||||
## 其他 |
||||
如果有其他的需求,请参考[el-table](http://element-cn.eleme.io/#/en-US/component/table)的api自行修改index.vue |
@ -0,0 +1,81 @@
|
||||
<template> |
||||
<div class="json-editor"> |
||||
<textarea ref="textarea"/> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import CodeMirror from 'codemirror' |
||||
import 'codemirror/lib/codemirror.css' |
||||
// 替换主题这里需修改名称 |
||||
import 'codemirror/theme/idea.css' |
||||
require('codemirror/mode/yaml/yaml.js') |
||||
export default { |
||||
props: { |
||||
value: { |
||||
type: String, |
||||
required: true |
||||
}, |
||||
height: { |
||||
type: String, |
||||
required: true |
||||
} |
||||
}, |
||||
data() { |
||||
return { |
||||
editor: false |
||||
} |
||||
}, |
||||
watch: { |
||||
value(value) { |
||||
const editorValue = this.editor.getValue() |
||||
if (value !== editorValue) { |
||||
this.editor.setValue(this.value) |
||||
} |
||||
}, |
||||
height(value) { |
||||
this.editor.setSize('auto', this.height) |
||||
} |
||||
}, |
||||
mounted() { |
||||
this.editor = CodeMirror.fromTextArea(this.$refs.textarea, { |
||||
mode: 'text/x-yaml', |
||||
lineNumbers: true, |
||||
lint: true, |
||||
lineWrapping: true, |
||||
tabSize: 2, |
||||
cursorHeight: 0.9, |
||||
// 替换主题这里需修改名称 |
||||
theme: 'idea' |
||||
}) |
||||
this.editor.setSize('auto', this.height) |
||||
this.editor.setValue(this.value) |
||||
this.editor.on('change', cm => { |
||||
this.$emit('changed', cm.getValue()) |
||||
this.$emit('input', cm.getValue()) |
||||
}) |
||||
}, |
||||
methods: { |
||||
getValue() { |
||||
return this.editor.getValue() |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style scoped> |
||||
.json-editor{ |
||||
height: 100%; |
||||
margin-bottom: 10px; |
||||
} |
||||
.json-editor >>> .CodeMirror { |
||||
font-size: 13px; |
||||
overflow-y:auto; |
||||
font-weight:normal |
||||
} |
||||
.json-editor >>> .CodeMirror-scroll{ |
||||
} |
||||
.json-editor >>> .cm-s-rubyblue span.cm-string { |
||||
color: #F08047; |
||||
} |
||||
</style> |
@ -0,0 +1,30 @@
|
||||
<template> |
||||
<div v-loading="loading" :style="'height:'+ height"> |
||||
<iframe :src="src" frameborder="no" style="width: 100%;height: 100%" scrolling="auto"/> |
||||
</div> |
||||
</template> |
||||
<script> |
||||
export default { |
||||
props: { |
||||
src: { |
||||
type: String, |
||||
required: true |
||||
} |
||||
}, |
||||
data() { |
||||
return { |
||||
height: document.documentElement.clientHeight - 94.5 + 'px;', |
||||
loading: true |
||||
} |
||||
}, |
||||
mounted: function() { |
||||
setTimeout(() => { |
||||
this.loading = false |
||||
}, 230) |
||||
const that = this |
||||
window.onresize = function temp() { |
||||
that.height = document.documentElement.clientHeight - 94.5 + 'px;' |
||||
} |
||||
} |
||||
} |
||||
</script> |
@ -0,0 +1,94 @@
|
||||
<template> |
||||
<div> |
||||
<el-upload |
||||
:action="qiNiuUploadApi" |
||||
:headers="headers" |
||||
list-type="picture-card" |
||||
:on-preview="handlePictureCardPreview" |
||||
:on-remove="handleRemove" |
||||
:on-success="handleUploadSuccess" |
||||
:file-list="imageList" |
||||
:before-upload="beforeAvatarUpload"> |
||||
<i class="el-icon-plus"></i> |
||||
</el-upload> |
||||
<el-dialog :visible.sync="dialogVisible"> |
||||
<img width="100%" :src="dialogImageUrl" alt=""> |
||||
</el-dialog> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import { getToken } from '@/utils/auth' |
||||
import { mapGetters } from 'vuex' |
||||
export default { |
||||
data () { |
||||
return { |
||||
dialogImageUrl: '', |
||||
dialogVisible: false, |
||||
resourcesUrl: '', |
||||
headers: { |
||||
'Authorization': 'Bearer ' + getToken() |
||||
} |
||||
} |
||||
}, |
||||
props: { |
||||
value: { |
||||
default: '', |
||||
type: String |
||||
} |
||||
}, |
||||
computed: { |
||||
...mapGetters([ |
||||
'qiNiuUploadApi' |
||||
]), |
||||
imageList () { |
||||
let res = [] |
||||
if (this.value) { |
||||
let imageArray = this.value.split(',') |
||||
for (let i = 0; i < imageArray.length; i++) { |
||||
res.push({url: this.resourcesUrl + imageArray[i], response: imageArray[i]}) |
||||
} |
||||
} |
||||
this.$emit('input', this.value) |
||||
return res |
||||
} |
||||
}, |
||||
methods: { |
||||
// 图片上传 |
||||
handleUploadSuccess (response, file, fileList) { |
||||
console.log(file); |
||||
console.log(fileList) |
||||
let pics = fileList.map(file => { |
||||
if((typeof file.response) == 'object'){ |
||||
return file.response.data[0] |
||||
}else{ |
||||
return file.response |
||||
} |
||||
}).join(',') |
||||
console.log(pics) |
||||
this.$emit('input', pics) |
||||
}, |
||||
// 限制图片上传大小 |
||||
beforeAvatarUpload (file) { |
||||
const isLt2M = file.size / 1024 / 1024 < 2 |
||||
if (!isLt2M) { |
||||
this.$message.error('上传头像图片大小不能超过 2MB!') |
||||
} |
||||
return isLt2M |
||||
}, |
||||
handleRemove (file, fileList) { |
||||
let pics = fileList.map(file => { |
||||
return file.response |
||||
}).join(',') |
||||
this.$emit('input', pics) |
||||
}, |
||||
handlePictureCardPreview (file) { |
||||
this.dialogImageUrl = file.url |
||||
this.dialogVisible = true |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style lang="scss"> |
||||
</style> |
@ -0,0 +1,13 @@
|
||||
import permission from './permission' |
||||
|
||||
const install = function(Vue) { |
||||
Vue.directive('permission', permission) |
||||
} |
||||
|
||||
if (window.Vue) { |
||||
window['permission'] = permission |
||||
Vue.use(install); // eslint-disable-line
|
||||
} |
||||
|
||||
permission.install = install |
||||
export default permission |
@ -0,0 +1,22 @@
|
||||
import store from '@/store' |
||||
|
||||
export default { |
||||
inserted(el, binding, vnode) { |
||||
const { value } = binding |
||||
const roles = store.getters && store.getters.roles |
||||
|
||||
if (value && value instanceof Array && value.length > 0) { |
||||
const permissionRoles = value |
||||
|
||||
const hasPermission = roles.some(role => { |
||||
return permissionRoles.includes(role) |
||||
}) |
||||
|
||||
if (!hasPermission) { |
||||
el.parentNode && el.parentNode.removeChild(el) |
||||
} |
||||
} else { |
||||
throw new Error(`need roles! Like v-permission="['admin','editor']"`) |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,82 @@
|
||||
<template> |
||||
<div> |
||||
<el-upload |
||||
class="pic-uploader-component" |
||||
:action="qiNiuUploadApi" |
||||
:headers="headers" |
||||
:show-file-list="false" |
||||
:on-success="handleUploadSuccess" |
||||
:before-upload="beforeAvatarUpload"> |
||||
<img v-if="value" :src="resourcesUrl + value" class="pic"> |
||||
<i v-else class="el-icon-plus pic-uploader-icon"></i> |
||||
</el-upload> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import { getToken } from '@/utils/auth' |
||||
import { mapGetters } from 'vuex' |
||||
export default { |
||||
data () { |
||||
return { |
||||
resourcesUrl: '', |
||||
headers: { |
||||
'Authorization': 'Bearer ' + getToken() |
||||
} |
||||
} |
||||
}, |
||||
computed: { |
||||
...mapGetters([ |
||||
'qiNiuUploadApi' |
||||
]) |
||||
}, |
||||
props: { |
||||
value: { |
||||
default: '', |
||||
type: String |
||||
} |
||||
}, |
||||
methods: { |
||||
// 图片上传 |
||||
handleUploadSuccess(response, file, fileList) { |
||||
console.log(file) |
||||
this.$emit('input', file.response.data[0]) |
||||
}, |
||||
// 限制图片上传大小 |
||||
beforeAvatarUpload(file) { |
||||
const isLt2M = file.size / 1024 / 1024 < 2 |
||||
if (!isLt2M) { |
||||
this.$message.error('上传头像图片大小不能超过 2MB!') |
||||
} |
||||
return isLt2M |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.pic-uploader-component .el-upload { |
||||
border: 1px dashed #d9d9d9; |
||||
border-radius: 6px; |
||||
cursor: pointer; |
||||
position: relative; |
||||
overflow: hidden; |
||||
.pic-uploader-icon { |
||||
font-size: 28px; |
||||
color: #8c939d; |
||||
width: 100%; |
||||
height: 40px; |
||||
//line-height: 178px; |
||||
text-align: center; |
||||
} |
||||
.pic { |
||||
width: 100%; |
||||
height: 40px; |
||||
display: block; |
||||
} |
||||
} |
||||
.pic-uploader-component .el-upload:hover { |
||||
border-color: #409EFF; |
||||
} |
||||
|
||||
</style> |
@ -0,0 +1,82 @@
|
||||
<template> |
||||
<div> |
||||
<el-upload |
||||
class="pic-uploader-component" |
||||
:action="qiNiuUploadApi" |
||||
:headers="headers" |
||||
:show-file-list="false" |
||||
:on-success="handleUploadSuccess" |
||||
:before-upload="beforeAvatarUpload"> |
||||
<img v-if="value" :src="resourcesUrl + value" class="pic"> |
||||
<i v-else class="el-icon-plus pic-uploader-icon"></i> |
||||
</el-upload> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import { getToken } from '@/utils/auth' |
||||
import { mapGetters } from 'vuex' |
||||
export default { |
||||
data () { |
||||
return { |
||||
resourcesUrl: '', |
||||
headers: { |
||||
'Authorization': 'Bearer ' + getToken() |
||||
} |
||||
} |
||||
}, |
||||
computed: { |
||||
...mapGetters([ |
||||
'qiNiuUploadApi' |
||||
]) |
||||
}, |
||||
props: { |
||||
value: { |
||||
default: '', |
||||
type: String |
||||
} |
||||
}, |
||||
methods: { |
||||
// 图片上传 |
||||
handleUploadSuccess(response, file, fileList) { |
||||
console.log(file) |
||||
this.$emit('input', file.response.data[0]) |
||||
}, |
||||
// 限制图片上传大小 |
||||
beforeAvatarUpload(file) { |
||||
const isLt2M = file.size / 1024 / 1024 < 2 |
||||
if (!isLt2M) { |
||||
this.$message.error('上传头像图片大小不能超过 2MB!') |
||||
} |
||||
return isLt2M |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style lang="scss"> |
||||
.pic-uploader-component .el-upload { |
||||
border: 1px dashed #d9d9d9; |
||||
border-radius: 6px; |
||||
cursor: pointer; |
||||
position: relative; |
||||
overflow: hidden; |
||||
.pic-uploader-icon { |
||||
font-size: 28px; |
||||
color: #8c939d; |
||||
width: 178px; |
||||
height: 178px; |
||||
line-height: 178px; |
||||
text-align: center; |
||||
} |
||||
.pic { |
||||
width: 178px; |
||||
height: 178px; |
||||
display: block; |
||||
} |
||||
} |
||||
.pic-uploader-component .el-upload:hover { |
||||
border-color: #409EFF; |
||||
} |
||||
|
||||
</style> |
@ -0,0 +1,82 @@
|
||||
<!--<template>--> |
||||
<!--<div>--> |
||||
<!--<el-upload--> |
||||
<!--class="pic-uploader-component"--> |
||||
<!--:action="imagesUploadApi"--> |
||||
<!--:headers="headers"--> |
||||
<!--:show-file-list="false"--> |
||||
<!--:on-success="handleUploadSuccess"--> |
||||
<!--:before-upload="beforeAvatarUpload">--> |
||||
<!--<img v-if="value" :src="resourcesUrl + value" class="pic">--> |
||||
<!--<i v-else class="el-icon-plus pic-uploader-icon"></i>--> |
||||
<!--</el-upload>--> |
||||
<!--</div>--> |
||||
<!--</template>--> |
||||
|
||||
<!--<script>--> |
||||
<!--import { getToken } from '@/utils/auth'--> |
||||
<!--import { mapGetters } from 'vuex'--> |
||||
<!--export default {--> |
||||
<!--data () {--> |
||||
<!--return {--> |
||||
<!--resourcesUrl: '',--> |
||||
<!--headers: {--> |
||||
<!--'Authorization': 'Bearer ' + getToken()--> |
||||
<!--}--> |
||||
<!--}--> |
||||
<!--},--> |
||||
<!--computed: {--> |
||||
<!--...mapGetters([--> |
||||
<!--'imagesUploadApi'--> |
||||
<!--])--> |
||||
<!--},--> |
||||
<!--props: {--> |
||||
<!--value: {--> |
||||
<!--default: '',--> |
||||
<!--type: String--> |
||||
<!--}--> |
||||
<!--},--> |
||||
<!--methods: {--> |
||||
<!--// 图片上传--> |
||||
<!--handleUploadSuccess(response, file, fileList) {--> |
||||
<!--console.log(file)--> |
||||
<!--this.$emit('input', file.response.data[0])--> |
||||
<!--},--> |
||||
<!--// 限制图片上传大小--> |
||||
<!--beforeAvatarUpload(file) {--> |
||||
<!--const isLt2M = file.size / 1024 / 1024 < 2--> |
||||
<!--if (!isLt2M) {--> |
||||
<!--this.$message.error('上传头像图片大小不能超过 2MB!')--> |
||||
<!--}--> |
||||
<!--return isLt2M--> |
||||
<!--}--> |
||||
<!--}--> |
||||
<!--}--> |
||||
<!--</script>--> |
||||
|
||||
<!--<style lang="scss">--> |
||||
<!--.pic-uploader-component .el-upload {--> |
||||
<!--border: 1px dashed #d9d9d9;--> |
||||
<!--border-radius: 6px;--> |
||||
<!--cursor: pointer;--> |
||||
<!--position: relative;--> |
||||
<!--overflow: hidden;--> |
||||
<!--.pic-uploader-icon {--> |
||||
<!--font-size: 28px;--> |
||||
<!--color: #8c939d;--> |
||||
<!--width: 100%;--> |
||||
<!--height: 40px;--> |
||||
<!--//line-height: 178px;--> |
||||
<!--text-align: center;--> |
||||
<!--}--> |
||||
<!--.pic {--> |
||||
<!--width: 100%;--> |
||||
<!--height: 40px;--> |
||||
<!--display: block;--> |
||||
<!--}--> |
||||
<!--}--> |
||||
<!--.pic-uploader-component .el-upload:hover {--> |
||||
<!--border-color: #409EFF;--> |
||||
<!--}--> |
||||
|
||||
<!--</style>--> |
@ -0,0 +1,65 @@
|
||||
/** |
||||
* @description 系统全局配置 |
||||
*/ |
||||
export default { |
||||
/** |
||||
* @description 记住密码状态下的token在Cookie中存储的天数,默认1天 |
||||
*/ |
||||
tokenCookieExpires: 1, |
||||
/** |
||||
* @description 记住密码状态下的密码在Cookie中存储的天数,默认1天 |
||||
*/ |
||||
passCookieExpires: 1, |
||||
/** |
||||
* @description 此处修改网站名称 |
||||
*/ |
||||
webName: 'Yshop', |
||||
/** |
||||
* @description 是否只保持一个子菜单的展开 |
||||
*/ |
||||
uniqueOpened: true, |
||||
/** |
||||
* @description token key |
||||
*/ |
||||
TokenKey: 'Yshop-TOEKN', |
||||
|
||||
/** |
||||
* @description 请求超时时间,毫秒(默认2分钟) |
||||
*/ |
||||
timeout: 1200000, |
||||
|
||||
/** |
||||
* @description 是否显示 tagsView |
||||
*/ |
||||
tagsView: true, |
||||
|
||||
/** |
||||
* @description 固定头部 |
||||
*/ |
||||
fixedHeader: true, |
||||
|
||||
/** |
||||
* @description 是否显示logo |
||||
*/ |
||||
sidebarLogo: true, |
||||
|
||||
/** |
||||
* 是否显示设置的悬浮按钮 |
||||
*/ |
||||
settingBtn: false, |
||||
|
||||
/** |
||||
* 是否显示设置的底部信息 |
||||
*/ |
||||
showFooter: true, |
||||
|
||||
/** |
||||
* 底部文字,支持html语法 |
||||
*/ |
||||
footerTxt: '© 2019 YSHOP <a href="http://www.apache.org/licenses/LICENSE-2.0" target="_blank">Apache License 2.0</a>', |
||||
|
||||
/** |
||||
* 备案号 |
||||
*/ |
||||
caseNumber: '豫ICP备17049587号' |
||||
} |
@ -0,0 +1,9 @@
|
||||
import Vue from 'vue' |
||||
import SvgIcon from '@/components/SvgIcon' // svg组件
|
||||
|
||||
// register globally
|
||||
Vue.component('svg-icon', SvgIcon) |
||||
|
||||
const requireAll = requireContext => requireContext.keys().map(requireContext) |
||||
const req = require.context('./svg', false, /\.svg$/) |
||||
requireAll(req) |
After Width: | Height: | Size: 6.2 KiB |