修复工作人员作业预检状态与提示
This commit is contained in:
@@ -29,7 +29,7 @@ class GeolocatorLocationService implements LocationService {
|
||||
permission = await Geolocator.requestPermission();
|
||||
}
|
||||
if (permission == LocationPermission.denied || permission == LocationPermission.deniedForever) {
|
||||
throw StateError('定位权限未授权,无法完成该在线动作');
|
||||
throw StateError('定位权限未授权,请在浏览器站点权限或系统设置中允许定位后重试');
|
||||
}
|
||||
final position = await Geolocator.getCurrentPosition();
|
||||
return LocationPoint(
|
||||
|
||||
@@ -35,6 +35,12 @@ class PreflightResult {
|
||||
final bool canWork;
|
||||
final Map<String, Object?> checks;
|
||||
|
||||
/// 仅统计真正阻止进入工作台的检查项。
|
||||
int get blockerCount => checks.values.where((value) {
|
||||
final detail = _map(value);
|
||||
return detail['status'] == 'blocked';
|
||||
}).length;
|
||||
|
||||
factory PreflightResult.fromJson(Map<String, Object?> json) => PreflightResult(
|
||||
roleCode: json['role_code'] as String? ?? '',
|
||||
workStatus: json['work_status'] as String? ?? 'off_duty',
|
||||
|
||||
@@ -46,7 +46,15 @@ class _PreflightPageState extends State<PreflightPage> {
|
||||
return;
|
||||
} catch (error) {
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(error.toString())));
|
||||
final message = error is StateError ? error.message : error.toString();
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(message),
|
||||
action: error is StateError
|
||||
? SnackBarAction(label: '重新授权', onPressed: () => _attendance(action))
|
||||
: null,
|
||||
),
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
if (mounted) setState(() => _busy = false);
|
||||
@@ -107,7 +115,7 @@ class _PreflightPageState extends State<PreflightPage> {
|
||||
else ...[
|
||||
FilledButton(
|
||||
onPressed: result.canWork ? () => context.go('/work') : null,
|
||||
child: const Text('进入工作台'),
|
||||
child: Text(result.canWork ? '进入工作台' : '完成 ${result.blockerCount} 项阻断后可进入'),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
TextButton(
|
||||
@@ -200,17 +208,28 @@ class _CheckRow extends StatelessWidget {
|
||||
final tone = passed
|
||||
? StatusTone.success
|
||||
: status == 'not_configured'
|
||||
? StatusTone.warning
|
||||
? StatusTone.neutral
|
||||
: StatusTone.danger;
|
||||
final text = status == 'not_configured'
|
||||
? '平台暂未启用'
|
||||
? '暂不检查'
|
||||
: passed
|
||||
? '已通过'
|
||||
: '未通过';
|
||||
final description = entry.key == 'credential' && !passed
|
||||
? _credentialDescription(detail['reason']?.toString())
|
||||
: null;
|
||||
return ListTile(
|
||||
leading: Icon(passed ? Icons.check_circle_outline : Icons.info_outline_rounded),
|
||||
title: Text(label),
|
||||
subtitle: description == null ? null : Text(description),
|
||||
trailing: StatusPill(label: text, tone: tone),
|
||||
);
|
||||
}
|
||||
|
||||
/// 将服务端稳定原因码转换为可执行的中文处理说明。
|
||||
String _credentialDescription(String? reason) => switch (reason) {
|
||||
'expired' => '人员资质已过期,请联系所属组织管理员更新',
|
||||
'disabled' => '人员资质已停用,请联系所属组织管理员处理',
|
||||
_ => '尚未配置有效资质,请联系所属组织管理员补充或审核',
|
||||
};
|
||||
}
|
||||
|
||||
@@ -51,6 +51,26 @@ class _FailOnceRepository extends ServiceRepository {
|
||||
}
|
||||
}
|
||||
|
||||
/// 返回包含一个真实阻断项和一个暂不检查项的固定预检结果。
|
||||
class _BlockedRepository extends ServiceRepository {
|
||||
_BlockedRepository()
|
||||
: super(
|
||||
ApiClient(() => '', baseUrl: 'https://api.example.com'),
|
||||
_UnusedLocationService(),
|
||||
);
|
||||
|
||||
@override
|
||||
Future<PreflightResult> preflight() async => const PreflightResult(
|
||||
roleCode: 'delivery',
|
||||
workStatus: 'on_duty',
|
||||
canWork: false,
|
||||
checks: {
|
||||
'credential': {'status': 'blocked', 'reason': 'missing'},
|
||||
'daily_training': {'status': 'not_configured'},
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// 点击重新加载后应成功刷新,且测试过程不得出现 Flutter 断言。
|
||||
void main() {
|
||||
testWidgets('作业检查失败后可重新加载', (tester) async {
|
||||
@@ -74,4 +94,21 @@ void main() {
|
||||
expect(repository.calls, 2);
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
|
||||
testWidgets('仅统计阻断项并显示资质处理指引', (tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: PreflightPage(
|
||||
session: StaffSession(_EmptySessionStore()),
|
||||
repository: _BlockedRepository(),
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('完成 1 项阻断后可进入'), findsOneWidget);
|
||||
expect(find.text('暂不检查'), findsOneWidget);
|
||||
expect(find.text('尚未配置有效资质,请联系所属组织管理员补充或审核'), findsOneWidget);
|
||||
expect(find.text('下班打卡'), findsOneWidget);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user