feat: add Flutter mobile clients and staff delivery API

This commit is contained in:
david
2026-07-30 21:47:41 +08:00
parent 550efb3812
commit 36a5ced1c0
228 changed files with 17159 additions and 22 deletions

View File

@@ -0,0 +1,116 @@
import 'package:flutter/material.dart';
import '../../../app/dependencies.dart';
class LoginPage extends StatefulWidget {
const LoginPage({required this.session, super.key});
final StaffSession session;
@override
State<LoginPage> createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
final _phone = TextEditingController();
final _password = TextEditingController();
bool _busy = false;
String? _error;
Future<void> _login() async {
setState(() {
_busy = true;
_error = null;
});
try {
await widget.session.login(_phone.text.trim(), _password.text);
} catch (error) {
if (mounted) setState(() => _error = error.toString());
} finally {
if (mounted) setState(() => _busy = false);
}
}
@override
void dispose() {
_phone.dispose();
_password.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) => Scaffold(
body: SafeArea(
child: Center(
child: SingleChildScrollView(
padding: const EdgeInsets.all(24),
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 420),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Icon(
Icons.engineering_rounded,
size: 72,
color: Theme.of(context).colorScheme.primary,
),
const SizedBox(height: 20),
Text(
'瓶安芯服务工作台',
textAlign: TextAlign.center,
style: Theme.of(
context,
).textTheme.headlineMedium?.copyWith(fontWeight: FontWeight.w900),
),
const SizedBox(height: 8),
const Text('配送、安装维修与安检共用入口', textAlign: TextAlign.center),
const SizedBox(height: 34),
TextField(
controller: _phone,
keyboardType: TextInputType.phone,
decoration: const InputDecoration(
labelText: '工作人员手机号',
prefixIcon: Icon(Icons.phone_outlined),
),
),
const SizedBox(height: 14),
TextField(
controller: _password,
obscureText: true,
decoration: const InputDecoration(
labelText: '登录密码',
prefixIcon: Icon(Icons.lock_outline),
),
),
if (_error != null)
Padding(
padding: const EdgeInsets.only(top: 12),
child: Text(
_error!,
style: TextStyle(color: Theme.of(context).colorScheme.error),
),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: _busy ? null : _login,
child: _busy
? const SizedBox.square(
dimension: 22,
child: CircularProgressIndicator(strokeWidth: 2),
)
: const Text('进入工作台'),
),
const SizedBox(height: 12),
const Text(
'账号与角色由平台审核分配,不提供自助注册',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 12),
),
],
),
),
),
),
),
);
}