├── .gitignore ├── LICENSE ├── README.md ├── images ├── login.png ├── main.png ├── rightList.png ├── roleList.png └── userList.png ├── shop.sql ├── springboot ├── LICENSE ├── README.md ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── wxy97 │ │ │ └── shop │ │ │ ├── SpringbootShopApplication.java │ │ │ ├── config │ │ │ ├── CorsConfig.java │ │ │ ├── IntercepterConfig.java │ │ │ ├── RedisConfig.java │ │ │ ├── SwaggerConfig.java │ │ │ └── TokenInterceptor.java │ │ │ ├── controller │ │ │ ├── LoginController.java │ │ │ ├── MenuController.java │ │ │ ├── RightsController.java │ │ │ ├── RoleController.java │ │ │ └── UserControler.java │ │ │ ├── dao │ │ │ ├── MenuRepository.java │ │ │ ├── RightsJpaRepostory.java │ │ │ ├── RightsRepostory.java │ │ │ ├── RoleRepository.java │ │ │ ├── RoleRightsRepository.java │ │ │ └── UserRepository.java │ │ │ ├── pojo │ │ │ ├── Menu.java │ │ │ ├── Rights.java │ │ │ ├── Role.java │ │ │ ├── RoleRights.java │ │ │ └── User.java │ │ │ ├── result │ │ │ ├── Result.java │ │ │ ├── ResultFactory.java │ │ │ └── StatusCode.java │ │ │ ├── service │ │ │ ├── MenuService.java │ │ │ ├── MenuServiceImpl.java │ │ │ ├── RightsService.java │ │ │ ├── RightsServiceImpl.java │ │ │ ├── RoleRihtsService.java │ │ │ ├── RoleRihtsServiceImpl.java │ │ │ ├── RoleService.java │ │ │ ├── RoleServiceImpl.java │ │ │ ├── UserService.java │ │ │ └── UserServiceImpl.java │ │ │ ├── shiro │ │ │ ├── MyRealm.java │ │ │ └── ShiroConfig.java │ │ │ └── util │ │ │ ├── JWTUtil.java │ │ │ ├── JsonUtils.java │ │ │ ├── RedisUtil.java │ │ │ └── TreeUtil.java │ └── resources │ │ └── application.yml │ └── test │ └── java │ └── com │ └── wxy97 │ └── shop │ └── SpringbootShopApplicationTests.java └── vue ├── .browserslistrc ├── .editorconfig ├── .eslintrc.js ├── .gitignore ├── README.md ├── babel.config.js ├── package-lock.json ├── package.json ├── public ├── favicon.ico └── index.html └── src ├── App.vue ├── assets ├── css │ └── global.css ├── fonts │ ├── demo.css │ ├── demo_index.html │ ├── iconfont.css │ ├── iconfont.eot │ ├── iconfont.js │ ├── iconfont.json │ ├── iconfont.svg │ ├── iconfont.ttf │ ├── iconfont.woff │ └── iconfont.woff2 └── logo.png ├── components ├── Login.vue ├── Main.vue ├── Welcome.vue ├── goods │ ├── Add.vue │ └── List.vue ├── power │ ├── Rights.vue │ └── Roles.vue └── user │ └── Users.vue ├── main.js ├── plugins └── element.js └── router └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | 23 | 24 | ####springboot 25 | HELP.md 26 | target/ 27 | !.mvn/wrapper/maven-wrapper.jar 28 | !**/src/main/** 29 | !**/src/test/** 30 | 31 | ### STS ### 32 | .apt_generated 33 | .classpath 34 | .factorypath 35 | .project 36 | .settings 37 | .springBeans 38 | .sts4-cache 39 | 40 | ### IntelliJ IDEA ### 41 | .idea 42 | *.iws 43 | *.iml 44 | *.ipr 45 | 46 | ### NetBeans ### 47 | /nbproject/private/ 48 | /nbbuild/ 49 | /dist/ 50 | /nbdist/ 51 | /.nb-gradle/ 52 | build/ 53 | 54 | ### VS Code ### 55 | .vscode/ 56 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![head](https://socialify.git.ci/wxyShine/springboot_vue_shop/png?description=1&forks=1&issues=0&pulls=0) 2 | ## 开发环境 3 | > win10 4 | > Mysql5.5 5 | > idea 6 | > springBoot2.2.2 7 | ## 涉及到的技术 8 | ### 前端采用技术 9 | > 1.Vue 10 | > 2.ElementUI 11 | > 3.axios 12 | ### 后端采用技术 13 | > 1.Spring Boot 14 | > 2.Spring Data + JPA 15 | > 3.MySQL 16 | > 4.Hikari 17 | > 5.Shiro 18 | > 6.JWT 19 | > 7.Redis 20 | 21 | ### 登录界面 22 | ![login](./images/login.png) 23 | 24 | ### 后台主界面 25 | ![main](./images/main.png) 26 | 27 | ### 用户管理模块 28 | #### 用户列表 29 | ![user](./images/userList.png) 30 | 31 | ### 权限理模块 32 | #### 角色列表 33 | ![user](./images/roleList.png) 34 | 35 | #### 权限列表 36 | ![user](./images/rightList.png) 37 | 38 | #### 目前处于开发中状态... 39 | 40 | #### 项目码云地址 41 | > 后端 https://gitee.com/wxyShine/springboot_shop.git 42 | > 前端 https://gitee.com/wxyShine/vue_shop.git 43 | -------------------------------------------------------------------------------- /images/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxyShine/springboot_vue_shop/51a84521b42c18b3053ad8b848eb9443fa0f3afc/images/login.png -------------------------------------------------------------------------------- /images/main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxyShine/springboot_vue_shop/51a84521b42c18b3053ad8b848eb9443fa0f3afc/images/main.png -------------------------------------------------------------------------------- /images/rightList.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxyShine/springboot_vue_shop/51a84521b42c18b3053ad8b848eb9443fa0f3afc/images/rightList.png -------------------------------------------------------------------------------- /images/roleList.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxyShine/springboot_vue_shop/51a84521b42c18b3053ad8b848eb9443fa0f3afc/images/roleList.png -------------------------------------------------------------------------------- /images/userList.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxyShine/springboot_vue_shop/51a84521b42c18b3053ad8b848eb9443fa0f3afc/images/userList.png -------------------------------------------------------------------------------- /shop.sql: -------------------------------------------------------------------------------- 1 | -- phpMyAdmin SQL Dump 2 | -- version 4.4.15.10 3 | -- https://www.phpmyadmin.net 4 | -- 5 | -- Host: localhost 6 | -- Generation Time: 2020-01-21 17:32:16 7 | -- 服务器版本: 5.5.57-log 8 | -- PHP Version: 5.4.45 9 | 10 | SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; 11 | SET time_zone = "+00:00"; 12 | 13 | 14 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 15 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 16 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 17 | /*!40101 SET NAMES utf8mb4 */; 18 | 19 | -- 20 | -- Database: `shop` 21 | -- 22 | 23 | -- -------------------------------------------------------- 24 | 25 | -- 26 | -- 表的结构 `s_menu` 27 | -- 28 | 29 | CREATE TABLE IF NOT EXISTS `s_menu` ( 30 | `id` int(11) NOT NULL, 31 | `name` varchar(255) DEFAULT NULL, 32 | `parent_id` int(11) DEFAULT '0', 33 | `path` varchar(255) DEFAULT NULL, 34 | `queue` int(11) DEFAULT '0' 35 | ) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4; 36 | 37 | -- 38 | -- 转存表中的数据 `s_menu` 39 | -- 40 | 41 | INSERT INTO `s_menu` (`id`, `name`, `parent_id`, `path`, `queue`) VALUES 42 | (1, '用户管理', 0, 'users', 1), 43 | (2, '用户列表', 1, 'users', 0), 44 | (3, '权限管理', 0, 'rights', 2), 45 | (4, '角色管理', 3, 'roles', 0), 46 | (5, '权限列表', 3, 'rights', 0), 47 | (6, '商品管理', 0, 'goods', 3), 48 | (7, '商品列表', 6, 'goods', 0), 49 | (8, '分类参数', 6, 'params', 0), 50 | (9, '商品分类', 6, 'categories', 0), 51 | (10, '订单管理', 0, 'orders', 4), 52 | (11, '订单列表', 10, 'orders', 0), 53 | (12, '数据统计', 0, 'reports', 5), 54 | (13, '统计报表', 12, 'reports', 0); 55 | 56 | -- -------------------------------------------------------- 57 | 58 | -- 59 | -- 表的结构 `s_rights` 60 | -- 61 | 62 | CREATE TABLE IF NOT EXISTS `s_rights` ( 63 | `id` int(11) NOT NULL, 64 | `auth_name` varchar(255) DEFAULT NULL, 65 | `level` varchar(255) DEFAULT NULL, 66 | `path` varchar(255) DEFAULT NULL, 67 | `pid` int(11) DEFAULT NULL 68 | ) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8mb4; 69 | 70 | -- 71 | -- 转存表中的数据 `s_rights` 72 | -- 73 | 74 | INSERT INTO `s_rights` (`id`, `auth_name`, `level`, `path`, `pid`) VALUES 75 | (1, '商品管理', '0', 'goods', 0), 76 | (2, '订单管理', '0', 'orders', 0), 77 | (3, '权限管理', '0', 'rights', 0), 78 | (4, '用户管理', '0', 'users', 0), 79 | (5, '数据统计', '0', 'reports', 0), 80 | (6, '商品列表', '1', 'goods', 1), 81 | (7, '分类参数', '1', 'params', 1), 82 | (8, '商品分类', '1', 'categories', 1), 83 | (9, '添加商品', '2', 'goods', 6), 84 | (10, '商品修改', '2', 'goods', 6), 85 | (11, '商品删除', '2', 'goods', 6), 86 | (12, '更新商品图片', '2', 'goods', 6), 87 | (13, '更新商品属性', '2', 'goods', 6), 88 | (14, '更新商品状态', '2', 'goods', 6), 89 | (15, '获取商品详情', '2', 'goods', 6), 90 | (16, '获取参数列表', '2', 'params', 7), 91 | (17, '创建商品参数', '2', 'params', 7), 92 | (18, '删除商品参数', '2', 'params', 7), 93 | (19, '添加分类', '2', 'categories', 8), 94 | (20, '删除分类', '2', 'categories', 8), 95 | (21, '获取分类详情', '2', 'categories', 8); 96 | 97 | -- -------------------------------------------------------- 98 | 99 | -- 100 | -- 表的结构 `s_role` 101 | -- 102 | 103 | CREATE TABLE IF NOT EXISTS `s_role` ( 104 | `id` int(11) NOT NULL, 105 | `d_esc` varchar(255) DEFAULT NULL, 106 | `name` varchar(255) DEFAULT NULL 107 | ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4; 108 | 109 | -- 110 | -- 转存表中的数据 `s_role` 111 | -- 112 | 113 | INSERT INTO `s_role` (`id`, `d_esc`, `name`) VALUES 114 | (1, '管理员', '管理员'), 115 | (2, '普通', '普通用户'); 116 | 117 | -- -------------------------------------------------------- 118 | 119 | -- 120 | -- 表的结构 `s_role_right` 121 | -- 122 | 123 | CREATE TABLE IF NOT EXISTS `s_role_right` ( 124 | `id` int(11) NOT NULL, 125 | `role_id` int(11) NOT NULL, 126 | `right_id` int(11) NOT NULL 127 | ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4; 128 | 129 | -- 130 | -- 转存表中的数据 `s_role_right` 131 | -- 132 | 133 | INSERT INTO `s_role_right` (`id`, `role_id`, `right_id`) VALUES 134 | (1, 1, 1), 135 | (2, 1, 6), 136 | (3, 1, 7), 137 | (4, 2, 1); 138 | 139 | -- -------------------------------------------------------- 140 | 141 | -- 142 | -- 表的结构 `s_user` 143 | -- 144 | 145 | CREATE TABLE IF NOT EXISTS `s_user` ( 146 | `id` int(11) NOT NULL, 147 | `email` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, 148 | `mg_state` bit(1) NOT NULL, 149 | `name` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, 150 | `password` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, 151 | `tel` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, 152 | `username` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, 153 | `rid` int(11) DEFAULT NULL 154 | ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; 155 | 156 | -- 157 | -- 转存表中的数据 `s_user` 158 | -- 159 | 160 | INSERT INTO `s_user` (`id`, `email`, `mg_state`, `name`, `password`, `tel`, `username`, `rid`) VALUES 161 | (1, 'wxyrrcj@gmail.com', b'0', '若如初见', '3579c5bed0f11113ebfbbcfb9371eeb5', '1566666666', 'wxy', NULL), 162 | (3, '11aa@qq.com', b'0', '啊啊', '啊 啊啊啊1', ' 啊啊', '啊啊', NULL), 163 | (4, '123@qq.com', b'0', '123', '123', '123', '添加测试', NULL); 164 | 165 | -- 166 | -- Indexes for dumped tables 167 | -- 168 | 169 | -- 170 | -- Indexes for table `s_menu` 171 | -- 172 | ALTER TABLE `s_menu` 173 | ADD PRIMARY KEY (`id`); 174 | 175 | -- 176 | -- Indexes for table `s_rights` 177 | -- 178 | ALTER TABLE `s_rights` 179 | ADD PRIMARY KEY (`id`); 180 | 181 | -- 182 | -- Indexes for table `s_role` 183 | -- 184 | ALTER TABLE `s_role` 185 | ADD PRIMARY KEY (`id`); 186 | 187 | -- 188 | -- Indexes for table `s_role_right` 189 | -- 190 | ALTER TABLE `s_role_right` 191 | ADD PRIMARY KEY (`id`), 192 | ADD KEY `FK33j8vu3m6ps0gdq1yofaeaol7` (`right_id`), 193 | ADD KEY `FKopajvv2w93mnwwwerf72w8h6m` (`role_id`); 194 | 195 | -- 196 | -- Indexes for table `s_user` 197 | -- 198 | ALTER TABLE `s_user` 199 | ADD PRIMARY KEY (`id`), 200 | ADD KEY `FKb66umb8i6jord32jk70vmbsqd` (`rid`); 201 | 202 | -- 203 | -- AUTO_INCREMENT for dumped tables 204 | -- 205 | 206 | -- 207 | -- AUTO_INCREMENT for table `s_menu` 208 | -- 209 | ALTER TABLE `s_menu` 210 | MODIFY `id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=14; 211 | -- 212 | -- AUTO_INCREMENT for table `s_rights` 213 | -- 214 | ALTER TABLE `s_rights` 215 | MODIFY `id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=22; 216 | -- 217 | -- AUTO_INCREMENT for table `s_role` 218 | -- 219 | ALTER TABLE `s_role` 220 | MODIFY `id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=3; 221 | -- 222 | -- AUTO_INCREMENT for table `s_role_right` 223 | -- 224 | ALTER TABLE `s_role_right` 225 | MODIFY `id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=5; 226 | -- 227 | -- AUTO_INCREMENT for table `s_user` 228 | -- 229 | ALTER TABLE `s_user` 230 | MODIFY `id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=5; 231 | -- 232 | -- 限制导出的表 233 | -- 234 | 235 | -- 236 | -- 限制表 `s_role_right` 237 | -- 238 | ALTER TABLE `s_role_right` 239 | ADD CONSTRAINT `FK33j8vu3m6ps0gdq1yofaeaol7` FOREIGN KEY (`right_id`) REFERENCES `s_rights` (`id`), 240 | ADD CONSTRAINT `FKopajvv2w93mnwwwerf72w8h6m` FOREIGN KEY (`role_id`) REFERENCES `s_role` (`id`); 241 | 242 | -- 243 | -- 限制表 `s_user` 244 | -- 245 | ALTER TABLE `s_user` 246 | ADD CONSTRAINT `FKb66umb8i6jord32jk70vmbsqd` FOREIGN KEY (`rid`) REFERENCES `s_role` (`id`); 247 | 248 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 249 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 250 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 251 | -------------------------------------------------------------------------------- /springboot/LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /springboot/README.md: -------------------------------------------------------------------------------- 1 | ### Vue+Spring Boot 开发的前后端分离入门项目 -------------------------------------------------------------------------------- /springboot/mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # https://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven2 Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Mingw, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | fi 118 | 119 | if [ -z "$JAVA_HOME" ]; then 120 | javaExecutable="`which javac`" 121 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 122 | # readlink(1) is not available as standard on Solaris 10. 123 | readLink=`which readlink` 124 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 125 | if $darwin ; then 126 | javaHome="`dirname \"$javaExecutable\"`" 127 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 128 | else 129 | javaExecutable="`readlink -f \"$javaExecutable\"`" 130 | fi 131 | javaHome="`dirname \"$javaExecutable\"`" 132 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 133 | JAVA_HOME="$javaHome" 134 | export JAVA_HOME 135 | fi 136 | fi 137 | fi 138 | 139 | if [ -z "$JAVACMD" ] ; then 140 | if [ -n "$JAVA_HOME" ] ; then 141 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 142 | # IBM's JDK on AIX uses strange locations for the executables 143 | JAVACMD="$JAVA_HOME/jre/sh/java" 144 | else 145 | JAVACMD="$JAVA_HOME/bin/java" 146 | fi 147 | else 148 | JAVACMD="`which java`" 149 | fi 150 | fi 151 | 152 | if [ ! -x "$JAVACMD" ] ; then 153 | echo "Error: JAVA_HOME is not defined correctly." >&2 154 | echo " We cannot execute $JAVACMD" >&2 155 | exit 1 156 | fi 157 | 158 | if [ -z "$JAVA_HOME" ] ; then 159 | echo "Warning: JAVA_HOME environment variable is not set." 160 | fi 161 | 162 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 163 | 164 | # traverses directory structure from process work directory to filesystem root 165 | # first directory with .mvn subdirectory is considered project base directory 166 | find_maven_basedir() { 167 | 168 | if [ -z "$1" ] 169 | then 170 | echo "Path not specified to find_maven_basedir" 171 | return 1 172 | fi 173 | 174 | basedir="$1" 175 | wdir="$1" 176 | while [ "$wdir" != '/' ] ; do 177 | if [ -d "$wdir"/.mvn ] ; then 178 | basedir=$wdir 179 | break 180 | fi 181 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 182 | if [ -d "${wdir}" ]; then 183 | wdir=`cd "$wdir/.."; pwd` 184 | fi 185 | # end of workaround 186 | done 187 | echo "${basedir}" 188 | } 189 | 190 | # concatenates all lines of a file 191 | concat_lines() { 192 | if [ -f "$1" ]; then 193 | echo "$(tr -s '\n' ' ' < "$1")" 194 | fi 195 | } 196 | 197 | BASE_DIR=`find_maven_basedir "$(pwd)"` 198 | if [ -z "$BASE_DIR" ]; then 199 | exit 1; 200 | fi 201 | 202 | ########################################################################################## 203 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 204 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 205 | ########################################################################################## 206 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 207 | if [ "$MVNW_VERBOSE" = true ]; then 208 | echo "Found .mvn/wrapper/maven-wrapper.jar" 209 | fi 210 | else 211 | if [ "$MVNW_VERBOSE" = true ]; then 212 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 213 | fi 214 | if [ -n "$MVNW_REPOURL" ]; then 215 | jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" 216 | else 217 | jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" 218 | fi 219 | while IFS="=" read key value; do 220 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 221 | esac 222 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 223 | if [ "$MVNW_VERBOSE" = true ]; then 224 | echo "Downloading from: $jarUrl" 225 | fi 226 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 227 | if $cygwin; then 228 | wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` 229 | fi 230 | 231 | if command -v wget > /dev/null; then 232 | if [ "$MVNW_VERBOSE" = true ]; then 233 | echo "Found wget ... using wget" 234 | fi 235 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 236 | wget "$jarUrl" -O "$wrapperJarPath" 237 | else 238 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" 239 | fi 240 | elif command -v curl > /dev/null; then 241 | if [ "$MVNW_VERBOSE" = true ]; then 242 | echo "Found curl ... using curl" 243 | fi 244 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 245 | curl -o "$wrapperJarPath" "$jarUrl" -f 246 | else 247 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f 248 | fi 249 | 250 | else 251 | if [ "$MVNW_VERBOSE" = true ]; then 252 | echo "Falling back to using Java to download" 253 | fi 254 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 255 | # For Cygwin, switch paths to Windows format before running javac 256 | if $cygwin; then 257 | javaClass=`cygpath --path --windows "$javaClass"` 258 | fi 259 | if [ -e "$javaClass" ]; then 260 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 261 | if [ "$MVNW_VERBOSE" = true ]; then 262 | echo " - Compiling MavenWrapperDownloader.java ..." 263 | fi 264 | # Compiling the Java class 265 | ("$JAVA_HOME/bin/javac" "$javaClass") 266 | fi 267 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 268 | # Running the downloader 269 | if [ "$MVNW_VERBOSE" = true ]; then 270 | echo " - Running MavenWrapperDownloader.java ..." 271 | fi 272 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 273 | fi 274 | fi 275 | fi 276 | fi 277 | ########################################################################################## 278 | # End of extension 279 | ########################################################################################## 280 | 281 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 282 | if [ "$MVNW_VERBOSE" = true ]; then 283 | echo $MAVEN_PROJECTBASEDIR 284 | fi 285 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 286 | 287 | # For Cygwin, switch paths to Windows format before running java 288 | if $cygwin; then 289 | [ -n "$M2_HOME" ] && 290 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 291 | [ -n "$JAVA_HOME" ] && 292 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 293 | [ -n "$CLASSPATH" ] && 294 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 295 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 296 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 297 | fi 298 | 299 | # Provide a "standardized" way to retrieve the CLI args that will 300 | # work with both Windows and non-Windows executions. 301 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 302 | export MAVEN_CMD_LINE_ARGS 303 | 304 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 305 | 306 | exec "$JAVACMD" \ 307 | $MAVEN_OPTS \ 308 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 309 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 310 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 311 | -------------------------------------------------------------------------------- /springboot/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM https://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" 124 | 125 | FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 127 | ) 128 | 129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 131 | if exist %WRAPPER_JAR% ( 132 | if "%MVNW_VERBOSE%" == "true" ( 133 | echo Found %WRAPPER_JAR% 134 | ) 135 | ) else ( 136 | if not "%MVNW_REPOURL%" == "" ( 137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" 138 | ) 139 | if "%MVNW_VERBOSE%" == "true" ( 140 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 141 | echo Downloading from: %DOWNLOAD_URL% 142 | ) 143 | 144 | powershell -Command "&{"^ 145 | "$webclient = new-object System.Net.WebClient;"^ 146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ 147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ 148 | "}"^ 149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ 150 | "}" 151 | if "%MVNW_VERBOSE%" == "true" ( 152 | echo Finished downloading %WRAPPER_JAR% 153 | ) 154 | ) 155 | @REM End of extension 156 | 157 | @REM Provide a "standardized" way to retrieve the CLI args that will 158 | @REM work with both Windows and non-Windows executions. 159 | set MAVEN_CMD_LINE_ARGS=%* 160 | 161 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 162 | if ERRORLEVEL 1 goto error 163 | goto end 164 | 165 | :error 166 | set ERROR_CODE=1 167 | 168 | :end 169 | @endlocal & set ERROR_CODE=%ERROR_CODE% 170 | 171 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 172 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 173 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 174 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 175 | :skipRcPost 176 | 177 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 178 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 179 | 180 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 181 | 182 | exit /B %ERROR_CODE% 183 | -------------------------------------------------------------------------------- /springboot/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.2.2.RELEASE 9 | 10 | 11 | com.wxy97.shop 12 | springboot_shop 13 | 0.0.1-SNAPSHOT 14 | springboot_shop 15 | Demo project for Spring Boot 16 | 17 | 1.8 18 | 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-data-jpa 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-web 28 | 29 | 30 | 31 | org.projectlombok 32 | lombok 33 | true 34 | 35 | 36 | 37 | mysql 38 | mysql-connector-java 39 | 40 | 41 | 42 | org.apache.shiro 43 | shiro-spring 44 | 1.4.1 45 | 46 | 47 | 48 | com.auth0 49 | java-jwt 50 | 3.8.3 51 | 52 | 53 | 54 | io.springfox 55 | springfox-swagger2 56 | 2.9.2 57 | 58 | 59 | io.springfox 60 | springfox-swagger-ui 61 | 2.9.2 62 | 63 | 64 | 65 | org.springframework.boot 66 | spring-boot-starter-data-redis 67 | 68 | 69 | 70 | org.springframework.boot 71 | spring-boot-devtools 72 | true 73 | 74 | 75 | 76 | org.springframework.boot 77 | spring-boot-starter-test 78 | test 79 | 80 | 81 | org.junit.vintage 82 | junit-vintage-engine 83 | 84 | 85 | 86 | 87 | org.jetbrains 88 | annotations 89 | RELEASE 90 | compile 91 | 92 | 93 | 94 | 95 | 96 | 97 | org.springframework.boot 98 | spring-boot-maven-plugin 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/SpringbootShopApplication.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 6 | 7 | @SpringBootApplication 8 | @EnableSwagger2 9 | public class SpringbootShopApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(SpringbootShopApplication.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/config/CorsConfig.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.config; 2 | import org.springframework.context.annotation.Bean; 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.web.cors.CorsConfiguration; 5 | import org.springframework.web.cors.UrlBasedCorsConfigurationSource; 6 | import org.springframework.web.filter.CorsFilter; 7 | /** 8 | * @Author: wxySmile 9 | * @Date 20-1-3 上午11:18 10 | * 全局设置允许跨域请求 11 | */ 12 | @Configuration 13 | public class CorsConfig { 14 | @Bean 15 | public CorsFilter corsFilter() { 16 | UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 17 | source.registerCorsConfiguration("/**", buildConfig()); 18 | return new CorsFilter(source); 19 | } 20 | 21 | private CorsConfiguration buildConfig() { 22 | CorsConfiguration corsConfiguration = new CorsConfiguration(); 23 | // 1允许任何域名使用 24 | corsConfiguration.addAllowedOrigin("*"); 25 | // 2允许任何头 26 | corsConfiguration.addAllowedHeader("*"); 27 | // 3允许任何方法(post、get等) 28 | corsConfiguration.addAllowedMethod("*"); 29 | return corsConfiguration; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/config/IntercepterConfig.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 5 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 6 | 7 | /** 8 | * @Author: wxySmile 9 | * @Date 20-1-3 下午5:10 10 | */ 11 | @Configuration 12 | public class IntercepterConfig implements WebMvcConfigurer{ 13 | private TokenInterceptor tokenInterceptor; 14 | 15 | //构造方法 16 | public IntercepterConfig(TokenInterceptor tokenInterceptor){ 17 | this.tokenInterceptor = tokenInterceptor; 18 | } 19 | 20 | @Override 21 | public void addInterceptors(InterceptorRegistry registry){ 22 | registry.addInterceptor(tokenInterceptor) 23 | .addPathPatterns("/**") 24 | .excludePathPatterns("/login","/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**"); 25 | WebMvcConfigurer.super.addInterceptors(registry); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/config/RedisConfig.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.config; 2 | 3 | import com.fasterxml.jackson.annotation.JsonAutoDetect; 4 | import com.fasterxml.jackson.annotation.PropertyAccessor; 5 | import com.fasterxml.jackson.databind.ObjectMapper; 6 | import org.springframework.cache.annotation.EnableCaching; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.data.redis.connection.RedisConnectionFactory; 10 | import org.springframework.data.redis.core.*; 11 | import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; 12 | import org.springframework.data.redis.serializer.StringRedisSerializer; 13 | 14 | /** 15 | * @Author: wxySmile 16 | * @Date 20-1-5 上午11:56 17 | */ 18 | @Configuration 19 | @EnableCaching //开启注解 20 | public class RedisConfig { 21 | 22 | /** 23 | * retemplate相关配置 24 | * @param factory 25 | * @return 26 | */ 27 | @Bean 28 | public RedisTemplate redisTemplate(RedisConnectionFactory factory) { 29 | 30 | RedisTemplate template = new RedisTemplate<>(); 31 | // 配置连接工厂 32 | template.setConnectionFactory(factory); 33 | 34 | //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式) 35 | Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class); 36 | 37 | ObjectMapper om = new ObjectMapper(); 38 | // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public 39 | om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); 40 | // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会抛出异常 41 | om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); 42 | jacksonSeial.setObjectMapper(om); 43 | 44 | // 值采用json序列化 45 | template.setValueSerializer(jacksonSeial); 46 | //使用StringRedisSerializer来序列化和反序列化redis的key值 47 | template.setKeySerializer(new StringRedisSerializer()); 48 | 49 | // 设置hash key 和value序列化模式 50 | template.setHashKeySerializer(new StringRedisSerializer()); 51 | template.setHashValueSerializer(jacksonSeial); 52 | template.afterPropertiesSet(); 53 | 54 | return template; 55 | } 56 | 57 | /** 58 | * 对hash类型的数据操作 59 | * 60 | * @param redisTemplate 61 | * @return 62 | */ 63 | @Bean 64 | public HashOperations hashOperations(RedisTemplate redisTemplate) { 65 | return redisTemplate.opsForHash(); 66 | } 67 | 68 | /** 69 | * 对redis字符串类型数据操作 70 | * 71 | * @param redisTemplate 72 | * @return 73 | */ 74 | @Bean 75 | public ValueOperations valueOperations(RedisTemplate redisTemplate) { 76 | return redisTemplate.opsForValue(); 77 | } 78 | 79 | /** 80 | * 对链表类型的数据操作 81 | * 82 | * @param redisTemplate 83 | * @return 84 | */ 85 | @Bean 86 | public ListOperations listOperations(RedisTemplate redisTemplate) { 87 | return redisTemplate.opsForList(); 88 | } 89 | 90 | /** 91 | * 对无序集合类型的数据操作 92 | * 93 | * @param redisTemplate 94 | * @return 95 | */ 96 | @Bean 97 | public SetOperations setOperations(RedisTemplate redisTemplate) { 98 | return redisTemplate.opsForSet(); 99 | } 100 | 101 | /** 102 | * 对有序集合类型的数据操作 103 | * 104 | * @param redisTemplate 105 | * @return 106 | */ 107 | @Bean 108 | public ZSetOperations zSetOperations(RedisTemplate redisTemplate) { 109 | return redisTemplate.opsForZSet(); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/config/SwaggerConfig.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.config; 2 | 3 | import com.google.common.base.Predicates; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import springfox.documentation.builders.ApiInfoBuilder; 7 | import springfox.documentation.builders.PathSelectors; 8 | import springfox.documentation.builders.RequestHandlerSelectors; 9 | import springfox.documentation.service.ApiInfo; 10 | import springfox.documentation.service.Contact; 11 | import springfox.documentation.spi.DocumentationType; 12 | import springfox.documentation.spring.web.plugins.Docket; 13 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 14 | 15 | /** 16 | * @Author: wxySmile 17 | * @Date 20-1-5 上午10:15 18 | */ 19 | @Configuration 20 | @EnableSwagger2 21 | public class SwaggerConfig{ 22 | @Bean 23 | public Docket api() { 24 | return new Docket(DocumentationType.SWAGGER_2) 25 | .apiInfo(apiInfo()) 26 | .pathMapping("/") 27 | // 选择那些路径和api会生成document 28 | .select() 29 | // 对所有api进行监控 30 | .apis(RequestHandlerSelectors.any()) 31 | //不显示错误的接口地址 32 | //错误路径不监控 33 | .paths(Predicates.not(PathSelectors.regex("/error.*"))) 34 | // 对根下所有路径进行监控 35 | .paths(PathSelectors.regex("/.*")) 36 | .build(); 37 | } 38 | 39 | private ApiInfo apiInfo() { 40 | return new ApiInfoBuilder().title("springboot_shop接口文档") 41 | .contact(new Contact("wxySmile", "http://wxy97.com/", "wxyrrcj@163.com")) 42 | .description("个人博客地址:http://wxy97.com/") 43 | .version("v1.0") 44 | .build(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/config/TokenInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.config; 2 | import com.wxy97.shop.result.Result; 3 | import com.wxy97.shop.result.ResultFactory; 4 | import com.wxy97.shop.util.JWTUtil; 5 | import com.wxy97.shop.util.JsonUtils; 6 | import org.springframework.stereotype.Component; 7 | import org.springframework.web.servlet.HandlerInterceptor; 8 | 9 | import javax.servlet.http.HttpServletRequest; 10 | import javax.servlet.http.HttpServletResponse; 11 | import java.io.PrintWriter; 12 | 13 | /** 14 | * @Author: wxySmile 15 | * @Date 20-1-3 下午5:11 16 | * 完成token认证 17 | */ 18 | @Component 19 | public class TokenInterceptor implements HandlerInterceptor { 20 | 21 | @Override 22 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception{ 23 | if(request.getMethod().equals("OPTIONS")){ 24 | response.setStatus(HttpServletResponse.SC_OK); 25 | return true; 26 | } 27 | 28 | System.out.println("请求地址"+request.getRequestURI()); 29 | response.setCharacterEncoding("utf-8"); 30 | //获取请求头的token Authorization属性 31 | String token = request.getHeader("Authorization"); 32 | if(token != null){ 33 | boolean result = JWTUtil.verify(token); 34 | if(result){ 35 | System.out.println("通过拦截器"); 36 | return true; 37 | } 38 | } 39 | response.setCharacterEncoding("UTF-8"); 40 | response.setContentType("application/json; charset=utf-8"); 41 | PrintWriter out = null; 42 | try{ 43 | Result result = ResultFactory.buildFailResult("token认证失败"); 44 | response.getWriter().append(JsonUtils.toJson(result)); 45 | System.out.println("认证失败,未通过拦截器"); 46 | }catch (Exception e){ 47 | e.printStackTrace(); 48 | response.sendError(500); 49 | return false; 50 | } 51 | return false; 52 | 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/controller/LoginController.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.controller; 2 | 3 | 4 | import com.wxy97.shop.pojo.User; 5 | import com.wxy97.shop.result.Result; 6 | import com.wxy97.shop.result.ResultFactory; 7 | import com.wxy97.shop.util.JWTUtil; 8 | import io.swagger.annotations.Api; 9 | import io.swagger.annotations.ApiImplicitParam; 10 | import io.swagger.annotations.ApiImplicitParams; 11 | import io.swagger.annotations.ApiOperation; 12 | import org.apache.shiro.SecurityUtils; 13 | import org.apache.shiro.authc.AuthenticationException; 14 | import org.apache.shiro.authc.UsernamePasswordToken; 15 | import org.apache.shiro.crypto.hash.SimpleHash; 16 | import org.apache.shiro.subject.Subject; 17 | import org.springframework.boot.autoconfigure.cache.CacheProperties; 18 | import org.springframework.web.bind.annotation.*; 19 | 20 | import java.util.HashMap; 21 | 22 | /** 23 | * @Author: wxySmile 24 | * @Date 20-1-2 下午12:12 25 | */ 26 | @RestController 27 | public class LoginController { 28 | @ApiOperation("登录") 29 | @ApiImplicitParams({@ApiImplicitParam(name="username",value = "用户名",required = true), 30 | @ApiImplicitParam(name = "password", value = "密码", required = true)}) 31 | @ApiImplicitParam(name="password",value = "密码",required = true) 32 | @RequestMapping(value = "login",method = RequestMethod.POST) 33 | public Result login(@RequestBody User user){ 34 | SimpleHash simpleHash = new SimpleHash("MD5",user.getPassword(),user.getUsername(),1024); 35 | UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), simpleHash.toString()); 36 | token.setRememberMe(true); 37 | Subject subject = SecurityUtils.getSubject(); 38 | try { 39 | //完成登录 40 | subject.login(token); 41 | //获得用户对象 42 | User resultUser = (User) subject.getPrincipal(); 43 | HashMap data = new HashMap<>(); 44 | data.put("id",resultUser.getId()); 45 | data.put("name",resultUser.getName()); 46 | //生成token返回给客户端 47 | data.put("token",JWTUtil.sign(resultUser)); 48 | return ResultFactory.buildSuccessResult(data,"登录成功"); 49 | } catch (AuthenticationException e) { 50 | //登录失败 51 | return ResultFactory.buildFailResult("登录失败"); 52 | } 53 | } 54 | /* public static void main(String[] args) { 55 | //明码 56 | String password = "wxy"; 57 | //加密算法 58 | String algorithmName = "MD5"; 59 | //要加密的密码 60 | Object source = password; 61 | //盐值,一般都是用户名或者userid,要保证唯一 62 | Object salt = "wxy"; 63 | //加密次数 64 | int hashIterations = 1024; 65 | SimpleHash simpleHash = new SimpleHash(algorithmName,source,salt,hashIterations); 66 | //打印出经过盐值、加密次数、md5后的密码 67 | System.out.println(simpleHash.toString()); 68 | }*/ 69 | 70 | } 71 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/controller/MenuController.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.controller; 2 | 3 | import com.wxy97.shop.result.Result; 4 | import com.wxy97.shop.result.ResultFactory; 5 | import com.wxy97.shop.service.MenuService; 6 | import com.wxy97.shop.util.RedisUtil; 7 | import org.springframework.web.bind.annotation.CrossOrigin; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RequestMethod; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | import javax.annotation.Resource; 13 | 14 | /** 15 | * @Author: wxySmile 16 | * @Date 20-1-3 下午12:40 17 | */ 18 | @RestController 19 | @CrossOrigin("*") 20 | public class MenuController { 21 | @Resource 22 | MenuService menuServiceImpl; 23 | 24 | @Resource 25 | RedisUtil redisUtil; 26 | 27 | /** 28 | * 获取侧栏菜单列表 29 | * 30 | * @return 31 | */ 32 | @RequestMapping(value = "menus",method = RequestMethod.GET) 33 | public Result menuList(){ 34 | Object list = redisUtil.hget("shop", "menuList"); 35 | if (list == null){ 36 | System.out.println("redis缓存没有,从数据库取出并存入redis"); 37 | list = menuServiceImpl.bulidMenuList(); 38 | redisUtil.hset("shop","menuList",list); 39 | } 40 | return ResultFactory.buildSuccessResult(list,"请求菜单数据成功"); 41 | } 42 | } 43 | 44 | 45 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/controller/RightsController.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.controller; 2 | 3 | import com.wxy97.shop.dao.RightsJpaRepostory; 4 | import com.wxy97.shop.pojo.Rights; 5 | import com.wxy97.shop.result.Result; 6 | import com.wxy97.shop.result.ResultFactory; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | import javax.annotation.Resource; 11 | import java.util.List; 12 | 13 | /** 14 | * @Author: wxySmile 15 | * @Date 20-1-9 上午11:23 16 | */ 17 | @RestController 18 | public class RightsController { 19 | 20 | @Resource 21 | RightsJpaRepostory rightsJpaRepostory; 22 | 23 | /* @RequestMapping("add") 24 | public String add(){ 25 | Rights rights1 = new Rights(); 26 | Rights rights2 = new Rights(); 27 | Rights rights3 = new Rights(); 28 | Rights rights4 = new Rights(); 29 | Rights rights5 = new Rights(); 30 | Rights rights6 = new Rights(); 31 | Rights rights7 = new Rights(); 32 | Rights rights8 = new Rights(); 33 | Rights rights9 = new Rights(); 34 | Rights rights10 = new Rights(); 35 | Rights rights11 = new Rights(); 36 | Rights rights12 = new Rights(); 37 | Rights rights13 = new Rights(); 38 | Rights rights14 = new Rights(); 39 | Rights rights15 = new Rights(); 40 | Rights rights16 = new Rights(); 41 | Rights rights17 = new Rights(); 42 | Rights rights18 = new Rights(); 43 | Rights rights19 = new Rights(); 44 | Rights rights20 = new Rights(); 45 | Rights rights21 = new Rights(); 46 | Rights rights22 = new Rights(); 47 | Rights rights23 = new Rights(); 48 | Rights rights24 = new Rights(); 49 | Rights rights25 = new Rights(); 50 | Rights rights26 = new Rights(); 51 | Rights rights27 = new Rights(); 52 | Rights rights28 = new Rights(); 53 | Rights rights29 = new Rights(); 54 | Rights rights30 = new Rights(); 55 | Rights rights31 = new Rights(); 56 | Rights rights32 = new Rights(); 57 | Rights rights33 = new Rights(); 58 | Rights rights34 = new Rights(); 59 | Rights rights35 = new Rights(); 60 | Rights rights36 = new Rights(); 61 | Rights rights37 = new Rights(); 62 | Rights rights38 = new Rights(); 63 | Rights rights39 = new Rights(); 64 | Rights rights40 = new Rights(); 65 | Rights rights41 = new Rights(); 66 | Rights rights42 = new Rights(); 67 | Rights rights43 = new Rights(); 68 | Rights rights44 = new Rights(); 69 | Rights rights45 = new Rights(); 70 | 71 | rights1.setAuthName("商品管理").setPid(null).setLevel("0").setPath("goods"); 72 | rights2.setAuthName("订单管理").setPid(null).setLevel("0").setPath("orders"); 73 | rights3.setAuthName("权限管理").setPid(null).setLevel("0").setPath("rights"); 74 | rights4.setAuthName("用户管理").setPid(null).setLevel("0").setPath("users"); 75 | rights5.setAuthName("数据统计").setPid(null).setLevel("0").setPath("reports"); 76 | 77 | rights6.setAuthName("商品列表").setPid(1).setLevel("1").setPath("goods"); 78 | rights7.setAuthName("分类参数").setPid(1).setLevel("1").setPath("params"); 79 | rights8.setAuthName("商品分类").setPid(1).setLevel("1").setPath("categories"); 80 | 81 | rights9.setAuthName("添加商品").setPid(6).setLevel("2").setPath("goods"); 82 | rights10.setAuthName("商品修改").setPid(6).setLevel("2").setPath("goods"); 83 | rights11.setAuthName("商品删除").setPid(6).setLevel("2").setPath("goods"); 84 | rights12.setAuthName("更新商品图片").setPid(6).setLevel("2").setPath("goods"); 85 | rights13.setAuthName("更新商品属性").setPid(6).setLevel("2").setPath("goods"); 86 | rights14.setAuthName("更新商品状态").setPid(6).setLevel("2").setPath("goods"); 87 | rights15.setAuthName("获取商品详情").setPid(6).setLevel("2").setPath("goods"); 88 | 89 | rights16.setAuthName("获取参数列表").setPid(7).setLevel("2").setPath("params"); 90 | rights17.setAuthName("创建商品参数").setPid(7).setLevel("2").setPath("params"); 91 | rights18.setAuthName("删除商品参数").setPid(7).setLevel("2").setPath("params"); 92 | 93 | rights19.setAuthName("添加分类").setPid(8).setLevel("2").setPath("categories"); 94 | rights20.setAuthName("删除分类").setPid(8).setLevel("2").setPath("categories"); 95 | rights21.setAuthName("获取分类详情").setPid(8).setLevel("2").setPath("categories"); 96 | 97 | rightsJpaRepostory.save(rights1); 98 | rightsJpaRepostory.save(rights2); 99 | rightsJpaRepostory.save(rights3); 100 | rightsJpaRepostory.save(rights4); 101 | rightsJpaRepostory.save(rights5); 102 | rightsJpaRepostory.save(rights6); 103 | rightsJpaRepostory.save(rights7); 104 | rightsJpaRepostory.save(rights8); 105 | rightsJpaRepostory.save(rights9); 106 | rightsJpaRepostory.save(rights10); 107 | rightsJpaRepostory.save(rights11); 108 | rightsJpaRepostory.save(rights12); 109 | rightsJpaRepostory.save(rights13); 110 | rightsJpaRepostory.save(rights14); 111 | rightsJpaRepostory.save(rights15); 112 | rightsJpaRepostory.save(rights16); 113 | rightsJpaRepostory.save(rights17); 114 | rightsJpaRepostory.save(rights18); 115 | rightsJpaRepostory.save(rights19); 116 | rightsJpaRepostory.save(rights20); 117 | rightsJpaRepostory.save(rights21); 118 | rights22.setAuthName("订单管理").setPid(2).setLevel("1").setPath("orders"); 119 | rights27.setAuthName("添加订单").setPid(22).setLevel("2").setPath("orders"); 120 | rights28.setAuthName("订单更新").setPid(22).setLevel("2").setPath("orders"); 121 | rights29.setAuthName("获取订单详情").setPid(22).setLevel("2").setPath("orders"); 122 | 123 | 124 | rights23.setAuthName("角色列表").setPid(3).setLevel("1").setPath("roles"); 125 | rights30.setAuthName("添加角色").setPid(23).setLevel("2").setPath("roles"); 126 | rights31.setAuthName("删除角色").setPid(23).setLevel("2").setPath("roles"); 127 | rights32.setAuthName("角色授权").setPid(23).setLevel("2").setPath("roles"); 128 | rights33.setAuthName("取消角色授权").setPid(23).setLevel("2").setPath("roles"); 129 | rights34.setAuthName("获取角色列表").setPid(23).setLevel("2").setPath("roles"); 130 | rights35.setAuthName("获取角色详情").setPid(23).setLevel("2").setPath("roles"); 131 | rights36.setAuthName("更新角色信息").setPid(23).setLevel("2").setPath("roles"); 132 | rights37.setAuthName("更新角色权限").setPid(23).setLevel("2").setPath("roles"); 133 | 134 | rights24.setAuthName("权限列表").setPid(3).setLevel("1").setPath("rights"); 135 | rights38.setAuthName("查看权限").setPid(24).setLevel("2").setPath("roles"); 136 | 137 | rights25.setAuthName("用户列表").setPid(4).setLevel("1").setPath("users"); 138 | rights39.setAuthName("添加用户").setPid(25).setLevel("2").setPath("users"); 139 | rights40.setAuthName("删除用户").setPid(25).setLevel("2").setPath("users"); 140 | rights41.setAuthName("更新用户").setPid(25).setLevel("2").setPath("users"); 141 | rights42.setAuthName("获取用户详情").setPid(25).setLevel("2").setPath("users"); 142 | rights43.setAuthName("分配用户角色").setPid(25).setLevel("2").setPath("users"); 143 | rights44.setAuthName("设置管理状态").setPid(25).setLevel("2").setPath("users"); 144 | 145 | rights26.setAuthName("数据报表").setPid(5).setLevel("1").setPath("reports"); 146 | rights45.setAuthName("查看数据").setPid(26).setLevel("2").setPath("reports"); 147 | 148 | 149 | rightsJpaRepostory.save(rights22); 150 | rightsJpaRepostory.save(rights23); 151 | rightsJpaRepostory.save(rights24); 152 | rightsJpaRepostory.save(rights25); 153 | rightsJpaRepostory.save(rights26); 154 | rightsJpaRepostory.save(rights27); 155 | rightsJpaRepostory.save(rights28); 156 | rightsJpaRepostory.save(rights29); 157 | rightsJpaRepostory.save(rights30); 158 | rightsJpaRepostory.save(rights31); 159 | rightsJpaRepostory.save(rights32); 160 | rightsJpaRepostory.save(rights33); 161 | rightsJpaRepostory.save(rights34); 162 | rightsJpaRepostory.save(rights35); 163 | rightsJpaRepostory.save(rights36); 164 | rightsJpaRepostory.save(rights37); 165 | rightsJpaRepostory.save(rights38); 166 | rightsJpaRepostory.save(rights39); 167 | rightsJpaRepostory.save(rights40); 168 | rightsJpaRepostory.save(rights41); 169 | rightsJpaRepostory.save(rights42); 170 | rightsJpaRepostory.save(rights43); 171 | rightsJpaRepostory.save(rights44); 172 | rightsJpaRepostory.save(rights45); 173 | return "123"; 174 | }*/ 175 | 176 | 177 | @RequestMapping("/rights/list") 178 | public Result list(){ 179 | List list = rightsJpaRepostory.findAll(); 180 | return ResultFactory.buildSuccessResult(list,"获取成功"); 181 | } 182 | 183 | } 184 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/controller/RoleController.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.controller; 2 | 3 | import com.wxy97.shop.dao.RoleRepository; 4 | import com.wxy97.shop.pojo.Rights; 5 | import com.wxy97.shop.pojo.Role; 6 | import com.wxy97.shop.result.Result; 7 | import com.wxy97.shop.result.ResultFactory; 8 | import com.wxy97.shop.service.RoleService; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | import javax.annotation.Resource; 13 | import java.util.List; 14 | 15 | /** 16 | * @Author: wxySmile 17 | * @Date 20-1-9 下午12:49 18 | */ 19 | @RestController 20 | public class RoleController { 21 | 22 | @Resource 23 | RoleService roleServiceImpl; 24 | 25 | @RequestMapping("/role/list") 26 | public Result roleList(){ 27 | List list = roleServiceImpl.getRoleList(); 28 | return ResultFactory.buildSuccessResult(list,"获取成功!"); 29 | } 30 | 31 | 32 | 33 | } 34 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/controller/UserControler.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.controller; 2 | import com.wxy97.shop.pojo.User; 3 | import com.wxy97.shop.result.Result; 4 | import com.wxy97.shop.result.ResultFactory; 5 | import com.wxy97.shop.service.UserService; 6 | import io.swagger.annotations.ApiOperation; 7 | import org.springframework.web.bind.annotation.*; 8 | 9 | import javax.annotation.Resource; 10 | /** 11 | * @Author: wxySmile 12 | * @Date 20-1-3 下午7:07 13 | */ 14 | @RestController 15 | public class UserControler { 16 | 17 | @Resource 18 | UserService userServiceImpl; 19 | 20 | @ApiOperation(value = "查询用户列表数据") 21 | @RequestMapping(value = "users",method = RequestMethod.GET) 22 | public Result getUsers(){ 23 | //后端实现分页查询 24 | //userServiceImpl.getUserListByPage(pagenum,pagesize); 25 | return ResultFactory.buildSuccessResult(userServiceImpl.getUserList(),"查询所有用户"); 26 | } 27 | 28 | /** 29 | * 用户id存在修改 不存在添加用户 30 | * @param user 用户对象 31 | * @return 32 | */ 33 | @RequestMapping(value ={"/u/update","/u/save"},method = RequestMethod.POST) 34 | public Result update(@RequestBody User user){ 35 | User u = userServiceImpl.updateOrSave(user); 36 | return ResultFactory.buildSuccessResult(u,"操作成功"); 37 | } 38 | @ApiOperation(value = "根据id删除") 39 | @RequestMapping(value ="/u/delete") 40 | public Result delete(@RequestBody User user){ 41 | userServiceImpl.deleteById(user.getId()); 42 | return ResultFactory.buildSuccessResult(null,"删除成功"); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/dao/MenuRepository.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.dao; 2 | 3 | import com.wxy97.shop.pojo.Menu; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @Author: wxySmile 10 | * @Date 20-1-2 下午1:09 11 | */ 12 | public interface MenuRepository extends JpaRepository { 13 | @Override 14 | List findAll(); 15 | 16 | List findAllByParentId(int parentId); 17 | 18 | 19 | } 20 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/dao/RightsJpaRepostory.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.dao; 2 | 3 | import com.wxy97.shop.pojo.Rights; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | public interface RightsJpaRepostory extends JpaRepository { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/dao/RightsRepostory.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.dao; 2 | 3 | import com.wxy97.shop.pojo.Rights; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import org.springframework.stereotype.Repository; 6 | 7 | import javax.persistence.EntityManager; 8 | import javax.persistence.PersistenceContext; 9 | import javax.persistence.Query; 10 | import java.util.List; 11 | import java.util.Optional; 12 | 13 | 14 | /** 15 | * @Author: wxySmile 16 | * @Date 20-1-6 下午12:21 17 | * 自定义 清除jpa一级缓存 18 | */ 19 | @Repository 20 | public class RightsRepostory { 21 | 22 | @PersistenceContext 23 | private EntityManager em; 24 | 25 | public Rights findById(Integer id) { 26 | String sql="select * from s_rights where id="+id; 27 | Query query = em.createNativeQuery(sql, Rights.class); 28 | em.clear(); // 清除缓存 29 | return (Rights) query.getResultList().get(0); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/dao/RoleRepository.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.dao; 2 | 3 | import com.wxy97.shop.pojo.Role; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | /** 7 | * @Author: wxySmile 8 | * @Date 20-1-9 下午12:50 9 | */ 10 | public interface RoleRepository extends JpaRepository { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/dao/RoleRightsRepository.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.dao; 2 | 3 | import com.wxy97.shop.pojo.Menu; 4 | import com.wxy97.shop.pojo.RoleRights; 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @Author: wxySmile 11 | * @Date 20-1-2 下午1:09 12 | */ 13 | public interface RoleRightsRepository extends JpaRepository { 14 | List findAllByRoleId(Integer role_id); 15 | // void deleteAllByRole_id(Integer role_id); 16 | } 17 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/dao/UserRepository.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.dao; 2 | 3 | import com.wxy97.shop.pojo.User; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.util.List; 7 | 8 | 9 | /** 10 | * @Author: wxySmile 11 | * @Date 20-1-2 下午1:09 12 | */ 13 | public interface UserRepository extends JpaRepository { 14 | 15 | User findByUsername(String username); 16 | 17 | /* 18 | @Override 19 | Page findAll(Pageable pageable);*/ 20 | 21 | @Override 22 | void deleteById(Integer integer); 23 | 24 | @Override 25 | List findAll(); 26 | } 27 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/pojo/Menu.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.pojo; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | import lombok.Data; 5 | 6 | import javax.persistence.*; 7 | import java.io.Serializable; 8 | import java.util.List; 9 | 10 | /** 11 | * @Author: wxySmile 12 | * @Date 20-1-3 下午12:07 13 | */ 14 | @Entity 15 | @Table(name = "s_menu") 16 | @Data 17 | @JsonIgnoreProperties({"handler", "hibernateLazyInitializer"}) 18 | public class Menu implements Serializable { 19 | 20 | @Id 21 | @GeneratedValue(strategy = GenerationType.IDENTITY) 22 | private Integer id; 23 | 24 | private String name; 25 | private String path; 26 | @Column(columnDefinition="INT default 0") 27 | private int queue; 28 | @Column(columnDefinition="INT default 0") 29 | private int parentId; 30 | 31 | @Transient 32 | private List children; 33 | 34 | } 35 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/pojo/Rights.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.pojo; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | import lombok.experimental.Accessors; 7 | import org.hibernate.annotations.CacheConcurrencyStrategy; 8 | import org.hibernate.annotations.Fetch; 9 | import org.hibernate.annotations.FetchMode; 10 | 11 | import javax.persistence.*; 12 | import java.io.Serializable; 13 | import java.util.ArrayList; 14 | import java.util.HashSet; 15 | import java.util.List; 16 | import java.util.Set; 17 | 18 | /** 19 | * @Author: wxySmile 20 | * @Date 20-1-9 上午11:15 21 | */ 22 | 23 | @Entity 24 | @Getter 25 | @Setter 26 | @Table(name = "s_rights") 27 | @Accessors(chain = true)//链式结构 28 | 29 | public class Rights implements Serializable { 30 | @Id 31 | @GeneratedValue(strategy = GenerationType.IDENTITY) 32 | private Integer id; 33 | 34 | private String authName; 35 | private String level; 36 | private String path; 37 | private Integer pid; 38 | 39 | @Transient 40 | private List children; 41 | 42 | } 43 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/pojo/Role.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.pojo; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import org.hibernate.annotations.CacheConcurrencyStrategy; 6 | 7 | import javax.persistence.*; 8 | import java.io.Serializable; 9 | 10 | import java.util.List; 11 | import java.util.Set; 12 | 13 | 14 | /** 15 | * @Author: wxySmile 16 | * @Date 20-1-3 下午6:52 17 | */ 18 | @Entity 19 | @Table(name = "s_role") 20 | @Getter 21 | @Setter 22 | public class Role implements Serializable { 23 | private static final long serialVersionUID = 1L; 24 | @Id 25 | @GeneratedValue(strategy = GenerationType.IDENTITY) 26 | private Integer id; 27 | private String name; 28 | @Column(name = "d_esc") 29 | private String desc; 30 | 31 | @Transient 32 | private List rights; 33 | } 34 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/pojo/RoleRights.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.pojo; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import org.hibernate.annotations.Fetch; 6 | import org.hibernate.annotations.FetchMode; 7 | 8 | import javax.persistence.*; 9 | import java.io.Serializable; 10 | 11 | @Entity 12 | @Table(name = "s_role_right") 13 | @Getter 14 | @Setter 15 | public class RoleRights implements Serializable { 16 | 17 | @Id 18 | @GeneratedValue(strategy = GenerationType.IDENTITY) 19 | private Integer id; 20 | 21 | @Fetch(FetchMode.JOIN) 22 | private Integer roleId; 23 | private Integer rightId; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/pojo/User.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.pojo; 2 | import lombok.Data; 3 | import org.hibernate.annotations.CacheConcurrencyStrategy; 4 | 5 | import javax.persistence.*; 6 | import java.io.Serializable; 7 | 8 | /** 9 | * @Author: wxySmile 10 | * @Date 20-1-2 下午12:19 11 | */ 12 | 13 | @Entity 14 | @Table(name = "s_user") 15 | @Data 16 | public class User implements Serializable { 17 | @Id 18 | @GeneratedValue(strategy = GenerationType.IDENTITY) 19 | private Integer id; 20 | 21 | private String username; 22 | private String password; //3579c5bed0f11113ebfbbcfb9371eeb5 23 | private boolean mg_state; 24 | private String name; 25 | private String email; 26 | private String tel; 27 | 28 | @ManyToOne() 29 | @JoinColumn(name="rid") 30 | @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) 31 | private Role role; 32 | } 33 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/result/Result.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.result; 2 | 3 | 4 | import lombok.Data; 5 | 6 | import java.util.HashMap; 7 | 8 | /** 9 | * @Author: wxySmile 10 | * @Date 20-1-2 上午11:50 11 | */ 12 | @Data 13 | public class Result { 14 | 15 | private Object data; 16 | private HashMap meta =new HashMap<>(); 17 | 18 | public Result(Object data, String msg, Integer status) { 19 | meta.put("msg",msg); 20 | meta.put("status",status); 21 | this.data = data; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/result/ResultFactory.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.result; 2 | 3 | /** 4 | * @Author: wxySmile 5 | * @Date 20-1-2 上午11:58 6 | */ 7 | public class ResultFactory { 8 | 9 | public static Result buildSuccessResult(Object data,String message) { 10 | return buildResult(data,message,StatusCode.SUCCESS.code); 11 | } 12 | 13 | public static Result buildFailResult(String message) { 14 | return buildResult(null,message,StatusCode.FAIL.code); 15 | } 16 | 17 | public static Result buildResult(Object data, String message,Integer resultCode) { 18 | return new Result(data, message, resultCode); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/result/StatusCode.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.result; 2 | 3 | /** 4 | * @Author: wxySmile 5 | * @Date 20-1-2 上午11:55 6 | */ 7 | public enum StatusCode { 8 | SUCCESS(200), 9 | FAIL(400); 10 | public int code; 11 | 12 | StatusCode(int code) { 13 | this.code = code; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/service/MenuService.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.service; 2 | 3 | import com.wxy97.shop.pojo.Menu; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @Author: wxySmile 9 | * @Date 20-1-3 下午2:14 10 | */ 11 | public interface MenuService { 12 | 13 | List bulidMenuList(); 14 | } 15 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/service/MenuServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.service; 2 | 3 | import com.wxy97.shop.dao.MenuRepository; 4 | import com.wxy97.shop.pojo.Menu; 5 | import org.springframework.stereotype.Service; 6 | 7 | import javax.annotation.Resource; 8 | import java.util.ArrayList; 9 | import java.util.Collections; 10 | import java.util.Comparator; 11 | import java.util.List; 12 | 13 | /** 14 | * @Author: wxySmile 15 | * @Date 20-1-3 下午2:14 16 | */ 17 | @Service 18 | public class MenuServiceImpl implements MenuService { 19 | 20 | @Resource 21 | MenuRepository menuRepository; 22 | 23 | @Override 24 | public List bulidMenuList() { 25 | List menus = menuRepository.findAllByParentId(0); 26 | List all = menuRepository.findAll(); 27 | 28 | for (Menu menu : menus) { 29 | List child = getChild(menu.getId(), all); 30 | menu.setChildren(child); 31 | } 32 | return menus; 33 | } 34 | 35 | /** 36 | * 获取子节点 37 | * @param id 父节点id 38 | * @param allMenu allMenu 所有菜单列表 39 | * @return 每个根节点下,所有子菜单列表 40 | */ 41 | public List getChild(int id,List allMenu){ 42 | //子菜单 43 | List childList = new ArrayList(); 44 | for (Menu nav : allMenu) { 45 | // 遍历所有节点,将所有菜单的父id与传过来的根节点的id比较 46 | //相等说明:为该根节点的子节点。 47 | if(nav.getParentId()==id){ 48 | childList.add(nav); 49 | } 50 | } 51 | //递归 52 | for (Menu nav : childList) { 53 | nav.setChildren(getChild(nav.getId(), allMenu)); 54 | } 55 | Collections.sort(childList,order());//排序 56 | //如果节点下没有子节点,返回一个空List(递归退出) 57 | if(childList.size() == 0){ 58 | return new ArrayList(); 59 | } 60 | return childList; 61 | } 62 | 63 | 64 | /** 65 | * 根据菜单queue属性排序 66 | * @return 67 | */ 68 | public Comparator order(){ 69 | Comparator comparator = new Comparator() { 70 | @Override 71 | public int compare(Menu o1, Menu o2) { 72 | if(o1.getQueue() != o2.getQueue()){ 73 | return o1.getQueue() - o2.getQueue(); 74 | } 75 | return 0; 76 | } 77 | }; 78 | return comparator; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/service/RightsService.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.service; 2 | 3 | import com.wxy97.shop.pojo.Rights; 4 | 5 | import java.util.List; 6 | 7 | public interface RightsService { 8 | 9 | List listRightsByRoleId(int rid); 10 | } 11 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/service/RightsServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.service; 2 | 3 | import com.wxy97.shop.dao.RightsRepostory; 4 | import com.wxy97.shop.dao.RoleRightsRepository; 5 | import com.wxy97.shop.pojo.Rights; 6 | import com.wxy97.shop.pojo.RoleRights; 7 | import org.springframework.stereotype.Service; 8 | 9 | import javax.annotation.Resource; 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | @Service 14 | public class RightsServiceImpl implements RightsService { 15 | 16 | @Resource 17 | RoleRightsRepository roleRightsRepository; 18 | @Resource 19 | RightsRepostory rightsRepostory; 20 | 21 | @Override 22 | public List listRightsByRoleId(int rid) { 23 | List roleRights = roleRightsRepository.findAllByRoleId(rid); 24 | ArrayList list = new ArrayList<>(); 25 | 26 | for (RoleRights roleRight : roleRights) { 27 | list.add(rightsRepostory.findById(roleRight.getRightId())); 28 | } 29 | return list; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/service/RoleRihtsService.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.service; 2 | 3 | import com.wxy97.shop.pojo.RoleRights; 4 | 5 | import java.util.List; 6 | 7 | public interface RoleRihtsService { 8 | 9 | List findAllByRid(Integer rid); 10 | } 11 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/service/RoleRihtsServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.service; 2 | 3 | import com.wxy97.shop.dao.RoleRightsRepository; 4 | import com.wxy97.shop.pojo.RoleRights; 5 | import org.springframework.stereotype.Service; 6 | 7 | import javax.annotation.Resource; 8 | import java.util.List; 9 | 10 | @Service 11 | public class RoleRihtsServiceImpl implements RoleRihtsService { 12 | 13 | @Resource 14 | RoleRightsRepository roleRightsRepository; 15 | 16 | @Override 17 | public List findAllByRid(Integer rid) { 18 | return roleRightsRepository.findAllByRoleId(rid); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/service/RoleService.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.service; 2 | 3 | import com.wxy97.shop.pojo.Role; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @Author: wxySmile 9 | * @Date 20-1-9 下午3:36 10 | */ 11 | public interface RoleService { 12 | 13 | List getRoleList(); 14 | } 15 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/service/RoleServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.service; 2 | 3 | import com.wxy97.shop.dao.RightsRepostory; 4 | import com.wxy97.shop.dao.RoleRepository; 5 | import com.wxy97.shop.pojo.Rights; 6 | import com.wxy97.shop.pojo.Role; 7 | import org.springframework.stereotype.Service; 8 | 9 | import javax.annotation.Resource; 10 | import java.util.*; 11 | 12 | /** 13 | * @Author: wxySmile 14 | * @Date 20-1-9 下午3:36 15 | */ 16 | @Service 17 | public class RoleServiceImpl implements RoleService { 18 | 19 | 20 | @Resource 21 | RoleRepository roleRepository; 22 | 23 | @Resource 24 | RightsService rightsServiceImpl; 25 | 26 | @Override 27 | public List getRoleList() { 28 | List roles = roleRepository.findAll(); 29 | for (Role role : roles) { 30 | 31 | //根节点 32 | List rootRights = new ArrayList(); 33 | List rights = rightsServiceImpl.listRightsByRoleId(role.getId()); 34 | List list=new ArrayList<>(); 35 | for (Rights right : rights) { 36 | if (right.getLevel().equals("0")){ 37 | rootRights.add(right); 38 | }else { 39 | list.add(right); 40 | } 41 | } 42 | 43 | for (Rights rootRight : rootRights) { 44 | List child = getChild(rootRight.getId(), list); 45 | rootRight.setChildren(child); 46 | } 47 | //设置根节点 48 | role.setRights(rootRights); 49 | } 50 | return roles; 51 | } 52 | /** 53 | * 获取子节点 54 | * @param id 父节点id 55 | * @param allRights 所有列表 56 | * @return 每个根节点下,所有子菜单列表 57 | */ 58 | public List getChild(Integer id,List allRights){ 59 | //子菜单 60 | List childList = new ArrayList<>(); 61 | for (Rights nav : allRights) { 62 | // 遍历所有节点,将所有菜单的父id与传过来的根节点的id比较 63 | //相等说明:为该根节点的子节点。 64 | if(nav.getPid().equals(id)){ 65 | childList.add(nav); 66 | } 67 | } 68 | //递归 69 | for (Rights nav : childList) { 70 | nav.setChildren(getChild(nav.getId(), allRights)); 71 | } 72 | //如果节点下没有子节点,返回一个空List(递归退出) 73 | if(childList.size() == 0){ 74 | return new ArrayList<>(); 75 | } 76 | return childList; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.service; 2 | 3 | import com.wxy97.shop.pojo.User; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @Author: wxySmile 9 | * @Date 20-1-3 上午11:09 10 | */ 11 | public interface UserService { 12 | 13 | User findByUsername(String username); 14 | 15 | /* *//** 16 | * 后端实现分页查询 17 | * @param 18 | * @param 19 | * @return 20 | *//* 21 | Page getUserListByPage(Integer pagenum, Integer pagesize);*/ 22 | 23 | List getUserList(); 24 | 25 | User updateOrSave(User user); 26 | 27 | void deleteById(Integer id); 28 | } 29 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/service/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.service; 2 | 3 | import com.wxy97.shop.dao.UserRepository; 4 | import com.wxy97.shop.pojo.User; 5 | import com.wxy97.shop.util.RedisUtil; 6 | import org.springframework.stereotype.Service; 7 | 8 | import javax.annotation.Resource; 9 | import java.util.List; 10 | 11 | /** 12 | * @Author: wxySmile 13 | * @Date 20-1-3 上午11:10 14 | */ 15 | @Service 16 | public class UserServiceImpl implements UserService { 17 | 18 | @Resource 19 | UserRepository userRepository; 20 | 21 | @Resource 22 | RedisUtil redisUtil; 23 | 24 | @Override 25 | public User findByUsername(String username) { 26 | return userRepository.findByUsername(username); 27 | } 28 | 29 | @Override 30 | public List getUserList() { 31 | List userList = (List) redisUtil.hget("shop", "userList"); 32 | if (userList == null){ 33 | userList=userRepository.findAll(); 34 | redisUtil.hset("shop","userList",userList); 35 | } 36 | return userList; 37 | } 38 | 39 | /* *//** 40 | * 后端实现分页查询 41 | * @param 42 | * @param 43 | * @return 44 | *//* 45 | @Override 46 | public Page getUserListByPage(Integer pagenum, Integer pagesize) { 47 | Pageable pageable = PageRequest.of(pagenum-1,pagesize); 48 | return userRepository.findAll(pageable); 49 | }*/ 50 | 51 | @Override 52 | public User updateOrSave(User user) { 53 | redisUtil.hdel("shop","userList"); 54 | return userRepository.save(user); 55 | } 56 | 57 | @Override 58 | public void deleteById(Integer id) { 59 | redisUtil.hdel("shop","userList"); 60 | userRepository.deleteById(id); 61 | } 62 | 63 | 64 | } 65 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/shiro/MyRealm.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.shiro; 2 | 3 | import com.wxy97.shop.service.UserService; 4 | import com.wxy97.shop.pojo.User; 5 | import org.apache.shiro.authc.*; 6 | import org.apache.shiro.realm.AuthenticatingRealm; 7 | 8 | import javax.annotation.Resource; 9 | 10 | /** 11 | * @Author: wxySmile 12 | * @Date 19-11-13 上午9:39 13 | */ 14 | public class MyRealm extends AuthenticatingRealm { 15 | 16 | @Resource 17 | UserService userServiceImpl; 18 | 19 | 20 | @Override 21 | protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { 22 | UsernamePasswordToken usernamePasswordToken= (UsernamePasswordToken) authenticationToken; 23 | User user = userServiceImpl.findByUsername(usernamePasswordToken.getUsername()); 24 | return new SimpleAuthenticationInfo(user,user.getPassword(),this.getClass().getName()) ; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/shiro/ShiroConfig.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.shiro; 2 | 3 | import org.apache.shiro.mgt.DefaultSecurityManager; 4 | import org.apache.shiro.spring.web.ShiroFilterFactoryBean; 5 | import org.apache.shiro.web.mgt.DefaultWebSecurityManager; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | import java.util.HashMap; 10 | 11 | /** 12 | * @Author: wxySmile 13 | * @Date 20-1-2 下午2:13 14 | */ 15 | @Configuration 16 | public class ShiroConfig { 17 | 18 | /** 19 | * @Bean 声明创建对象 并把对象放在工厂中 相当于bean标签 20 | * 如果形参类型对应的对象在工厂中有 会自动装配上 21 | * @return 22 | */ 23 | @Bean 24 | public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultSecurityManager defaultSecurityManager){ 25 | ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); 26 | /** 27 | * 设置安全管理器,将创建的安全管理器放进shiroFilterFactoryBean过滤工厂里面 28 | */ 29 | shiroFilterFactoryBean.setSecurityManager(defaultSecurityManager); 30 | 31 | HashMap filterMap = new HashMap<>(); 32 | return shiroFilterFactoryBean; 33 | } 34 | 35 | /** 36 | * 创建安全管理器,并将自定义的Realm放进去管理器 37 | * @return 38 | */ 39 | @Bean 40 | public DefaultSecurityManager getDefaultSecurityManager(MyRealm myRealm){ 41 | DefaultSecurityManager defaultSecurityManager = new DefaultWebSecurityManager(); 42 | // 需要赋值一个Realm 43 | defaultSecurityManager.setRealm(myRealm); 44 | return defaultSecurityManager; 45 | } 46 | 47 | /** 48 | * 创建自定义的Realm 49 | */ 50 | @Bean 51 | public MyRealm getMyRealm(){ 52 | return new MyRealm(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/util/JWTUtil.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.util; 2 | 3 | import com.auth0.jwt.JWT; 4 | import com.auth0.jwt.algorithms.Algorithm; 5 | import com.auth0.jwt.interfaces.DecodedJWT; 6 | import com.auth0.jwt.interfaces.JWTVerifier; 7 | import com.wxy97.shop.pojo.User; 8 | 9 | import java.util.Date; 10 | 11 | /** 12 | * @Author: wxySmile 13 | * @Date 20-1-3 上午10:17 14 | */ 15 | public class JWTUtil { 16 | //有效期12h 17 | private static final long EXPIRE_TIME= 12*60*60*1000; 18 | //密钥盐 19 | private static final String TOKEN_SECRET="token123"; 20 | 21 | /** 22 | * 签名生成 23 | * @param user 24 | * @return 25 | */ 26 | public static String sign(User user){ 27 | String token = null; 28 | try { 29 | Date expiresAt = new Date(System.currentTimeMillis() + EXPIRE_TIME); 30 | token = JWT.create() 31 | .withIssuer("auth0") 32 | .withClaim("username", user.getUsername()) 33 | .withExpiresAt(expiresAt) 34 | // 使用了HMAC256加密算法。 35 | .sign(Algorithm.HMAC256(TOKEN_SECRET)); 36 | } catch (Exception e){ 37 | e.printStackTrace(); 38 | } 39 | return token; 40 | 41 | } 42 | 43 | 44 | /** 45 | * 签名验证 46 | * @param token 47 | * @return 48 | */ 49 | public static boolean verify(String token){ 50 | try { 51 | JWTVerifier verifier = JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer("auth0").build(); 52 | DecodedJWT jwt = verifier.verify(token); 53 | System.out.println("认证通过:"); 54 | System.out.println("issuer: " + jwt.getIssuer()); 55 | System.out.println("username: " + jwt.getClaim("username").asString()); 56 | System.out.println("过期时间: " + jwt.getExpiresAt()); 57 | return true; 58 | } catch (Exception e){ 59 | return false; 60 | } 61 | 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/util/JsonUtils.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.util; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | /** 5 | * @Author: wxySmile 6 | * @Date 20-1-3 下午5:51 7 | * 在拦截器中返回Json 8 | */ 9 | public class JsonUtils { 10 | private static ObjectMapper objectMapper = new ObjectMapper(); 11 | /** 12 | * 对象转json 13 | * @param obj 14 | * @param 15 | * @return 16 | */ 17 | public static String toJson(T obj){ 18 | if (obj == null){ 19 | } 20 | try { 21 | return obj instanceof String ? (String) obj : objectMapper.writeValueAsString(obj); 22 | } catch (Exception e) { 23 | e.printStackTrace(); 24 | return null; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /springboot/src/main/java/com/wxy97/shop/util/TreeUtil.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop.util; 2 | 3 | import com.wxy97.shop.pojo.Rights; 4 | 5 | import java.util.ArrayList; 6 | import java.util.HashSet; 7 | import java.util.List; 8 | import java.util.Set; 9 | 10 | /** 11 | * @Author: wxySmile 12 | * @Date 20-1-9 下午8:19 13 | */ 14 | public class TreeUtil { 15 | 16 | //判断是否根节点 17 | public static boolean isRootElement(Rights rights){ 18 | if(rights.getPid().equals("0")){ 19 | return true; 20 | } 21 | return false; 22 | } 23 | 24 | public static List getChildNodes(Integer pid, List rootList){ 25 | List childList = new ArrayList<>(); 26 | for(Rights n:rootList){ 27 | if(n.getPid().equals(pid)){ 28 | childList.add(n); 29 | } 30 | } 31 | //递归查找子节点的子节点并赋值 32 | for(Rights c:childList){ 33 | c.setChildren(getChildNodes(c.getId(), rootList)); 34 | } 35 | //子节点查找结束 36 | if(childList.size() == 0){ 37 | return null; 38 | } 39 | return childList; 40 | } 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /springboot/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 1106 3 | spring: 4 | datasource: 5 | type: com.zaxxer.hikari.HikariDataSource 6 | driver-class-name: com.mysql.cj.jdbc.Driver 7 | url: jdbc:mysql://localhost:3306/shop?characterEncoding=utf-8 8 | username: root 9 | password: wxy123456 10 | hikari: 11 | auto-commit: true 12 | max-lifetime: 1200000 13 | jpa: 14 | hibernate: 15 | ddl-auto: update 16 | show-sql: true 17 | open-in-view: true 18 | redis: 19 | host: 127.0.0.1 20 | port: 6379 21 | jedis: 22 | pool: 23 | max-active: 100 #连接池最大连接数(使用负值表示没有限制) 24 | max-wait: 1 #连接池最大阻塞等待时间(使用负值表示没有限制) 25 | max-idle: 10 #连接池中的最大空闲连接 26 | min-idle: 0 #连接池中的最小空闲连接 27 | timeout: 1000 #连接超时时间毫秒 -------------------------------------------------------------------------------- /springboot/src/test/java/com/wxy97/shop/SpringbootShopApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.wxy97.shop; 2 | 3 | 4 | import org.junit.jupiter.api.Test; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | 7 | @SpringBootTest 8 | class SpringbootShopApplicationTests { 9 | 10 | 11 | 12 | @Test 13 | void contextLoads() { 14 | 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /vue/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | -------------------------------------------------------------------------------- /vue/.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{js,jsx,ts,tsx,vue}] 2 | indent_style = space 3 | indent_size = 2 4 | trim_trailing_whitespace = true 5 | insert_final_newline = true 6 | -------------------------------------------------------------------------------- /vue/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | 'extends': [ 7 | 'plugin:vue/essential', 8 | '@vue/standard' 9 | ], 10 | rules: { 11 | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', 12 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', 13 | 'handle-callback-err': 'off', 14 | 'space-in-parens': 'off', 15 | "no-irregular-whitespace":"off",//这禁止掉 空格报错检查 16 | 'space-before-function-paren': 0, 17 | 'object-property-newline':"off", 18 | "indent": ["off", 2] 19 | }, 20 | parserOptions: { 21 | parser: 'babel-eslint' 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /vue/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /vue/README.md: -------------------------------------------------------------------------------- 1 | # vue_shop 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Lints and fixes files 19 | ``` 20 | npm run lint 21 | ``` 22 | 23 | ### Customize configuration 24 | See [Configuration Reference](https://cli.vuejs.org/config/). 25 | -------------------------------------------------------------------------------- /vue/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 'presets': [ 3 | '@vue/cli-plugin-babel/preset' 4 | ], 5 | 'plugins': [ 6 | [ 7 | 'component', 8 | { 9 | 'libraryName': 'element-ui', 10 | 'styleLibraryName': 'theme-chalk' 11 | } 12 | ] 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /vue/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue_shop", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve --open", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "axios": "^0.19.0", 12 | "core-js": "^3.4.4", 13 | "element-ui": "^2.4.5", 14 | "vue": "^2.6.10", 15 | "vue-router": "^3.1.3" 16 | }, 17 | "devDependencies": { 18 | "@hapi/hoek": ">=8.5.1", 19 | "@vue/cli-plugin-babel": "^4.1.0", 20 | "@vue/cli-plugin-eslint": "^4.1.0", 21 | "@vue/cli-plugin-router": "^4.1.0", 22 | "@vue/cli-service": "^4.1.0", 23 | "@vue/eslint-config-standard": "^4.0.0", 24 | "babel-eslint": "^10.0.3", 25 | "babel-plugin-component": "^1.1.1", 26 | "eslint": "^5.16.0", 27 | "eslint-plugin-vue": "^5.0.0", 28 | "less": "^3.10.3", 29 | "less-loader": "^5.0.0", 30 | "vue-cli-plugin-element": "^1.0.1", 31 | "vue-template-compiler": "^2.6.10" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /vue/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxyShine/springboot_vue_shop/51a84521b42c18b3053ad8b848eb9443fa0f3afc/vue/public/favicon.ico -------------------------------------------------------------------------------- /vue/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | vue_shop 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /vue/src/App.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 13 | 14 | 16 | -------------------------------------------------------------------------------- /vue/src/assets/css/global.css: -------------------------------------------------------------------------------- 1 | html, body, #app{ 2 | margin: 0; 3 | padding: 0; 4 | height: 100%; 5 | min-width: 1366px; 6 | } 7 | /*面包屑*/ 8 | .el-breadcrumb{ 9 | margin-bottom: 15px; 10 | font-size: 14px; 11 | } 12 | /*卡片样式*/ 13 | .el-card{ 14 | box-shadow: 0 1px 1px rgba(0,0,0,0.15)!important; 15 | } 16 | .el-table { 17 | margin: 12px 0; 18 | } 19 | -------------------------------------------------------------------------------- /vue/src/assets/fonts/demo.css: -------------------------------------------------------------------------------- 1 | /* Logo 字体 */ 2 | @font-face { 3 | font-family: "iconfont logo"; 4 | src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834'); 5 | src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'), 6 | url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'), 7 | url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'), 8 | url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg'); 9 | } 10 | 11 | .logo { 12 | font-family: "iconfont logo"; 13 | font-size: 160px; 14 | font-style: normal; 15 | -webkit-font-smoothing: antialiased; 16 | -moz-osx-font-smoothing: grayscale; 17 | } 18 | 19 | /* tabs */ 20 | .nav-tabs { 21 | position: relative; 22 | } 23 | 24 | .nav-tabs .nav-more { 25 | position: absolute; 26 | right: 0; 27 | bottom: 0; 28 | height: 42px; 29 | line-height: 42px; 30 | color: #666; 31 | } 32 | 33 | #tabs { 34 | border-bottom: 1px solid #eee; 35 | } 36 | 37 | #tabs li { 38 | cursor: pointer; 39 | width: 100px; 40 | height: 40px; 41 | line-height: 40px; 42 | text-align: center; 43 | font-size: 16px; 44 | border-bottom: 2px solid transparent; 45 | position: relative; 46 | z-index: 1; 47 | margin-bottom: -1px; 48 | color: #666; 49 | } 50 | 51 | 52 | #tabs .active { 53 | border-bottom-color: #f00; 54 | color: #222; 55 | } 56 | 57 | .tab-container .content { 58 | display: none; 59 | } 60 | 61 | /* 页面布局 */ 62 | .main { 63 | padding: 30px 100px; 64 | width: 960px; 65 | margin: 0 auto; 66 | } 67 | 68 | .main .logo { 69 | color: #333; 70 | text-align: left; 71 | margin-bottom: 30px; 72 | line-height: 1; 73 | height: 110px; 74 | margin-top: -50px; 75 | overflow: hidden; 76 | *zoom: 1; 77 | } 78 | 79 | .main .logo a { 80 | font-size: 160px; 81 | color: #333; 82 | } 83 | 84 | .helps { 85 | margin-top: 40px; 86 | } 87 | 88 | .helps pre { 89 | padding: 20px; 90 | margin: 10px 0; 91 | border: solid 1px #e7e1cd; 92 | background-color: #fffdef; 93 | overflow: auto; 94 | } 95 | 96 | .icon_lists { 97 | width: 100% !important; 98 | overflow: hidden; 99 | *zoom: 1; 100 | } 101 | 102 | .icon_lists li { 103 | width: 100px; 104 | margin-bottom: 10px; 105 | margin-right: 20px; 106 | text-align: center; 107 | list-style: none !important; 108 | cursor: default; 109 | } 110 | 111 | .icon_lists li .code-name { 112 | line-height: 1.2; 113 | } 114 | 115 | .icon_lists .icon { 116 | display: block; 117 | height: 100px; 118 | line-height: 100px; 119 | font-size: 42px; 120 | margin: 10px auto; 121 | color: #333; 122 | -webkit-transition: font-size 0.25s linear, width 0.25s linear; 123 | -moz-transition: font-size 0.25s linear, width 0.25s linear; 124 | transition: font-size 0.25s linear, width 0.25s linear; 125 | } 126 | 127 | .icon_lists .icon:hover { 128 | font-size: 100px; 129 | } 130 | 131 | .icon_lists .svg-icon { 132 | /* 通过设置 font-size 来改变图标大小 */ 133 | width: 1em; 134 | /* 图标和文字相邻时,垂直对齐 */ 135 | vertical-align: -0.15em; 136 | /* 通过设置 color 来改变 SVG 的颜色/fill */ 137 | fill: currentColor; 138 | /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示 139 | normalize.css 中也包含这行 */ 140 | overflow: hidden; 141 | } 142 | 143 | .icon_lists li .name, 144 | .icon_lists li .code-name { 145 | color: #666; 146 | } 147 | 148 | /* markdown 样式 */ 149 | .markdown { 150 | color: #666; 151 | font-size: 14px; 152 | line-height: 1.8; 153 | } 154 | 155 | .highlight { 156 | line-height: 1.5; 157 | } 158 | 159 | .markdown img { 160 | vertical-align: middle; 161 | max-width: 100%; 162 | } 163 | 164 | .markdown h1 { 165 | color: #404040; 166 | font-weight: 500; 167 | line-height: 40px; 168 | margin-bottom: 24px; 169 | } 170 | 171 | .markdown h2, 172 | .markdown h3, 173 | .markdown h4, 174 | .markdown h5, 175 | .markdown h6 { 176 | color: #404040; 177 | margin: 1.6em 0 0.6em 0; 178 | font-weight: 500; 179 | clear: both; 180 | } 181 | 182 | .markdown h1 { 183 | font-size: 28px; 184 | } 185 | 186 | .markdown h2 { 187 | font-size: 22px; 188 | } 189 | 190 | .markdown h3 { 191 | font-size: 16px; 192 | } 193 | 194 | .markdown h4 { 195 | font-size: 14px; 196 | } 197 | 198 | .markdown h5 { 199 | font-size: 12px; 200 | } 201 | 202 | .markdown h6 { 203 | font-size: 12px; 204 | } 205 | 206 | .markdown hr { 207 | height: 1px; 208 | border: 0; 209 | background: #e9e9e9; 210 | margin: 16px 0; 211 | clear: both; 212 | } 213 | 214 | .markdown p { 215 | margin: 1em 0; 216 | } 217 | 218 | .markdown>p, 219 | .markdown>blockquote, 220 | .markdown>.highlight, 221 | .markdown>ol, 222 | .markdown>ul { 223 | width: 80%; 224 | } 225 | 226 | .markdown ul>li { 227 | list-style: circle; 228 | } 229 | 230 | .markdown>ul li, 231 | .markdown blockquote ul>li { 232 | margin-left: 20px; 233 | padding-left: 4px; 234 | } 235 | 236 | .markdown>ul li p, 237 | .markdown>ol li p { 238 | margin: 0.6em 0; 239 | } 240 | 241 | .markdown ol>li { 242 | list-style: decimal; 243 | } 244 | 245 | .markdown>ol li, 246 | .markdown blockquote ol>li { 247 | margin-left: 20px; 248 | padding-left: 4px; 249 | } 250 | 251 | .markdown code { 252 | margin: 0 3px; 253 | padding: 0 5px; 254 | background: #eee; 255 | border-radius: 3px; 256 | } 257 | 258 | .markdown strong, 259 | .markdown b { 260 | font-weight: 600; 261 | } 262 | 263 | .markdown>table { 264 | border-collapse: collapse; 265 | border-spacing: 0px; 266 | empty-cells: show; 267 | border: 1px solid #e9e9e9; 268 | width: 95%; 269 | margin-bottom: 24px; 270 | } 271 | 272 | .markdown>table th { 273 | white-space: nowrap; 274 | color: #333; 275 | font-weight: 600; 276 | } 277 | 278 | .markdown>table th, 279 | .markdown>table td { 280 | border: 1px solid #e9e9e9; 281 | padding: 8px 16px; 282 | text-align: left; 283 | } 284 | 285 | .markdown>table th { 286 | background: #F7F7F7; 287 | } 288 | 289 | .markdown blockquote { 290 | font-size: 90%; 291 | color: #999; 292 | border-left: 4px solid #e9e9e9; 293 | padding-left: 0.8em; 294 | margin: 1em 0; 295 | } 296 | 297 | .markdown blockquote p { 298 | margin: 0; 299 | } 300 | 301 | .markdown .anchor { 302 | opacity: 0; 303 | transition: opacity 0.3s ease; 304 | margin-left: 8px; 305 | } 306 | 307 | .markdown .waiting { 308 | color: #ccc; 309 | } 310 | 311 | .markdown h1:hover .anchor, 312 | .markdown h2:hover .anchor, 313 | .markdown h3:hover .anchor, 314 | .markdown h4:hover .anchor, 315 | .markdown h5:hover .anchor, 316 | .markdown h6:hover .anchor { 317 | opacity: 1; 318 | display: inline-block; 319 | } 320 | 321 | .markdown>br, 322 | .markdown>p>br { 323 | clear: both; 324 | } 325 | 326 | 327 | .hljs { 328 | display: block; 329 | background: white; 330 | padding: 0.5em; 331 | color: #333333; 332 | overflow-x: auto; 333 | } 334 | 335 | .hljs-comment, 336 | .hljs-meta { 337 | color: #969896; 338 | } 339 | 340 | .hljs-string, 341 | .hljs-variable, 342 | .hljs-template-variable, 343 | .hljs-strong, 344 | .hljs-emphasis, 345 | .hljs-quote { 346 | color: #df5000; 347 | } 348 | 349 | .hljs-keyword, 350 | .hljs-selector-tag, 351 | .hljs-type { 352 | color: #a71d5d; 353 | } 354 | 355 | .hljs-literal, 356 | .hljs-symbol, 357 | .hljs-bullet, 358 | .hljs-attribute { 359 | color: #0086b3; 360 | } 361 | 362 | .hljs-section, 363 | .hljs-name { 364 | color: #63a35c; 365 | } 366 | 367 | .hljs-tag { 368 | color: #333333; 369 | } 370 | 371 | .hljs-title, 372 | .hljs-attr, 373 | .hljs-selector-id, 374 | .hljs-selector-class, 375 | .hljs-selector-attr, 376 | .hljs-selector-pseudo { 377 | color: #795da3; 378 | } 379 | 380 | .hljs-addition { 381 | color: #55a532; 382 | background-color: #eaffea; 383 | } 384 | 385 | .hljs-deletion { 386 | color: #bd2c00; 387 | background-color: #ffecec; 388 | } 389 | 390 | .hljs-link { 391 | text-decoration: underline; 392 | } 393 | 394 | /* 代码高亮 */ 395 | /* PrismJS 1.15.0 396 | https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */ 397 | /** 398 | * prism.js default theme for JavaScript, CSS and HTML 399 | * Based on dabblet (http://dabblet.com) 400 | * @author Lea Verou 401 | */ 402 | code[class*="language-"], 403 | pre[class*="language-"] { 404 | color: black; 405 | background: none; 406 | text-shadow: 0 1px white; 407 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; 408 | text-align: left; 409 | white-space: pre; 410 | word-spacing: normal; 411 | word-break: normal; 412 | word-wrap: normal; 413 | line-height: 1.5; 414 | 415 | -moz-tab-size: 4; 416 | -o-tab-size: 4; 417 | tab-size: 4; 418 | 419 | -webkit-hyphens: none; 420 | -moz-hyphens: none; 421 | -ms-hyphens: none; 422 | hyphens: none; 423 | } 424 | 425 | pre[class*="language-"]::-moz-selection, 426 | pre[class*="language-"] ::-moz-selection, 427 | code[class*="language-"]::-moz-selection, 428 | code[class*="language-"] ::-moz-selection { 429 | text-shadow: none; 430 | background: #b3d4fc; 431 | } 432 | 433 | pre[class*="language-"]::selection, 434 | pre[class*="language-"] ::selection, 435 | code[class*="language-"]::selection, 436 | code[class*="language-"] ::selection { 437 | text-shadow: none; 438 | background: #b3d4fc; 439 | } 440 | 441 | @media print { 442 | 443 | code[class*="language-"], 444 | pre[class*="language-"] { 445 | text-shadow: none; 446 | } 447 | } 448 | 449 | /* Code blocks */ 450 | pre[class*="language-"] { 451 | padding: 1em; 452 | margin: .5em 0; 453 | overflow: auto; 454 | } 455 | 456 | :not(pre)>code[class*="language-"], 457 | pre[class*="language-"] { 458 | background: #f5f2f0; 459 | } 460 | 461 | /* Inline code */ 462 | :not(pre)>code[class*="language-"] { 463 | padding: .1em; 464 | border-radius: .3em; 465 | white-space: normal; 466 | } 467 | 468 | .token.comment, 469 | .token.prolog, 470 | .token.doctype, 471 | .token.cdata { 472 | color: slategray; 473 | } 474 | 475 | .token.punctuation { 476 | color: #999; 477 | } 478 | 479 | .namespace { 480 | opacity: .7; 481 | } 482 | 483 | .token.property, 484 | .token.tag, 485 | .token.boolean, 486 | .token.number, 487 | .token.constant, 488 | .token.symbol, 489 | .token.deleted { 490 | color: #905; 491 | } 492 | 493 | .token.selector, 494 | .token.attr-name, 495 | .token.string, 496 | .token.char, 497 | .token.builtin, 498 | .token.inserted { 499 | color: #690; 500 | } 501 | 502 | .token.operator, 503 | .token.entity, 504 | .token.url, 505 | .language-css .token.string, 506 | .style .token.string { 507 | color: #9a6e3a; 508 | background: hsla(0, 0%, 100%, .5); 509 | } 510 | 511 | .token.atrule, 512 | .token.attr-value, 513 | .token.keyword { 514 | color: #07a; 515 | } 516 | 517 | .token.function, 518 | .token.class-name { 519 | color: #DD4A68; 520 | } 521 | 522 | .token.regex, 523 | .token.important, 524 | .token.variable { 525 | color: #e90; 526 | } 527 | 528 | .token.important, 529 | .token.bold { 530 | font-weight: bold; 531 | } 532 | 533 | .token.italic { 534 | font-style: italic; 535 | } 536 | 537 | .token.entity { 538 | cursor: help; 539 | } 540 | -------------------------------------------------------------------------------- /vue/src/assets/fonts/demo_index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IconFont Demo 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 |

