Просмотр исходного кода

:recycle: Refactoring code login can support socail

冷冷 6 лет назад
Родитель
Сommit
396ee0203f
24 измененных файлов с 359 добавлено и 148 удалено
  1. 1 1
      pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/CommonConstant.java
  2. 10 3
      pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/SecurityConstants.java
  3. 7 2
      pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/enums/EnumLoginType.java
  4. 0 82
      pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/mobile/MobileAuthenticationEntryPoint.java
  5. 4 1
      pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/mobile/MobileAuthenticationFilter.java
  6. 5 0
      pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/mobile/MobileSecurityConfigurer.java
  7. 1 0
      pigx-config/src/main/resources/config/pigx-upms-dev.yml
  8. 2 1
      pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/filter/PasswordDecoderFilter.java
  9. 8 7
      pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/filter/ValidateCodeGatewayFilter.java
  10. 12 7
      pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysSocialDetails.java
  11. 1 1
      pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteUserService.java
  12. 2 3
      pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysSocialDetailsController.java
  13. 7 2
      pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/UserController.java
  14. 39 0
      pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/AbstractLoginHandler.java
  15. 53 0
      pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/LoginHandler.java
  16. 69 0
      pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/SmsLoginHandler.java
  17. 88 0
      pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/WeChatLoginHandler.java
  18. 4 5
      pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysSocialDetailsService.java
  19. 2 3
      pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysUserService.java
  20. 4 2
      pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/MobileServiceImpl.java
  21. 4 1
      pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysDeptRelationServiceImpl.java
  22. 15 1
      pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysDeptServiceImpl.java
  23. 17 12
      pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysSocialDetailsServiceImpl.java
  24. 4 14
      pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysUserServiceImpl.java

+ 1 - 1
pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/CommonConstant.java

@@ -80,5 +80,5 @@ public interface CommonConstant {
 	/**
 	 * 验证码前缀
 	 */
-	String DEFAULT_CODE_KEY = "DEFAULT_CODE_KEY";
+	String DEFAULT_CODE_KEY = "DEFAULT_CODE_KEY_";
 }

+ 10 - 3
pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/SecurityConstants.java

