当前位置:   article > 正文

SpringBoot + Vue 动态加载菜单栏_springboot+vue动态菜单

springboot+vue动态菜单

 

第一步:SpirngBoot 项目

1.1 建库脚本

  1. /*
  2. Navicat MySQL Data Transfer
  3. Source Server : 192.168.1.73
  4. Source Server Type : MySQL
  5. Source Server Version : 80015
  6. Source Host : 192.168.1.73:3306
  7. Source Schema : auth_shrio
  8. Target Server Type : MySQL
  9. Target Server Version : 80015
  10. File Encoding : 65001
  11. Date: 02/12/2020 18:45:00
  12. */
  13. SET NAMES utf8mb4;
  14. SET FOREIGN_KEY_CHECKS = 0;
  15. -- ----------------------------
  16. -- Table structure for cost
  17. -- ----------------------------
  18. DROP TABLE IF EXISTS `cost`;
  19. CREATE TABLE `cost` (
  20. `cost_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  21. `house_id` int(11) NOT NULL COMMENT '房屋ID',
  22. `create_date` date NOT NULL COMMENT '创建日期',
  23. `money` int(11) NOT NULL DEFAULT 0 COMMENT '金额',
  24. `status` tinyint(4) NOT NULL DEFAULT 1 COMMENT '状态:1 未支付,2:已支付',
  25. PRIMARY KEY (`cost_id`) USING BTREE,
  26. INDEX `FK_cost_house`(`house_id`) USING BTREE,
  27. CONSTRAINT `FK_cost_house` FOREIGN KEY (`house_id`) REFERENCES `house` (`house_id`) ON DELETE RESTRICT ON UPDATE RESTRICT
  28. ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '费用信息表' ROW_FORMAT = Dynamic;
  29. -- ----------------------------
  30. -- Records of cost
  31. -- ----------------------------
  32. INSERT INTO `cost` VALUES (1, 2, '2020-12-02', 3360, 1);
  33. -- ----------------------------
  34. -- Table structure for house
  35. -- ----------------------------
  36. DROP TABLE IF EXISTS `house`;
  37. CREATE TABLE `house` (
  38. `house_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  39. `house_number` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '房屋编号',
  40. `area` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '区域',
  41. `house_address` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '房屋地址',
  42. `house_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '房屋类型',
  43. `acreage` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '房屋面积',
  44. `peroples` int(10) NULL DEFAULT NULL COMMENT '可容纳人数',
  45. `rent` int(10) NULL DEFAULT NULL COMMENT '房屋租金',
  46. `status` tinyint(4) NULL DEFAULT NULL COMMENT '房屋状态:1:已租、2:待租',
  47. `user_id` int(11) NOT NULL COMMENT '用户ID',
  48. PRIMARY KEY (`house_id`) USING BTREE,
  49. INDEX `FK_house_user`(`user_id`) USING BTREE,
  50. CONSTRAINT `FK_house_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`) ON DELETE RESTRICT ON UPDATE RESTRICT
  51. ) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '房屋信息表' ROW_FORMAT = Dynamic;
  52. -- ----------------------------
  53. -- Records of house
  54. -- ----------------------------
  55. INSERT INTO `house` VALUES (1, '0001', '广东省宝安区麻布新村', '105号13-1101', '1', '28.35平方', 3, 1800, 1, 3);
  56. INSERT INTO `house` VALUES (2, '0002', '广东省宝安区麻布新村', '105号13-1102', '1', '44.2平方', 5, 3400, 1, 1);
  57. INSERT INTO `house` VALUES (4, '0003', '广东省宝安区麻布新村', '105号13-1103', '1', '38.35平方', 3, 2800, 1, 1);
  58. -- ----------------------------
  59. -- Table structure for house_lease
  60. -- ----------------------------
  61. DROP TABLE IF EXISTS `house_lease`;
  62. CREATE TABLE `house_lease` (
  63. `house_id` int(11) NOT NULL COMMENT '房屋ID',
  64. `lease_id` int(11) NOT NULL COMMENT '租赁者ID',
  65. PRIMARY KEY (`house_id`, `lease_id`) USING BTREE,
  66. INDEX `FK_house_lease_lease`(`lease_id`) USING BTREE,
  67. CONSTRAINT `FK_house_lease_house` FOREIGN KEY (`house_id`) REFERENCES `house` (`house_id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
  68. CONSTRAINT `FK_house_lease_lease` FOREIGN KEY (`lease_id`) REFERENCES `lease` (`lease_id`) ON DELETE RESTRICT ON UPDATE RESTRICT
  69. ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '房屋租赁信息表' ROW_FORMAT = Dynamic;
  70. -- ----------------------------
  71. -- Records of house_lease
  72. -- ----------------------------
  73. INSERT INTO `house_lease` VALUES (1, 1);
  74. INSERT INTO `house_lease` VALUES (2, 1);
  75. -- ----------------------------
  76. -- Table structure for lease
  77. -- ----------------------------
  78. DROP TABLE IF EXISTS `lease`;
  79. CREATE TABLE `lease` (
  80. `lease_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  81. `real_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '租赁者姓名',
  82. `id_card` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '租赁者身份证号码',
  83. `sex` tinyint(4) NOT NULL COMMENT '性别:1 男 2 女',
  84. `telphone` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '电话',
  85. `hometown` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '租赁者籍贯',
  86. `status` tinyint(4) NOT NULL COMMENT '状态:1:租房中 2:未租房',
  87. `start_date` date NOT NULL COMMENT '租赁开始时间',
  88. `end_date` date NOT NULL COMMENT '租赁结束时间',
  89. `sign_date` date NOT NULL COMMENT '租赁签订时间',
  90. PRIMARY KEY (`lease_id`) USING BTREE
  91. ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '租赁者信息表' ROW_FORMAT = Dynamic;
  92. -- ----------------------------
  93. -- Records of lease
  94. -- ----------------------------
  95. INSERT INTO `lease` VALUES (1, '周志刚', '430921199112205454', 1, '13265740591', '湖南', 1, '2015-10-01', '2025-01-01', '2020-12-02');
  96. -- ----------------------------
  97. -- Table structure for permission
  98. -- ----------------------------
  99. DROP TABLE IF EXISTS `permission`;
  100. CREATE TABLE `permission` (
  101. `permission_id` int(11) NOT NULL,
  102. `permision_component` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  103. `permision_icon` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  104. `permision_parent_id` int(11) NULL DEFAULT NULL,
  105. `permission_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  106. `permission_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  107. `permission_zh` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  108. PRIMARY KEY (`permission_id`) USING BTREE
  109. ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
  110. -- ----------------------------
  111. -- Records of permission
  112. -- ----------------------------
  113. INSERT INTO `permission`(permission_id,permission_zh,permission_name,permission_path,permision_icon,permision_component,permision_parent_id) VALUES (1, '首页', 'Admin', '/admin', 'el-icon-s-home', 'AdminIndex', 0);
  114. INSERT INTO `permission`(permission_id,permission_zh,permission_name,permission_path,permision_icon,permision_component,permision_parent_id) VALUES (2, '运行情况', 'DashBoard', '/admin/dashboard', NULL, 'dashboard/Index', 1);
  115. INSERT INTO `permission`(permission_id,permission_zh,permission_name,permission_path,permision_icon,permision_component,permision_parent_id) VALUES (3, '用户管理', 'User', '/admin', 'el-icon-user', 'AdminIndex', 0);
  116. INSERT INTO `permission`(permission_id,permission_zh,permission_name,permission_path,permision_icon,permision_component,permision_parent_id) VALUES (4, '用户信息', 'Profile', '/admin/user/Profile', NULL, 'user/Profile', 3);
  117. INSERT INTO `permission`(permission_id,permission_zh,permission_name,permission_path,permision_icon,permision_component,permision_parent_id) VALUES (5, '角色配置', 'Role', '/admin/user/Role', NULL, 'user/Role', 3);
  118. INSERT INTO `permission`(permission_id,permission_zh,permission_name,permission_path,permision_icon,permision_component,permision_parent_id) VALUES (6, '测试菜单', 'ArticleManage', '/admin', 'el-icon-edit', 'AdminIndex', 0);
  119. INSERT INTO `permission`(permission_id,permission_zh,permission_name,permission_path,permision_icon,permision_component,permision_parent_id) VALUES (7, '菜单列表1', 'ArticleList', '/admin/test/Test1', NULL, 'test/Test1', 6);
  120. INSERT INTO `permission`(permission_id,permission_zh,permission_name,permission_path,permision_icon,permision_component,permision_parent_id) VALUES (8, '菜单列表2', 'ArticleEdit', '/admin/test/Test2', NULL, 'test/Test2', 6);
  121. -- ----------------------------
  122. -- Table structure for role
  123. -- ----------------------------
  124. DROP TABLE IF EXISTS `role`;
  125. CREATE TABLE `role` (
  126. `role_id` int(11) NOT NULL,
  127. `role_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  128. PRIMARY KEY (`role_id`) USING BTREE
  129. ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
  130. -- ----------------------------
  131. -- Records of role
  132. -- ----------------------------
  133. INSERT INTO `role` VALUES (1, 'svip');
  134. INSERT INTO `role` VALUES (2, 'vip');
  135. INSERT INTO `role` VALUES (3, 'p');
  136. INSERT INTO `role` VALUES (4, 'admin');
  137. -- ----------------------------
  138. -- Table structure for role_permission
  139. -- ----------------------------
  140. DROP TABLE IF EXISTS `role_permission`;
  141. CREATE TABLE `role_permission` (
  142. `role_id` int(11) NOT NULL,
  143. `permission_id` int(11) NOT NULL,
  144. PRIMARY KEY (`role_id`, `permission_id`) USING BTREE,
  145. INDEX `FKf8yllw1ecvwqy3ehyxawqa1qp`(`permission_id`) USING BTREE,
  146. CONSTRAINT `FKa6jx8n8xkesmjmv6jqug6bg68` FOREIGN KEY (`role_id`) REFERENCES `role` (`role_id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
  147. CONSTRAINT `FKf8yllw1ecvwqy3ehyxawqa1qp` FOREIGN KEY (`permission_id`) REFERENCES `permission` (`permission_id`) ON DELETE RESTRICT ON UPDATE RESTRICT
  148. ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
  149. -- ----------------------------
  150. -- Records of role_permission
  151. -- ----------------------------
  152. INSERT INTO `role_permission` VALUES (1, 1);
  153. INSERT INTO `role_permission` VALUES (1, 2);
  154. INSERT INTO `role_permission` VALUES (1, 3);
  155. INSERT INTO `role_permission` VALUES (1, 4);
  156. INSERT INTO `role_permission` VALUES (1, 5);
  157. INSERT INTO `role_permission` VALUES (1, 6);
  158. INSERT INTO `role_permission` VALUES (1, 7);
  159. INSERT INTO `role_permission` VALUES (1, 8);
  160. INSERT INTO `role_permission` VALUES (2, 1);
  161. INSERT INTO `role_permission` VALUES (2, 2);
  162. -- ----------------------------
  163. -- Table structure for token_relation
  164. -- ----------------------------
  165. DROP TABLE IF EXISTS `token_relation`;
  166. CREATE TABLE `token_relation` (
  167. `relation_sid` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  168. `username` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '用户名',
  169. `token` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'token凭证',
  170. PRIMARY KEY (`relation_sid`) USING BTREE
  171. ) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
  172. -- ----------------------------
  173. -- Records of token_relation
  174. -- ----------------------------
  175. INSERT INTO `token_relation` VALUES (3, 'Jack', 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MDY5NTkzNzAsInVzZXJuYW1lIjoiSmFjayJ9.m3OZ1w2YQLmI0cE9oK79_pZbXnON_-e5YMbZLPtdyrU');
  176. -- ----------------------------
  177. -- Table structure for user
  178. -- ----------------------------
  179. DROP TABLE IF EXISTS `user`;
  180. CREATE TABLE `user` (
  181. `user_id` int(11) NOT NULL COMMENT '主键',
  182. `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '密码',
  183. `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '账户',
  184. `telephone` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '手机号码',
  185. `email` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '邮箱地址',
  186. `guid` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '唯一码',
  187. `real_name` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '真实姓名',
  188. `address` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '地址',
  189. PRIMARY KEY (`user_id`) USING BTREE
  190. ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
  191. -- ----------------------------
  192. -- Records of user
  193. -- ----------------------------
  194. INSERT INTO `user` VALUES (1, '123', 'Jack', '123', '123@163.com', NULL, NULL, NULL);
  195. INSERT INTO `user` VALUES (2, '123', 'Rose', '1234', '1234@163.com', NULL, NULL, NULL);
  196. INSERT INTO `user` VALUES (3, '123', 'Paul', '12345', '12345@163.com', NULL, NULL, NULL);
  197. INSERT INTO `user` VALUES (4, '123', 'Jane', '123456', '123456@163.com', NULL, '简', '中国广东省深圳市盐田区');
  198. -- ----------------------------
  199. -- Table structure for user_role
  200. -- ----------------------------
  201. DROP TABLE IF EXISTS `user_role`;
  202. CREATE TABLE `user_role` (
  203. `user_id` int(11) NOT NULL,
  204. `role_id` int(11) NOT NULL,
  205. PRIMARY KEY (`user_id`, `role_id`) USING BTREE,
  206. INDEX `FKa68196081fvovjhkek5m97n3y`(`role_id`) USING BTREE,
  207. CONSTRAINT `FK859n2jvi8ivhui0rl0esws6o` FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
  208. CONSTRAINT `FKa68196081fvovjhkek5m97n3y` FOREIGN KEY (`role_id`) REFERENCES `role` (`role_id`) ON DELETE RESTRICT ON UPDATE RESTRICT
  209. ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
  210. -- ----------------------------
  211. -- Records of user_role
  212. -- ----------------------------
  213. INSERT INTO `user_role` VALUES (3, 3);
  214. INSERT INTO `user_role` VALUES (4, 4);
  215. -- ----------------------------
  216. -- Table structure for verification
  217. -- ----------------------------
  218. DROP TABLE IF EXISTS `verification`;
  219. CREATE TABLE `verification` (
  220. `verification_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  221. `verification_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '验证码',
  222. `status` tinyint(255) NULL DEFAULT NULL COMMENT '状态:1:未使用,2:已使用',
  223. `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建日期',
  224. `fail_date` datetime(0) NULL DEFAULT NULL COMMENT '失效日期',
  225. PRIMARY KEY (`verification_id`) USING BTREE
  226. ) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
  227. SET FOREIGN_KEY_CHECKS = 1;

1.2 SpringBoot项目源码

1.2.1 实体层定义:

  1. package com.zzg.entity;
  2. import java.util.Date;
  3. import javax.persistence.CascadeType;
  4. import javax.persistence.Entity;
  5. import javax.persistence.GeneratedValue;
  6. import javax.persistence.GenerationType;
  7. import javax.persistence.Id;
  8. import javax.persistence.JoinColumn;
  9. import javax.persistence.ManyToOne;
  10. import lombok.Getter;
  11. import lombok.Setter;
  12. @Getter
  13. @Setter
  14. @Entity
  15. public class Cost {
  16. @Id
  17. @GeneratedValue(strategy = GenerationType.IDENTITY) // 自增长策略
  18. private Integer costId;
  19. @ManyToOne(cascade={CascadeType.MERGE,CascadeType.REFRESH},optional=false)//可选属性optional=false,表示house不能为空。删除房屋,不影响用户
  20. @JoinColumn(name="house_id")//设置在house表中的关联字段(外键)
  21. private House house;//所属房屋
  22. private Date createDate;
  23. private Integer money;
  24. private Integer status;
  25. }
  1. package com.zzg.entity;
  2. import java.util.Set;
  3. import javax.persistence.CascadeType;
  4. import javax.persistence.Entity;
  5. import javax.persistence.FetchType;
  6. import javax.persistence.GeneratedValue;
  7. import javax.persistence.GenerationType;
  8. import javax.persistence.Id;
  9. import javax.persistence.JoinColumn;
  10. import javax.persistence.JoinTable;
  11. import javax.persistence.ManyToMany;
  12. import javax.persistence.ManyToOne;
  13. import lombok.Getter;
  14. import lombok.Setter;
  15. @Getter
  16. @Setter
  17. @Entity
  18. public class House {
  19. @Id
  20. @GeneratedValue(strategy = GenerationType.IDENTITY) // 自增长策略
  21. private Integer houseId;
  22. private String houseNumber;
  23. private String area;
  24. private String houseAddress;
  25. private String houseType;
  26. private String acreage;
  27. private Integer peroples;
  28. private Integer rent;
  29. private Integer status;
  30. @ManyToOne(cascade = {CascadeType.MERGE,CascadeType.REFRESH}, optional = false) // 可选属性optional=false,表示house不能为空。删除房屋,不影响用户
  31. @JoinColumn(name = "user_id") // 设置在house表中的关联字段(外键)
  32. private User user;// 所属房屋
  33. @ManyToMany(fetch = FetchType.EAGER)
  34. @JoinTable(name = "house_lease", joinColumns = {
  35. @JoinColumn(name = "house_id", referencedColumnName = "houseId") }, inverseJoinColumns = {
  36. @JoinColumn(name = "lease_id", referencedColumnName = "leaseId") })
  37. private Set<Lease> leases;
  38. }
  1. package com.zzg.entity;
  2. import java.util.Date;
  3. import javax.persistence.Entity;
  4. import javax.persistence.GeneratedValue;
  5. import javax.persistence.GenerationType;
  6. import javax.persistence.Id;
  7. import lombok.Getter;
  8. import lombok.Setter;
  9. @Getter
  10. @Setter
  11. @Entity
  12. public class Lease {
  13. @Id
  14. @GeneratedValue(strategy = GenerationType.IDENTITY) // 自增长策略
  15. private Integer leaseId;
  16. private String realName;
  17. private String idCard;
  18. private Integer sex;
  19. private String telphone;
  20. private String hometown;
  21. private Integer status;
  22. private Date startDate;
  23. private Date endDate;
  24. private Date signDate;
  25. // @ManyToMany(fetch = FetchType.EAGER)
  26. // @JoinTable(name = "house_lease", joinColumns = {
  27. // @JoinColumn(name = "lease_id", referencedColumnName = "leaseId") }, inverseJoinColumns = {
  28. // @JoinColumn(name = "house_id", referencedColumnName = "houseId") })
  29. // private Set<House> houses;
  30. }
  1. package com.zzg.entity;
  2. import javax.persistence.Entity;
  3. import javax.persistence.Id;
  4. import lombok.Getter;
  5. import lombok.Setter;
  6. /**
  7. *
  8. * @author zzg
  9. *
  10. */
  11. @Getter
  12. @Setter
  13. @Entity
  14. public class Permission {
  15. @Id
  16. private Integer permissionId;
  17. private String permissionName;
  18. private String permissionZh;
  19. private String permissionPath;
  20. private String permisionIcon;
  21. private String permisionComponent;
  22. private Integer permisionParentId;
  23. // @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
  24. // @JoinColumn(name="permision_parent_id")
  25. // private Permission parent;
  26. // // 子菜单项
  27. // @OneToMany(cascade = CascadeType.ALL, mappedBy = "parent", fetch = FetchType.EAGER)
  28. // private Set<Permission> child = new HashSet<Permission>() ;
  29. }
  1. package com.zzg.entity;
  2. import lombok.Getter;
  3. import lombok.Setter;
  4. import javax.persistence.*;
  5. import java.util.Set;
  6. /**
  7. *
  8. * @author zzg
  9. *
  10. */
  11. @Getter
  12. @Setter
  13. @Entity
  14. public class Role {
  15. @Id
  16. private Integer roleId;
  17. private String roleName;
  18. @ManyToMany(fetch = FetchType.EAGER)
  19. @JoinTable(name = "role_permission",
  20. joinColumns = {@JoinColumn(name = "ROLE_ID", referencedColumnName = "roleId")},
  21. inverseJoinColumns = {@JoinColumn(name = "PERMISSION_ID", referencedColumnName = "permissionId")})
  22. private Set<Permission> permissions;
  23. }
  1. package com.zzg.entity;
  2. import javax.persistence.Entity;
  3. import javax.persistence.GeneratedValue;
  4. import javax.persistence.GenerationType;
  5. import javax.persistence.Id;
  6. import lombok.Getter;
  7. import lombok.Setter;
  8. @Getter
  9. @Setter
  10. @Entity(name="token_relation")
  11. public class TokenRelation {
  12. @Id
  13. @GeneratedValue(strategy = GenerationType.IDENTITY) // 自增长策略
  14. private Integer relationSid;
  15. private String username;
  16. private String token;
  17. }
  1. package com.zzg.entity;
  2. import java.util.List;
  3. import java.util.Set;
  4. import javax.persistence.CascadeType;
  5. import javax.persistence.Entity;
  6. import javax.persistence.FetchType;
  7. import javax.persistence.Id;
  8. import javax.persistence.JoinColumn;
  9. import javax.persistence.JoinTable;
  10. import javax.persistence.ManyToMany;
  11. import javax.persistence.OneToMany;
  12. import lombok.Getter;
  13. import lombok.Setter;
  14. /**
  15. *
  16. * @author zzg
  17. *
  18. */
  19. @Getter
  20. @Setter
  21. @Entity
  22. public class User {
  23. @Id
  24. private Integer userId;
  25. private String username;
  26. private String password;
  27. @ManyToMany(fetch = FetchType.EAGER)
  28. @JoinTable(name = "user_role",
  29. joinColumns = {@JoinColumn(name = "USER_ID", referencedColumnName = "userId")},
  30. inverseJoinColumns = {@JoinColumn(name = "ROLE_ID", referencedColumnName = "roleId")})
  31. private Set<Role> roles;
  32. private String telephone;
  33. private String email;
  34. private String guid;
  35. private String realName;
  36. private String address;
  37. }
  1. package com.zzg.entity;
  2. import java.util.Date;
  3. import javax.persistence.Entity;
  4. import javax.persistence.GeneratedValue;
  5. import javax.persistence.GenerationType;
  6. import javax.persistence.Id;
  7. import lombok.Getter;
  8. import lombok.Setter;
  9. @Getter
  10. @Setter
  11. @Entity(name="verification")
  12. public class Verification {
  13. @Id
  14. @GeneratedValue(strategy = GenerationType.IDENTITY) // 自增长策略
  15. private Integer verificationId;
  16. private String verificationCode;
  17. private Integer status;
  18. private Date createDate;
  19. private Date failDate;
  20. }

1.2.2 dao层定义:

  1. package com.zzg.dao;
  2. import javax.transaction.Transactional;
  3. import org.springframework.data.jpa.repository.JpaRepository;
  4. import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
  5. import org.springframework.data.jpa.repository.Modifying;
  6. import org.springframework.data.jpa.repository.Query;
  7. import org.springframework.stereotype.Repository;
  8. import com.zzg.entity.Cost;
  9. @Repository
  10. public interface CostRepository extends JpaRepository<Cost, Integer>, JpaSpecificationExecutor<Cost> {
  11. /**
  12. * 原生SQL
  13. * @param houseId
  14. * @param costId
  15. * @return
  16. */
  17. @Transactional
  18. @Modifying
  19. @Query(nativeQuery = true,value="update cost u set u.house_id = ?1 where u.cost_id = ?2")
  20. int modifyHouseId(Integer houseId, Integer costId);
  21. }
  1. package com.zzg.dao;
  2. import javax.transaction.Transactional;
  3. import org.springframework.data.jpa.repository.JpaRepository;
  4. import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
  5. import org.springframework.data.jpa.repository.Modifying;
  6. import org.springframework.data.jpa.repository.Query;
  7. import org.springframework.stereotype.Repository;
  8. import com.zzg.entity.House;
  9. @Repository
  10. public interface HouseRepository extends JpaRepository<House, Integer>, JpaSpecificationExecutor<House> {
  11. /**
  12. * 原生SQL
  13. * @param houseId
  14. * @param costId
  15. * @return
  16. */
  17. @Transactional
  18. @Modifying
  19. @Query(nativeQuery = true,value="update house u set u.user_id = ?1 where u.house_id = ?2")
  20. int modifyUserId(Integer userId, Integer houseId);
  21. }
  1. package com.zzg.dao;
  2. import org.springframework.data.jpa.repository.JpaRepository;
  3. import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
  4. import org.springframework.stereotype.Repository;
  5. import com.zzg.entity.Lease;
  6. @Repository
  7. public interface LeaseRepository extends JpaRepository<Lease, Integer>, JpaSpecificationExecutor<Lease> {
  8. }
  1. package com.zzg.dao;
  2. import java.util.List;
  3. import org.springframework.data.jpa.repository.JpaRepository;
  4. import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
  5. import org.springframework.stereotype.Repository;
  6. import com.zzg.entity.Permission;
  7. /**
  8. *
  9. * @author zzg
  10. *
  11. */
  12. @Repository
  13. public interface PermissionRepository extends JpaRepository<Permission, Integer>, JpaSpecificationExecutor<Permission> {
  14. }
  1. package com.zzg.dao;
  2. import org.springframework.data.jpa.repository.JpaRepository;
  3. import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
  4. import org.springframework.stereotype.Repository;
  5. import com.zzg.entity.Role;
  6. /**
  7. *
  8. * @author zzg
  9. *
  10. */
  11. @Repository
  12. public interface RoleRepository extends JpaRepository<Role, Integer>, JpaSpecificationExecutor<Role> {
  13. Role findByRoleId(Integer userId);
  14. }
  1. package com.zzg.dao;
  2. import org.springframework.data.jpa.repository.JpaRepository;
  3. import org.springframework.stereotype.Repository;
  4. import com.zzg.entity.TokenRelation;
  5. @Repository("tokenRelationRepository")
  6. public interface TokenRelationRepository extends JpaRepository<TokenRelation, Integer> {
  7. TokenRelation findByUsername(String username);
  8. TokenRelation findByToken(String token);
  9. }
  1. package com.zzg.dao;
  2. import org.springframework.data.jpa.repository.JpaRepository;
  3. import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
  4. import org.springframework.stereotype.Repository;
  5. import com.zzg.entity.User;
  6. /**
  7. *
  8. * @author zzg
  9. *
  10. */
  11. @Repository
  12. public interface UserRepository extends JpaRepository<User, Integer>, JpaSpecificationExecutor<User> {
  13. User findByUsername(String username);
  14. User findByUserId(Integer userId);
  15. User findByEmail(String email);
  16. User findByTelephone(String telephone);
  17. }
  1. package com.zzg.dao;
  2. import org.springframework.data.jpa.repository.JpaRepository;
  3. import org.springframework.stereotype.Repository;
  4. import com.zzg.entity.Verification;
  5. @Repository
  6. public interface VerificationRepository extends JpaRepository<Verification, Integer> {
  7. Verification findByVerificationCode(String verificationCode);
  8. }

1.2.3 controller层定义:

  1. package com.zzg.controller;
  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. import java.util.List;
  5. import java.util.Map;
  6. import java.util.Optional;
  7. import javax.persistence.criteria.CriteriaBuilder;
  8. import javax.persistence.criteria.CriteriaQuery;
  9. import javax.persistence.criteria.Predicate;
  10. import javax.persistence.criteria.Root;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.data.domain.Page;
  13. import org.springframework.data.domain.PageRequest;
  14. import org.springframework.data.jpa.domain.Specification;
  15. import org.springframework.web.bind.annotation.PathVariable;
  16. import org.springframework.web.bind.annotation.RequestBody;
  17. import org.springframework.web.bind.annotation.RequestMapping;
  18. import org.springframework.web.bind.annotation.RequestMethod;
  19. import org.springframework.web.bind.annotation.ResponseBody;
  20. import org.springframework.web.bind.annotation.RestController;
  21. import com.zzg.common.AbstractController;
  22. import com.zzg.dao.CostRepository;
  23. import com.zzg.entity.Cost;
  24. @RestController
  25. public class CostController extends AbstractController {
  26. @Autowired
  27. CostRepository costRepository;
  28. @RequestMapping(value = "/cost/save", method = RequestMethod.POST)
  29. @ResponseBody
  30. public Map insert(@RequestBody Cost cost) {
  31. costRepository.save(cost);
  32. Map<String,Object> map = new HashMap<String, Object>();
  33. map.put("code", 200);
  34. map.put("message", "新增成功");
  35. return map;
  36. }
  37. /**
  38. * 动态更新:仅限于更新单表字段和多对多表关系,产生原因:由于@Many-To-One
  39. * @param house
  40. * @return
  41. */
  42. @RequestMapping(value = "/cost/update", method = RequestMethod.POST)
  43. @ResponseBody
  44. public Map update(@RequestBody Cost cost) {
  45. Optional<Cost> old = costRepository.findById(cost.getCostId());
  46. if(old.isPresent()){
  47. Cost oldCost = old.get();
  48. //将传过来的 house 中的非NULL属性值复制到 oldHouse 中
  49. copyPropertiesIgnoreNull(cost, oldCost);
  50. //将得到的新的 oldHouse 对象重新保存到数据库,因为数据库中已经存在该记录
  51. //所以JPA会很智能的 改为更新操作,更新数据库
  52. costRepository.save(oldCost);
  53. }
  54. Map<String,Object> map = new HashMap<String, Object>();
  55. map.put("code", 200);
  56. map.put("message", "更新成功");
  57. return map;
  58. }
  59. /**
  60. * 基于原生SQL 功能实现
  61. * @param houseId
  62. * @param costId
  63. * @return
  64. */
  65. @RequestMapping(value = "/cost/houseId", method = RequestMethod.GET)
  66. @ResponseBody
  67. public Map updateHouseId(Integer houseId,Integer costId) {
  68. costRepository.modifyHouseId(houseId, costId);
  69. Map<String,Object> map = new HashMap<String, Object>();
  70. map.put("code", 200);
  71. map.put("message", "更新成功");
  72. return map;
  73. }
  74. @RequestMapping(value = "/cost/findPage", method = RequestMethod.POST)
  75. @ResponseBody
  76. public Map findPage(@RequestBody Map<String, Object> paramter) {
  77. //显示第1页每页显示3
  78. PageRequest pr = super.initPageBounds(paramter);
  79. Page<Cost> stus = costRepository.findAll(new Specification<Cost>(){
  80. @Override
  81. public Predicate toPredicate(Root<Cost> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
  82. // TODO Auto-generated method stub
  83. List<Predicate> predicateList = new ArrayList<>();
  84. return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
  85. }
  86. }, pr);
  87. Map<String, Object> map = new HashMap<String, Object>();
  88. map.put("code", 200);
  89. map.put("message", "查询成功");
  90. map.put("date", stus);
  91. return map;
  92. }
  93. @RequestMapping(value = "/cost/delete/{id}", method = RequestMethod.GET)
  94. @ResponseBody
  95. public Map delete(@PathVariable("id") Integer id) {
  96. costRepository.deleteById(id);
  97. Map<String,Object> map = new HashMap<String, Object>();
  98. map.put("code", 200);
  99. map.put("message", "删除成功");
  100. return map;
  101. }
  102. }
  1. package com.zzg.controller;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. import org.apache.shiro.authz.annotation.RequiresPermissions;
  5. import org.apache.shiro.authz.annotation.RequiresRoles;
  6. import org.springframework.web.bind.annotation.DeleteMapping;
  7. import org.springframework.web.bind.annotation.GetMapping;
  8. import org.springframework.web.bind.annotation.PostMapping;
  9. import org.springframework.web.bind.annotation.PutMapping;
  10. import org.springframework.web.bind.annotation.RequestHeader;
  11. import org.springframework.web.bind.annotation.ResponseBody;
  12. import org.springframework.web.bind.annotation.RestController;
  13. @RestController
  14. public class DataController {
  15. @RequiresPermissions({"save"}) //没有的话 AuthorizationException
  16. @PostMapping("/data/save")
  17. @ResponseBody
  18. public Map<String, Object> save(@RequestHeader("token")String token) {
  19. System.out.println("save");
  20. Map<String, Object> map = new HashMap<String, Object>();
  21. map.put("status", 200);
  22. map.put("msg", "当前用户有save的权力");
  23. return map;
  24. }//f603cd4348b8f1d41226e3f555d392bd
  25. @RequiresPermissions({"delete"}) //没有的话 AuthorizationException
  26. @DeleteMapping("/data/delete")
  27. @ResponseBody
  28. public Map<String, Object> delete(@RequestHeader("token")String token) {
  29. System.out.println("delete");
  30. Map<String, Object> map = new HashMap<String, Object>();
  31. map.put("status", 200);
  32. map.put("msg", "当前用户有delete的权力");
  33. return map;
  34. }
  35. @RequiresPermissions({"update"}) //没有的话 AuthorizationException
  36. @PutMapping("/data/update")
  37. @ResponseBody
  38. public Map<String, Object> update(@RequestHeader("token")String token) {
  39. System.out.println("update");
  40. Map<String, Object> map = new HashMap<String, Object>();
  41. map.put("status", 200);
  42. map.put("msg", "当前用户有update的权力");
  43. return map;
  44. }
  45. @RequiresPermissions({"select"}) //没有的话 AuthorizationException
  46. @GetMapping("/data/select")
  47. @ResponseBody
  48. public Map<String, Object> select(@RequestHeader("token")String token) {
  49. System.out.println("select");
  50. Map<String, Object> map = new HashMap<String, Object>();
  51. map.put("status", 200);
  52. map.put("msg", "当前用户有select的权力");
  53. return map;
  54. }
  55. @RequiresRoles({"vip"}) //没有的话 AuthorizationException
  56. @GetMapping("/data/vip")
  57. @ResponseBody
  58. public Map<String, Object> vip(@RequestHeader("token")String token) {
  59. System.out.println("vip");
  60. Map<String, Object> map = new HashMap<String, Object>();
  61. map.put("status", 200);
  62. map.put("msg", "当前用户有VIP角色");
  63. return map;
  64. }
  65. @RequiresRoles({"svip"}) //没有的话 AuthorizationException
  66. @GetMapping("/data/svip")
  67. @ResponseBody
  68. public Map<String, Object> svip(@RequestHeader("token")String token) {
  69. System.out.println("svip");
  70. Map<String, Object> map = new HashMap<String, Object>();
  71. map.put("status", 200);
  72. map.put("msg", "当前用户有SVIP角色");
  73. return map;
  74. }
  75. @RequiresRoles({"p"}) //没有的话 AuthorizationException
  76. @GetMapping("/data/p")
  77. @ResponseBody
  78. public Map<String, Object> p(@RequestHeader("token")String token) {
  79. System.out.println("p");
  80. Map<String, Object> map = new HashMap<String, Object>();
  81. map.put("status", 200);
  82. map.put("msg", "当前用户有P角色");
  83. return map;
  84. }
  85. }
  1. package com.zzg.controller;
  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. import java.util.List;
  5. import java.util.Map;
  6. import java.util.Optional;
  7. import javax.persistence.criteria.CriteriaBuilder;
  8. import javax.persistence.criteria.CriteriaQuery;
  9. import javax.persistence.criteria.Predicate;
  10. import javax.persistence.criteria.Root;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.data.domain.Page;
  13. import org.springframework.data.domain.PageRequest;
  14. import org.springframework.data.jpa.domain.Specification;
  15. import org.springframework.web.bind.annotation.PathVariable;
  16. import org.springframework.web.bind.annotation.RequestBody;
  17. import org.springframework.web.bind.annotation.RequestMapping;
  18. import org.springframework.web.bind.annotation.RequestMethod;
  19. import org.springframework.web.bind.annotation.ResponseBody;
  20. import org.springframework.web.bind.annotation.RestController;
  21. import com.zzg.common.AbstractController;
  22. import com.zzg.dao.HouseRepository;
  23. import com.zzg.entity.House;
  24. @RestController
  25. public class HouseController extends AbstractController{
  26. @Autowired
  27. HouseRepository houseRepository;
  28. @RequestMapping(value = "/house/save", method = RequestMethod.POST)
  29. @ResponseBody
  30. public Map insert(@RequestBody House house) {
  31. houseRepository.save(house);
  32. Map<String,Object> map = new HashMap<String, Object>();
  33. map.put("code", 200);
  34. map.put("message", "新增成功");
  35. return map;
  36. }
  37. /**
  38. * 动态更新:仅限于更新单表字段和多对多表关系,产生原因:由于@Many-To-One
  39. * @param house
  40. * @return
  41. */
  42. @RequestMapping(value = "/house/update", method = RequestMethod.POST)
  43. @ResponseBody
  44. public Map update(@RequestBody House house) {
  45. Optional<House> old = houseRepository.findById(house.getHouseId());
  46. if(old.isPresent()){
  47. House oldHouse = old.get();
  48. //将传过来的 house 中的非NULL属性值复制到 oldHouse 中
  49. copyPropertiesIgnoreNull(house, oldHouse);
  50. //将得到的新的 oldHouse 对象重新保存到数据库,因为数据库中已经存在该记录
  51. //所以JPA会很智能的 改为更新操作,更新数据库
  52. houseRepository.save(oldHouse);
  53. }
  54. Map<String,Object> map = new HashMap<String, Object>();
  55. map.put("code", 200);
  56. map.put("message", "更新成功");
  57. return map;
  58. }
  59. /**
  60. * 基于原生SQL 功能实现
  61. * @param houseId
  62. * @param costId
  63. * @return
  64. */
  65. @RequestMapping(value = "/house/userId", method = RequestMethod.GET)
  66. @ResponseBody
  67. public Map updateUserId(Integer userId,Integer houseId) {
  68. houseRepository.modifyUserId(userId, houseId);
  69. Map<String,Object> map = new HashMap<String, Object>();
  70. map.put("code", 200);
  71. map.put("message", "更新成功");
  72. return map;
  73. }
  74. @RequestMapping(value = "/house/findPage", method = RequestMethod.POST)
  75. @ResponseBody
  76. public Map findPage(@RequestBody Map<String, Object> paramter) {
  77. //显示第1页每页显示3
  78. PageRequest pr = super.initPageBounds(paramter);
  79. Page<House> stus = houseRepository.findAll(new Specification<House>(){
  80. @Override
  81. public Predicate toPredicate(Root<House> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
  82. // TODO Auto-generated method stub
  83. List<Predicate> predicateList = new ArrayList<>();
  84. if(paramter.get("houseId") != null){
  85. predicateList.add(criteriaBuilder.equal(root.get("houseId"), paramter.get("houseId")));
  86. }
  87. if(paramter.get("houseNumber") != null){
  88. predicateList.add(criteriaBuilder.equal(root.get("houseNumber"), paramter.get("houseNumber")));
  89. }
  90. if(paramter.get("area") != null){
  91. predicateList.add(criteriaBuilder.like(root.get("area"), "%" + paramter.get("area") +"%"));
  92. }
  93. return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
  94. }
  95. }, pr);
  96. Map<String, Object> map = new HashMap<String, Object>();
  97. map.put("code", 200);
  98. map.put("message", "查询成功");
  99. map.put("date", stus);
  100. return map;
  101. }
  102. @RequestMapping(value = "/house/delete/{id}", method = RequestMethod.GET)
  103. @ResponseBody
  104. public Map delete(@PathVariable("id") Integer id) {
  105. houseRepository.deleteById(id);
  106. Map<String,Object> map = new HashMap<String, Object>();
  107. map.put("code", 200);
  108. map.put("message", "删除成功");
  109. return map;
  110. }
  111. }
  1. package com.zzg.controller;
  2. import java.awt.image.BufferedImage;
  3. import java.io.ByteArrayOutputStream;
  4. import javax.imageio.ImageIO;
  5. import javax.servlet.ServletOutputStream;
  6. import javax.servlet.http.HttpServletRequest;
  7. import javax.servlet.http.HttpServletResponse;
  8. import org.springframework.web.bind.annotation.GetMapping;
  9. import org.springframework.web.bind.annotation.RestController;
  10. import com.google.code.kaptcha.impl.DefaultKaptcha;
  11. import com.zzg.redis.RedisUtils;
  12. import com.zzg.util.KaptchaUtil;
  13. @RestController
  14. public class KaptchaController {
  15. public static final String VRIFY_CODE = "VRIFYCODE";
  16. @GetMapping("/sys/kaptcha")
  17. public void defaultKaptcha(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
  18. throws Exception {
  19. byte[] captchaChallengeAsJpeg = null;
  20. ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
  21. try {
  22. // 代码方式创建:DefaultKaptcha
  23. KaptchaUtil single = KaptchaUtil.getInstance();
  24. DefaultKaptcha defaultKaptcha = single.produce();
  25. // 生产验证码字符串并保存到session中
  26. String createText = defaultKaptcha.createText();
  27. // 基于session 方式
  28. //httpServletRequest.getSession().setAttribute(VRIFY_CODE, createText);
  29. // 基于redis 方式
  30. RedisUtils.hPut(VRIFY_CODE, createText, createText);
  31. // 使用生产的验证码字符串返回一个BufferedImage对象并转为byte写入到byte数组中
  32. BufferedImage challenge = defaultKaptcha.createImage(createText);
  33. ImageIO.write(challenge, "jpg", jpegOutputStream);
  34. } catch (IllegalArgumentException e) {
  35. httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
  36. return;
  37. }
  38. // 定义response输出类型为image/jpeg类型,使用response输出流输出图片的byte数组
  39. captchaChallengeAsJpeg = jpegOutputStream.toByteArray();
  40. httpServletResponse.setHeader("Cache-Control", "no-store");
  41. httpServletResponse.setHeader("Pragma", "no-cache");
  42. httpServletResponse.setDateHeader("Expires", 0);
  43. httpServletResponse.setContentType("image/jpeg");
  44. ServletOutputStream responseOutputStream = httpServletResponse.getOutputStream();
  45. responseOutputStream.write(captchaChallengeAsJpeg);
  46. responseOutputStream.flush();
  47. responseOutputStream.close();
  48. }
  49. }
  1. package com.zzg.controller;
  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. import java.util.List;
  5. import java.util.Map;
  6. import java.util.Optional;
  7. import javax.persistence.criteria.CriteriaBuilder;
  8. import javax.persistence.criteria.CriteriaQuery;
  9. import javax.persistence.criteria.Predicate;
  10. import javax.persistence.criteria.Root;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.data.domain.Page;
  13. import org.springframework.data.domain.PageRequest;
  14. import org.springframework.data.jpa.domain.Specification;
  15. import org.springframework.web.bind.annotation.PathVariable;
  16. import org.springframework.web.bind.annotation.RequestBody;
  17. import org.springframework.web.bind.annotation.RequestMapping;
  18. import org.springframework.web.bind.annotation.RequestMethod;
  19. import org.springframework.web.bind.annotation.ResponseBody;
  20. import org.springframework.web.bind.annotation.RestController;
  21. import com.zzg.common.AbstractController;
  22. import com.zzg.dao.LeaseRepository;
  23. import com.zzg.entity.Lease;
  24. @RestController
  25. public class LeaseController extends AbstractController {
  26. @Autowired
  27. private LeaseRepository leaseRepository;
  28. @RequestMapping(value = "/lease/save", method = RequestMethod.POST)
  29. @ResponseBody
  30. public Map insert(@RequestBody Lease lease) {
  31. leaseRepository.save(lease);
  32. Map<String,Object> map = new HashMap<String, Object>();
  33. map.put("code", 200);
  34. map.put("message", "新增成功");
  35. return map;
  36. }
  37. /**
  38. * 动态更新:仅限于更新单表字段和和多对多表关系
  39. * @param house
  40. * @return
  41. */
  42. @RequestMapping(value = "/lease/update", method = RequestMethod.POST)
  43. @ResponseBody
  44. public Map update(@RequestBody Lease lease) {
  45. Optional<Lease> old = leaseRepository.findById(lease.getLeaseId());
  46. if(old.isPresent()){
  47. Lease oldLease = old.get();
  48. //将传过来的 house 中的非NULL属性值复制到 oldHouse 中
  49. copyPropertiesIgnoreNull(lease, oldLease);
  50. //将得到的新的 oldHouse 对象重新保存到数据库,因为数据库中已经存在该记录
  51. //所以JPA会很智能的 改为更新操作,更新数据库
  52. leaseRepository.save(oldLease);
  53. }
  54. Map<String,Object> map = new HashMap<String, Object>();
  55. map.put("code", 200);
  56. map.put("message", "更新成功");
  57. return map;
  58. }
  59. @RequestMapping(value = "/lease/findPage", method = RequestMethod.POST)
  60. @ResponseBody
  61. public Map findPage(@RequestBody Map<String, Object> paramter) {
  62. //显示第1页每页显示3
  63. PageRequest pr = super.initPageBounds(paramter);
  64. Page<Lease> stus = leaseRepository.findAll(new Specification<Lease>(){
  65. @Override
  66. public Predicate toPredicate(Root<Lease> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
  67. // TODO Auto-generated method stub
  68. List<Predicate> predicateList = new ArrayList<>();
  69. return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
  70. }
  71. }, pr);
  72. Map<String, Object> map = new HashMap<String, Object>();
  73. map.put("code", 200);
  74. map.put("message", "查询成功");
  75. map.put("date", stus);
  76. return map;
  77. }
  78. @RequestMapping(value = "/lease/delete/{id}", method = RequestMethod.GET)
  79. @ResponseBody
  80. public Map delete(@PathVariable("id") Integer id) {
  81. leaseRepository.deleteById(id);
  82. Map<String,Object> map = new HashMap<String, Object>();
  83. map.put("code", 200);
  84. map.put("message", "删除成功");
  85. return map;
  86. }
  87. }
  1. package com.zzg.controller;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.web.bind.annotation.CrossOrigin;
  6. import org.springframework.web.bind.annotation.PostMapping;
  7. import org.springframework.web.bind.annotation.RequestBody;
  8. import org.springframework.web.bind.annotation.RequestHeader;
  9. import org.springframework.web.bind.annotation.RequestParam;
  10. import org.springframework.web.bind.annotation.ResponseBody;
  11. import org.springframework.web.bind.annotation.RestController;
  12. import com.alibaba.druid.util.StringUtils;
  13. import com.zzg.dao.TokenRelationRepository;
  14. import com.zzg.dao.UserRepository;
  15. import com.zzg.dao.VerificationRepository;
  16. import com.zzg.entity.TokenRelation;
  17. import com.zzg.entity.User;
  18. import com.zzg.entity.Verification;
  19. import com.zzg.redis.RedisUtils;
  20. import com.zzg.util.JWTUtil;
  21. @RestController
  22. public class LoginController {
  23. public static final String VRIFY_CODE = "VRIFYCODE";
  24. // 过期时间 24 小时
  25. private static final long EXPIRE_TIME = 60 * 24 * 60 * 1000;
  26. @Autowired
  27. UserRepository userRepository;
  28. @Autowired
  29. TokenRelationRepository tokenRelationRepository;
  30. @Autowired
  31. VerificationRepository verificationRepository;
  32. /**
  33. * 登录
  34. */
  35. @CrossOrigin
  36. @PostMapping("/common/login")
  37. @ResponseBody
  38. public Map<String, Object> commonLogin(@RequestBody Map<String, Object> parame) {
  39. Map<String, Object> result = new HashMap<>();
  40. String username = (String) parame.get("username");
  41. String password = (String) parame.get("password");
  42. //用户信息
  43. User user = userRepository.findByUsername(username);
  44. //账号不存在、密码错误
  45. if (user == null || !user.getPassword().equals(password)) {
  46. result.put("status", 400);
  47. result.put("msg", "账号或密码有误");
  48. } else {
  49. //生成token,并保存到redis
  50. String token = JWTUtil.createToken(username);
  51. RedisUtils.set(username,token);
  52. RedisUtils.expire(username, EXPIRE_TIME);
  53. // user->token 关系保存到mysql 中
  54. TokenRelation relation = tokenRelationRepository.findByUsername(username);
  55. if(relation == null){
  56. relation = new TokenRelation();
  57. relation.setUsername(username);
  58. relation.setToken(token);
  59. } else {
  60. relation.setToken(token);
  61. }
  62. tokenRelationRepository.save(relation);
  63. result.put("uid", user.getUserId());
  64. result.put("username", username);
  65. result.put("token", token);
  66. result.put("status", 200);
  67. result.put("msg", "登陆成功");
  68. }
  69. return result;
  70. }
  71. /**
  72. * 登录
  73. */
  74. @PostMapping("/sys/login")
  75. @ResponseBody
  76. public Map<String, Object> login(@RequestParam("username")String username, @RequestParam("password")String password, @RequestParam("captcha")String captcha) {
  77. Map<String, Object> result = new HashMap<>();
  78. //校验验证码
  79. //基于session的验证码
  80. // String sessionCaptcha = (String) SecurityUtils.getSubject().getSession().getAttribute(VRIFY_CODE);
  81. //基于redis的验证码
  82. String redisCaptcha = (String) RedisUtils.hGet(VRIFY_CODE, captcha);
  83. if (StringUtils.isEmpty(redisCaptcha)) {
  84. result.put("status", 400);
  85. result.put("msg", "验证码有误");
  86. return result;
  87. }
  88. //用户信息
  89. User user = userRepository.findByUsername(username);
  90. //账号不存在、密码错误
  91. if (user == null || !user.getPassword().equals(password)) {
  92. result.put("status", 400);
  93. result.put("msg", "账号或密码有误");
  94. } else {
  95. //生成token,并保存到redis
  96. String token = JWTUtil.createToken(username);
  97. RedisUtils.set(username,token);
  98. RedisUtils.expire(username, EXPIRE_TIME);
  99. // user->token 关系保存到mysql 中
  100. TokenRelation relation = tokenRelationRepository.findByUsername(username);
  101. if(relation == null){
  102. relation = new TokenRelation();
  103. relation.setUsername(username);
  104. relation.setToken(token);
  105. } else {
  106. relation.setToken(token);
  107. }
  108. tokenRelationRepository.save(relation);
  109. result.put("token", token);
  110. result.put("status", 200);
  111. result.put("msg", "登陆成功");
  112. // 移除验证码
  113. RedisUtils.hDelete(VRIFY_CODE, captcha);
  114. }
  115. return result;
  116. }
  117. public boolean validateCode(String code){
  118. Verification verification = verificationRepository.findByVerificationCode(code);
  119. if(verification != null){
  120. }
  121. return false;
  122. }
  123. /**
  124. * 邮箱登录
  125. */
  126. @PostMapping("/email/login")
  127. @ResponseBody
  128. public Map<String, Object> emailLogin(@RequestParam("email")String email, @RequestParam("code")String code) {
  129. Map<String, Object> result = new HashMap<>();
  130. //用户信息
  131. User user = userRepository.findByEmail(email);
  132. Verification verification = verificationRepository.findByVerificationCode(code);
  133. //账号不存在、验证码错误
  134. if (user == null || verification == null) {
  135. result.put("status", 400);
  136. result.put("msg", "邮箱有误");
  137. } else {
  138. //生成token,并保存到redis
  139. String token = JWTUtil.createToken(user.getUsername());
  140. RedisUtils.set(user.getUsername(),token);
  141. RedisUtils.expire(user.getUsername(), EXPIRE_TIME);
  142. // user->token 关系保存到mysql 中
  143. TokenRelation relation = tokenRelationRepository.findByUsername(user.getUsername());
  144. if(relation == null){
  145. relation = new TokenRelation();
  146. relation.setUsername(user.getUsername());
  147. relation.setToken(token);
  148. } else {
  149. relation.setToken(token);
  150. }
  151. tokenRelationRepository.save(relation);
  152. result.put("token", token);
  153. result.put("status", 200);
  154. result.put("msg", "登陆成功");
  155. // 验证码移除
  156. verificationRepository.deleteById(verification.getVerificationId());
  157. }
  158. return result;
  159. }
  160. /**
  161. * 邮箱登录
  162. */
  163. @PostMapping("/phone/login")
  164. @ResponseBody
  165. public Map<String, Object> phoneLogin(@RequestParam("phone")String phone, @RequestParam("code")String code) {
  166. Map<String, Object> result = new HashMap<>();
  167. //用户信息
  168. User user = userRepository.findByTelephone(phone);
  169. Verification verification = verificationRepository.findByVerificationCode(code);
  170. //账号不存在、验证码错误
  171. if (user == null || verification == null) {
  172. result.put("status", 400);
  173. result.put("msg", "手机号码有误");
  174. } else {
  175. //生成token,并保存到redis
  176. String token = JWTUtil.createToken(user.getUsername());
  177. RedisUtils.set(user.getUsername(),token);
  178. RedisUtils.expire(user.getUsername(), EXPIRE_TIME);
  179. // user->token 关系保存到mysql 中
  180. TokenRelation relation = tokenRelationRepository.findByUsername(user.getUsername());
  181. if(relation == null){
  182. relation = new TokenRelation();
  183. relation.setUsername(user.getUsername());
  184. relation.setToken(token);
  185. } else {
  186. relation.setToken(token);
  187. }
  188. tokenRelationRepository.save(relation);
  189. result.put("token", token);
  190. result.put("status", 200);
  191. result.put("msg", "登陆成功");
  192. // 验证码移除
  193. verificationRepository.deleteById(verification.getVerificationId());
  194. }
  195. return result;
  196. }
  197. /**
  198. * 退出
  199. */
  200. @PostMapping("/sys/logout")
  201. public Map<String, Object> logout(@RequestHeader("token")String token) {
  202. Map<String, Object> result = new HashMap<>();
  203. String username = null;
  204. TokenRelation relation = tokenRelationRepository.findByToken(token);
  205. if(relation != null){
  206. username = relation.getUsername();
  207. tokenRelationRepository.deleteById(relation.getRelationSid());
  208. }
  209. if(!StringUtils.isEmpty(username)){
  210. // redis 移除token
  211. RedisUtils.del(username);
  212. }
  213. result.put("status", 200);
  214. result.put("msg", "您已安全退出系统");
  215. return result;
  216. }
  217. }
  1. package com.zzg.controller;
  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. import java.util.Iterator;
  5. import java.util.List;
  6. import java.util.Map;
  7. import java.util.Optional;
  8. import javax.persistence.criteria.CriteriaBuilder;
  9. import javax.persistence.criteria.CriteriaQuery;
  10. import javax.persistence.criteria.Predicate;
  11. import javax.persistence.criteria.Root;
  12. import org.apache.shiro.util.CollectionUtils;
  13. import org.springframework.beans.BeanUtils;
  14. import org.springframework.beans.factory.annotation.Autowired;
  15. import org.springframework.data.domain.Page;
  16. import org.springframework.data.domain.PageRequest;
  17. import org.springframework.data.jpa.domain.Specification;
  18. import org.springframework.web.bind.annotation.PathVariable;
  19. import org.springframework.web.bind.annotation.RequestBody;
  20. import org.springframework.web.bind.annotation.RequestMapping;
  21. import org.springframework.web.bind.annotation.RequestMethod;
  22. import org.springframework.web.bind.annotation.RequestParam;
  23. import org.springframework.web.bind.annotation.ResponseBody;
  24. import org.springframework.web.bind.annotation.RestController;
  25. import com.zzg.common.AbstractController;
  26. import com.zzg.dao.PermissionRepository;
  27. import com.zzg.dao.RoleRepository;
  28. import com.zzg.dao.UserRepository;
  29. import com.zzg.entity.Permission;
  30. import com.zzg.entity.Role;
  31. import com.zzg.entity.User;
  32. import com.zzg.vo.PermissionVo;
  33. @RestController
  34. public class PermissionController extends AbstractController{
  35. @Autowired
  36. private PermissionRepository permissionRepository;
  37. @Autowired
  38. private UserRepository userRepository;
  39. @Autowired
  40. private RoleRepository roleRepository;
  41. @RequestMapping(value = "/permission/save", method = RequestMethod.POST)
  42. @ResponseBody
  43. public Map insert(@RequestBody Permission permission) {
  44. permissionRepository.save(permission);
  45. Map<String,Object> map = new HashMap<String, Object>();
  46. map.put("code", 200);
  47. map.put("message", "新增成功");
  48. return map;
  49. }
  50. /**
  51. * 动态更新:仅限于更新单表字段
  52. * @param house
  53. * @return
  54. */
  55. @RequestMapping(value = "/permission/update", method = RequestMethod.POST)
  56. @ResponseBody
  57. public Map update(@RequestBody Permission permission) {
  58. Optional<Permission> old = permissionRepository.findById(permission.getPermissionId());
  59. if(old.isPresent()){
  60. Permission oldPermission = old.get();
  61. //将传过来的 house 中的非NULL属性值复制到 oldHouse 中
  62. copyPropertiesIgnoreNull(permission, oldPermission);
  63. //将得到的新的 oldHouse 对象重新保存到数据库,因为数据库中已经存在该记录
  64. //所以JPA会很智能的 改为更新操作,更新数据库
  65. permissionRepository.save(oldPermission);
  66. }
  67. Map<String,Object> map = new HashMap<String, Object>();
  68. map.put("code", 200);
  69. map.put("message", "更新成功");
  70. return map;
  71. }
  72. @RequestMapping(value = "/permission/findPage", method = RequestMethod.POST)
  73. @ResponseBody
  74. public Map findPage(@RequestBody Map<String, Object> paramter) {
  75. //显示第1页每页显示3
  76. PageRequest pr = super.initPageBounds(paramter);
  77. Page<Permission> stus = permissionRepository.findAll(new Specification<Permission>(){
  78. @Override
  79. public Predicate toPredicate(Root<Permission> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
  80. // TODO Auto-generated method stub
  81. List<Predicate> predicateList = new ArrayList<>();
  82. return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
  83. }
  84. }, pr);
  85. Map<String, Object> map = new HashMap<String, Object>();
  86. map.put("code", 200);
  87. map.put("message", "查询成功");
  88. map.put("date", stus);
  89. return map;
  90. }
  91. /**
  92. * 查询用户指定权限
  93. * @param uid
  94. * @return
  95. */
  96. @RequestMapping(value = "/permission/{uid}", method = RequestMethod.GET)
  97. @ResponseBody
  98. public Map findPermission(@PathVariable Integer uid) {
  99. List<PermissionVo> permissionsVos = new ArrayList<PermissionVo>();
  100. List<Permission> permissions = new ArrayList<Permission>();
  101. //显示第1页每页显示3
  102. User user = userRepository.findByUserId(uid);
  103. user.getRoles().stream().forEach(item->{
  104. Role role = roleRepository.findByRoleId(item.getRoleId());
  105. if(!CollectionUtils.isEmpty(role.getPermissions())){
  106. for(Permission permission : role.getPermissions()){
  107. if(permission.getPermisionParentId() == null){
  108. permissions.add(permission);
  109. }
  110. }
  111. }
  112. });
  113. permissions.stream().forEach(item ->{
  114. /**
  115. * Spring Data JPA 动态查询条件
  116. */
  117. Specification<Permission> specification = new Specification<Permission>() {
  118. @Override
  119. public Predicate toPredicate(Root<Permission> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
  120. List<Predicate> predicates = new ArrayList<Predicate>();
  121. if(null != item.getPermissionId()) {
  122. predicates.add(cb.equal(root.<Integer>get("permisionParentId"), item.getPermissionId()));
  123. }
  124. return cq.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
  125. }
  126. };
  127. List<Permission> childPermission = permissionRepository.findAll(specification);
  128. List<PermissionVo> childPermissionVO = new ArrayList<PermissionVo>();
  129. for(Permission permission : childPermission){
  130. PermissionVo vo = new PermissionVo();
  131. BeanUtils.copyProperties(permission, vo);
  132. childPermissionVO.add(vo);
  133. }
  134. PermissionVo vo = new PermissionVo();
  135. BeanUtils.copyProperties(item, vo);
  136. vo.setChild(childPermissionVO);
  137. permissionsVos.add(vo);
  138. });
  139. // 数据清理
  140. // Iterator<Permission> iterator = permissions.iterator();
  141. // while(iterator.hasNext()){
  142. // Permission permission = iterator.next();
  143. // if(permission.getPermisionParentId() != null){
  144. // iterator.remove();
  145. // }
  146. // }
  147. // for(Permission permission : permissions){
  148. // if(permission.getParent() != null){
  149. // permissions.remove(permission);
  150. // }
  151. // }
  152. Map<String, Object> map = new HashMap<String, Object>();
  153. map.put("code", 200);
  154. map.put("message", "查询成功");
  155. map.put("date", permissionsVos);
  156. return map;
  157. }
  158. @RequestMapping(value = "/permission/delete/{id}", method = RequestMethod.GET)
  159. @ResponseBody
  160. public Map delete(@PathVariable("id") Integer id) {
  161. permissionRepository.deleteById(id);
  162. Map<String,Object> map = new HashMap<String, Object>();
  163. map.put("code", 200);
  164. map.put("message", "删除成功");
  165. return map;
  166. }
  167. }
  1. package com.zzg.controller;
  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. import java.util.List;
  5. import java.util.Map;
  6. import java.util.Optional;
  7. import javax.persistence.criteria.CriteriaBuilder;
  8. import javax.persistence.criteria.CriteriaQuery;
  9. import javax.persistence.criteria.Predicate;
  10. import javax.persistence.criteria.Root;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.data.domain.Page;
  13. import org.springframework.data.domain.PageRequest;
  14. import org.springframework.data.jpa.domain.Specification;
  15. import org.springframework.web.bind.annotation.PathVariable;
  16. import org.springframework.web.bind.annotation.RequestBody;
  17. import org.springframework.web.bind.annotation.RequestMapping;
  18. import org.springframework.web.bind.annotation.RequestMethod;
  19. import org.springframework.web.bind.annotation.ResponseBody;
  20. import org.springframework.web.bind.annotation.RestController;
  21. import com.zzg.common.AbstractController;
  22. import com.zzg.dao.RoleRepository;
  23. import com.zzg.entity.Role;
  24. @RestController
  25. public class RoleController extends AbstractController {
  26. @Autowired
  27. private RoleRepository roleRepository;
  28. @RequestMapping(value = "/role/save", method = RequestMethod.POST)
  29. @ResponseBody
  30. public Map insert(@RequestBody Role role) {
  31. roleRepository.save(role);
  32. Map<String,Object> map = new HashMap<String, Object>();
  33. map.put("code", 200);
  34. map.put("message", "新增成功");
  35. return map;
  36. }
  37. /**
  38. * 动态更新:仅限于更新单表字段
  39. * @param house
  40. * @return
  41. */
  42. @RequestMapping(value = "/role/update", method = RequestMethod.POST)
  43. @ResponseBody
  44. public Map update(@RequestBody Role role) {
  45. Optional<Role> old = roleRepository.findById(role.getRoleId());
  46. if(old.isPresent()){
  47. Role oldRole = old.get();
  48. //将传过来的 house 中的非NULL属性值复制到 oldHouse 中
  49. copyPropertiesIgnoreNull(role, oldRole);
  50. //将得到的新的 oldHouse 对象重新保存到数据库,因为数据库中已经存在该记录
  51. //所以JPA会很智能的 改为更新操作,更新数据库
  52. roleRepository.save(oldRole);
  53. }
  54. Map<String,Object> map = new HashMap<String, Object>();
  55. map.put("code", 200);
  56. map.put("message", "更新成功");
  57. return map;
  58. }
  59. @RequestMapping(value = "/role/findPage", method = RequestMethod.POST)
  60. @ResponseBody
  61. public Map findPage(@RequestBody Map<String, Object> paramter) {
  62. //显示第1页每页显示3
  63. PageRequest pr = super.initPageBounds(paramter);
  64. Page<Role> stus = roleRepository.findAll(new Specification<Role>(){
  65. @Override
  66. public Predicate toPredicate(Root<Role> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
  67. // TODO Auto-generated method stub
  68. List<Predicate> predicateList = new ArrayList<>();
  69. return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
  70. }
  71. }, pr);
  72. Map<String, Object> map = new HashMap<String, Object>();
  73. map.put("code", 200);
  74. map.put("message", "查询成功");
  75. map.put("date", stus);
  76. return map;
  77. }
  78. @RequestMapping(value = "/role/delete/{id}", method = RequestMethod.GET)
  79. @ResponseBody
  80. public Map delete(@PathVariable("id") Integer id) {
  81. roleRepository.deleteById(id);
  82. Map<String,Object> map = new HashMap<String, Object>();
  83. map.put("code", 200);
  84. map.put("message", "删除成功");
  85. return map;
  86. }
  87. }
  1. package com.zzg.controller;
  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. import java.util.List;
  5. import java.util.Map;
  6. import java.util.Optional;
  7. import javax.persistence.criteria.CriteriaBuilder;
  8. import javax.persistence.criteria.CriteriaQuery;
  9. import javax.persistence.criteria.Predicate;
  10. import javax.persistence.criteria.Root;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.data.domain.Page;
  13. import org.springframework.data.domain.PageRequest;
  14. import org.springframework.data.jpa.domain.Specification;
  15. import org.springframework.web.bind.annotation.PathVariable;
  16. import org.springframework.web.bind.annotation.RequestBody;
  17. import org.springframework.web.bind.annotation.RequestMapping;
  18. import org.springframework.web.bind.annotation.RequestMethod;
  19. import org.springframework.web.bind.annotation.ResponseBody;
  20. import org.springframework.web.bind.annotation.RestController;
  21. import com.zzg.common.AbstractController;
  22. import com.zzg.dao.UserRepository;
  23. import com.zzg.entity.User;
  24. @RestController
  25. public class UserController extends AbstractController {
  26. @Autowired
  27. private UserRepository userRepository;
  28. @RequestMapping(value = "/user/save", method = RequestMethod.POST)
  29. @ResponseBody
  30. public Map insert(@RequestBody User user) {
  31. userRepository.save(user);
  32. Map<String,Object> map = new HashMap<String, Object>();
  33. map.put("code", 200);
  34. map.put("message", "新增成功");
  35. return map;
  36. }
  37. /**
  38. * 动态更新:仅限于更新单表字段
  39. * @param house
  40. * @return
  41. */
  42. @RequestMapping(value = "/user/update", method = RequestMethod.POST)
  43. @ResponseBody
  44. public Map update(@RequestBody User user) {
  45. Optional<User> old = userRepository.findById(user.getUserId());
  46. if(old.isPresent()){
  47. User oldUser = old.get();
  48. //将传过来的 house 中的非NULL属性值复制到 oldHouse 中
  49. copyPropertiesIgnoreNull(user, oldUser);
  50. //将得到的新的 oldHouse 对象重新保存到数据库,因为数据库中已经存在该记录
  51. //所以JPA会很智能的 改为更新操作,更新数据库
  52. userRepository.save(oldUser);
  53. }
  54. Map<String,Object> map = new HashMap<String, Object>();
  55. map.put("code", 200);
  56. map.put("message", "更新成功");
  57. return map;
  58. }
  59. @RequestMapping(value = "/user/findPage", method = RequestMethod.POST)
  60. @ResponseBody
  61. public Map findPage(@RequestBody Map<String, Object> paramter) {
  62. //显示第1页每页显示3
  63. PageRequest pr = super.initPageBounds(paramter);
  64. Page<User> stus = userRepository.findAll(new Specification<User>(){
  65. @Override
  66. public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
  67. // TODO Auto-generated method stub
  68. List<Predicate> predicateList = new ArrayList<>();
  69. return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
  70. }
  71. }, pr);
  72. Map<String, Object> map = new HashMap<String, Object>();
  73. map.put("code", 200);
  74. map.put("message", "查询成功");
  75. map.put("date", stus);
  76. return map;
  77. }
  78. @RequestMapping(value = "/user/delete/{id}", method = RequestMethod.GET)
  79. @ResponseBody
  80. public Map delete(@PathVariable("id") Integer id) {
  81. userRepository.deleteById(id);
  82. Map<String,Object> map = new HashMap<String, Object>();
  83. map.put("code", 200);
  84. map.put("message", "删除成功");
  85. return map;
  86. }
  87. }
  1. package com.zzg.controller;
  2. import java.util.Calendar;
  3. import java.util.Date;
  4. import java.util.HashMap;
  5. import java.util.Map;
  6. import javax.servlet.http.HttpServletRequest;
  7. import javax.servlet.http.HttpServletResponse;
  8. import org.springframework.beans.factory.annotation.Autowired;
  9. import org.springframework.web.bind.annotation.GetMapping;
  10. import org.springframework.web.bind.annotation.RestController;
  11. import com.fasterxml.jackson.databind.ObjectMapper;
  12. import com.zzg.dao.VerificationRepository;
  13. import com.zzg.entity.Verification;
  14. import com.zzg.util.HttpContextUtil;
  15. @RestController
  16. public class VerificationController {
  17. // 定义jackson对象
  18. private static final ObjectMapper MAPPER = new ObjectMapper();
  19. @Autowired
  20. VerificationRepository verificationRepository;
  21. public Verification getVerification(String code){
  22. Date date = new Date();
  23. Verification verification = new Verification();
  24. verification.setCreateDate(date);
  25. Calendar calendar = Calendar.getInstance();
  26. calendar.setTime(date);
  27. calendar.set(Calendar.MINUTE, calendar.get(Calendar.MINUTE) + 15);//分钟+15
  28. verification.setFailDate(calendar.getTime());
  29. verification.setStatus(1);
  30. verification.setVerificationCode(code);
  31. return verification;
  32. }
  33. @GetMapping("/sys/verification")
  34. public void defaultVerification(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
  35. throws Exception {
  36. Verification verification = this.getVerification("123456");
  37. verificationRepository.save(verification);
  38. httpServletResponse.setContentType("application/json;charset=utf-8");
  39. httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
  40. httpServletResponse.setHeader("Access-Control-Allow-Origin", HttpContextUtil.getOrigin());
  41. httpServletResponse.setCharacterEncoding("UTF-8");
  42. //设置编码,否则中文字符在重定向时会变为空字符串
  43. Map<String, Object> result = new HashMap<>();
  44. result.put("status", 200);
  45. result.put("code", verification.getVerificationCode());
  46. result.put("msg", "验证码发送成功");
  47. String json = MAPPER.writeValueAsString(result);
  48. httpServletResponse.getWriter().print(json);
  49. }
  50. }

1.2.4 通用定义:

  1. package com.zzg.common.constant;
  2. public class WebAppConstants {
  3. public static final String LIMIT = "limit";
  4. public static final String PAGE = "page";
  5. }
  1. package com.zzg.common;
  2. import java.util.HashSet;
  3. import java.util.Map;
  4. import java.util.Set;
  5. import org.springframework.beans.BeanUtils;
  6. import org.springframework.beans.BeanWrapper;
  7. import org.springframework.beans.BeanWrapperImpl;
  8. import org.springframework.beans.SimpleTypeConverter;
  9. import org.springframework.data.domain.PageRequest;
  10. import com.zzg.common.constant.WebAppConstants;
  11. public abstract class AbstractController {
  12. /**
  13. * 参数分页参数转换校验:现在仅支持:get请求、参数格式:?page=1&limit=10
  14. *
  15. * @param param
  16. * @return
  17. */
  18. protected PageRequest initPageBounds(Map<String, Object> paramter) {
  19. SimpleTypeConverter converter = new SimpleTypeConverter();
  20. // 页码、分页大小初始化设置值
  21. int page = 0;
  22. int limit = 10;
  23. if (paramter.get(WebAppConstants.PAGE) != null) {
  24. page = converter.convertIfNecessary(paramter.get(WebAppConstants.PAGE), int.class);
  25. }
  26. if (paramter.get(WebAppConstants.LIMIT) != null) {
  27. limit = converter.convertIfNecessary(paramter.get(WebAppConstants.LIMIT), int.class);
  28. }
  29. PageRequest pb = new PageRequest(page, limit);
  30. return pb;
  31. }
  32. public static void copyPropertiesIgnoreNull(Object src, Object target) {
  33. BeanUtils.copyProperties(src, target, getNullPropertyNames(src));
  34. }
  35. public static String[] getNullPropertyNames(Object source) {
  36. final BeanWrapper src = new BeanWrapperImpl(source);
  37. java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
  38. Set<String> emptyNames = new HashSet<String>();
  39. for (java.beans.PropertyDescriptor pd : pds) {
  40. Object srcValue = src.getPropertyValue(pd.getName());
  41. if (srcValue == null)
  42. emptyNames.add(pd.getName());
  43. }
  44. String[] result = new String[emptyNames.size()];
  45. return emptyNames.toArray(result);
  46. }
  47. }

1.2.5 配置对象定义:GlobalCorsConfig :系统跨域对象配置、ShiroConfig :apache shrio 用户登入鉴权配置

  1. package com.zzg.config;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.web.cors.CorsConfiguration;
  5. import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
  6. import org.springframework.web.filter.CorsFilter;
  7. @Configuration
  8. public class GlobalCorsConfig {
  9. @Bean
  10. public CorsFilter corsFilter() {
  11. //1.添加CORS配置信息
  12. CorsConfiguration config = new CorsConfiguration();
  13. //放行哪些原始域
  14. config.addAllowedOrigin("*");
  15. //是否发送Cookie信息
  16. config.setAllowCredentials(true);
  17. //放行哪些原始域(请求方式)
  18. config.addAllowedMethod("*");
  19. //放行哪些原始域(头部信息)
  20. config.addAllowedHeader("*");
  21. //暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)
  22. // config.addExposedHeader("*");
  23. config.addExposedHeader("Content-Type");
  24. config.addExposedHeader( "X-Requested-With");
  25. config.addExposedHeader("accept");
  26. config.addExposedHeader("Origin");
  27. config.addExposedHeader( "Access-Control-Request-Method");
  28. config.addExposedHeader("Access-Control-Request-Headers");
  29. //2.添加映射路径
  30. UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
  31. configSource.registerCorsConfiguration("/**", config);
  32. //3.返回新的CorsFilter.
  33. return new CorsFilter(configSource);
  34. }
  35. }
  1. package com.zzg.config;
  2. import java.util.HashMap;
  3. import java.util.LinkedHashMap;
  4. import java.util.Map;
  5. import javax.servlet.Filter;
  6. import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
  7. import org.apache.shiro.mgt.DefaultSubjectDAO;
  8. import org.apache.shiro.spring.LifecycleBeanPostProcessor;
  9. import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
  10. import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
  11. import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
  12. import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
  13. import org.springframework.context.annotation.Bean;
  14. import org.springframework.context.annotation.Configuration;
  15. import com.zzg.filter.JWTFilter;
  16. import com.zzg.shrio.MyRealm;
  17. @Configuration
  18. public class ShiroConfig {
  19. /**
  20. * 先走 filter ,然后 filter 如果检测到请求头存在 token,则用 token 去 login,走 Realm 去验证
  21. */
  22. @Bean
  23. public ShiroFilterFactoryBean factory(org.apache.shiro.mgt.SecurityManager securityManager) {
  24. ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
  25. // 添加自己的过滤器并且取名为jwt
  26. Map<String, Filter> filterMap = new LinkedHashMap<>();
  27. // 设置自定义的JWT过滤器
  28. filterMap.put("jwt", new JWTFilter());
  29. factoryBean.setFilters(filterMap);
  30. factoryBean.setSecurityManager(securityManager);
  31. Map<String, String> filterRuleMap = new HashMap<>();
  32. filterRuleMap.put("/common/login", "anon"); //简单登录接口排除
  33. filterRuleMap.put("/phone/login", "anon"); //邮箱登录接口排除
  34. filterRuleMap.put("/email/login", "anon"); //邮箱登录接口排除
  35. filterRuleMap.put("/sys/login", "anon"); //登录接口排除
  36. filterRuleMap.put("/sys/logout", "anon"); //登出接口排除
  37. filterRuleMap.put("/sys/kaptcha", "anon"); //验证码接口排除
  38. filterRuleMap.put("/sys/verification", "anon"); //验证码接口排除
  39. // 所有请求通过我们自己的JWT Filter
  40. filterRuleMap.put("/**", "jwt");
  41. factoryBean.setFilterChainDefinitionMap(filterRuleMap);
  42. return factoryBean;
  43. }
  44. /**
  45. * 注入 securityManager
  46. */
  47. @Bean
  48. public org.apache.shiro.mgt.SecurityManager securityManager(MyRealm customRealm) {
  49. DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
  50. // 设置自定义 realm.
  51. securityManager.setRealm(customRealm);
  52. /*
  53. * 关闭shiro自带的session,详情见文档
  54. * http://shiro.apache.org/session-management.html#SessionManagement-
  55. * StatelessApplications%28Sessionless%29
  56. */
  57. DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
  58. DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
  59. defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
  60. subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
  61. securityManager.setSubjectDAO(subjectDAO);
  62. return securityManager;
  63. }
  64. /**
  65. * 添加注解支持
  66. */
  67. @Bean
  68. public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
  69. DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
  70. // 强制使用cglib,防止重复代理和可能引起代理出错的问题
  71. // https://zhuanlan.zhihu.com/p/29161098
  72. defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
  73. return defaultAdvisorAutoProxyCreator;
  74. }
  75. @Bean
  76. public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(org.apache.shiro.mgt.SecurityManager securityManager) {
  77. AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
  78. advisor.setSecurityManager(securityManager);
  79. return advisor;
  80. }
  81. @Bean
  82. public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
  83. return new LifecycleBeanPostProcessor();
  84. }
  85. }

1.2.6 全局异常定义

  1. package com.zzg.exception;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. import org.apache.shiro.authz.AuthorizationException;
  5. import org.springframework.web.bind.annotation.ExceptionHandler;
  6. import org.springframework.web.bind.annotation.RestControllerAdvice;
  7. /**
  8. * 全局异常处理器
  9. */
  10. @RestControllerAdvice
  11. public class GlobalExceptionHandler {
  12. @ExceptionHandler(value = AuthorizationException.class)
  13. public Map<String, String> handleException(AuthorizationException e) {
  14. // e.printStackTrace();
  15. Map<String, String> result = new HashMap<String, String>();
  16. result.put("status", "400");
  17. // 获取错误中中括号的内容
  18. String message = e.getMessage();
  19. String msg = message.substring(message.indexOf("[") + 1, message.indexOf("]"));
  20. // 判断是角色错误还是权限错误
  21. if (message.contains("role")) {
  22. result.put("msg", "对不起,您没有" + msg + "角色");
  23. } else if (message.contains("permission")) {
  24. result.put("msg", "对不起,您没有" + msg + "权限");
  25. } else {
  26. result.put("msg", "对不起,您的权限有误");
  27. }
  28. return result;
  29. }
  30. }

1.2.7 JWTFilter 过滤器定义

  1. package com.zzg.filter;
  2. import java.io.IOException;
  3. import java.util.HashMap;
  4. import java.util.Map;
  5. import javax.servlet.ServletRequest;
  6. import javax.servlet.ServletResponse;
  7. import javax.servlet.http.HttpServletRequest;
  8. import javax.servlet.http.HttpServletResponse;
  9. import org.apache.shiro.authz.UnauthorizedException;
  10. import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
  11. import org.slf4j.Logger;
  12. import org.slf4j.LoggerFactory;
  13. import org.springframework.beans.factory.annotation.Autowired;
  14. import org.springframework.http.HttpStatus;
  15. import org.springframework.web.bind.annotation.RequestMethod;
  16. import com.alibaba.druid.util.StringUtils;
  17. import com.fasterxml.jackson.databind.ObjectMapper;
  18. import com.zzg.dao.TokenRelationRepository;
  19. import com.zzg.entity.TokenRelation;
  20. import com.zzg.redis.RedisUtils;
  21. import com.zzg.shrio.JWTToken;
  22. import com.zzg.spring.SpringContextUtil;
  23. import com.zzg.util.HttpContextUtil;
  24. public class JWTFilter extends BasicHttpAuthenticationFilter {
  25. private Logger logger = LoggerFactory.getLogger(this.getClass());
  26. // 定义jackson对象
  27. private static final ObjectMapper MAPPER = new ObjectMapper();
  28. /**
  29. * 如果带有 token,则对 token 进行检查,否则直接通过
  30. * >2 接着执行 isAccessAllowed
  31. */
  32. @Override
  33. protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws UnauthorizedException {
  34. // 判断请求的请求头是否存在 Token
  35. if (isLoginAttempt(request, response)) {
  36. //如果存在,则进入 executeLogin 方法执行登入,检查 token 是否正确
  37. // 不正常就会抛出异常
  38. try {
  39. // 执行登录
  40. executeLogin(request, response);
  41. return true;
  42. } catch (Exception e) {
  43. //token 错误
  44. responseError(response, e.getMessage());
  45. }
  46. } else {
  47. try{
  48. HttpServletResponse httpResponse = (HttpServletResponse) response;
  49. httpResponse.setContentType("application/json;charset=utf-8");
  50. httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
  51. httpResponse.setHeader("Access-Control-Allow-Origin", HttpContextUtil.getOrigin());
  52. httpResponse.setCharacterEncoding("UTF-8");
  53. //设置编码,否则中文字符在重定向时会变为空字符串
  54. Map<String, Object> result = new HashMap<>();
  55. result.put("status", 400);
  56. result.put("msg", "token 已经注销");
  57. String json = MAPPER.writeValueAsString(result);
  58. httpResponse.getWriter().print(json);
  59. return false;
  60. }catch(IOException e) {
  61. logger.error(e.getMessage());
  62. }
  63. }
  64. // 如果请求头不存在 Token,则可能是执行登陆操作或者是游客状态访问,
  65. // 无需检查 token,直接返回 true
  66. return true;
  67. }
  68. /**
  69. * 判断用户是否想要登入。
  70. * 检测 header 里面是否包含 Token 字段
  71. *
  72. */
  73. @Override
  74. protected boolean isLoginAttempt(ServletRequest request, ServletResponse response) {
  75. HttpServletRequest req = (HttpServletRequest) request;
  76. System.out.println("req.getHeader(Token)"+req.getHeader("Token"));
  77. String token = req.getHeader("Token");
  78. if(StringUtils.isEmpty(token)){
  79. return false;
  80. }
  81. TokenRelationRepository tokenRelationRepository = SpringContextUtil.getBean(TokenRelationRepository.class);
  82. TokenRelation relation = tokenRelationRepository.findByToken(token);
  83. if(relation != null){
  84. return RedisUtils.get(relation.getUsername()) != null;
  85. }
  86. return false;
  87. }
  88. /**
  89. * 执行登陆操作
  90. *
  91. */
  92. @Override
  93. protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
  94. HttpServletRequest httpServletRequest = (HttpServletRequest) request;
  95. String token = httpServletRequest.getHeader("Token");
  96. JWTToken jwtToken = new JWTToken(token);
  97. // 提交给realm进行登入,如果错误他会抛出异常并被捕获
  98. getSubject(request, response).login(jwtToken);
  99. // 如果没有抛出异常则代表登入成功,返回true
  100. return true;
  101. }
  102. /**
  103. *
  104. * 对跨域提供支持
  105. *
  106. * >1 请求最先从这开始执行
  107. *
  108. */
  109. @Override
  110. protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
  111. HttpServletRequest httpServletRequest = (HttpServletRequest) request;
  112. HttpServletResponse httpServletResponse = (HttpServletResponse) response;
  113. // 设置 header key-value
  114. // httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin"));
  115. httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE,aaa");
  116. // System.out.println(httpServletRequest.getHeader("Origin"));
  117. httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));
  118. // System.out.println( httpServletRequest.getHeader("Access-Control-Request-Headers"));
  119. // 跨域时会首先发送一个option请求,这里我们给option请求直接返回正常状态
  120. if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
  121. httpServletResponse.setStatus(HttpStatus.OK.value());
  122. return false;
  123. }
  124. return super.preHandle(request, response);
  125. }
  126. /**
  127. * 将非法请求跳转到 /unauthorized/**
  128. */
  129. private void responseError(ServletResponse response, String message) {
  130. try {
  131. HttpServletResponse httpResponse = (HttpServletResponse) response;
  132. httpResponse.setContentType("application/json;charset=utf-8");
  133. httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
  134. httpResponse.setHeader("Access-Control-Allow-Origin", HttpContextUtil.getOrigin());
  135. httpResponse.setCharacterEncoding("UTF-8");
  136. //设置编码,否则中文字符在重定向时会变为空字符串
  137. Map<String, Object> result = new HashMap<>();
  138. result.put("status", 500);
  139. result.put("msg", message);
  140. String json = MAPPER.writeValueAsString(result);
  141. httpResponse.getWriter().print(json);
  142. } catch (IOException e) {
  143. logger.error(e.getMessage());
  144. }
  145. }
  146. }

1.2.8 Redis工具类封装

  1. package com.zzg.redis;
  2. import java.util.Collection;
  3. import java.util.List;
  4. import java.util.Map;
  5. import java.util.concurrent.TimeUnit;
  6. import org.springframework.data.redis.core.RedisTemplate;
  7. import com.zzg.spring.SpringContextUtil;
  8. public class RedisUtils {
  9. private RedisUtils() {
  10. }
  11. @SuppressWarnings("unchecked")
  12. private static RedisTemplate<String, Object> redisTemplate = SpringContextUtil
  13. .getBean("redisTemplate", RedisTemplate.class);
  14. /**
  15. * 设置有效时间
  16. *
  17. * @param key Redis键
  18. * @param timeout 超时时间
  19. * @return true=设置成功;false=设置失败
  20. */
  21. public static boolean expire(final String key, final long timeout) {
  22. return expire(key, timeout, TimeUnit.SECONDS);
  23. }
  24. /**
  25. * 设置有效时间
  26. *
  27. * @param key Redis键
  28. * @param timeout 超时时间
  29. * @param unit 时间单位
  30. * @return true=设置成功;false=设置失败
  31. */
  32. public static boolean expire(final String key, final long timeout, final TimeUnit unit) {
  33. Boolean ret = redisTemplate.expire(key, timeout, unit);
  34. return ret != null && ret;
  35. }
  36. /**
  37. * 删除单个key
  38. *
  39. * @param key 键
  40. * @return true=删除成功;false=删除失败
  41. */
  42. public static boolean del(final String key) {
  43. Boolean ret = redisTemplate.delete(key);
  44. return ret != null && ret;
  45. }
  46. /**
  47. * 删除多个key
  48. *
  49. * @param keys 键集合
  50. * @return 成功删除的个数
  51. */
  52. public static long del(final Collection<String> keys) {
  53. Long ret = redisTemplate.delete(keys);
  54. return ret == null ? 0 : ret;
  55. }
  56. /**
  57. * 存入普通对象
  58. *
  59. * @param key Redis键
  60. * @param value 值
  61. */
  62. public static void set(final String key, final Object value) {
  63. redisTemplate.opsForValue().set(key, value, 1, TimeUnit.MINUTES);
  64. }
  65. // 存储普通对象操作
  66. /**
  67. * 存入普通对象
  68. *
  69. * @param key 键
  70. * @param value 值
  71. * @param timeout 有效期,单位秒
  72. */
  73. public static void set(final String key, final Object value, final long timeout) {
  74. redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
  75. }
  76. /**
  77. * 获取普通对象
  78. *
  79. * @param key 键
  80. * @return 对象
  81. */
  82. public static Object get(final String key) {
  83. return redisTemplate.opsForValue().get(key);
  84. }
  85. // 存储Hash操作
  86. /**
  87. * 删除Hash中指定数据
  88. *
  89. * @param key Redis键
  90. * @param hKey Hash键
  91. */
  92. public static void hDelete(final String key, final String hKey) {
  93. redisTemplate.opsForHash().delete(key, hKey);
  94. }
  95. /**
  96. * 往Hash中存入数据
  97. *
  98. * @param key Redis键
  99. * @param hKey Hash键
  100. * @param value 值
  101. */
  102. public static void hPut(final String key, final String hKey, final Object value) {
  103. redisTemplate.opsForHash().put(key, hKey, value);
  104. }
  105. /**
  106. * 往Hash中存入多个数据
  107. *
  108. * @param key Redis键
  109. * @param values Hash键值对
  110. */
  111. public static void hPutAll(final String key, final Map<String, Object> values) {
  112. redisTemplate.opsForHash().putAll(key, values);
  113. }
  114. /**
  115. * 获取Hash中的数据
  116. *
  117. * @param key Redis键
  118. * @param hKey Hash键
  119. * @return Hash中的对象
  120. */
  121. public static Object hGet(final String key, final String hKey) {
  122. return redisTemplate.opsForHash().get(key, hKey);
  123. }
  124. /**
  125. * 获取多个Hash中的数据
  126. *
  127. * @param key Redis键
  128. * @param hKeys Hash键集合
  129. * @return Hash对象集合
  130. */
  131. public static List<Object> hMultiGet(final String key, final Collection<Object> hKeys) {
  132. return redisTemplate.opsForHash().multiGet(key, hKeys);
  133. }
  134. // 存储Set相关操作
  135. /**
  136. * 往Set中存入数据
  137. *
  138. * @param key Redis键
  139. * @param values 值
  140. * @return 存入的个数
  141. */
  142. public static long sSet(final String key, final Object... values) {
  143. Long count = redisTemplate.opsForSet().add(key, values);
  144. return count == null ? 0 : count;
  145. }
  146. /**
  147. * 删除Set中的数据
  148. *
  149. * @param key Redis键
  150. * @param values 值
  151. * @return 移除的个数
  152. */
  153. public static long sDel(final String key, final Object... values) {
  154. Long count = redisTemplate.opsForSet().remove(key, values);
  155. return count == null ? 0 : count;
  156. }
  157. // 存储List相关操作
  158. /**
  159. * 往List中存入数据
  160. *
  161. * @param key Redis键
  162. * @param value 数据
  163. * @return 存入的个数
  164. */
  165. public static long lPush(final String key, final Object value) {
  166. Long count = redisTemplate.opsForList().rightPush(key, value);
  167. return count == null ? 0 : count;
  168. }
  169. /**
  170. * 往List中存入多个数据
  171. *
  172. * @param key Redis键
  173. * @param values 多个数据
  174. * @return 存入的个数
  175. */
  176. public static long lPushAll(final String key, final Collection<Object> values) {
  177. Long count = redisTemplate.opsForList().rightPushAll(key, values);
  178. return count == null ? 0 : count;
  179. }
  180. /**
  181. * 往List中存入多个数据
  182. *
  183. * @param key Redis键
  184. * @param values 多个数据
  185. * @return 存入的个数
  186. */
  187. public static long lPushAll(final String key, final Object... values) {
  188. Long count = redisTemplate.opsForList().rightPushAll(key, values);
  189. return count == null ? 0 : count;
  190. }
  191. /**
  192. * 从List中获取begin到end之间的元素
  193. *
  194. * @param key Redis键
  195. * @param start 开始位置
  196. * @param end 结束位置(start=0,end=-1表示获取全部元素)
  197. * @return List对象
  198. */
  199. public static List<Object> lGet(final String key, final int start, final int end) {
  200. return redisTemplate.opsForList().range(key, start, end);
  201. }
  202. }

1.2.9  Apache Shrio 认证相关类定义

  1. package com.zzg.shrio;
  2. import org.apache.shiro.authc.AuthenticationToken;
  3. public class JWTToken implements AuthenticationToken{
  4. /**
  5. *
  6. */
  7. private static final long serialVersionUID = -6747540462673342320L;
  8. private String token;
  9. public JWTToken(String token) {
  10. this.token = token;
  11. }
  12. @Override
  13. public Object getPrincipal() {
  14. return token;
  15. }
  16. @Override
  17. public Object getCredentials() {
  18. return token;
  19. }
  20. }
  1. package com.zzg.shrio;
  2. import java.util.HashSet;
  3. import java.util.Set;
  4. import org.apache.shiro.authc.AuthenticationException;
  5. import org.apache.shiro.authc.AuthenticationInfo;
  6. import org.apache.shiro.authc.AuthenticationToken;
  7. import org.apache.shiro.authc.SimpleAuthenticationInfo;
  8. import org.apache.shiro.authz.AuthorizationInfo;
  9. import org.apache.shiro.authz.SimpleAuthorizationInfo;
  10. import org.apache.shiro.realm.AuthorizingRealm;
  11. import org.apache.shiro.subject.PrincipalCollection;
  12. import org.apache.shiro.util.CollectionUtils;
  13. import org.springframework.beans.factory.annotation.Autowired;
  14. import org.springframework.context.annotation.Lazy;
  15. import org.springframework.stereotype.Component;
  16. import com.alibaba.druid.util.StringUtils;
  17. import com.zzg.dao.RoleRepository;
  18. import com.zzg.dao.UserRepository;
  19. import com.zzg.entity.Permission;
  20. import com.zzg.entity.Role;
  21. import com.zzg.entity.User;
  22. import com.zzg.util.JWTUtil;
  23. @Component
  24. public class MyRealm extends AuthorizingRealm {
  25. @Autowired
  26. @Lazy
  27. private UserRepository userRepository;
  28. @Autowired
  29. @Lazy
  30. private RoleRepository roleRepository;
  31. /**
  32. * 必须重写此方法,不然会报错
  33. */
  34. @Override
  35. public boolean supports(AuthenticationToken token) {
  36. return token instanceof JWTToken;
  37. }
  38. /**
  39. * 只有当需要检测用户权限的时候才会调用此方法,例如checkRole,checkPermission之类的
  40. */
  41. @Override
  42. protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
  43. // TODO Auto-generated method stub
  44. System.out.println(">执行 doGetAuthorizationInfo 权限认证");
  45. // principals 传过来的是 token
  46. // System.out.println(">principals = "+principals);
  47. String username = JWTUtil.getUsername(principals.toString());
  48. SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
  49. //获得该用户角色
  50. User user = userRepository.findByUsername(username);
  51. Set<String> roleSet = new HashSet<>();
  52. Set<String> permissionSet = new HashSet<>();
  53. // 需要将 role, permission 封装到 Set 作为 info.setRoles(), info.setStringPermissions() 的参数
  54. user.getRoles().stream().forEach(item->{
  55. roleSet.add(item.getRoleName());
  56. });
  57. user.getRoles().stream().forEach(item->{
  58. Role role = roleRepository.findByRoleId(item.getRoleId());
  59. if(!CollectionUtils.isEmpty(role.getPermissions())){
  60. for(Permission permission : role.getPermissions()){
  61. permissionSet.add(permission.getPermissionPath());
  62. }
  63. }
  64. });
  65. // 设置该用户拥有的角色和权限
  66. info.setRoles(roleSet);
  67. info.setStringPermissions(permissionSet);
  68. return info;
  69. }
  70. /**
  71. * 默认使用此方法进行用户名正确与否验证,错误抛出异常即可。
  72. */
  73. @Override
  74. protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
  75. // TODO Auto-generated method stub
  76. System.out.println(">执行 doGetAuthenticationInfo 身份认证");
  77. String token = (String) authenticationToken.getCredentials();
  78. System.out.println(">token "+token);
  79. // 解密获得 username 用于和数据库进行对比
  80. String username = JWTUtil.getUsername(token);
  81. if (username == null || !JWTUtil.verify(token, username)) {
  82. throw new AuthenticationException("token 认证失败");
  83. }
  84. // 检查用户是否存在 通过密码来判断
  85. User user = userRepository.findByUsername(username);
  86. if (StringUtils.isEmpty(user.getPassword())) {
  87. throw new AuthenticationException("该用户不存在 ");
  88. }
  89. System.out.println(">getName "+getName());
  90. // return new SimpleAuthenticationInfo(token, token, "MyRealm");
  91. return new SimpleAuthenticationInfo(token, token, getName());
  92. }
  93. }

1.2.10  Spring 工具类

  1. package com.zzg.spring;
  2. import org.springframework.context.ApplicationContext;
  3. public class SpringContextUtil {
  4. private static ApplicationContext applicationContext;
  5. public static void setApplicationContext(ApplicationContext applicationContext){
  6. // TODO Auto-generated method stub
  7. if(SpringContextUtil.applicationContext == null) {
  8. SpringContextUtil.applicationContext = applicationContext;
  9. }
  10. }
  11. public static ApplicationContext getApplicationContext() {
  12. return applicationContext;
  13. }
  14. // 通过class 获取bean
  15. public static <T> T getBean(Class<T> clazz) {
  16. return applicationContext.getBean(clazz);
  17. }
  18. // 通过name 获取bean
  19. public static Object getBean(String name) {
  20. return applicationContext.getBean(name);
  21. }
  22. //通过name,以及Clazz返回指定的Bean
  23. public static <T> T getBean(String name,Class<T> clazz){
  24. return applicationContext.getBean(name, clazz);
  25. }
  26. }

1.2.11  系统封装工具类

  1. package com.zzg.util;
  2. import javax.servlet.http.HttpServletRequest;
  3. import org.springframework.web.context.request.RequestContextHolder;
  4. import org.springframework.web.context.request.ServletRequestAttributes;
  5. public class HttpContextUtil {
  6. public static HttpServletRequest getHttpServletRequest() {
  7. return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
  8. }
  9. public static String getDomain() {
  10. HttpServletRequest request = getHttpServletRequest();
  11. StringBuffer url = request.getRequestURL();
  12. return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString();
  13. }
  14. public static String getOrigin() {
  15. HttpServletRequest request = getHttpServletRequest();
  16. return request.getHeader("Origin");
  17. }
  18. }
  1. package com.zzg.util;
  2. import java.util.Date;
  3. import com.auth0.jwt.JWT;
  4. import com.auth0.jwt.JWTVerifier;
  5. import com.auth0.jwt.algorithms.Algorithm;
  6. import com.auth0.jwt.exceptions.JWTDecodeException;
  7. import com.auth0.jwt.interfaces.DecodedJWT;
  8. public class JWTUtil {
  9. // 过期时间 24 小时
  10. private static final long EXPIRE_TIME = 60 * 24 * 60 * 1000;
  11. // 密钥
  12. private static final String SECRET = "SHIRO+JWT";
  13. /**
  14. * 登录时通过 loginController 生成 token, 5min后过期
  15. *
  16. * @param username
  17. * 用户名
  18. * @return 加密的token
  19. */
  20. public static String createToken(String username) {
  21. try {
  22. Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
  23. Algorithm algorithm = Algorithm.HMAC256(SECRET);
  24. System.out.println(">algorithm " + algorithm);
  25. // 返回 token
  26. // 附带username信息
  27. return JWT.create().withClaim("username", username)
  28. // 到期时间
  29. .withExpiresAt(date)
  30. // 创建一个新的JWT,并使用给定的算法进行标记
  31. .sign(algorithm);
  32. } catch (Exception e) {
  33. return null;
  34. }
  35. }
  36. /**
  37. * 校验 token 是否正确
  38. *
  39. * @param token
  40. * 密钥
  41. * @param username
  42. * 用户名
  43. * @return 是否正确
  44. */
  45. public static boolean verify(String token, String username) {
  46. System.out.println(">执行 verify");
  47. try {
  48. Algorithm algorithm = Algorithm.HMAC256(SECRET);
  49. // 在token中附带了 username 信息
  50. JWTVerifier verifier = JWT.require(algorithm).withClaim("username", username).build();
  51. // 验证 token
  52. verifier.verify(token);
  53. return true;
  54. } catch (Exception exception) {
  55. // 出错就返回 false
  56. return false;
  57. }
  58. }
  59. /**
  60. * 根据token 获取 username 获得token中的信息,无需 secret 解密也能获得
  61. *
  62. * @return token 中包含的 username
  63. */
  64. public static String getUsername(String token) {
  65. try {
  66. DecodedJWT jwt = JWT.decode(token);
  67. return jwt.getClaim("username").asString();
  68. } catch (JWTDecodeException e) {
  69. return null;
  70. }
  71. }
  72. }
  1. package com.zzg.util;
  2. import java.util.Properties;
  3. import com.google.code.kaptcha.impl.DefaultKaptcha;
  4. import com.google.code.kaptcha.util.Config;
  5. public class KaptchaUtil {
  6. private static KaptchaUtil instance;
  7. private KaptchaUtil() {
  8. };
  9. public static KaptchaUtil getInstance() {
  10. if (instance == null) {
  11. instance = new KaptchaUtil();
  12. }
  13. return instance;
  14. }
  15. /**
  16. * 生成DefaultKaptcha 默认配置
  17. * @return
  18. */
  19. public DefaultKaptcha produce() {
  20. Properties properties = new Properties();
  21. properties.put("kaptcha.border", "no");
  22. properties.put("kaptcha.border.color", "105,179,90");
  23. properties.put("kaptcha.textproducer.font.color", "blue");
  24. properties.put("kaptcha.image.width", "100");
  25. properties.put("kaptcha.image.height", "50");
  26. properties.put("kaptcha.textproducer.font.size", "27");
  27. properties.put("kaptcha.session.key", "code");
  28. properties.put("kaptcha.textproducer.char.length", "4");
  29. properties.put("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑");
  30. properties.put("kaptcha.textproducer.char.string", "0123456789ABCEFGHIJKLMNOPQRSTUVWXYZ");
  31. properties.put("kaptcha.obscurificator.impl", "com.google.code.kaptcha.impl.WaterRipple");
  32. properties.put("kaptcha.noise.color", "black");
  33. properties.put("kaptcha.noise.impl", "com.google.code.kaptcha.impl.DefaultNoise");
  34. properties.put("kaptcha.background.clear.from", "185,56,213");
  35. properties.put("kaptcha.background.clear.to", "white");
  36. properties.put("kaptcha.textproducer.char.space", "3");
  37. Config config = new Config(properties);
  38. DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
  39. defaultKaptcha.setConfig(config);
  40. return defaultKaptcha;
  41. }
  42. }

1.2.12  实体对象拓展

  1. package com.zzg.vo;
  2. import java.util.List;
  3. import lombok.Getter;
  4. import lombok.Setter;
  5. @Getter
  6. @Setter
  7. public class PermissionVo {
  8. private Integer permissionId;
  9. private String permissionName;
  10. private String permissionZh;
  11. private String permissionPath;
  12. private String permisionIcon;
  13. private String permisionComponent;
  14. private Integer permisionParentId;
  15. private List<PermissionVo> child;
  16. }

1.2.13  SpringBoot 程序入口

  1. package com.zzg;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. import org.springframework.boot.autoconfigure.domain.EntityScan;
  5. import org.springframework.context.ApplicationContext;
  6. import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
  7. import com.zzg.spring.SpringContextUtil;
  8. @SpringBootApplication
  9. @EntityScan("com.zzg.entity") //Spring-JPA实体扫描
  10. @EnableJpaRepositories(basePackages = { "com.zzg.dao" }) //Spring-JPA Repository扫描
  11. public class ShrioApplication {
  12. public static void main(String[] args) {
  13. // TODO Auto-generated method stub
  14. ApplicationContext applicationContext = SpringApplication.run(ShrioApplication.class, args);
  15. SpringContextUtil.setApplicationContext(applicationContext);
  16. }
  17. }

1.2.14 SpringBoot 程序资源文件(application.yml)

  1. # Tomcat
  2. server:
  3. tomcat:
  4. uri-encoding: UTF-8
  5. max-threads: 1000
  6. min-spare-threads: 30
  7. port: 9090
  8. connection-timeout: 5000ms
  9. servlet:
  10. context-path: /shiro
  11. #spring
  12. spring:
  13. # 数据源
  14. datasource:
  15. type: com.alibaba.druid.pool.DruidDataSource
  16. druid:
  17. driver-class-name: com.mysql.cj.jdbc.Driver
  18. url: jdbc:mysql://127.0.0.1:3306/auth_shrio?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&serverTimezone=Asia/Shanghai
  19. username: root
  20. password: 123456
  21. initial-size: 10
  22. max-active: 100
  23. min-idle: 10
  24. max-wait: 60000
  25. pool-prepared-statements: true
  26. max-pool-prepared-statement-per-connection-size: 20
  27. time-between-eviction-runs-millis: 60000
  28. min-evictable-idle-time-millis: 300000
  29. test-while-idle: true
  30. test-on-borrow: false
  31. test-on-return: false
  32. stat-view-servlet:
  33. enabled: true
  34. url-pattern: /druid/*
  35. filter:
  36. stat:
  37. log-slow-sql: false
  38. slow-sql-millis: 1000
  39. merge-sql: false
  40. wall:
  41. config:
  42. multi-statement-allow: true
  43. jpa:
  44. show-sql: true
  45. hibernate:
  46. ddl-auto: update
  47. database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
  48. database: mysql
  49. redis:
  50. database: 0
  51. host: 127.0.0.1
  52. port: 6379
  53. password: abc123

1.2.15 SpringBoot 程序依赖pom.xml 文件

  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  2. <modelVersion>4.0.0</modelVersion>
  3. <groupId>com.zzg</groupId>
  4. <artifactId>lease_sys</artifactId>
  5. <version>0.0.1-SNAPSHOT</version>
  6. <parent>
  7. <groupId>org.springframework.boot</groupId>
  8. <artifactId>spring-boot-starter-parent</artifactId>
  9. <version>2.1.0.RELEASE</version>
  10. <relativePath /> <!-- lookup parent from repository -->
  11. </parent>
  12. <properties>
  13. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  14. <encoding>UTF-8</encoding>
  15. <java.version>1.8</java.version>
  16. </properties>
  17. <dependencies>
  18. <!--starter-->
  19. <dependency>
  20. <groupId>org.springframework.boot</groupId>
  21. <artifactId>spring-boot-starter</artifactId>
  22. </dependency>
  23. <!-- test-->
  24. <dependency>
  25. <groupId>org.springframework.boot</groupId>
  26. <artifactId>spring-boot-starter-test</artifactId>
  27. <scope>test</scope>
  28. </dependency>
  29. <!--web-->
  30. <dependency>
  31. <groupId>org.springframework.boot</groupId>
  32. <artifactId>spring-boot-starter-web</artifactId>
  33. </dependency>
  34. <!--validation-->
  35. <dependency>
  36. <groupId>org.springframework.boot</groupId>
  37. <artifactId>spring-boot-starter-validation</artifactId>
  38. </dependency>
  39. <!--JPA-->
  40. <dependency>
  41. <groupId>org.springframework.boot</groupId>
  42. <artifactId>spring-boot-starter-data-jpa</artifactId>
  43. </dependency>
  44. <!--JDBC-->
  45. <dependency>
  46. <groupId>org.springframework.boot</groupId>
  47. <artifactId>spring-boot-starter-jdbc</artifactId>
  48. </dependency>
  49. <!--lombok-->
  50. <dependency>
  51. <groupId>org.projectlombok</groupId>
  52. <artifactId>lombok</artifactId>
  53. </dependency>
  54. <!-- shiro-->
  55. <dependency>
  56. <groupId>org.apache.shiro</groupId>
  57. <artifactId>shiro-spring</artifactId>
  58. <version>1.3.2</version>
  59. </dependency>
  60. <!-- jwt -->
  61. <dependency>
  62. <groupId>com.auth0</groupId>
  63. <artifactId>java-jwt</artifactId>
  64. <version>3.8.1</version>
  65. </dependency>
  66. <!--mysql-connector-->
  67. <dependency>
  68. <groupId>mysql</groupId>
  69. <artifactId>mysql-connector-java</artifactId>
  70. <scope>runtime</scope>
  71. </dependency>
  72. <!-- druid-spring-boot-starter -->
  73. <dependency>
  74. <groupId>com.alibaba</groupId>
  75. <artifactId>druid-spring-boot-starter</artifactId>
  76. <version>1.1.10</version>
  77. </dependency>
  78. <!-- redis-->
  79. <dependency>
  80. <groupId>org.springframework.boot</groupId>
  81. <artifactId>spring-boot-starter-data-redis</artifactId>
  82. </dependency>
  83. <!-- commons-lang -->
  84. <dependency>
  85. <groupId>commons-lang</groupId>
  86. <artifactId>commons-lang</artifactId>
  87. <version>2.6</version>
  88. </dependency>
  89. <!-- apache common 模块 -->
  90. <!--commons-lang3 工具包 -->
  91. <dependency>
  92. <groupId>org.apache.commons</groupId>
  93. <artifactId>commons-lang3</artifactId>
  94. <version>3.9</version>
  95. </dependency>
  96. <!--commons-codec 加密工具包 -->
  97. <dependency>
  98. <groupId>commons-codec</groupId>
  99. <artifactId>commons-codec</artifactId>
  100. <version>1.10</version>
  101. </dependency>
  102. <!--commons-net 网络工具包 -->
  103. <dependency>
  104. <groupId>commons-net</groupId>
  105. <artifactId>commons-net</artifactId>
  106. <version>3.6</version>
  107. </dependency>
  108. <!--common-io 工具包 -->
  109. <dependency>
  110. <groupId>commons-io</groupId>
  111. <artifactId>commons-io</artifactId>
  112. <version>2.6</version>
  113. </dependency>
  114. <!--common-collection 工具包 -->
  115. <dependency>
  116. <groupId>commons-collections</groupId>
  117. <artifactId>commons-collections</artifactId>
  118. <version>3.2.1</version>
  119. </dependency>
  120. <!-- 依赖kaptcha图形生成器 -->
  121. <dependency>
  122. <groupId>com.github.penggle</groupId>
  123. <artifactId>kaptcha</artifactId>
  124. <version>2.3.2</version>
  125. </dependency>
  126. </dependencies>
  127. </project>

1.2.15 SpringBoot  项目整体截图:

1.3 Vue项目源码

1.3.1 Vue 项目整体结构图

1.3.2 main.js 函数:安装element-ui、安装axios、集成路由(router)、集成Vuex(store)

  1. // The Vue build version to load with the `import` command
  2. // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
  3. import Vue from 'vue'
  4. import App from './App'
  5. import router from './router'
  6. import store from './store'
  7. import ElementUI from 'element-ui';
  8. import 'element-ui/lib/theme-chalk/index.css';
  9. import axios from 'axios'
  10. Vue.prototype.$axios = axios
  11. Vue.use(ElementUI);
  12. Vue.config.productionTip = false
  13. /* eslint-disable no-new */
  14. new Vue({
  15. el: '#app',
  16. router,
  17. store,
  18. components: { App },
  19. template: '<App/>'
  20. })

1.3.3 App.vue:定义Vue程序入口

  1. <template>
  2. <div id="app">
  3. <router-view/>
  4. </div>
  5. </template>
  6. <script>
  7. export default {
  8. name: 'App'
  9. }
  10. </script>
  11. <style>
  12. * {
  13. margin: 0;
  14. padding: 0;
  15. box-sizing: border-box;
  16. }
  17. </style>

1.3.4 utils 文件夹:封装axios 请求(post\get\delete),  封装axios 请求拦截器和响应拦截器 、异步转同步定时函数

  1. import axios from 'axios'
  2. // 设置后端请求地址
  3. axios.defaults.baseURL='http://192.168.1.74:9090/shiro'
  4. // post请求头
  5. axios.defaults.headers.post['Content-Type'] = 'application/json'
  6. // 携带凭证信息
  7. axios.defaults.withCredentials = true
  8. // 添加请求拦截器,在请求头中加token
  9. axios.interceptors.request.use(
  10. config => {
  11. if (window.localStorage.getItem('token')) {
  12. config.headers.token = window.localStorage.getItem('token');
  13. }
  14. return config;
  15. },
  16. error => {
  17. return Promise.reject(error);
  18. });
  19. // 添加响应拦截器,移除token
  20. axios.interceptors.response.use(
  21. response =>{
  22. return response;
  23. },
  24. error=>{
  25. if(error.response){
  26. switch(error.response.status){
  27. case 401:
  28. localStorage.removeItem('token');
  29. this.$router.push('/login');
  30. }
  31. }
  32. })
  33. /**
  34. * get方法,对应get请求
  35. * @param {Stringf} url [请求的url地址]
  36. * @param {Object} params [请求时携带的参数]
  37. */
  38. export function get (url, params) {
  39. return new Promise((resolve, reject) => {
  40. axios.get(url, {
  41. params: params
  42. }).then(res => {
  43. resolve(res.data)
  44. }).catch(err => {
  45. reject(err.data)
  46. })
  47. })
  48. }
  49. /**
  50. * post方法,对应post请求
  51. * @param {String} url [请求的url地址]
  52. * @param {Object} params [请求时携带的参数]
  53. */
  54. export function post (url, params) {
  55. return new Promise((resolve, reject) => {
  56. axios.post(url, params).then(res => {
  57. resolve(res.data)
  58. }).catch(err => {
  59. reject(err.data)
  60. })
  61. })
  62. }
  63. /**
  64. * del 方法,对应del 请求
  65. * @param {String} url [请求的url地址]
  66. * @param {Object} params [请求时携带的参数]
  67. */
  68. export function del (url, params) {
  69. return new Promise((resolve, reject) => {
  70. axios.delete(url, params).then(res => {
  71. resolve(res.data)
  72. }).catch(err => {
  73. reject(err.data)
  74. })
  75. })
  76. }
  77. export function waitsleep (method) {
  78. const start = Number(Date.now())
  79. return new Promise((resolve) => {
  80. (function selfRecursion () {
  81. setTimeout(() => {
  82. let flag
  83. if (typeof method === 'function') {
  84. flag = method()
  85. }
  86. if (typeof method === 'number') {
  87. flag = Number(Date.now()) - start < method
  88. }
  89. if (flag) {
  90. selfRecursion()
  91. } else {
  92. resolve()
  93. }
  94. }, 10)
  95. })()
  96. })
  97. }

 routerFormat.js :动态加载菜单函数定义

  1. /**
  2. * 构建动态菜单路由对象
  3. * @param {Object} routes [后台返回路由数据]
  4. */
  5. export function formatRoutes (routes) {
  6. console.log(routes)
  7. let fmtRoutes = []
  8. routes.forEach(routes => {
  9. if (routes.child) {
  10. routes.child = formatRoutes(routes.child)
  11. }
  12. let fmtRoute = {
  13. path: routes.permissionPath,
  14. component: resolve => {
  15. require(['@/components/admin/' + routes.permisionComponent + '.vue'], resolve)
  16. },
  17. name: routes.permissionName,
  18. nameZh: routes.permissionZh,
  19. iconCls: routes.permisionIcon,
  20. children: routes.child
  21. }
  22. fmtRoutes.push(fmtRoute)
  23. })
  24. return fmtRoutes
  25. }

initAdmin.js:触发动态加载菜单函数

  1. import {get, waitsleep} from '@/utils/http'
  2. import {formatRoutes} from '../utils/routerFormat'
  3. export default function initAdminMenu (router, store) {
  4. if (store.state.adminMenus.length > 0) {
  5. return
  6. }
  7. // 定时函数:定时函数实现异步方法模拟同步方法
  8. waitsleep(() => store.state.uid === -1).then(() => {
  9. // 动态权限请求
  10. get('/permission/' + store.state.uid).then(resp => {
  11. console.log(resp.date)
  12. console.log(resp.date)
  13. var fmtRoutes = formatRoutes(resp.date)
  14. router.addRoutes(fmtRoutes)
  15. store.commit('initAdminMenu', fmtRoutes)
  16. })
  17. })
  18. }

1.3.5 store文件夹:定义存储在Vuex 中的变量

index.js

  1. import Vue from 'vue'
  2. import Vuex from 'vuex'
  3. Vue.use(Vuex);
  4. const store = new Vuex.Store({
  5. state: {
  6. // 存储token
  7. token: window.localStorage.getItem('token') ? window.localStorage.getItem('token') : '',
  8. // 存储username
  9. username: window.localStorage.getItem('username') ? window.localStorage.getItem('username') : '',
  10. // 存储用户ID
  11. uid: -1,
  12. // 存储用户菜单
  13. adminMenus: []
  14. },
  15. mutations: {
  16. // 修改token,并将token存入localStorage
  17. setToken (state, user) {
  18. console.log(user)
  19. state.token = user;
  20. window.localStorage.setItem('token', user);
  21. },
  22. setUserName (state, user) {
  23. console.log(user)
  24. state.username = user;
  25. window.localStorage.setItem('username', user);
  26. },
  27. setUserId (state, user) {
  28. console.log(user)
  29. state.uid = user
  30. },
  31. initAdminMenu (state, menu) {
  32. state.adminMenus = menu
  33. },
  34. logout (state, user) {
  35. state.username = ''
  36. state.token = ''
  37. state.uid = -1
  38. state.adminMenus = []
  39. localStorage.removeItem('token')
  40. localStorage.removeItem('username')
  41. }
  42. }
  43. });
  44. export default store;

1.3.6 route文件夹:定义组件路由访问和路由守护

index.js

  1. import Vue from 'vue'
  2. import Router from 'vue-router'
  3. import login from '@/components/login';
  4. import Admin from '@/components/admin/AdminIndex'
  5. import initAdminMenu from '../utils/initAdmin'
  6. import store from '../store'
  7. Vue.use(Router)
  8. const router = new Router({
  9. routes: [
  10. {
  11. path: '/',
  12. redirect: '/login'
  13. },
  14. {
  15. path: '/login',
  16. name: 'login',
  17. component: login
  18. },
  19. {
  20. path: '/admin',
  21. name: 'admin',
  22. component: Admin,
  23. redirect: '/admin/dashboard',
  24. children: [
  25. {
  26. path: '/admin/dashboard',
  27. name: 'adminDashboard',
  28. component: () => import('@/components/admin/dashboard/Index')
  29. },
  30. {
  31. path: '/admin/user/Profile',
  32. name: 'adminUserProfile',
  33. component: () => import('@/components/admin/user/Profile')
  34. },
  35. {
  36. path: '/admin/user/Role',
  37. name: 'adminUserRole',
  38. component: () => import('@/components/admin/user/Role')
  39. },
  40. {
  41. path: '/admin/test/Test1',
  42. name: 'adminTest1',
  43. component: () => import('@/components/admin/test/Test1')
  44. },
  45. {
  46. path: '/admin/test/Test2',
  47. name: 'adminTest2',
  48. component: () => import('@/components/admin/test/Test2')
  49. }
  50. ]
  51. }
  52. ]
  53. })
  54. // 导航守卫
  55. // 使用 router.beforeEach 注册一个全局前置守卫,判断用户是否登陆
  56. router.beforeEach((to, from, next) => {
  57. if (to.path === '/login') {
  58. next();
  59. } else {
  60. let token = localStorage.getItem('token');
  61. if (token === null || token === '') {
  62. next('/login');
  63. } else {
  64. console.log('12345')
  65. // 查询动态表单
  66. initAdminMenu(router, store)
  67. // 跳转至指定页面
  68. next();
  69. }
  70. }
  71. });
  72. export default router;

1.3.7 components文件夹:定义组件

components/login.vue 定义:登入首页

  1. <template>
  2. <div class="login-container">
  3. <el-form label-position="left"
  4. label-width="0px"
  5. status-icon>
  6. <h3 class="login_title">系统登录</h3>
  7. <el-form-item>
  8. <el-input
  9. type="text"
  10. v-model="loginForm.username"
  11. auto-coplete="off"
  12. placeholder="账号">
  13. </el-input>
  14. </el-form-item>
  15. <el-form-item>
  16. <el-input
  17. type="password"
  18. v-model="loginForm.password"
  19. auto-coplete="off"
  20. placeholder="密码">
  21. </el-input>
  22. </el-form-item>
  23. <el-form-item style="width: 100%">
  24. <el-button type="primary" @click.native.prevent="login" style="width: 100%">登录</el-button>
  25. <!--
  26. <el-button type="primary" @click.native.prevent="register" style="width: 100%; margin-top: 30px">注册</el-button>
  27. -->
  28. </el-form-item>
  29. </el-form>
  30. </div>
  31. </template>
  32. <script>
  33. import { post, waitsleep } from '@/utils/http'
  34. export default {
  35. data () {
  36. return {
  37. loginForm: {
  38. username: '',
  39. password: ''
  40. },
  41. userToken: ''
  42. };
  43. },
  44. methods: {
  45. login () {
  46. let _this = this;
  47. if (this.loginForm.username === '' || this.loginForm.password === '') {
  48. alert('账号或密码不能为空');
  49. } else {
  50. var params = {
  51. username: _this.loginForm.username,
  52. password: _this.loginForm.password
  53. }
  54. post('/common/login',params).then(res => {
  55. console.log(res);
  56. _this.userToken = res.token;
  57. // 将用户token保存到vuex中
  58. _this.$store.commit('setToken', res.token);
  59. _this.$store.commit('setUserName', res.username);
  60. _this.$store.commit('setUserId', res.uid);
  61. _this.$router.push('/admin');
  62. alert('登陆成功');
  63. })
  64. }
  65. }
  66. }
  67. };
  68. </script>
  69. <style scoped>
  70. .login-container{
  71. border-radius: 15px;
  72. background-clip: padding-box;
  73. margin: 10% auto;
  74. width: 350px;
  75. padding: 35px 35px 15px 35px;
  76. background: #fff;
  77. border: 1px solid #eaeaea;
  78. box-shadow: 0 0 25px #cac6c6;
  79. }
  80. .login_title{
  81. margin: 0px auto 40px auto;
  82. text-align: center;
  83. color: #505458;
  84. }
  85. </style>

components/home/Head.vue 定义:公共顶部栏组件

  1. <!-- -->
  2. <template>
  3. <div>
  4. <div class="home_title">后台系统</div>
  5. <div class="home_userinfoContainer">
  6. <el-dropdown @command="handleCommand">
  7. <span class="el-dropdown-link home_userinfo">
  8. {{currentUserName}}
  9. <i class="el-icon-arrow-down el-icon--right home_userinfo"></i>
  10. </span>
  11. <el-dropdown-menu slot="dropdown">
  12. <el-dropdown-item command="goIndex">返回主页</el-dropdown-item>
  13. <el-dropdown-item command="logout" divided>退出登录</el-dropdown-item>
  14. </el-dropdown-menu>
  15. </el-dropdown>
  16. </div>
  17. </div>
  18. </template>
  19. <script>
  20. import {post} from '@/utils/http'
  21. export default {
  22. data () {
  23. return {
  24. currentUserName: ''
  25. }
  26. },
  27. mounted: function getUser () {
  28. this.currentUserName = this.$store.state.username
  29. },
  30. methods: {
  31. handleCommand (command) {
  32. var _this = this
  33. if (command === 'logout') {
  34. this.$confirm('注销登录吗?', '提示', {
  35. confirmButtonText: '确定',
  36. cancelButtonText: '取消',
  37. type: 'warning'
  38. }).then(function () {
  39. post('/sys/logout')
  40. _this.$store.commit('logout')
  41. _this.$router.replace({name: 'login'})
  42. _this.$message.success('退出成功')
  43. }, function () {
  44. // 取消
  45. })
  46. } else if (command === 'goIndex') {
  47. this.$router.push({name: 'index'})
  48. }
  49. }
  50. }
  51. }
  52. </script>
  53. <style>
  54. .el-header {
  55. background-color: #20a0ff;
  56. color: #333;
  57. text-align: center;
  58. display: flex;
  59. align-items: center;
  60. justify-content: space-between;
  61. }
  62. .home_title {
  63. color: #fff;
  64. font-size: 22px;
  65. display: inline;
  66. }
  67. .home_userinfo {
  68. color: #fff;
  69. cursor: pointer;
  70. }
  71. .home_userinfoContainer {
  72. position: absolute;
  73. right: 0px;
  74. display: inline;
  75. margin-right: 20px;
  76. }
  77. </style>

components/home/Side.vue 定义:公共动态菜单栏组件

  1. <!-- -->
  2. <template>
  3. <el-menu router default-active="/admin/dashboard" mode="vertical" :collapse="isCollapse" style="height:100%">
  4. <template v-for="(item,i) in adminMenus">
  5. <el-submenu :key="i" :index="i + ''" style="text-align: left">
  6. <span slot="title">
  7. <i :class="item.iconCls" style="font-size:10px"></i>
  8. {{item.nameZh}}
  9. </span>
  10. <el-menu-item v-for="child in item.children" :key="child.path" :index="child.path">
  11. <i :class="child.icon"></i>
  12. {{ child.nameZh }}
  13. </el-menu-item>
  14. </el-submenu>
  15. </template>
  16. </el-menu>
  17. </template>
  18. <script>
  19. export default {
  20. data () {
  21. return {
  22. isCollapse: false
  23. // adminMenus: [
  24. // {
  25. // iconCls: 'el-icon-s-home',
  26. // nameZh: '首页',
  27. // children: [
  28. // {
  29. // icon: '',
  30. // nameZh: '首页1-1',
  31. // path: '/admin/user/Profile'
  32. // }
  33. // ]
  34. // }
  35. // ]
  36. }
  37. },
  38. computed: {
  39. adminMenus () {
  40. return this.$store.state.adminMenus
  41. }
  42. }
  43. }
  44. </script>

components/admin/AdminIndex.vue: 系统首页框架

  1. <!-- -->
  2. <template>
  3. <div>
  4. <el-container>
  5. <el-header>
  6. <Head></Head>
  7. </el-header>
  8. <el-container ref="homePage">
  9. <el-aside :width="sideWidth">
  10. <Side></Side>
  11. </el-aside>
  12. <el-main>
  13. <router-view />
  14. </el-main>
  15. </el-container>
  16. </el-container>
  17. </div>
  18. </template>
  19. <script>
  20. import Side from '@/components/home/Side'
  21. import Head from '@/components/home/Head'
  22. export default {
  23. data () {
  24. return {
  25. clientHeight: '',
  26. sideWidth: '200px'
  27. }
  28. },
  29. mounted: function () {
  30. // 获取浏览器可视区域高度
  31. this.clientHeight = `${document.documentElement.clientHeight}`
  32. this.sideWidth = document.body.clientWidth * 0.15 + 'px'
  33. // document.body.clientWidth;
  34. // console.log(self.clientHeight);
  35. window.onresize = function temp () {
  36. this.clientHeight = `${document.documentElement.clientHeight}`
  37. }
  38. },
  39. watch: {
  40. // 如果 `clientHeight` 发生改变,这个函数就会运行
  41. clientHeight: function () {
  42. this.changeFixed(this.clientHeight)
  43. }
  44. },
  45. methods: {
  46. changeFixed (clientHeight) {
  47. // 动态修改样式
  48. // console.log(clientHeight);
  49. // console.log(this.$refs.homePage.$el.style.height);
  50. this.$refs.homePage.$el.style.height = clientHeight - 80 + 'px'
  51. }
  52. },
  53. components: {
  54. Head,
  55. Side
  56. }
  57. }
  58. </script>
  59. <style>
  60. </style>

components/admin/dashboard/index.vue: 系统首页详情

  1. <template>
  2. <div>
  3. 首页
  4. </div>
  5. </template>
  6. <script>
  7. export default {
  8. name: 'Index',
  9. data () {
  10. return {}
  11. },
  12. computed: {},
  13. watch: {},
  14. methods: {}
  15. }
  16. </script>
  17. <style scoped>
  18. </style>

components/admin/test/Test1.vue: 测试页面一

  1. <template>
  2. <div>
  3. 测试1
  4. </div>
  5. </template>
  6. <script>
  7. export default {
  8. name: 'Test1',
  9. data () {
  10. return {}
  11. },
  12. computed: {},
  13. watch: {},
  14. methods: {}
  15. }
  16. </script>
  17. <style scoped>
  18. </style>

components/admin/test/Test2.vue: 测试页面二

  1. <template>
  2. <div>
  3. 测试2
  4. </div>
  5. </template>
  6. <script>
  7. export default {
  8. name: 'Test2',
  9. data () {
  10. return {}
  11. },
  12. computed: {},
  13. watch: {},
  14. methods: {}
  15. }
  16. </script>
  17. <style scoped>
  18. </style>

components/admin/user/Role.vue: 角色配置详情页面

  1. <template>
  2. <div>
  3. 角色配置
  4. </div>
  5. </template>
  6. <script>
  7. export default {
  8. name: 'Role',
  9. data () {
  10. return {}
  11. },
  12. computed: {},
  13. watch: {},
  14. methods: {}
  15. }
  16. </script>
  17. <style scoped>
  18. </style>

components/admin/user/Profile.vue: 用户详情页面

  1. <template>
  2. <div>
  3. 用户信息
  4. </div>
  5. </template>
  6. <script>
  7. export default {
  8. name: 'Profile',
  9. data () {
  10. return {}
  11. },
  12. computed: {},
  13. watch: {},
  14. methods: {}
  15. }
  16. </script>
  17. <style scoped>
  18. </style>

1.3.8 package.json:需要安装的第三方工具包

1.4 效果展示

 

前端git 项目地址:https://github.com/zhouzhiwengang/eight.git

后台git 项目地址:https://github.com/zhouzhiwengang/lease_sys.git

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号