19 | 27 |
28 |
29 |
    30 | 31 |
  • 32 | 33 |
    用户
    34 |
    &#xe603;
    35 |
  • 36 | 37 |
  • 38 | 39 |
    password
    40 |
    &#xe62d;
    41 |
  • 42 | 43 |
  • 44 | 45 |
    数据统计
    46 |
    &#xe604;
    47 |
  • 48 | 49 |
  • 50 | 51 |
    商品创建
    52 |
    &#xe61e;
    53 |
  • 54 | 55 |
  • 56 | 57 |
    login_username
    58 |
    &#xe6ca;
    59 |
  • 60 | 61 |
  • 62 | 63 |
    权限
    64 |
    &#xe656;
    65 |
  • 66 | 67 |
  • 68 | 69 |
    订单
    70 |
    &#xe625;
    71 |
  • 72 | 73 |
74 |
75 |

Unicode 引用

76 |
77 | 78 |

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

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

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

86 |
87 |

Unicode 使用步骤如下:

88 |

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

89 |
@font-face {
 91 |   font-family: 'iconfont';
 92 |   src: url('iconfont.eot');
 93 |   src: url('iconfont.eot?#iefix') format('embedded-opentype'),
 94 |       url('iconfont.woff2') format('woff2'),
 95 |       url('iconfont.woff') format('woff'),
 96 |       url('iconfont.ttf') format('truetype'),
 97 |       url('iconfont.svg#iconfont') format('svg');
 98 | }
 99 | 
