diff --git a/app/src/main/java/com/zjgsu/jianshu/Activity/Author_introductionActivity.kt b/app/src/main/java/com/zjgsu/jianshu/Activity/Author_introductionActivity.kt
index 9d2536f..5242f99 100644
--- a/app/src/main/java/com/zjgsu/jianshu/Activity/Author_introductionActivity.kt
+++ b/app/src/main/java/com/zjgsu/jianshu/Activity/Author_introductionActivity.kt
@@ -33,10 +33,10 @@ class Author_introductionActivity : AppCompatActivity() {
authorwork_recyclerView.adapter = adapter
inits()
author_back.setOnClickListener {
- val bookName=intent.getStringExtra("book_name")
- val intent = Intent(this, BookInformationActivity::class.java)
- intent.putExtra("Book_name", bookName)
- startActivity(intent)
+// val bookName=intent.getStringExtra("book_name")
+// val intent = Intent(this, BookInformationActivity::class.java)
+// intent.putExtra("Book_name", bookName)
+// startActivity(intent)
finish()
}
}
diff --git a/app/src/main/java/com/zjgsu/jianshu/Activity/BookInformationActivity.kt b/app/src/main/java/com/zjgsu/jianshu/Activity/BookInformationActivity.kt
index 37fe275..d626e8b 100644
--- a/app/src/main/java/com/zjgsu/jianshu/Activity/BookInformationActivity.kt
+++ b/app/src/main/java/com/zjgsu/jianshu/Activity/BookInformationActivity.kt
@@ -156,15 +156,15 @@ class BookInformationActivity : AppCompatActivity() {
}
//TODO:不一定回到MainActivity::class,后面还要在跳转前保存上一个页面
bookinfo_return.setOnClickListener {
- if (sourceActivityClass != null) {
- // 返回到上一个页面
- val intent = Intent(this, sourceActivityClass!!)
- startActivity(intent)
- } else {
- // 如果没有来源页面信息,则返回到 MainActivity
- val intent = Intent(this, MainActivity::class.java)
- startActivity(intent)
- }
+// if (sourceActivityClass != null) {
+// // 返回到上一个页面
+// val intent = Intent(this, sourceActivityClass!!)
+// startActivity(intent)
+// } else {
+// // 如果没有来源页面信息,则返回到 MainActivity
+// val intent = Intent(this, MainActivity::class.java)
+// startActivity(intent)
+// }
finish()
}
addBook2.setOnClickListener {
diff --git a/app/src/main/java/com/zjgsu/jianshu/Activity/GoodBookActivity.kt b/app/src/main/java/com/zjgsu/jianshu/Activity/GoodBookActivity.kt
index 2f6688f..01fe9db 100644
--- a/app/src/main/java/com/zjgsu/jianshu/Activity/GoodBookActivity.kt
+++ b/app/src/main/java/com/zjgsu/jianshu/Activity/GoodBookActivity.kt
@@ -92,8 +92,8 @@ class GoodBookActivity : AppCompatActivity() {
}
private fun returnTOCity() {
bookrank_return.setOnClickListener {
- val intent = Intent(this, MainActivity::class.java)
- startActivity(intent)
+// val intent = Intent(this, MainActivity::class.java)
+// startActivity(intent)
finish() // 结束当前页面
}
}
diff --git a/app/src/main/java/com/zjgsu/jianshu/Activity/HotBookActivity.kt b/app/src/main/java/com/zjgsu/jianshu/Activity/HotBookActivity.kt
index 3b1b331..738f229 100644
--- a/app/src/main/java/com/zjgsu/jianshu/Activity/HotBookActivity.kt
+++ b/app/src/main/java/com/zjgsu/jianshu/Activity/HotBookActivity.kt
@@ -79,8 +79,8 @@ class HotBookActivity: AppCompatActivity() {
//TODO:未来添加一个返回到上个页面指定位置的功能
private fun returnTOCity() {
bookrank_return.setOnClickListener {
- val intent = Intent(this, MainActivity::class.java)
- startActivity(intent)
+// val intent = Intent(this, MainActivity::class.java)
+// startActivity(intent)
finish() // 结束当前页面
}
}
diff --git a/app/src/main/java/com/zjgsu/jianshu/Activity/LiteratureActivity.kt b/app/src/main/java/com/zjgsu/jianshu/Activity/LiteratureActivity.kt
index 320ade8..eaae30c 100644
--- a/app/src/main/java/com/zjgsu/jianshu/Activity/LiteratureActivity.kt
+++ b/app/src/main/java/com/zjgsu/jianshu/Activity/LiteratureActivity.kt
@@ -97,7 +97,8 @@ class LiteratureActivity : AppCompatActivity() {
}
private fun returnToBookcity(){
categoryPage_back.setOnClickListener{
- startActivity(Intent(this, MainActivity::class.java))
+// startActivity(Intent(this, MainActivity::class.java))
+ finish()
}
}
diff --git a/app/src/main/java/com/zjgsu/jianshu/Activity/ManagementActivity.kt b/app/src/main/java/com/zjgsu/jianshu/Activity/ManagementActivity.kt
index d2ab39e..0669e51 100644
--- a/app/src/main/java/com/zjgsu/jianshu/Activity/ManagementActivity.kt
+++ b/app/src/main/java/com/zjgsu/jianshu/Activity/ManagementActivity.kt
@@ -95,7 +95,8 @@ class ManagementActivity:AppCompatActivity() {
}
private fun returnToBookcity(){
categoryPage_back.setOnClickListener{
- startActivity(Intent(this, MainActivity::class.java))
+// startActivity(Intent(this, MainActivity::class.java))
+ finish()
}
}
diff --git a/app/src/main/java/com/zjgsu/jianshu/Activity/PhilosophyActivity.kt b/app/src/main/java/com/zjgsu/jianshu/Activity/PhilosophyActivity.kt
index 182b922..d1b8480 100644
--- a/app/src/main/java/com/zjgsu/jianshu/Activity/PhilosophyActivity.kt
+++ b/app/src/main/java/com/zjgsu/jianshu/Activity/PhilosophyActivity.kt
@@ -96,7 +96,8 @@ class PhilosophyActivity:AppCompatActivity() {
}
private fun returnToBookcity(){
categoryPage_back.setOnClickListener{
- startActivity(Intent(this, MainActivity::class.java))
+// startActivity(Intent(this, MainActivity::class.java))
+ finish()
}
}
diff --git a/app/src/main/java/com/zjgsu/jianshu/Activity/PsychologyActivity.kt b/app/src/main/java/com/zjgsu/jianshu/Activity/PsychologyActivity.kt
index bd2a295..726ea44 100644
--- a/app/src/main/java/com/zjgsu/jianshu/Activity/PsychologyActivity.kt
+++ b/app/src/main/java/com/zjgsu/jianshu/Activity/PsychologyActivity.kt
@@ -95,7 +95,8 @@ class PsychologyActivity:AppCompatActivity() {
}
private fun returnToBookcity(){
categoryPage_back.setOnClickListener{
- startActivity(Intent(this, MainActivity::class.java))
+// startActivity(Intent(this, MainActivity::class.java))
+ finish()
}
}
diff --git a/app/src/main/java/com/zjgsu/jianshu/Activity/ScienceActivity.kt b/app/src/main/java/com/zjgsu/jianshu/Activity/ScienceActivity.kt
index 008cf9e..c17cac2 100644
--- a/app/src/main/java/com/zjgsu/jianshu/Activity/ScienceActivity.kt
+++ b/app/src/main/java/com/zjgsu/jianshu/Activity/ScienceActivity.kt
@@ -96,7 +96,8 @@ class ScienceActivity:AppCompatActivity() {
}
private fun returnToBookcity(){
categoryPage_back.setOnClickListener{
- startActivity(Intent(this, MainActivity::class.java))
+// startActivity(Intent(this, MainActivity::class.java))
+ finish()
}
}
diff --git a/app/src/main/res/layout/activity_anthor_introduction.xml b/app/src/main/res/layout/activity_anthor_introduction.xml
index 544ac97..a7908b2 100644
--- a/app/src/main/res/layout/activity_anthor_introduction.xml
+++ b/app/src/main/res/layout/activity_anthor_introduction.xml
@@ -20,7 +20,7 @@
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginStart="10dp"
- android:padding="8dp"
+ android:padding="4dp"
android:src="@drawable/return1" />
diff --git a/app/src/main/res/layout/bookinfo_title.xml b/app/src/main/res/layout/bookinfo_title.xml
index 2fe849e..2466c26 100644
--- a/app/src/main/res/layout/bookinfo_title.xml
+++ b/app/src/main/res/layout/bookinfo_title.xml
@@ -8,6 +8,7 @@
android:id="@+id/bookinfo_return"
android:layout_width="40dp"
android:layout_height="40dp"
+ android:padding="4dp"
android:src="@drawable/return1" />
{
private List messages;
+ private Context context;
+ private OnRegenerateClickListener onRegenerateClickListener;
+ public void setOnRegenerateClickListener(OnRegenerateClickListener listener) {
+ this.onRegenerateClickListener = listener;
+ }
- public MessageAdapter(List messages) {
+ public interface OnRegenerateClickListener {
+ void onRegenerateClick(int position);
+ }
+
+ public MessageAdapter(List messages, Context context) {
this.messages = messages;
+ this.context = context;
}
@Override
@@ -38,17 +53,52 @@ public class MessageAdapter extends RecyclerView.Adapter= 0; i--) {
+ if (messages.get(i).getIsuser() == 0) { // Assuming 0 is the bot
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ private void setupClickListeners(MessageViewHolder holder, Message message, int position) {
+ holder.imageViewCopy.setOnClickListener(v -> {
+ copyTextToClipboard(message.getContent());
+ });
+
+ holder.imageViewRegenerate.setOnClickListener(view -> {
+ if (onRegenerateClickListener != null) {
+ onRegenerateClickListener.onRegenerateClick(position);
+ }
+ });
+ }
+
+ private void copyTextToClipboard(String text) {
+ ClipboardManager clipboardManager = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
+ ClipData clipData = ClipData.newPlainText("copiedText", text);
+ clipboardManager.setPrimaryClip(clipData);
+ Toast.makeText(context, "已复制到剪贴板", Toast.LENGTH_SHORT).show();
+ }
+
@Override
public int getItemCount() {
return messages.size();
@@ -56,14 +106,17 @@ public class MessageAdapter extends RecyclerView.Adapter choices;
+ public List getChoices() {
+ return choices;
+ }
+
+ public void setChoices(List choices) {
+ this.choices = choices;
+ }
+
public static class Choice {
int index;
public Message message;
diff --git a/hwtxtreaderlib/src/main/java/com/bifan/txtreaderlib/bean/GenerateQue_bmob.java b/hwtxtreaderlib/src/main/java/com/bifan/txtreaderlib/bean/GenerateQue_bmob.java
new file mode 100644
index 0000000..02c0461
--- /dev/null
+++ b/hwtxtreaderlib/src/main/java/com/bifan/txtreaderlib/bean/GenerateQue_bmob.java
@@ -0,0 +1,60 @@
+package com.bifan.txtreaderlib.bean;
+
+import cn.bmob.v3.BmobObject;
+
+public class GenerateQue_bmob extends BmobObject {
+ private String relatedBook;
+ private String userid;
+ private String ques1;
+ private String ques2;
+ private String ques3;
+
+ public GenerateQue_bmob(String relatedBook, String userid, String ques1, String ques2, String ques3) {
+ this.relatedBook = relatedBook;
+ this.userid = userid;
+ this.ques1 = ques1;
+ this.ques2 = ques2;
+ this.ques3 = ques3;
+ }
+ public GenerateQue_bmob(){}
+
+ public String getRelatedBook() {
+ return relatedBook;
+ }
+
+ public void setRelatedBook(String relatedBook) {
+ this.relatedBook = relatedBook;
+ }
+
+ public String getUserid() {
+ return userid;
+ }
+
+ public void setUserid(String userid) {
+ this.userid = userid;
+ }
+
+ public String getQues1() {
+ return ques1;
+ }
+
+ public void setQues1(String ques1) {
+ this.ques1 = ques1;
+ }
+
+ public String getQues2() {
+ return ques2;
+ }
+
+ public void setQues2(String ques2) {
+ this.ques2 = ques2;
+ }
+
+ public String getQues3() {
+ return ques3;
+ }
+
+ public void setQues3(String ques3) {
+ this.ques3 = ques3;
+ }
+}
diff --git a/hwtxtreaderlib/src/main/java/com/bifan/txtreaderlib/ui/ChatWithGptActivity.java b/hwtxtreaderlib/src/main/java/com/bifan/txtreaderlib/ui/ChatWithGptActivity.java
index 2da2636..375ac00 100644
--- a/hwtxtreaderlib/src/main/java/com/bifan/txtreaderlib/ui/ChatWithGptActivity.java
+++ b/hwtxtreaderlib/src/main/java/com/bifan/txtreaderlib/ui/ChatWithGptActivity.java
@@ -1,16 +1,21 @@
package com.bifan.txtreaderlib.ui;
+import android.content.ClipboardManager;
import android.content.Context;
+import android.content.Intent;
import android.content.SharedPreferences;
+import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
+import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.widget.NestedScrollView;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -19,6 +24,7 @@ import com.bifan.txtreaderlib.adapter.MessageAdapter;
import com.bifan.txtreaderlib.bean.ChatMessage_bmob;
import com.bifan.txtreaderlib.bean.ChatRequest;
import com.bifan.txtreaderlib.bean.ChatResponse;
+import com.bifan.txtreaderlib.bean.GenerateQue_bmob;
import com.bifan.txtreaderlib.bean.Message;
import com.bifan.txtreaderlib.interfaces.ChatGPTService;
@@ -26,14 +32,18 @@ import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
import cn.bmob.v3.Bmob;
import cn.bmob.v3.BmobQuery;
import cn.bmob.v3.exception.BmobException;
import cn.bmob.v3.listener.FindListener;
import cn.bmob.v3.listener.SaveListener;
+import cn.bmob.v3.listener.UpdateListener;
import okhttp3.OkHttpClient;
import retrofit2.Call;
import retrofit2.Callback;
@@ -41,15 +51,17 @@ import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
-public class ChatWithGptActivity extends AppCompatActivity {
+public class ChatWithGptActivity extends AppCompatActivity implements MessageAdapter.OnRegenerateClickListener {
private RecyclerView recyclerView;
private MessageAdapter messageAdapter;
private EditText editTextMessage;
private TextView chatbot_title;
- private Button buttonSend;
+ private ImageView buttonSend,chat_return;
private String bookName = "";
- private String userid="";
+ private String userid = "";
+ private String lastUserQuestion = ""; // 全局变量来存储最后一条用户消息
private ArrayList messageList = new ArrayList<>();
+ private TextView questionView1, questionView2, questionView3;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -62,41 +74,99 @@ public class ChatWithGptActivity extends AppCompatActivity {
SharedPreferences sharedPreferences = getSharedPreferences("userinf", Context.MODE_PRIVATE);
String userIdFromPrefs = sharedPreferences.getString("user_id", "");
userid = userIdFromPrefs != null ? userIdFromPrefs : "";
-
- recyclerView = findViewById(R.id.chatRecyclerView);
- editTextMessage = findViewById(R.id.inputEditText);
- buttonSend = findViewById(R.id.sendButton);
- chatbot_title=findViewById(R.id.chatbot_title);
- messageAdapter = new MessageAdapter(messageList);
- recyclerView.setLayoutManager(new LinearLayoutManager(this));
- recyclerView.setAdapter(messageAdapter);
+ setupViews();
init();
- buttonSend.setOnClickListener(new View.OnClickListener() {
+ initgenerateUserQuestions();
+ loadLastUserMessage();
+ setupListeners();
+ }
+
+ private void setupListeners() {
+ buttonSend.setOnClickListener(v -> sendandStoreMessage(editTextMessage.getText().toString()));
+
+ View.OnClickListener questionClickListener = view -> {
+ TextView questionView = (TextView) view;
+ String message = questionView.getText().toString();
+ clearQuestionsVisibility();
+ sendandStoreMessage(message);
+ };
+
+ questionView1.setOnClickListener(questionClickListener);
+ questionView2.setOnClickListener(questionClickListener);
+ questionView3.setOnClickListener(questionClickListener);
+ chat_return.setOnClickListener(new View.OnClickListener() {
@Override
- public void onClick(View v) {
- String text = editTextMessage.getText().toString();
- if (!text.isEmpty()) {
- messageList.add(new Message(text, 1)); // User message
- messageAdapter.notifyItemInserted(messageList.size() - 1);
- recyclerView.scrollToPosition(messageList.size() - 1);
- editTextMessage.setText("");
- sendMessageToChatGPT(text);
- ChatMessage_bmob chatMessage_bmob=new ChatMessage_bmob(text,1,bookName,userid);
- chatMessage_bmob.save(new SaveListener() {
- @Override
- public void done(String objectId,BmobException e) {
- if(e==null){
+ public void onClick(View view) {
+ finish();
+ }
+ });
+ }
+
+ private void clearQuestionsVisibility() {
+ questionView1.setVisibility(View.GONE);
+ questionView2.setVisibility(View.GONE);
+ questionView3.setVisibility(View.GONE);
+ }
+
+ private void sendandStoreMessage(String text) {
+ messageList.add(new Message(text, 1)); // User message
+ messageAdapter.notifyItemInserted(messageList.size() - 1);
+ editTextMessage.setText("");
+ sendMessageToChatGPT(text);
+ lastUserQuestion=text;
+ storeMessage(text,1);
+ }
+ private void storeMessage(String text,int isuser){
+ ChatMessage_bmob chatMessage_bmob = new ChatMessage_bmob(text, isuser, bookName, userid);
+ chatMessage_bmob.save(new SaveListener() {
+ @Override
+ public void done(String objectId, BmobException e) {
+ if (e == null) {
// toast("添加数据成功,返回objectId为:"+objectId);
- }else{
- //toast("创建数据失败:" + e.getMessage());
- }
- }
- });
+ } else {
+ //toast("创建数据失败:" + e.getMessage());
}
}
});
}
- private void init(){
+
+ private void setupViews() {
+ recyclerView = findViewById(R.id.chatRecyclerView);
+ editTextMessage = findViewById(R.id.inputEditText);
+ buttonSend = findViewById(R.id.sendButton);
+ chatbot_title = findViewById(R.id.chatbot_title);
+ questionView1 = findViewById(R.id.question1);
+ questionView2 = findViewById(R.id.question2);
+ questionView3 = findViewById(R.id.question3);
+ chat_return=findViewById(R.id.chat_return);
+ messageAdapter = new MessageAdapter(messageList, this);
+ messageAdapter.setOnRegenerateClickListener(this);
+ recyclerView.setLayoutManager(new LinearLayoutManager(this));
+ recyclerView.setAdapter(messageAdapter);
+ }
+
+ private void loadLastUserMessage() {
+ BmobQuery bmobQuery = new BmobQuery<>();
+ bmobQuery.addWhereEqualTo("relatedBook", bookName);
+ bmobQuery.addWhereEqualTo("userid", userid);
+ bmobQuery.addWhereEqualTo("isuser", 1); // 只查找用户的消息
+ bmobQuery.order("-createdAt"); // 按创建时间降序排列,以确保最新的消息排在最前
+ bmobQuery.setLimit(1); // 只获取一条记录
+
+ bmobQuery.findObjects(new FindListener() {
+ @Override
+ public void done(List messages, BmobException e) {
+ if (e == null && messages != null && !messages.isEmpty()) {
+ lastUserQuestion = messages.get(0).getContent(); // 获取最新的用户消息
+ // 可以在此处更新界面或处理消息
+ } else {
+ Log.e("ChatActivity", "No recent user message found, or error fetching data: " + (e != null ? e.getMessage() : "No details"));
+ }
+ }
+ });
+ }
+
+ private void init() {
chatbot_title.setText(bookName);
BmobQuery bmobQuery = new BmobQuery<>();
bmobQuery.addWhereEqualTo("relatedBook", bookName);
@@ -118,13 +188,13 @@ public class ChatWithGptActivity extends AppCompatActivity {
// 如果没有消息,添加一条 bot 的欢迎消息
String welcomeMessage = "你好!我是你的阅读助手。我可以帮助你解答关于书籍的各种问题,比如内容概述、作者信息、主要主题和角色分析等。请随时向我提问,现在,你有什么关于《" + bookName + "》的问题吗?";
messageList.add(new Message(welcomeMessage, 0)); // 假设 0 表示系统或助手消息
- ChatMessage_bmob chatMessage_bmob=new ChatMessage_bmob(welcomeMessage,0,bookName,userid);
+ ChatMessage_bmob chatMessage_bmob = new ChatMessage_bmob(welcomeMessage, 0, bookName, userid);
chatMessage_bmob.save(new SaveListener() {
@Override
- public void done(String objectId,BmobException e) {
- if(e==null){
+ public void done(String objectId, BmobException e) {
+ if (e == null) {
// toast("添加数据成功,返回objectId为:"+objectId);
- }else{
+ } else {
//toast("创建数据失败:" + e.getMessage());
}
}
@@ -139,6 +209,58 @@ public class ChatWithGptActivity extends AppCompatActivity {
});
}
+ private void initgenerateUserQuestions() {
+ BmobQuery bmobQuery = new BmobQuery<>();
+ bmobQuery.addWhereEqualTo("relatedBook", bookName);
+ bmobQuery.addWhereEqualTo("userid", userid);
+ bmobQuery.addWhereEqualTo("isuser", 1);
+ bmobQuery.findObjects(new FindListener() {
+ @Override
+ public void done(List messages, BmobException e) {
+ if (e == null && messages != null) {
+ if (!messages.isEmpty()) {
+ BmobQuery bmobQueryGen = new BmobQuery<>();
+ bmobQueryGen.addWhereEqualTo("relatedBook", bookName);
+ bmobQueryGen.addWhereEqualTo("userid", userid);
+ bmobQueryGen.findObjects(new FindListener() {
+ @Override
+ public void done(List list, BmobException e) {
+ if (e == null) {
+ for (GenerateQue_bmob generateQue : list) {
+ if (generateQue.getQues1() != null) {
+ questionView1.setVisibility(View.VISIBLE);
+ questionView1.setText(generateQue.getQues1());
+ }
+ if (generateQue.getQues2() != null) {
+ questionView2.setVisibility(View.VISIBLE);
+ questionView2.setText(generateQue.getQues2());
+ }
+ if (generateQue.getQues2() != null) {
+ questionView3.setVisibility(View.VISIBLE);
+ questionView3.setText(generateQue.getQues3());
+ }
+ }
+ } else {
+
+ }
+ }
+ });
+ } else {
+ questionView1.setVisibility(View.VISIBLE);
+ questionView1.setText("请告诉我有关这本书的内容概述。");
+ questionView2.setVisibility(View.VISIBLE);
+ questionView2.setText("请告诉有关这本书作者的信息。");
+ questionView3.setVisibility(View.VISIBLE);
+ questionView3.setText("请告诉我这本书的主题是什么。");
+ }
+ messageAdapter.notifyDataSetChanged();
+ } else {
+ Log.e("BookInfo", "Error loading book info: " + (e != null ? e.getMessage() : ""));
+ }
+ }
+ });
+ }
+
/**
* 从数据库加载历史对话并构建消息列表
*/
@@ -147,18 +269,17 @@ public class ChatWithGptActivity extends AppCompatActivity {
BmobQuery bmobQuery = new BmobQuery<>();
bmobQuery.addWhereEqualTo("relatedBook", bookName);
bmobQuery.addWhereEqualTo("userid", userId);
- bmobQuery.order("createdAt");
+ bmobQuery.order("-createdAt");
bmobQuery.setLimit(10); //设置上下文最多10条历史对话
bmobQuery.findObjects(new FindListener() {
@Override
public void done(List chatMessages, BmobException e) {
if (e == null && chatMessages != null && !chatMessages.isEmpty()) {
for (ChatMessage_bmob item : chatMessages) {
- // 根据消息来源判断角色,假设 0 表示用户,1 表示助手
String role = item.getIsuser() == 0 ? "user" : "assistant";
messages.add(new ChatRequest.Message(role, item.getContent()));
- Log.d("test",item.getContent());
}
+ Collections.reverse(messages); // 反转列表以使消息按时间升序排列, 展示最近的10条数据,按时间顺序。
} else {
Log.e("BookInfo", "Error loading book info: " + (e != null ? e.getMessage() : "No error details."));
}
@@ -168,6 +289,7 @@ public class ChatWithGptActivity extends AppCompatActivity {
}
private void sendMessageToChatGPT(String messageText) {
+ buttonSend.setImageResource(R.drawable.ic_loading);
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
@@ -180,16 +302,25 @@ public class ChatWithGptActivity extends AppCompatActivity {
.build();
ChatGPTService service = retrofit.create(ChatGPTService.class);
List messages = new ArrayList<>();
- String prompt = "你好!我是你的阅读助手。我可以帮助你解答关于书籍的各种问题,比如内容概述、作者信息、主要主题和角色分析等。请随时向我提问,我会用中文简体来回答你。现在,你有什么关于《" + bookName + "》的问题吗?";
- messages.add(new ChatRequest.Message("system", prompt));
+ String prompt = "你好!我是你的阅读助手。";
-// messages.add(new ChatRequest.Message("system", "You are a reading assistant. The user will ask you questions about the book '" + bookName + "'."));
+ if (messageText.equals("请告诉我更多内容。") && !lastUserQuestion.isEmpty()) {
+ // 特别关注用户的上一个问题
+ prompt += "你之前问了关于《" + bookName + "》的'" + lastUserQuestion + "'。关于这个问题,你需要更多的哪方面信息?";
+ } else if (!lastUserQuestion.isEmpty()) {
+ // 处理正常的用户问题
+ prompt += "关于你之前的问题:" + lastUserQuestion + ",你需要我提供更多的信息吗?或者,你有其他关于《" + bookName + "》的新问题吗?";
+ } else {
+ // 没有历史问题的情况
+ prompt += "我可以帮助你解答关于《" + bookName + "》的各种问题,比如内容概述、作者信息、主要主题和角色分析等。请随时向我提问,现在,你有什么问题吗?";
+ }
+ messages.add(new ChatRequest.Message("system", prompt));
messages.addAll(loadMessagesFromDatabase(bookName, userid));
messages.add(new ChatRequest.Message("user", messageText)); // 添加用户消息
ChatRequest request = new ChatRequest(messages); // 使用消息列表创建请求
request.setModel("gpt-4-turbo"); // 根据需要选择不同的模型
- request.setMaxTokens(200); // 设置最大 token 数,根据需要调整
+ request.setMaxTokens(50); // 设置最大 token 数,根据需要调整
request.setTemperature(0.5); // 设置适当的温度
service.postMessage(request).enqueue(new Callback() {
@Override
@@ -201,19 +332,11 @@ public class ChatWithGptActivity extends AppCompatActivity {
String reply = message.content; // 这是从 GPT-3.5 响应中提取的内容
runOnUiThread(() -> {
messageList.add(new Message(reply, 0));
- messageAdapter.notifyItemInserted(messageList.size() - 1);
- recyclerView.scrollToPosition(messageList.size() - 1);
- ChatMessage_bmob chatMessage_bmob = new ChatMessage_bmob(reply, 0, bookName, userid);
- chatMessage_bmob.save(new SaveListener() {
- @Override
- public void done(String objectId, BmobException e) {
- if (e == null) {
- // toast("添加数据成功,返回objectId为:" + objectId);
- } else {
- // toast("创建数据失败:" + e.getMessage());
- }
- }
- });
+ messageAdapter.notifyDataSetChanged();
+ moveToNewest();
+ buttonSend.setImageResource(R.drawable.ic_send);
+ generateUserQuestions(reply);
+ storeMessage(reply,0);
});
}
} else {
@@ -226,6 +349,124 @@ public class ChatWithGptActivity extends AppCompatActivity {
}
}
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ String content="机器人响应超时,请重新生成回答!";
+ buttonSend.setImageResource(R.drawable.ic_send);
+ messageList.add(new Message(content, 0));
+ messageAdapter.notifyDataSetChanged();
+ moveToNewest();
+ storeMessage(content,0);
+ Log.e("ChatGPT", "Failure: " + t.getMessage());
+ }
+ });
+ }
+ //自动移动至最新回答
+private void moveToNewest(){
+ NestedScrollView nestedScrollView = findViewById(R.id.nestedScrollView);
+ recyclerView.post(() -> {
+ // 确保最后一条消息可见
+ if (messageList.size() > 0) {
+ recyclerView.scrollToPosition(messageList.size() - 1);
+ recyclerView.post(() -> {
+ // 获取最后一个视图的引用
+ View lastChild = recyclerView.getChildAt(recyclerView.getChildCount() - 1);
+ int bottom = lastChild.getBottom() + recyclerView.getPaddingBottom();
+ int sy = nestedScrollView.getScrollY();
+ int sh = nestedScrollView.getHeight();
+ int delta = bottom - (sy + sh);
+ nestedScrollView.smoothScrollBy(0, delta);
+ });
+ }
+ });
+}
+ //回调函数,重新生成回答
+ @Override
+ public void onRegenerateClick(int position) {
+ questionView1.setVisibility(View.GONE);
+ questionView2.setVisibility(View.GONE);
+ questionView3.setVisibility(View.GONE);
+ BmobQuery bmobQuery = new BmobQuery<>();
+ bmobQuery.addWhereEqualTo("relatedBook", bookName);
+ bmobQuery.addWhereEqualTo("userid", userid);
+ bmobQuery.addWhereEqualTo("isuser", 0);
+ bmobQuery.order("-createdAt");
+ bmobQuery.setLimit(2);
+ bmobQuery.findObjects(new FindListener() {
+ @Override
+ public void done(List chatMessages, BmobException e) {
+ if (e == null && chatMessages != null && !chatMessages.isEmpty()) {
+ for (ChatMessage_bmob item : chatMessages) {
+ ChatMessage_bmob chatMessage_bmob = new ChatMessage_bmob();
+ chatMessage_bmob.setObjectId(item.getObjectId());
+ chatMessage_bmob.delete(new UpdateListener() {
+ @Override
+ public void done(BmobException e) {
+ if (e == null) {
+ // 删除成功
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ messageList.remove(position);
+ messageAdapter.notifyItemRemoved(position);
+ messageAdapter.notifyItemRangeChanged(position, messageList.size());
+ sendMessageToChatGPT(lastUserQuestion);
+ }
+ });
+ } else {
+ // 删除失败
+ }
+ }
+ });
+ }
+ }
+ }
+ });
+ }
+
+ //模拟生成用户回答
+ private void generateUserQuestions(String lastBotReply) {
+ OkHttpClient client = new OkHttpClient.Builder()
+ .connectTimeout(60, TimeUnit.SECONDS)
+ .readTimeout(60, TimeUnit.SECONDS)
+ .writeTimeout(60, TimeUnit.SECONDS)
+ .build();
+ Retrofit retrofit = new Retrofit.Builder()
+ .client(client)
+ .baseUrl("https://api.openai-ch.top/")
+ .addConverterFactory(GsonConverterFactory.create())
+ .build();
+ ChatGPTService service = retrofit.create(ChatGPTService.class);
+
+ // 构建请求数据
+ List messages = new ArrayList<>();
+ messages.add(new ChatRequest.Message("system", "请你模拟用户的口吻,基于《" + bookName + "》" +
+ "的内容,请根据上一条聊天机器人的回复,生成两个读者可能的简短提问,每个提问不多于20个字,每个问题占一行,以序号开头,示例如下:1.勒庞是否提出了群体心理中的自我意识丧失和传染性特征?" +
+ "2.《乌合之众》是否强调了群体行为易受领导者情感诉求的影响?"));
+ messages.add(new ChatRequest.Message("user", lastBotReply)); // 模拟用户的提问
+
+ ChatRequest request = new ChatRequest(messages);
+ request.setModel("gpt-3.5-turbo");
+ request.setMaxTokens(60); // 增加 token 数以生成多个问题
+ request.setTemperature(0.9); // 较高温度以增加多样性
+
+ service.postMessage(request).enqueue(new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ if (response.isSuccessful() && response.body() != null) {
+ ChatResponse chatResponse = response.body();
+ List questions = extractQuestions(chatResponse);
+ runOnUiThread(() -> displayQuestions(questions));
+ } else {
+ try {
+ String errorBody = response.errorBody() != null ? response.errorBody().string() : "Unknown error";
+ Log.e("ChatGPT", "Error: " + errorBody);
+ } catch (IOException e) {
+ Log.e("ChatGPT", "Error reading error body", e);
+ }
+ }
+ }
+
@Override
public void onFailure(Call call, Throwable t) {
Log.e("ChatGPT", "Failure: " + t.getMessage());
@@ -233,5 +474,88 @@ public class ChatWithGptActivity extends AppCompatActivity {
});
}
+ // 提取问题
+ private List extractQuestions(ChatResponse response) {
+ GenerateQue_bmob generateQue_bmob = new GenerateQue_bmob();
+ generateQue_bmob.setQues1("请告诉我更多。");
+ generateQue_bmob.setUserid(userid);
+ generateQue_bmob.setRelatedBook(bookName);
+ List questions = new ArrayList<>();
+ if (response.getChoices() != null && !response.getChoices().isEmpty()) {
+ String text = response.choices.get(0).message.content;
+ if (text != null && !text.trim().isEmpty()) {
+ Log.d("ChatGPT Response:", text);
+ String[] lines = text.trim().split("\\r?\\n");
+ int questionIndex = 2; // Start from ques2 since ques1 is set by default
+
+ for (String line : lines) {
+ if (line.matches("^\\d+\\.\\s+.*")) {
+ String cleanedLine = line.replaceFirst("^\\d+\\.\\s*", "");
+ if (!cleanedLine.trim().isEmpty()) {
+ questions.add(cleanedLine);
+ // Set questions to Bmob object based on availability
+ if (questionIndex == 2) {
+ generateQue_bmob.setQues2(cleanedLine);
+ questionIndex++;
+ } else if (questionIndex == 3) {
+ generateQue_bmob.setQues3(cleanedLine);
+ questionIndex++;
+ }
+ }
+ }
+ }
+ }
+ }
+ BmobQuery bmobQuery = new BmobQuery<>();
+ bmobQuery.addWhereEqualTo("relatedBook", bookName);
+ bmobQuery.addWhereEqualTo("userid", userid);
+ bmobQuery.findObjects(new FindListener() {
+ @Override
+ public void done(List list, BmobException e) {
+ if (e == null && !list.isEmpty()) {
+ generateQue_bmob.update(list.get(0).getObjectId(), new UpdateListener() {
+ @Override
+ public void done(BmobException e) {
+ if (e == null) {
+ //toast("更新成功:"+p2.getUpdatedAt());
+ } else {
+ //toast("更新失败:" + e.getMessage());
+ }
+ }
+ });
+ } else {
+ // Save the Bmob object to database
+ generateQue_bmob.save(new SaveListener() {
+ @Override
+ public void done(String objectId, BmobException e) {
+ if (e == null) {
+ Log.d("Save Successful", "Object saved with objectId: " + objectId);
+ } else {
+ Log.e("Save Failed", "Error saving object: " + e.getMessage());
+ }
+ }
+ });
+ }
+ }
+ });
+ return questions;
+ }
+
+
+ // 将问题显示在 UI 上的逻辑
+ private void displayQuestions(List questions) {
+ questionView1.setText("请告诉我更多内容。");
+ questionView1.setVisibility(View.VISIBLE);
+
+ // Display questions based on size
+ if (questions.size() > 0) {
+ questionView2.setText(questions.get(0));
+ questionView2.setVisibility(View.VISIBLE);
+ }
+ if (questions.size() > 1) {
+ questionView3.setText(questions.get(1));
+ questionView3.setVisibility(View.VISIBLE);
+ }
+ }
}
diff --git a/hwtxtreaderlib/src/main/res/drawable/ic_loading.png b/hwtxtreaderlib/src/main/res/drawable/ic_loading.png
new file mode 100644
index 0000000..c606f94
Binary files /dev/null and b/hwtxtreaderlib/src/main/res/drawable/ic_loading.png differ
diff --git a/hwtxtreaderlib/src/main/res/drawable/ic_return.png b/hwtxtreaderlib/src/main/res/drawable/ic_return.png
new file mode 100644
index 0000000..04afdbd
Binary files /dev/null and b/hwtxtreaderlib/src/main/res/drawable/ic_return.png differ
diff --git a/hwtxtreaderlib/src/main/res/drawable/ic_send.png b/hwtxtreaderlib/src/main/res/drawable/ic_send.png
new file mode 100644
index 0000000..533e7c3
Binary files /dev/null and b/hwtxtreaderlib/src/main/res/drawable/ic_send.png differ
diff --git a/hwtxtreaderlib/src/main/res/drawable/rounded_question_background.xml b/hwtxtreaderlib/src/main/res/drawable/rounded_question_background.xml
new file mode 100644
index 0000000..5daee35
--- /dev/null
+++ b/hwtxtreaderlib/src/main/res/drawable/rounded_question_background.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
diff --git a/hwtxtreaderlib/src/main/res/layout/activity_chatwithgpt.xml b/hwtxtreaderlib/src/main/res/layout/activity_chatwithgpt.xml
index 4ff46d3..bf5d540 100644
--- a/hwtxtreaderlib/src/main/res/layout/activity_chatwithgpt.xml
+++ b/hwtxtreaderlib/src/main/res/layout/activity_chatwithgpt.xml
@@ -1,4 +1,3 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+ android:text="书名"
+ android:textSize="22sp"
+ android:gravity="center"
+ app:layout_constraintStart_toEndOf="@id/chat_return"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toTopOf="parent" />
+ app:layout_constraintRight_toLeftOf="@id/sendButton" />
-
-
-
+ app:layout_constraintRight_toRightOf="parent">
diff --git a/hwtxtreaderlib/src/main/res/layout/item_message_bot.xml b/hwtxtreaderlib/src/main/res/layout/item_message_bot.xml
index ea6377d..72e5ac9 100644
--- a/hwtxtreaderlib/src/main/res/layout/item_message_bot.xml
+++ b/hwtxtreaderlib/src/main/res/layout/item_message_bot.xml
@@ -29,7 +29,6 @@
android:src="@drawable/ic_copy"
android:layout_marginLeft="5dp"
android:alpha="0.6"
- android:visibility="gone"
android:contentDescription="Copy text" />
\ No newline at end of file