@ -40,6 +40,7 @@ class ChatKFPage extends StatefulWidget {
final String ? title ;
final String ? title ;
final String ? custom ;
final String ? custom ;
final String ? postscript ;
final String ? postscript ;
final bool ? isV2Robot ;
/ / 从 历 史 会 话 或 者 点 击 通 知 栏 进 入
/ / 从 历 史 会 话 或 者 点 击 通 知 栏 进 入
final bool ? isThread ;
final bool ? isThread ;
final Thread ? thread ;
final Thread ? thread ;
@ -53,6 +54,7 @@ class ChatKFPage extends StatefulWidget {
this . title ,
this . title ,
this . custom ,
this . custom ,
this . postscript ,
this . postscript ,
this . isV2Robot ,
this . isThread ,
this . isThread ,
this . thread ,
this . thread ,
this . customCallback } )
this . customCallback } )
@ -89,6 +91,7 @@ class _ChatKFPageState extends State<ChatKFPage>
String ? _currentAvatar = SpUtil . getString ( BytedeskConstants . avatar ) ;
String ? _currentAvatar = SpUtil . getString ( BytedeskConstants . avatar ) ;
/ / 当 前 会 话
/ / 当 前 会 话
Thread ? _currentThread ;
Thread ? _currentThread ;
User ? _robotUser ;
/ / 判 断 是 否 机 器 人 对 话 状 态
/ / 判 断 是 否 机 器 人 对 话 状 态
bool _isRobot = false ;
bool _isRobot = false ;
/ / 分 页 加 载 聊 天 记 录
/ / 分 页 加 载 聊 天 记 录
@ -189,11 +192,8 @@ class _ChatKFPageState extends State<ChatKFPage>
_currentThread = state . threadResult . msg ! . thread ;
_currentThread = state . threadResult . msg ! . thread ;
_isRequestingThread = false ;
_isRequestingThread = false ;
} ) ;
} ) ;
/ / 插 入 本 地
/ / _messageProvider . insert ( state . threadResult . msg ! ) ;
/ / TODO: 加 载 本 地 历 史 消 息
/ / TODO: 加 载 本 地 历 史 消 息
_getMessages ( _page , _size ) ;
_getMessages ( _page , _size ) ;
/ / _appendMessage ( state . threadResult . msg ! ) ;
/ /
/ /
if ( state . threadResult . statusCode = = 200 | |
if ( state . threadResult . statusCode = = 200 | |
state . threadResult . statusCode = = 201 ) {
state . threadResult . statusCode = = 201 ) {
@ -286,6 +286,7 @@ class _ChatKFPageState extends State<ChatKFPage>
/ / TODO: 显 示 问 题 列 表
/ / TODO: 显 示 问 题 列 表
setState ( ( ) {
setState ( ( ) {
_isRobot = true ;
_isRobot = true ;
_robotUser = state . threadResult . msg ! . user ;
_currentThread = state . threadResult . msg ! . thread ;
_currentThread = state . threadResult . msg ! . thread ;
} ) ;
} ) ;
/ / 插 入 本 地
/ / 插 入 本 地
@ -347,20 +348,25 @@ class _ChatKFPageState extends State<ChatKFPage>
} else if ( state is UploadVideoSuccess ) {
} else if ( state is UploadVideoSuccess ) {
_bdMqtt . sendVideoMessage (
_bdMqtt . sendVideoMessage (
state . uploadJsonResult . url ! , _currentThread ! ) ;
state . uploadJsonResult . url ! , _currentThread ! ) ;
/ / TODO: 调 用 http rest 接 口 发 送 消 息 sendImageRest
} else if ( state is QueryAnswerSuccess ) {
} else if ( state is QueryAnswerSuccess ) {
Message queryMessage = state . query ! ;
/ / 已 经 修 改 为 直 接 插 入 本 地
queryMessage . isSend = 1 ;
/ / Message queryMessage = state . query ! ;
_messageProvider . insert ( queryMessage ) ;
/ / queryMessage . isSend = 1 ;
_appendMessage ( queryMessage ) ;
/ / _messageProvider . insert ( queryMessage ) ;
/ /
/ / _appendMessage ( queryMessage ) ;
/ / / /
/ / _messageProvider . insert ( state . answer ! ) ;
/ / _appendMessage ( state . answer ! ) ;
} else if ( state is QueryCategorySuccess ) {
_messageProvider . insert ( state . answer ! ) ;
_messageProvider . insert ( state . answer ! ) ;
_appendMessage ( state . answer ! ) ;
_appendMessage ( state . answer ! ) ;
} else if ( state is MessageAnswerSuccess ) {
} else if ( state is MessageAnswerSuccess ) {
Message queryMessage = state . query ! ;
/ / Message queryMessage = state . query ! ;
queryMessage . isSend = 1 ;
/ / queryMessage . isSend = 1 ;
_messageProvider . insert ( queryMessage ) ;
/ / _messageProvider . insert ( queryMessage ) ;
_appendMessage ( queryMessage ) ;
/ / _appendMessage ( queryMessage ) ;
/ /
/ /
if ( state . query ! . content ! . contains ( ' 人工 ' ) ) {
if ( state . query ! . content ! . contains ( ' 人工 ' ) ) {
BlocProvider . of < ThreadBloc > ( context )
BlocProvider . of < ThreadBloc > ( context )
@ -375,7 +381,7 @@ class _ChatKFPageState extends State<ChatKFPage>
} else if ( state is RateAnswerSuccess ) {
} else if ( state is RateAnswerSuccess ) {
/ / TODO:
/ / TODO:
} else if ( state is LoadHistoryMessageSuccess ) {
} else if ( state is LoadHistoryMessageSuccess ) {
print ( ' LoadHistoryMessageSuccess ' ) ;
/ / print ( ' LoadHistoryMessageSuccess ' ) ;
/ / 插 入 历 史 聊 天 记 录
/ / 插 入 历 史 聊 天 记 录
for ( var i = 0 ; i < state . messageList ! . length ; i + + ) {
for ( var i = 0 ; i < state . messageList ! . length ; i + + ) {
Message message = state . messageList ! [ i ] ;
Message message = state . messageList ! [ i ] ;
@ -490,7 +496,7 @@ class _ChatKFPageState extends State<ChatKFPage>
if ( _debounce ? . isActive ? ? false ) _debounce ! . cancel ( ) ;
if ( _debounce ? . isActive ? ? false ) _debounce ! . cancel ( ) ;
/ / 积 累 500 毫 秒 , 再 发 送 。 否 则 发 送 过 于 频 繁
/ / 积 累 500 毫 秒 , 再 发 送 。 否 则 发 送 过 于 频 繁
_debounce = Timer ( const Duration ( milliseconds: 500 ) , ( ) {
_debounce = Timer ( const Duration ( milliseconds: 500 ) , ( ) {
print ( ' send preview $ value ' ) ;
/ / print ( ' send preview $ value ' ) ;
/ / 发 送 预 知 消 息
/ / 发 送 预 知 消 息
if ( value . trim ( ) . length > 0 ) {
if ( value . trim ( ) . length > 0 ) {
_bdMqtt . sendPreviewMessage ( value , _currentThread ! ) ;
_bdMqtt . sendPreviewMessage ( value , _currentThread ! ) ;
@ -530,12 +536,14 @@ class _ChatKFPageState extends State<ChatKFPage>
}
}
/ /
/ /
if ( _isRobot ) {
if ( _isRobot ) {
/ /
appendQueryMessage ( text ) ;
/ / 请 求 机 器 人 答 案
/ / 请 求 机 器 人 答 案
BlocProvider . of < MessageBloc > ( context )
BlocProvider . of < MessageBloc > ( context )
. . add ( MessageAnswerEvent (
. . add ( MessageAnswerEvent (
type: widget . type ,
/ / type: widget . type ,
wid: widget . wid ,
wid: widget . wid ,
aid: widget . aid ,
/ / aid: widget . aid ,
content: text ) ) ;
content: text ) ) ;
} else if ( _bdMqtt . isConnected ( ) ) {
} else if ( _bdMqtt . isConnected ( ) ) {
if ( _currentThread = = null ) {
if ( _currentThread = = null ) {
@ -545,7 +553,7 @@ class _ChatKFPageState extends State<ChatKFPage>
/ / 长 连 接 正 常 情 况 下 , 调 用 长 连 接 接 口
/ / 长 连 接 正 常 情 况 下 , 调 用 长 连 接 接 口
_bdMqtt . sendTextMessage ( text , _currentThread ! ) ;
_bdMqtt . sendTextMessage ( text , _currentThread ! ) ;
} else {
} else {
print ( ' 长连接断开的情况下, 调用rest接口 ' ) ;
/ / print ( ' 长连接断开的情况下, 调用rest接口 ' ) ;
sendTextMessageRest ( text ) ;
sendTextMessageRest ( text ) ;
}
}
}
}
@ -553,7 +561,7 @@ class _ChatKFPageState extends State<ChatKFPage>
/ / http rest 接 口 发 生 文 本 消 息
/ / http rest 接 口 发 生 文 本 消 息
void sendTextMessageRest ( String text ) {
void sendTextMessageRest ( String text ) {
/ /
/ /
String ? mid = BytedeskUuid . generateV4 ( ) ;
String ? mid = BytedeskUuid . uuid ( ) ;
String ? timestamp = BytedeskUtils . formatedDateNow ( ) ;
String ? timestamp = BytedeskUtils . formatedDateNow ( ) ;
String ? client = BytedeskUtils . getClient ( ) ;
String ? client = BytedeskUtils . getClient ( ) ;
String ? type = BytedeskConstants . MESSAGE_TYPE_TEXT ;
String ? type = BytedeskConstants . MESSAGE_TYPE_TEXT ;
@ -564,6 +572,7 @@ class _ChatKFPageState extends State<ChatKFPage>
" client " : client ,
" client " : client ,
" version " : " 1 " ,
" version " : " 1 " ,
" type " : type ,
" type " : type ,
" status " : " sending " ,
" user " : {
" user " : {
" uid " : this . _currentUid ,
" uid " : this . _currentUid ,
" nickname " : this . _currentNickname ,
" nickname " : this . _currentNickname ,
@ -606,12 +615,14 @@ class _ChatKFPageState extends State<ChatKFPage>
message . content = text ;
message . content = text ;
/ / 插 入 本 地 数 据 库
/ / 插 入 本 地 数 据 库
_messageProvider . insert ( message ) ;
_messageProvider . insert ( message ) ;
/ /
pushToMessageArray ( message , true ) ;
}
}
/ / http rest 接 口 发 送 图 片 消 息
/ / http rest 接 口 发 送 图 片 消 息
void sendImageMessageRest ( String imageUrl ) {
void sendImageMessageRest ( String imageUrl ) {
/ /
/ /
String ? mid = BytedeskUuid . generateV4 ( ) ;
String ? mid = BytedeskUuid . uuid ( ) ;
String ? timestamp = BytedeskUtils . formatedDateNow ( ) ;
String ? timestamp = BytedeskUtils . formatedDateNow ( ) ;
String ? client = BytedeskUtils . getClient ( ) ;
String ? client = BytedeskUtils . getClient ( ) ;
String ? type = BytedeskConstants . MESSAGE_TYPE_IMAGE ;
String ? type = BytedeskConstants . MESSAGE_TYPE_IMAGE ;
@ -622,6 +633,7 @@ class _ChatKFPageState extends State<ChatKFPage>
" client " : client ,
" client " : client ,
" version " : " 1 " ,
" version " : " 1 " ,
" type " : type ,
" type " : type ,
" status " : " sending " ,
" user " : {
" user " : {
" uid " : this . _currentUid ,
" uid " : this . _currentUid ,
" nickname " : this . _currentNickname ,
" nickname " : this . _currentNickname ,
@ -664,6 +676,73 @@ class _ChatKFPageState extends State<ChatKFPage>
message . imageUrl = imageUrl ;
message . imageUrl = imageUrl ;
/ / 插 入 本 地 数 据 库
/ / 插 入 本 地 数 据 库
_messageProvider . insert ( message ) ;
_messageProvider . insert ( message ) ;
/ /
pushToMessageArray ( message , true ) ;
}
void appendQueryMessage ( String content ) {
/ /
String ? mid = BytedeskUuid . uuid ( ) ;
String ? timestamp = BytedeskUtils . formatedDateNow ( ) ;
String ? client = BytedeskUtils . getClient ( ) ;
String ? type = BytedeskConstants . MESSAGE_TYPE_ROBOT ;
/ /
/ / 暂 时 没 有 将 插 入 本 地 函 数 独 立 出 来 , 暂 时
Message message = new Message ( ) ;
message . mid = mid ;
message . type = type ;
message . timestamp = timestamp ;
message . client = client ;
message . nickname = _currentNickname ;
message . avatar = _currentAvatar ;
message . topic = this . _currentThread ! . topic ;
message . status = BytedeskConstants . MESSAGE_STATUS_STORED ;
message . isSend = 1 ;
message . currentUid = this . _currentUid ;
message . answersJson = ' ' ;
message . thread = this . _currentThread ;
message . user = User (
uid: this . _currentUid ,
avatar: this . _currentAvatar ,
nickname: this . _currentNickname ) ;
/ /
message . content = content ;
/ / 插 入 本 地 数 据 库
_messageProvider . insert ( message ) ;
/ /
pushToMessageArray ( message , true ) ;
}
void appendReplyMessage ( String aid , String mid , String content ) {
/ /
String ? timestamp = BytedeskUtils . formatedDateNow ( ) ;
String ? client = BytedeskUtils . getClient ( ) ;
String ? type = BytedeskConstants . MESSAGE_TYPE_ROBOT_RESULT ;
/ /
/ / 暂 时 没 有 将 插 入 本 地 函 数 独 立 出 来 , 暂 时 R
Message message = new Message ( ) ;
message . mid = mid ;
message . type = type ;
message . timestamp = timestamp ;
message . client = client ;
message . nickname = _robotUser ! . nickname ;
message . avatar = _robotUser ! . avatar ;
message . topic = this . _currentThread ! . topic ;
message . status = BytedeskConstants . MESSAGE_STATUS_STORED ;
message . isSend = 0 ;
message . currentUid = this . _currentUid ;
message . answersJson = ' ' ;
message . thread = this . _currentThread ;
message . user = User (
uid: this . _robotUser ! . uid ,
avatar: this . _robotUser ! . avatar ,
nickname: this . _robotUser ! . nickname ) ;
/ /
message . content = content ;
/ / 插 入 本 地 数 据 库
_messageProvider . insert ( message ) ;
/ /
pushToMessageArray ( message , true ) ;
}
}
/ /
/ /
@ -731,18 +810,19 @@ class _ChatKFPageState extends State<ChatKFPage>
event . message . mid ! , event . message . thread ! ) ;
event . message . mid ! , event . message . thread ! ) ;
}
}
/ /
/ /
if ( this . mounted ) {
pushToMessageArray ( event . message , true ) ;
/ / 界 面 显 示
/ / if ( this . mounted ) {
MessageWidget messageWidget = new MessageWidget (
/ / / / 界 面 显 示
message: event . message ,
/ / MessageWidget messageWidget = new MessageWidget (
customCallback: widget . customCallback ,
/ / message: event . message ,
animationController: new AnimationController (
/ / customCallback: widget . customCallback ,
vsync: this , duration: Duration ( milliseconds: 500 ) ) ) ;
/ / animationController: new AnimationController (
setState ( ( ) {
/ / vsync: this , duration: Duration ( milliseconds: 500 ) ) ) ;
_messages . insert ( 0 , messageWidget ) ;
/ / setState ( ( ) {
/ / _messages . add ( messageWidget ) ;
/ / _messages . insert ( 0 , messageWidget ) ;
} ) ;
/ / / / _messages . add ( messageWidget ) ;
}
/ / } ) ;
/ / }
} ) ;
} ) ;
/ / 删 除 消 息
/ / 删 除 消 息
bytedeskEventBus . on < DeleteMessageEventBus > ( ) . listen ( ( event ) {
bytedeskEventBus . on < DeleteMessageEventBus > ( ) . listen ( ( event ) {
@ -761,11 +841,26 @@ class _ChatKFPageState extends State<ChatKFPage>
if ( this . mounted ) {
if ( this . mounted ) {
/ / print ( ' aid ${ event . aid } , question ${ event . question } , answer ${ event . answer } ' ) ;
/ / print ( ' aid ${ event . aid } , question ${ event . question } , answer ${ event . answer } ' ) ;
/ / 可 以 直 接 将 问 题 和 答 案 插 入 本 地 , 并 显 示 , 但 为 了 服 务 器 保 存 查 询 记 录 , 特 将 请 求 发 送 给 服 务 器
/ / 可 以 直 接 将 问 题 和 答 案 插 入 本 地 , 并 显 示 , 但 为 了 服 务 器 保 存 查 询 记 录 , 特 将 请 求 发 送 给 服 务 器
appendQueryMessage ( event . question ) ;
/ /
String ? mid = BytedeskUuid . uuid ( ) ;
appendReplyMessage ( event . aid , mid , event . answer ) ;
/ /
BlocProvider . of < MessageBloc > ( context )
BlocProvider . of < MessageBloc > ( context )
. . add ( QueryAnswerEvent (
. . add ( QueryAnswerEvent (
tid: _currentThread ! . tid ,
tid: _currentThread ! . tid , aid: event . aid , mid: mid ) ) ;
aid: event . aid ,
}
) ) ;
} ) ;
/ / 查 询 分 类 下 属 问 题
bytedeskEventBus . on < QueryCategoryEventBus > ( ) . listen ( ( event ) {
if ( this . mounted ) {
print ( ' cid ${ event . cid } , name ${ event . name } ' ) ;
/ / 可 以 直 接 将 问 题 和 答 案 插 入 本 地 , 并 显 示 , 但 为 了 服 务 器 保 存 查 询 记 录 , 特 将 请 求 发 送 给 服 务 器
appendQueryMessage ( event . name ) ;
/ /
BlocProvider . of < MessageBloc > ( context )
. . add ( QueryCategoryEvent (
tid: _currentThread ! . tid , cid: event . cid ) ) ;
}
}
} ) ;
} ) ;
/ / 点 击 机 器 人 消 息 ‘ 人 工 客 服 ’
/ / 点 击 机 器 人 消 息 ‘ 人 工 客 服 ’
@ -971,30 +1066,45 @@ class _ChatKFPageState extends State<ChatKFPage>
BytedeskConstants . MESSAGE_TYPE_NOTIFICATION_THREAD_REENTRY ) {
BytedeskConstants . MESSAGE_TYPE_NOTIFICATION_THREAD_REENTRY ) {
continue ;
continue ;
} else {
} else {
pushToMessageArray ( message );
pushToMessageArray ( message , false );
}
}
}
}
} else {
} else {
pushToMessageArray ( message );
pushToMessageArray ( message , false );
}
}
}
}
/ /
/ /
_page + = 1 ;
_page + = 1 ;
}
}
void pushToMessageArray ( Message message ) {
void pushToMessageArray ( Message message , bool append ) {
if ( this . mounted ) {
if ( this . mounted ) {
MessageWidget messageWidget = new MessageWidget (
bool contains = false ;
message: message ,
for ( var i = 0 ; i < _messages . length ; i + + ) {
customCallback: widget . customCallback ,
Message ? element = _messages [ i ] . message ;
animationController: new AnimationController (
if ( element ! . mid = = message . mid ) {
vsync: this , duration: Duration ( milliseconds: 500 ) ) ) ;
contains = true ;
setState ( ( ) {
/ / 更 新 消 息 状 态
_messages . add ( messageWidget ) ;
_messageProvider . update ( element . mid , message . status ) ;
_messages . sort ( ( a , b ) {
}
return b . message ! . timestamp ! . compareTo ( a . message ! . timestamp ! ) ;
}
if ( ! contains ) {
MessageWidget messageWidget = new MessageWidget (
message: message ,
customCallback: widget . customCallback ,
animationController: new AnimationController (
vsync: this , duration: Duration ( milliseconds: 500 ) ) ) ;
setState ( ( ) {
if ( append ) {
_messages . insert ( 0 , messageWidget ) ;
} else {
_messages . add ( messageWidget ) ;
_messages . sort ( ( a , b ) {
return b . message ! . timestamp ! . compareTo ( a . message ! . timestamp ! ) ;
} ) ;
}
} ) ;
} ) ;
} ) ;
}
}
}
if ( message . status ! = BytedeskConstants . MESSAGE_STATUS_READ ) {
if ( message . status ! = BytedeskConstants . MESSAGE_STATUS_READ ) {
/ / 发 送 已 读 回 执
/ / 发 送 已 读 回 执
@ -1005,29 +1115,8 @@ class _ChatKFPageState extends State<ChatKFPage>
}
}
Future < Null > _appendMessage ( Message message ) async {
Future < Null > _appendMessage ( Message message ) async {
/ / print ( ' append: ' + message . mid ! + ' content: ' + message . content ! ) ;
print ( ' append: ' + message . mid ! + ' content: ' + message . content ! ) ;
bool contains = false ;
pushToMessageArray ( message , true ) ;
for ( var i = 0 ; i < _messages . length ; i + + ) {
Message ? element = _messages [ i ] . message ;
if ( element ! . mid = = message . mid ) {
contains = true ;
/ / 更 新 消 息 状 态
_messageProvider . update ( element . mid , message . status ) ;
}
}
if ( ! contains ) {
/ / _messageProvider . insert ( message ) ; / / 造 成 重 复 插 入
MessageWidget messageWidget = new MessageWidget (
message: message ,
customCallback: widget . customCallback ,
animationController: new AnimationController (
vsync: this , duration: Duration ( milliseconds: 500 ) ) ) ;
if ( this . mounted ) {
setState ( ( ) {
_messages . insert ( 0 , messageWidget ) ;
} ) ;
}
}
}
}
void scrollToBottom ( ) {
void scrollToBottom ( ) {