- message_send_service:所有消息走统一门禁(登录/连接/空接收方/好友校验), 失败打印 SDK 原始 code 并映射中文提示,不再只吞异常 - chat_screen 接入统一发送服务,失败提示真实原因 - account-service 新增 GET /api/directory(登录用户可读启用员工,用于添加同事) - add_friend_screen 增加可编辑验证消息(视觉规范 4.2) - new_friends_screen 五态 + 窄屏(<360)按钮组换行不挤压姓名(视觉规范 5.3) Co-authored-by: multica-agent <github@multica.ai>
107 lines
3.5 KiB
Dart
107 lines
3.5 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_openim_sdk/flutter_openim_sdk.dart';
|
|
|
|
import '../theme.dart';
|
|
|
|
/// 添加同事:输入对方工号(userID)+ 可编辑验证消息,发送好友申请
|
|
class AddFriendScreen extends StatefulWidget {
|
|
const AddFriendScreen({super.key});
|
|
|
|
@override
|
|
State<AddFriendScreen> createState() => _AddFriendScreenState();
|
|
}
|
|
|
|
class _AddFriendScreenState extends State<AddFriendScreen> {
|
|
final TextEditingController _idCtrl = TextEditingController();
|
|
final TextEditingController _msgCtrl = TextEditingController(text: '你好,我想加你为同事');
|
|
bool _sending = false;
|
|
|
|
@override
|
|
void dispose() {
|
|
_idCtrl.dispose();
|
|
_msgCtrl.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
Future<void> _send() async {
|
|
final userID = _idCtrl.text.trim();
|
|
if (userID.isEmpty) {
|
|
_toast('请输入对方工号');
|
|
return;
|
|
}
|
|
setState(() => _sending = true);
|
|
try {
|
|
await OpenIM.iMManager.friendshipManager.addFriend(userID: userID, reason: _msgCtrl.text.trim());
|
|
if (!mounted) return;
|
|
_toast('申请已发送,等对方通过');
|
|
Navigator.of(context).pop();
|
|
} catch (_) {
|
|
_toast('发送失败,请确认工号正确、网络正常');
|
|
} finally {
|
|
if (mounted) setState(() => _sending = false);
|
|
}
|
|
}
|
|
|
|
void _toast(String text) {
|
|
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(text), duration: const Duration(seconds: 2)));
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: AppBar(title: const Text('添加同事')),
|
|
body: Padding(
|
|
padding: const EdgeInsets.all(AppGap.x4),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
children: [
|
|
TextField(
|
|
controller: _idCtrl,
|
|
decoration: InputDecoration(
|
|
hintText: '请输入对方工号',
|
|
hintStyle: const TextStyle(color: AppColors.textSecondary),
|
|
filled: true,
|
|
fillColor: AppColors.searchBg,
|
|
border: OutlineInputBorder(
|
|
borderRadius: BorderRadius.circular(8),
|
|
borderSide: BorderSide.none,
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(height: AppGap.x4),
|
|
TextField(
|
|
controller: _msgCtrl,
|
|
maxLines: 3,
|
|
minLines: 2,
|
|
decoration: InputDecoration(
|
|
hintText: '验证消息(可不填)',
|
|
hintStyle: const TextStyle(color: AppColors.textSecondary),
|
|
filled: true,
|
|
fillColor: AppColors.searchBg,
|
|
border: OutlineInputBorder(
|
|
borderRadius: BorderRadius.circular(8),
|
|
borderSide: BorderSide.none,
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(height: AppGap.x6),
|
|
SizedBox(
|
|
height: 48,
|
|
child: FilledButton(
|
|
onPressed: _sending ? null : _send,
|
|
style: FilledButton.styleFrom(
|
|
backgroundColor: AppColors.primary,
|
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
|
|
),
|
|
child: _sending
|
|
? const SizedBox(width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2, color: Colors.white))
|
|
: const Text('发送申请', style: TextStyle(fontSize: AppFont.body)),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|