feat: 장비 관리 기능 강화 및 이력 추적 개선
- EquipmentHistoryDto 모델 확장 (상세 정보 추가) - 장비 이력 화면 UI/UX 개선 - 장비 입고 폼 검증 로직 강화 - 테스트 이력 화면 추가 - API 응답 처리 개선 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
183
lib/screens/equipment/test_history_screen.dart
Normal file
183
lib/screens/equipment/test_history_screen.dart
Normal file
@@ -0,0 +1,183 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:superport/services/equipment_service.dart';
|
||||
import 'package:superport/data/models/equipment/equipment_history_dto.dart';
|
||||
|
||||
class TestHistoryScreen extends StatefulWidget {
|
||||
const TestHistoryScreen({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<TestHistoryScreen> createState() => _TestHistoryScreenState();
|
||||
}
|
||||
|
||||
class _TestHistoryScreenState extends State<TestHistoryScreen> {
|
||||
final EquipmentService _equipmentService = GetIt.instance<EquipmentService>();
|
||||
final TextEditingController _idController = TextEditingController(text: '1');
|
||||
List<EquipmentHistoryDto>? _histories;
|
||||
bool _isLoading = false;
|
||||
String? _error;
|
||||
|
||||
Future<void> _testAddHistory() async {
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
_error = null;
|
||||
});
|
||||
|
||||
try {
|
||||
final equipmentId = int.tryParse(_idController.text) ?? 1;
|
||||
|
||||
// 테스트 이력 추가
|
||||
await _equipmentService.addEquipmentHistory(
|
||||
equipmentId,
|
||||
'I', // transaction type
|
||||
10, // quantity
|
||||
'Test history added at ${DateTime.now()}', // remarks
|
||||
);
|
||||
|
||||
// 이력 다시 조회
|
||||
await _testGetHistory();
|
||||
|
||||
} catch (e) {
|
||||
setState(() {
|
||||
_error = 'Error adding history: $e';
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _testGetHistory() async {
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
_error = null;
|
||||
_histories = null;
|
||||
});
|
||||
|
||||
try {
|
||||
final equipmentId = int.tryParse(_idController.text) ?? 1;
|
||||
|
||||
print('[TEST] Fetching history for equipment ID: $equipmentId');
|
||||
|
||||
final histories = await _equipmentService.getEquipmentHistory(
|
||||
equipmentId,
|
||||
page: 1,
|
||||
perPage: 20,
|
||||
);
|
||||
|
||||
print('[TEST] Received ${histories.length} history records');
|
||||
|
||||
setState(() {
|
||||
_histories = histories;
|
||||
_isLoading = false;
|
||||
});
|
||||
} catch (e) {
|
||||
print('[TEST ERROR] $e');
|
||||
setState(() {
|
||||
_error = 'Error: $e';
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Equipment History Test'),
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: _idController,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Equipment ID',
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
keyboardType: TextInputType.number,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
ElevatedButton(
|
||||
onPressed: _isLoading ? null : _testGetHistory,
|
||||
child: const Text('Get History'),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
ElevatedButton(
|
||||
onPressed: _isLoading ? null : _testAddHistory,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.green,
|
||||
),
|
||||
child: const Text('Add Test History'),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
if (_isLoading)
|
||||
const Center(child: CircularProgressIndicator())
|
||||
else if (_error != null)
|
||||
Card(
|
||||
color: Colors.red[50],
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Text(
|
||||
_error!,
|
||||
style: const TextStyle(color: Colors.red),
|
||||
),
|
||||
),
|
||||
)
|
||||
else if (_histories != null)
|
||||
Expanded(
|
||||
child: Card(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Found ${_histories!.length} history records',
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
const Divider(),
|
||||
Expanded(
|
||||
child: _histories!.isEmpty
|
||||
? const Center(child: Text('No history found'))
|
||||
: ListView.builder(
|
||||
itemCount: _histories!.length,
|
||||
itemBuilder: (context, index) {
|
||||
final history = _histories![index];
|
||||
return Card(
|
||||
margin: const EdgeInsets.symmetric(vertical: 4),
|
||||
child: ListTile(
|
||||
leading: CircleAvatar(
|
||||
child: Text(history.transactionType),
|
||||
),
|
||||
title: Text('Quantity: ${history.quantity}'),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('Remarks: ${history.remarks ?? "N/A"}'),
|
||||
Text('Date: ${history.transactionDate}'),
|
||||
Text('User: ${history.userName ?? "Unknown"}'),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user