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 +