From bd6a8b54c907e8026f662ce6b8a5263d38892d1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=AB=A0=E6=96=87=E8=BD=A9?= <12812285557@qq.com> Date: Wed, 17 Aug 2022 15:24:11 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E8=AE=A2=E5=8D=95=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=8F=91=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bytedesk_demo/lib/page/chat_type_page.dart | 36 +- bytedesk_kefu/lib/bytedesk_kefu.dart | 9 +- .../lib/ui/chat/page/chat_kf_page.dart | 783 +++++++++--------- bytedesk_kefu/lib/util/bytedesk_utils.dart | 1 + 4 files changed, 437 insertions(+), 392 deletions(-) diff --git a/bytedesk_demo/lib/page/chat_type_page.dart b/bytedesk_demo/lib/page/chat_type_page.dart index f123393..98c6abe 100755 --- a/bytedesk_demo/lib/page/chat_type_page.dart +++ b/bytedesk_demo/lib/page/chat_type_page.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'package:bytedesk_kefu/bytedesk_kefu.dart'; import 'package:bytedesk_kefu/util/bytedesk_constants.dart'; +import 'package:bytedesk_kefu/util/bytedesk_utils.dart'; import 'package:flutter/material.dart'; // 多种客服对话类型列表页面 @@ -126,6 +127,7 @@ class _ChatTypePageState extends State { "other2": "", // 可另外添加自定义字段,客服端不可见,可用于回调原样返回 "other3": "", // 可另外添加自定义字段,客服端不可见,可用于回调原样返回 }); + BytedeskKefu.startWorkGroupChatShopCallback( context, _workGroupWid, "技能组客服-电商-回调", custom, (value) { print('value为custom参数原样返回 $value'); @@ -133,10 +135,36 @@ class _ChatTypePageState extends State { showModalBottomSheet( context: context, builder: (context) { - return Container( - width: 200, - height: 200, - color: Colors.red, + return GestureDetector( + onTap: (){ + custom = json.encode({ + "type": BytedeskConstants.MESSAGE_TYPE_COMMODITY, // 不能修改 + "title": "11111", // 可自定义, 类型为字符串 + "content": "11111", // 可自定义, 类型为字符串 + "price": "11111", // 可自定义, 类型为字符串 + "url": + "https://item.m.jd.com/product/12172344.html", // 必须为url网址, 类型为字符串 + "imageUrl": + "https://bytedesk.oss-cn-shenzhen.aliyuncs.com/images/123.webp", //必须为图片网址, 类型为字符串 + "id": 123, // 可自定义 + "categoryCode": "100010003", // 可自定义, 类型为字符串 + "client": "flutter", // 可自定义, 类型为字符串 + // 可自定义添加key:value, 客服端不可见,可用于回调原样返回 + "other1": "", // 可另外添加自定义字段,客服端不可见,可用于回调原样返回 + "other2": "", // 可另外添加自定义字段,客服端不可见,可用于回调原样返回 + "other3": "", // 可另外添加自定义字段,客服端不可见,可用于回调原样返回 + }); + print('11111'); + BytedeskKefu.updateGoods(custom); + setState(() { + + }); + }, + child: Container( + width: 200, + height: 200, + color: Colors.red, + ), ); }); }); diff --git a/bytedesk_kefu/lib/bytedesk_kefu.dart b/bytedesk_kefu/lib/bytedesk_kefu.dart index f32a245..119aa7e 100644 --- a/bytedesk_kefu/lib/bytedesk_kefu.dart +++ b/bytedesk_kefu/lib/bytedesk_kefu.dart @@ -1,5 +1,4 @@ import 'dart:async'; -// import 'dart:io'; import 'package:bytedesk_kefu/http/bytedesk_device_api.dart'; import 'package:bytedesk_kefu/http/bytedesk_thread_api.dart'; @@ -161,6 +160,7 @@ class BytedeskKefu { // 建立长连接 static bool connect() { return BytedeskUtils.mqttConnect(); + } // 重连 @@ -206,6 +206,13 @@ class BytedeskKefu { commodity, null); } + + ///用于更新订单数据 + static void updateGoods(String info) { + BytedeskUtils.goodsInfo = info; + } + + static void startWorkGroupChatShopCallback(BuildContext context, String wid, String title, String commodity, ValueSetter customCallback,{Widget? widget}) { startChatShop(context, wid, BytedeskConstants.CHAT_TYPE_WORKGROUP, title, diff --git a/bytedesk_kefu/lib/ui/chat/page/chat_kf_page.dart b/bytedesk_kefu/lib/ui/chat/page/chat_kf_page.dart index 1a19215..a392248 100755 --- a/bytedesk_kefu/lib/ui/chat/page/chat_kf_page.dart +++ b/bytedesk_kefu/lib/ui/chat/page/chat_kf_page.dart @@ -119,12 +119,14 @@ class _ChatKFPageState extends State String goodPrice = ''; String goodUrl = ''; bool showGood = false; + String customGoods = ''; @override void initState() { - if (widget.custom != null && - widget.custom!.trim().length > 0){ + customGoods = widget.custom??''; + if ( + customGoods.trim().length > 0){ showGood = true; - Map json = jsonDecode(widget.custom??""); + Map json = jsonDecode(customGoods); json.forEach((key, value) { //typeOne等所对应的数组数据 if(key=='title'){ @@ -216,424 +218,429 @@ class _ChatKFPageState extends State Widget build(BuildContext context) { super.build(context); // - return Scaffold ( - appBar: AppBar( - title: Text(_title ?? '请求中, 请稍后...',style: TextStyle(color: Color(0xFF333333),fontSize: 16),), - backgroundColor: Colors.white, - centerTitle: true, - elevation: 0, - leading: IconButton( - icon: Icon( - Icons.arrow_back_ios, - size: 17, - color: Color(0xFF333333), + return GestureDetector( + onTap: (){ + FocusScope.of(context).requestFocus(FocusNode()); + }, + child: Scaffold ( + appBar: AppBar( + title: Text(_title ?? '请求中, 请稍后...',style: TextStyle(color: Color(0xFF333333),fontSize: 16),), + backgroundColor: Colors.white, + centerTitle: true, + elevation: 0, + leading: IconButton( + icon: Icon( + Icons.arrow_back_ios, + size: 17, + color: Color(0xFF333333), + ), + onPressed: + () { + Navigator.maybePop(context); + }), + actions: [ + // TODO: 评价 + // TODO: 常见问题 + Visibility( + visible: _isRobot, + child: Align( + alignment: Alignment.centerRight, + child: Container( + padding: new EdgeInsets.only(right: 10), + width: 60, + child: InkWell( + onTap: () { + BlocProvider.of(context) + ..add(RequestAgentEvent( + wid: widget.wid, + aid: widget.aid, + type: widget.type)); + }, + child: Text( + '转人工', + // style: TextStyle(color: Colors.black), + ), + ))), ), - onPressed: - () { - Navigator.maybePop(context); - }), - actions: [ - // TODO: 评价 - // TODO: 常见问题 - Visibility( - visible: _isRobot, - child: Align( - alignment: Alignment.centerRight, - child: Container( - padding: new EdgeInsets.only(right: 10), - width: 60, - child: InkWell( - onTap: () { - BlocProvider.of(context) - ..add(RequestAgentEvent( - wid: widget.wid, - aid: widget.aid, - type: widget.type)); - }, - child: Text( - '转人工', - // style: TextStyle(color: Colors.black), - ), - ))), - ), - ], - ), - body: MultiBlocListener( - listeners: [ - BlocListener( - listener: (context, state) { - // 隐藏toast - // Fluttertoast.cancel(); - if (state is RequestThreading) { - setState(() { - _isRequestingThread = true; - }); - } else if (state is RequestThreadSuccess) { - setState(() { - _isRobot = false; // 需要,勿删 - _currentThread = state.threadResult.msg!.thread; - _isRequestingThread = false; - }); - // TODO: 加载本地历史消息 - _getMessages(_page, _size); - // 加载未读消息 - BlocProvider.of(context) - ..add(LoadUnreadVisitorMessagesEvent(page: 0, size: 10)); - // 结果解析 - if (state.threadResult.statusCode == 200 || - state.threadResult.statusCode == 201) { - BytedeskUtils.printLog('创建新会话'); - // TODO: 参考拼多多,在发送按钮上方显示pop商品信息,用户确认之后才会发送商品信息 - // 发送商品信息 - // if (widget.custom != null && - // widget.custom!.trim().length > 0) { - // _bdMqtt.sendCommodityMessage( - // widget.custom!, _currentThread!); - // } - // 发送附言消息 - if (widget.postscript != null && - widget.postscript!.trim().length > 0) { - _bdMqtt.sendTextMessage( - widget.postscript!, _currentThread!); - } - } else if (state.threadResult.statusCode == 202) { - BytedeskUtils.printLog('提示排队中'); - // 插入本地 - _messageProvider.insert(state.threadResult.msg!); - // 加载本地历史消息 - _appendMessage(state.threadResult.msg!); - // 发送商品信息 - // if (widget.custom != null && - // widget.custom!.trim().length > 0) { - // _bdMqtt.sendCommodityMessage( - // widget.custom!, _currentThread!); - // } - // 发送附言消息 - if (widget.postscript != null && - widget.postscript!.trim().length > 0) { - _bdMqtt.sendTextMessage( - widget.postscript!, _currentThread!); - } - } else if (state.threadResult.statusCode == 203) { - BytedeskUtils.printLog('当前非工作时间,请自助查询或留言'); + ], + ), + body: MultiBlocListener( + listeners: [ + BlocListener( + listener: (context, state) { + // 隐藏toast + // Fluttertoast.cancel(); + if (state is RequestThreading) { setState(() { - _currentThread = state.threadResult.msg!.thread; + _isRequestingThread = true; }); - // 插入本地 - _messageProvider.insert(state.threadResult.msg!); - // TODO: 加载本地历史消息 - _appendMessage(state.threadResult.msg!); - // 跳转留言页面,TODO: 关闭当前页面? - Navigator.of(context) - .push(new MaterialPageRoute(builder: (context) { - return new LeaveMsgProvider( - wid: this.widget.wid, - aid: this.widget.aid, - type: this.widget.type, - tip: state.threadResult.msg!.content); - })); - } else if (state.threadResult.statusCode == 204) { - BytedeskUtils.printLog('当前无客服在线,请自助查询或留言'); + } else if (state is RequestThreadSuccess) { setState(() { + _isRobot = false; // 需要,勿删 _currentThread = state.threadResult.msg!.thread; + _isRequestingThread = false; }); - // 插入本地 - _messageProvider.insert(state.threadResult.msg!); // TODO: 加载本地历史消息 - // _getMessages(_page, _size); - _appendMessage(state.threadResult.msg!); - // 跳转留言页面, TODO: 关闭当前页面? - Navigator.of(context) - .push(new MaterialPageRoute(builder: (context) { - return new LeaveMsgProvider( - wid: this.widget.wid, - aid: this.widget.aid, - type: this.widget.type, - tip: state.threadResult.msg!.content); - })); - } else if (state.threadResult.statusCode == 205) { - BytedeskUtils.printLog('咨询前问卷'); + _getMessages(_page, _size); + // 加载未读消息 + BlocProvider.of(context) + ..add(LoadUnreadVisitorMessagesEvent(page: 0, size: 10)); + // 结果解析 + if (state.threadResult.statusCode == 200 || + state.threadResult.statusCode == 201) { + BytedeskUtils.printLog('创建新会话'); + // TODO: 参考拼多多,在发送按钮上方显示pop商品信息,用户确认之后才会发送商品信息 + // 发送商品信息 + // if (widget.custom != null && + // widget.custom!.trim().length > 0) { + // _bdMqtt.sendCommodityMessage( + // widget.custom!, _currentThread!); + // } + // 发送附言消息 + if (widget.postscript != null && + widget.postscript!.trim().length > 0) { + _bdMqtt.sendTextMessage( + widget.postscript!, _currentThread!); + } + } else if (state.threadResult.statusCode == 202) { + BytedeskUtils.printLog('提示排队中'); + // 插入本地 + _messageProvider.insert(state.threadResult.msg!); + // 加载本地历史消息 + _appendMessage(state.threadResult.msg!); + // 发送商品信息 + // if (widget.custom != null && + // widget.custom!.trim().length > 0) { + // _bdMqtt.sendCommodityMessage( + // widget.custom!, _currentThread!); + // } + // 发送附言消息 + if (widget.postscript != null && + widget.postscript!.trim().length > 0) { + _bdMqtt.sendTextMessage( + widget.postscript!, _currentThread!); + } + } else if (state.threadResult.statusCode == 203) { + BytedeskUtils.printLog('当前非工作时间,请自助查询或留言'); + setState(() { + _currentThread = state.threadResult.msg!.thread; + }); + // 插入本地 + _messageProvider.insert(state.threadResult.msg!); + // TODO: 加载本地历史消息 + _appendMessage(state.threadResult.msg!); + // 跳转留言页面,TODO: 关闭当前页面? + Navigator.of(context) + .push(new MaterialPageRoute(builder: (context) { + return new LeaveMsgProvider( + wid: this.widget.wid, + aid: this.widget.aid, + type: this.widget.type, + tip: state.threadResult.msg!.content); + })); + } else if (state.threadResult.statusCode == 204) { + BytedeskUtils.printLog('当前无客服在线,请自助查询或留言'); + setState(() { + _currentThread = state.threadResult.msg!.thread; + }); + // 插入本地 + _messageProvider.insert(state.threadResult.msg!); + // TODO: 加载本地历史消息 + // _getMessages(_page, _size); + _appendMessage(state.threadResult.msg!); + // 跳转留言页面, TODO: 关闭当前页面? + Navigator.of(context) + .push(new MaterialPageRoute(builder: (context) { + return new LeaveMsgProvider( + wid: this.widget.wid, + aid: this.widget.aid, + type: this.widget.type, + tip: state.threadResult.msg!.content); + })); + } else if (state.threadResult.statusCode == 205) { + BytedeskUtils.printLog('咨询前问卷'); + setState(() { + _currentThread = state.threadResult.msg!.thread; + }); + // 插入本地 + _messageProvider.insert(state.threadResult.msg!); + // TODO: 加载本地历史消息 + // _getMessages(_page, _size); + _appendMessage(state.threadResult.msg!); + // + } else if (state.threadResult.statusCode == 206) { + // BytedeskUtils.printLog('返回机器人初始欢迎语 + 欢迎问题列表'); + // TODO: 显示问题列表 + setState(() { + _isRobot = true; + _robotUser = state.threadResult.msg!.user; + _currentThread = state.threadResult.msg!.thread; + }); + // 插入本地 + _messageProvider.insert(state.threadResult.msg!); + // TODO: 加载本地历史消息 + // _getMessages(_page, _size); + _appendMessage(state.threadResult.msg!); + // + } else if (state.threadResult.statusCode == -1) { + Fluttertoast.showToast(msg: "请求会话失败"); + } else if (state.threadResult.statusCode == -2) { + Fluttertoast.showToast(msg: "siteId或者工作组id错误"); + } else if (state.threadResult.statusCode == -3) { + Fluttertoast.showToast(msg: "您已经被禁言"); + } else { + Fluttertoast.showToast(msg: "请求会话失败"); + } + } else if (state is RequestThreadError) { + Fluttertoast.showToast(msg: "请求会话失败"); setState(() { - _currentThread = state.threadResult.msg!.thread; + _isRequestingThread = false; }); - // 插入本地 - _messageProvider.insert(state.threadResult.msg!); - // TODO: 加载本地历史消息 - // _getMessages(_page, _size); - _appendMessage(state.threadResult.msg!); - // - } else if (state.threadResult.statusCode == 206) { - // BytedeskUtils.printLog('返回机器人初始欢迎语 + 欢迎问题列表'); - // TODO: 显示问题列表 + } else if (state is RequestAgentThreading) { setState(() { - _isRobot = true; - _robotUser = state.threadResult.msg!.user; + _isRequestingThread = true; + }); + } else if (state is RequestAgentSuccess) { + // 请求人工客服,不管此工作组是否设置为默认机器人,只要有人工客服在线,则可以直接对接人工 + setState(() { + _isRobot = false; // 需要,勿删 _currentThread = state.threadResult.msg!.thread; + _isRequestingThread = false; }); // 插入本地 _messageProvider.insert(state.threadResult.msg!); - // TODO: 加载本地历史消息 - // _getMessages(_page, _size); - _appendMessage(state.threadResult.msg!); - // - } else if (state.threadResult.statusCode == -1) { - Fluttertoast.showToast(msg: "请求会话失败"); - } else if (state.threadResult.statusCode == -2) { - Fluttertoast.showToast(msg: "siteId或者工作组id错误"); - } else if (state.threadResult.statusCode == -3) { - Fluttertoast.showToast(msg: "您已经被禁言"); - } else { + // _appendMessage(state.threadResult.msg!); + } else if (state is RequestAgentThreadError) { Fluttertoast.showToast(msg: "请求会话失败"); + setState(() { + _isRequestingThread = false; + }); } - } else if (state is RequestThreadError) { - Fluttertoast.showToast(msg: "请求会话失败"); - setState(() { - _isRequestingThread = false; - }); - } else if (state is RequestAgentThreading) { - setState(() { - _isRequestingThread = true; - }); - } else if (state is RequestAgentSuccess) { - // 请求人工客服,不管此工作组是否设置为默认机器人,只要有人工客服在线,则可以直接对接人工 - setState(() { - _isRobot = false; // 需要,勿删 - _currentThread = state.threadResult.msg!.thread; - _isRequestingThread = false; - }); - // 插入本地 - _messageProvider.insert(state.threadResult.msg!); - // _appendMessage(state.threadResult.msg!); - } else if (state is RequestAgentThreadError) { - Fluttertoast.showToast(msg: "请求会话失败"); - setState(() { - _isRequestingThread = false; - }); - } - }, - ), - BlocListener( - listener: (context, state) { - // BytedeskUtils.printLog('message state change'); - if (state is ReceiveMessageState) { - // BytedeskUtils.printLog('receive message:' + state.message!.content!); - } else if (state is MessageUpLoading) { - Fluttertoast.showToast(msg: '上传中...'); - } else if (state is UploadImageSuccess) { - if (_bdMqtt.isConnected()) { - _bdMqtt.sendImageMessage( + }, + ), + BlocListener( + listener: (context, state) { + // BytedeskUtils.printLog('message state change'); + if (state is ReceiveMessageState) { + // BytedeskUtils.printLog('receive message:' + state.message!.content!); + } else if (state is MessageUpLoading) { + Fluttertoast.showToast(msg: '上传中...'); + } else if (state is UploadImageSuccess) { + if (_bdMqtt.isConnected()) { + _bdMqtt.sendImageMessage( + state.uploadJsonResult.url!, _currentThread!); + } else { + sendImageMessageRest(state.uploadJsonResult.url!); + } + } else if (state is UploadVideoSuccess) { + _bdMqtt.sendVideoMessage( state.uploadJsonResult.url!, _currentThread!); - } else { - sendImageMessageRest(state.uploadJsonResult.url!); - } - } else if (state is UploadVideoSuccess) { - _bdMqtt.sendVideoMessage( - state.uploadJsonResult.url!, _currentThread!); - } else if (state is QueryAnswerSuccess) { - // 已经修改为直接插入本地 - // Message queryMessage = state.query!; - // queryMessage.isSend = 1; - // _messageProvider.insert(queryMessage); - // _appendMessage(queryMessage); - // // - // _messageProvider.insert(state.answer!); - // _appendMessage(state.answer!); - } else if (state is QueryCategorySuccess) { - _messageProvider.insert(state.answer!); - _appendMessage(state.answer!); - } else if (state is MessageAnswerSuccess) { - // Message queryMessage = state.query!; - // queryMessage.isSend = 1; - // _messageProvider.insert(queryMessage); - // _appendMessage(queryMessage); - // - if (state.query!.content!.contains('人工')) { - BlocProvider.of(context) - ..add(RequestAgentEvent( - wid: widget.wid, - aid: widget.aid, - type: widget.type)); - } else { + } else if (state is QueryAnswerSuccess) { + // 已经修改为直接插入本地 + // Message queryMessage = state.query!; + // queryMessage.isSend = 1; + // _messageProvider.insert(queryMessage); + // _appendMessage(queryMessage); + // // + // _messageProvider.insert(state.answer!); + // _appendMessage(state.answer!); + } else if (state is QueryCategorySuccess) { _messageProvider.insert(state.answer!); _appendMessage(state.answer!); - } - } else if (state is RateAnswerSuccess) { - // TODO: - } else if (state is LoadHistoryMessageSuccess) { - // BytedeskUtils.printLog('LoadHistoryMessageSuccess'); - // 插入历史聊天记录 - for (var i = 0; i < state.messageList!.length; i++) { - Message message = state.messageList![i]; - _appendMessage(message); - } - } else if (state is LoadUnreadVisitorMessageSuccess) { - // 插入历史聊天记录 - if (state.messageList!.length > 0) { - // for (var i = 0; i < state.messageList!.length; i++) { - for (var i = state.messageList!.length - 1; i >= 0; i--) { + } else if (state is MessageAnswerSuccess) { + // Message queryMessage = state.query!; + // queryMessage.isSend = 1; + // _messageProvider.insert(queryMessage); + // _appendMessage(queryMessage); + // + if (state.query!.content!.contains('人工')) { + BlocProvider.of(context) + ..add(RequestAgentEvent( + wid: widget.wid, + aid: widget.aid, + type: widget.type)); + } else { + _messageProvider.insert(state.answer!); + _appendMessage(state.answer!); + } + } else if (state is RateAnswerSuccess) { + // TODO: + } else if (state is LoadHistoryMessageSuccess) { + // BytedeskUtils.printLog('LoadHistoryMessageSuccess'); + // 插入历史聊天记录 + for (var i = 0; i < state.messageList!.length; i++) { Message message = state.messageList![i]; - // 本地持久化 - _messageProvider.insert(message); - // 界面显示 _appendMessage(message); - // 发送已读回执 - _bdMqtt.sendReceiptReadMessage( - message.mid!, _currentThread!); } + } else if (state is LoadUnreadVisitorMessageSuccess) { + // 插入历史聊天记录 + if (state.messageList!.length > 0) { + // for (var i = 0; i < state.messageList!.length; i++) { + for (var i = state.messageList!.length - 1; i >= 0; i--) { + Message message = state.messageList![i]; + // 本地持久化 + _messageProvider.insert(message); + // 界面显示 + _appendMessage(message); + // 发送已读回执 + _bdMqtt.sendReceiptReadMessage( + message.mid!, _currentThread!); + } + } + } else if (state is SendMessageRestSuccess) { + // http rest 发送消息成功 + String jsonMessage = state.jsonResult.data!; + String mid = json.decode(jsonMessage); + _messageProvider.update( + mid, BytedeskConstants.MESSAGE_STATUS_STORED); + } else if (state is SendMessageRestError) { + // http rest 发送消息失败 + String jsonMessage = state.json; + String mid = json.decode(jsonMessage); + _messageProvider.update( + mid, BytedeskConstants.MESSAGE_STATUS_STORED); } - } else if (state is SendMessageRestSuccess) { - // http rest 发送消息成功 - String jsonMessage = state.jsonResult.data!; - String mid = json.decode(jsonMessage); - _messageProvider.update( - mid, BytedeskConstants.MESSAGE_STATUS_STORED); - } else if (state is SendMessageRestError) { - // http rest 发送消息失败 - String jsonMessage = state.json; - String mid = json.decode(jsonMessage); - _messageProvider.update( - mid, BytedeskConstants.MESSAGE_STATUS_STORED); - } - }, - ), - ], - child: _isRequestingThread - ? Container( - margin: EdgeInsets.only(top: 50), + }, + ), + ], + child: _isRequestingThread + ? Container( + margin: EdgeInsets.only(top: 50), + alignment: Alignment.center, + child: Column(children: [ + CircularProgressIndicator( + strokeWidth: 2, + ), + Text('会话请求中, 请稍后...',style: TextStyle(color: Color(0xFF333333)),) + ])) + : Stack( alignment: Alignment.center, - child: Column(children: [ - CircularProgressIndicator( - strokeWidth: 2, - ), - Text('会话请求中, 请稍后...',style: TextStyle(color: Color(0xFF333333)),) - ])) - : Stack( - alignment: Alignment.center, - children: [ + children: [ - Container( - alignment: Alignment.bottomCenter, - color: Color(0xFFDEEEEEE), - child: Column( - children: [ - // 参考pull_to_refresh库中 QQChatList例子 - Expanded( - // - child: SmartRefresher( - enablePullDown: false, - onLoading: () async { - // BytedeskUtils.printLog('TODO: 下拉刷新'); // 注意:方向跟默认是反着的 - // await Future.delayed(Duration(milliseconds: 1000)); - _getMessages(_page, _size); - setState(() {}); - _refreshController.loadComplete(); - }, - footer: ClassicFooter( - loadStyle: LoadStyle.ShowWhenLoading, - ), - enablePullUp: true, + Container( + alignment: Alignment.bottomCenter, + color: Color(0xFFDEEEEEE), + child: Column( + children: [ + // 参考pull_to_refresh库中 QQChatList例子 + Expanded( // - child: Scrollable( - controller: _scrollController, - axisDirection: AxisDirection.up, - viewportBuilder: (context, offset) { - return ExpandedViewport( - offset: offset, - axisDirection: AxisDirection.up, - slivers: [ - SliverExpanded(), - SliverList( - delegate: SliverChildBuilderDelegate( - (c, i) => _messages[i], - childCount: _messages.length), - ) - ], - ); + child: SmartRefresher( + enablePullDown: false, + onLoading: () async { + // BytedeskUtils.printLog('TODO: 下拉刷新'); // 注意:方向跟默认是反着的 + // await Future.delayed(Duration(milliseconds: 1000)); + _getMessages(_page, _size); + setState(() {}); + _refreshController.loadComplete(); }, + footer: ClassicFooter( + loadStyle: LoadStyle.ShowWhenLoading, + ), + enablePullUp: true, + // + child: Scrollable( + controller: _scrollController, + axisDirection: AxisDirection.up, + viewportBuilder: (context, offset) { + return ExpandedViewport( + offset: offset, + axisDirection: AxisDirection.up, + slivers: [ + SliverExpanded(), + SliverList( + delegate: SliverChildBuilderDelegate( + (c, i) => _messages[i], + childCount: _messages.length), + ) + ], + ); + }, + ), + // + controller: _refreshController, ), - // - controller: _refreshController, ), - ), - Divider( - height: 1.0, - ), - Container( - decoration: BoxDecoration( - color: Colors.white + Divider( + height: 1.0, + ), + Container( + decoration: BoxDecoration( + color: Colors.white + ), + // child: _textComposerWidget(), + child: _chatInput(), ), - // child: _textComposerWidget(), - child: _chatInput(), - ), - ], + ], + ), ), - ), - showGood? Positioned( - top: 0, - child:Container( - width: MediaQuery.of(context).size.width, + showGood? Positioned( + top: 0, + child:Container( + width: MediaQuery.of(context).size.width, - padding: EdgeInsets.symmetric(vertical: 10), - decoration: BoxDecoration( - color: Color(0xFFe5f9ff), - borderRadius: BorderRadius.all(Radius.circular(5)), - ), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox(width: 10,), - Image.network(goodUrl,width: 50,height: 50,), - SizedBox(width: 10,), - Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(goodName,style: TextStyle(color: Color(0xFF333333),fontSize: 15),), - SizedBox(height: 8,), - Row( - children: [ - Text('¥ '+goodPrice,style: TextStyle(color: Colors.red,fontSize: 16),), - SizedBox(width: 30,), - GestureDetector( - onTap: (){ - showGood = false; - setState(() { - }); - _goodsSubmitted(); - }, - child: Container( - decoration: BoxDecoration( - color: Color(0xFFefefef), - borderRadius: BorderRadius.all(Radius.circular(4)), - border: Border.all(color:Color(0xFF999999) ) + padding: EdgeInsets.symmetric(vertical: 10), + decoration: BoxDecoration( + color: Color(0xFFe5f9ff), + borderRadius: BorderRadius.all(Radius.circular(5)), + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(width: 10,), + Image.network(goodUrl,width: 50,height: 50,), + SizedBox(width: 10,), + Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(goodName,style: TextStyle(color: Color(0xFF333333),fontSize: 15),), + SizedBox(height: 8,), + Row( + children: [ + Text('¥ '+goodPrice,style: TextStyle(color: Colors.red,fontSize: 16),), + SizedBox(width: 30,), + GestureDetector( + onTap: (){ + //showGood = false; + setState(() { + }); + _goodsSubmitted(); + }, + child: Container( + decoration: BoxDecoration( + color: Color(0xFFefefef), + borderRadius: BorderRadius.all(Radius.circular(4)), + border: Border.all(color:Color(0xFF999999) ) + ), + padding: EdgeInsets.symmetric(horizontal: 5), + child: Text('发送链接',style: TextStyle(color: Color(0xFF333333)),), ), - padding: EdgeInsets.symmetric(horizontal: 5), - child: Text('发送链接',style: TextStyle(color: Color(0xFF333333)),), ), - ), - ], + ], + ), + ], + ), + Spacer(), + IconButton( + padding: const EdgeInsets.only(bottom: 30), + icon: Icon( + Icons.close, ), - ], - ), - Spacer(), - IconButton( - padding: const EdgeInsets.only(bottom: 30), - icon: Icon( - Icons.close, + onPressed: () { + showGood = false; + setState(() { + }); + }, ), - onPressed: () { - showGood = false; - setState(() { - }); - }, - ), - ], - ), - ),):SizedBox(), - ], - ))); + ], + ), + ),):SizedBox(), + ], + ))), + ); } Widget _chatInput() { @@ -690,6 +697,8 @@ class _ChatKFPageState extends State print('_handleShowOrders'); if(widget.customCallback!=null){ widget.customCallback!('点击订单'); + customGoods = BytedeskUtils.goodsInfo; + _goodsSubmitted(); } } @@ -784,9 +793,9 @@ class _ChatKFPageState extends State // 发送商品消息 void _goodsSubmitted() { - - if (widget.custom != null && - widget.custom!.trim().length > 0) { + print(customGoods); + if ( + customGoods.trim().length > 0) { if (_bdMqtt.isConnected()) { if (_currentThread == null) { @@ -795,7 +804,7 @@ class _ChatKFPageState extends State } // 长连接正常情况下,调用长连接接口 _bdMqtt.sendCommodityMessage( - widget.custom!, _currentThread!); + customGoods, _currentThread!); } else { } diff --git a/bytedesk_kefu/lib/util/bytedesk_utils.dart b/bytedesk_kefu/lib/util/bytedesk_utils.dart index f64eb25..663e7ce 100755 --- a/bytedesk_kefu/lib/util/bytedesk_utils.dart +++ b/bytedesk_kefu/lib/util/bytedesk_utils.dart @@ -29,6 +29,7 @@ import 'package:flutter/services.dart' show rootBundle; class BytedeskUtils { // + static String goodsInfo = ''; static bool get isDesktop => !isWeb && (isWindows || isLinux || isMacOS); static bool get isMobile => isAndroid || isIOS; static bool get isWeb => kIsWeb;