스마트기기 반출 대장: 1시간 59분 이상 요청은 목록에서 빨간 테두리로 표시
기존엔 "많은 시간요청 학생" 팝업에서만 2시간 기준으로 걸러냈는데, 메인 목록 카드 자체에도 (대기중/승인/거절 등 상태 무관하게) 빨간 테두리를 씌워서 바로 눈에 띄게 함. 기준을 2시간 → 1시간 59분(119분)으로 낮춰서 두 기능이 같은 기준을 쓰도록 통일. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -16,25 +16,38 @@ class DeviceCheckoutLedgerController extends ChangeNotifier {
|
||||
bool get isLoading => _isLoading;
|
||||
bool get isWorking => _isWorking;
|
||||
|
||||
/// ⏰ 요청 시간이 얼마나 되는지(시간 단위). 형식이 이상하면 null.
|
||||
double? durationHours(dynamic request) {
|
||||
// 🚨 [장시간 요청 기준] 1시간 59분(119분) 이상이면 "많은 시간요청"으로 본다.
|
||||
static const int longRequestMinutes = 119;
|
||||
|
||||
int? _durationMinutes(dynamic request) {
|
||||
try {
|
||||
final start = DateTime.parse(request['requestedStart']);
|
||||
final end = DateTime.parse(request['requestedEnd']);
|
||||
final minutes = end.difference(start).inMinutes;
|
||||
return minutes > 0 ? minutes / 60.0 : null;
|
||||
return minutes > 0 ? minutes : null;
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// 🚨 [장시간 요청 감지] 2시간 넘게 신청한, 아직 대기 중인 요청 목록.
|
||||
/// 학생이 시간을 비정상적으로 길게 적어냈을 수 있으니 전체 승인 전에 따로 훑어볼 수 있게 한다.
|
||||
List<dynamic> get longPendingRequests => _requests.where((r) {
|
||||
if (r['status'] != 'PENDING') return false;
|
||||
final hours = durationHours(r);
|
||||
return hours != null && hours >= 2;
|
||||
}).toList();
|
||||
/// ⏰ 요청 시간이 얼마나 되는지(시간 단위). 형식이 이상하면 null.
|
||||
double? durationHours(dynamic request) {
|
||||
final minutes = _durationMinutes(request);
|
||||
return minutes == null ? null : minutes / 60.0;
|
||||
}
|
||||
|
||||
/// 🚨 [장시간 요청 감지] 1시간 59분 넘게 신청했는지. 상태(대기/승인 등)와 무관하게 판단한다 -
|
||||
/// 목록 카드에 빨간 테두리를 씌우는 데 쓴다.
|
||||
bool isLongRequest(dynamic request) {
|
||||
final minutes = _durationMinutes(request);
|
||||
return minutes != null && minutes >= longRequestMinutes;
|
||||
}
|
||||
|
||||
/// 학생이 시간을 비정상적으로 길게 적어냈을 수 있으니, 아직 대기 중인 장시간 요청만
|
||||
/// 따로 모아서 전체 승인 전에 훑어볼 수 있게 한다.
|
||||
List<dynamic> get longPendingRequests => _requests
|
||||
.where((r) => r['status'] == 'PENDING' && isLongRequest(r))
|
||||
.toList();
|
||||
|
||||
void _safeNotify() {
|
||||
if (!_disposed) notifyListeners();
|
||||
|
||||
@@ -89,7 +89,7 @@ class _DeviceCheckoutLedgerPageState extends State<DeviceCheckoutLedgerPage> {
|
||||
);
|
||||
}
|
||||
|
||||
// 🚨 [많은 시간요청 학생] 2시간 넘게 신청한 대기 중인 요청만 따로 모아 보여준다.
|
||||
// 🚨 [많은 시간요청 학생] 1시간 59분 넘게 신청한 대기 중인 요청만 따로 모아 보여준다.
|
||||
// 학생이 시간을 비정상적으로 길게 적어냈을 수 있으니, 전체 승인 전에 훑어보는 용도.
|
||||
void _showLongRequestsDialog() {
|
||||
showDialog(
|
||||
@@ -113,7 +113,7 @@ class _DeviceCheckoutLedgerPageState extends State<DeviceCheckoutLedgerPage> {
|
||||
return const Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 16),
|
||||
child: Text(
|
||||
'2시간 넘게 신청한 대기 중인 요청이 없습니다.',
|
||||
'1시간 59분 넘게 신청한 대기 중인 요청이 없습니다.',
|
||||
style: TextStyle(color: Colors.grey),
|
||||
),
|
||||
);
|
||||
@@ -320,6 +320,10 @@ class _DeviceCheckoutLedgerPageState extends State<DeviceCheckoutLedgerPage> {
|
||||
final String status = r['status'];
|
||||
final info = _statusInfo(status);
|
||||
final bool isPending = status == 'PENDING';
|
||||
// 🚨 1시간 59분 넘게 신청했으면 상태와 무관하게 빨간 테두리로 눈에 띄게.
|
||||
final bool isLong = _controller.isLongRequest(
|
||||
r,
|
||||
);
|
||||
|
||||
return Card(
|
||||
elevation: 0,
|
||||
@@ -327,9 +331,18 @@ class _DeviceCheckoutLedgerPageState extends State<DeviceCheckoutLedgerPage> {
|
||||
margin: const EdgeInsets.only(bottom: 10),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
side: isPending
|
||||
? BorderSide(color: Colors.orange[300]!)
|
||||
: BorderSide(color: AppPalette.sage),
|
||||
side: isLong
|
||||
? BorderSide(
|
||||
color: Colors.red[400]!,
|
||||
width: 2,
|
||||
)
|
||||
: (isPending
|
||||
? BorderSide(
|
||||
color: Colors.orange[300]!,
|
||||
)
|
||||
: BorderSide(
|
||||
color: AppPalette.sage,
|
||||
)),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
|
||||
Reference in New Issue
Block a user