zhuyifan

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

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



See merge request !2
...@@ -2,6 +2,7 @@ package com.infoloop.tianting.controller; ...@@ -2,6 +2,7 @@ package com.infoloop.tianting.controller;
2 2
3 import cn.dev33.satoken.annotation.SaIgnore; 3 import cn.dev33.satoken.annotation.SaIgnore;
4 import cn.dev33.satoken.stp.SaTokenInfo; 4 import cn.dev33.satoken.stp.SaTokenInfo;
5 +import cn.dev33.satoken.stp.StpUtil;
5 import com.github.xiaoymin.knife4j.annotations.ApiSupport; 6 import com.github.xiaoymin.knife4j.annotations.ApiSupport;
6 import com.infoloop.tianting.mealorderservice.SingleMpAccountRpcResponse; 7 import com.infoloop.tianting.mealorderservice.SingleMpAccountRpcResponse;
7 import com.infoloop.tianting.model.dto.MpAccountDTO; 8 import com.infoloop.tianting.model.dto.MpAccountDTO;
...@@ -61,4 +62,12 @@ public class LoginController { ...@@ -61,4 +62,12 @@ public class LoginController {
61 @RequestBody @Valid MpAccountDTO.ModifyMpAccountDTO modifyMpAccountDTO) { 62 @RequestBody @Valid MpAccountDTO.ModifyMpAccountDTO modifyMpAccountDTO) {
62 loginService.updateMpAccount(mpAccount, modifyMpAccountDTO); 63 loginService.updateMpAccount(mpAccount, modifyMpAccountDTO);
63 } 64 }
65 +
66 + @SaIgnore
67 + @ApiOperation(value = "踢人下线")
68 + @PostMapping("/kickout")
69 + @ResponseStatus(HttpStatus.OK)
70 + public void kickout(@Valid @RequestBody PermissionDTO.KickOutDTO kickOutDTO) {
71 + StpUtil.kickout(kickOutDTO.getId());
72 + }
64 } 73 }
......
...@@ -62,7 +62,9 @@ public enum ErrorCodeEnum implements BaseEnum { ...@@ -62,7 +62,9 @@ public enum ErrorCodeEnum implements BaseEnum {
62 62
63 MEAL_ORDER_TIME_NOT_IN_RANGE(406000022, "当前时间不在选餐时间内"), 63 MEAL_ORDER_TIME_NOT_IN_RANGE(406000022, "当前时间不在选餐时间内"),
64 64
65 - DINER_NAME_STUDENT_NO_NOT_MISMATCH(406000023, "该就餐人学号和名称不匹配") 65 + DINER_NAME_STUDENT_NO_NOT_MISMATCH(406000023, "该就餐人学号和名称不匹配"),
66 +
67 + MP_ACCOUNT_ALREADY_DISABLED(406000024, "账号已禁用"),
66 68
67 69
68 ; 70 ;
......
...@@ -40,4 +40,13 @@ public class PermissionDTO { ...@@ -40,4 +40,13 @@ public class PermissionDTO {
40 private Integer enterpriseId = 0; 40 private Integer enterpriseId = 0;
41 } 41 }
42 42
43 + @Data
44 + @Builder
45 + @ApiModel(description = "kickOut DTO")
46 + public static class KickOutDTO {
47 +
48 + private String id;
49 +
50 + }
51 +
43 } 52 }
......
...@@ -8,6 +8,7 @@ import com.infoloop.tianting.WOperatorStatus; ...@@ -8,6 +8,7 @@ import com.infoloop.tianting.WOperatorStatus;
8 import com.infoloop.tianting.clientcustomerservice.ClientCustomerHospitalRecordHospitalStatusEnum; 8 import com.infoloop.tianting.clientcustomerservice.ClientCustomerHospitalRecordHospitalStatusEnum;
9 import com.infoloop.tianting.constant.CommonConstants; 9 import com.infoloop.tianting.constant.CommonConstants;
10 import com.infoloop.tianting.context.LoginContextHolder; 10 import com.infoloop.tianting.context.LoginContextHolder;
11 +import com.infoloop.tianting.enums.LoginSourceEnum;
11 import com.infoloop.tianting.exception.ClientEndExceptions; 12 import com.infoloop.tianting.exception.ClientEndExceptions;
12 import com.infoloop.tianting.exception.ErrorCodeEnum; 13 import com.infoloop.tianting.exception.ErrorCodeEnum;
13 import com.infoloop.tianting.mealorderservice.MpAccountCreation; 14 import com.infoloop.tianting.mealorderservice.MpAccountCreation;
...@@ -45,6 +46,21 @@ public class LoginServiceImpl implements LoginService { ...@@ -45,6 +46,21 @@ public class LoginServiceImpl implements LoginService {
45 private final WOperatorServiceRpcClient wOperatorServiceRpcClient; 46 private final WOperatorServiceRpcClient wOperatorServiceRpcClient;
46 private final MeiZhongYiHeServiceClient meiZhongYiHeServiceClient; 47 private final MeiZhongYiHeServiceClient meiZhongYiHeServiceClient;
47 48
49 + public static String sha1Hash(String input) throws NoSuchAlgorithmException {
50 + MessageDigest md = MessageDigest.getInstance("SHA-1");
51 + md.update(input.getBytes());
52 + byte[] digest = md.digest();
53 + return bytesToHex(digest);
54 + }
55 +
56 + private static String bytesToHex(byte[] bytes) {
57 + StringBuilder sb = new StringBuilder();
58 + for (byte b : bytes) {
59 + sb.append(String.format("%02x", b));
60 + }
61 + return sb.toString();
62 + }
63 +
48 @Override 64 @Override
49 public SaTokenInfo login(LoginDto loginDto) throws NoSuchAlgorithmException { 65 public SaTokenInfo login(LoginDto loginDto) throws NoSuchAlgorithmException {
50 if (loginDto.isShouldLoginWithOpenCode()) { 66 if (loginDto.isShouldLoginWithOpenCode()) {
...@@ -54,7 +70,7 @@ public class LoginServiceImpl implements LoginService { ...@@ -54,7 +70,7 @@ public class LoginServiceImpl implements LoginService {
54 .setExtra(CommonConstants.LOGIN_SOURCE, loginDto.getLoginSourceEnum().getValue()) 70 .setExtra(CommonConstants.LOGIN_SOURCE, loginDto.getLoginSourceEnum().getValue())
55 .build()); 71 .build());
56 return StpUtil.getTokenInfo(); 72 return StpUtil.getTokenInfo();
57 - } else if (loginDto.isShouldLoginWithOpenId()){ 73 + } else if (loginDto.isShouldLoginWithOpenId()) {
58 final var mpAccountByOpenId = mealOrderServiceRpcClient.getMpAccountByOpenId(loginDto.getOpenId()); 74 final var mpAccountByOpenId = mealOrderServiceRpcClient.getMpAccountByOpenId(loginDto.getOpenId());
59 int mpAccountId; 75 int mpAccountId;
60 if (mpAccountByOpenId == null) { 76 if (mpAccountByOpenId == null) {
...@@ -64,6 +80,18 @@ public class LoginServiceImpl implements LoginService { ...@@ -64,6 +80,18 @@ public class LoginServiceImpl implements LoginService {
64 .setPhoneNumber(loginDto.getOperatorPhone() != null ? loginDto.getOperatorPhone() : "") 80 .setPhoneNumber(loginDto.getOperatorPhone() != null ? loginDto.getOperatorPhone() : "")
65 .build()).getId(); 81 .build()).getId();
66 } else { 82 } else {
83 + if (mpAccountByOpenId.getStatus() != MpAccountStatusEnum.MP_ACCOUNT_STATUS_ENABLE) {
84 + throw ClientEndExceptions.IncorrectRequestValue.build(ErrorCodeEnum.MP_ACCOUNT_ALREADY_DISABLED);
85 + }
86 + mealOrderServiceRpcClient.updateMpAccount(LoginContextHolder.LoginInfo.builder()
87 + .id(mpAccountByOpenId.getId())
88 + .enterpriseId(loginDto.getEnterpriseId())
89 + .loginSource(LoginSourceEnum.MINI_PROGRAM)
90 + .build(),
91 + MpAccountModification.newBuilder()
92 + .setId(mpAccountByOpenId.getId())
93 + .setPhoneNumber(loginDto.getOperatorPhone() != null ? loginDto.getOperatorPhone() : "")
94 + .build());
67 mpAccountId = mpAccountByOpenId.getId(); 95 mpAccountId = mpAccountByOpenId.getId();
68 } 96 }
69 Assert.isTrue(mpAccountId != 0, "创建小程序账号失败"); 97 Assert.isTrue(mpAccountId != 0, "创建小程序账号失败");
...@@ -169,20 +197,5 @@ public class LoginServiceImpl implements LoginService { ...@@ -169,20 +197,5 @@ public class LoginServiceImpl implements LoginService {
169 .setGender(modifyMpAccountDTO.getGender() != null ? modifyMpAccountDTO.getGender() : mpAccount.getGender()) 197 .setGender(modifyMpAccountDTO.getGender() != null ? modifyMpAccountDTO.getGender() : mpAccount.getGender())
170 .build()); 198 .build());
171 } 199 }
172 -
173 - public static String sha1Hash(String input) throws NoSuchAlgorithmException {
174 - MessageDigest md = MessageDigest.getInstance("SHA-1");
175 - md.update(input.getBytes());
176 - byte[] digest = md.digest();
177 - return bytesToHex(digest);
178 - }
179 -
180 - private static String bytesToHex(byte[] bytes) {
181 - StringBuilder sb = new StringBuilder();
182 - for (byte b : bytes) {
183 - sb.append(String.format("%02x", b));
184 - }
185 - return sb.toString();
186 - }
187 } 200 }
188 201
......