修复全页面走查发现的问题(第四批:精准查找、隐私锁定、搜索防抖)
精准查找搜不到手机号(第5章 5.5)
- 一直写死 type=exact_account,而该分支只比对 profile.public_account / u.username / u.id
(tenant_adapter.go:9170-9172),**不匹配 u.phone**。参考图 5.5 里输的恰恰是手机号,
这个场景必然搜不到。改为按输入形态分流:11 位 1 开头走 type=phone。
- phone 分支服务端不做 E.164 归一化(只有模糊的 account 分支才调 normalizeUserPhone),
库里存的是 +86 开头,所以裸号码由前端补区号——注册流程本来也是这么拼的。
- 已用真实后端验证请求正确路由为 q=%2B8613800001188&type=phone。
隐私设置忽略 editable(第10章 10.12/10.13)
- 后端 userPrivacyPayload 返回 editable{add_me_methods, profile_visibility,
last_seen_visibility, read_receipts} 表达"企业强制策略锁死了这一项",前端完全没读。
被锁的开关照样能点,点了 400 再回滚,用户只看到开关自己弹回去。现在禁用并给出说明文案,
同时补 .personal-switch:disabled 的视觉反馈(否则看不出为什么点不动)。
搜索防抖
- 新增共享的 useDebouncedValue,用在三处真正发服务端请求的搜索:收藏、会话内检索、
群列表、群文件。原来 query 直接进 effect 依赖,每敲一个字符发一次请求;群列表更糟,
reload 对三个分类各发一次,一个字符就是 3 个请求。而且返回顺序没有保证,后发的短前缀
请求可能后到、把正确结果覆盖掉。
- 实测:群列表输入 4 个字,请求数从 12 降到 3。
- FavoriteShare 那处搜索是本地过滤 chatList、不发请求,没有动。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
c9b8125013
commit
35d3e1cf6b
@@ -195,6 +195,21 @@ function FriendRequests({onToast}) {
|
||||
</main></div>;
|
||||
}
|
||||
|
||||
// 中国大陆手机号:11 位、1 开头。与本文件注册/验证流程用的判断保持一致。
|
||||
const CN_MOBILE = /^1[3-9]\d{9}$/;
|
||||
|
||||
function classifySearchInput(text) {
|
||||
if (text.startsWith('+')) {
|
||||
// 已经是国际格式,原样按手机号查
|
||||
return {query: text.replace(/[\s-]/g, ''), type: 'phone'};
|
||||
}
|
||||
const digits = text.replace(/[\s-]/g, '');
|
||||
if (CN_MOBILE.test(digits)) {
|
||||
return {query: '+86' + digits, type: 'phone'};
|
||||
}
|
||||
return {query: text, type: 'exact_account'};
|
||||
}
|
||||
|
||||
// 与 personal-settings-view.jsx 的 GENDER_OPTIONS 一一对应,两处写的是同一套后端枚举
|
||||
const GENDER_LABELS = {male: '男', female: '女', other: '其他'};
|
||||
|
||||
@@ -222,9 +237,16 @@ function AddFriend({result = false, onToast, onOpenScanner}) {
|
||||
const [searched, setSearched] = React.useState(result);
|
||||
const [results, setResults] = React.useState([]);
|
||||
const runSearch = q => {
|
||||
if (!q.trim()) { setSearched(false); setResults([]); return; }
|
||||
const text = q.trim();
|
||||
if (!text) { setSearched(false); setResults([]); return; }
|
||||
setSearching(true); setSearched(true);
|
||||
searchUsers(q.trim(), 'exact_account').then(data => setResults(data.items || [])).catch(() => setResults([])).finally(() => setSearching(false));
|
||||
// 按输入形态选搜索类型。exact_account 只比对 profile.public_account / u.username / u.id
|
||||
// (tenant_adapter.go:9170-9172),**不匹配 u.phone** —— 参考图 5.5 里输的恰恰是手机号
|
||||
// 18826827724,一直写死 exact_account 的话这个场景必然搜不到。手机号要走 type=phone。
|
||||
// 另外 phone 分支服务端不做 E.164 归一化(只有模糊的 account 分支才调 normalizeUserPhone),
|
||||
// 而库里存的是 +86 开头的 E.164,所以裸 11 位号码由前端补上区号——注册流程也是这么拼的。
|
||||
const {query, type} = classifySearchInput(text);
|
||||
searchUsers(query, type).then(data => setResults(data.items || [])).catch(() => setResults([])).finally(() => setSearching(false));
|
||||
};
|
||||
const shareCard = () => {
|
||||
createMyQRCode().then(data => {
|
||||
|
||||
Reference in New Issue
Block a user