This commit is contained in:
fengjignqi
2026-05-16 16:19:39 +08:00
commit 1b1575eb8a
1632 changed files with 242221 additions and 0 deletions

View File

@@ -0,0 +1,900 @@
package com.ckkj.water.chat;
import static android.app.Activity.RESULT_OK;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.core.widget.NestedScrollView;
import androidx.recyclerview.widget.GridLayoutManager;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.ckkj.water.AppConfig;
import com.ckkj.water.EventMessage;
import com.ckkj.water.R;
import com.ckkj.water.base.BaseFragment;
import com.ckkj.water.chat.adapter.ChatQuestionDetailAdapter;
import com.ckkj.water.chat.adapter.ChatZixunAdapter;
import com.ckkj.water.chat.entity.ChatQuestionEntity;
import com.ckkj.water.custom.GridSpacingItemDecoration;
import com.ckkj.water.databinding.IndexLayoutBinding;
import com.ckkj.water.chat.adapter.IndexChatAdapter;
import com.ckkj.water.chat.adapter.IndexOptionAdapter;
import com.ckkj.water.chat.adapter.IndexEnterHintAdapter;
import com.ckkj.water.chat.adapter.IndexQuickAskAdapter;
import com.ckkj.water.chat.entity.CharHistoryEntity;
import com.ckkj.water.chat.entity.ChatAiMsgEntity;
import com.ckkj.water.chat.entity.ChatMultiItem;
import com.ckkj.water.chat.entity.IndexTemplateEntity;
import com.ckkj.water.chat.mvp.IndexContract;
import com.ckkj.water.chat.mvp.IndexImpl;
import com.ckkj.water.chat.mvp.IndexPresenter;
import com.ckkj.water.dialog.ContentReportDialog;
import com.ckkj.water.login.LoginActivity;
import com.ckkj.water.network.BaseBean;
import com.ckkj.water.plate.entity.BaziResultBean;
import com.ckkj.water.plate.entity.PaipanCache;
import com.ckkj.water.utils.click.ClickUtil;
import com.ckkj.water.utils.manager.ColorManage;
import com.ckkj.water.utils.show.ToastUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import de.greenrobot.event.Subscribe;
import de.greenrobot.event.ThreadMode;
import android.content.ClipData;
import android.content.ClipboardManager;
/**
* @author fengxiaoyang
* @date 2025/7/7
* @description TODO: 描述该类的作用
*/
public class ChatFragment extends BaseFragment<IndexLayoutBinding, IndexPresenter> implements IndexContract.IndexView {
//顶部 adapter
private IndexOptionAdapter mOptionAdapter;
private ChatZixunAdapter mZixunQuestAdapter;
private ChatQuestionDetailAdapter mQuesDetailAdapter;
//快速提问 adapter
private IndexQuickAskAdapter mQuickAskAdapter;
private List<IndexTemplateEntity> mQuickAskList = new ArrayList<>();
private List<ChatMultiItem> mChatMsgList = new ArrayList<>();
//聊天 adapter
private IndexChatAdapter mChatAdapter;
//欢迎语 adapter
private IndexEnterHintAdapter mHintAdapter;
//输入的内容
private String mCurrentInputContent = "";
//当前options 的 pos
private int mCurrentStreamPos = 0;
//模板数据 list
private List<IndexTemplateEntity> mIndexTemList = new ArrayList<>();
//输出是否完成
private boolean mIsStreamStop = true;
//当前选中 option 的 typeID
private String mSelectTypeID = "1";
//会话 ID
private String mSessionId = "";
// 添加流式数据累积变量
private StringBuilder mStreamContentBuilder = new StringBuilder();
private ChatAiMsgEntity mCurrentStreamEntity = null;
// 智能滚动管理
private boolean mIsUserScrolling = false;
// 优化防抖机制
private Handler mUpdateHandler = new Handler();
private Runnable mUpdateRunnable;
private List<ChatQuestionEntity> mQuesTypeList = new ArrayList<>();
private boolean mIsShowQuestions = true;
@Override
public void initData(Bundle state) {
mOptionAdapter = new IndexOptionAdapter(mContext, R.layout.index_device_list_item, mIndexTemList);
viewBinding.rvOptions.setAdapter(mOptionAdapter);
mQuickAskAdapter = new IndexQuickAskAdapter(mContext, R.layout.index_home_quick_ask_item, mQuickAskList);
viewBinding.rvQuickAsk.setAdapter(mQuickAskAdapter);
mChatAdapter = new IndexChatAdapter(mContext, mChatMsgList, viewBinding.rvChat);
viewBinding.rvChat.setAdapter(mChatAdapter);
//提问类型
GridLayoutManager manager = new GridLayoutManager(mContext, 2);
viewBinding.rvChatQuick.setLayoutManager(manager);
List<ChatQuestionEntity.SubheadingsDTO> subList = new ArrayList<>();
mQuesDetailAdapter = new ChatQuestionDetailAdapter(R.layout.chat_quest_detail_item, subList);
viewBinding.rvChatQuick.setAdapter(mQuesDetailAdapter);
viewBinding.rvChatQuick.addItemDecoration(new GridSpacingItemDecoration(2, 10, true));
mZixunQuestAdapter = new ChatZixunAdapter(mContext, R.layout.chat_zixun_type_item, mQuesTypeList);
viewBinding.rvChatType.setAdapter(mZixunQuestAdapter);
// 设置聊天RecyclerView的LayoutManager禁用滚动
androidx.recyclerview.widget.LinearLayoutManager chatLayoutManager =
new androidx.recyclerview.widget.LinearLayoutManager(mContext);
chatLayoutManager.setStackFromEnd(false);
viewBinding.rvChat.setLayoutManager(chatLayoutManager);
// 禁用RecyclerView的滚动让NestedScrollView处理滚动
viewBinding.rvChat.setNestedScrollingEnabled(false);
mHintAdapter = new IndexEnterHintAdapter(mContext, R.layout.index_enter_hint_item, new ArrayList<>());
viewBinding.rvEnterHint.setAdapter(mHintAdapter);
setAdapterClick();
// 添加EditText的焦点监听器
viewBinding.editInput.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
// EditText获取焦点时延迟滚动到底部确保键盘弹出后再滚动
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
scrollNestedScrollViewToBottom();
}
}, 300); // 延迟300ms等待键盘弹出
}
}
});
viewBinding.editInput.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if (s != null) {
mCurrentInputContent = s.toString().trim();
if (TextUtils.isEmpty(s.toString().trim())) {
viewBinding.imgSend.setImageDrawable(ContextCompat.getDrawable(mContext, R.mipmap.icon_index_send));
viewBinding.editInput.setHint("请输入您的问题");
} else {
viewBinding.imgSend.setImageDrawable(ContextCompat.getDrawable(mContext, R.mipmap.icon_index_send_b));
}
}
}
});
//请求页面模板数据
mPresenter.getIndexTemplateDatas();
mPresenter.getChatTemplateDatas();
//组件增加点击区域
ClickUtil.addClickPart(viewBinding.imgCloseQuick, 30);
ClickUtil.addClickPart(viewBinding.imgRefresh, 30);
ClickUtil.addClickPart(viewBinding.imgHistory, 30);
// 设置智能滚动监听
setupSmartScrollListener();
// 设置页面点击监听,用于隐藏键盘
setupPageClickListener();
// 检查是否有传递过来的参数
checkAndHandleBundle();
}
/**
* 检查并处理传递过来的Bundle参数
*/
private void checkAndHandleBundle() {
Bundle args = getArguments();
if (args != null) {
handleBirthInfoBundle(args);
}
}
/**
* 处理出生信息Bundle参数
*
* @param bundle 包含出生信息的Bundle
*/
public void handleBirthInfoBundle(Bundle bundle) {
if (bundle != null) {
BaziResultBean baseEntity = PaipanCache.get();
// 获取出生信息
BaziResultBean.BaseInfoDTO birthInfo = baseEntity.getBaseInfo();
BaziResultBean.DetailInfoDTO.SizhuInfoDTO sizhuInfoDTO = baseEntity.getDetailInfo().getSizhuInfo();
BaziResultBean.DetailInfoDTO.DayunInfoDTO defaulLiunian = (BaziResultBean.DetailInfoDTO.DayunInfoDTO) bundle.getSerializable("defaul_liunian");
if (birthInfo != null) {
viewBinding.editInput.setText("我叫" + birthInfo.getName() + "," +
((birthInfo.getSex().equals("乾造") ? "" : "") + "," +
"生于公历" + birthInfo.getGongli() + "," + "当前大运为" + defaulLiunian.getDayunStartYear() + "--" +
defaulLiunian.getDayunEndYear() + "" + defaulLiunian.getDayunStartGanzhi() + "大运,四柱为"
+ sizhuInfoDTO.getYear().getTg() + sizhuInfoDTO.getYear().getDz() + "" +
sizhuInfoDTO.getMonth().getTg() + sizhuInfoDTO.getMonth().getDz() + "" +
sizhuInfoDTO.getDay().getTg() + sizhuInfoDTO.getDay().getDz() + "" +
sizhuInfoDTO.getHour().getTg() + sizhuInfoDTO.getHour().getDz() + "," +
"现在需要你根据我的八字,给我具体分析一下我的事业、感情、健康、财富、格局、喜用神"));
}
}
}
/**
* 当Fragment参数更新时调用用于处理onNewIntent的情况
*/
@Override
public void onResume() {
super.onResume();
// 检查是否有新的参数需要处理
Bundle args = getArguments();
if (args != null && args.getBoolean("goto_index_fragment", false)) {
// 处理参数
handleBirthInfoBundle(args);
// 清除标记,避免重复处理
args.remove("goto_index_fragment");
}
}
@Subscribe(threadMode = ThreadMode.MainThread)
public void onGetMessage(EventMessage message) {
//用户添加地址成功
if (message.getEventStrKey().equals(EventMessage.HISTORY_SESSIONID_DELETE_SUCCESS)) {
if (message.getMsg().equals(mSessionId)) {
// viewBinding.linearOptionHint.setVisibility(View.VISIBLE);
mChatMsgList.clear();
mChatAdapter.setNewData(mChatMsgList);
mSessionId = "";
}
}
}
/**
* 设置页面点击监听器
*/
private void setupPageClickListener() {
viewBinding.rvChat.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// 当用户触摸NestedScrollView时隐藏键盘并清除焦点
if (event.getAction() == MotionEvent.ACTION_DOWN) {
hideKeyboardAndClearFocus();
}
return false;
}
});
}
/**
* 隐藏键盘并清除EditText焦点
*/
private void hideKeyboardAndClearFocus() {
// 清除EditText焦点
viewBinding.editInput.clearFocus();
// 隐藏键盘
InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
imm.hideSoftInputFromWindow(viewBinding.editInput.getWindowToken(), 0);
}
}
/**
* 滚动NestedScrollView到底部
*/
private void scrollNestedScrollViewToBottom() {
if (viewBinding.nestedScrollChat != null) {
// 获取NestedScrollView的子视图RecyclerView
View childView = viewBinding.nestedScrollChat.getChildAt(0);
if (childView != null) {
// 滚动到底部
viewBinding.nestedScrollChat.smoothScrollTo(0, childView.getHeight());
}
}
}
/**
* 设置智能滚动监听器修改为监听NestedScrollView
*/
private void setupSmartScrollListener() {
// 监听NestedScrollView的滚动
viewBinding.nestedScrollChat.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
@Override
public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
// 检测用户是否向上滑动
if (scrollY < oldScrollY) {
// 用户向上滑动
mIsUserScrolling = true;
} else if (scrollY > oldScrollY) {
// 用户向下滑动
mIsUserScrolling = true;
}
// 检查是否滚动到底部
if (scrollY >= (v.getChildAt(0).getHeight() - v.getHeight())) {
// 滚动到底部,恢复自动滚动
mIsUserScrolling = false;
}
}
});
}
private void setAdapterClick() {
//顶部的选项 adapter 点击事件
mOptionAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
@Override
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
if (mCurrentStreamPos != position) {
if (mIsStreamStop) {
viewBinding.rlQuickAsk.setVisibility(View.GONE);
mOptionAdapter.setSelectPos(position);
setOptionSelStyle(position);
mCurrentStreamPos = position;
mSessionId = "";
mSelectTypeID = mIndexTemList.get(position).getId();
} else {
ToastUtil.showShort(mContext, "Ai解答中请稍后操作");
}
}
}
});
//咨询类型 adapter
mZixunQuestAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
@Override
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
if (mIsStreamStop) {
mZixunQuestAdapter.setSelectPos(position);
mQuesDetailAdapter.setNewData(mQuesTypeList.get(position).getSubheadings());
} else {
ToastUtil.showShort(mContext, "Ai解答中请稍后操作");
}
}
});
//快速提问
mQuesDetailAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
@Override
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
if (!AppConfig.USER_LOGIN) {
goTo(mContext, LoginActivity.class, null);
return;
}
if (!mIsStreamStop) {
ToastUtil.showShort(mContext, "Ai解答中请稍后操作");
return;
}
String quickAskContent = mQuesTypeList.get(mZixunQuestAdapter.getmSelPos()).
getSubheadings().get(position).getContent();
sendMsgToAi(quickAskContent);
}
});
//流式输出,是否完成
mChatAdapter.setOnStreamCompleteListener(new IndexChatAdapter.OnStreamCompleteListener() {
@Override
//此时已经流式输出完成
public void onStreamComplete(int position) {
mCurrentStreamPos = position;
viewBinding.imgSend.setVisibility(View.VISIBLE);
viewBinding.imgStop.setVisibility(View.GONE);
mIsStreamStop = true;
}
@Override
public void onStreamStop() {
viewBinding.imgSend.setVisibility(View.VISIBLE);
viewBinding.imgStop.setVisibility(View.GONE);
mIsStreamStop = true;
}
});
mChatAdapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {
@Override
public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
switch (view.getId()) {
case R.id.img_jb:
ContentReportDialog cancelDialog = new ContentReportDialog(mContext, R.layout.dialog_report_reason, "");
cancelDialog.show();
cancelDialog.setOnDialogListener(new ContentReportDialog.DialogListener() {
@Override
public void callBackDatas(String reason) {
showLoadingDialog();
//举报
mPresenter.commitReport(reason);
}
});
break;
}
}
});
// 设置长按菜单监听器
mChatAdapter.setOnItemLongClickMenuListener(new IndexChatAdapter.OnItemLongClickMenuListener() {
@Override
public void onCopyClick(ChatMultiItem item, int position) {
// 处理复制操作
String content = item.getMessage().getContent();
if (!TextUtils.isEmpty(content)) {
ClipboardManager clipboard = (ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("chat_content", content);
clipboard.setPrimaryClip(clip);
ToastUtil.showShort(mContext, "内容已复制");
}
}
@Override
public void onReportClick(ChatMultiItem item, int position) {
// 处理举报操作
ContentReportDialog cancelDialog = new ContentReportDialog(mContext, R.layout.dialog_report_reason, "");
cancelDialog.show();
cancelDialog.setOnDialogListener(new ContentReportDialog.DialogListener() {
@Override
public void callBackDatas(String reason) {
showLoadingDialog();
//举报
mPresenter.commitReport(reason);
}
});
}
});
// 添加长按监听器
// mChatAdapter.setOnItemChildLongClickListener(new BaseQuickAdapter.OnItemChildLongClickListener() {
// @Override
// public boolean onItemChildLongClick(BaseQuickAdapter adapter, View view, int position) {
// switch (view.getId()) {
// case R.id.tv_text: // 文本内容的view id
// XPopup.fixLongClick(view); // 能保证弹窗弹出后下层的View无法滑动
//
// // 获取当前消息内容
// ChatMultiItem item = mChatMsgList.get(position);
// String content = item.getMessage().getContent();
//
// // 使用链式调用确保atView在asAttachList之前
// new XPopup.Builder(getContext())
// .hasShadowBg(false)
// .atView(view) // 使用atView而不是watchView
// .asAttachList(new String[]{"复制", "举报"},
// null,
// new OnSelectListener() {
// @Override
// public void onSelect(int selectPosition, String text) {
// switch (selectPosition) {
// case 0: // 复制
// if (!TextUtils.isEmpty(content)) {
// ClipboardManager clipboard = (ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE);
// ClipData clip = ClipData.newPlainText("chat_content", content);
// clipboard.setPrimaryClip(clip);
// ToastUtil.showShort(mContext, "内容已复制");
// }
// break;
// case 1: // 举报
// ContentReportDialog cancelDialog = new ContentReportDialog(mContext, R.layout.dialog_report_reason, "");
// cancelDialog.show();
// cancelDialog.setOnDialogListener(new ContentReportDialog.DialogListener() {
// @Override
// public void callBackDatas(String reason) {
// showLoadingDialog();
// //举报
// mPresenter.commitReport(reason);
// }
// });
// break;
// }
// }
// })
// .show();
// return true;
// }
// return false;
// }
// });
}
/**
* 停止输出
*/
private void stopSteamOutput() {
// 停止当前网络请求
mPresenter.stopCurrentRequest();
// 获取当前正在流式输出的位置
int currentPosition = mChatMsgList.size() - 1;
// 标记当前消息为被停止状态
mChatAdapter.markAsStopped(currentPosition);
// 停止适配器中的流式输出
mChatAdapter.setStreamerStop(currentPosition);
// 清除当前流式输出位置
mChatAdapter.setCurrentStreamingPosition(-1);
// 强制更新当前item以显示停止标识
mChatAdapter.notifyItemChanged(currentPosition);
// 恢复UI状态
viewBinding.imgSend.setVisibility(View.VISIBLE);
viewBinding.imgStop.setVisibility(View.GONE);
mIsStreamStop = true;
}
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (data != null) {
if (resultCode == RESULT_OK) {
switch (requestCode) {
case REQUEST_EVENT_CODE_10001:
String sessionId = data.getStringExtra("session_id");
String numerologyType = data.getStringExtra("numerology_type");
int showSelPos = -1;
for (int i = 0; i < mIndexTemList.size(); i++) {
if (numerologyType.equals(mIndexTemList.get(i).getId())) {
showSelPos = i;
}
}
if (mCurrentStreamPos != showSelPos) {
}
if (mIsStreamStop) {
viewBinding.rlQuickAsk.setVisibility(View.GONE);
mOptionAdapter.setSelectPos(showSelPos);
setOptionSelStyle(showSelPos);
mCurrentStreamPos = showSelPos;
mSelectTypeID = mIndexTemList.get(showSelPos).getId();
if (!TextUtils.isEmpty(sessionId)) {
mPresenter.getChatDetailByID(sessionId);
}
} else {
ToastUtil.showShort(mContext, "Ai解答中请稍后操作");
}
break;
}
}
}
}
/**
* 发送消息给 AI
*/
private void sendMsgToAi(String senMsg) {
if (!AppConfig.USER_LOGIN) {
goTo(mContext, LoginActivity.class, null);
return;
}
viewBinding.cardQuestion.setVisibility(View.GONE);
viewBinding.imgClose.setImageDrawable(ContextCompat.getDrawable(mContext, R.mipmap.icon_chat_down));
mIsShowQuestions = false;
viewBinding.linearOptionHint.setVisibility(View.GONE);
// 重置滚动状态
mIsUserScrolling = false;
// 清理适配器缓存
mChatAdapter.clearCache();
// 创建用户消息
ChatAiMsgEntity chatMsgEntity = new ChatAiMsgEntity();
chatMsgEntity.setSessionId(mSessionId);
chatMsgEntity.setType(mSelectTypeID);
chatMsgEntity.setContent(senMsg);
ChatMultiItem userEntity = new ChatMultiItem(ChatMultiItem.TYPE_TEXT_RIGHT, chatMsgEntity);
mChatMsgList.add(userEntity);
mChatAdapter.notifyItemInserted(mChatMsgList.size() - 1);
// 创建AI回复消息初始为空
mCurrentStreamEntity = new ChatAiMsgEntity();
mCurrentStreamEntity.setSessionId(mSessionId);
mCurrentStreamEntity.setType(mSelectTypeID);
mCurrentStreamEntity.setContent(""); // 初始为空
ChatMultiItem aiEntity = new ChatMultiItem(ChatMultiItem.TYPE_TEXT_LEFT, mCurrentStreamEntity);
mChatMsgList.add(aiEntity);
// 设置当前流式输出位置
int aiMessagePosition = mChatMsgList.size() - 1;
mChatAdapter.setCurrentStreamingPosition(aiMessagePosition);
mChatAdapter.notifyItemInserted(aiMessagePosition);
// 重置流式数据累积器
mStreamContentBuilder.setLength(0);
// 清空输入框
viewBinding.editInput.setText("");
// 设置UI状态
viewBinding.imgSend.setVisibility(View.GONE);
viewBinding.imgStop.setVisibility(View.VISIBLE);
// 发送消息后自动滚动到底部
scrollToBottomAfterSend();
// 发起流式请求
mPresenter.talkToAi(senMsg, mSelectTypeID, mSessionId);
}
@Override
public IndexPresenter createPresenter() {
return new IndexPresenter(new IndexImpl());
}
@Override
public void getTalkResultSuccess(ChatAiMsgEntity bean) {
hideDialogLoading();
}
/**
* 首页数据获取成功
*
* @param list
*/
@Override
public void getIndexTemplateSuccess(List<IndexTemplateEntity> list) {
if (list != null && list.size() != 0) {
mIndexTemList = list;
mOptionAdapter.setNewData(mIndexTemList);
setAdapterClick();
setOptionSelStyle(0);
mSelectTypeID = mIndexTemList.get(0).getId();
}
}
/**
* 切换设置显示内容
*
* @param pos
*/
private void setOptionSelStyle(int pos) {
try {
mChatMsgList.clear();
mChatAdapter.setNewData(mChatMsgList);
// 清理缓存
mChatAdapter.clearCache();
// viewBinding.linearOptionHint.setVisibility(View.VISIBLE);
IndexTemplateEntity defaulEntity = mIndexTemList.get(pos);
viewBinding.tvTitleExpert.setText(defaulEntity.getTitle() + "专家");
viewBinding.tvSelectOptionLable.setText(defaulEntity.getTitle() + "专家");
viewBinding.tvSelectOptionSlogan.setText(defaulEntity.getSubheading());
if (ColorManage.getInstance().isParsableColor(defaulEntity.getColor())) {
viewBinding.tvSelectOptionSlogan.setTextColor(Color.parseColor(defaulEntity.getColor()));
} else {
viewBinding.tvSelectOptionSlogan.setTextColor(ContextCompat.getColor(mContext, R.color.color_zhu));
}
//提示语
List<String> hintMsgList = new ArrayList<>();
hintMsgList = Arrays.asList(defaulEntity.getIntermediateContent().split("#"));
mHintAdapter.setNewData(hintMsgList);
//快速提问
mQuickAskList.clear();
List<String> quickAskList = new ArrayList<>();
quickAskList = Arrays.asList(defaulEntity.getQuickQuestions().split("#"));
for (String content : quickAskList) {
IndexTemplateEntity entity = new IndexTemplateEntity();
entity.setColor(defaulEntity.getColor());
entity.setBlackcolor(defaulEntity.getBlackcolor());
entity.setSpliteItemContent(content);
mQuickAskList.add(entity);
}
mQuickAskAdapter.setNewData(mQuickAskList);
} catch (Exception e) {
}
}
@Override
public void onNetChange(int netModel) {
}
@Override
public void showError(String message) {
hideDialogLoading();
ToastUtil.showShort(mContext, message);
// 流式传输完成恢复UI状态
viewBinding.imgSend.setVisibility(View.VISIBLE);
viewBinding.imgStop.setVisibility(View.GONE);
mIsStreamStop = true;
// 可以在这里处理会话ID等
if (mCurrentStreamEntity != null && !TextUtils.isEmpty(mCurrentStreamEntity.getSessionId())) {
mSessionId = mCurrentStreamEntity.getSessionId();
}
// 清理当前流式实体
mCurrentStreamEntity = null;
mStreamContentBuilder.setLength(0);
}
@Override
public void logOut(BaseBean bean) {
}
// 实现流式消息接收回调
@Override
public void onStreamMessageReceived(String messageChunk) {
mIsStreamStop = false;
if (mCurrentStreamEntity != null) {
// 更新当前AI消息的内容
mCurrentStreamEntity.setContent(messageChunk);
// 取消之前的更新任务
if (mUpdateRunnable != null) {
mUpdateHandler.removeCallbacks(mUpdateRunnable);
}
mUpdateRunnable = () -> {
// 只更新最后一个item
int lastPosition = mChatMsgList.size() - 1;
if (lastPosition >= 0) {
// 使用更轻量的更新方式,避免重新布局
mChatAdapter.notifyItemChanged(lastPosition, "content_only");
// 流式输出时如果用户没有手动滑动则自动滚动NestedScrollView
if (!mIsUserScrolling) {
smoothScrollNestedScrollView();
}
}
};
// 增加延迟时间,减少更新频率
mUpdateHandler.postDelayed(mUpdateRunnable, 100);
}
}
// 实现流式完成回调
@Override
public void onStreamComplete(String complateMsg) {
// 流式传输完成恢复UI状态
viewBinding.imgSend.setVisibility(View.VISIBLE);
viewBinding.imgStop.setVisibility(View.GONE);
mIsStreamStop = true;
// 清除当前流式输出位置
mChatAdapter.setCurrentStreamingPosition(-1);
// 注意:这里不标记为停止状态,因为这是正常完成
// 可以在这里处理会话ID等
if (mCurrentStreamEntity != null && !TextUtils.isEmpty(mCurrentStreamEntity.getSessionId())) {
mSessionId = mCurrentStreamEntity.getSessionId();
}
// 清理当前流式实体
mCurrentStreamEntity = null;
mStreamContentBuilder.setLength(0);
// 假设你最后一个消息是流式的 placeholder现在替换它
ChatMultiItem lastMessage = mChatMsgList.get(mChatMsgList.size() - 1);
lastMessage.getMessage().setContent(complateMsg); // 你可以解析 Markdown 变 PlainText或保留 Markdown 渲染
// mChatAdapter.notifyItemChanged(mChatMsgList.size() - 1); // 更新 UI
int lastPos = mChatAdapter.getItemCount() - 1;
mChatAdapter.updateTipsVisibility(lastPos);
}
/**
* 根据会话 id 查询对话详情
*
* @param list
*/
@Override
public void getChatDetailSuccess(List<ChatAiMsgEntity> list) {
mChatMsgList.clear();
if (list != null && list.size() != 0) {
mSessionId = list.get(0).getSessionId();
}
for (ChatAiMsgEntity entity : list) {
ChatMultiItem item;
if (entity.getRole().equals("user")) {
item = new ChatMultiItem(ChatMultiItem.TYPE_TEXT_RIGHT, entity);
} else {
item = new ChatMultiItem(ChatMultiItem.TYPE_TEXT_LEFT, entity);
}
mChatMsgList.add(item);
}
mChatAdapter.setNewData(mChatMsgList);
viewBinding.linearOptionHint.setVisibility(View.GONE);
}
@Override
public void loginLost() {
if (isFragmentVisible()) {
handleLoginLost();
}
stopSteamOutput();
if (mChatAdapter != null) {
mChatAdapter.remove(mChatMsgList.size() - 1);
}
}
/**
* 获取咨询模板成功
*
* @param list
*/
@Override
public void getChatZixunSuccess(List<ChatQuestionEntity> list) {
this.mQuesTypeList = list;
if (list != null) {
mZixunQuestAdapter.setNewData(list);
mQuesDetailAdapter.setNewData(list.get(0).getSubheadings());
setAdapterClick();
}
}
/**
* 举报成功
* @param bean
*/
@Override
public void commitReportSuccess(BaseBean bean) {
ToastUtil.showShort(mContext, "星语明灯感谢您的反馈");
hideDialogLoading();
}
// 实现sessionId接收回调
@Override
public void onSessionReceived(String sessionId) {
// 保存sessionId
mSessionId = sessionId;
}
@Override
public void getHistoryDataSuccess(CharHistoryEntity entity) {
}
@Override
public void deleteHistorySuccess(BaseBean bean, int delPos) {
}
/**
* 平滑滚动NestedScrollView到底部
*/
private void smoothScrollNestedScrollView() {
if (mChatAdapter != null && mChatAdapter.getItemCount() > 0) {
// 直接滚动NestedScrollView到底部
viewBinding.nestedScrollChat.post(() -> {
viewBinding.nestedScrollChat.fullScroll(View.FOCUS_DOWN);
});
}
}
/**
* 发送消息后滚动到底部
*/
private void scrollToBottomAfterSend() {
new Handler().postDelayed(() -> {
if (isFragmentVisible()) {
viewBinding.nestedScrollChat.fullScroll(View.FOCUS_DOWN);
}
}, 100);
}
@Override
public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) {
}
@Override
public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
}
}