bug修改

This commit is contained in:
周鹏 committed 2026-09-06 12:54:57 +08:00
1 parent ee47e3a94c
commit d521f55b1d
6 files changed
+75 -19

No files matched your search

@@ -57,15 +57,16 @@ public class AppAuthController {
}
@GetMapping("/airline-check")
@Operation(summary = "航空账号会话校验(免登录,按手机号+渠道+设备识别号核对账号)")
@Parameter(name = "mobile", description = "手机号", required = true)
@Operation(summary = "航空账号会话校验(免登录,兼容新旧客户端:Token/手机号+渠道/设备识别号 任一定位)")
@Parameter(name = "deviceId", description = "设备唯一识别号", required = true)
@Parameter(name = "channel", description = "品牌渠道(CZ/MU/HU)", required = true)
@Parameter(name = "mobile", description = "手机号(新客户端传)")
@Parameter(name = "channel", description = "品牌渠道 CZ/MU/HU(新客户端传)")
@PermitAll
public CommonResult<Boolean> airlineCheck(@RequestParam("mobile") String mobile,
@RequestParam("deviceId") String deviceId,
@RequestParam("channel") String channel) {
authService.airlineCheck(mobile, deviceId, channel);
public CommonResult<Boolean> airlineCheck(
@RequestParam(value = "mobile", required = false) String mobile,
@RequestParam("deviceId") String deviceId,
@RequestParam(value = "channel", required = false) String channel) {
authService.airlineCheck(getLoginUserId(), mobile, deviceId, channel);
return success(true);
}
@@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.member.controller.admin.airline.vo.MemberAirlineA
import cn.iocoder.yudao.module.member.dal.dataobject.airline.MemberAirlineAccountDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface MemberAirlineAccountMapper extends BaseMapperX<MemberAirlineAccountDO> {
@@ -32,4 +34,9 @@ public interface MemberAirlineAccountMapper extends BaseMapperX<MemberAirlineAcc
.eq(MemberAirlineAccountDO::getChannel, channel));
}
default List<MemberAirlineAccountDO> selectListByDeviceId(String deviceId) {
return selectList(new LambdaQueryWrapperX<MemberAirlineAccountDO>()
.eq(MemberAirlineAccountDO::getDeviceId, deviceId));
}
}
@@ -34,9 +34,12 @@ public interface MemberAirlineAccountService {
MemberAirlineAccountDO authenticateAndBindDevice(String mobile, String password, String deviceId, String channel);
/**
* 会话校验(免登录):按 手机号+渠道 定位账号,校验存在/禁用/有效期/设备绑定。
* 不依赖任何 Token,App 每次打开直接核对账号表。
* 会话校验(免登录,兼容新旧客户端):
* ① Token 有效 → 按登录用户(航空账号编号)定位;
* ② Token 失效但传了 手机号+渠道 → 按账号表定位;
* ③ 都没有 → 仅按设备识别号兜底(设备绑定的任一有效账号即放行)。
* 校验内容:账号存在、未禁用、在有效期内、设备绑定匹配。
*/
void validateAirlineSession(String mobile, String deviceId, String channel);
void validateAirlineSession(Long loginUserId, String mobile, String deviceId, String channel);
}
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.member.service.airline;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.member.controller.admin.airline.vo.MemberAirlineAccountCreateReqVO;
@@ -16,6 +17,8 @@ import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -123,12 +126,51 @@ public class MemberAirlineAccountServiceImpl implements MemberAirlineAccountServ
}
@Override
public void validateAirlineSession(String mobile, String deviceId, String channel) {
// 按 手机号+渠道 定位账号(免 Token 校验,直接核对账号表)
MemberAirlineAccountDO account = airlineAccountMapper.selectByMobileAndChannel(mobile, channel);
if (account == null) {
public void validateAirlineSession(Long loginUserId, String mobile, String deviceId, String channel) {
// ① 手机号+渠道:精确匹配,直接认定是本人账号
if (StrUtil.isNotBlank(mobile) && StrUtil.isNotBlank(channel)) {
MemberAirlineAccountDO account = airlineAccountMapper.selectByMobileAndChannel(mobile, channel);
if (account == null) {
throw exception(AIRLINE_ACCOUNT_NOT_EXISTS);
}
validateAccount(account, deviceId);
return;
}
// 收集候选账号:② Token 定位 + ③ 设备识别号定位(两者合并,逐个核实)
// 注意:旧 Token(member_user 同步方案时期签发)的 userId 是 member_user 编号,
// 与 member_airline_account 的 id 共用数字空间,selectById 可能撞号命中别人的账号,
// 因此候选必须经过"设备匹配"核实身份后,才能采信其状态。
List<MemberAirlineAccountDO> candidates = new ArrayList<>();
if (loginUserId != null) {
MemberAirlineAccountDO account = airlineAccountMapper.selectById(loginUserId);
if (account != null) {
candidates.add(account);
}
}
for (MemberAirlineAccountDO account : airlineAccountMapper.selectListByDeviceId(deviceId)) {
if (candidates.stream().noneMatch(c -> Objects.equals(c.getId(), account.getId()))) {
candidates.add(account);
}
}
if (candidates.isEmpty()) {
throw exception(AIRLINE_ACCOUNT_NOT_EXISTS);
}
// 逐个候选核实:设备不匹配说明不是本机绑定的账号(如旧 Token 撞号),跳过换下一个;
// 设备匹配后才校验状态,此时报"禁用/到期"才是真实问题
for (MemberAirlineAccountDO account : candidates) {
if (StrUtil.isBlank(account.getDeviceId()) || !StrUtil.equals(account.getDeviceId(), deviceId)) {
continue;
}
validateAccount(account, deviceId);
return;
}
// 所有候选的绑定设备都与本机不符
throw exception(AIRLINE_ACCOUNT_DEVICE_BOUND);
}
private void validateAccount(MemberAirlineAccountDO account, String deviceId) {
if (CommonStatusEnum.isDisable(account.getStatus())) {
throw exception(AIRLINE_ACCOUNT_DISABLED);
}
@@ -116,9 +116,12 @@ public interface MemberAuthService {
AppAuthLoginRespVO airlineLogin(@Valid AppAuthAirlineLoginReqVO reqVO);
/**
* 航空账号会话校验(免登录):按 手机号+渠道+设备识别号 定位账号,
* 校验账号存在、未禁用、在有效期内、设备绑定匹配。不依赖任何 Token。
* 航空账号会话校验(免登录,兼容新旧客户端):
* ① Token 有效 → 按登录用户定位账号校验;
* ② Token 失效但传了 手机号+渠道 → 按账号表定位校验;
* ③ 都没有 → 仅按设备识别号兜底(设备绑定的任一有效账号即放行)。
* 校验内容:账号存在、未禁用、在有效期内、设备绑定匹配。
*/
void airlineCheck(String mobile, String deviceId, String channel);
void airlineCheck(Long loginUserId, String mobile, String deviceId, String channel);
}
@@ -453,8 +453,8 @@ public class MemberAuthServiceImpl implements MemberAuthService {
}
@Override
public void airlineCheck(String mobile, String deviceId, String channel) {
airlineAccountService.validateAirlineSession(mobile, deviceId, channel);
public void airlineCheck(Long loginUserId, String mobile, String deviceId, String channel) {
airlineAccountService.validateAirlineSession(loginUserId, mobile, deviceId, channel);
}
private void createLogoutLog(Long userId) {