feat(client/auth): 注册页加邀请码(选填)输入,提交时传 invite_code

This commit is contained in:
wangjia
2026-07-13 08:00:25 +08:00
parent e061237496
commit 0b24e26fb6
2 changed files with 117 additions and 2 deletions
+14 -2
View File
@@ -24,10 +24,14 @@ const _easeOut = Cubic(0.22, 1, 0.36, 1);
enum _AuthMode { login, register }
class AuthScreen extends ConsumerStatefulWidget {
const AuthScreen({super.key, required this.onDone, required this.t});
const AuthScreen({super.key, required this.onDone, required this.t, this.api});
final VoidCallback onDone;
final AppText t;
/// 测试可注入(见 test/widget/auth_invite_field_test.dart);生产不传,内部
/// 用 kApiBaseUrl 现建一个,行为不变。
final AuthApi? api;
@override
ConsumerState<AuthScreen> createState() => _AuthScreenState();
}
@@ -44,6 +48,7 @@ class _AuthScreenState extends ConsumerState<AuthScreen>
final _email = TextEditingController();
final _code = TextEditingController();
final _pw = TextEditingController();
final _invite = TextEditingController();
final _emailFocus = FocusNode();
final _pwFocus = FocusNode();
@@ -54,7 +59,7 @@ class _AuthScreenState extends ConsumerState<AuthScreen>
duration: const Duration(milliseconds: 620),
);
late final AuthApi _api = AuthApi(baseUrl: kApiBaseUrl);
late final AuthApi _api = widget.api ?? AuthApi(baseUrl: kApiBaseUrl);
bool get _emailValid => RegExp(r'\S+@\S+\.\S+').hasMatch(_email.text);
@@ -79,6 +84,7 @@ class _AuthScreenState extends ConsumerState<AuthScreen>
_email.dispose();
_code.dispose();
_pw.dispose();
_invite.dispose();
_emailFocus.dispose();
_pwFocus.dispose();
_codeFocus.dispose();
@@ -108,6 +114,7 @@ class _AuthScreenState extends ConsumerState<AuthScreen>
code: _code.text.trim(),
password: _pw.text,
device: device,
inviteCode: _invite.text.trim(),
);
await ref.read(tokenStoreProvider).saveLastEmail(_email.text.trim());
await ref.read(authProvider.notifier).saveTokens(tokens);
@@ -464,6 +471,11 @@ class _AuthScreenState extends ConsumerState<AuthScreen>
),
const SizedBox(height: 16),
_field(c, icon: PangolinIcons.lock, label: t.pwLabel, focused: _pwFocus.hasFocus, child: _pwInput(c, t.setPwPh, onSubmit: _submitRegister)),
const SizedBox(height: 16),
_field(c, icon: PangolinIcons.gift, label: t.inviteCodeFieldLabel, focused: false,
child: TextField(key: const Key('invite-code-field'), controller: _invite,
textInputAction: TextInputAction.done,
decoration: _bare.copyWith(hintText: ''))),
const SizedBox(height: 18),
_primaryBtn(c, label: _loading ? '...' : t.doCreate,
onPressed: (!_loading && _pw.text.length >= 6) ? _doRegister : null),