zhuyifan

Merge branch 'qa/2025-05-28' into 'master'

feat(login): 添加账号禁用异常处理和踢人下线功能



See merge request !2
......@@ -2,6 +2,7 @@ package com.infoloop.tianting.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.infoloop.tianting.mealorderservice.SingleMpAccountRpcResponse;
import com.infoloop.tianting.model.dto.MpAccountDTO;
......@@ -61,4 +62,12 @@ public class LoginController {
@RequestBody @Valid MpAccountDTO.ModifyMpAccountDTO modifyMpAccountDTO) {
loginService.updateMpAccount(mpAccount, modifyMpAccountDTO);
}
@SaIgnore
@ApiOperation(value = "踢人下线")
@PostMapping("/kickout")
@ResponseStatus(HttpStatus.OK)
public void kickout(@Valid @RequestBody PermissionDTO.KickOutDTO kickOutDTO) {
StpUtil.kickout(kickOutDTO.getId());
}
}
......
......@@ -62,7 +62,9 @@ public enum ErrorCodeEnum implements BaseEnum {
MEAL_ORDER_TIME_NOT_IN_RANGE(406000022, "当前时间不在选餐时间内"),
DINER_NAME_STUDENT_NO_NOT_MISMATCH(406000023, "该就餐人学号和名称不匹配")
DINER_NAME_STUDENT_NO_NOT_MISMATCH(406000023, "该就餐人学号和名称不匹配"),
MP_ACCOUNT_ALREADY_DISABLED(406000024, "账号已禁用"),
;
......
......@@ -40,4 +40,13 @@ public class PermissionDTO {
private Integer enterpriseId = 0;
}
@Data
@Builder
@ApiModel(description = "kickOut DTO")
public static class KickOutDTO {
private String id;
}
}
......
......@@ -8,6 +8,7 @@ import com.infoloop.tianting.WOperatorStatus;
import com.infoloop.tianting.clientcustomerservice.ClientCustomerHospitalRecordHospitalStatusEnum;
import com.infoloop.tianting.constant.CommonConstants;
import com.infoloop.tianting.context.LoginContextHolder;
import com.infoloop.tianting.enums.LoginSourceEnum;
import com.infoloop.tianting.exception.ClientEndExceptions;
import com.infoloop.tianting.exception.ErrorCodeEnum;
import com.infoloop.tianting.mealorderservice.MpAccountCreation;
......@@ -45,6 +46,21 @@ public class LoginServiceImpl implements LoginService {
private final WOperatorServiceRpcClient wOperatorServiceRpcClient;
private final MeiZhongYiHeServiceClient meiZhongYiHeServiceClient;
public static String sha1Hash(String input) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(input.getBytes());
byte[] digest = md.digest();
return bytesToHex(digest);
}
private static String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
@Override
public SaTokenInfo login(LoginDto loginDto) throws NoSuchAlgorithmException {
if (loginDto.isShouldLoginWithOpenCode()) {
......@@ -54,7 +70,7 @@ public class LoginServiceImpl implements LoginService {
.setExtra(CommonConstants.LOGIN_SOURCE, loginDto.getLoginSourceEnum().getValue())
.build());
return StpUtil.getTokenInfo();
} else if (loginDto.isShouldLoginWithOpenId()){
} else if (loginDto.isShouldLoginWithOpenId()) {
final var mpAccountByOpenId = mealOrderServiceRpcClient.getMpAccountByOpenId(loginDto.getOpenId());
int mpAccountId;
if (mpAccountByOpenId == null) {
......@@ -64,6 +80,18 @@ public class LoginServiceImpl implements LoginService {
.setPhoneNumber(loginDto.getOperatorPhone() != null ? loginDto.getOperatorPhone() : "")
.build()).getId();
} else {
if (mpAccountByOpenId.getStatus() != MpAccountStatusEnum.MP_ACCOUNT_STATUS_ENABLE) {
throw ClientEndExceptions.IncorrectRequestValue.build(ErrorCodeEnum.MP_ACCOUNT_ALREADY_DISABLED);
}
mealOrderServiceRpcClient.updateMpAccount(LoginContextHolder.LoginInfo.builder()
.id(mpAccountByOpenId.getId())
.enterpriseId(loginDto.getEnterpriseId())
.loginSource(LoginSourceEnum.MINI_PROGRAM)
.build(),
MpAccountModification.newBuilder()
.setId(mpAccountByOpenId.getId())
.setPhoneNumber(loginDto.getOperatorPhone() != null ? loginDto.getOperatorPhone() : "")
.build());
mpAccountId = mpAccountByOpenId.getId();
}
Assert.isTrue(mpAccountId != 0, "创建小程序账号失败");
......@@ -116,9 +144,9 @@ public class LoginServiceImpl implements LoginService {
throw ClientEndExceptions.AuthenticationFailure.build(ErrorCodeEnum.VALIDATE_FAILED.name());
}
StpUtil.login(operator.getId(), SaLoginModel.create()
.setExtra(CommonConstants.ENTERPRISE_ID, operator.getEnterpriseId())
.setExtra(CommonConstants.LOGIN_SOURCE, loginDto.getLoginSourceEnum().getValue())
.build());
.setExtra(CommonConstants.ENTERPRISE_ID, operator.getEnterpriseId())
.setExtra(CommonConstants.LOGIN_SOURCE, loginDto.getLoginSourceEnum().getValue())
.build());
return StpUtil.getTokenInfo();
} else {
final var operator = wOperatorServiceRpcClient.getWOperatorByEmail(loginDto.getEmail()).getResponse();
......@@ -132,9 +160,9 @@ public class LoginServiceImpl implements LoginService {
throw ClientEndExceptions.AuthenticationFailure.build(ErrorCodeEnum.VALIDATE_FAILED.name());
}
StpUtil.login(operator.getId(), SaLoginModel.create()
.setExtra(CommonConstants.ENTERPRISE_ID, operator.getEnterpriseId())
.setExtra(CommonConstants.LOGIN_SOURCE, loginDto.getLoginSourceEnum().getValue())
.build());
.setExtra(CommonConstants.ENTERPRISE_ID, operator.getEnterpriseId())
.setExtra(CommonConstants.LOGIN_SOURCE, loginDto.getLoginSourceEnum().getValue())
.build());
return StpUtil.getTokenInfo();
}
}
......@@ -169,20 +197,5 @@ public class LoginServiceImpl implements LoginService {
.setGender(modifyMpAccountDTO.getGender() != null ? modifyMpAccountDTO.getGender() : mpAccount.getGender())
.build());
}
public static String sha1Hash(String input) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(input.getBytes());
byte[] digest = md.digest();
return bytesToHex(digest);
}
private static String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
}
......