import 'package:flutter/material.dart'; import '../api/oa_client.dart'; import '../theme.dart'; import '../widgets/wecom.dart'; class PickPeoplePage extends StatefulWidget { const PickPeoplePage({ super.key, required this.api, required this.title, this.multiple = true, this.exclude = const {}, }); final OaClient api; final String title; final bool multiple; final Set exclude; @override State createState() => _PickPeoplePageState(); } class _PickPeoplePageState extends State { List> _items = []; final _selected = {}; String _q = ''; bool _loading = true; @override void initState() { super.initState(); _load(); } Future _load() async { try { final data = await widget.api.get('/staff'); if (!mounted) return; setState(() { _items = asMaps(data); _loading = false; }); } catch (_) { if (mounted) setState(() => _loading = false); } } @override Widget build(BuildContext context) { final shown = _items.where((e) { final id = '${e['id']}'; if (widget.exclude.contains(id)) return false; if (_q.isEmpty) return true; return '${e['name']}${e['department']}${e['title']}'.contains(_q); }).toList(); return Scaffold( backgroundColor: Colors.white, appBar: AppBar( title: Text(widget.title), leading: IconButton(icon: const Icon(Icons.close), onPressed: () => Navigator.pop(context)), actions: [ if (widget.multiple) TextButton( onPressed: _selected.isEmpty ? null : () => Navigator.pop(context, _selected.entries.map((e) => {'id': e.key, 'name': e.value}).toList()), child: Text('确定(${_selected.length})'), ), ], ), body: Column( children: [ WxSearchBar(hint: '搜索同事', onChanged: (v) => setState(() => _q = v.trim())), if (_loading) const LinearProgressIndicator(minHeight: 2, color: kBind), Expanded( child: ListView.builder( itemCount: shown.length, itemBuilder: (_, i) { final r = shown[i]; final id = '${r['id']}'; final name = '${r['name'] ?? ''}'; final on = _selected.containsKey(id); return InkWell( onTap: () { if (!widget.multiple) { Navigator.pop(context, [ {'id': id, 'name': name}, ]); return; } setState(() { if (on) { _selected.remove(id); } else { _selected[id] = name; } }); }, child: Padding( padding: const EdgeInsets.fromLTRB(12, 10, 12, 0), child: Row( children: [ if (widget.multiple) Padding( padding: const EdgeInsets.only(right: 10), child: Icon(on ? Icons.check_circle : Icons.circle_outlined, color: on ? kBind : kMute, size: 22), ), SquareAvatar( label: name, fileId: '${r['avatarFileId'] ?? ''}', api: widget.api, ), const SizedBox(width: 10), Expanded( child: Container( padding: const EdgeInsets.only(bottom: 10), decoration: const BoxDecoration(border: Border(bottom: BorderSide(color: kLine, width: 0.5))), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(name, style: const TextStyle(fontSize: 16)), Text( [r['department'], r['title']].where((e) => e != null && '$e'.isNotEmpty).join(' · '), style: const TextStyle(fontSize: 12, color: kMute), ), ], ), ), ), ], ), ), ); }, ), ), ], ), ); } }