import 'dart:async'; import 'dart:convert'; import 'package:flutter/material.dart'; import '../../api/oa_client.dart'; import '../../nav/notice_route.dart'; import '../../session/session.dart'; import '../desk_theme.dart'; import '../widgets/desk_widgets.dart'; class DeskSystemNoticePage extends StatefulWidget { const DeskSystemNoticePage({super.key, required this.session, required this.api, required this.conversationId}); final SessionStore session; final OaClient api; final String conversationId; @override State createState() => _DeskSystemNoticePageState(); } class _DeskSystemNoticePageState extends State { List> _items = []; bool _loading = true; @override void initState() { super.initState(); _load(); } Future _load() async { try { final data = await widget.api.get('/im/messages', query: {'conversationId': widget.conversationId}); if (!mounted) return; setState(() { _items = data is Map ? asMaps(data['items'] ?? data) : asMaps(data); _loading = false; }); } catch (_) { if (mounted) setState(() => _loading = false); } } Map _meta(Map row) { final raw = row['meta']; if (raw is Map) return Map.from(raw); if (raw is String && raw.isNotEmpty) { try { final d = jsonDecode(raw); if (d is Map) return Map.from(d); } catch (_) {} } return {}; } void _open(Map row) { final meta = _meta(row); openNoticeTarget( context, widget.api, session: widget.session, kind: '${meta['kind'] ?? row['kind'] ?? ''}', bizType: '${meta['bizType'] ?? ''}', bizId: '${meta['bizId'] ?? ''}', title: '${row['body'] ?? meta['title'] ?? '系统通知'}', ); } @override Widget build(BuildContext context) { return ColoredBox( color: const Color(0xFFF5F5F5), child: Column( children: [ const DeskPaneHeader(title: '系统通知'), if (_loading) const LinearProgressIndicator(minHeight: 2, color: kDeskBind), Expanded( child: _items.isEmpty ? const Center(child: Text('暂无通知', style: TextStyle(color: kDeskMute))) : ListView.builder( padding: const EdgeInsets.all(16), itemCount: _items.length, itemBuilder: (_, i) { final r = _items[i]; return Padding( padding: const EdgeInsets.only(bottom: 8), child: Material( color: Colors.white, borderRadius: BorderRadius.circular(8), child: InkWell( onTap: () => _open(r), borderRadius: BorderRadius.circular(8), child: Padding( padding: const EdgeInsets.all(14), child: Row( children: [ const Icon(Icons.notifications_none, color: kDeskBind), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('${r['body'] ?? '通知'}', style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500)), const SizedBox(height: 4), Text(shortTime(r['createdAt']), style: const TextStyle(fontSize: 12, color: kDeskMute)), ], ), ), const Icon(Icons.chevron_right, color: kDeskMute, size: 18), ], ), ), ), ), ); }, ), ), ], ), ); } }