From 0748f30cc11fc10f568f1b0d700f2b9eff938397 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 6 Sep 2026 13:21:05 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E5=90=8D=E8=AE=A4=E8=AF=81=E6=8F=90?= =?UTF-8?q?=E4=BA=A4=E6=88=90=E5=8A=9F=E5=90=8E=E8=A1=A5=E6=8B=89=E4=B8=80?= =?UTF-8?q?=E6=AC=A1=20GET=EF=BC=8C=E7=94=A8=E6=9C=8D=E5=8A=A1=E7=AB=AF?= =?UTF-8?q?=E8=84=B1=E6=95=8F=E5=AD=97=E6=AE=B5=E6=9B=BF=E6=8D=A2=E6=9C=AC?= =?UTF-8?q?=E5=9C=B0=E8=8D=89=E7=A8=BF=E5=9B=9E=E6=98=BE=EF=BC=88=E6=96=B0?= =?UTF-8?q?=E5=A2=9E61=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 现象(IM-后端问题清单-2026-09-04.md"新增61"):POST /security/realname/submissions 成功响应只有 {status, submission_id},从不带 masked_name/masked_id_number,前端此前 的兜底是回显用户本次会话里刚输入的原始姓名/证件号草稿——多数情况下看起来没问题, 但那是未脱敏的原始值,不是服务端认可的脱敏展示值,且只覆盖"这次会话内",换一个 从未在本会话提交过的场景(比如同一账号换设备/清缓存后第一次看提交结果)就没有任何 草稿可回退,只能空白。 之前的复核已经确认 GET /security/realname 从这个功能最初上线的 commit 起就一直带着 masked_name/masked_id_number 这两个字段,只是提交成功后从未再调用过它。 修法:submit() 里 POST 成功后追加一次 getRealnameStatus(),用响应里的 masked_name/masked_id_number 覆盖本地状态,展示服务端脱敏后的真实值;这次追加请求 失败时静默忽略(提交本身已经成功,不应该因为这次锦上添花的请求失败而回退),保留 原有的本会话草稿兜底作为这次请求解析完成前的过渡显示。 验证:注册全新测试账号(无历史提交),提交姓名"测试用户"+证件号 110105199003077856 后,抓包确认 POST 响应确实只有 {status,submission_id},紧接着 自动触发的 GET 响应带 masked_name:"测*"、masked_id_number:"110***********7856"; 页面输入框读取到的实际 value 是这两个脱敏值,不是刚输入的原始文本,证实修复生效。 Co-Authored-By: Claude Sonnet 5 --- src/views/auth-onboarding-view.jsx | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/views/auth-onboarding-view.jsx b/src/views/auth-onboarding-view.jsx index 64d71714..ec758925 100644 --- a/src/views/auth-onboarding-view.jsx +++ b/src/views/auth-onboarding-view.jsx @@ -678,6 +678,16 @@ function Realname({authenticated = false}) { const data = await submitRealname({name: name.trim(), id_type: 'cn_id', id_number: idNumber.toUpperCase()}); setStatus(data.status || 'pending'); setError(''); + // The submissions POST only ever returns {status, submission_id} -- never masked_name/ + // masked_id_number -- but GET /security/realname has carried both fields since this feature's + // original commit (confirmed against server source), we just weren't calling it again right + // after a successful submit. Best-effort: the submission itself already succeeded above, so a + // failure here shouldn't take that away from the user -- it just means the pre-existing + // fallback below (this session's own typed draft) keeps covering the display like before. + getRealnameStatus().then(fresh => { + if (fresh.masked_name) setMaskedName(fresh.masked_name); + if (fresh.masked_id_number) setMaskedIdNumber(fresh.masked_id_number); + }).catch(() => {}); } catch (err) { setError(err.message || '提交失败,请稍后重试'); } finally { @@ -701,12 +711,14 @@ function Realname({authenticated = false}) { 一旦账号真的走到 verified 状态就会显示一句参考图里根本不存在的标题。 */}

请您使用有效身份证信息认证

- {/* submitRealname's success response never actually carries masked_name/masked_id_number - (only {status, submission_id}) -- falling back to what was just typed (still sitting in - `name`/`idNumber` local state) means a fresh submission at least shows the user what - they submitted, instead of switching straight from their typed input to two blank - fields the instant `editable` flips false. Only degrades to genuinely blank on a fresh - page load with no draft in this session, which is the pre-existing, unavoidable case. */} + {/* submitRealname's own success response never carries masked_name/masked_id_number (only + {status, submission_id}) -- submit() above now follows up with a GET /security/realname + to fetch the server's authoritative masked values right after a successful submission, so + this local-draft fallback (`name`/`idNumber`, still sitting in state from what was just + typed) only matters for the brief window before that GET resolves. It still degrades to + genuinely blank on a fresh page load with no draft in this session and no masked value + from a prior GET either (e.g. a submission made in an earlier session) -- that residual + case isn't fixable from here since it depends on the follow-up GET actually having run. */} {error ?
{error}
: null}