100 |

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

101 |
.iconfont {
103 |   font-family: "iconfont" !important;
104 |   font-size: 16px;
105 |   font-style: normal;
106 |   -webkit-font-smoothing: antialiased;
107 |   -moz-osx-font-smoothing: grayscale;
108 | }
109 | 
110 |

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

111 |
112 | <span class="iconfont">&#x33;</span>
114 | 
115 |
116 |

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

117 |
118 |
119 |
120 |
121 |
    122 | 123 |
  • 124 | 125 |
    126 | 用户 127 |
    128 |
    .icon-yonghu 129 |
    130 |
  • 131 | 132 |
  • 133 | 134 |
    135 | password 136 |
    137 |
    .icon-mima 138 |
    139 |
  • 140 | 141 |
  • 142 | 143 |
    144 | 数据统计 145 |
    146 |
    .icon-icon-test 147 |
    148 |
  • 149 | 150 |
  • 151 | 152 |
    153 | 商品创建 154 |
    155 |
    .icon-shangpinchuangjian 156 |
    157 |
  • 158 | 159 |
  • 160 | 161 |
    162 | login_username 163 |
    164 |
    .icon-login_username 165 |
    166 |
  • 167 | 168 |
  • 169 | 170 |
    171 | 权限 172 |
    173 |
    .icon-quanxian 174 |
    175 |
  • 176 | 177 |
  • 178 | 179 |
    180 | 订单 181 |
    182 |
    .icon-5 183 |
    184 |
  • 185 | 186 |
