fix:前后端校验手机号区域码 (#104)
Project CI / Frontend tests (push) Successful in 34s
Project CI / Backend tests (push) Failing after 39s
Project CI / Repository checks (push) Successful in 52s
Project CI / Native shell tests (push) Successful in 2m4s

来自今早群友反映
before:
![shotmd-1784692399.jpg](/attachments/3ab36252-78f4-44e2-bb51-fca84badc79e)
and failed
after:
![shotmd-1784702966.jpg](/attachments/3eea7ec9-8aca-43f6-a675-1316162619d4)
![shotmd-1784702843.jpg](/attachments/29182a41-26cf-4954-be16-de060d844d9c)
![shotmd-1784787134.jpg](/attachments/c04a1981-c6bf-4a26-b5ad-d2af51d74a29)

* https://developers.weixin.qq.com/miniprogram/dev/server/API/user-info/phone-number/api_getphonenumber.html#Res-phone-info-Object-Payload 参考微信这个文档修改了微信返回的struct 手机号 区域码字段不应是Optional

* 登录注册改密码改绑定等 api 把单一 phone字段改成 country_code(可选,缺省为86) + pure_phone_number 分别进行了前后端校验

Reviewed-on: https://git.genarrative.world/git/GenarrativeAI/Genarrative/pulls/104
Co-authored-by: 王德宇 <kvtodev@outlook.com>
Co-committed-by: 王德宇 <kvtodev@outlook.com>
This commit was merged in pull request #104.
This commit is contained in:
2026-07-23 14:52:57 +08:00
committed by 段舒康
parent b72e2163d7
commit 44748b7846
25 changed files with 650 additions and 208 deletions
+26 -7
View File
@@ -39,10 +39,9 @@ const authMocks = vi.hoisted(() => ({
}));
vi.mock('../../services/apiClient', async () => {
const actual =
await vi.importActual<typeof import('../../services/apiClient')>(
'../../services/apiClient',
);
const actual = await vi.importActual<
typeof import('../../services/apiClient')
>('../../services/apiClient');
return {
...actual,
@@ -480,9 +479,7 @@ test('auth gate opens a login modal for protected actions and resumes after logi
const phoneInput = within(dialog).getByLabelText(
'手机号',
) as HTMLInputElement;
const codeInput = within(dialog).getByLabelText(
'验证码',
) as HTMLInputElement;
const codeInput = within(dialog).getByLabelText('验证码') as HTMLInputElement;
expect(phoneInput.className).toContain('platform-text-field');
expect(codeInput.className).toContain('platform-text-field');
@@ -937,6 +934,28 @@ test('auth gate shows sms send feedback in the login modal', async () => {
expect(within(dialog).getByRole('button', { name: '60s' })).toBeTruthy();
});
test('auth gate shows mainland China phone validation errors', async () => {
const user = userEvent.setup();
authMocks.sendPhoneLoginCode.mockRejectedValueOnce(
new Error('仅支持中国大陆手机号(+86)'),
);
render(
<AuthGate>
<ProtectedActionButton onAuthenticated={vi.fn()} />
</AuthGate>,
);
await user.click(await screen.findByRole('button', { name: '进入作品' }));
const dialog = screen.getByRole('dialog', { name: '账号入口' });
await user.type(within(dialog).getByLabelText('手机号'), '+12025550123');
await user.click(within(dialog).getByRole('button', { name: '获取验证码' }));
expect(
await within(dialog).findByText('仅支持中国大陆手机号(+86)'),
).toBeTruthy();
});
test('login modal resets draft state every time it is reopened', async () => {
const user = userEvent.setup();
+6 -2
View File
@@ -530,7 +530,9 @@ function PhoneCodeForm({
tone="secondary"
size="lg"
className="shrink-0 text-sm"
onClick={() => void onSendCode()}
onClick={() => {
void onSendCode().catch(() => undefined);
}}
>
{sendingCode
? '发送中'
@@ -624,7 +626,9 @@ function PasswordResetPanel({
tone="secondary"
size="lg"
className="shrink-0 text-sm"
onClick={() => void onSendCode()}
onClick={() => {
void onSendCode().catch(() => undefined);
}}
>
{sendingCode
? '发送中'