├── .gitignore ├── .idea ├── .gitignore ├── compiler.xml ├── dbnavigator.xml ├── encodings.xml ├── inspectionProfiles │ └── Project_Default.xml ├── jarRepositories.xml ├── misc.xml └── vcs.xml ├── .mvn └── wrapper │ └── maven-wrapper.properties ├── LICENSE ├── README.md ├── pom.xml ├── src ├── main │ ├── java │ │ └── com │ │ │ └── wms │ │ │ ├── WarehouseSystemApplication.java │ │ │ ├── common │ │ │ ├── AutoFillMetaInfoHandler.java │ │ │ ├── CodeGenerator.java │ │ │ ├── CorsConfig.java │ │ │ ├── MybatisPlusConfig.java │ │ │ ├── QueryPageParam.java │ │ │ └── Result.java │ │ │ ├── controller │ │ │ ├── GoodsController.java │ │ │ ├── GoodstypeController.java │ │ │ ├── MenuController.java │ │ │ ├── RecordController.java │ │ │ ├── StorageController.java │ │ │ └── UserController.java │ │ │ ├── entity │ │ │ ├── Goods.java │ │ │ ├── Goodstype.java │ │ │ ├── Menu.java │ │ │ ├── Record.java │ │ │ ├── RecordRes.java │ │ │ ├── Storage.java │ │ │ └── User.java │ │ │ ├── mapper │ │ │ ├── GoodsMapper.java │ │ │ ├── GoodstypeMapper.java │ │ │ ├── MenuMapper.java │ │ │ ├── RecordMapper.java │ │ │ ├── StorageMapper.java │ │ │ └── UserMapper.java │ │ │ └── service │ │ │ ├── GoodsService.java │ │ │ ├── GoodstypeService.java │ │ │ ├── Impl │ │ │ ├── GoodsServiceImpl.java │ │ │ ├── GoodstypeServiceImpl.java │ │ │ ├── MenuServiceImpl.java │ │ │ ├── RecordServiceImpl.java │ │ │ ├── StorageServiceImpl.java │ │ │ └── UserServiceImpl.java │ │ │ ├── MenuService.java │ │ │ ├── RecordService.java │ │ │ ├── StorageService.java │ │ │ └── UserService.java │ └── resources │ │ ├── application.yml │ │ └── mapper │ │ ├── GoodsMapper.xml │ │ ├── GoodstypeMapper.xml │ │ ├── MenuMapper.xml │ │ ├── RecordMapper.xml │ │ ├── StorageMapper.xml │ │ └── UserMapper.xml └── test │ └── java │ └── com │ └── wms │ └── WarehouseSystemApplicationTests.java ├── target └── classes │ ├── application.yml │ └── mapper │ ├── GoodsMapper.xml │ ├── GoodstypeMapper.xml │ ├── MenuMapper.xml │ ├── RecordMapper.xml │ ├── StorageMapper.xml │ └── UserMapper.xml └── wms.sql /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # 默认忽略的文件 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/dbnavigator.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 |
108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 |
123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 |
154 |
155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 |
553 | 554 | 555 | 556 |
-------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 14 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar 3 | -------------------------------------------------------------------------------- /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 | # 1. 项目概述 2 | 3 | 项目是基于SpringBoot+Vue前后端分离的仓库管理系统 4 | 5 | 后端:SpringBoot + MybatisPlus 6 | 7 | 前端:Node.js + Vue + element-ui 8 | 9 | 数据库:mysql 10 | 11 | 12 | 13 | # 2. 创建后端项目 14 | 15 | ## 2.1 创建模块 16 | 17 | 1. 创建项目模块 18 | 19 | ![QQ截图20230102145345](https://img.yiqiangshiyia.cn/blog/QQ%E6%88%AA%E5%9B%BE20230102145345.png) 20 | 21 | 2. 导入项目依赖 22 | 23 | pom.xml 24 | 25 | ```xml 26 | 27 | 29 | 4.0.0 30 | 31 | org.springframework.boot 32 | spring-boot-starter-parent 33 | 2.7.5 34 | 35 | 36 | com.wms 37 | Warehouse-System 38 | 0.0.1-SNAPSHOT 39 | Warehouse-System 40 | Warehouse management system 41 | 42 | 11 43 | 44 | 45 | 46 | org.springframework.boot 47 | spring-boot-starter 48 | 49 | 50 | org.springframework.boot 51 | spring-boot-starter-test 52 | test 53 | 54 | 55 | org.springframework.boot 56 | spring-boot-starter-web 57 | 58 | 59 | mysql 60 | mysql-connector-java 61 | 8.0.30 62 | runtime 63 | 64 | 65 | org.projectlombok 66 | lombok 67 | true 68 | 69 | 70 | 71 | com.baomidou 72 | mybatis-plus-boot-starter 73 | 3.4.1 74 | 75 | 76 | 77 | com.baomidou 78 | mybatis-plus-generator 79 | 3.4.1 80 | 81 | 82 | org.freemarker 83 | freemarker 84 | 2.3.30 85 | 86 | 87 | com.spring4all 88 | spring-boot-starter-swagger 89 | 1.5.1.RELEASE 90 | 91 | 92 | 93 | 94 | 95 | 96 | org.springframework.boot 97 | spring-boot-maven-plugin 98 | 99 | 100 | 101 | 102 | 103 | ``` 104 | 105 | 106 | 107 | ## 2.2 加入MybatisPlus支持 108 | 109 | 1. 导入依赖 110 | 111 | ```xml 112 | 113 | 114 | com.baomidou 115 | mybatis-plus-boot-starter 116 | 3.5.2 117 | 118 | ``` 119 | 120 | 2. 创建并连接数据库 121 | 122 | ![QQ截图20230102150422](https://img.yiqiangshiyia.cn/blog/QQ%E6%88%AA%E5%9B%BE20230102150422.png) 123 | 124 | 3. 配置端口和数据源 125 | 126 | application.yml 127 | 128 | ```yml 129 | server: 130 | port: 8002 131 | 132 | spring: 133 | datasource: 134 | url: jdbc:mysql://localhost:3306/wms?useUnicode=true&characterEncoding=utf-8&serveTimezone=UTC 135 | driver-class-name: com.mysql.cj.jdbc.Driver 136 | username: root 137 | password: 123456 138 | ``` 139 | 140 | 4. 编写实体类 141 | 142 | ```java 143 | @Data 144 | public class User { 145 | private int id; 146 | private String no; 147 | private String name; 148 | private String password; 149 | private int sex; 150 | private int roleId; 151 | private String phone; 152 | private String isvalid; 153 | } 154 | ``` 155 | 156 | 5. 编写Mapper接口 157 | 158 | ```java 159 | @Mapper 160 | public interface UserMapper extends BaseMapper { 161 | public List selectAll(); 162 | } 163 | ``` 164 | 165 | 6. 编写Service接口 166 | 167 | ```java 168 | public interface UserService extends IService { 169 | public List selectAll(); 170 | } 171 | ``` 172 | 173 | 7. 编写Service实现类 174 | 175 | ```java 176 | @Service 177 | public class UserServiceImpl extends ServiceImpl implements UserService { 178 | 179 | @Autowired 180 | private UserMapper userMapper; 181 | 182 | public List selectAll(){ 183 | return userMapper.selectAll(); 184 | } 185 | } 186 | ``` 187 | 188 | 8. 编写配置文件 189 | 190 | UserMapper.xml 191 | 192 | ```xml 193 | 194 | 196 | 197 | 200 | 201 | ``` 202 | 203 | 9. 编写测试代码 204 | 205 | ```java 206 | @RestController 207 | public class testController { 208 | @Autowired 209 | private UserService userService; 210 | 211 | @GetMapping 212 | public List test(){ 213 | return userService.selectAll(); 214 | } 215 | } 216 | ``` 217 | 218 | 10. 测试结果 219 | 220 | ![QQ截图20230102161434](https://img.yiqiangshiyia.cn/blog/QQ%E6%88%AA%E5%9B%BE20230102161434.png) 221 | 222 | 223 | 224 | # 3. 代码生成器 225 | 226 | > 简化开发:删除之前编写的实体类、接口、实现类、配置文件以及测试类,利用MyBatisPlus代码生成器自动生成代码 227 | 228 | 1. 导入依赖 229 | 230 | > 注意:MybatisPlus版本用3.4.1,3.5版本的MybatisPlus会报错! 231 | 232 | ```xml 233 | 234 | 235 | com.baomidou 236 | mybatis-plus-generator 237 | 3.4.1 238 | 239 | 240 | org.freemarker 241 | freemarker 242 | 2.3.30 243 | 244 | ``` 245 | 246 | 2. 编写代码生成器 247 | 248 | > 参考MybatisPlus官网:https://baomidou.com/pages/d357af/ 249 | 250 | ```java 251 | package com.wms.common; 252 | 253 | import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException; 254 | import com.baomidou.mybatisplus.core.toolkit.StringPool; 255 | import com.baomidou.mybatisplus.core.toolkit.StringUtils; 256 | import com.baomidou.mybatisplus.generator.AutoGenerator; 257 | import com.baomidou.mybatisplus.generator.InjectionConfig; 258 | import com.baomidou.mybatisplus.generator.config.*; 259 | import com.baomidou.mybatisplus.generator.config.po.TableInfo; 260 | import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; 261 | import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine; 262 | 263 | import java.util.ArrayList; 264 | import java.util.List; 265 | import java.util.Scanner; 266 | 267 | public class CodeGenerator { 268 | 269 | /** 270 | *

271 | * 读取控制台内容 272 | *