187 |
188 |

font-class 引用

189 |
190 | 191 |

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

192 |

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

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

使用步骤如下:

200 |

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

201 |
<link rel="stylesheet" href="./iconfont.css">
202 | 
203 |

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

204 |
<span class="iconfont icon-xxx"></span>
205 | 
206 |
207 |

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

209 |
210 |
211 |
212 |
213 |
    214 | 215 |
  • 216 | 219 |
    用户
    220 |
    #icon-yonghu
    221 |
  • 222 | 223 |
  • 224 | 227 |
    password
    228 |
    #icon-mima
    229 |
  • 230 | 231 |
  • 232 | 235 |
    数据统计
    236 |
    #icon-icon-test
    237 |
  • 238 | 239 |
  • 240 | 243 |
    商品创建
    244 |
    #icon-shangpinchuangjian
    245 |
  • 246 | 247 |
  • 248 | 251 |
    login_username
    252 |
    #icon-login_username
    253 |
  • 254 | 255 |
  • 256 | 259 |
    权限
    260 |
    #icon-quanxian
    261 |
  • 262 | 263 |
  • 264 | 267 |
    订单
    268 |
    #icon-5
    269 |
  • 270 | 271 |
272 |
273 |

Symbol 引用

274 |
275 | 276 |

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

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

