import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; import '../services/auth_service.dart'; class LeetCodeCard extends StatefulWidget { const LeetCodeCard({super.key}); @override State createState() => _LeetCodeCardState(); } class _LeetCodeCardState extends State { List _submissions = []; bool _isLoading = false; String? _error; Future _fetchSubmissions() async { setState(() { _isLoading = true; _error = null; }); try { final authService = Provider.of(context, listen: false); final cookie = authService.credentials['leetcode']; if (cookie == null || cookie.isEmpty) { throw Exception('未配置 LeetCode Cookie'); } final response = await http.post( Uri.parse('https://leetcode.cn/graphql/noj-go/'), headers: {'Content-Type': 'application/json', 'Cookie': cookie}, body: jsonEncode({ 'query': ''' query recentAcSubmissions(\$userSlug: String!) { recentACSubmissions(userSlug: \$userSlug) { submissionId submitTime question { title translatedTitle titleSlug questionFrontendId } } } ''', 'variables': {'userSlug': 'keen-wilsonv9s'}, 'operationName': 'recentAcSubmissions', }), ); if (response.statusCode == 200) { final data = jsonDecode(response.body); setState(() { _submissions = data['data']['recentACSubmissions']; _isLoading = false; }); } else { throw Exception('请求失败: ${response.statusCode}'); } } catch (e) { setState(() { _error = e.toString(); _isLoading = false; }); } } @override void initState() { super.initState(); _fetchSubmissions(); } @override Widget build(BuildContext context) { return Card( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Text( 'LeetCode 最近提交', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), IconButton( icon: const Icon(Icons.refresh), onPressed: _isLoading ? null : _fetchSubmissions, ), ], ), if (_isLoading) const Center( child: Padding( padding: EdgeInsets.all(16.0), child: CircularProgressIndicator(), ), ) else if (_error != null) Center( child: Padding( padding: const EdgeInsets.all(16.0), child: Text( _error!, style: const TextStyle(color: Colors.red), ), ), ) else if (_submissions.isEmpty) const Center( child: Padding( padding: EdgeInsets.all(16.0), child: Text('暂无提交记录'), ), ) else Expanded( child: ListView.builder( itemCount: _submissions.length, itemBuilder: (context, index) { final submission = _submissions[index]; final question = submission['question']; final submitTime = DateTime.fromMillisecondsSinceEpoch( submission['submitTime'] * 1000, ); return ListTile( title: Text( question['translatedTitle'] ?? question['title'], ), subtitle: Text( '提交时间: ${submitTime.toString().substring(0, 19)}', ), trailing: Text('#${question['questionFrontendId']}'), ); }, ), ), ], ), ), ); } }