273 | */ 274 | public static String scanner(String tip) { 275 | Scanner scanner = new Scanner(System.in); 276 | StringBuilder help = new StringBuilder(); 277 | help.append("请输入" + tip + ":"); 278 | System.out.println(help.toString()); 279 | if (scanner.hasNext()) { 280 | String ipt = scanner.next(); 281 | if (StringUtils.isNotBlank(ipt)) { 282 | return ipt; 283 | } 284 | } 285 | throw new MybatisPlusException("请输入正确的" + tip + "!"); 286 | } 287 | 288 | public static void main(String[] args) { 289 | // 代码生成器 290 | AutoGenerator mpg = new AutoGenerator(); 291 | 292 | // 全局配置 293 | GlobalConfig gc = new GlobalConfig(); 294 | String projectPath = System.getProperty("user.dir"); 295 | gc.setOutputDir(projectPath + "/src/main/java"); 296 | gc.setAuthor("linsuwen"); 297 | gc.setOpen(false); 298 | gc.setSwagger2(true); //实体属性 Swagger2 注解 299 | gc.setBaseResultMap(true); // XML ResultMap 300 | gc.setBaseColumnList(true); // XML columList 301 | //去掉service接口首字母的I, 如DO为User则叫UserService 302 | gc.setServiceName("%sService"); 303 | mpg.setGlobalConfig(gc); 304 | 305 | // 数据源配置 306 | DataSourceConfig dsc = new DataSourceConfig(); 307 | dsc.setUrl("jdbc:mysql://localhost:3306/wms?useUnicode=true&characterEncoding=utf-8&serveTimezone=UTC"); 308 | // dsc.setSchemaName("public"); 309 | dsc.setDriverName("com.mysql.cj.jdbc.Driver"); 310 | dsc.setUsername("root"); 311 | dsc.setPassword("123456"); 312 | mpg.setDataSource(dsc); 313 | 314 | // 包配置 315 | PackageConfig pc = new PackageConfig(); 316 | //pc.setModuleName(scanner("模块名")); 317 | //模块配置 318 | pc.setParent("com.wms") 319 | .setEntity("entity") 320 | .setMapper("mapper") 321 | .setService("service") 322 | .setServiceImpl("service.Impl") 323 | .setController("controller"); 324 | mpg.setPackageInfo(pc); 325 | 326 | // 自定义配置 327 | InjectionConfig cfg = new InjectionConfig() { 328 | @Override 329 | public void initMap() { 330 | // to do nothing 331 | } 332 | }; 333 | 334 | // 如果模板引擎是 freemarker 335 | String templatePath = "/templates/mapper.xml.ftl"; 336 | // 如果模板引擎是 velocity 337 | // String templatePath = "/templates/mapper.xml.vm"; 338 | 339 | // 自定义输出配置 340 | List focList = new ArrayList<>(); 341 | // 自定义配置会被优先输出 342 | focList.add(new FileOutConfig(templatePath) { 343 | @Override 344 | public String outputFile(TableInfo tableInfo) { 345 | // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!! 346 | return projectPath + "/src/main/resources/mapper/" + pc.getModuleName() 347 | + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML; 348 | } 349 | }); 350 | 351 | cfg.setFileOutConfigList(focList); 352 | mpg.setCfg(cfg); 353 | 354 | // 配置模板 355 | TemplateConfig templateConfig = new TemplateConfig(); 356 | 357 | templateConfig.setXml(null); 358 | mpg.setTemplate(templateConfig); 359 | 360 | // 策略配置 361 | StrategyConfig strategy = new StrategyConfig(); 362 | strategy.setNaming(NamingStrategy.underline_to_camel); 363 | strategy.setColumnNaming(NamingStrategy.underline_to_camel); 364 | //strategy.setSuperEntityClass("你自己的父类实体,没有就不用设置!"); 365 | strategy.setEntityLombokModel(true); 366 | strategy.setRestControllerStyle(true); 367 | // 公共父类 368 | //strategy.setSuperControllerClass("你自己的父类控制器,没有就不用设置!"); 369 | // 写于父类中的公共字段 370 | //strategy.setSuperEntityColumns("id"); 371 | strategy.setInclude(scanner("表名,多个英文逗号分割").split(",")); 372 | strategy.setControllerMappingHyphenStyle(true); 373 | //strategy.setTablePrefix(pc.getModuleName() + "_"); 374 | mpg.setStrategy(strategy); 375 | mpg.setTemplateEngine(new FreemarkerTemplateEngine()); 376 | mpg.execute(); 377 | } 378 | 379 | } 380 | ``` 381 | 382 | 3. 运行代码生成器自动生成代码 383 | 384 | 生成结果: 385 | 386 | ![QQ截图20230102185756](https://img.yiqiangshiyia.cn/blog/QQ%E6%88%AA%E5%9B%BE20230102185756.png) 387 | 388 | 389 | 390 | # 4. 用户的增删改查 391 | 392 | ## 4.1 新增用户 393 | 394 | ```java 395 | /* 396 | * 新增用户 397 | * @author linsuwen 398 | * @date 2023/1/2 19:11 399 | */ 400 | @PostMapping("/save") 401 | public boolean save(@RequestBody User user){ 402 | return userService.save(user); 403 | } 404 | ``` 405 | 406 | 407 | 408 | ## 4.2 删除用户 409 | 410 | ```java 411 | /* 412 | * 删除用户 413 | * @author linsuwen 414 | * @date 2023/1/2 19:15 415 | */ 416 | @GetMapping("/delete") 417 | public boolean delete(Integer id){ 418 | return userService.removeById(id); 419 | } 420 | ``` 421 | 422 | 423 | 424 | ## 4.3 更新用户 425 | 426 | ```java 427 | /* 428 | * 更新用户 429 | * @author linsuwen 430 | * @date 2023/1/2 19:11 431 | */ 432 | @PostMapping("/update") 433 | public boolean update(@RequestBody User user){ 434 | return userService.updateById(user); 435 | } 436 | ``` 437 | 438 | ```java 439 | /* 440 | * 新增或修改:存在用户则修改,否则新增用户 441 | * @author linsuwen 442 | * @date 2023/1/2 19:12 443 | */ 444 | @PostMapping("/saveOrUpdate") 445 | public boolean saveOrUpdate(@RequestBody User user){ 446 | return userService.saveOrUpdate(user); 447 | } 448 | ``` 449 | 450 | 451 | 452 | ## 4.4 查询用户 453 | 454 | ```java 455 | /* 456 | * 查询全部用户 457 | * @author linsuwen 458 | * @date 2023/1/2 19:26 459 | */ 460 | @GetMapping("/list") 461 | public List list(){ 462 | return userService.list(); 463 | } 464 | ``` 465 | 466 | ```java 467 | /* 468 | * 模糊查询 469 | * @author linsuwen 470 | * @date 2023/1/2 19:36 471 | */ 472 | @PostMapping("/listP") 473 | public List query(@RequestBody User user){ 474 | LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); 475 | wrapper.eq(User::getName,user.getName()); 476 | return userService.list(wrapper); 477 | } 478 | ``` 479 | 480 | 481 | 482 | # 5. 分页的处理 483 | 484 | 1. 参数的封装 485 | 486 | > 注:可以不封装,在controller层用HashMap接收参数 487 | 488 | ```java 489 | package com.wms.common; 490 | /* 491 | * 分页参数的封装类 492 | * @author linsuwen 493 | * @date 2023/1/2 19:53 494 | */ 495 | @Data 496 | public class QueryPageParam { 497 | //设置默认值 498 | private static int PAGE_SIZE=20; 499 | private static int PAGE_NUM=1; 500 | 501 | private int pageSize=PAGE_SIZE; 502 | private int pageNum=PAGE_NUM; 503 | 504 | private HashMap param = new HashMap(); 505 | 506 | } 507 | ``` 508 | 509 | 2. 添加分页拦截器 510 | 511 | ```java 512 | /* 513 | * MybatisPlus分页拦截器 514 | * @author linsuwen 515 | * @date 2023/1/2 20:06 516 | */ 517 | @Configuration 518 | public class MybatisPlusConfig { 519 | @Bean 520 | public MybatisPlusInterceptor mybatisPlusInterceptor() { 521 | MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); 522 | interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); 523 | return interceptor; 524 | } 525 | } 526 | ``` 527 | 528 | 3. 编写分页的Mapper方法 529 | 530 | ```java 531 | /* 532 | * 分页查询 533 | * @author linsuwen 534 | * @date 2023/1/2 19:48 535 | */ 536 | @PostMapping("/lsitPage") 537 | public Result page(@RequestBody QueryPageParam query){ 538 | HashMap param = query.getParam(); 539 | String name = (String)param.get("name"); 540 | 541 | Page page = new Page(); 542 | page.setCurrent(query.getPageNum()); 543 | page.setSize(query.getPageSize()); 544 | 545 | LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); 546 | wrapper.like(User::getName,name); 547 | 548 | IPage result = userService.page(page,wrapper); 549 | return Result.success(result.getRecords(),result.getTotal()); 550 | } 551 | ``` 552 | 553 | 4. 自定义SQL使用Wrapper 554 | 555 | 556 | 557 | # 6. 返回前端数据的封装 558 | 559 | > 让前端收到统一的数据,方便处理 560 | 561 | ```java 562 | package com.wms.common; 563 | import lombok.Data; 564 | /* 565 | * 返回前端统一数据的封装类 566 | * @author linsuwen 567 | * @date 2023/1/2 20:36 568 | */ 569 | @Data 570 | public class Result { 571 | 572 | private int code; //编码 200/400 573 | private String msg; //成功/失败 574 | private Long total; //总记录数 575 | private Object data; //数据 576 | 577 | public static Result fail(){ 578 | return result(400,"失败",0L,null); 579 | } 580 | 581 | public static Result success(){ 582 | return result(200,"成功",0L,null); 583 | } 584 | 585 | public static Result success(Object data){ 586 | return result(200,"成功",0L,data); 587 | } 588 | 589 | public static Result success(Object data,Long total){ 590 | return result(200,"成功",total,data); 591 | } 592 | 593 | private static Result result(int code,String msg,Long total,Object data){ 594 | Result res = new Result(); 595 | res.setData(data); 596 | res.setMsg(msg); 597 | res.setCode(code); 598 | res.setTotal(total); 599 | return res; 600 | } 601 | 602 | } 603 | ``` 604 | 605 | 606 | 607 | # 7. 创建前端项目 608 | 609 | 1. 创建一个名为 Warehouse-System-Web 的工程 610 | 611 | ```shell 612 | npm init #项目初始化命令 613 | #如果想直接生成 package.json 文件,那么可以使用命令 614 | npm init -y 615 | ``` 616 | 617 | 2. 安装依赖 618 | 619 | ```shell 620 | #进入工程目录 621 | cd Warehouse-System-Web 622 | #安装vue-router 623 | npm install vue-router --save-dev 624 | #安装element-ui 625 | npm i element-ui -S 626 | #安装依赖 627 | npm install 628 | #安装SASS加载器 629 | cnpm install sass-loader node-sass --save-dev 630 | ``` 631 | 632 | 3. 启动项目 633 | 634 | ```shell 635 | #启动测试 636 | npm run serve 637 | ``` 638 | 639 | ![QQ截图20230102220417](https://img.yiqiangshiyia.cn/blog/QQ%E6%88%AA%E5%9B%BE20230102220417.png) 640 | 641 | 642 | 643 | # 8. 编写前端页面 644 | 645 | ## 8.1 搭建页面布局 646 | 647 | > 参考Element-ui Container 布局容器:https://element.eleme.cn/#/zh-CN/component/container 648 | 649 | Index.vue:整体页面布局 Vue 组件 650 | 651 | 652 | 653 | ## 8.2 页面布局拆分 654 | 655 | 从 Index.vue 中拆分出 Aside.vue 和 Header.vue 组件后,然后在 Index.vue 再导入拆分出去的组件 656 | 657 | ```js 658 | import Aside from "./Aside"; 659 | import Header from "./Header"; 660 | ``` 661 | 662 | 663 | 664 | ## 8.3 编写头部页面 665 | 666 | > 编写步骤: 667 | 668 | 1. dropdown下拉 669 | 2. 菜单伸缩图标 670 | 3. 欢迎字样 671 | 4. 去除背景,加入下拉框 672 | 673 | > 代码实现: 674 | 675 | ```vue 676 | 677 | 698 | 699 | 704 | 705 | 708 | ``` 709 | 710 | 711 | 712 | ## 8.4 编写导航菜单页面 713 | 714 | ```vue 715 | 716 | 739 | 740 | 745 | 746 | 749 | ``` 750 | 751 | 752 | 753 | ## 8.5 菜单导航页面伸缩 754 | 755 | 菜单导航页面伸缩思路: 756 | 757 | 1. header点击图标提交 758 | 2. 父组件改变 759 | 3. aside子组件(collapse) 760 | 761 | 762 | 763 | # 9. 安装axios与跨域处理 764 | 765 | > **Axios:**Axios是一个基于promise 的 HTTP 库,可以用在浏览器和 node.js中。 766 | > 767 | > **Ajax:**Ajax即**A**synchronous **J**avascript **A**nd **X**ML(异步JavaScript和[ XML])在 2005年被Jesse James Garrett提出的新术语,用来描述一种使用现有技术集合的'新'方法,包括:HTML 或 XHTML,CSS,JavaScript,DOM,XML,XSLT以及最重要的 XMLHttpRequest。使用Ajax技术网页应用能够快速地将增量更新呈现在用户界面上,而不需要重载(刷新)整个页面,这使得程序能够更快地回应用户的操作。 768 | > 769 | > **Axios与Ajax的区别:** 770 | > 771 | > 1. axios是一个基于Promise的HTTP库,而ajax是对原生XHR的封装。 772 | > 2. ajax技术实现了局部数据的刷新,而axios实现了对ajax的封装。 773 | 774 | > **什么是跨域访问:**说到跨域访问,必须先解释一个名词:同源策略。所谓同源策略就是在浏览器端出于安全考量,向服务端发起请求必须满足:协议相同、Host(ip)相同、端口相同的条件,否则访问将被禁止,该访问也就被称为跨域访问。 775 | > 776 | > 虽然跨域访问被禁止之后,可以在一定程度上提高了应用的安全性,但也为开发带来了一定的麻烦。比如:我们开发一个前后端分离的易用,页面及js部署在一个主机的nginx服务中,后端接口部署在一个tomcat应用容器中,当前端向后端发起请求的时候一定是不符合同源策略的,也就无法访问。 777 | > 778 | > **SpringBoot下解决跨域问题的四种方式:** 779 | > 780 | > 1. 使用CorsFilter进行全局跨域配置 781 | > 2. 重写WebMvcConfigurer的addCorsMappings方法(全局跨域配置) 782 | > 3. 使用CrossOrigin注解(局部跨域配置) 783 | > 4. 使用HttpServletResponse设置响应头(局部跨域配置) 784 | > 785 | > 参考文章:https://cloud.tencent.com/developer/news/472954 786 | 787 | **安装axios与跨域处理:** 788 | 789 | 1. 安装axios 790 | 791 | ```shell 792 | npm install axios --save 793 | ``` 794 | 795 | 2. 在main.js全局引⼊axios 796 | 797 | ```shell 798 | import axios from "axios"; 799 | Vue.prototype.$axios =axios; 800 | ``` 801 | 802 | 3. 解决跨域问题 803 | 804 | 重写WebMvcConfigurer的addCorsMappings方法(全局跨域配置): 805 | 806 | ```java 807 | package com.wms.common; 808 | /* 809 | * 解决跨域问题:重写WebMvcConfigurer的addCorsMappings方法(全局跨域配置) 810 | * @author linsuwen 811 | * @date 2023/1/3 1:30 812 | */ 813 | @Configuration 814 | public class CorsConfig implements WebMvcConfigurer { 815 | 816 | @Override 817 | public void addCorsMappings(CorsRegistry registry) { 818 | registry.addMapping("/**") 819 | //是否发送Cookie 820 | .allowCredentials(true) 821 | //放行哪些原始域 822 | .allowedOriginPatterns("*") 823 | .allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE"}) 824 | .allowedHeaders("*") 825 | .exposedHeaders("*"); 826 | } 827 | } 828 | ``` 829 | 830 | 4. 测试请求 831 | 832 | get请求的使⽤: 833 | 834 | ```js 835 | this.$axios.get('http://localhost:8002/user/list').then(res=>{ 836 | console.log(res) 837 | }) 838 | ``` 839 | 840 | post请求的使用: 841 | 842 | ```js 843 | this.$axios.post('http://localhost:8002/user/query',{}).then(res=>{ 844 | console.log(res) 845 | }) 846 | ``` 847 | 848 | 5. 将地址设置为全局 849 | 850 | main.js 851 | 852 | ```js 853 | Vue.prototype.$httpUrl='http://localhost:8002' //将地址设置为全局 854 | ``` 855 | 856 | 857 | 858 | # 10. 登录退出功能 859 | 860 | ## 10.1 登录功能 861 | 862 | 1. 编写登录页面 863 | 864 | Login.vue 865 | 866 | ![QQ截图20230103144539](https://img.yiqiangshiyia.cn/blog/QQ%E6%88%AA%E5%9B%BE20230103144539.png) 867 | 868 | 2. 后台查询登录代码 869 | 870 | ```java 871 | /* 872 | * 用户登录 873 | * @author linsuwen 874 | * @date 2023/1/3 14:08 875 | */ 876 | @PostMapping("/login") 877 | public Result login(@RequestBody User user){ 878 | //匹配账号和密码 879 | List list = userService.lambdaQuery() 880 | .eq(User::getNo,user.getNo()) 881 | .eq(User::getPassword,user.getPassword()) 882 | .list(); 883 | return list.size()>0?Result.success(list.get(0)):Result.fail(); 884 | } 885 | ``` 886 | 887 | 3. 登录页面的路由跳转 888 | 889 | 安装路由插件 890 | 891 | ```shell 892 | npm i vue-router@3.5.4 893 | ``` 894 | 895 | 创建路由文件(router目录下的index.js文件),访问路由跳转到登录页面 896 | 897 | ```js 898 | import VueRouter from 'vue-router'; 899 | 900 | const routes = [ 901 | { 902 | path:'/', 903 | name:'login', 904 | component:()=>import('../components/Login') 905 | } 906 | ] 907 | 908 | const router = new VueRouter({ 909 | mode:'history', 910 | routes 911 | }) 912 | 913 | export default router; 914 | ``` 915 | 916 | 在main.js中注册路由 917 | 918 | ```js 919 | import VueRouter from 'vue-router'; 920 | import router from './router'; 921 | Vue.use(VueRouter); 922 | new Vue({ 923 | router, 924 | render: h => h(App), 925 | }).$mount('#app') 926 | ``` 927 | 928 | 4. 主页的路由(接收路由) 929 | 930 | App.vue 931 | 932 | ```vue 933 | 938 | 939 | 949 | 950 | 955 | ``` 956 | 957 | 5. 登录成功后页面跳转到首页 958 | 959 | ... 960 | 961 | http://localhost:8081/ 跳转到 http://localhost:8081/index 962 | 963 | 964 | 965 | ## 10.2 退出登录功能 966 | 967 | 1. 展示名字(Header.vue) 968 | 969 | ```vue 970 | 971 | 972 | {{user.name}} 973 | 974 | 个人中心 975 | 退出登录 976 | 977 | 978 | 979 | data(){ 980 | return { 981 | user : JSON.parse(sessionStorage.getItem('CurUser')) 982 | } 983 | } 984 | ``` 985 | 986 | 2. 退出登录事件 987 | 988 | ```vue 989 | 退出登录 990 | ``` 991 | 992 | 3. 退出跳转、清空相关数据以及退出确认 993 | 994 | ```js 995 | logout(){ 996 | console.log('logout') 997 | 998 | this.$confirm('您确定要退出登录吗?', '提示', { 999 | confirmButtonText: '确定', //确认按钮的文字显示 1000 | type: 'warning', 1001 | center: true, //文字居中显示 1002 | 1003 | }) 1004 | .then(() => { 1005 | this.$message({ 1006 | type:'success', 1007 | message:'退出登录成功!' 1008 | }) 1009 | 1010 | this.$router.push("/") 1011 | sessionStorage.clear() 1012 | }) 1013 | .catch(() => { 1014 | this.$message({ 1015 | type:'info', 1016 | message:'已取消退出登录!' 1017 | }) 1018 | }) 1019 | 1020 | } 1021 | ``` 1022 | 1023 | 1024 | 1025 | ## 10.3 个人中心 1026 | 1027 | 1. 编写页面 1028 | 1029 | 2. 路由跳转(Header.vue) 1030 | 1031 | ```vue 1032 | 个人中心 1033 | methods:{ 1034 | toUser(){ 1035 | console.log('to_user') 1036 | 1037 | this.$router.push("/Home") 1038 | } 1039 | } 1040 | ``` 1041 | 1042 | 3. 路由错误解决(router/index.js) 1043 | 1044 | ```js 1045 | const VueRouterPush = VueRouter.prototype.push 1046 | VueRouter.prototype.push = function push (to) { 1047 | return VueRouterPush.call(this, to).catch(err => err) 1048 | } 1049 | ``` 1050 | 1051 | 1052 | 1053 | # 11. 菜单展示 1054 | 1055 | ## 11.1 菜单跳转 1056 | 1057 | 1. 菜单增加router、高亮 1058 | 1059 | ```vue 1060 | 1070 | ``` 1071 | 1072 | 2. 配置子菜单 1073 | 1074 | ```js 1075 | data(){ 1076 | return { 1077 | menu:[ 1078 | { 1079 | menuClick:'Admin', 1080 | menuName:'管路员管理', 1081 | menuIcon:'el-icon-s-custom' 1082 | },{ 1083 | menuClick:'User', 1084 | menuName:'用户管理', 1085 | menuIcon:'el-icon-user-solid' 1086 | } 1087 | ] 1088 | } 1089 | } 1090 | } 1091 | ``` 1092 | 1093 | 3. 模拟动态menu 1094 | 1095 | ```vue 1096 | 1097 | 1098 | {{item.menuName}} 1099 | 1100 | ``` 1101 | 1102 | 1103 | 1104 | ## 11.2 动态路由 1105 | 1106 | > **vuex状态管理:** 1107 | > 1108 | > vuex是专为vue.js应用程序开发的状态管理模式。它采用集中存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。 1109 | > 1110 | > Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。 1111 | > 1112 | > 状态管理有5个核心,分别是state、getter、mutation、action以及module。 1113 | 1114 | > **动态路由的实现:** 1115 | 1116 | 1. 设计menu表和数据 1117 | 1118 | ```mysql 1119 | CREATE TABLE `menu` ( 1120 | `id` int NOT NULL, 1121 | `menuCode` varchar(8) DEFAULT NULL COMMENT '菜单编码', 1122 | `menuName` varchar(16) DEFAULT NULL COMMENT '菜单名字', 1123 | `menuLevel` varchar(2) DEFAULT NULL COMMENT '菜单级别', 1124 | `menuParentCode` varchar(8) DEFAULT NULL COMMENT '菜单的父code', 1125 | `menuClick` varchar(16) DEFAULT NULL COMMENT '点击触发的函数', 1126 | `menuRight` varchar(8) DEFAULT NULL COMMENT '权限 0超级管理员,1表示管理员,2表示普通用户,可以用逗号组合使用', 1127 | `menuComponent` varchar(200) DEFAULT NULL, 1128 | `menuIcon` varchar(100) DEFAULT NULL, 1129 | PRIMARY KEY (`id`) 1130 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; 1131 | ``` 1132 | 1133 | ```mysql 1134 | INSERT INTO `menu` VALUES (1, '001', '管理员管理', '1', NULL, 'Admin', '0', 'admin/AdminManage.vue', 'el-icon-s-custom'); 1135 | INSERT INTO `menu` VALUES (2, '002', '用户管理', '1', NULL, 'User', '0,1', 'user/UserManage.vue', 'el-icon-user-solid'); 1136 | INSERT INTO `menu` VALUES (3, '003', '仓库管理', '1', NULL, 'Storage', '0,1', 'storage/StorageManage', 'el-icon-office-building'); 1137 | INSERT INTO `menu` VALUES (4, '004', '物品分类管理', '1', NULL, 'Goodstype', '0,1', 'goodstype/GoodstypeManage', 'el-icon-menu'); 1138 | INSERT INTO `menu` VALUES (5, '005', '物品管理 ', '1', NULL, 'Goods', '0,1,2', 'goods/GoodsManage', 'el-icon-s-management'); 1139 | INSERT INTO `menu` VALUES (6, '006', '记录管理', '1', NULL, 'Record', '0,1,2', 'record/RecordManage', 'el-icon-s-order'); 1140 | ``` 1141 | 1142 | 2. 生成menu对应的后端代码 1143 | 1144 | ```java 1145 | /* 1146 | * 根据用户身份获取菜单列表 1147 | * @author linsuwen 1148 | * @date 2023/1/3 20:48 1149 | */ 1150 | @GetMapping("/list") 1151 | public Result list(@RequestParam String roleId){ 1152 | List list = menuService.lambdaQuery() 1153 | .like(Menu::getMenuright,roleId) 1154 | .list(); 1155 | return Result.success(list); 1156 | } 1157 | ``` 1158 | 1159 | 3. 返回前端数据 1160 | 1161 | 思路:登录的时候一并查询 menu,这样只需要异步查询一次即可将菜单页面展示出来 1162 | 1163 | 修改后端UserController中的登录代码,将用户角色数据和用户角色对应的菜单数据返回给前端 1164 | 1165 | ```java 1166 | /* 1167 | * 用户登录 1168 | * @author linsuwen 1169 | * @date 2023/1/3 14:08 1170 | */ 1171 | @PostMapping("/login") 1172 | public Result login(@RequestBody User user){ 1173 | //匹配账号和密码 1174 | List list = userService.lambdaQuery() 1175 | .eq(User::getNo,user.getNo()) 1176 | .eq(User::getPassword,user.getPassword()) 1177 | .list(); 1178 | 1179 | if(list.size()>0){ 1180 | User user1 = list.get(0); 1181 | List menuList = menuService.lambdaQuery() 1182 | .like(Menu::getMenuright,user1.getRoleId()) 1183 | .list(); 1184 | HashMap res = new HashMap(); 1185 | res.put("user",user1); 1186 | res.put("menu",menuList); 1187 | return Result.success(res); 1188 | } 1189 | return Result.fail(); 1190 | } 1191 | ``` 1192 | 1193 | 4. vuex状态管理 1194 | 1195 | 安装vuex状态管理 1196 | 1197 | ```shell 1198 | npm i vuex@3.0.0 1199 | ``` 1200 | 1201 | 编写store 1202 | 1203 | ```js 1204 | import vue from 'vue' 1205 | import Vuex from 'vuex' 1206 | vue.use(Vuex) 1207 | //... 1208 | ``` 1209 | 1210 | 编写vue状态管理(store/index.js) 1211 | 1212 | ```js 1213 | export default new Vuex.Store({ 1214 | state: { 1215 | menu: [] 1216 | }, 1217 | mutations: { 1218 | setMenu(state,menuList) { 1219 | state.menu = menuList 1220 | 1221 | addNewRoute(menuList) 1222 | } 1223 | }, 1224 | getters: { 1225 | getMenu(state) { 1226 | return state.menu 1227 | } 1228 | } 1229 | }) 1230 | ``` 1231 | 1232 | 在main.js中注册 1233 | 1234 | ```js 1235 | import store from "./store" 1236 | ``` 1237 | 1238 | 5. 存储数据(Login.vue) 1239 | 1240 | 将登录时从后台查询到的菜单数据存储到vuex状态管理中 1241 | 1242 | ```js 1243 | //存储 1244 | sessionStorage.setItem("CurUser",JSON.stringify(res.data.user)) 1245 | console.log(res.data.menu) 1246 | this.$store.commit("setMenu",res.data.menu) 1247 | ``` 1248 | 1249 | 6. 生成menu数据 1250 | 1251 | Aside.vue 1252 | 1253 | ```vue 1254 | 1255 | 1256 | 1257 | {{item.menuname}} 1258 | 1259 | ``` 1260 | 1261 | 7. 生成路由数据 1262 | 1263 | 获取路由列表(store/index.js) 1264 | 1265 | ```js 1266 | let routes = router.options.routes 1267 | ``` 1268 | 1269 | 组装路由 1270 | 1271 | ```js 1272 | routes.forEach(routeItem=>{ 1273 | if(routeItem.path=="/Index"){ 1274 | menuList.forEach(menu=>{ 1275 | let childRoute = { 1276 | path:'/'+menu.menuclick, 1277 | name:menu.menuname, 1278 | meta:{ 1279 | title:menu.menuname 1280 | }, 1281 | component:()=>import('../components/'+menu.menucomponent) 1282 | } 1283 | 1284 | routeItem.children.push(childRoute) 1285 | }) 1286 | } 1287 | }) 1288 | ``` 1289 | 1290 | 合并路由 1291 | 1292 | ```js 1293 | router.addRoutes(routes) 1294 | ``` 1295 | 1296 | 错误处理 1297 | 1298 | ```js 1299 | export function resetRouter() { 1300 | router.matcher = new VueRouter({ 1301 | mode:'history', 1302 | routes: [] 1303 | }).matcher 1304 | } 1305 | ``` 1306 | 1307 | 1308 | 1309 | ## 11.3 菜单展示 1310 | 1311 | ![QQ截图20230104224949](https://img.yiqiangshiyia.cn/blog/QQ%E6%88%AA%E5%9B%BE20230104224949.png) 1312 | 1313 | 1314 | 1315 | # 12. 管理员管理 1316 | 1317 | ## 12.1 列表展示 1318 | 1319 | 1. 列表数据 1320 | 1321 | 后端给前端返回列表数据 1322 | 1323 | 2. ⽤tag转换列 1324 | 1325 | 数据库字段sex(0,1)=> 前端性别显示(男,女) 1326 | 1327 | ```vue 1328 | 1333 | ``` 1334 | 1335 | 3. header-cell-style设置表头样式 1336 | 1337 | ```vue 1338 | 1341 | ``` 1342 | 1343 | 4. 加上边框 1344 | 1345 | ```vue 1346 | 1350 | ``` 1351 | 1352 | 5. 按钮(编辑、删除) 1353 | 1354 | ```vue 1355 | 1356 | 1366 | 1367 | ``` 1368 | 1369 | 6. 后端返回结果封装(Result) 1370 | 1371 | ```java 1372 | /* 1373 | * 模糊查询 1374 | * @author linsuwen 1375 | * @date 2023/1/2 19:36 1376 | */ 1377 | @PostMapping("/listP") 1378 | public Result query(@RequestBody User user){ 1379 | LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); 1380 | if(StringUtils.isNotBlank(user.getName())){ 1381 | wrapper.like(User::getName,user.getName()); 1382 | } 1383 | return Result.success(userService.list(wrapper)); 1384 | } 1385 | ``` 1386 | 1387 | 1388 | 1389 | ## 12.2 分页处理 1390 | 1391 | 1. 页面加上分页代码 1392 | 1393 | ```vue 1394 | 1402 | 1403 | ``` 1404 | 1405 | 2. 修改查询方法和参数 1406 | 1407 | ```js 1408 | loadPost(){ 1409 | this.$axios.post(this.$httpUrl+'/user/listPageC1',{ 1410 | pageSize:this.pageSize, 1411 | pageNum:this.pageNum, 1412 | param:{ 1413 | name:this.name, 1414 | sex:this.sex 1415 | } 1416 | }).then(res=>res.data).then(res=>{ 1417 | console.log(res) 1418 | if(res.code==200){ 1419 | this.tableData=res.data 1420 | this.total=res.total 1421 | }else{ 1422 | alert('获取数据失败') 1423 | } 1424 | 1425 | }) 1426 | } 1427 | ``` 1428 | 1429 | 3. 处理翻页、设置条数逻辑 1430 | 1431 | ```js 1432 | handleSizeChange(val) { 1433 | console.log(`每页 ${val} 条`); 1434 | this.pageNum=1 1435 | this.pageSize=val 1436 | this.loadPost() 1437 | }, 1438 | handleCurrentChange(val) { 1439 | console.log(`当前页: ${val}`); 1440 | this.pageNum=val 1441 | this.loadPost() 1442 | }, 1443 | ``` 1444 | 1445 | 4. 后端逻辑处理 1446 | 1447 | ```java 1448 | @PostMapping("/listPageC") 1449 | public List listPageC(@RequestBody QueryPageParam query){ 1450 | HashMap param = query.getParam(); 1451 | String name = (String)param.get("name"); 1452 | System.out.println("name=>"+(String)param.get("name")); 1453 | 1454 | Page page = new Page(); 1455 | page.setCurrent(query.getPageNum()); 1456 | page.setSize(query.getPageSize()); 1457 | 1458 | LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper(); 1459 | lambdaQueryWrapper.like(User::getName,name); 1460 | 1461 | IPage result = userService.pageCC(page,lambdaQueryWrapper); 1462 | 1463 | System.out.println("total=>"+result.getTotal()); 1464 | 1465 | return result.getRecords(); 1466 | } 1467 | ``` 1468 | 1469 | 1470 | 1471 | ## 12.3 查询功能 1472 | 1473 | 1. 查询的布局(包含查询、重置按钮) 1474 | 1475 | ```vue 1476 |
1477 | 查询 1478 | 重置 1479 | 1480 | 新增 1481 |
1482 | ``` 1483 | 1484 | 2. 输入框 1485 | 1486 | ```vue 1487 | 1489 | ``` 1490 | 1491 | 3. 下拉框 1492 | 1493 | ```vue 1494 | 1495 | 1500 | 1501 | 1502 | ``` 1503 | 1504 | 4. 回车事件(查询) 1505 | 1506 | ```js 1507 | @keyup.enter.native="loadPost" 1508 | ``` 1509 | 1510 | 5. 重置处理 1511 | 1512 | ```vue 1513 | 重置 1514 | ``` 1515 | 1516 | 6. 后端逻辑处理 1517 | 1518 | ```java 1519 | /* 1520 | * 查询功能:根据前端表单输入的信息或者下拉框选择查询用户,并以分页的形式返回前端 1521 | * @author linsuwen 1522 | * @date 2023/1/4 20:28 1523 | */ 1524 | @PostMapping("/listPageC1") 1525 | public Result listPageC1(@RequestBody QueryPageParam query){ 1526 | HashMap param = query.getParam(); 1527 | String name = (String)param.get("name"); 1528 | String sex = (String)param.get("sex"); 1529 | String roleId = (String)param.get("roleId"); 1530 | 1531 | Page page = new Page(); 1532 | page.setCurrent(query.getPageNum()); 1533 | page.setSize(query.getPageSize()); 1534 | 1535 | LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper(); 1536 | if(StringUtils.isNotBlank(name) && !"null".equals(name)){ 1537 | lambdaQueryWrapper.like(User::getName,name); 1538 | } 1539 | if(StringUtils.isNotBlank(sex)){ 1540 | lambdaQueryWrapper.eq(User::getSex,sex); 1541 | } 1542 | if(StringUtils.isNotBlank(roleId)){ 1543 | lambdaQueryWrapper.eq(User::getRoleId,roleId); 1544 | } 1545 | 1546 | IPage result = userService.pageCC(page,lambdaQueryWrapper); 1547 | 1548 | System.out.println("total=="+result.getTotal()); 1549 | 1550 | return Result.success(result.getRecords(),result.getTotal()); 1551 | } 1552 | ``` 1553 | 1554 | 1555 | 1556 | ## 12.4 新增功能 1557 | 1558 | 1. 新增按钮(Main.vue) 1559 | 1560 | ```vue 1561 | 新增 1562 | ``` 1563 | 1564 | 2. 弹出窗口 1565 | 1566 | ```js 1567 | add(){ 1568 | this.centerDialogVisible = true 1569 | this.$nextTick(()=>{ 1570 | this.resetForm() 1571 | }) 1572 | } 1573 | ``` 1574 | 1575 | 3. 编写表单(Main.vue) 1576 | 1577 | ```vue 1578 | 1583 | 1584 | 1585 | 1586 | 1587 | 1588 | 1589 | 1590 | 1591 | 1592 | 1593 | 1594 | 1595 | 1596 | 1597 | 1598 | 1599 | 1600 | 1601 | 1602 | 1603 | 1604 | 1605 | 1606 | 1607 | 1608 | 1609 | 1610 | 1611 | 1612 | 1613 | 1614 | 1615 | 1616 | 1617 | 1618 | 取 消 1619 | 确 定 1620 | 1621 | 1622 | ``` 1623 | 1624 | 4. 提交数据(提示信息、列表刷新) 1625 | 1626 | 前端提交数据(Main.vue) 1627 | 1628 | ```js 1629 | doSave({ 1630 | this.$axios.post(this.$httpUrl+'/user/save',this.form).then(res=>res.data).then(res=>{ 1631 | console.log(res) 1632 | if(res.code==200){ 1633 | 1634 | this.$message({ 1635 | message: '操作成功!', 1636 | type: 'success' 1637 | }); 1638 | this.centerDialogVisible = false 1639 | this.loadPost() //成功后刷新加载数据 1640 | this. resetForm() 1641 | }else{ 1642 | this.$message({ 1643 | message: '操作失败!', 1644 | type: 'error' 1645 | }); 1646 | } 1647 | 1648 | }) 1649 | } 1650 | ``` 1651 | 1652 | 后端接收前端提交的数据并将数据存入数据库中 1653 | 1654 | ```java 1655 | /* 1656 | * 新增用户 1657 | * @author linsuwen 1658 | * @date 2023/1/2 19:11 1659 | */ 1660 | @PostMapping("/save") 1661 | public Result save(@RequestBody User user){ 1662 | return userService.save(user)?Result.success():Result.fail(); 1663 | } 1664 | ``` 1665 | 1666 | 5. 数据的检查 1667 | 1668 | 检查所输入数据(Main.vue) 1669 | 1670 | ```js 1671 | rules: { 1672 | no: [ 1673 | {required: true, message: '请输入账号', trigger: 'blur'}, 1674 | {min: 3, max: 8, message: '长度在 3 到 8 个字符', trigger: 'blur'}, 1675 | {validator:checkDuplicate,trigger: 'blur'} 1676 | ], 1677 | name: [ 1678 | {required: true, message: '请输入名字', trigger: 'blur'} 1679 | ], 1680 | password: [ 1681 | {required: true, message: '请输入密码', trigger: 'blur'}, 1682 | {min: 3, max: 8, message: '长度在 3 到 8 个字符', trigger: 'blur'} 1683 | ], 1684 | age: [ 1685 | {required: true, message: '请输入年龄', trigger: 'blur'}, 1686 | {min: 1, max: 3, message: '长度在 1 到 3 个位', trigger: 'blur'}, 1687 | {pattern: /^([1-9][0-9]*){1,3}$/,message: '年龄必须为正整数字',trigger: "blur"}, 1688 | {validator:checkAge,trigger: 'blur'} 1689 | ], 1690 | phone: [ 1691 | {required: true,message: "手机号不能为空",trigger: "blur"}, 1692 | {pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "请输入正确的手机号码", trigger: "blur"} 1693 | ] 1694 | } 1695 | ``` 1696 | 1697 | ```js 1698 | let checkAge = (rule, value, callback) => { 1699 | if(value>150){ 1700 | callback(new Error('年龄输入过大')); 1701 | }else{ 1702 | callback(); 1703 | } 1704 | }; 1705 | ``` 1706 | 1707 | 6. 账号的唯一验证 1708 | 1709 | 检查账号是否已经存在(Main.vue) 1710 | 1711 | ```js 1712 | let checkDuplicate =(rule,value,callback)=>{ 1713 | if(this.form.id){ 1714 | return callback(); 1715 | } 1716 | this.$axios.get(this.$httpUrl+"/user/findByNo?no="+this.form.no).then(res=>res.data).then(res=>{ 1717 | if(res.code!=200){ 1718 | callback() 1719 | }else{ 1720 | callback(new Error('账号已经存在')); 1721 | } 1722 | }) 1723 | }; 1724 | ``` 1725 | 1726 | 后端查询用户 1727 | 1728 | ```java 1729 | /* 1730 | * 根据账号查找用户 1731 | * @author linsuwen 1732 | * @date 2023/1/4 14:53 1733 | */ 1734 | @GetMapping("/findByNo") 1735 | public Result findByNo(@RequestParam String no){ 1736 | List list = userService.lambdaQuery() 1737 | .eq(User::getNo,no) 1738 | .list(); 1739 | return list.size()>0?Result.success(list):Result.fail(); 1740 | } 1741 | ``` 1742 | 1743 | 7. 表单重置 1744 | 1745 | 1746 | 1747 | ## 12.5 编辑功能 1748 | 1749 | 1. 传递数据到表单(Main.vue) 1750 | 1751 | ```vue 1752 | 删除 1753 | ``` 1754 | 1755 | ```js 1756 | mod(row){ 1757 | console.log(row) 1758 | 1759 | this.centerDialogVisible = true 1760 | this.$nextTick(()=>{ 1761 | //赋值到表单 1762 | this.form.id = row.id 1763 | this.form.no = row.no 1764 | this.form.name = row.name 1765 | this.form.password = '' 1766 | this.form.age = row.age +'' 1767 | this.form.sex = row.sex +'' 1768 | this.form.phone = row.phone 1769 | this.form.roleId = row.roleId 1770 | }) 1771 | }, 1772 | ``` 1773 | 1774 | 2. 提交数据到后台 1775 | 1776 | ```js 1777 | doMod(){ 1778 | this.$axios.post(this.$httpUrl+'/user/update',this.form).then(res=>res.data).then(res=>{ 1779 | console.log(res) 1780 | if(res.code==200){ 1781 | 1782 | this.$message({ 1783 | message: '操作成功!', 1784 | type: 'success' 1785 | }); 1786 | this.centerDialogVisible = false 1787 | this.loadPost() 1788 | this. resetForm() 1789 | }else{ 1790 | this.$message({ 1791 | message: '操作失败!', 1792 | type: 'error' 1793 | }); 1794 | } 1795 | 1796 | }) 1797 | } 1798 | ``` 1799 | 1800 | 3. 后端逻辑处理 1801 | 1802 | ```java 1803 | /* 1804 | * 更新用户 1805 | * @author linsuwen 1806 | * @date 2023/1/2 19:11 1807 | */ 1808 | @PostMapping("/update") 1809 | public Result update(@RequestBody User user){ 1810 | return userService.updateById(user)?Result.success():Result.fail(); 1811 | } 1812 | ``` 1813 | 1814 | 4. 表单重置(异步) 1815 | 1816 | ```js 1817 | mod(row){ 1818 | console.log(row) 1819 | 1820 | this.centerDialogVisible = true 1821 | this.$nextTick(()=>{ 1822 | //赋值到表单 1823 | }) 1824 | }, 1825 | ``` 1826 | 1827 | 1828 | 1829 | ## 12.6 删除功能 1830 | 1831 | 1. 获取数据(id) 1832 | 1833 | ```js 1834 | scope.row.id 1835 | ``` 1836 | 1837 | 2. 删除确认(Main.vue) 1838 | 1839 | ```vue 1840 | 1845 | 删除 1846 | 1847 | ``` 1848 | 1849 | 3. 提交到后台 1850 | 1851 | ```js 1852 | del(id){ 1853 | console.log(id) 1854 | 1855 | this.$axios.get(this.$httpUrl+'/user/del?id='+id).then(res=>res.data).then(res=>{ 1856 | console.log(res) 1857 | if(res.code==200){ 1858 | 1859 | this.$message({ 1860 | message: '操作成功!', 1861 | type: 'success' 1862 | }); 1863 | this.loadPost() 1864 | }else{ 1865 | this.$message({ 1866 | message: '操作失败!', 1867 | type: 'error' 1868 | }); 1869 | } 1870 | 1871 | }) 1872 | }, 1873 | ``` 1874 | 1875 | 4. 后端处理 1876 | 1877 | ```java 1878 | /* 1879 | * 删除用户 1880 | * @author linsuwen 1881 | * @date 2023/1/2 19:15 1882 | */ 1883 | @GetMapping("/del") 1884 | public Result delete(Integer id){ 1885 | return userService.removeById(id)?Result.success():Result.fail(); 1886 | } 1887 | ``` 1888 | 1889 | 1890 | 1891 | # 13. 用户管理 1892 | 1893 | 用户管理和管理员管理的区别在于 roleId 不同,所以代码可以复用 1894 | 1895 | 1896 | 1897 | # 14. 仓库管理 1898 | 1899 | 1. 仓库表设计 1900 | 1901 | ```mysql 1902 | CREATE TABLE `storage` ( 1903 | `id` int NOT NULL AUTO_INCREMENT COMMENT '主键', 1904 | `name` varchar(100) NOT NULL COMMENT '仓库名', 1905 | `remark` varchar(1000) DEFAULT NULL COMMENT '备注', 1906 | PRIMARY KEY (`id`) 1907 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; 1908 | ``` 1909 | 1910 | 2. 根据表生成后端代码 1911 | 1912 | 使用代码生成器自动生成代码 1913 | 1914 | 3. 编写后端增删改查代码 1915 | 1916 | ```java 1917 | @RestController 1918 | @RequestMapping("/storage") 1919 | public class StorageController { 1920 | @Autowired 1921 | private StorageService storageService; 1922 | 1923 | /* 1924 | * 新增仓库 1925 | * @author linsuwen 1926 | * @date 2023/1/5 19:36 1927 | */ 1928 | @PostMapping("/save") 1929 | public Result save(@RequestBody Storage storage){ 1930 | return storageService.save(storage)?Result.success():Result.fail(); 1931 | } 1932 | 1933 | /* 1934 | * 更新仓库 1935 | * @author linsuwen 1936 | * @date 2023/1/5 19:38 1937 | */ 1938 | @PostMapping("/update") 1939 | public Result update(@RequestBody Storage storage){ 1940 | return storageService.updateById(storage)?Result.success():Result.fail(); 1941 | } 1942 | 1943 | /* 1944 | * 删除仓库 1945 | * @author linsuwen 1946 | * @date 2023/1/5 19:40 1947 | */ 1948 | @GetMapping("/del") 1949 | public Result del(@RequestParam String id){ 1950 | return storageService.removeById(id)?Result.success():Result.fail(); 1951 | } 1952 | 1953 | /* 1954 | * 查询仓库列表 1955 | * @author linsuwen 1956 | * @date 2023/1/5 19:42 1957 | */ 1958 | @GetMapping("/list") 1959 | public Result list(){ 1960 | List list = storageService.list(); 1961 | return Result.success(list); 1962 | } 1963 | 1964 | /* 1965 | * 模糊查询:根据输入查询仓库并以分页的形式展示 1966 | * @author linsuwen 1967 | * @date 2023/1/5 19:43 1968 | */ 1969 | @PostMapping("/listPage") 1970 | public Result listPage(@RequestBody QueryPageParam query){ 1971 | HashMap param = query.getParam(); 1972 | String name = (String)param.get("name"); 1973 | 1974 | Page page = new Page(); 1975 | page.setCurrent(query.getPageNum()); 1976 | page.setSize(query.getPageSize()); 1977 | 1978 | LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); 1979 | if(StringUtils.isNotBlank(name) && !"null".equals(name)){ 1980 | queryWrapper.like(Storage::getName,name); 1981 | } 1982 | 1983 | IPage result = storageService.pageCC(page,queryWrapper); 1984 | return Result.success(result.getRecords(),result.getTotal()); 1985 | } 1986 | 1987 | } 1988 | ``` 1989 | 1990 | 4. postman测试查询代码 1991 | 1992 | 5. 编写前端相关代码(storage/StorageManage.vue) 1993 | 1994 | 复用 user/UserManage.vue 部分代码,稍加修改 1995 | 1996 | 1997 | 1998 | # 15. 物品分类管理 1999 | 2000 | 1. 物品分类表设计 2001 | 2002 | ```mysql 2003 | CREATE TABLE `goodstype` ( 2004 | `id` int NOT NULL AUTO_INCREMENT COMMENT '主键', 2005 | `name` varchar(100) NOT NULL COMMENT '分类名', 2006 | `remark` varchar(1000) DEFAULT NULL COMMENT '备注', 2007 | PRIMARY KEY (`id`) 2008 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; 2009 | ``` 2010 | 2011 | 2. 根据表生成后端代码 2012 | 2013 | 使用代码生成器自动生成代码 2014 | 2015 | 3. 编写后端增删改查代码 2016 | 2017 | ```java 2018 | @RestController 2019 | @RequestMapping("/goodstype") 2020 | public class GoodstypeController { 2021 | 2022 | @Autowired 2023 | private GoodstypeService goodstypeService; 2024 | 2025 | /* 2026 | * 新增物品分类 2027 | * @author linsuwen 2028 | * @date 2023/1/5 20:39 2029 | */ 2030 | @PostMapping("/save") 2031 | public Result save(@RequestBody Goodstype goodstype){ 2032 | return goodstypeService.save(goodstype)?Result.success():Result.fail(); 2033 | } 2034 | 2035 | /* 2036 | * 更新物品分类 2037 | * @author linsuwen 2038 | * @date 2023/1/5 20:41 2039 | */ 2040 | @PostMapping("/update") 2041 | public Result update(@RequestBody Goodstype goodstype){ 2042 | return goodstypeService.updateById(goodstype)?Result.success():Result.fail(); 2043 | } 2044 | 2045 | /* 2046 | * 删除物品分类 2047 | * @author linsuwen 2048 | * @date 2023/1/5 20:43 2049 | */ 2050 | @GetMapping("/del") 2051 | public Result del(@RequestParam String id){ 2052 | return goodstypeService.removeById(id)?Result.success():Result.fail(); 2053 | } 2054 | 2055 | /* 2056 | * 查询物品分类列表 2057 | * @author linsuwen 2058 | * @date 2023/1/5 21:06 2059 | */ 2060 | @GetMapping("/list") 2061 | public Result list(){ 2062 | List list = goodstypeService.list(); 2063 | return Result.success(list); 2064 | } 2065 | 2066 | /* 2067 | * 模糊查询:根据输入查询物品分类并以分页的形式展示 2068 | * @author linsuwen 2069 | * @date 2023/1/5 21:13 2070 | */ 2071 | @PostMapping("/listPage") 2072 | public Result listPage(@RequestBody QueryPageParam query){ 2073 | HashMap param = query.getParam(); 2074 | String name = (String)param.get("name"); 2075 | 2076 | Page page = new Page(); 2077 | page.setCurrent(query.getPageNum()); 2078 | page.setSize(query.getPageSize()); 2079 | 2080 | LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper(); 2081 | if(StringUtils.isNotBlank(name) && !"null".equals(name)){ 2082 | queryWrapper.like(Goodstype::getName,name); 2083 | } 2084 | 2085 | IPage result = goodstypeService.pageCC(page,queryWrapper); 2086 | return Result.success(result.getRecords(),result.getTotal()); 2087 | } 2088 | 2089 | } 2090 | ``` 2091 | 2092 | 4. postman测试查询代码 2093 | 2094 | 5. 编写前端相关代码(goodstype/GoodstypeManage.vue) 2095 | 2096 | 复用 StorageManage.vue 部分代码,稍加修改 2097 | 2098 | 2099 | 2100 | # 16. 物品管理 2101 | 2102 | 1. 物品表设计 2103 | 2104 | ```mysql 2105 | CREATE TABLE `goods` ( 2106 | `id` int NOT NULL AUTO_INCREMENT COMMENT '主键', 2107 | `name` varchar(100) NOT NULL COMMENT '货名', 2108 | `storage` int NOT NULL COMMENT '仓库', 2109 | `goodsType` int NOT NULL COMMENT '分类', 2110 | `count` int DEFAULT NULL COMMENT '数量', 2111 | `remark` varchar(1000) DEFAULT NULL COMMENT '备注', 2112 | PRIMARY KEY (`id`) 2113 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; 2114 | ``` 2115 | 2116 | 2. 根据表生成后端代码 2117 | 2118 | 3. 编写后端增删改查代码 2119 | 2120 | ```java 2121 | @RestController 2122 | @RequestMapping("/goods") 2123 | public class GoodsController { 2124 | @Autowired 2125 | private GoodsService goodsService; 2126 | 2127 | /* 2128 | * 新增物品 2129 | * @author linsuwen 2130 | * @date 2023/1/6 12:12 2131 | */ 2132 | @PostMapping("/save") 2133 | public Result save(@RequestBody Goods goods){ 2134 | return goodsService.save(goods)?Result.success():Result.fail(); 2135 | } 2136 | 2137 | /* 2138 | * 更新物品 2139 | * @author linsuwen 2140 | * @date 2023/1/6 13:22 2141 | */ 2142 | @PostMapping("/update") 2143 | public Result update(@RequestBody Goods goods){ 2144 | return goodsService.updateById(goods)?Result.success():Result.fail(); 2145 | } 2146 | 2147 | /* 2148 | * 删除物品 2149 | * @author linsuwen 2150 | * @date 2023/1/6 13:24 2151 | */ 2152 | @GetMapping("/del") 2153 | public Result del(@RequestParam String id){ 2154 | return goodsService.removeById(id)?Result.success():Result.fail(); 2155 | } 2156 | 2157 | /* 2158 | * 模糊查询:根据输入查询物品并以分页的形式展示 2159 | * @author linsuwen 2160 | * @date 2023/1/6 13:31 2161 | */ 2162 | @PostMapping("/listPage") 2163 | public Result listPage(@RequestBody QueryPageParam query){ 2164 | HashMap param = query.getParam(); 2165 | String name = (String)param.get("name"); 2166 | String goodstype = (String)param.get("goodstype"); 2167 | String storage = (String)param.get("storage"); 2168 | 2169 | Page page = new Page(); 2170 | page.setCurrent(query.getPageNum()); 2171 | page.setSize(query.getPageSize()); 2172 | 2173 | LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); 2174 | if(StringUtils.isNotBlank(name) && !"null".equals(name)){ 2175 | queryWrapper.like(Goods::getName,name); 2176 | } 2177 | if(StringUtils.isNotBlank(goodstype) && !"null".equals(goodstype)){ 2178 | queryWrapper.like(Goods::getGoodstype,goodstype); 2179 | } 2180 | if(StringUtils.isNotBlank(storage) && !"null".equals(storage)){ 2181 | queryWrapper.like(Goods::getStorage,storage); 2182 | } 2183 | 2184 | IPage result = goodsService.pageCC(page,queryWrapper); 2185 | return Result.success(result.getRecords(),result.getTotal()); 2186 | } 2187 | } 2188 | ``` 2189 | 2190 | 4. postman测试查询代码 2191 | 2192 | 5. 编写前端相关代码(goods/GoodsManage.vue) 2193 | 2194 | ```js 2195 | count: [ 2196 | {required: true, message: '请输⼊数量', trigger: 'blur'}, 2197 | {pattern: /^([1-9][0-9]*){1,4}$/,message: '数量必须为正整数字',trigger: "blur"}, {validator:checkCount,trigger: 'blur'} 2198 | ], 2199 | ``` 2200 | 2201 | ```js 2202 | let checkCount = (rule, value, callback) => { 2203 | if(value>9999){ 2204 | callback(new Error('数量输入过大')); 2205 | }else{ 2206 | callback(); 2207 | } 2208 | }; 2209 | ``` 2210 | 2211 | 6. 仓库和分类列表展示 2212 | 2213 | ```vue 2214 | 2215 | 2216 | 2217 | 2218 | ``` 2219 | 2220 | ```js 2221 | formatStorage(row){ 2222 | let temp = this.storageData.find(item=>{ 2223 | return item.id == row.storage 2224 | }) 2225 | 2226 | return temp && temp.name 2227 | }, 2228 | formatGoodstype(row){ 2229 | let temp = this.goodstypeData.find(item=>{ 2230 | return item.id == row.goodstype 2231 | }) 2232 | 2233 | return temp && temp.name 2234 | }, 2235 | ``` 2236 | 2237 | 7. 查询条件中增加仓库和分类的条件 2238 | 2239 | 8. 表单中仓库和分类下拉实现 2240 | 2241 | ```vue 2242 | 2243 | 2248 | 2249 | 2250 | 2251 | 2256 | 2257 | 2258 | ``` 2259 | 2260 | 2261 | 2262 | # 17. 记录管理 2263 | 2264 | 1. 记录表设计 2265 | 2266 | ```mysql 2267 | CREATE TABLE `record` ( 2268 | `id` int NOT NULL AUTO_INCREMENT COMMENT '主键', 2269 | `goods` int NOT NULL COMMENT '货品id', 2270 | `userId` int DEFAULT NULL COMMENT '取货人/补货人', 2271 | `admin_id` int DEFAULT NULL COMMENT '操作人id', 2272 | `count` int DEFAULT NULL COMMENT '数量', 2273 | `createtime` datetime DEFAULT NULL COMMENT '操作时间', 2274 | `remark` varchar(1000) DEFAULT NULL COMMENT '备注', 2275 | PRIMARY KEY (`id`) 2276 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; 2277 | ``` 2278 | 2279 | 2. 根据表生成后端代码 2280 | 2281 | 3. 编写后端查询代码 2282 | 2283 | 4. 编写前端相关代码 2284 | 2285 | 5. 优化 2286 | 2287 | 6. 列表展示商品名、仓库、分类名 2288 | 2289 | 7. 按物品名查询、仓库、分类查询 2290 | 2291 | 2292 | 2293 | # 18. 出入库管理 2294 | 2295 | 1. 表单编写 2296 | 2. 入库操作(记录、更新物品数量、自动填充时间) 2297 | 3. 用户选择 2298 | 2299 | 2300 | 2301 | # 19. 权限控制优化 2302 | 2303 | 1. 出入库权限控制 2304 | 2. 记录查询权限控制 2305 | 2306 | 2307 | 2308 | # 20. 项目部署 2309 | 2310 | SpringBoot + Vue项目部署到服务器上 2311 | 2312 | 2313 | 2314 | # 21. vuex持久化后刷新数据丢失 2315 | 2316 | > 系统Bug:刷新系统后会导致数据丢失 2317 | 2318 | Bug分析:vuex持久化后,每当浏览器刷新就会丢失state中的数据 2319 | 2320 | 解决方法:保存这个state的数据 2321 | 2322 | 具体解决方法: 2323 | 2324 | 1. 解决菜单丢失问题 2325 | 2326 | 安装插件vuex-persistedstate: 2327 | 2328 | ```shell 2329 | npm i vuex-persistedstate 2330 | ``` 2331 | 2332 | 引入(store/index.js): 2333 | 2334 | ```js 2335 | import createPersistedState from 'vuex-persistedstate' 2336 | ``` 2337 | 2338 | 使用(store/index.js): 2339 | 2340 | ```js 2341 | plugins:[createPersistedState()] 2342 | ``` 2343 | 2344 | 2. 解决路由丢失问题(App.vue) 2345 | 2346 | ```js 2347 | //解决前端刷新页面路由丢失问题 2348 | data(){ 2349 | return{ 2350 | user : JSON.parse(sessionStorage.getItem('CurUser')) 2351 | } 2352 | }, 2353 | watch:{ 2354 | '$store.state.menu':{ 2355 | handler(val,old){ 2356 | console.log(val) 2357 | if(!old && this.user && this.user.no){ 2358 | this.$store.commit('setMenu',val) 2359 | } 2360 | }, 2361 | immediate: true 2362 | } 2363 | } 2364 | ``` 2365 | 2366 | 2367 | 2368 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.7.5 9 | 10 | 11 | com.wms 12 | Warehouse-System 13 | 0.0.1-SNAPSHOT 14 | Warehouse-System 15 | Warehouse management system 16 | 17 | 11 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-starter-test 27 | test 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-web 32 | 33 | 34 | mysql 35 | mysql-connector-java 36 | 8.0.30 37 | runtime 38 | 39 | 40 | org.projectlombok 41 | lombok 42 | true 43 | 44 | 45 | 46 | com.baomidou 47 | mybatis-plus-boot-starter 48 | 3.4.1 49 | 50 | 51 | 52 | com.baomidou 53 | mybatis-plus-generator 54 | 3.4.1 55 | 56 | 57 | org.freemarker 58 | freemarker 59 | 2.3.30 60 | 61 | 62 | 63 | com.spring4all 64 | spring-boot-starter-swagger 65 | 1.5.1.RELEASE 66 | 67 | 68 | 69 | 70 | 71 | 72 | org.springframework.boot 73 | spring-boot-maven-plugin 74 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /src/main/java/com/wms/WarehouseSystemApplication.java: -------------------------------------------------------------------------------- 1 | package com.wms; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class WarehouseSystemApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(WarehouseSystemApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/wms/common/AutoFillMetaInfoHandler.java: -------------------------------------------------------------------------------- 1 | package com.wms.common; 2 | 3 | import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; 4 | import org.apache.ibatis.reflection.MetaObject; 5 | import org.springframework.stereotype.Component; 6 | 7 | import java.time.LocalDateTime; 8 | 9 | @Component 10 | public class AutoFillMetaInfoHandler implements MetaObjectHandler { 11 | @Override 12 | public void insertFill(MetaObject metaObject) { 13 | this.setFieldValByName("createtime", LocalDateTime.now(),metaObject); 14 | } 15 | 16 | @Override 17 | public void updateFill(MetaObject metaObject) { 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/wms/common/CodeGenerator.java: -------------------------------------------------------------------------------- 1 | package com.wms.common; 2 | 3 | import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException; 4 | import com.baomidou.mybatisplus.core.toolkit.StringPool; 5 | import com.baomidou.mybatisplus.core.toolkit.StringUtils; 6 | import com.baomidou.mybatisplus.generator.AutoGenerator; 7 | import com.baomidou.mybatisplus.generator.InjectionConfig; 8 | import com.baomidou.mybatisplus.generator.config.*; 9 | import com.baomidou.mybatisplus.generator.config.po.TableInfo; 10 | import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; 11 | import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine; 12 | 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | import java.util.Scanner; 16 | 17 | /* 18 | * 代码生成器 19 | * @author linsuwen 20 | * @date 2023/1/2 19:52 21 | */ 22 | public class CodeGenerator { 23 | 24 | /** 25 | *

26 | * 读取控制台内容 27 | *

28 | */ 29 | public static String scanner(String tip) { 30 | Scanner scanner = new Scanner(System.in); 31 | StringBuilder help = new StringBuilder(); 32 | help.append("请输入" + tip + ":"); 33 | System.out.println(help.toString()); 34 | if (scanner.hasNext()) { 35 | String ipt = scanner.next(); 36 | if (StringUtils.isNotBlank(ipt)) { 37 | return ipt; 38 | } 39 | } 40 | throw new MybatisPlusException("请输入正确的" + tip + "!"); 41 | } 42 | 43 | public static void main(String[] args) { 44 | // 代码生成器 45 | AutoGenerator mpg = new AutoGenerator(); 46 | 47 | // 全局配置 48 | GlobalConfig gc = new GlobalConfig(); 49 | String projectPath = System.getProperty("user.dir"); 50 | gc.setOutputDir(projectPath + "/src/main/java"); 51 | gc.setAuthor("linsuwen"); 52 | gc.setOpen(false); 53 | gc.setSwagger2(true); //实体属性 Swagger2 注解 54 | gc.setBaseResultMap(true); // XML ResultMap 55 | gc.setBaseColumnList(true); // XML columList 56 | //去掉service接口首字母的I, 如DO为User则叫UserService 57 | gc.setServiceName("%sService"); 58 | mpg.setGlobalConfig(gc); 59 | 60 | // 数据源配置 61 | DataSourceConfig dsc = new DataSourceConfig(); 62 | dsc.setUrl("jdbc:mysql://localhost:3306/wms?useUnicode=true&characterEncoding=utf-8&serveTimezone=UTC"); 63 | // dsc.setSchemaName("public"); 64 | dsc.setDriverName("com.mysql.cj.jdbc.Driver"); 65 | dsc.setUsername("root"); 66 | dsc.setPassword("123456"); 67 | mpg.setDataSource(dsc); 68 | 69 | // 包配置 70 | PackageConfig pc = new PackageConfig(); 71 | //pc.setModuleName(scanner("模块名")); 72 | //模块配置 73 | pc.setParent("com.wms") 74 | .setEntity("entity") 75 | .setMapper("mapper") 76 | .setService("service") 77 | .setServiceImpl("service.Impl") 78 | .setController("controller"); 79 | mpg.setPackageInfo(pc); 80 | 81 | // 自定义配置 82 | InjectionConfig cfg = new InjectionConfig() { 83 | @Override 84 | public void initMap() { 85 | // to do nothing 86 | } 87 | }; 88 | 89 | // 如果模板引擎是 freemarker 90 | String templatePath = "/templates/mapper.xml.ftl"; 91 | // 如果模板引擎是 velocity 92 | // String templatePath = "/templates/mapper.xml.vm"; 93 | 94 | // 自定义输出配置 95 | List focList = new ArrayList<>(); 96 | // 自定义配置会被优先输出 97 | focList.add(new FileOutConfig(templatePath) { 98 | @Override 99 | public String outputFile(TableInfo tableInfo) { 100 | // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!! 101 | return projectPath + "/src/main/resources/mapper/" + pc.getModuleName() 102 | + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML; 103 | } 104 | }); 105 | 106 | cfg.setFileOutConfigList(focList); 107 | mpg.setCfg(cfg); 108 | 109 | // 配置模板 110 | TemplateConfig templateConfig = new TemplateConfig(); 111 | 112 | templateConfig.setXml(null); 113 | mpg.setTemplate(templateConfig); 114 | 115 | // 策略配置 116 | StrategyConfig strategy = new StrategyConfig(); 117 | strategy.setNaming(NamingStrategy.underline_to_camel); 118 | strategy.setColumnNaming(NamingStrategy.underline_to_camel); 119 | //strategy.setSuperEntityClass("你自己的父类实体,没有就不用设置!"); 120 | strategy.setEntityLombokModel(true); 121 | strategy.setRestControllerStyle(true); 122 | // 公共父类 123 | //strategy.setSuperControllerClass("你自己的父类控制器,没有就不用设置!"); 124 | // 写于父类中的公共字段 125 | //strategy.setSuperEntityColumns("id"); 126 | strategy.setInclude(scanner("表名,多个英文逗号分割").split(",")); 127 | strategy.setControllerMappingHyphenStyle(true); 128 | //strategy.setTablePrefix(pc.getModuleName() + "_"); 129 | mpg.setStrategy(strategy); 130 | mpg.setTemplateEngine(new FreemarkerTemplateEngine()); 131 | mpg.execute(); 132 | } 133 | 134 | } -------------------------------------------------------------------------------- /src/main/java/com/wms/common/CorsConfig.java: -------------------------------------------------------------------------------- 1 | package com.wms.common; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.web.servlet.config.annotation.CorsRegistry; 5 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 6 | 7 | /* 8 | * 解决跨域问题:重写WebMvcConfigurer的addCorsMappings方法(全局跨域配置) 9 | * @author linsuwen 10 | * @date 2023/1/3 1:30 11 | */ 12 | @Configuration 13 | public class CorsConfig implements WebMvcConfigurer { 14 | 15 | @Override 16 | public void addCorsMappings(CorsRegistry registry) { 17 | registry.addMapping("/**") 18 | //是否发送Cookie 19 | .allowCredentials(true) 20 | //放行哪些原始域 21 | .allowedOriginPatterns("*") 22 | .allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE"}) 23 | .allowedHeaders("*") 24 | .exposedHeaders("*"); 25 | } 26 | } -------------------------------------------------------------------------------- /src/main/java/com/wms/common/MybatisPlusConfig.java: -------------------------------------------------------------------------------- 1 | package com.wms.common; 2 | 3 | import com.baomidou.mybatisplus.annotation.DbType; 4 | import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; 5 | import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | /* 10 | * MybatisPlus分页拦截器 11 | * @author linsuwen 12 | * @date 2023/1/2 20:06 13 | */ 14 | @Configuration 15 | public class MybatisPlusConfig { 16 | @Bean 17 | public MybatisPlusInterceptor mybatisPlusInterceptor() { 18 | MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); 19 | interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); 20 | return interceptor; 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /src/main/java/com/wms/common/QueryPageParam.java: -------------------------------------------------------------------------------- 1 | package com.wms.common; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.HashMap; 6 | 7 | /* 8 | * 分页参数的封装类 9 | * @author linsuwen 10 | * @date 2023/1/2 19:53 11 | */ 12 | @Data 13 | public class QueryPageParam { 14 | //设置默认值 15 | private static int PAGE_SIZE=20; 16 | private static int PAGE_NUM=1; 17 | 18 | private int pageSize=PAGE_SIZE; 19 | private int pageNum=PAGE_NUM; 20 | 21 | private HashMap param = new HashMap(); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/wms/common/Result.java: -------------------------------------------------------------------------------- 1 | package com.wms.common; 2 | 3 | import lombok.Data; 4 | 5 | /* 6 | * 返回前端统一数据的封装类 7 | * @author linsuwen 8 | * @date 2023/1/2 20:36 9 | */ 10 | @Data 11 | public class Result { 12 | 13 | private int code; //编码 200/400 14 | private String msg; //成功/失败 15 | private Long total; //总记录数 16 | private Object data; //数据 17 | 18 | public static Result fail(){ 19 | return result(400,"失败",0L,null); 20 | } 21 | 22 | public static Result success(){ 23 | return result(200,"成功",0L,null); 24 | } 25 | 26 | public static Result success(Object data){ 27 | return result(200,"成功",0L,data); 28 | } 29 | 30 | public static Result success(Object data,Long total){ 31 | return result(200,"成功",total,data); 32 | } 33 | 34 | private static Result result(int code,String msg,Long total,Object data){ 35 | Result res = new Result(); 36 | res.setData(data); 37 | res.setMsg(msg); 38 | res.setCode(code); 39 | res.setTotal(total); 40 | return res; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/wms/controller/GoodsController.java: -------------------------------------------------------------------------------- 1 | package com.wms.controller; 2 | 3 | 4 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 5 | import com.baomidou.mybatisplus.core.metadata.IPage; 6 | import com.baomidou.mybatisplus.core.toolkit.StringUtils; 7 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 8 | import com.wms.common.QueryPageParam; 9 | import com.wms.common.Result; 10 | import com.wms.entity.Goods; 11 | import com.wms.service.GoodsService; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.web.bind.annotation.*; 14 | 15 | import java.util.HashMap; 16 | import java.util.List; 17 | 18 | /** 19 | *

20 | * 前端控制器:物品管理 21 | *

22 | * 23 | * @author linsuwen 24 | * @since 2023-01-06 25 | */ 26 | @RestController 27 | @RequestMapping("/goods") 28 | public class GoodsController { 29 | @Autowired 30 | private GoodsService goodsService; 31 | 32 | /* 33 | * 新增物品 34 | * @author linsuwen 35 | * @date 2023/1/6 12:12 36 | */ 37 | @PostMapping("/save") 38 | public Result save(@RequestBody Goods goods){ 39 | return goodsService.save(goods)?Result.success():Result.fail(); 40 | } 41 | 42 | /* 43 | * 更新物品 44 | * @author linsuwen 45 | * @date 2023/1/6 13:22 46 | */ 47 | @PostMapping("/update") 48 | public Result update(@RequestBody Goods goods){ 49 | return goodsService.updateById(goods)?Result.success():Result.fail(); 50 | } 51 | 52 | /* 53 | * 删除物品 54 | * @author linsuwen 55 | * @date 2023/1/6 13:24 56 | */ 57 | @GetMapping("/del") 58 | public Result del(@RequestParam String id){ 59 | return goodsService.removeById(id)?Result.success():Result.fail(); 60 | } 61 | 62 | /* 63 | * 模糊查询:根据输入查询物品并以分页的形式展示 64 | * @author linsuwen 65 | * @date 2023/1/6 13:31 66 | */ 67 | @PostMapping("/listPage") 68 | public Result listPage(@RequestBody QueryPageParam query){ 69 | HashMap param = query.getParam(); 70 | String name = (String)param.get("name"); 71 | String goodstype = (String)param.get("goodstype"); 72 | String storage = (String)param.get("storage"); 73 | 74 | Page page = new Page(); 75 | page.setCurrent(query.getPageNum()); 76 | page.setSize(query.getPageSize()); 77 | 78 | LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); 79 | if(StringUtils.isNotBlank(name) && !"null".equals(name)){ 80 | queryWrapper.like(Goods::getName,name); 81 | } 82 | if(StringUtils.isNotBlank(goodstype) && !"null".equals(goodstype)){ 83 | queryWrapper.like(Goods::getGoodstype,goodstype); 84 | } 85 | if(StringUtils.isNotBlank(storage) && !"null".equals(storage)){ 86 | queryWrapper.like(Goods::getStorage,storage); 87 | } 88 | 89 | IPage result = goodsService.pageCC(page,queryWrapper); 90 | return Result.success(result.getRecords(),result.getTotal()); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/com/wms/controller/GoodstypeController.java: -------------------------------------------------------------------------------- 1 | package com.wms.controller; 2 | 3 | 4 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 5 | import com.baomidou.mybatisplus.core.metadata.IPage; 6 | import com.baomidou.mybatisplus.core.toolkit.StringUtils; 7 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 8 | import com.wms.common.QueryPageParam; 9 | import com.wms.common.Result; 10 | import com.wms.entity.Goodstype; 11 | import com.wms.entity.Storage; 12 | import com.wms.service.GoodstypeService; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.web.bind.annotation.*; 15 | 16 | import java.util.HashMap; 17 | import java.util.List; 18 | 19 | /** 20 | *

21 | * 前端控制器:物品分类管理 22 | *

23 | * 24 | * @author linsuwen 25 | * @since 2023-01-05 26 | */ 27 | @RestController 28 | @RequestMapping("/goodstype") 29 | public class GoodstypeController { 30 | 31 | @Autowired 32 | private GoodstypeService goodstypeService; 33 | 34 | /* 35 | * 新增物品分类 36 | * @author linsuwen 37 | * @date 2023/1/5 20:39 38 | */ 39 | @PostMapping("/save") 40 | public Result save(@RequestBody Goodstype goodstype){ 41 | return goodstypeService.save(goodstype)?Result.success():Result.fail(); 42 | } 43 | 44 | /* 45 | * 更新物品分类 46 | * @author linsuwen 47 | * @date 2023/1/5 20:41 48 | */ 49 | @PostMapping("/update") 50 | public Result update(@RequestBody Goodstype goodstype){ 51 | return goodstypeService.updateById(goodstype)?Result.success():Result.fail(); 52 | } 53 | 54 | /* 55 | * 删除物品分类 56 | * @author linsuwen 57 | * @date 2023/1/5 20:43 58 | */ 59 | @GetMapping("/del") 60 | public Result del(@RequestParam String id){ 61 | return goodstypeService.removeById(id)?Result.success():Result.fail(); 62 | } 63 | 64 | /* 65 | * 查询物品分类列表 66 | * @author linsuwen 67 | * @date 2023/1/5 21:06 68 | */ 69 | @GetMapping("/list") 70 | public Result list(){ 71 | List list = goodstypeService.list(); 72 | return Result.success(list); 73 | } 74 | 75 | /* 76 | * 模糊查询:根据输入查询物品分类并以分页的形式展示 77 | * @author linsuwen 78 | * @date 2023/1/5 21:13 79 | */ 80 | @PostMapping("/listPage") 81 | public Result listPage(@RequestBody QueryPageParam query){ 82 | HashMap param = query.getParam(); 83 | String name = (String)param.get("name"); 84 | 85 | Page page = new Page(); 86 | page.setCurrent(query.getPageNum()); 87 | page.setSize(query.getPageSize()); 88 | 89 | LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper(); 90 | if(StringUtils.isNotBlank(name) && !"null".equals(name)){ 91 | queryWrapper.like(Goodstype::getName,name); 92 | } 93 | 94 | IPage result = goodstypeService.pageCC(page,queryWrapper); 95 | return Result.success(result.getRecords(),result.getTotal()); 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/com/wms/controller/MenuController.java: -------------------------------------------------------------------------------- 1 | package com.wms.controller; 2 | 3 | 4 | import com.wms.common.Result; 5 | import com.wms.entity.Menu; 6 | import com.wms.service.MenuService; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.web.bind.annotation.*; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | *

14 | * 前端控制器:菜单栏模块 15 | *

16 | * 17 | * @author linsuwen 18 | * @since 2023-01-03 19 | */ 20 | @RestController 21 | @RequestMapping("/menu") 22 | public class MenuController { 23 | @Autowired 24 | private MenuService menuService; 25 | 26 | /* 27 | * 根据用户身份获取菜单列表 28 | * @author linsuwen 29 | * @date 2023/1/3 20:48 30 | */ 31 | @GetMapping("/list") 32 | public Result list(@RequestParam String roleId){ 33 | List list = menuService.lambdaQuery() 34 | .like(Menu::getMenuright,roleId) 35 | .list(); 36 | return Result.success(list); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/wms/controller/RecordController.java: -------------------------------------------------------------------------------- 1 | package com.wms.controller; 2 | 3 | 4 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 5 | import com.baomidou.mybatisplus.core.metadata.IPage; 6 | import com.baomidou.mybatisplus.core.toolkit.StringUtils; 7 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 8 | import com.wms.common.QueryPageParam; 9 | import com.wms.common.Result; 10 | import com.wms.entity.Goods; 11 | import com.wms.service.GoodsService; 12 | import com.wms.service.RecordService; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.web.bind.annotation.PostMapping; 15 | import org.springframework.web.bind.annotation.RequestBody; 16 | import org.springframework.web.bind.annotation.RequestMapping; 17 | import com.wms.entity.Record; 18 | 19 | import org.springframework.web.bind.annotation.RestController; 20 | 21 | import java.util.HashMap; 22 | 23 | /** 24 | *

25 | * 前端控制器:记录管理 26 | *

27 | * 28 | * @author linsuwen 29 | * @since 2023-01-06 30 | */ 31 | @RestController 32 | @RequestMapping("/record") 33 | public class RecordController { 34 | @Autowired 35 | private RecordService recordService; 36 | @Autowired 37 | private GoodsService goodsService; 38 | 39 | /* 40 | * 41 | * @author linsuwen 42 | * @date 2023/1/6 20:58 43 | */ 44 | @PostMapping("/listPage") 45 | public Result listPage(@RequestBody QueryPageParam query){ 46 | HashMap param = query.getParam(); 47 | String name = (String)param.get("name"); 48 | String goodstype = (String)param.get("goodstype"); 49 | String storage = (String)param.get("storage"); 50 | String roleId = (String)param.get("roleId"); 51 | String userId = (String)param.get("userId"); 52 | 53 | Page page = new Page(); 54 | page.setCurrent(query.getPageNum()); 55 | page.setSize(query.getPageSize()); 56 | 57 | QueryWrapper queryWrapper = new QueryWrapper(); 58 | queryWrapper.apply("a.goods=b.id and b.storage=c.id and b.goodsType=d.id "); 59 | 60 | if("2".equals(roleId)){ 61 | // queryWrapper.eq(Record::getUserid,userId); 62 | queryWrapper.apply(" a.userId= "+userId); 63 | } 64 | 65 | if(StringUtils.isNotBlank(name) && !"null".equals(name)){ 66 | queryWrapper.like("b.name",name); 67 | } 68 | if(StringUtils.isNotBlank(goodstype) && !"null".equals(goodstype)){ 69 | queryWrapper.eq("d.id",goodstype); 70 | } 71 | if(StringUtils.isNotBlank(storage) && !"null".equals(storage)){ 72 | queryWrapper.eq("c.id",storage); 73 | } 74 | 75 | IPage result = recordService.pageCC(page,queryWrapper); 76 | return Result.success(result.getRecords(),result.getTotal()); 77 | } 78 | 79 | /* 80 | * 新增记录 81 | * @author linsuwen 82 | * @date 2023/1/6 21:21 83 | */ 84 | @PostMapping("/save") 85 | public Result save(@RequestBody Record record){ 86 | Goods goods = goodsService.getById(record.getGoods()); 87 | int n = record.getCount(); 88 | //出库 89 | if("2".equals(record.getAction())){ 90 | n = -n; 91 | record.setCount(n); 92 | } 93 | 94 | int num = goods.getCount()+n; 95 | goods.setCount(num); 96 | goodsService.updateById(goods); 97 | 98 | return recordService.save(record)?Result.success():Result.fail(); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/main/java/com/wms/controller/StorageController.java: -------------------------------------------------------------------------------- 1 | package com.wms.controller; 2 | 3 | 4 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 5 | import com.baomidou.mybatisplus.core.metadata.IPage; 6 | import com.baomidou.mybatisplus.core.toolkit.StringUtils; 7 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 8 | import com.wms.common.QueryPageParam; 9 | import com.wms.common.Result; 10 | import com.wms.entity.Storage; 11 | import com.wms.service.StorageService; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.web.bind.annotation.*; 14 | 15 | import java.util.HashMap; 16 | import java.util.List; 17 | 18 | /** 19 | *

20 | * 前端控制器:仓库管理模块 21 | *

22 | * 23 | * @author linsuwen 24 | * @since 2023-01-05 25 | */ 26 | @RestController 27 | @RequestMapping("/storage") 28 | public class StorageController { 29 | @Autowired 30 | private StorageService storageService; 31 | 32 | /* 33 | * 新增仓库 34 | * @author linsuwen 35 | * @date 2023/1/5 19:36 36 | */ 37 | @PostMapping("/save") 38 | public Result save(@RequestBody Storage storage){ 39 | return storageService.save(storage)?Result.success():Result.fail(); 40 | } 41 | 42 | /* 43 | * 更新仓库 44 | * @author linsuwen 45 | * @date 2023/1/5 19:38 46 | */ 47 | @PostMapping("/update") 48 | public Result update(@RequestBody Storage storage){ 49 | return storageService.updateById(storage)?Result.success():Result.fail(); 50 | } 51 | 52 | /* 53 | * 删除仓库 54 | * @author linsuwen 55 | * @date 2023/1/5 19:40 56 | */ 57 | @GetMapping("/del") 58 | public Result del(@RequestParam String id){ 59 | return storageService.removeById(id)?Result.success():Result.fail(); 60 | } 61 | 62 | /* 63 | * 查询仓库列表 64 | * @author linsuwen 65 | * @date 2023/1/5 19:42 66 | */ 67 | @GetMapping("/list") 68 | public Result list(){ 69 | List list = storageService.list(); 70 | return Result.success(list); 71 | } 72 | 73 | /* 74 | * 模糊查询:根据输入查询仓库并以分页的形式展示 75 | * @author linsuwen 76 | * @date 2023/1/5 19:43 77 | */ 78 | @PostMapping("/listPage") 79 | public Result listPage(@RequestBody QueryPageParam query){ 80 | HashMap param = query.getParam(); 81 | String name = (String)param.get("name"); 82 | 83 | Page page = new Page(); 84 | page.setCurrent(query.getPageNum()); 85 | page.setSize(query.getPageSize()); 86 | 87 | LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); 88 | if(StringUtils.isNotBlank(name) && !"null".equals(name)){ 89 | queryWrapper.like(Storage::getName,name); 90 | } 91 | 92 | IPage result = storageService.pageCC(page,queryWrapper); 93 | return Result.success(result.getRecords(),result.getTotal()); 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/com/wms/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package com.wms.controller; 2 | 3 | 4 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 5 | import com.baomidou.mybatisplus.core.metadata.IPage; 6 | import com.baomidou.mybatisplus.core.toolkit.StringUtils; 7 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 8 | import com.wms.common.QueryPageParam; 9 | import com.wms.common.Result; 10 | import com.wms.entity.Menu; 11 | import com.wms.entity.User; 12 | import com.wms.service.MenuService; 13 | import com.wms.service.UserService; 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | import org.springframework.web.bind.annotation.*; 16 | 17 | import java.util.HashMap; 18 | import java.util.List; 19 | 20 | /** 21 | *

22 | * 前端控制器:用户管理和管理员管理模块 23 | *

24 | * 25 | * @author linsuwen 26 | * @since 2023-01-02 27 | */ 28 | @RestController 29 | @RequestMapping("/user") 30 | public class UserController { 31 | @Autowired 32 | private UserService userService; 33 | @Autowired 34 | private MenuService menuService; 35 | 36 | /* 37 | * 查询全部用户 38 | * @author linsuwen 39 | * @date 2023/1/2 19:26 40 | */ 41 | @GetMapping("/list") 42 | public List list(){ 43 | return userService.list(); 44 | } 45 | 46 | /* 47 | * 根据账号查找用户 48 | * @author linsuwen 49 | * @date 2023/1/4 14:53 50 | */ 51 | @GetMapping("/findByNo") 52 | public Result findByNo(@RequestParam String no){ 53 | List list = userService.lambdaQuery() 54 | .eq(User::getNo,no) 55 | .list(); 56 | return list.size()>0?Result.success(list):Result.fail(); 57 | } 58 | 59 | /* 60 | * 新增用户 61 | * @author linsuwen 62 | * @date 2023/1/2 19:11 63 | */ 64 | @PostMapping("/save") 65 | public Result save(@RequestBody User user){ 66 | return userService.save(user)?Result.success():Result.fail(); 67 | } 68 | 69 | /* 70 | * 更新用户 71 | * @author linsuwen 72 | * @date 2023/1/2 19:11 73 | */ 74 | @PostMapping("/update") 75 | public Result update(@RequestBody User user){ 76 | return userService.updateById(user)?Result.success():Result.fail(); 77 | } 78 | 79 | /* 80 | * 用户登录:登录的时候一并将菜单信息也查询出来 81 | * @author linsuwen 82 | * @date 2023/1/3 14:08 83 | */ 84 | @PostMapping("/login") 85 | public Result login(@RequestBody User user){ 86 | //匹配账号和密码 87 | List list = userService.lambdaQuery() 88 | .eq(User::getNo,user.getNo()) 89 | .eq(User::getPassword,user.getPassword()) 90 | .list(); 91 | 92 | if(list.size()>0){ 93 | User user1 = (User)list.get(0); 94 | List menuList = menuService.lambdaQuery() 95 | .like(Menu::getMenuright,user1.getRoleId()) 96 | .list(); 97 | HashMap res = new HashMap(); 98 | res.put("user",user1); 99 | res.put("menu",menuList); 100 | return Result.success(res); 101 | } 102 | return Result.fail(); 103 | } 104 | 105 | /* 106 | * 修改用户 107 | * @author linsuwen 108 | * @date 2023/1/4 15:02 109 | */ 110 | @PostMapping("/mod") 111 | public boolean mod(@RequestBody User user){ 112 | return userService.updateById(user); 113 | } 114 | 115 | /* 116 | * 新增或修改:存在用户则修改,否则新增用户 117 | * @author linsuwen 118 | * @date 2023/1/2 19:12 119 | */ 120 | @PostMapping("/saveOrUpdate") 121 | public Result saveOrUpdate(@RequestBody User user){ 122 | return userService.saveOrUpdate(user)?Result.success():Result.fail(); 123 | } 124 | 125 | /* 126 | * 删除用户 127 | * @author linsuwen 128 | * @date 2023/1/2 19:15 129 | */ 130 | @GetMapping("/del") 131 | public Result delete(Integer id){ 132 | return userService.removeById(id)?Result.success():Result.fail(); 133 | } 134 | 135 | /* 136 | * 模糊查询 137 | * @author linsuwen 138 | * @date 2023/1/2 19:36 139 | */ 140 | @PostMapping("/listP") 141 | public Result query(@RequestBody User user){ 142 | LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); 143 | if(StringUtils.isNotBlank(user.getName())){ 144 | wrapper.like(User::getName,user.getName()); 145 | } 146 | return Result.success(userService.list(wrapper)); 147 | } 148 | 149 | /* 150 | * 分页查询 151 | * @author linsuwen 152 | * @date 2023/1/2 19:48 153 | */ 154 | // @PostMapping("/listPage") 155 | // public Result page(@RequestBody QueryPageParam query){ 156 | // HashMap param = query.getParam(); 157 | // String name = (String)param.get("name"); 158 | // 159 | // Page page = new Page(); 160 | // page.setCurrent(query.getPageNum()); 161 | // page.setSize(query.getPageSize()); 162 | // 163 | // LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); 164 | // wrapper.like(User::getName,name); 165 | // 166 | // IPage result = userService.page(page,wrapper); 167 | // return Result.success(result.getRecords(),result.getTotal()); 168 | // } 169 | 170 | @PostMapping("/listPage") 171 | public List listPage(@RequestBody QueryPageParam query){ 172 | HashMap param = query.getParam(); 173 | String name = (String)param.get("name"); 174 | System.out.println("name=>"+(String)param.get("name")); 175 | 176 | Page page = new Page(); 177 | page.setCurrent(query.getPageNum()); 178 | page.setSize(query.getPageSize()); 179 | 180 | LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper(); 181 | lambdaQueryWrapper.like(User::getName,name); 182 | 183 | 184 | IPage result = userService.page(page,lambdaQueryWrapper); 185 | 186 | System.out.println("total=>"+result.getTotal()); 187 | 188 | return result.getRecords(); 189 | } 190 | 191 | /* 192 | * 查询功能:根据前端表单输入的信息或者下拉框选择查询用户,并以分页的形式返回前端 193 | * @author linsuwen 194 | * @date 2023/1/4 20:28 195 | */ 196 | @PostMapping("/listPageC1") 197 | public Result listPageC1(@RequestBody QueryPageParam query){ 198 | HashMap param = query.getParam(); 199 | String name = (String)param.get("name"); 200 | String sex = (String)param.get("sex"); 201 | String roleId = (String)param.get("roleId"); 202 | 203 | Page page = new Page(); 204 | page.setCurrent(query.getPageNum()); 205 | page.setSize(query.getPageSize()); 206 | 207 | LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper(); 208 | if(StringUtils.isNotBlank(name) && !"null".equals(name)){ 209 | lambdaQueryWrapper.like(User::getName,name); 210 | } 211 | if(StringUtils.isNotBlank(sex)){ 212 | lambdaQueryWrapper.eq(User::getSex,sex); 213 | } 214 | if(StringUtils.isNotBlank(roleId)){ 215 | lambdaQueryWrapper.eq(User::getRoleId,roleId); 216 | } 217 | 218 | IPage result = userService.pageCC(page,lambdaQueryWrapper); 219 | 220 | System.out.println("total=>"+result.getTotal()); 221 | 222 | return Result.success(result.getRecords(),result.getTotal()); 223 | } 224 | 225 | } 226 | -------------------------------------------------------------------------------- /src/main/java/com/wms/entity/Goods.java: -------------------------------------------------------------------------------- 1 | package com.wms.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.annotation.TableField; 6 | import java.io.Serializable; 7 | import io.swagger.annotations.ApiModel; 8 | import io.swagger.annotations.ApiModelProperty; 9 | import lombok.Data; 10 | import lombok.EqualsAndHashCode; 11 | 12 | /** 13 | *

14 | * 15 | *

16 | * 17 | * @author linsuwen 18 | * @since 2023-01-06 19 | */ 20 | @Data 21 | @EqualsAndHashCode(callSuper = false) 22 | @ApiModel(value="Goods对象", description="") 23 | public class Goods implements Serializable { 24 | 25 | private static final long serialVersionUID = 1L; 26 | 27 | @ApiModelProperty(value = "主键") 28 | @TableId(value = "id", type = IdType.AUTO) 29 | private Integer id; 30 | 31 | @ApiModelProperty(value = "货名") 32 | private String name; 33 | 34 | @ApiModelProperty(value = "仓库") 35 | private Integer storage; 36 | 37 | @ApiModelProperty(value = "分类") 38 | @TableField("goodsType") 39 | private Integer goodstype; 40 | 41 | @ApiModelProperty(value = "数量") 42 | private Integer count; 43 | 44 | @ApiModelProperty(value = "备注") 45 | private String remark; 46 | 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/wms/entity/Goodstype.java: -------------------------------------------------------------------------------- 1 | package com.wms.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import java.io.Serializable; 6 | import io.swagger.annotations.ApiModel; 7 | import io.swagger.annotations.ApiModelProperty; 8 | import lombok.Data; 9 | import lombok.EqualsAndHashCode; 10 | 11 | /** 12 | *

13 | * 14 | *

15 | * 16 | * @author linsuwen 17 | * @since 2023-01-05 18 | */ 19 | @Data 20 | @EqualsAndHashCode(callSuper = false) 21 | @ApiModel(value="Goodstype对象", description="") 22 | public class Goodstype implements Serializable { 23 | 24 | private static final long serialVersionUID = 1L; 25 | 26 | @ApiModelProperty(value = "主键") 27 | @TableId(value = "id", type = IdType.AUTO) 28 | private Integer id; 29 | 30 | @ApiModelProperty(value = "分类名") 31 | private String name; 32 | 33 | @ApiModelProperty(value = "备注") 34 | private String remark; 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/wms/entity/Menu.java: -------------------------------------------------------------------------------- 1 | package com.wms.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableField; 4 | import java.io.Serializable; 5 | import io.swagger.annotations.ApiModel; 6 | import io.swagger.annotations.ApiModelProperty; 7 | import lombok.Data; 8 | import lombok.EqualsAndHashCode; 9 | 10 | /** 11 | *

12 | * 13 | *

14 | * 15 | * @author linsuwen 16 | * @since 2023-01-03 17 | */ 18 | @Data 19 | @EqualsAndHashCode(callSuper = false) 20 | @ApiModel(value="Menu对象", description="") 21 | public class Menu implements Serializable { 22 | 23 | private static final long serialVersionUID = 1L; 24 | 25 | private Integer id; 26 | 27 | @ApiModelProperty(value = "菜单编码") 28 | @TableField("menuCode") 29 | private String menucode; 30 | 31 | @ApiModelProperty(value = "菜单名字") 32 | @TableField("menuName") 33 | private String menuname; 34 | 35 | @ApiModelProperty(value = "菜单级别") 36 | @TableField("menuLevel") 37 | private String menulevel; 38 | 39 | @ApiModelProperty(value = "菜单的父code") 40 | @TableField("menuParentCode") 41 | private String menuparentcode; 42 | 43 | @ApiModelProperty(value = "点击触发的函数") 44 | @TableField("menuClick") 45 | private String menuclick; 46 | 47 | @ApiModelProperty(value = "权限 0超级管理员,1表示管理员,2表示普通用户,可以用逗号组合使用") 48 | @TableField("menuRight") 49 | private String menuright; 50 | 51 | @TableField("menuComponent") 52 | private String menucomponent; 53 | 54 | @TableField("menuIcon") 55 | private String menuicon; 56 | 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/wms/entity/Record.java: -------------------------------------------------------------------------------- 1 | package com.wms.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import java.time.LocalDateTime; 6 | import com.baomidou.mybatisplus.annotation.TableField; 7 | import java.io.Serializable; 8 | import io.swagger.annotations.ApiModel; 9 | import io.swagger.annotations.ApiModelProperty; 10 | import lombok.Data; 11 | import lombok.EqualsAndHashCode; 12 | 13 | /** 14 | *

15 | * 16 | *

17 | * 18 | * @author linsuwen 19 | * @since 2023-01-06 20 | */ 21 | @Data 22 | @EqualsAndHashCode(callSuper = false) 23 | @ApiModel(value="Record对象", description="") 24 | public class Record implements Serializable { 25 | 26 | private static final long serialVersionUID = 1L; 27 | 28 | @ApiModelProperty(value = "主键") 29 | @TableId(value = "id", type = IdType.AUTO) 30 | private Integer id; 31 | 32 | @ApiModelProperty(value = "货品id") 33 | private Integer goods; 34 | 35 | @ApiModelProperty(value = "取货人/补货人") 36 | @TableField("userId") 37 | private Integer userid; 38 | 39 | @ApiModelProperty(value = "操作人id") 40 | private Integer adminId; 41 | 42 | @ApiModelProperty(value = "数量") 43 | private Integer count; 44 | 45 | @ApiModelProperty(value = "操作时间") 46 | private LocalDateTime createtime; 47 | 48 | @ApiModelProperty(value = "备注") 49 | private String remark; 50 | 51 | @TableField(exist = false) 52 | private String action; 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/wms/entity/RecordRes.java: -------------------------------------------------------------------------------- 1 | package com.wms.entity; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class RecordRes extends Record{ 7 | 8 | private String username; 9 | private String adminname; 10 | private String goodsname; 11 | private String storagename; 12 | private String goodstypename; 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/wms/entity/Storage.java: -------------------------------------------------------------------------------- 1 | package com.wms.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import java.io.Serializable; 6 | import io.swagger.annotations.ApiModel; 7 | import io.swagger.annotations.ApiModelProperty; 8 | import lombok.Data; 9 | import lombok.EqualsAndHashCode; 10 | 11 | /** 12 | *

13 | * 14 | *

15 | * 16 | * @author linsuwen 17 | * @since 2023-01-05 18 | */ 19 | @Data 20 | @EqualsAndHashCode(callSuper = false) 21 | @ApiModel(value="Storage对象", description="") 22 | public class Storage implements Serializable { 23 | 24 | private static final long serialVersionUID = 1L; 25 | 26 | @ApiModelProperty(value = "主键") 27 | @TableId(value = "id", type = IdType.AUTO) 28 | private Integer id; 29 | 30 | @ApiModelProperty(value = "仓库名") 31 | private String name; 32 | 33 | @ApiModelProperty(value = "备注") 34 | private String remark; 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/wms/entity/User.java: -------------------------------------------------------------------------------- 1 | package com.wms.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.annotation.TableField; 6 | import java.io.Serializable; 7 | import io.swagger.annotations.ApiModel; 8 | import io.swagger.annotations.ApiModelProperty; 9 | import lombok.Data; 10 | import lombok.EqualsAndHashCode; 11 | 12 | /** 13 | *

14 | * 用户实体类 15 | *

16 | * 17 | * @author linsuwen 18 | * @since 2023-01-02 19 | */ 20 | @Data 21 | @EqualsAndHashCode(callSuper = false) 22 | @ApiModel(value="User对象", description="") 23 | public class User implements Serializable { 24 | 25 | private static final long serialVersionUID = 1L; 26 | 27 | @ApiModelProperty(value = "主键") 28 | @TableId(value = "id", type = IdType.AUTO) 29 | private Integer id; 30 | 31 | @ApiModelProperty(value = "账号") 32 | private String no; 33 | 34 | @ApiModelProperty(value = "名字") 35 | private String name; 36 | 37 | @ApiModelProperty(value = "密码") 38 | private String password; 39 | 40 | private Integer age; 41 | 42 | @ApiModelProperty(value = "性别") 43 | private Integer sex; 44 | 45 | @ApiModelProperty(value = "电话") 46 | private String phone; 47 | 48 | @ApiModelProperty(value = "角色 0超级管理员,1管理员,2普通账号") 49 | private Integer roleId; 50 | 51 | @ApiModelProperty(value = "是否有效,Y有效,其他无效") 52 | @TableField("isValid") 53 | private String isvalid; 54 | 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/wms/mapper/GoodsMapper.java: -------------------------------------------------------------------------------- 1 | package com.wms.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.Wrapper; 4 | import com.baomidou.mybatisplus.core.metadata.IPage; 5 | import com.baomidou.mybatisplus.core.toolkit.Constants; 6 | import com.wms.entity.Goods; 7 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 8 | import org.apache.ibatis.annotations.Mapper; 9 | import org.apache.ibatis.annotations.Param; 10 | 11 | /** 12 | *

13 | * Mapper 接口 14 | *

15 | * 16 | * @author linsuwen 17 | * @since 2023-01-06 18 | */ 19 | @Mapper 20 | public interface GoodsMapper extends BaseMapper { 21 | IPage pageCC(IPage page, @Param(Constants.WRAPPER) Wrapper wrapper); 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/wms/mapper/GoodstypeMapper.java: -------------------------------------------------------------------------------- 1 | package com.wms.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.Wrapper; 4 | import com.baomidou.mybatisplus.core.metadata.IPage; 5 | import com.baomidou.mybatisplus.core.toolkit.Constants; 6 | import com.wms.entity.Goodstype; 7 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 8 | import org.apache.ibatis.annotations.Mapper; 9 | import org.apache.ibatis.annotations.Param; 10 | 11 | /** 12 | *

13 | * Mapper 接口 14 | *

15 | * 16 | * @author linsuwen 17 | * @since 2023-01-05 18 | */ 19 | @Mapper 20 | public interface GoodstypeMapper extends BaseMapper { 21 | IPage pageCC(IPage page, @Param(Constants.WRAPPER) Wrapper wrapper); 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/wms/mapper/MenuMapper.java: -------------------------------------------------------------------------------- 1 | package com.wms.mapper; 2 | 3 | import com.wms.entity.Menu; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | /** 8 | *

9 | * Mapper 接口 10 | *

11 | * 12 | * @author linsuwen 13 | * @since 2023-01-03 14 | */ 15 | @Mapper 16 | public interface MenuMapper extends BaseMapper { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/wms/mapper/RecordMapper.java: -------------------------------------------------------------------------------- 1 | package com.wms.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.Wrapper; 4 | import com.baomidou.mybatisplus.core.metadata.IPage; 5 | import com.baomidou.mybatisplus.core.toolkit.Constants; 6 | import com.wms.entity.Record; 7 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 8 | import org.apache.ibatis.annotations.Mapper; 9 | import org.apache.ibatis.annotations.Param; 10 | 11 | /** 12 | *

13 | * Mapper 接口 14 | *

15 | * 16 | * @author linsuwen 17 | * @since 2023-01-06 18 | */ 19 | @Mapper 20 | public interface RecordMapper extends BaseMapper { 21 | IPage pageCC(IPage page, @Param(Constants.WRAPPER) Wrapper wrapper); 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/wms/mapper/StorageMapper.java: -------------------------------------------------------------------------------- 1 | package com.wms.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.Wrapper; 4 | import com.baomidou.mybatisplus.core.metadata.IPage; 5 | import com.baomidou.mybatisplus.core.toolkit.Constants; 6 | import com.wms.entity.Storage; 7 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 8 | import org.apache.ibatis.annotations.Mapper; 9 | import org.apache.ibatis.annotations.Param; 10 | 11 | /** 12 | *

13 | * Mapper 接口 14 | *

15 | * 16 | * @author linsuwen 17 | * @since 2023-01-05 18 | */ 19 | @Mapper 20 | public interface StorageMapper extends BaseMapper { 21 | IPage pageCC(IPage page, @Param(Constants.WRAPPER) Wrapper wrapper); 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/wms/mapper/UserMapper.java: -------------------------------------------------------------------------------- 1 | package com.wms.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.Wrapper; 4 | import com.baomidou.mybatisplus.core.metadata.IPage; 5 | import com.baomidou.mybatisplus.core.toolkit.Constants; 6 | import com.wms.entity.User; 7 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 8 | import org.apache.ibatis.annotations.Mapper; 9 | import org.apache.ibatis.annotations.Param; 10 | 11 | /** 12 | *

13 | * Mapper 接口 14 | *

15 | * 16 | * @author linsuwen 17 | * @since 2023-01-02 18 | */ 19 | @Mapper 20 | public interface UserMapper extends BaseMapper { 21 | IPage pageC(IPage page); 22 | 23 | IPage pageCC(IPage page, @Param(Constants.WRAPPER) Wrapper wrapper); 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/wms/service/GoodsService.java: -------------------------------------------------------------------------------- 1 | package com.wms.service; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.Wrapper; 4 | import com.baomidou.mybatisplus.core.metadata.IPage; 5 | import com.wms.entity.Goods; 6 | import com.baomidou.mybatisplus.extension.service.IService; 7 | 8 | /** 9 | *

10 | * 服务类 11 | *

12 | * 13 | * @author linsuwen 14 | * @since 2023-01-06 15 | */ 16 | public interface GoodsService extends IService { 17 | IPage pageCC(IPage page, Wrapper wrapper); 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/wms/service/GoodstypeService.java: -------------------------------------------------------------------------------- 1 | package com.wms.service; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.Wrapper; 4 | import com.baomidou.mybatisplus.core.metadata.IPage; 5 | import com.wms.entity.Goodstype; 6 | import com.baomidou.mybatisplus.extension.service.IService; 7 | 8 | /** 9 | *

10 | * 服务类 11 | *

12 | * 13 | * @author linsuwen 14 | * @since 2023-01-05 15 | */ 16 | public interface GoodstypeService extends IService { 17 | IPage pageCC(IPage page, Wrapper wrapper); 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/wms/service/Impl/GoodsServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.wms.service.Impl; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.Wrapper; 4 | import com.baomidou.mybatisplus.core.metadata.IPage; 5 | import com.wms.entity.Goods; 6 | import com.wms.mapper.GoodsMapper; 7 | import com.wms.service.GoodsService; 8 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Service; 11 | 12 | /** 13 | *

14 | * 服务实现类 15 | *

16 | * 17 | * @author linsuwen 18 | * @since 2023-01-06 19 | */ 20 | @Service 21 | public class GoodsServiceImpl extends ServiceImpl implements GoodsService { 22 | @Autowired 23 | private GoodsMapper goodsMapper; 24 | @Override 25 | public IPage pageCC(IPage page, Wrapper wrapper) { 26 | return goodsMapper.pageCC(page,wrapper); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/wms/service/Impl/GoodstypeServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.wms.service.Impl; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.Wrapper; 4 | import com.baomidou.mybatisplus.core.metadata.IPage; 5 | import com.wms.entity.Goodstype; 6 | import com.wms.mapper.GoodstypeMapper; 7 | import com.wms.service.GoodstypeService; 8 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Service; 11 | 12 | /** 13 | *

14 | * 服务实现类 15 | *

16 | * 17 | * @author linsuwen 18 | * @since 2023-01-05 19 | */ 20 | @Service 21 | public class GoodstypeServiceImpl extends ServiceImpl implements GoodstypeService { 22 | 23 | @Autowired 24 | private GoodstypeMapper goodstypeMapper; 25 | 26 | @Override 27 | public IPage pageCC(IPage page, Wrapper wrapper) { 28 | return goodstypeMapper.pageCC(page,wrapper); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/wms/service/Impl/MenuServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.wms.service.Impl; 2 | 3 | import com.wms.entity.Menu; 4 | import com.wms.mapper.MenuMapper; 5 | import com.wms.service.MenuService; 6 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 7 | import org.springframework.stereotype.Service; 8 | 9 | /** 10 | *

11 | * 服务实现类 12 | *

13 | * 14 | * @author linsuwen 15 | * @since 2023-01-03 16 | */ 17 | @Service 18 | public class MenuServiceImpl extends ServiceImpl implements MenuService { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/wms/service/Impl/RecordServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.wms.service.Impl; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.Wrapper; 4 | import com.baomidou.mybatisplus.core.metadata.IPage; 5 | import com.wms.entity.Record; 6 | import com.wms.mapper.RecordMapper; 7 | import com.wms.service.RecordService; 8 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Service; 11 | 12 | /** 13 | *

14 | * 服务实现类 15 | *

16 | * 17 | * @author linsuwen 18 | * @since 2023-01-06 19 | */ 20 | @Service 21 | public class RecordServiceImpl extends ServiceImpl implements RecordService { 22 | @Autowired 23 | private RecordMapper recordMapper; 24 | 25 | @Override 26 | public IPage pageCC(IPage page, Wrapper wrapper) { 27 | return recordMapper.pageCC(page,wrapper); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/wms/service/Impl/StorageServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.wms.service.Impl; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.Wrapper; 4 | import com.baomidou.mybatisplus.core.metadata.IPage; 5 | import com.wms.entity.Storage; 6 | import com.wms.mapper.StorageMapper; 7 | import com.wms.service.StorageService; 8 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Service; 11 | 12 | /** 13 | *

14 | * 服务实现类 15 | *

16 | * 17 | * @author linsuwen 18 | * @since 2023-01-05 19 | */ 20 | @Service 21 | public class StorageServiceImpl extends ServiceImpl implements StorageService { 22 | @Autowired 23 | private StorageMapper storageMapper; 24 | 25 | @Override 26 | public IPage pageCC(IPage page, Wrapper wrapper) { 27 | return storageMapper.pageCC(page,wrapper); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/wms/service/Impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.wms.service.Impl; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.Wrapper; 4 | import com.baomidou.mybatisplus.core.metadata.IPage; 5 | import com.wms.entity.User; 6 | import com.wms.mapper.UserMapper; 7 | import com.wms.service.UserService; 8 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Service; 11 | 12 | /** 13 | *

14 | * 服务实现类 15 | *

16 | * 17 | * @author linsuwen 18 | * @since 2023-01-02 19 | */ 20 | @Service 21 | public class UserServiceImpl extends ServiceImpl implements UserService { 22 | @Autowired 23 | private UserMapper userMapper; 24 | @Override 25 | public IPage pageC(IPage page) { 26 | return userMapper.pageC(page); 27 | } 28 | 29 | @Override 30 | public IPage pageCC(IPage page, Wrapper wrapper) { 31 | return userMapper.pageCC(page,wrapper); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/wms/service/MenuService.java: -------------------------------------------------------------------------------- 1 | package com.wms.service; 2 | 3 | import com.wms.entity.Menu; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | /** 7 | *

8 | * 服务类 9 | *

10 | * 11 | * @author linsuwen 12 | * @since 2023-01-03 13 | */ 14 | public interface MenuService extends IService { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/wms/service/RecordService.java: -------------------------------------------------------------------------------- 1 | package com.wms.service; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.Wrapper; 4 | import com.baomidou.mybatisplus.core.metadata.IPage; 5 | import com.wms.entity.Record; 6 | import com.baomidou.mybatisplus.extension.service.IService; 7 | 8 | /** 9 | *

10 | * 服务类 11 | *

12 | * 13 | * @author linsuwen 14 | * @since 2023-01-06 15 | */ 16 | public interface RecordService extends IService { 17 | IPage pageCC(IPage page, Wrapper wrapper); 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/wms/service/StorageService.java: -------------------------------------------------------------------------------- 1 | package com.wms.service; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.Wrapper; 4 | import com.baomidou.mybatisplus.core.metadata.IPage; 5 | import com.wms.entity.Storage; 6 | import com.baomidou.mybatisplus.extension.service.IService; 7 | 8 | /** 9 | *

10 | * 服务类 11 | *

12 | * 13 | * @author linsuwen 14 | * @since 2023-01-05 15 | */ 16 | public interface StorageService extends IService { 17 | IPage pageCC(IPage page, Wrapper wrapper); 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/wms/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.wms.service; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.Wrapper; 4 | import com.baomidou.mybatisplus.core.metadata.IPage; 5 | import com.wms.entity.User; 6 | import com.baomidou.mybatisplus.extension.service.IService; 7 | 8 | /** 9 | *

10 | * 服务类 11 | *

12 | * 13 | * @author linsuwen 14 | * @since 2023-01-02 15 | */ 16 | public interface UserService extends IService { 17 | IPage pageC(IPage page); 18 | 19 | IPage pageCC(IPage page, Wrapper wrapper); 20 | } 21 | -------------------------------------------------------------------------------- /src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8002 3 | 4 | spring: 5 | datasource: 6 | url: jdbc:mysql://localhost:3306/wms?useUnicode=true&characterEncoding=utf-8&serveTimezone=UTC 7 | driver-class-name: com.mysql.cj.jdbc.Driver 8 | username: root 9 | password: 123456 10 | 11 | Logging: 12 | level: 13 | com.wms: debug -------------------------------------------------------------------------------- /src/main/resources/mapper/GoodsMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | id, name, storage, goodsType, count, remark 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/main/resources/mapper/GoodstypeMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | id, name, remark 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/main/resources/mapper/MenuMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | id, menuCode, menuName, menuLevel, menuParentCode, menuClick, menuRight, menuComponent, menuIcon 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/main/resources/mapper/RecordMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | id, goods, userId, admin_id, count, createtime, remark 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/main/resources/mapper/StorageMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | id, name, remark 15 | 16 | 17 | 20 | 21 | -------------------------------------------------------------------------------- /src/main/resources/mapper/UserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | id, no, name, password, age, sex, phone, role_id, isValid 21 | 22 | 23 | 26 | 27 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/test/java/com/wms/WarehouseSystemApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.wms; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class WarehouseSystemApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /target/classes/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8002 3 | 4 | spring: 5 | datasource: 6 | url: jdbc:mysql://localhost:3306/wms?useUnicode=true&characterEncoding=utf-8&serveTimezone=UTC 7 | driver-class-name: com.mysql.cj.jdbc.Driver 8 | username: root 9 | password: 123456 10 | 11 | Logging: 12 | level: 13 | com.wms: debug -------------------------------------------------------------------------------- /target/classes/mapper/GoodsMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | id, name, storage, goodsType, count, remark 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /target/classes/mapper/GoodstypeMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | id, name, remark 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /target/classes/mapper/MenuMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | id, menuCode, menuName, menuLevel, menuParentCode, menuClick, menuRight, menuComponent, menuIcon 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /target/classes/mapper/RecordMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | id, goods, userId, admin_id, count, createtime, remark 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /target/classes/mapper/StorageMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | id, name, remark 15 | 16 | 17 | 20 | 21 | -------------------------------------------------------------------------------- /target/classes/mapper/UserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | id, no, name, password, age, sex, phone, role_id, isValid 21 | 22 | 23 | 26 | 27 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /wms.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Navicat Premium Data Transfer 3 | 4 | Source Server : Mybatis 5 | Source Server Type : MySQL 6 | Source Server Version : 80028 7 | Source Host : localhost:3306 8 | Source Schema : wms 9 | 10 | Target Server Type : MySQL 11 | Target Server Version : 80028 12 | File Encoding : 65001 13 | 14 | Date: 06/01/2023 23:05:16 15 | */ 16 | 17 | SET NAMES utf8mb4; 18 | SET FOREIGN_KEY_CHECKS = 0; 19 | 20 | -- ---------------------------- 21 | -- Table structure for goods 22 | -- ---------------------------- 23 | DROP TABLE IF EXISTS `goods`; 24 | CREATE TABLE `goods` ( 25 | `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键', 26 | `name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '货名', 27 | `storage` int(0) NOT NULL COMMENT '仓库', 28 | `goodsType` int(0) NOT NULL COMMENT '分类', 29 | `count` int(0) NULL DEFAULT NULL COMMENT '数量', 30 | `remark` varchar(1000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '备注', 31 | PRIMARY KEY (`id`) USING BTREE 32 | ) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; 33 | 34 | -- ---------------------------- 35 | -- Records of goods 36 | -- ---------------------------- 37 | INSERT INTO `goods` VALUES (1, 'iPhone14', 2, 2, 100, '货物不可以挤压'); 38 | INSERT INTO `goods` VALUES (4, '洁面乳', 1, 1, 1000, '货物不可以挤压'); 39 | INSERT INTO `goods` VALUES (5, '葡萄', 5, 5, 500, '货物不可以挤压'); 40 | INSERT INTO `goods` VALUES (6, '西红柿', 5, 6, 800, '货物不可以挤压'); 41 | INSERT INTO `goods` VALUES (7, '皮皮虾', 4, 4, 500, '货物不可以挤压'); 42 | INSERT INTO `goods` VALUES (8, 'AD钙', 3, 3, 400, '货物不可以挤压'); 43 | INSERT INTO `goods` VALUES (11, 'iPad Air5', 2, 2, 800, '货物不可以挤压'); 44 | 45 | -- ---------------------------- 46 | -- Table structure for goodstype 47 | -- ---------------------------- 48 | DROP TABLE IF EXISTS `goodstype`; 49 | CREATE TABLE `goodstype` ( 50 | `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键', 51 | `name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '分类名', 52 | `remark` varchar(1000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '备注', 53 | PRIMARY KEY (`id`) USING BTREE 54 | ) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; 55 | 56 | -- ---------------------------- 57 | -- Records of goodstype 58 | -- ---------------------------- 59 | INSERT INTO `goodstype` VALUES (1, '日用品', '日常生活用品'); 60 | INSERT INTO `goodstype` VALUES (2, '数码产品', '数码产品'); 61 | INSERT INTO `goodstype` VALUES (3, '食品', '食品'); 62 | INSERT INTO `goodstype` VALUES (4, '冷冻品', '冷冻食品'); 63 | INSERT INTO `goodstype` VALUES (5, '水果', '水果产品'); 64 | INSERT INTO `goodstype` VALUES (6, '蔬菜', '蔬菜产品'); 65 | 66 | -- ---------------------------- 67 | -- Table structure for menu 68 | -- ---------------------------- 69 | DROP TABLE IF EXISTS `menu`; 70 | CREATE TABLE `menu` ( 71 | `id` int(0) NOT NULL, 72 | `menuCode` varchar(8) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '菜单编码', 73 | `menuName` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '菜单名字', 74 | `menuLevel` varchar(2) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '菜单级别', 75 | `menuParentCode` varchar(8) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '菜单的父code', 76 | `menuClick` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '点击触发的函数', 77 | `menuRight` varchar(8) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '权限 0超级管理员,1表示管理员,2表示普通用户,可以用逗号组合使用', 78 | `menuComponent` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, 79 | `menuIcon` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, 80 | PRIMARY KEY (`id`) USING BTREE 81 | ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; 82 | 83 | -- ---------------------------- 84 | -- Records of menu 85 | -- ---------------------------- 86 | INSERT INTO `menu` VALUES (1, '001', '管理员管理', '1', NULL, 'Admin', '0', 'admin/AdminManage.vue', 'el-icon-s-custom'); 87 | INSERT INTO `menu` VALUES (2, '002', '用户管理', '1', NULL, 'User', '0,1', 'user/UserManage.vue', 'el-icon-user-solid'); 88 | INSERT INTO `menu` VALUES (3, '003', '仓库管理', '1', NULL, 'Storage', '0,1', 'storage/StorageManage', 'el-icon-office-building'); 89 | INSERT INTO `menu` VALUES (4, '004', '物品分类管理', '1', NULL, 'Goodstype', '0,1', 'goodstype/GoodstypeManage', 'el-icon-menu'); 90 | INSERT INTO `menu` VALUES (5, '005', '物品管理 ', '1', NULL, 'Goods', '0,1,2', 'goods/GoodsManage', 'el-icon-s-management'); 91 | INSERT INTO `menu` VALUES (6, '006', '记录管理', '1', NULL, 'Record', '0,1,2', 'record/RecordManage', 'el-icon-s-order'); 92 | 93 | -- ---------------------------- 94 | -- Table structure for record 95 | -- ---------------------------- 96 | DROP TABLE IF EXISTS `record`; 97 | CREATE TABLE `record` ( 98 | `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键', 99 | `goods` int(0) NOT NULL COMMENT '货品id', 100 | `userId` int(0) NULL DEFAULT NULL COMMENT '取货人/补货人', 101 | `admin_id` int(0) NULL DEFAULT NULL COMMENT '操作人id', 102 | `count` int(0) NULL DEFAULT NULL COMMENT '数量', 103 | `createtime` datetime(0) NULL DEFAULT NULL COMMENT '操作时间', 104 | `remark` varchar(1000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '备注', 105 | PRIMARY KEY (`id`) USING BTREE 106 | ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; 107 | 108 | -- ---------------------------- 109 | -- Records of record 110 | -- ---------------------------- 111 | INSERT INTO `record` VALUES (1, 1, 3, 2, 100, '2023-01-06 20:46:48', '取货'); 112 | INSERT INTO `record` VALUES (2, 4, 9, 8, 200, '2023-01-06 20:47:45', '补货'); 113 | INSERT INTO `record` VALUES (3, 5, 4, 2, 80, '2023-01-06 20:48:47', '取货'); 114 | INSERT INTO `record` VALUES (4, 6, 5, 8, 120, '2023-01-06 20:49:57', '补货'); 115 | INSERT INTO `record` VALUES (5, 11, 6, 2, 50, '2023-01-06 20:50:20', '取货'); 116 | INSERT INTO `record` VALUES (6, 7, 9, 1, 200, NULL, '入库200只皮皮虾'); 117 | INSERT INTO `record` VALUES (9, 8, 5, 1, 300, NULL, '入库300箱AD钙'); 118 | INSERT INTO `record` VALUES (10, 8, 5, 1, -100, NULL, '出库100箱AD钙'); 119 | INSERT INTO `record` VALUES (11, 11, 4, 2, -200, NULL, '出库iPad Air5 200台'); 120 | 121 | -- ---------------------------- 122 | -- Table structure for storage 123 | -- ---------------------------- 124 | DROP TABLE IF EXISTS `storage`; 125 | CREATE TABLE `storage` ( 126 | `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键', 127 | `name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '仓库名', 128 | `remark` varchar(1000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '备注', 129 | PRIMARY KEY (`id`) USING BTREE 130 | ) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; 131 | 132 | -- ---------------------------- 133 | -- Records of storage 134 | -- ---------------------------- 135 | INSERT INTO `storage` VALUES (1, '日用品仓库', '用于存放日用品'); 136 | INSERT INTO `storage` VALUES (2, '数码仓库', '用于存放数码产品'); 137 | INSERT INTO `storage` VALUES (3, '食品仓库', '用于存放食品'); 138 | INSERT INTO `storage` VALUES (4, '冷冻仓库', '用于存放冷冻食品'); 139 | INSERT INTO `storage` VALUES (5, '果蔬仓库', '用于存放水果和蔬菜'); 140 | INSERT INTO `storage` VALUES (6, '服装仓库', '用于存放服装'); 141 | INSERT INTO `storage` VALUES (7, '水产仓库', '用于存放水产品'); 142 | 143 | -- ---------------------------- 144 | -- Table structure for user 145 | -- ---------------------------- 146 | DROP TABLE IF EXISTS `user`; 147 | CREATE TABLE `user` ( 148 | `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键', 149 | `no` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '账号', 150 | `name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '名字', 151 | `password` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '密码', 152 | `age` int(0) NULL DEFAULT NULL, 153 | `sex` int(0) NULL DEFAULT NULL COMMENT '性别', 154 | `phone` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '电话', 155 | `role_id` int(0) NULL DEFAULT NULL COMMENT '角色 0超级管理员,1管理员,2普通账号', 156 | `isValid` varchar(4) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'Y' COMMENT '是否有效,Y有效,其他无效', 157 | PRIMARY KEY (`id`) USING BTREE 158 | ) ENGINE = InnoDB AUTO_INCREMENT = 17 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; 159 | 160 | -- ---------------------------- 161 | -- Records of user 162 | -- ---------------------------- 163 | INSERT INTO `user` VALUES (1, 'adminPromax', '超级管理员', '123456', 18, 1, '18855079621', 0, 'Y'); 164 | INSERT INTO `user` VALUES (2, 'admin', '普通管理员', '123456', 19, 0, '18855079621', 1, 'Y'); 165 | INSERT INTO `user` VALUES (3, 'user', '用户01', '123456', 20, 0, '18855079621', 2, 'Y'); 166 | INSERT INTO `user` VALUES (4, 'user03', '湫', '123456', 20, 1, '18855079621', 2, 'Y'); 167 | INSERT INTO `user` VALUES (5, 'user04', '朝菌', '123456', 18, 1, '18855079621', 2, 'Y'); 168 | INSERT INTO `user` VALUES (6, 'user05', '蟪蛄', '123456', 32, 0, '18855079621', 2, 'Y'); 169 | INSERT INTO `user` VALUES (7, 'user06', '鲲鹏', '123456', 26, 1, '18855079621', 2, 'Y'); 170 | INSERT INTO `user` VALUES (8, 'admin02', '管理员02', '123456', 24, 0, '18855079621', 1, 'Y'); 171 | INSERT INTO `user` VALUES (9, 'user02', '椿', '123456', 18, 0, '18855079621', 2, 'Y'); 172 | 173 | SET FOREIGN_KEY_CHECKS = 1; 174 | --------------------------------------------------------------------------------