使用步骤如下:

285 |

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

286 |
<script src="./iconfont.js"></script>
287 | 
288 |

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

289 |
<style>
290 | .icon {
291 |   width: 1em;
292 |   height: 1em;
293 |   vertical-align: -0.15em;
294 |   fill: currentColor;
295 |   overflow: hidden;
296 | }
297 | </style>
298 | 
299 |

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

300 |
<svg class="icon" aria-hidden="true">
301 |   <use xlink:href="#icon-xxx"></use>
302 | </svg>
303 | 
304 |
305 |
306 | 307 |
308 |
309 | 328 | 329 | 330 | -------------------------------------------------------------------------------- /vue/src/assets/fonts/iconfont.css: -------------------------------------------------------------------------------- 1 | @font-face {font-family: "iconfont"; 2 | src: url('iconfont.eot?t=1578036136452'); /* IE9 */ 3 | src: url('iconfont.eot?t=1578036136452#iefix') format('embedded-opentype'), /* IE6-IE8 */ 4 | url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAdQAAsAAAAADUwAAAcBAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDbAqMcIorATYCJAMgCxIABCAFhG0HeBstCxFVpMGT/Tywm1n+g9b2NMdtmqGaAUIe+3nctPcTJE1Qr1GomQAzsTCtbA4VP0dmIsiZsnMv6Ng+BiohRbfW8gELJFSEeZQ//s+X7GEWeLLZwvg6XaUqZCtcGyCAIO/BYdOfE2zeb3uXuQY1F0cFGtBYw3pKs9ICCogDSYc4G24GnSp3vx8gACBBB7GASstrTUAAA9iI0DV/zqwpQGRcwGhgIiCsrIpzGYD2AhMIrA17CAB7gp9H30AyIgAwYOLAD2qcWTYdCgN44D5Oj9AZj9NAby4AAP2LAHAAiAUABgBqrQxtBjwyxAYmsuplDLAAAA8IwIAVYAR0gYhAXMASuD8yArDp8dmxXEPAA4EoqQEHBrBhA395wARALOiYOMBOL7MBArgjBQggwDBC0ayDEWCOgEprjoMDMJgtcAAL5vtQ3eIQAOENCgBABYDJyb0fmJIKBrxjYMruGDAANxijeDwScemriPhydlCyXs2IMCo4nHVADkZf9pWfNnTKjqScCLf64nsPG4ZeVHi9pn5PpA3oHqnTu/qKv+KMsUt+OP542OBran9Bl3HwebnHYx7wRtnB3i1xeEoxamgNbSMF7Z1oyJ/wonmHPmSVnfeF+fyj1sSmPZk2yXtf8jYd8q5DPp+F9HhMQDL4zOnkqDcPo6ErHZe03Qf14zjoNX8FdcsbCus6nMCiHe0uxLa619hpyXRb0mCVz+rqmNxDmxCjTtTbaKnZ3uG2yiyd7Stox+53cVndlLDDOQ/5txwwA7k1R/nN7rlcm0PS4+xwI6tLRqHGqU33oDrOKSf0XCR57ZfVk/ouUBS3rWJz/a7TDtq5rlOmY73Ks8fLHLW1R2cj745Rq4MZoVLkHcd9ZyNhor153pDQOq7TKnf7j3Gndr3NJrUrjwFtCkYtfeY1D2h7nBTl862bOtnWDZjN23TJW5Vl75Abz/hbXvhluLV3NkLWcSTYTnsUqFPW6XINqodi3P60U3FOraT/aSpQdicA7bB0oa4uebOSEZ0kmwRhI9mlCDuhS94/z/qC4nY8A8qxaxnLKo5y4LmOOfSCGtN+YopKxSkGyMmvDwIR3LeS/9BQ8MmKkewbBtVMfWbXVzdbfins4CdxZtYe+GOT69hiC5a6Go3mhZu+MROUPPXKImn6xx7NbP3orr9ONv/S0MEjGsbyql0fBrlenTwGS12DjeXqW941B5GGtMOLpQtQ9rW0py+DLpLB5MUghWSLW39d9n25kkPO1BonYviM7NZp2CQsewc2PTVyIm8mwY1K//6KPOW+ZCskfnJ+GFtsty/GSCv33xRbPDzR8L5BefVN4zGVSY5/UPEdzjKpJvAkw4rq6sUkXVWtGAYWXsgT8hyTxutLvfpqq7qVx3PNwo7jhjlLPnlSie2et2naLl7sUoep15hN3Rpq04rbQHxzLpqxYsdoTOTedmhGbmEuqmmeeuyY8yuoJjfyFzkfazP0iAXGzyJy/5mS0+5Rk+UcQ9PC6Ej1l+qM6LKFBq5id9hq9cKPJW2G1sn0Cdsgca9ASbafe2kbO65p55o1vatbe7t2/C56+UUxsXexb5qAyBwtM07sm1xxdRS2bBualh01qXB5wp7PkJ2jlbeGMkUXQhoS0Khpy2qQWJyYKd7UuKC0XlsmCXvLsc/cKmt4vSx0hmAj2rjqOmSG3Zi1RK65/yh1B48YM+qf3jFESBKZxOa7py0blfvo+B3q6IJPAcDMzm7mhuvCeb59W3/vjtuKsobWVYpiFkyuY+AEf25uztNkPuInF74NoK9msdmsiMywVFPxyWvPmraGlpSn5Gg1sozwlBnJJ59dm7osGaJHwoXhQAjaj7mxAOs61hQtWqVfLTKLWvU7RCanIBVaJXB7O8M6AAAY6fV/ZxLb5iJ8hv2qYihEyeF1nK5i9uLpFZdu3PIN3g/23qXDJvFzfyOoH/WGd9M4jk5yxOYerKb6GppBrf6+qpVzGDMtG4j5ksFRqSOEle/qAgaAlDUA39OYyN8mLVK1+k/BIk0Aw6YFHEGPZGBjgYmSCiyEAiDFqC6miJEptA1AtC8DiMA3YHiuAE7gRw45sL/AJPMPLIIEkiXxNSmGPlmyFFvGAbpP0H0Mwnr5Iux+RFlcS2ltwHpFyjoLh/jEfLXCgLSJE/KbPDILEBQ9nM3D0LkIiaLBnreKOZ12CTOrTtz20Y8ulCCoxZ7oAHQ+ZbVeFIj12UXh+x8hqXBa1DDhVPYVIpneOjjY2iuQlSmoJjyUweyNdMQUEMApkMhHlnMngJyUIpCq9zJQj22pFQrJyY4WElrTdvcWf0+b4O6blF9LVEgzHC6PDeuLglRltmCOb9e34uQNY+aHrNogkw69KqHdaPfkm/mLpA51yUih9bhaUmr46CbHaTACAAAA') format('woff2'), 5 | url('iconfont.woff?t=1578036136452') format('woff'), 6 | url('iconfont.ttf?t=1578036136452') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ 7 | url('iconfont.svg?t=1578036136452#iconfont') format('svg'); /* iOS 4.1- */ 8 | } 9 | 10 | .iconfont { 11 | font-family: "iconfont" !important; 12 | font-size: 16px; 13 | font-style: normal; 14 | -webkit-font-smoothing: antialiased; 15 | -moz-osx-font-smoothing: grayscale; 16 | } 17 | 18 | .icon-yonghu:before { 19 | content: "\e603"; 20 | } 21 | 22 | .icon-mima:before { 23 | content: "\e62d"; 24 | } 25 | 26 | .icon-icon-test:before { 27 | content: "\e604"; 28 | } 29 | 30 | .icon-shangpinchuangjian:before { 31 | content: "\e61e"; 32 | } 33 | 34 | .icon-login_username:before { 35 | content: "\e6ca"; 36 | } 37 | 38 | .icon-quanxian:before { 39 | content: "\e656"; 40 | } 41 | 42 | .icon-5:before { 43 | content: "\e625"; 44 | } 45 | 46 | -------------------------------------------------------------------------------- /vue/src/assets/fonts/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxyShine/springboot_vue_shop/51a84521b42c18b3053ad8b848eb9443fa0f3afc/vue/src/assets/fonts/iconfont.eot -------------------------------------------------------------------------------- /vue/src/assets/fonts/iconfont.js: -------------------------------------------------------------------------------- 1 | !function(l){var t,i='',e=(t=document.getElementsByTagName("script"))[t.length-1].getAttribute("data-injectcss");if(e&&!l.__iconfont__svg__cssinject__){l.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(t){console&&console.log(t)}}!function(t){if(document.addEventListener)if(~["complete","loaded","interactive"].indexOf(document.readyState))setTimeout(t,0);else{var e=function(){document.removeEventListener("DOMContentLoaded",e,!1),t()};document.addEventListener("DOMContentLoaded",e,!1)}else document.attachEvent&&(c=t,n=l.document,o=!1,(i=function(){try{n.documentElement.doScroll("left")}catch(t){return void setTimeout(i,50)}a()})(),n.onreadystatechange=function(){"complete"==n.readyState&&(n.onreadystatechange=null,a())});function a(){o||(o=!0,c())}var c,n,o,i}(function(){var t,e,a,c,n,o;(t=document.createElement("div")).innerHTML=i,i=null,(e=t.getElementsByTagName("svg")[0])&&(e.setAttribute("aria-hidden","true"),e.style.position="absolute",e.style.width=0,e.style.height=0,e.style.overflow="hidden",a=e,(c=document.body).firstChild?(n=a,(o=c.firstChild).parentNode.insertBefore(n,o)):c.appendChild(a))})}(window); -------------------------------------------------------------------------------- /vue/src/assets/fonts/iconfont.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "", 3 | "name": "", 4 | "font_family": "iconfont", 5 | "css_prefix_text": "icon-", 6 | "description": "", 7 | "glyphs": [ 8 | { 9 | "icon_id": "725731", 10 | "name": "用户", 11 | "font_class": "yonghu", 12 | "unicode": "e603", 13 | "unicode_decimal": 58883 14 | }, 15 | { 16 | "icon_id": "925167", 17 | "name": "password", 18 | "font_class": "mima", 19 | "unicode": "e62d", 20 | "unicode_decimal": 58925 21 | }, 22 | { 23 | "icon_id": "1915205", 24 | "name": "数据统计", 25 | "font_class": "icon-test", 26 | "unicode": "e604", 27 | "unicode_decimal": 58884 28 | }, 29 | { 30 | "icon_id": "4948990", 31 | "name": "商品创建", 32 | "font_class": "shangpinchuangjian", 33 | "unicode": "e61e", 34 | "unicode_decimal": 58910 35 | }, 36 | { 37 | "icon_id": "8017608", 38 | "name": "login_username", 39 | "font_class": "login_username", 40 | "unicode": "e6ca", 41 | "unicode_decimal": 59082 42 | }, 43 | { 44 | "icon_id": "8802668", 45 | "name": "权限", 46 | "font_class": "quanxian", 47 | "unicode": "e656", 48 | "unicode_decimal": 58966 49 | }, 50 | { 51 | "icon_id": "11125637", 52 | "name": "订单", 53 | "font_class": "5", 54 | "unicode": "e625", 55 | "unicode_decimal": 58917 56 | } 57 | ] 58 | } 59 | -------------------------------------------------------------------------------- /vue/src/assets/fonts/iconfont.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | Created by iconfont 9 | 10 | 11 | 12 | 13 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /vue/src/assets/fonts/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxyShine/springboot_vue_shop/51a84521b42c18b3053ad8b848eb9443fa0f3afc/vue/src/assets/fonts/iconfont.ttf -------------------------------------------------------------------------------- /vue/src/assets/fonts/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxyShine/springboot_vue_shop/51a84521b42c18b3053ad8b848eb9443fa0f3afc/vue/src/assets/fonts/iconfont.woff -------------------------------------------------------------------------------- /vue/src/assets/fonts/iconfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxyShine/springboot_vue_shop/51a84521b42c18b3053ad8b848eb9443fa0f3afc/vue/src/assets/fonts/iconfont.woff2 -------------------------------------------------------------------------------- /vue/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxyShine/springboot_vue_shop/51a84521b42c18b3053ad8b848eb9443fa0f3afc/vue/src/assets/logo.png -------------------------------------------------------------------------------- /vue/src/components/Login.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 77 | 78 | 123 | -------------------------------------------------------------------------------- /vue/src/components/Main.vue: -------------------------------------------------------------------------------- 1 | 41 | 42 | 83 | 129 | -------------------------------------------------------------------------------- /vue/src/components/Welcome.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 16 | -------------------------------------------------------------------------------- /vue/src/components/goods/Add.vue: -------------------------------------------------------------------------------- 1 | 106 | 107 | 295 | 296 | 307 | -------------------------------------------------------------------------------- /vue/src/components/goods/List.vue: -------------------------------------------------------------------------------- 1 | 57 | 58 | 124 | 125 | 127 | -------------------------------------------------------------------------------- /vue/src/components/power/Rights.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 49 | 50 | 53 | -------------------------------------------------------------------------------- /vue/src/components/power/Roles.vue: -------------------------------------------------------------------------------- 1 | 64 | 65 | 84 | 85 | 100 | -------------------------------------------------------------------------------- /vue/src/components/user/Users.vue: -------------------------------------------------------------------------------- 1 | 112 | 113 | 279 | 280 | 282 | -------------------------------------------------------------------------------- /vue/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import router from './router' 4 | import './plugins/element.js' 5 | /* 导入全局样式 */ 6 | import './assets/css/global.css' 7 | /* 图标库 */ 8 | import './assets/fonts/iconfont.css' 9 | import axios from 'axios' 10 | axios.defaults.baseURL = 'http://localhost:1106' 11 | /* 请求拦截器,设置发送请求时携带token */ 12 | axios.interceptors.request.use(config => { 13 | config.headers.Authorization = window.sessionStorage.getItem('token') 14 | return config 15 | }) 16 | Vue.prototype.$axios = axios 17 | Vue.config.productionTip = false 18 | 19 | new Vue({ 20 | router, 21 | render: h => h(App) 22 | }).$mount('#app') 23 | -------------------------------------------------------------------------------- /vue/src/plugins/element.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import { Button, 3 | Input, 4 | Form, 5 | FormItem, 6 | Message, 7 | Header, 8 | Container, 9 | Aside, 10 | Main, 11 | Menu, 12 | MenuItem, 13 | MenuItemGroup, 14 | Submenu, 15 | Breadcrumb, 16 | BreadcrumbItem, 17 | Card, 18 | Select, 19 | Option, 20 | Row, 21 | Col, 22 | Table, 23 | TableColumn, 24 | Pagination, 25 | Switch, 26 | Tooltip, 27 | Dialog, 28 | MessageBox, 29 | Tag 30 | } from 'element-ui' 31 | 32 | Vue.use(Button) 33 | Vue.use(Input) 34 | Vue.use(Form) 35 | Vue.use(FormItem) 36 | Vue.use(Header) 37 | Vue.use(Container) 38 | Vue.use(Aside) 39 | Vue.use(Main) 40 | Vue.use(Menu) 41 | Vue.use(MenuItem) 42 | Vue.use(MenuItemGroup) 43 | Vue.use(Submenu) 44 | Vue.use(Breadcrumb) 45 | Vue.use(BreadcrumbItem) 46 | Vue.use(Card) 47 | Vue.use(Select) 48 | Vue.use(Option) 49 | Vue.use(Row) 50 | Vue.use(Col) 51 | Vue.use(TableColumn) 52 | Vue.use(Table) 53 | Vue.use(Pagination) 54 | Vue.use(Switch) 55 | Vue.use(Tooltip) 56 | Vue.use(Dialog) 57 | Vue.use(Tag) 58 | 59 | Vue.prototype.$message = Message 60 | Vue.prototype.$confirm = MessageBox.confirm 61 | -------------------------------------------------------------------------------- /vue/src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueRouter from 'vue-router' 3 | import Login from '../components/Login' 4 | import Main from '../components/Main' 5 | import Welcome from '../components/Welcome' 6 | import Users from '../components/user/Users' 7 | import Rights from '../components/power/Rights' 8 | import Roles from '../components/power/Roles' 9 | import Goods from '../components/goods/List' 10 | import Add from '../components/goods/Add' 11 | 12 | Vue.use(VueRouter) 13 | 14 | const routes = [ 15 | { path: '/', redirect: '/login' }, 16 | { path: '/login', component: Login }, 17 | { path: '/main', component: Main, redirect: '/welcome', children: [ 18 | { path: '/welcome', component: Welcome }, 19 | { path: '/rights', component: Rights }, 20 | { path: '/roles', component: Roles }, 21 | { path: '/users', component: Users }, 22 | { path: '/goods', component: Goods }, 23 | { path: '/goods/add', component: Add }] } 24 | 25 | ] 26 | 27 | const router = new VueRouter({ 28 | routes 29 | }) 30 | /* 挂载路由导航守卫 */ 31 | router.beforeEach((to, from, next) => { 32 | if (to.path === '/login') return next() 33 | let tokenStr = window.sessionStorage.getItem('token') 34 | /* 本地是否存有token */ 35 | if (tokenStr !== null && tokenStr !== 'undefined') { 36 | return next() 37 | } else { 38 | next('/login') 39 | } 40 | }) 41 | export default router 42 | --------------------------------------------------------------------------------