@@ -61,11 +61,18 @@ public interface SecurityConstants {
 	String FROM = "from";
 
 	/**
-	 * 手机号登录URL
+	 * OAUTH URL
 	 */
-	String MOBILE_TOKEN_URL = "/mobile/token";
-
+	String OAUTH_TOKEN_URL = "/oauth/token";
 
+	/**
+	 * 手机号登录URL
+	 */
+	String SMS_TOKEN_URL = "/mobile/token/sms";
+	/**
+	 * 自定义登录URL
+	 */
+	String MOBILE_TOKEN_URL = "/mobile/token/*";
 	/**
 	 * oauth 客户端信息
 	 */

+ 7 - 2
pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/enums/EnumLoginType.java

@@ -33,6 +33,11 @@ public enum EnumLoginType {
 	 */
 	PWD("PWD", "账号密码登录"),
 
+	/**
+	 * 验证码登录
+	 */
+	SMS("SMS", "验证码登录"),
+
 	/**
 	 * QQ登录
 	 */
@@ -46,9 +51,9 @@ public enum EnumLoginType {
 	/**
 	 * 类型
 	 */
-	private final String type;
+	private String type;
 	/**
 	 * 描述
 	 */
-	private final String description;
+	private String description;
 }

+ 0 - 82
pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/mobile/MobileAuthenticationEntryPoint.java

@@ -1,82 +0,0 @@
-/*
- *    Copyright (c) 2018-2025, lengleng All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * Neither the name of the pig4cloud.com developer nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * Author: lengleng (wangiegie@gmail.com)
- */
-
-package com.pig4cloud.pigx.common.security.mobile;
-
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.security.core.AuthenticationException;
-import org.springframework.security.oauth2.common.OAuth2AccessToken;
-import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
-import org.springframework.security.oauth2.provider.error.AbstractOAuth2SecurityExceptionHandler;
-import org.springframework.security.web.AuthenticationEntryPoint;
-import org.springframework.util.StringUtils;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-
-/**
- * @author lengleng
- * @date 2018/8/16
- * 手机号登录异常处理
- */
-public class MobileAuthenticationEntryPoint extends AbstractOAuth2SecurityExceptionHandler implements
-	AuthenticationEntryPoint {
-	private static final String WWW_AUTHENTICATE = "WWW-Authenticate";
-	private static final String SUFFIX = ",";
-
-	@Override
-	public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)
-		throws IOException, ServletException {
-		doHandle(request, response, authException);
-	}
-
-	@Override
-	protected ResponseEntity<OAuth2Exception> enhanceResponse(ResponseEntity<OAuth2Exception> response, Exception exception) {
-		HttpHeaders headers = response.getHeaders();
-		String existing = null;
-		if (headers.containsKey(WWW_AUTHENTICATE)) {
-			existing = extractTypePrefix(headers.getFirst("WWW-Authenticate"));
-		}
-		StringBuilder builder = new StringBuilder();
-		String typeName = OAuth2AccessToken.BEARER_TYPE;
-		builder.append(typeName + " ");
-		String realmName = "oauth";
-		builder.append("realm=\"" + realmName + "\"");
-		if (existing != null) {
-			builder.append(", " + existing);
-		}
-		HttpHeaders update = new HttpHeaders();
-		update.putAll(response.getHeaders());
-		update.set("WWW-Authenticate", builder.toString());
-		return new ResponseEntity<>(response.getBody(), update, HttpStatus.EXPECTATION_FAILED);
-	}
-
-	private String extractTypePrefix(String header) {
-		String existing = header;
-		String[] tokens = existing.split(" +");
-		if (tokens.length > 1 && !tokens[0].endsWith(SUFFIX)) {
-			existing = StringUtils.arrayToDelimitedString(tokens, " ").substring(existing.indexOf(" ") + 1);
-		}
-		return existing;
-	}
-
-}
-

+ 4 - 1
pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/mobile/MobileAuthenticationFilter.java

@@ -43,7 +43,6 @@ import javax.servlet.http.HttpServletResponse;
  */
 public class MobileAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
 	private static final String SPRING_SECURITY_FORM_MOBILE_KEY = "mobile";
-	private AuthenticationEntryPoint authenticationEntryPoint = new MobileAuthenticationEntryPoint();
 	@Getter
 	@Setter
 	private String mobileParameter = SPRING_SECURITY_FORM_MOBILE_KEY;
@@ -53,6 +52,10 @@ public class MobileAuthenticationFilter extends AbstractAuthenticationProcessing
 	@Getter
 	@Setter
 	private AuthenticationEventPublisher eventPublisher;
+	@Getter
+	@Setter
+	private AuthenticationEntryPoint authenticationEntryPoint;
+
 
 	public MobileAuthenticationFilter() {
 		super(new AntPathRequestMatcher(SecurityConstants.MOBILE_TOKEN_URL, "POST"));

+ 5 - 0
pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/mobile/MobileSecurityConfigurer.java

@@ -17,6 +17,8 @@
 
 package com.pig4cloud.pigx.common.security.mobile;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.pig4cloud.pigx.common.security.component.ResourceAuthExceptionEntryPoint;
 import com.pig4cloud.pigx.common.security.service.PigxUserDetailsService;
 import lombok.Getter;
 import lombok.Setter;
@@ -39,6 +41,8 @@ import org.springframework.stereotype.Component;
 @Setter
 @Component
 public class MobileSecurityConfigurer extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
+	@Autowired
+	private ObjectMapper objectMapper;
 	@Autowired
 	private AuthenticationEventPublisher defaultAuthenticationEventPublisher;
 	private AuthenticationSuccessHandler mobileLoginSuccessHandler;
@@ -50,6 +54,7 @@ public class MobileSecurityConfigurer extends SecurityConfigurerAdapter<DefaultS
 		mobileAuthenticationFilter.setAuthenticationManager(http.getSharedObject(AuthenticationManager.class));
 		mobileAuthenticationFilter.setAuthenticationSuccessHandler(mobileLoginSuccessHandler);
 		mobileAuthenticationFilter.setEventPublisher(defaultAuthenticationEventPublisher);
+		mobileAuthenticationFilter.setAuthenticationEntryPoint(new ResourceAuthExceptionEntryPoint(objectMapper));
 
 		MobileAuthenticationProvider mobileAuthenticationProvider = new MobileAuthenticationProvider();
 		mobileAuthenticationProvider.setUserDetailsService(userDetailsService);

+ 1 - 0
pigx-config/src/main/resources/config/pigx-upms-dev.yml

@@ -11,6 +11,7 @@ security:
         - '/v2/api-docs'
         - '/user/info/*'
         - '/social/info/**'
+        - '/mobile/*'
         - '/log/**'
 
 # 数据源

+ 2 - 1
pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/filter/PasswordDecoderFilter.java

@@ -21,6 +21,7 @@ import cn.hutool.core.codec.Base64;
 import cn.hutool.core.util.CharsetUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.http.HttpUtil;
+import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.cloud.gateway.filter.GatewayFilter;
@@ -65,7 +66,7 @@ public class PasswordDecoderFilter extends AbstractGatewayFilterFactory {
 			ServerHttpRequest request = exchange.getRequest();
 
 			// 不是登录请求,直接向下执行
-			if (!StrUtil.containsAnyIgnoreCase(request.getURI().getPath(), ValidateCodeGatewayFilter.OAUTH_TOKEN_URL)) {
+			if (!StrUtil.containsAnyIgnoreCase(request.getURI().getPath(), SecurityConstants.OAUTH_TOKEN_URL)) {
 				return chain.filter(exchange);
 			}
 

+ 8 - 7
pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/filter/ValidateCodeGatewayFilter.java

@@ -23,6 +23,7 @@ import cn.hutool.core.util.StrUtil;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.pig4cloud.pigx.common.core.constant.CommonConstant;
+import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
 import com.pig4cloud.pigx.common.core.exception.CheckedException;
 import com.pig4cloud.pigx.common.core.exception.ValidateCodeException;
 import com.pig4cloud.pigx.common.core.util.R;
@@ -50,7 +51,6 @@ import java.io.IOException;
 @Component
 @AllArgsConstructor
 public class ValidateCodeGatewayFilter extends AbstractGatewayFilterFactory {
-	static final String OAUTH_TOKEN_URL = "/oauth/token";
 	private static final String BASIC_ = "Basic ";
 	private final ObjectMapper objectMapper;
 	private final RedisTemplate redisTemplate;
@@ -109,17 +109,18 @@ public class ValidateCodeGatewayFilter extends AbstractGatewayFilterFactory {
 			ServerHttpRequest request = exchange.getRequest();
 
 			// 不是登录请求,直接向下执行
-			if (!StrUtil.containsAnyIgnoreCase(request.getURI().getPath(), OAUTH_TOKEN_URL)) {
+			if (!StrUtil.containsAnyIgnoreCase(request.getURI().getPath()
+				, SecurityConstants.OAUTH_TOKEN_URL, SecurityConstants.SMS_TOKEN_URL)) {
 				return chain.filter(exchange);
 			}
 
 			// 终端设置不校验, 直接向下执行(1. 从请求参数中获取 2.从header取)
 			String clientId = request.getQueryParams().getFirst("client_id");
-			if (StrUtil.isNotBlank(clientId)) {
-				if (filterIgnorePropertiesConfig.getClients().contains(clientId)) {
-					return chain.filter(exchange);
-				}
+			if (StrUtil.isNotBlank(clientId)
+				&& filterIgnorePropertiesConfig.getClients().contains(clientId)) {
+				return chain.filter(exchange);
 			}
+
 			try {
 				String[] clientInfos = extractAndDecodeHeader(request);
 				if (filterIgnorePropertiesConfig.getClients().contains(clientInfos[0])) {
@@ -158,7 +159,7 @@ public class ValidateCodeGatewayFilter extends AbstractGatewayFilterFactory {
 
 		String randomStr = request.getQueryParams().getFirst("randomStr");
 		if (StrUtil.isBlank(randomStr)) {
-			throw new ValidateCodeException();
+			randomStr = request.getQueryParams().getFirst("mobile");
 		}
 
 		String key = CommonConstant.DEFAULT_CODE_KEY + randomStr;

+ 12 - 7
pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysSocialDetails.java

@@ -82,11 +82,16 @@ public class SysSocialDetails extends Model<SysSocialDetails> {
 	@TableLogic
 	private String delFlag;
 
-  /**
-   * 主键值
-   */
-  @Override
-  protected Serializable pkVal() {
-    return this.id;
-  }
+	/**
+	 * 租户ID
+	 */
+	private Integer tenantId;
+
+	/**
+	 * 主键值
+	 */
+	@Override
+	protected Serializable pkVal() {
+		return this.id;
+	}
 }

+ 1 - 1
pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteUserService.java

@@ -50,7 +50,7 @@ public interface RemoteUserService {
 		, @RequestHeader(SecurityConstants.FROM) String from);
 
 	/**
-	 * 通过社交账号查询用户、角色信息
+	 * 通过社交账号或手机号查询用户、角色信息
 	 *
 	 * @param inStr appid@code
 	 * @return

+ 2 - 3
pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysSocialDetailsController.java

@@ -111,15 +111,14 @@ public class SysSocialDetailsController {
 	}
 
 	/**
-	 * 通过社交账号查询用户、角色信息
+	 * 通过社交账号、手机号查询用户、角色信息
 	 *
 	 * @param inStr appid@code
 	 * @return
 	 */
 	@GetMapping("/info/{inStr}")
 	public R<UserInfo> social(@PathVariable String inStr) {
-		Map<String, String> result = sysSocialDetailsService.findOpenId(inStr);
-		return new R<>(sysUserService.findUserInfo(result.get("type"), result.get("openId")));
+		return new R<>(sysSocialDetailsService.findUserInfo(inStr));
 	}
 
 	/**

+ 7 - 2
pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/UserController.java

@@ -30,7 +30,6 @@ import com.pig4cloud.pigx.admin.api.vo.UserVO;
 import com.pig4cloud.pigx.admin.service.SysUserService;
 import com.pig4cloud.pigx.common.core.constant.CommonConstant;
 import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
-import com.pig4cloud.pigx.common.core.constant.enums.EnumLoginType;
 import com.pig4cloud.pigx.common.core.util.Query;
 import com.pig4cloud.pigx.common.core.util.R;
 import com.pig4cloud.pigx.common.log.annotation.SysLog;
@@ -81,7 +80,13 @@ public class UserController {
 			username = SecurityUtils.getUser().getUsername();
 		}
 
-		return new R<>(userService.findUserInfo(EnumLoginType.PWD.getType(), username));
+		SysUser condition = new SysUser();
+		condition.setUsername(username);
+		SysUser sysUser = userService.selectOne(new EntityWrapper<>(condition));
+		if (sysUser == null) {
+			return new R<>();
+		}
+		return new R<>(userService.findUserInfo(sysUser));
 	}
 
 	/**

+ 39 - 0
pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/AbstractLoginHandler.java

@@ -0,0 +1,39 @@
+/*
+ *    Copyright (c) 2018-2025, lengleng All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the pig4cloud.com developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: lengleng (wangiegie@gmail.com)
+ */
+
+package com.pig4cloud.pigx.admin.handler;
+
+import com.pig4cloud.pigx.admin.api.dto.UserInfo;
+
+/**
+ * @author lengleng
+ * @date 2018/11/18
+ */
+public abstract class AbstractLoginHandler implements LoginHandler {
+
+	/**
+	 * 处理方法
+	 *
+	 * @param loginStr 登录参数
+	 * @return
+	 */
+	@Override
+	public UserInfo handle(String loginStr) {
+		String identify = identify(loginStr);
+		return info(identify);
+	}
+}

+ 53 - 0
pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/LoginHandler.java

@@ -0,0 +1,53 @@
+/*
+ *    Copyright (c) 2018-2025, lengleng All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the pig4cloud.com developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: lengleng (wangiegie@gmail.com)
+ */
+
+package com.pig4cloud.pigx.admin.handler;
+
+import com.pig4cloud.pigx.admin.api.dto.UserInfo;
+
+/**
+ * @author lengleng
+ * @date 2018/11/18
+ * <p>
+ * 登录处理器
+ */
+public interface LoginHandler {
+
+	/**
+	 * 通过用户传入获取唯一标识
+	 *
+	 * @param loginStr
+	 * @return
+	 */
+	String identify(String loginStr);
+
+	/**
+	 * 通过openId 获取用户信息
+	 *
+	 * @param identify
+	 * @return
+	 */
+	UserInfo info(String identify);
+
+	/**
+	 * 处理方法
+	 *
+	 * @param loginStr 登录参数
+	 * @return
+	 */
+	UserInfo handle(String loginStr);
+}

+ 69 - 0
pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/SmsLoginHandler.java

@@ -0,0 +1,69 @@
+/*
+ *    Copyright (c) 2018-2025, lengleng All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the pig4cloud.com developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: lengleng (wangiegie@gmail.com)
+ */
+
+package com.pig4cloud.pigx.admin.handler;
+
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.pig4cloud.pigx.admin.api.dto.UserInfo;
+import com.pig4cloud.pigx.admin.api.entity.SysUser;
+import com.pig4cloud.pigx.admin.service.SysUserService;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author lengleng
+ * @date 2018/11/18
+ */
+@Slf4j
+@Component("SMS")
+@AllArgsConstructor
+public class SmsLoginHandler extends AbstractLoginHandler {
+	private final SysUserService sysUserService;
+
+	/**
+	 * 验证码登录传入为手机号
+	 * 不用不处理
+	 *
+	 * @param mobile
+	 * @return
+	 */
+	@Override
+	public String identify(String mobile) {
+		return mobile;
+	}
+
+	/**
+	 * 通过mobile 获取用户信息
+	 *
+	 * @param identify
+	 * @return
+	 */
+	@Override
+	public UserInfo info(String identify) {
+		SysUser condition = new SysUser();
+		condition.setPhone(identify);
+		SysUser sysUser = sysUserService
+			.selectOne(new EntityWrapper<>(condition));
+
+		if (sysUser == null) {
+			log.info("手机号未注册:{}", identify);
+			return null;
+		}
+		return sysUserService.findUserInfo(sysUser);
+	}
+}

+ 88 - 0
pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/WeChatLoginHandler.java

@@ -0,0 +1,88 @@
+/*
+ *    Copyright (c) 2018-2025, lengleng All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the pig4cloud.com developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: lengleng (wangiegie@gmail.com)
+ */
+
+package com.pig4cloud.pigx.admin.handler;
+
+import cn.hutool.json.JSONUtil;
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.pig4cloud.pigx.admin.api.dto.UserInfo;
+import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails;
+import com.pig4cloud.pigx.admin.api.entity.SysUser;
+import com.pig4cloud.pigx.admin.mapper.SysSocialDetailsMapper;
+import com.pig4cloud.pigx.admin.service.SysUserService;
+import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
+import com.pig4cloud.pigx.common.core.constant.enums.EnumLoginType;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * @author lengleng
+ * @date 2018/11/18
+ */
+@Slf4j
+@Component("WX")
+@AllArgsConstructor
+public class WeChatLoginHandler extends AbstractLoginHandler {
+	private final RestTemplate restTemplate;
+	private final SysUserService sysUserService;
+	private final SysSocialDetailsMapper sysSocialDetailsMapper;
+
+	/**
+	 * 微信登录传入code
+	 * <p>
+	 * 通过code 调用qq 获取唯一标识
+	 *
+	 * @param code
+	 * @return
+	 */
+	@Override
+	public String identify(String code) {
+		SysSocialDetails condition = new SysSocialDetails();
+		condition.setType(EnumLoginType.WECHAT.getType());
+		SysSocialDetails socialDetails = sysSocialDetailsMapper.selectOne(condition);
+
+		String url = String.format(SecurityConstants.WX_AUTHORIZATION_CODE_URL
+			, socialDetails.getAppId(), socialDetails.getAppSecret(), code);
+		String result = restTemplate.getForObject(url, String.class);
+		log.debug("微信响应报文:{}", result);
+
+		Object obj = JSONUtil.parseObj(result).get("openid");
+		return obj.toString();
+	}
+
+	/**
+	 * openId 获取用户信息
+	 *
+	 * @param openId
+	 * @return
+	 */
+	@Override
+	public UserInfo info(String openId) {
+		SysUser condition = new SysUser();
+		condition.setWxOpenid(openId);
+		SysUser sysUser = sysUserService
+			.selectOne(new EntityWrapper<>(condition));
+
+		if (sysUser == null) {
+			log.info("微信未绑定:{}", openId);
+			return null;
+		}
+		return sysUserService.findUserInfo(sysUser);
+	}
+}

+ 4 - 5
pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysSocialDetailsService.java

@@ -18,10 +18,9 @@
 package com.pig4cloud.pigx.admin.service;
 
 import com.baomidou.mybatisplus.service.IService;
+import com.pig4cloud.pigx.admin.api.dto.UserInfo;
 import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails;
 
-import java.util.Map;
-
 /**
  * 系统社交登录账号表
  *
@@ -40,11 +39,11 @@ public interface SysSocialDetailsService extends IService<SysSocialDetails> {
 	Boolean bindSocial(String state, String code);
 
 	/**
-	 * 通过客户端信息查询openId
+	 * 根据入参查询用户信息
 	 *
-	 * @param inStr appid @ code
+	 * @param inStr
 	 * @return
 	 */
-	Map<String, String> findOpenId(String inStr);
+	UserInfo findUserInfo(String inStr);
 }
 

+ 2 - 3
pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysUserService.java

@@ -38,11 +38,10 @@ public interface SysUserService extends IService<SysUser> {
 	/**
 	 * 查询用户信息
 	 *
-	 * @param type     类型
-	 * @param username 用户名
+	 * @param sysUser 用户
 	 * @return userInfo
 	 */
-	UserInfo findUserInfo(String type, String username);
+	UserInfo findUserInfo(SysUser sysUser);
 
 	/**
 	 * 分页查询用户信息(含有角色信息)

+ 4 - 2
pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/MobileServiceImpl.java

@@ -25,6 +25,7 @@ import com.pig4cloud.pigx.admin.mapper.SysUserMapper;
 import com.pig4cloud.pigx.admin.service.MobileService;
 import com.pig4cloud.pigx.common.core.constant.CommonConstant;
 import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
+import com.pig4cloud.pigx.common.core.constant.enums.EnumLoginType;
 import com.pig4cloud.pigx.common.core.util.R;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -75,8 +76,9 @@ public class MobileServiceImpl implements MobileService {
 
 		String code = RandomUtil.randomNumbers(Integer.parseInt(SecurityConstants.CODE_SIZE));
 		log.debug("手机号生成验证码成功:{},{}", mobile, code);
-		redisTemplate.opsForValue().set(CommonConstant.DEFAULT_CODE_KEY + mobile, code
-			, SecurityConstants.CODE_TIME, TimeUnit.SECONDS);
+		redisTemplate.opsForValue().set(
+			CommonConstant.DEFAULT_CODE_KEY + EnumLoginType.SMS.getType() + "@" + mobile
+			, code, SecurityConstants.CODE_TIME, TimeUnit.SECONDS);
 		return new R<>(Boolean.TRUE, code);
 	}
 }

+ 4 - 1
pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysDeptRelationServiceImpl.java

@@ -19,6 +19,7 @@
 
 package com.pig4cloud.pigx.admin.service.impl;
 
+import cn.hutool.core.collection.CollUtil;
 import com.baomidou.mybatisplus.mapper.EntityWrapper;
 import com.baomidou.mybatisplus.service.impl.ServiceImpl;
 import com.pig4cloud.pigx.admin.api.entity.SysDept;
@@ -62,7 +63,9 @@ public class SysDeptRelationServiceImpl extends ServiceImpl<SysDeptRelationMappe
 				relation.setDescendant(sysDept.getDeptId());
 				return relation;
 			}).collect(Collectors.toList());
-		this.insertBatch(relationList);
+		if (CollUtil.isNotEmpty(relationList)) {
+			this.insertBatch(relationList);
+		}
 
 		//自己也要维护到关系表中
 		SysDeptRelation own = new SysDeptRelation();

+ 15 - 1
pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysDeptServiceImpl.java

@@ -19,6 +19,7 @@
 
 package com.pig4cloud.pigx.admin.service.impl;
 
+import cn.hutool.core.collection.CollUtil;
 import com.baomidou.mybatisplus.mapper.EntityWrapper;
 import com.baomidou.mybatisplus.service.impl.ServiceImpl;
 import com.pig4cloud.pigx.admin.api.dto.DeptTree;
@@ -75,7 +76,20 @@ public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> impl
 	@Override
 	@Transactional(rollbackFor = Exception.class)
 	public Boolean deleteDeptById(Integer id) {
-		this.deleteById(id);
+		//级联删除部门
+		SysDeptRelation condition = new SysDeptRelation();
+		condition.setAncestor(id);
+		List<Integer> idList = sysDeptRelationService
+			.selectList(new EntityWrapper<>(condition))
+			.stream()
+			.map(SysDeptRelation::getDescendant)
+			.collect(Collectors.toList());
+
+		if (CollUtil.isNotEmpty(idList)) {
+			this.deleteBatchIds(idList);
+		}
+
+		//删除部门级联关系
 		sysDeptRelationService.deleteAllDeptRealtion(id);
 		return Boolean.TRUE;
 	}

+ 17 - 12
pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysSocialDetailsServiceImpl.java

@@ -19,8 +19,10 @@ package com.pig4cloud.pigx.admin.service.impl;
 
 import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.service.impl.ServiceImpl;
+import com.pig4cloud.pigx.admin.api.dto.UserInfo;
 import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails;
 import com.pig4cloud.pigx.admin.api.entity.SysUser;
+import com.pig4cloud.pigx.admin.handler.LoginHandler;
 import com.pig4cloud.pigx.admin.mapper.SysSocialDetailsMapper;
 import com.pig4cloud.pigx.admin.mapper.SysUserMapper;
 import com.pig4cloud.pigx.admin.service.SysSocialDetailsService;
@@ -44,22 +46,11 @@ import java.util.Map;
 @AllArgsConstructor
 @Service("sysSocialDetailsService")
 public class SysSocialDetailsServiceImpl extends ServiceImpl<SysSocialDetailsMapper, SysSocialDetails> implements SysSocialDetailsService {
+	private final Map<String, LoginHandler> loginHandlerMap;
 	private final CacheManager cacheManager;
 	private final RestTemplate restTemplate;
 	private final SysUserMapper sysUserMapper;
 
-	/**
-	 * 通过客户端信息查询openId
-	 *
-	 * @param inStr appid @ code
-	 * @return
-	 */
-	@Override
-	public Map<String, String> findOpenId(String inStr) {
-		String[] inStrs = inStr.split("@");
-		return getOpenId(inStrs[0], inStrs[1]);
-	}
-
 	/**
 	 * 绑定社交账号
 	 *
@@ -80,6 +71,20 @@ public class SysSocialDetailsServiceImpl extends ServiceImpl<SysSocialDetailsMap
 		return Boolean.TRUE;
 	}
 
+	/**
+	 * 根据入参查询用户信息
+	 *
+	 * @param inStr TYPE@code
+	 * @return
+	 */
+	@Override
+	public UserInfo findUserInfo(String inStr) {
+		String[] inStrs = inStr.split("@");
+		String type = inStrs[0];
+		String loginStr = inStrs[1];
+		return loginHandlerMap.get(type).handle(loginStr);
+	}
+
 	/**
 	 * 通过appid 、code 获得openID
 	 *

+ 4 - 14
pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysUserServiceImpl.java

@@ -31,7 +31,6 @@ import com.pig4cloud.pigx.admin.api.vo.MenuVO;
 import com.pig4cloud.pigx.admin.api.vo.UserVO;
 import com.pig4cloud.pigx.admin.mapper.SysUserMapper;
 import com.pig4cloud.pigx.admin.service.*;
-import com.pig4cloud.pigx.common.core.constant.enums.EnumLoginType;
 import com.pig4cloud.pigx.common.core.datascope.DataScope;
 import com.pig4cloud.pigx.common.core.util.Query;
 import com.pig4cloud.pigx.common.core.util.R;
@@ -68,23 +67,14 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
 	private final SysDeptRelationService sysDeptRelationService;
 
 	/**
-	 * 通过用户名查用户的全部信息
+	 * 通过查用户的全部信息
 	 *
-	 * @param username 用户名
+	 * @param sysUser 用户
 	 * @return
 	 */
 	@Override
-	@Cacheable(value = "user_details", key = "#username", unless = "#result == null")
-	public UserInfo findUserInfo(String type, String username) {
-		SysUser condition = new SysUser();
-		if (EnumLoginType.PWD.getType().equals(type)) {
-			condition.setUsername(username);
-		} else if (EnumLoginType.WECHAT.getType().equals(type)) {
-			condition.setWxOpenid(username);
-		} else {
-			condition.setQqOpenid(username);
-		}
-		SysUser sysUser = this.selectOne(new EntityWrapper<>(condition));
+	@Cacheable(value = "user_details", key = "#sysUser.username", unless = "#result == null")
+	public UserInfo findUserInfo(SysUser sysUser) {
 		if (sysUser == null) {
 			return null;
 		}