diff --git a/seer-gateway/pom.xml b/seer-gateway/pom.xml
index d408cd2..4361787 100644
--- a/seer-gateway/pom.xml
+++ b/seer-gateway/pom.xml
@@ -75,8 +75,7 @@
${basedir}/src/main/resources
- **.xml
- **.yml
+ **
diff --git a/seer-gateway/src/main/java/com/seer/teach/filter/cors/CorsConfig.java b/seer-gateway/src/main/java/com/seer/teach/filter/cors/CorsConfig.java
new file mode 100644
index 0000000..d763c24
--- /dev/null
+++ b/seer-gateway/src/main/java/com/seer/teach/filter/cors/CorsConfig.java
@@ -0,0 +1,49 @@
+package com.seer.teach.filter.cors;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.reactive.CorsWebFilter;
+import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
+import org.springframework.web.util.pattern.PathPatternParser;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Configuration
+public class CorsConfig {
+
+ @Bean
+ @ConfigurationProperties(prefix = "zs.cors")
+ public Cors cors() {
+ return new Cors();
+ }
+
+ @Bean
+ public CorsWebFilter corsWebFilter(Cors cors) {
+ CorsConfiguration config = new CorsConfiguration();
+ config.setAllowedOriginPatterns(cors.getOrigins());
+ // 允许的HTTP方法
+ config.addAllowedMethod("*");
+ // 允许的请求头
+ config.addAllowedHeader("*");
+ config.setAllowCredentials(true);
+ // 暴露的响应头
+ config.addExposedHeader("token");
+ config.addExposedHeader("Content-Disposition");
+ config.setMaxAge(3600L);
+ UrlBasedCorsConfigurationSource source =
+ new UrlBasedCorsConfigurationSource(new PathPatternParser());
+ source.registerCorsConfiguration("/**", config);
+ return new CorsWebFilter(source);
+ }
+
+ @Getter
+ @Setter
+ public static class Cors {
+ private List origins = new ArrayList<>();
+ }
+}
diff --git a/seer-gateway/src/main/java/com/seer/teach/filter/cors/CorsFilter.java b/seer-gateway/src/main/java/com/seer/teach/filter/cors/CorsFilter.java
index 3aaa01b..eadb9b8 100644
--- a/seer-gateway/src/main/java/com/seer/teach/filter/cors/CorsFilter.java
+++ b/seer-gateway/src/main/java/com/seer/teach/filter/cors/CorsFilter.java
@@ -1,8 +1,10 @@
package com.seer.teach.filter.cors;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
+import org.springframework.http.server.RequestPath;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
@@ -13,7 +15,7 @@ import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;
-
+@Slf4j
@Component
public class CorsFilter implements WebFilter {
@@ -23,17 +25,21 @@ public class CorsFilter implements WebFilter {
public Mono filter(ServerWebExchange exchange, WebFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
if (!CorsUtils.isCorsRequest(request)) {
+ log.info("Not a CORS request");
return chain.filter(exchange);
}
-
+ RequestPath path = exchange.getRequest().getPath();
+ log.info("request path: {},method : {}", path, request.getMethod());
ServerHttpResponse response = exchange.getResponse();
HttpHeaders headers = response.getHeaders();
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, CorsConfiguration.ALL);
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, CorsConfiguration.ALL);
+ headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, CorsConfiguration.ALL);
headers.add(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS, CorsConfiguration.ALL);
headers.add(HttpHeaders.ACCESS_CONTROL_MAX_AGE, MAX_AGE);
if (request.getMethod() == HttpMethod.OPTIONS) {
response.setStatusCode(HttpStatus.OK);
+ log.info("CORS preflight request,OK");
return Mono.empty();
}
return chain.filter(exchange);
diff --git a/seer-gateway/src/main/java/com/seer/teach/filter/cors/CorsResponseHeaderFilter.java b/seer-gateway/src/main/java/com/seer/teach/filter/cors/CorsResponseHeaderFilter.java
new file mode 100644
index 0000000..fe9f19f
--- /dev/null
+++ b/seer-gateway/src/main/java/com/seer/teach/filter/cors/CorsResponseHeaderFilter.java
@@ -0,0 +1,50 @@
+package com.seer.teach.filter.cors;
+
+import org.springframework.cloud.gateway.filter.GatewayFilterChain;
+import org.springframework.cloud.gateway.filter.GlobalFilter;
+import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;
+import org.springframework.core.Ordered;
+import org.springframework.http.HttpHeaders;
+import org.springframework.stereotype.Component;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * 解决 Spring Cloud Gateway 2.x 跨域时,出现重复 Origin 的 BUG
+ *
+ * 参考文档:
+ *
+ */
+@Component
+public class CorsResponseHeaderFilter implements GlobalFilter, Ordered {
+
+ @Override
+ public int getOrder() {
+ return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER + 1;
+ }
+
+ @Override
+ public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
+ return chain.filter(exchange).then(Mono.defer(() -> {
+ List keysToModify = exchange.getResponse().getHeaders().entrySet().stream()
+ .filter(kv -> (kv.getValue() != null && kv.getValue().size() > 1))
+ .filter(kv -> (kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)
+ || kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS)))
+ .map(Map.Entry::getKey)
+ .collect(Collectors.toList());
+ keysToModify.forEach(key->{
+ List values = exchange.getResponse().getHeaders().get(key);
+ if (values != null && !values.isEmpty()) {
+ exchange.getResponse().getHeaders().put(key, Collections.singletonList(values.get(0)));
+ }
+ });
+ return chain.filter(exchange);
+ }));
+ }
+
+}
diff --git a/seer-gateway/src/main/resources/application.yml b/seer-gateway/src/main/resources/application.yml
index f84994c..631cf5b 100644
--- a/seer-gateway/src/main/resources/application.yml
+++ b/seer-gateway/src/main/resources/application.yml
@@ -81,4 +81,22 @@ logging:
level:
org.springframework.cloud.gateway: DEBUG # 查看 Gateway 过滤器链
org.springframework.security: DEBUG # 检查 Spring Security 拦截
- reactor.netty.http.client: DEBUG # 查看网络层交互
\ No newline at end of file
+ reactor.netty.http.client: DEBUG # 查看网络层交互
+
+
+zs:
+ decryption:
+ enabled: true
+ encryption:
+ enabled: true
+ cors:
+ origins:
+ - http://localhost:*
+ - http://192.168.*:*
+ - http://10.10.*:*
+ - http://10.10.4.143:8020
+ - http://10.10.3.134:8020
+ - https://admin-api.seerteach.net:*
+ - http://admin-api.seerteach.net:*
+ - https://admin.seerteach.net:*
+ - https://admin.seerteach.net
\ No newline at end of file
diff --git a/seer-mp/seer-mp-service-admin/src/main/java/com/seer/teach/mp/admin/controller/AdminMpAccountController.java b/seer-mp/seer-mp-service-admin/src/main/java/com/seer/teach/mp/admin/controller/AdminMpAccountController.java
index 6ca8c03..73dace7 100644
--- a/seer-mp/seer-mp-service-admin/src/main/java/com/seer/teach/mp/admin/controller/AdminMpAccountController.java
+++ b/seer-mp/seer-mp-service-admin/src/main/java/com/seer/teach/mp/admin/controller/AdminMpAccountController.java
@@ -76,7 +76,7 @@ public class AdminMpAccountController {
@PostMapping("/generate-qr-code")
@Operation(summary = "生成公众号二维码")
@SaCheckPermission("admin:mp:account:qr-code'")
- public ResultBean generateAccountQrCode(@RequestParam("id") Integer id) {
- return ResultBean.success(mpAccountService.generateAccountQrCode(id));
+ public ResultBean generateAccountQrCode(@RequestParam("id") Integer id,@RequestParam("场景值") String sceneStr) {
+ return ResultBean.success(mpAccountService.generateAccountQrCode(id,sceneStr));
}
}
\ No newline at end of file
diff --git a/seer-mp/seer-mp-service-admin/src/main/java/com/seer/teach/mp/admin/service/AdminMpAccountService.java b/seer-mp/seer-mp-service-admin/src/main/java/com/seer/teach/mp/admin/service/AdminMpAccountService.java
index c755dbb..df97661 100644
--- a/seer-mp/seer-mp-service-admin/src/main/java/com/seer/teach/mp/admin/service/AdminMpAccountService.java
+++ b/seer-mp/seer-mp-service-admin/src/main/java/com/seer/teach/mp/admin/service/AdminMpAccountService.java
@@ -141,12 +141,12 @@ public class AdminMpAccountService {
* @param id 公众号账号ID
* @return 是否生成成功
*/
- public Boolean generateAccountQrCode(Integer id) {
+ public Boolean generateAccountQrCode(Integer id,String sceneStr) {
MpAccountEntity account = mpAccountService.getById(id);
WxMpService mpService = mpServiceFactory.getRequiredMpService(account.getAppId());
String qrCodeUrl;
try {
- WxMpQrCodeTicket qrCodeTicket = mpService.getQrcodeService().qrCodeCreateLastTicket("default");
+ WxMpQrCodeTicket qrCodeTicket = mpService.getQrcodeService().qrCodeCreateLastTicket(sceneStr);
qrCodeUrl = mpService.getQrcodeService().qrCodePictureUrl(qrCodeTicket.getTicket());
} catch (WxErrorException e) {
log.error("生成公众号二维码失败", e);
diff --git a/seer-mp/seer-mp-service-app/src/main/java/com/seer/teach/mp/app/controller/req/MpGenerateQrCodeReq.java b/seer-mp/seer-mp-service-app/src/main/java/com/seer/teach/mp/app/controller/req/MpGenerateQrCodeReq.java
index 1f5fadc..f73fe0e 100644
--- a/seer-mp/seer-mp-service-app/src/main/java/com/seer/teach/mp/app/controller/req/MpGenerateQrCodeReq.java
+++ b/seer-mp/seer-mp-service-app/src/main/java/com/seer/teach/mp/app/controller/req/MpGenerateQrCodeReq.java
@@ -7,7 +7,12 @@ import lombok.Data;
@Data
public class MpGenerateQrCodeReq {
- private String userId;
+ @Schema(description = "场景值")
+ private String sceneStr;
+ @Schema(description = "小程序appid")
private String appId;
-}
+
+ @Schema(description = "二维码类型 1-临时 2-永久")
+ private Integer type;
+}
\ No newline at end of file
diff --git a/seer-mp/seer-mp-service-app/src/main/java/com/seer/teach/mp/app/service/AppOfficialQrCodeService.java b/seer-mp/seer-mp-service-app/src/main/java/com/seer/teach/mp/app/service/AppOfficialQrCodeService.java
index 4ea30ed..acf420f 100644
--- a/seer-mp/seer-mp-service-app/src/main/java/com/seer/teach/mp/app/service/AppOfficialQrCodeService.java
+++ b/seer-mp/seer-mp-service-app/src/main/java/com/seer/teach/mp/app/service/AppOfficialQrCodeService.java
@@ -8,6 +8,7 @@ import com.seer.teach.mp.factory.MpServiceFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.mp.api.WxMpQrcodeService;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket;
import org.springframework.beans.factory.annotation.Value;
@@ -30,8 +31,14 @@ public class AppOfficialQrCodeService {
WxMpService wxMpService = mpServiceFactory.getRequiredMpService(req.getAppId());
Integer expireSeconds = mpQrCodeExpireTime * 60 *60;
- WxMpQrCodeTicket ticket = wxMpService.getQrcodeService().qrCodeCreateTmpTicket(req.getUserId(), expireSeconds);;
+ WxMpQrcodeService qrcodeService = wxMpService.getQrcodeService();
+ WxMpQrCodeTicket ticket;
+ if(req.getType() == 1) {
+ ticket = qrcodeService.qrCodeCreateTmpTicket(req.getSceneStr(), expireSeconds);
+ }else{
+ ticket = qrcodeService.qrCodeCreateLastTicket(req.getSceneStr());
+ }
String qrCodeUrl = wxMpService.getQrcodeService().qrCodePictureUrl(ticket.getTicket());
MpQrCodeResp resp = new MpQrCodeResp();
diff --git a/seer-user/seer-user-service-app-bootstrap/src/main/resources/application.yml b/seer-user/seer-user-service-app-bootstrap/src/main/resources/application.yml
index 5830cae..b79c372 100644
--- a/seer-user/seer-user-service-app-bootstrap/src/main/resources/application.yml
+++ b/seer-user/seer-user-service-app-bootstrap/src/main/resources/application.yml
@@ -48,4 +48,8 @@ zs:
decryption:
enabled: false
encryption:
- enabled: false
\ No newline at end of file
+ enabled: false
+ cors:
+ origins:
+ - http://10.10.3.134:8020
+ - http://10.10.4.143:8020
\ No newline at end of file
diff --git a/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/LoginType.java b/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/LoginType.java
index 229a7a5..6fa7ef0 100644
--- a/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/LoginType.java
+++ b/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/LoginType.java
@@ -22,7 +22,12 @@ public enum LoginType {
/**
* 仓库登录
*/
- WAREHOUSE_ACCOUNT("warehouse_account", "仓库登录");
+ WAREHOUSE_ACCOUNT("warehouse_account", "仓库登录"),
+
+ /**
+ * 微信公众号账号密码登录
+ */
+ WECHAT_OAUTH_WITH_ACCOUNT("wechat_oauth_with_account", "微信公众号账号密码登录");
private String code;
diff --git a/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/controller/AppAuthController.java b/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/controller/AppAuthController.java
index 88142f6..95b4250 100644
--- a/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/controller/AppAuthController.java
+++ b/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/controller/AppAuthController.java
@@ -10,7 +10,7 @@ import com.seer.teach.common.annotation.EncryptionAnnotation;
import com.seer.teach.common.annotation.LogOperation;
import com.seer.teach.common.annotation.LogPrint;
import com.seer.teach.common.enums.ModuleEnum;
-import com.seer.teach.user.app.auth.request.WeChatLoginParam;
+import com.seer.teach.user.app.auth.request.LoginParam;
import com.seer.teach.user.app.auth.response.LoginResp;
import com.seer.teach.user.app.auth.service.AppAuthService;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -37,7 +37,7 @@ public class AppAuthController {
private AppAuthService userAuthService;
@PostMapping("/login")
- public ResultBean login(@RequestBody WeChatLoginParam request) {
+ public ResultBean login(@RequestBody LoginParam request) {
return ResultBean.success(userAuthService.authenticate(request));
}
diff --git a/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/request/WeChatLoginParam.java b/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/request/LoginParam.java
similarity index 72%
rename from seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/request/WeChatLoginParam.java
rename to seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/request/LoginParam.java
index b4041c8..641f819 100644
--- a/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/request/WeChatLoginParam.java
+++ b/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/request/LoginParam.java
@@ -2,24 +2,24 @@ package com.seer.teach.user.app.auth.request;
import com.seer.teach.user.app.auth.LoginType;
import io.swagger.v3.oas.annotations.media.Schema;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.*;
-
import jakarta.validation.constraints.NotBlank;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
-/**
- * @Author: Captain
- * @Description: 微信小程序登录请求参数
- * @Date: 2025-05-19 17:46
- */
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Builder
-@Schema(description = "微信登录请求实体类")
-public class WeChatLoginParam {
+@Schema(description = "登录请求实体类")
+public class LoginParam {
+ @Schema(description = "登录方式不可为空")
+ @NotBlank(message = "loginType不可为空")
LoginType loginType;
@Schema(description = "jsCode不可为空")
diff --git a/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/AppAuthService.java b/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/AppAuthService.java
index 8aae263..eccd194 100644
--- a/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/AppAuthService.java
+++ b/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/AppAuthService.java
@@ -5,7 +5,7 @@ import cn.hutool.core.collection.CollectionUtil;
import com.seer.teach.common.enums.ResultCodeEnum;
import com.seer.teach.common.utils.AssertUtils;
import com.seer.teach.user.app.auth.LoginType;
-import com.seer.teach.user.app.auth.request.WeChatLoginParam;
+import com.seer.teach.user.app.auth.request.LoginParam;
import com.seer.teach.user.app.auth.response.LoginResp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -43,7 +43,7 @@ public class AppAuthService {
* @return
*/
@Transactional(rollbackFor = Exception.class,timeout = 120)
- public LoginResp authenticate(WeChatLoginParam request) {
+ public LoginResp authenticate(LoginParam request) {
LoginStrategy strategy = strategyMap.get(request.getLoginType());
AssertUtils.notNull(strategy, ResultCodeEnum.LOGIN_TYPE_ERROR);
diff --git a/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/LoginStrategy.java b/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/LoginStrategy.java
index c168623..0b8629d 100644
--- a/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/LoginStrategy.java
+++ b/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/LoginStrategy.java
@@ -1,7 +1,7 @@
package com.seer.teach.user.app.auth.service;
import com.seer.teach.user.app.auth.LoginType;
-import com.seer.teach.user.app.auth.request.WeChatLoginParam;
+import com.seer.teach.user.app.auth.request.LoginParam;
public interface LoginStrategy {
@@ -13,5 +13,5 @@ public interface LoginStrategy {
* @param request
* @return
*/
- LoginUser authenticate(WeChatLoginParam request);
+ LoginUser authenticate(LoginParam request);
}
diff --git a/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/LoginUser.java b/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/LoginUser.java
index 9429260..d8f45c4 100644
--- a/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/LoginUser.java
+++ b/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/LoginUser.java
@@ -2,6 +2,8 @@ package com.seer.teach.user.app.auth.service;
import lombok.Data;
+import java.util.List;
+
@Data
public class LoginUser {
@@ -17,6 +19,8 @@ public class LoginUser {
*/
private Integer applyStatus;
+ private List roles;
+
public LoginUser(Integer userId) {
this.userId = userId;
}
diff --git a/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/strategy/MiniProgramLoginStrategy.java b/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/strategy/MiniProgramLoginStrategy.java
index 6997e4b..66c3893 100644
--- a/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/strategy/MiniProgramLoginStrategy.java
+++ b/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/strategy/MiniProgramLoginStrategy.java
@@ -11,7 +11,7 @@ import com.seer.teach.common.utils.AssertUtils;
import com.seer.teach.mp.api.WechatMiniProgramApi;
import com.seer.teach.mp.api.resp.WxMiniProgramSessionDTO;
import com.seer.teach.user.app.auth.LoginType;
-import com.seer.teach.user.app.auth.request.WeChatLoginParam;
+import com.seer.teach.user.app.auth.request.LoginParam;
import com.seer.teach.user.app.auth.service.LoginStrategy;
import com.seer.teach.user.app.auth.service.LoginUser;
import com.seer.teach.user.entity.UserAuthEntity;
@@ -69,7 +69,7 @@ public class MiniProgramLoginStrategy extends AbstractLoginStrategy implements L
}
@Override
- public LoginUser authenticate(WeChatLoginParam request) {
+ public LoginUser authenticate(LoginParam request) {
WxMiniProgramSessionDTO wxMiniProgramSessionDTO = wechatMiniProgramApi.code2Session(request.getJsCode());
AssertUtils.isTrue(wxMiniProgramSessionDTO.isSuccess(), ResultCodeEnum.WX_OAUTH_USED_ERROR);
UserAuthEntity userAuth = userAuthService.getOneByOpenIdAndUnionId(wxMiniProgramSessionDTO.getOpenid(), wxMiniProgramSessionDTO.getUnionid());
@@ -156,7 +156,7 @@ public class MiniProgramLoginStrategy extends AbstractLoginStrategy implements L
* @param request 登录参数
* @return boolean true 是扫码登录,false 密码登录
*/
- private boolean isScanQrCodeLogin(WeChatLoginParam request) {
+ private boolean isScanQrCodeLogin(LoginParam request) {
if (!StringUtils.hasText(request.getScene())) {
return false;
}
diff --git a/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/strategy/OfficialAccountLoginStrategy.java b/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/strategy/OfficialAccountLoginStrategy.java
index e8f8b9a..113a22a 100644
--- a/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/strategy/OfficialAccountLoginStrategy.java
+++ b/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/strategy/OfficialAccountLoginStrategy.java
@@ -5,7 +5,7 @@ import com.seer.teach.common.utils.AssertUtils;
import com.seer.teach.mp.api.WechatOfficialAccountApi;
import com.seer.teach.mp.api.resp.WxOAuth2AccessTokenDTO;
import com.seer.teach.user.app.auth.LoginType;
-import com.seer.teach.user.app.auth.request.WeChatLoginParam;
+import com.seer.teach.user.app.auth.request.LoginParam;
import com.seer.teach.user.app.auth.service.LoginStrategy;
import com.seer.teach.user.app.auth.service.LoginUser;
import com.seer.teach.user.entity.UserAuthEntity;
@@ -28,7 +28,6 @@ public class OfficialAccountLoginStrategy extends AbstractLoginStrategy implemen
@Autowired
private WechatOfficialAccountApi wechatOfficialAccountApi;
-
@Autowired
private IUserService userService;
@@ -41,7 +40,7 @@ public class OfficialAccountLoginStrategy extends AbstractLoginStrategy implemen
}
@Override
- public LoginUser authenticate(WeChatLoginParam request) {
+ public LoginUser authenticate(LoginParam request) {
log.info("微信公众号登录:{}",request);
WxOAuth2AccessTokenDTO wxOAuth2AccessToken = wechatOfficialAccountApi.getUserWxOAuth2AccessToken(request.getAppId(), request.getJsCode());
log.debug("获取用户信息:{}",wxOAuth2AccessToken);
@@ -61,7 +60,8 @@ public class OfficialAccountLoginStrategy extends AbstractLoginStrategy implemen
}else{
userAuth.setAppId(request.getAppId());
updateUserAuth(userAuth);
+ LoginUser loginUser = new LoginUser(userAuth.getUserId());
+ return loginUser;
}
- return new LoginUser(userAuth.getUserId());
}
}
\ No newline at end of file
diff --git a/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/strategy/OfficialOauthWithAccountLoginStrategy.java b/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/strategy/OfficialOauthWithAccountLoginStrategy.java
new file mode 100644
index 0000000..9714a41
--- /dev/null
+++ b/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/strategy/OfficialOauthWithAccountLoginStrategy.java
@@ -0,0 +1,75 @@
+package com.seer.teach.user.app.auth.service.strategy;
+
+import cn.dev33.satoken.stp.StpUtil;
+import com.seer.teach.common.enums.ResultCodeEnum;
+import com.seer.teach.common.exception.CommonException;
+import com.seer.teach.common.utils.AssertUtils;
+import com.seer.teach.common.utils.CommonUtils;
+import com.seer.teach.mp.api.WechatOfficialAccountApi;
+import com.seer.teach.mp.api.resp.WxOAuth2AccessTokenDTO;
+import com.seer.teach.user.app.auth.LoginType;
+import com.seer.teach.user.app.auth.request.LoginParam;
+import com.seer.teach.user.app.auth.service.LoginStrategy;
+import com.seer.teach.user.app.auth.service.LoginUser;
+import com.seer.teach.user.entity.UserAuthEntity;
+import com.seer.teach.user.entity.UserEntity;
+import com.seer.teach.user.service.IUserService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Objects;
+
+/**
+ * 账号密码登录策略
+ * 实现传统的用户名/手机号和密码登录,并生成token
+ */
+@RequiredArgsConstructor
+@Service
+@Slf4j
+public class OfficialOauthWithAccountLoginStrategy extends AbstractLoginStrategy implements LoginStrategy {
+
+ private final IUserService userService;
+
+ @Autowired
+ private WechatOfficialAccountApi wechatOfficialAccountApi;
+
+ @Override
+ public LoginType getType() {
+ return LoginType.WECHAT_OAUTH_WITH_ACCOUNT;
+ }
+
+ @Override
+ public LoginUser authenticate(LoginParam request) {
+ UserEntity accountUser = null;
+ if (request.getUserName() != null && !request.getUserName().isEmpty()) {
+ accountUser = userService.getOneByUserName(request.getUserName());
+ } else if (request.getPhoneNumber() != null && !request.getPhoneNumber().isEmpty()) {
+ accountUser = userService.getOneByMobile(request.getPhoneNumber());
+ }
+ AssertUtils.notNull(accountUser, ResultCodeEnum.USERNAME_OR_PASSWORD_IS_ERROR);
+ String password = CommonUtils.encryptPassword(request.getPassword());
+ if (password.equals(accountUser.getPassword())) {
+ WxOAuth2AccessTokenDTO wxOAuth2AccessToken = wechatOfficialAccountApi.getUserWxOAuth2AccessToken(request.getAppId(), request.getJsCode());
+ log.debug("获取用户信息:{}",wxOAuth2AccessToken);
+ AssertUtils.notNull(wxOAuth2AccessToken, ResultCodeEnum.WX_OAUTH_USED_ERROR);
+ String userOpenId = wxOAuth2AccessToken.getOpenId();
+ UserAuthEntity userAuth = userAuthService.getOneByOpenId(userOpenId);
+ StpUtil.login(accountUser.getId());
+ if(Objects.isNull(userAuth)){
+ boolean userAuthSaved = saveUserAuth(getType().getCode(), accountUser.getId(), wxOAuth2AccessToken, request.getAppId());
+ log.info("保存用户授权信息:{}", userAuthSaved);
+ }else{
+ userAuth.setAppId(request.getAppId());
+ updateUserAuth(userAuth);
+ }
+ log.info("用户[{}]账号密码登录成功", accountUser.getId());
+ return new LoginUser(accountUser.getId());
+ }else{
+ log.info("用户[{}]账号密码登录失败", accountUser.getId());
+ throw new CommonException(ResultCodeEnum.USERNAME_OR_PASSWORD_IS_ERROR);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/strategy/WarehouseAccountLoginStrategy.java b/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/strategy/WarehouseAccountLoginStrategy.java
index b06251c..a3765d3 100644
--- a/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/strategy/WarehouseAccountLoginStrategy.java
+++ b/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/strategy/WarehouseAccountLoginStrategy.java
@@ -8,7 +8,7 @@ import com.seer.teach.common.utils.CommonUtils;
import com.seer.teach.mp.api.WechatOfficialAccountApi;
import com.seer.teach.mp.api.resp.WxOAuth2AccessTokenDTO;
import com.seer.teach.user.app.auth.LoginType;
-import com.seer.teach.user.app.auth.request.WeChatLoginParam;
+import com.seer.teach.user.app.auth.request.LoginParam;
import com.seer.teach.user.app.auth.service.LoginStrategy;
import com.seer.teach.user.app.auth.service.LoginUser;
import com.seer.teach.user.entity.RoleEntity;
@@ -52,7 +52,7 @@ public class WarehouseAccountLoginStrategy extends AbstractLoginStrategy impleme
}
@Override
- public LoginUser authenticate(WeChatLoginParam request) {
+ public LoginUser authenticate(LoginParam request) {
AssertUtils.notNull(request.getPassword(), ResultCodeEnum.USERNAME_OR_PASSWORD_IS_ERROR);
UserEntity accountUser = userService.getOneByUserName(request.getUserName());
AssertUtils.notNull(accountUser, ResultCodeEnum.USERNAME_OR_PASSWORD_IS_ERROR);
diff --git a/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/strategy/WechatChildrenAccountLoginStrategy.java b/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/strategy/WechatChildrenAccountLoginStrategy.java
index 44c0332..1c99f41 100644
--- a/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/strategy/WechatChildrenAccountLoginStrategy.java
+++ b/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/auth/service/strategy/WechatChildrenAccountLoginStrategy.java
@@ -9,7 +9,7 @@ import com.seer.teach.iot.api.UserDeviceServiceApi;
import com.seer.teach.mp.api.WechatMiniProgramApi;
import com.seer.teach.mp.api.resp.WxMiniProgramSessionDTO;
import com.seer.teach.user.app.auth.LoginType;
-import com.seer.teach.user.app.auth.request.WeChatLoginParam;
+import com.seer.teach.user.app.auth.request.LoginParam;
import com.seer.teach.user.app.auth.service.LoginStrategy;
import com.seer.teach.user.app.auth.service.LoginUser;
import com.seer.teach.user.entity.UserAuthEntity;
@@ -49,7 +49,7 @@ public class WechatChildrenAccountLoginStrategy extends AbstractLoginStrategy im
}
@Override
- public LoginUser authenticate(WeChatLoginParam request) {
+ public LoginUser authenticate(LoginParam request) {
UserEntity accountUser =userService.getOneByMobile(request.getPhoneNumber());
AssertUtils.notNull(accountUser, ResultCodeEnum.USERNAME_OR_PASSWORD_IS_ERROR);
String password = CommonUtils.encryptPassword(request.getPassword());
diff --git a/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/user/controller/resp/AppUserInfoResp.java b/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/user/controller/resp/AppUserInfoResp.java
index 2655c9b..55cf11b 100644
--- a/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/user/controller/resp/AppUserInfoResp.java
+++ b/seer-user/seer-user-service-app/src/main/java/com/seer/teach/user/app/user/controller/resp/AppUserInfoResp.java
@@ -55,4 +55,6 @@ public class AppUserInfoResp {
@Schema(description = "是否是主监护人")
private boolean isPrimaryGuardian;
+
+
}
\ No newline at end of file
diff --git a/seer-user/seer-user-service/src/main/java/com/seer/teach/user/service/IUserRoleService.java b/seer-user/seer-user-service/src/main/java/com/seer/teach/user/service/IUserRoleService.java
index d1ae265..c5b8236 100644
--- a/seer-user/seer-user-service/src/main/java/com/seer/teach/user/service/IUserRoleService.java
+++ b/seer-user/seer-user-service/src/main/java/com/seer/teach/user/service/IUserRoleService.java
@@ -18,8 +18,21 @@ import java.util.Set;
*/
public interface IUserRoleService extends IService {
+ /**
+ * 根据用户ID获取用户角色列表
+ *
+ * @param userId 用户ID
+ * @return 用户角色列表
+ */
List getListByUserId(Integer userId);
+ /**
+ * 获取用户角色编码列表
+ *
+ * @param userId 用户编号
+ * @return 角色编码列表
+ */
+ List getRoleCodeListByUserId(Integer userId);
/**
* 为用户分配角色
diff --git a/seer-user/seer-user-service/src/main/java/com/seer/teach/user/service/impl/UserRoleServiceImpl.java b/seer-user/seer-user-service/src/main/java/com/seer/teach/user/service/impl/UserRoleServiceImpl.java
index bf16d5a..6f2a8d2 100644
--- a/seer-user/seer-user-service/src/main/java/com/seer/teach/user/service/impl/UserRoleServiceImpl.java
+++ b/seer-user/seer-user-service/src/main/java/com/seer/teach/user/service/impl/UserRoleServiceImpl.java
@@ -44,6 +44,19 @@ public class UserRoleServiceImpl extends ServiceImpl(UserRoleEntity.class).eq(UserRoleEntity::getUserId, userId));
}
+ @Override
+ public List getRoleCodeListByUserId(Integer userId) {
+ List userRoleList = this.getListByUserId(userId);
+ if(CollectionUtil.isNotEmpty(userRoleList)){
+ List roleIds = userRoleList.stream().map(UserRoleEntity::getRoleId).collect(Collectors.toList());
+ if(CollectionUtil.isNotEmpty(roleIds)){
+ Collection roles = roleService.getRoleListByRoleIds(roleIds);
+ return roles.stream().map(RoleEntity::getRoleCode).collect(Collectors.toList());
+ }
+ }
+ return List.of();
+ }
+
@Override
public void assignUserRole(Integer userId, Set roleIds) {
List userRoleList = this.getListByUserId(userId);