From a3bfafde009c644c21ee8c9971b436f4cd7481f1 Mon Sep 17 00:00:00 2001
From: 刘帅 <rr.iii@qq.com>
Date: 星期日, 20 九月 2026 11:59:29 +0800
Subject: [PATCH] feat:手机号隐私问题
---
cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/filter/SensitiveDataMaskingGlobalFilter.java | 10 +---------
cloud-server-account/src/main/java/com/dsh/account/model/vo/userBenefitDetail/AppUserDetailsVo.java | 2 --
cloud-server-account/src/main/java/com/dsh/account/controller/AppUserController.java | 18 ++++++++++++++++++
cloud-server-other/src/main/java/com/dsh/other/feignclient/account/AppUserClient.java | 9 +++++++++
cloud-server-other/src/main/java/com/dsh/other/controller/SiteController.java | 18 ++++++++++++++++++
5 files changed, 46 insertions(+), 11 deletions(-)
diff --git a/cloud-server-account/src/main/java/com/dsh/account/controller/AppUserController.java b/cloud-server-account/src/main/java/com/dsh/account/controller/AppUserController.java
index 279e705..d8b3fbe 100644
--- a/cloud-server-account/src/main/java/com/dsh/account/controller/AppUserController.java
+++ b/cloud-server-account/src/main/java/com/dsh/account/controller/AppUserController.java
@@ -269,6 +269,24 @@
}
/**
+ * Internal data source used when an APP booking submits its displayed,
+ * masked phone number. Limit the response to the single field needed for
+ * that booking; callers must use the internal sensitive-data header.
+ */
+ @PostMapping("/internal/sensitive/site-booking/app-user/{id}/phone")
+ public Map<String, Object> siteBookingPhone(@PathVariable("id") Integer id,
+ @RequestHeader(value = "X-Internal-Sensitive-Access", required = false) String access) {
+ if (!"true".equalsIgnoreCase(access)) {
+ throw new IllegalStateException("Sensitive data access is restricted to site booking");
+ }
+ TAppUser user = appUserService.getById(id);
+ if (user == null) return null;
+ Map<String, Object> result = new java.util.HashMap<String, Object>();
+ result.put("phone", user.getPhone());
+ return result;
+ }
+
+ /**
* 冻结/解冻 1=解冻 2=冻结
*/
@RequestMapping("/base/appUser/changeState")
diff --git a/cloud-server-account/src/main/java/com/dsh/account/model/vo/userBenefitDetail/AppUserDetailsVo.java b/cloud-server-account/src/main/java/com/dsh/account/model/vo/userBenefitDetail/AppUserDetailsVo.java
index 50b4f95..25047d6 100644
--- a/cloud-server-account/src/main/java/com/dsh/account/model/vo/userBenefitDetail/AppUserDetailsVo.java
+++ b/cloud-server-account/src/main/java/com/dsh/account/model/vo/userBenefitDetail/AppUserDetailsVo.java
@@ -1,7 +1,6 @@
package com.dsh.account.model.vo.userBenefitDetail;
-import com.dsh.privacy.UnmaskedSensitiveData;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -17,7 +16,6 @@
private String userName;
@ApiModelProperty(value = "用户手机号")
- @UnmaskedSensitiveData
private String userPhone;
@ApiModelProperty(value = "用户性别")
diff --git a/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/filter/SensitiveDataMaskingGlobalFilter.java b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/filter/SensitiveDataMaskingGlobalFilter.java
index b150ae6..d1dea58 100644
--- a/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/filter/SensitiveDataMaskingGlobalFilter.java
+++ b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/filter/SensitiveDataMaskingGlobalFilter.java
@@ -21,13 +21,6 @@
/** Final API boundary for APP traffic, including responses returned by every service. */
@Component
public class SensitiveDataMaskingGlobalFilter implements GlobalFilter, Ordered {
- /**
- * This response contains the current user's own phone number, which the APP
- * needs in its original form. The account service marks the field with
- * {@code @UnmaskedSensitiveData}; the gateway works on JSON text, so it
- * must mirror that narrow exception here.
- */
- private static final String UNMASKED_USER_DETAILS_PATH = "/account/api/useBenefit/userDetails";
private static final Pattern FIELD = Pattern.compile("(?i)(\\\"(?:[a-z]*phone|[a-z]*mobile|telephone|tel)\\\"\\s*:\\s*\\\")([^\\\"]*)(\\\")");
private static final Pattern IDCARD = Pattern.compile("(?i)(\\\"(?:[a-z]*idcard|[a-z]*identitycard|identitynumber|idnumber)\\\"\\s*:\\s*\\\")([^\\\"]*)(\\\")");
@@ -35,8 +28,7 @@
@Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// This route itself enforces the admin check and writes an audit record.
- String path = exchange.getRequest().getURI().getPath();
- if (path.startsWith("/system/sensitive/") || UNMASKED_USER_DETAILS_PATH.equals(path)) return chain.filter(exchange);
+ if (exchange.getRequest().getURI().getPath().startsWith("/system/sensitive/")) return chain.filter(exchange);
ServerHttpResponseDecorator decorated = new ServerHttpResponseDecorator(exchange.getResponse()) {
@Override public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
MediaType type = getHeaders().getContentType();
diff --git a/cloud-server-other/src/main/java/com/dsh/other/controller/SiteController.java b/cloud-server-other/src/main/java/com/dsh/other/controller/SiteController.java
index 06074d1..0019170 100644
--- a/cloud-server-other/src/main/java/com/dsh/other/controller/SiteController.java
+++ b/cloud-server-other/src/main/java/com/dsh/other/controller/SiteController.java
@@ -14,6 +14,7 @@
import com.dsh.other.enums.SiteBookingStatusEnum;
import com.dsh.other.mapper.QrLinkMapper;
import com.dsh.other.feignclient.CourseRecordClient;
+import com.dsh.other.feignclient.account.AppUserClient;
import com.dsh.other.feignclient.account.CityManagerClient;
import com.dsh.other.feignclient.activity.UserCouponClient;
import com.dsh.other.feignclient.activity.model.QueryUserCouponByIdAndUserId;
@@ -53,6 +54,7 @@
import java.util.*;
import java.security.SecureRandom;
import java.util.stream.Collectors;
+import java.util.regex.Pattern;
/**
* @author zhibing.pu
@@ -64,6 +66,7 @@
public class SiteController {
private static final char[] ENTRY_CODE_CHARS = "23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".toCharArray();
+ private static final Pattern MAINLAND_MOBILE = Pattern.compile("^1[3-9]\\d{9}$");
private final SecureRandom entryCodeRandom = new SecureRandom();
@Autowired
@@ -89,6 +92,8 @@
@Resource
private CityManagerClient cityManagerClient;
+ @Resource
+ private AppUserClient appUserClient;
@Autowired
private IOperatorUserService operatorUserService;
@@ -390,6 +395,19 @@
if (null == uid) {
return ResultUtil.tokenErr();
}
+ String phone = reservationSite.getPhone();
+ if (phone != null && phone.contains("*")) {
+ Map<String, Object> userPhone = appUserClient.siteBookingPhone(uid, "true");
+ Object originalPhone = userPhone == null ? null : userPhone.get("phone");
+ if (!(originalPhone instanceof String) || ((String) originalPhone).trim().isEmpty()) {
+ return ResultUtil.error("未获取到用户原始手机号");
+ }
+ reservationSite.setPhone((String) originalPhone);
+ } else if (phone == null || !MAINLAND_MOBILE.matcher(phone.trim()).matches()) {
+ return ResultUtil.error("请输入正确的手机号");
+ } else {
+ reservationSite.setPhone(phone.trim());
+ }
// Integer uid = 201;
return siteService.reservationSite(uid, reservationSite);
} catch (Exception e) {
diff --git a/cloud-server-other/src/main/java/com/dsh/other/feignclient/account/AppUserClient.java b/cloud-server-other/src/main/java/com/dsh/other/feignclient/account/AppUserClient.java
index 06a0fd4..1e2b234 100644
--- a/cloud-server-other/src/main/java/com/dsh/other/feignclient/account/AppUserClient.java
+++ b/cloud-server-other/src/main/java/com/dsh/other/feignclient/account/AppUserClient.java
@@ -2,7 +2,11 @@
import com.dsh.other.feignclient.account.model.AppUser;
import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestHeader;
+
+import java.util.Map;
/**
* @author zhibing.pu
@@ -28,4 +32,9 @@
*/
@PostMapping("/base/appUser/updateAppUser")
void updateAppUser(AppUser appUser);
+
+ /** Gets only the original phone for the authenticated user's site booking. */
+ @PostMapping("/internal/sensitive/site-booking/app-user/{id}/phone")
+ Map<String, Object> siteBookingPhone(@PathVariable("id") Integer appUserId,
+ @RequestHeader("X-Internal-Sensitive-Access") String sensitiveAccess);
}
--
Gitblit v1.7.1