diff --git a/urbanLifelineServ/auth/src/main/java/org/xyzh/auth/strategy/impl/WechatLoginStrategy.java b/urbanLifelineServ/auth/src/main/java/org/xyzh/auth/strategy/impl/WechatLoginStrategy.java
index b99cb780..473ab161 100644
--- a/urbanLifelineServ/auth/src/main/java/org/xyzh/auth/strategy/impl/WechatLoginStrategy.java
+++ b/urbanLifelineServ/auth/src/main/java/org/xyzh/auth/strategy/impl/WechatLoginStrategy.java
@@ -9,7 +9,7 @@ import org.xyzh.api.system.service.SysUserService;
import org.xyzh.api.system.vo.SysUserVO;
/**
- * @description WechatLoginStrategy.java文件描述 微信登录策略
+ * @description 微信二维码登录策略(PC端扫码登录)
* @filename WechatLoginStrategy.java
* @author yslg
* @copyright xyzh
@@ -24,7 +24,7 @@ public class WechatLoginStrategy implements LoginStrategy {
@Override
public String getLoginType() {
- return "wechat";
+ return "wechat_qrcode";
}
@Override
diff --git a/urbanLifelineServ/auth/src/main/java/org/xyzh/auth/strategy/impl/WechatMiniProgramLoginStrategy.java b/urbanLifelineServ/auth/src/main/java/org/xyzh/auth/strategy/impl/WechatMiniProgramLoginStrategy.java
new file mode 100644
index 00000000..d1d9356e
--- /dev/null
+++ b/urbanLifelineServ/auth/src/main/java/org/xyzh/auth/strategy/impl/WechatMiniProgramLoginStrategy.java
@@ -0,0 +1,75 @@
+package org.xyzh.auth.strategy.impl;
+
+import org.springframework.stereotype.Component;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.xyzh.auth.strategy.LoginStrategy;
+import org.xyzh.common.core.domain.LoginParam;
+import org.xyzh.api.system.service.SysUserService;
+import org.xyzh.api.system.vo.SysUserVO;
+
+/**
+ * @description 微信小程序登录策略
+ * @filename WechatMiniProgramLoginStrategy.java
+ * @author cascade
+ * @copyright xyzh
+ * @since 2025-12-22
+ */
+@Component
+public class WechatMiniProgramLoginStrategy implements LoginStrategy {
+
+ @Autowired
+ private SysUserService userService;
+
+ @Override
+ public String getLoginType() {
+ return "wechat_miniprogram";
+ }
+
+ @Override
+ public boolean validate(LoginParam loginParam) {
+ // 小程序登录需要wechatId或phone
+ boolean hasWechatId = loginParam.getWechatId() != null && !loginParam.getWechatId().trim().isEmpty();
+ boolean hasPhone = loginParam.getPhone() != null && !loginParam.getPhone().trim().isEmpty();
+ return hasWechatId || hasPhone;
+ }
+
+ @Override
+ public SysUserVO findUser(LoginParam loginParam) {
+ SysUserVO filter = new SysUserVO();
+
+ // 优先使用wechatId查询
+ if (loginParam.getWechatId() != null && !loginParam.getWechatId().trim().isEmpty()) {
+ filter.setWechatId(loginParam.getWechatId());
+ SysUserVO user = userService.getLoginUser(filter).getData();
+ if (user != null) {
+ return user;
+ }
+ }
+
+ // 如果wechatId未找到,尝试用phone查询
+ if (loginParam.getPhone() != null && !loginParam.getPhone().trim().isEmpty()) {
+ filter = new SysUserVO();
+ filter.setPhone(loginParam.getPhone());
+ SysUserVO user = userService.getLoginUser(filter).getData();
+ if (user != null) {
+ // 如果用户存在但没有wechatId,需要更新wechatId
+ if (user.getWechatId() == null && loginParam.getWechatId() != null) {
+ SysUserVO updateUser = new SysUserVO();
+ updateUser.setUserId(user.getUserId());
+ updateUser.setWechatId(loginParam.getWechatId());
+ userService.updateUser(updateUser);
+ user.setWechatId(loginParam.getWechatId());
+ }
+ return user;
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public boolean verifyCredential(String inputCredential, String storedCredential) {
+ // 微信小程序通过微信授权,不需要密码验证
+ return true;
+ }
+}
diff --git a/urbanLifelineServ/system/pom.xml b/urbanLifelineServ/system/pom.xml
index b7dde521..62b193ec 100644
--- a/urbanLifelineServ/system/pom.xml
+++ b/urbanLifelineServ/system/pom.xml
@@ -29,6 +29,10 @@
org.xyzh.apis
api-system
+
+ org.xyzh.apis
+ api-auth
+
org.springframework.boot
diff --git a/urbanLifelineServ/system/src/main/java/org/xyzh/system/controller/GuestController.java b/urbanLifelineServ/system/src/main/java/org/xyzh/system/controller/GuestController.java
index 26238193..fb2ea225 100644
--- a/urbanLifelineServ/system/src/main/java/org/xyzh/system/controller/GuestController.java
+++ b/urbanLifelineServ/system/src/main/java/org/xyzh/system/controller/GuestController.java
@@ -2,6 +2,7 @@ package org.xyzh.system.controller;
import java.util.Arrays;
+import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
@@ -9,14 +10,23 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
+import org.xyzh.api.auth.service.AuthService;
import org.xyzh.api.system.service.GuestService;
+import org.xyzh.common.core.domain.LoginDomain;
+import org.xyzh.common.core.domain.LoginParam;
import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.core.page.PageRequest;
import org.xyzh.common.dto.sys.TbGuestDTO;
+import org.xyzh.common.dto.sys.TbSysUserDTO;
+import org.xyzh.common.dto.sys.TbSysUserInfoDTO;
+import org.xyzh.common.utils.id.IdUtil;
import org.xyzh.common.utils.validation.ValidationUtils;
+import io.swagger.v3.oas.annotations.Operation;
+import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
@@ -35,6 +45,9 @@ public class GuestController {
@Autowired
private GuestService guestService;
+ @DubboReference(version = "1.0.0", group = "auth", timeout = 5000, check = false, retries = 0)
+ private AuthService authService;
+
@PostMapping
public ResultDomain createGuest(TbGuestDTO guest) {
@@ -81,5 +94,105 @@ public class GuestController {
return guestService.selectGuestPage(pageRequest);
}
-
+ // ========================= 微信小程序用户识别登录 =========================
+
+ @Operation(summary = "微信小程序用户识别登录")
+ @PostMapping("/identify")
+ public ResultDomain identifyUser(@RequestBody LoginParam loginParam, HttpServletRequest request) {
+ // 验证参数:必须有wechatId或phone
+ if ((loginParam.getWechatId() == null || loginParam.getWechatId().trim().isEmpty())
+ && (loginParam.getPhone() == null || loginParam.getPhone().trim().isEmpty())) {
+ return ResultDomain.failure("微信ID或手机号不能为空");
+ }
+
+ // 设置登录类型为微信小程序
+ loginParam.setLoginType("wechat_miniprogram");
+
+ // 1. 尝试通过AuthService登录(员工)
+ ResultDomain loginResult = authService.login(loginParam, request);
+ if (loginResult.getSuccess() && loginResult.getData() != null) {
+ // 登录成功,是系统员工
+ return loginResult;
+ }
+
+ // 2. 登录失败,查询/注册来客
+ return handleGuestLogin(loginParam);
+ }
+
+ /**
+ * 处理来客登录:查询或注册来客,构造LoginDomain
+ */
+ private ResultDomain handleGuestLogin(LoginParam loginParam) {
+ TbGuestDTO guest = null;
+
+ // 优先用wechatId查询
+ if (loginParam.getWechatId() != null && !loginParam.getWechatId().trim().isEmpty()) {
+ ResultDomain guestResult = guestService.selectGuestByWechatId(loginParam.getWechatId());
+ if (guestResult.getSuccess() && guestResult.getData() != null) {
+ guest = guestResult.getData();
+ }
+ }
+
+ // wechatId未找到,尝试用phone查询
+ if (guest == null && loginParam.getPhone() != null && !loginParam.getPhone().trim().isEmpty()) {
+ TbGuestDTO filter = new TbGuestDTO();
+ filter.setPhone(loginParam.getPhone());
+ ResultDomain guestResult = guestService.selectGuestOne(filter);
+ if (guestResult.getSuccess() && guestResult.getData() != null) {
+ guest = guestResult.getData();
+ // 如果来客存在但wechatId为空,更新wechatId
+ if (guest.getWechatId() == null && loginParam.getWechatId() != null) {
+ TbGuestDTO updateGuest = new TbGuestDTO();
+ updateGuest.setUserId(guest.getUserId());
+ updateGuest.setWechatId(loginParam.getWechatId());
+ guestService.updateGuest(updateGuest);
+ guest.setWechatId(loginParam.getWechatId());
+ }
+ }
+ }
+
+ // 3. 来客不存在,创建新来客
+ if (guest == null) {
+ TbGuestDTO newGuest = new TbGuestDTO();
+ newGuest.setUserId(IdUtil.generateID());
+ newGuest.setWechatId(loginParam.getWechatId());
+ newGuest.setPhone(loginParam.getPhone());
+ newGuest.setName(loginParam.getUsername() != null ? loginParam.getUsername() : "来客");
+
+ ResultDomain createResult = guestService.createGuest(newGuest);
+ if (!createResult.getSuccess()) {
+ return ResultDomain.failure("创建来客失败: " + createResult.getMessage());
+ }
+ guest = createResult.getData();
+ }
+
+ // 4. 构造来客的LoginDomain
+ return ResultDomain.success("来客登录成功", buildGuestLoginDomain(guest));
+ }
+
+ /**
+ * 从来客信息构造LoginDomain
+ */
+ private LoginDomain buildGuestLoginDomain(TbGuestDTO guest) {
+ LoginDomain loginDomain = new LoginDomain();
+
+ // 构造TbSysUserDTO,status设为guest
+ TbSysUserDTO userDTO = new TbSysUserDTO();
+ userDTO.setUserId(guest.getUserId());
+ userDTO.setPhone(guest.getPhone());
+ userDTO.setEmail(guest.getEmail());
+ userDTO.setWechatId(guest.getWechatId());
+ userDTO.setStatus("guest"); // 来客特殊状态
+ loginDomain.setUser(userDTO);
+
+ // 构造TbSysUserInfoDTO
+ TbSysUserInfoDTO userInfoDTO = new TbSysUserInfoDTO();
+ userInfoDTO.setUserId(guest.getUserId());
+ userInfoDTO.setUsername(guest.getName());
+ loginDomain.setUserInfo(userInfoDTO);
+
+ loginDomain.setLoginType("wechat_miniprogram");
+
+ return loginDomain;
+ }
}
diff --git a/urbanLifelineServ/workcase/pom.xml b/urbanLifelineServ/workcase/pom.xml
index 28268e71..a81545d3 100644
--- a/urbanLifelineServ/workcase/pom.xml
+++ b/urbanLifelineServ/workcase/pom.xml
@@ -26,6 +26,10 @@
org.xyzh.apis
api-system
+
+ org.xyzh.apis
+ api-auth
+