You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

293 lines
11 KiB

4 years ago
import 'package:bytedesk_kefu/bytedesk_kefu.dart';
4 years ago
import 'package:bytedesk_kefu/util/bytedesk_constants.dart';
import 'package:bytedesk_kefu/util/bytedesk_events.dart';
4 years ago
import 'package:bytedesk_kefu/util/bytedesk_utils.dart';
import 'package:bytedesk_demo/notification/custom_notification.dart';
4 years ago
import 'package:bytedesk_demo/page/chat_type_page.dart';
import 'package:bytedesk_demo/page/history_thread_page.dart';
import 'package:bytedesk_demo/page/online_status_page.dart';
4 years ago
import 'package:bytedesk_demo/page/setting_page.dart';
4 years ago
import 'package:bytedesk_demo/page/user_info_page.dart';
4 years ago
import 'package:overlay_support/overlay_support.dart';
4 years ago
import 'package:flutter/material.dart';
3 years ago
// import 'package:vibration/vibration.dart';
4 years ago
import 'package:audioplayers/audioplayers.dart';
4 years ago
4 years ago
void main() {
// runApp(MyApp());
4 years ago
runApp(OverlaySupport(
4 years ago
child: MaterialApp(
debugShowCheckedModeBanner: false, // 去除右上角debug的标签
home: MyApp(),
)));
4 years ago
4 years ago
// 参考文档https://github.com/Bytedesk/bytedesk-flutter
3 years ago
// 管理后台https://www.bytedesk.com/admin
4 years ago
// appkey和subDomain请替换为真实值
4 years ago
// 获取appkey登录后台->渠道管理->Flutter->添加应用->获取appkey
String _appKey = '81f427ea-4467-4c7c-b0cd-5c0e4b51456f';
4 years ago
// 获取subDomain也即企业号登录后台->客服管理->客服账号->企业号
String _subDomain = "vip";
4 years ago
// 第一步:初始化
BytedeskKefu.init(_appKey, _subDomain);
3 years ago
// 注如果需要多平台统一用户用于同步聊天记录等可使用下列接口其中username只能包含数字或字母不能含有汉字和特殊字符等nickname可以使用汉字
// BytedeskKefu.initWithUsernameAndNicknameAndAvatar('myflutterusername', '我是美女', 'https://bytedesk.oss-cn-shenzhen.aliyuncs.com/avatars/girl.png', _appKey, _subDomain);
// BytedeskKefu.initWithUsername('myflutterusername', _appKey, _subDomain); // 其中username为自定义用户名可与开发者所在用户系统对接
3 years ago
// 如果还需要自定义昵称/头像,可以使用 initWithUsernameAndNickname或initWithUsernameAndNicknameAndAvatar
// 具体参数可以参考 bytedesk_kefu/bytedesk_kefu.dart 文件
4 years ago
}
class MyApp extends StatefulWidget {
3 years ago
// const MyApp({Key? key}) : super(key: key);
4 years ago
@override
_MyAppState createState() => _MyAppState();
}
4 years ago
class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
3 years ago
// // 获取appkey登录后台->渠道管理->Flutter->添加应用->获取appkey
// String _appKey = '81f427ea-4467-4c7c-b0cd-5c0e4b51456f';
// // 获取subDomain也即企业号登录后台->客服管理->客服账号->企业号
// String _subDomain = "vip";
4 years ago
//
4 years ago
String _title = '萝卜丝客服Demo(连接中...)';
4 years ago
AudioCache audioCache = AudioCache();
3 years ago
// bool _isConnected = false;
4 years ago
//
@override
void initState() {
3 years ago
WidgetsBinding.instance?.addObserver(this);
4 years ago
super.initState();
_listener();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(_title),
elevation: 0,
),
body: ListView(
4 years ago
children: ListTile.divideTiles(
context: context,
tiles: [
4 years ago
ListTile(
3 years ago
title: const Text('联系客服'),
trailing: const Icon(Icons.keyboard_arrow_right),
4 years ago
onTap: () {
4 years ago
// 第二步:联系客服,完毕
4 years ago
Navigator.of(context)
3 years ago
.push(MaterialPageRoute(builder: (context) {
3 years ago
return const ChatTypePage();
4 years ago
}));
},
),
ListTile(
3 years ago
title: const Text('用户信息'), // 自定义用户资料,设置
trailing: const Icon(Icons.keyboard_arrow_right),
4 years ago
onTap: () {
4 years ago
// 需要首先调用anonymousLogin之后再调用设置用户信息接口
4 years ago
Navigator.of(context)
3 years ago
.push(MaterialPageRoute(builder: (context) {
3 years ago
return const UserInfoPage();
4 years ago
}));
},
),
ListTile(
3 years ago
title: const Text('在线状态'), // 技能组或客服账号 在线状态
trailing: const Icon(Icons.keyboard_arrow_right),
4 years ago
onTap: () {
Navigator.of(context)
3 years ago
.push(MaterialPageRoute(builder: (context) {
3 years ago
return const OnlineStatusPage();
4 years ago
}));
},
),
ListTile(
3 years ago
title: const Text('历史会话'), // 会话记录
trailing: const Icon(Icons.keyboard_arrow_right),
4 years ago
onTap: () {
Navigator.of(context)
3 years ago
.push(MaterialPageRoute(builder: (context) {
3 years ago
return const HistoryThreadPage();
4 years ago
}));
},
),
// ListTile(
// title: Text('TODO:提交工单'),
// trailing: Icon(Icons.keyboard_arrow_right),
// onTap: () {
// print('ticket');
// // TODO: 提交工单
// },
// ),
// ListTile(
// title: Text('TODO:意见反馈'),
// trailing: Icon(Icons.keyboard_arrow_right),
// onTap: () {
// print('feedback');
// // TODO: 意见反馈
// },
// ),
4 years ago
ListTile(
3 years ago
title: const Text('消息提示'),
trailing: const Icon(Icons.keyboard_arrow_right),
4 years ago
onTap: () {
Navigator.of(context)
3 years ago
.push(MaterialPageRoute(builder: (context) {
3 years ago
return const SettingPage();
4 years ago
}));
},
3 years ago
),
3 years ago
// ListTile(
// title: Text('退出登录'),
// onTap: () {
// BytedeskKefu.logout();
// },
// ),
// ListTile(
// title: Text('重新初始化'),
// onTap: () {
// BytedeskKefu.initWithUsernameAndNicknameAndAvatar(
// 'myflutterusername2',
// '我是帅哥',
// 'https://bytedesk.oss-cn-shenzhen.aliyuncs.com/avatars/boy.png',
// _appKey,
// _subDomain);
// },
// ),
3 years ago
const ListTile(
title: Text('技术支持: QQ-3群: 825257535'),
4 years ago
)
4 years ago
],
4 years ago
).toList()),
3 years ago
// floatingActionButton: FloatingActionButton(
// onPressed: () {
// // 第二步:到 客服管理->技能组-有一列 唯一IDwId, 默认设置工作组wid
// // 说明:一个技能组可以分配多个客服,访客会按照一定的规则分配给组内的各个客服账号
// String _workGroupWid = "201807171659201"; // 默认人工
// BytedeskKefu.startWorkGroupChat(context, _workGroupWid, "技能组客服-默认人工");
// },
// tooltip: '客服',
// child: Icon(Icons.message),
// ), // Th
4 years ago
);
}
// 监听状态
_listener() {
// 监听连接状态
4 years ago
bytedeskEventBus.on<ConnectionEventBus>().listen((event) {
4 years ago
print('长连接状态:' + event.content);
4 years ago
if (event.content == BytedeskConstants.USER_STATUS_CONNECTING) {
4 years ago
setState(() {
_title = "萝卜丝客服Demo(连接中...)";
});
4 years ago
} else if (event.content == BytedeskConstants.USER_STATUS_CONNECTED) {
4 years ago
setState(() {
_title = "萝卜丝客服Demo(连接成功)";
});
4 years ago
} else if (event.content == BytedeskConstants.USER_STATUS_DISCONNECTED) {
4 years ago
setState(() {
_title = "萝卜丝客服Demo(连接断开)";
});
}
});
4 years ago
// 监听消息,开发者可在此决定是否振动或播放提示音声音
4 years ago
bytedeskEventBus.on<ReceiveMessageEventBus>().listen((event) {
4 years ago
// print('receive message:' + event.message.content);
4 years ago
// 1. 首先将example/assets/audio文件夹中文件拷贝到自己项目2.在自己项目pubspec.yaml中添加assets
// 播放发送消息提示音
3 years ago
if (BytedeskKefu.getPlayAudioOnSendMessage()! &&
4 years ago
event.message.isSend == 1) {
4 years ago
print('play send audio');
// 修改为自己项目中语音文件路径
audioCache.play('audio/bytedesk_dingdong.wav');
}
if (event.message.isSend == 1) {
// 自己发送的消息,直接返回
return;
}
// 接收消息播放提示音
3 years ago
if (BytedeskKefu.getPlayAudioOnReceiveMessage()! &&
4 years ago
event.message.isSend == 0) {
4 years ago
print('play receive audio');
audioCache.play('audio/bytedesk_dingdong.wav');
}
// 振动
3 years ago
if (BytedeskKefu.getVibrateOnReceiveMessage()! &&
4 years ago
event.message.isSend == 0) {
4 years ago
print('should vibrate');
vibrate();
}
4 years ago
if (event.message.type == BytedeskConstants.MESSAGE_TYPE_TEXT) {
3 years ago
print('文字消息: ' + event.message.content!);
4 years ago
// 判断当前是否客服页面,如否,则显示顶部通知栏
3 years ago
if (!BytedeskUtils.isCurrentChatKfPage()!) {
4 years ago
// https://github.com/boyan01/overlay_support
showOverlayNotification((context) {
return MessageNotification(
3 years ago
avatar: event.message.user!.avatar!,
nickname: event.message.user!.nickname!,
content: event.message.content!,
4 years ago
onReply: () {
4 years ago
//
3 years ago
OverlaySupportEntry.of(context)!.dismiss();
4 years ago
// 进入客服页面,支持自定义页面标题
3 years ago
BytedeskKefu.startChatThread(context, event.message.thread!,
4 years ago
title: '客服会话');
4 years ago
},
);
3 years ago
}, duration: const Duration(milliseconds: 4000));
4 years ago
}
4 years ago
} else if (event.message.type == BytedeskConstants.MESSAGE_TYPE_IMAGE) {
3 years ago
print('图片消息:' + event.message.imageUrl!);
4 years ago
} else if (event.message.type == BytedeskConstants.MESSAGE_TYPE_VOICE) {
3 years ago
print('语音消息:' + event.message.voiceUrl!);
4 years ago
} else if (event.message.type == BytedeskConstants.MESSAGE_TYPE_VIDEO) {
3 years ago
print('视频消息:' + event.message.videoUrl!);
4 years ago
} else if (event.message.type == BytedeskConstants.MESSAGE_TYPE_FILE) {
3 years ago
print('文件消息:' + event.message.fileUrl!);
4 years ago
} else {
3 years ago
print('其他类型消息:' + event.message.type!);
4 years ago
}
});
3 years ago
// token过期
3 years ago
// bytedeskEventBus.on<InvalidTokenEventBus>().listen((event) {
// // 执行重新初始化
// print('InvalidTokenEventBus, token过期');
// });
4 years ago
}
4 years ago
// @override
// void didChangeAppLifecycleState(AppLifecycleState state) {
// print("main didChangeAppLifecycleState:" + state.toString());
// switch (state) {
// case AppLifecycleState.inactive: // 处于这种状态的应用程序应该假设它们可能在任何时候暂停。
// break;
// case AppLifecycleState.paused: // 应用程序不可见,后台
// break;
// case AppLifecycleState.resumed: // 应用程序可见,前台
// // APP切换到前台之后重连
// // BytedeskUtils.mqttReConnect();
// break;
// case AppLifecycleState.detached: // 申请将暂时暂停
// break;
// }
// }
4 years ago
// 振动
4 years ago
void vibrate() async {
3 years ago
// if (await Vibration.hasVibrator()) {
// Vibration.vibrate();
// }
4 years ago
}
4 years ago
@override
void dispose() {
3 years ago
WidgetsBinding.instance?.removeObserver(this);
4 years ago
super.dispose();
3 years ago
// audioCache?
4 years ago
}
4 years ago
}