Files
Public/apps/native/lib/pages/notice_detail_page.dart
T
daiyongkang 76f266645d Initial commit: 风影 OA 全栈源码(API/Web/Flutter/IM)
含 Phase 1.1 IM seq 排序、断线重连、多端已读同步与微信式语音转文字 UI。
排除 node_modules、构建产物、安装包与 .env 密钥。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-02 10:04:03 +00:00

74 lines
2.4 KiB
Dart

import 'package:flutter/material.dart';
import '../api/oa_client.dart';
import '../theme.dart';
import '../widgets/html_body.dart';
class NoticeDetailPage extends StatefulWidget {
const NoticeDetailPage({super.key, required this.api, required this.id, this.title = '公告'});
final OaClient api;
final String id;
final String title;
@override
State<NoticeDetailPage> createState() => _NoticeDetailPageState();
}
class _NoticeDetailPageState extends State<NoticeDetailPage> {
Map<String, dynamic> _row = {};
bool _loading = true;
String _err = '';
@override
void initState() {
super.initState();
_load();
}
Future<void> _load() async {
try {
final data = await widget.api.get('/office/notices/${widget.id}');
if (!mounted) return;
setState(() {
_row = data is Map ? Map<String, dynamic>.from(data) : {};
_loading = false;
});
} catch (e) {
if (!mounted) return;
setState(() {
_err = '$e';
_loading = false;
});
}
}
@override
Widget build(BuildContext context) {
final title = '${_row['title'] ?? widget.title}';
final author = '${(_row['createdBy'] is Map ? (_row['createdBy'] as Map)['displayName'] : '')}';
final time = fmtTime(_row['createdAt'] ?? _row['publishedAt']);
final content = '${_row['content'] ?? ''}';
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(title: const Text('通知公告'), leading: const BackButton()),
body: _loading
? const Center(child: CircularProgressIndicator())
: _err.isNotEmpty
? Center(child: Padding(padding: const EdgeInsets.all(24), child: Text(_err, style: const TextStyle(color: kMute))))
: ListView(
padding: const EdgeInsets.fromLTRB(20, 16, 20, 40),
children: [
Text(title, style: const TextStyle(fontSize: 22, fontWeight: FontWeight.w700, color: kInk, height: 1.35)),
const SizedBox(height: 8),
Text(
[if (author.isNotEmpty) author, if (time.isNotEmpty) time].join(' '),
style: const TextStyle(fontSize: 13, color: kMute),
),
const SizedBox(height: 20),
HtmlBody(html: content, api: widget.api),
],
),
);
}
}