Neuer 4. Login-Modus "QR" im LoginScreen: scannt den Token, den die Employee-App unter "Am Kiosk anmelden" anzeigt (POST /kiosk/my-qr-token im Haupt-Repo), meldet den Mitarbeiter per POST /kiosk/auth/qr an. Eigener QrLoginScanScreen (rohe Token-String statt JSON wie beim Geräte-Enrollment- QR). v0.1.11+12. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Dzdm3EWeNdYFUuXFRJryA1
68 lines
2.6 KiB
Dart
68 lines
2.6 KiB
Dart
import '../models/kiosk_session.dart';
|
|
import 'api_client.dart';
|
|
|
|
/// Bündelt alle /kiosk/*-Aufrufe. Device-Auth (Bearer-Token) hängt der
|
|
/// Dio-Interceptor in ApiClient automatisch an; session_token (Mitarbeiter-
|
|
/// Login) wird pro Aufruf im Body mitgegeben, siehe
|
|
/// backend/app/schemas/kiosk_auth.py.
|
|
class KioskService {
|
|
final _dio = ApiClient.instance.dio;
|
|
|
|
Future<KioskSession> loginPin(String personnelNumber, String pin) async {
|
|
final r = await _dio.post('/kiosk/auth/pin', data: {
|
|
'personnel_number': personnelNumber,
|
|
'pin': pin,
|
|
});
|
|
return KioskSession.fromJson(r.data as Map<String, dynamic>);
|
|
}
|
|
|
|
Future<KioskSession> loginNfc(String nfcUid, String pin) async {
|
|
final r = await _dio.post('/kiosk/auth/nfc', data: {
|
|
'nfc_uid': nfcUid,
|
|
'pin': pin,
|
|
});
|
|
return KioskSession.fromJson(r.data as Map<String, dynamic>);
|
|
}
|
|
|
|
Future<KioskSession> loginQr(String qrToken) async {
|
|
final r = await _dio.post('/kiosk/auth/qr', data: {'qr_token': qrToken});
|
|
return KioskSession.fromJson(r.data as Map<String, dynamic>);
|
|
}
|
|
|
|
Future<KioskSession> loginList(String userId) async {
|
|
final r = await _dio.post('/kiosk/auth/list', data: {'user_id': userId});
|
|
return KioskSession.fromJson(r.data as Map<String, dynamic>);
|
|
}
|
|
|
|
Future<List<KioskEmployee>> listEmployees() async {
|
|
final r = await _dio.get('/kiosk/auth/users');
|
|
return KioskEmployee.listFromResponse(r.data as Map<String, dynamic>);
|
|
}
|
|
|
|
Future<void> logout(String sessionToken) async {
|
|
await _dio.post('/kiosk/auth/logout', data: {'session_token': sessionToken});
|
|
}
|
|
|
|
Future<StampStatus> status(String sessionToken) async {
|
|
final r = await _dio.post('/kiosk/stamp/status', data: {'session_token': sessionToken});
|
|
return StampStatus.fromJson(r.data as Map<String, dynamic>);
|
|
}
|
|
|
|
Future<StampResult> stampIn(String sessionToken) => _stamp('in', sessionToken);
|
|
Future<StampResult> stampOut(String sessionToken) => _stamp('out', sessionToken);
|
|
Future<StampResult> breakStart(String sessionToken) => _stamp('break-start', sessionToken);
|
|
Future<StampResult> breakEnd(String sessionToken) => _stamp('break-end', sessionToken);
|
|
|
|
Future<StampResult> _stamp(String action, String sessionToken) async {
|
|
final r = await _dio.post('/kiosk/stamp/$action', data: {'session_token': sessionToken});
|
|
return StampResult.fromJson(r.data as Map<String, dynamic>);
|
|
}
|
|
|
|
Future<void> heartbeat({int queuedOfflineEntries = 0, required String clientVersion}) async {
|
|
await _dio.post('/kiosk/heartbeat', data: {
|
|
'queued_offline_entries': queuedOfflineEntries,
|
|
'client_version': clientVersion,
|
|
});
|
|
}
|
|
}
|