From f4c9a429749ec5a7013d48b49f1ddd32722508e4 Mon Sep 17 00:00:00 2001
From: xiao12feng8 <16507319+xiao12feng8@user.noreply.gitee.com>
Date: Thu, 25 Dec 2025 19:02:07 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/main/resources/application-dev.yml | 10 ++
Zhibo/zhibo-h/crmeb-common/pom.xml | 6 +
.../zbkj/common/model/chat/Conversation.java | 18 +++
.../common/model/chat/PrivateMessage.java | 21 ++++
.../zbkj/common/model/coupon/StoreCoupon.java | 1 +
.../com/zbkj/front/CrmebFrontApplication.java | 4 +
.../src/main/resources/application.yml | 13 ++
Zhibo/zhibo-h/pom.xml | 7 ++
.../livestreaming/ConversationActivity.java | 117 +++++++++++++++++-
.../ConversationMessagesAdapter.java | 6 +-
.../example/livestreaming/LoginActivity.java | 103 ++-------------
.../example/livestreaming/net/AuthStore.java | 11 +-
12 files changed, 217 insertions(+), 100 deletions(-)
diff --git a/Zhibo/zhibo-h/crmeb-admin/src/main/resources/application-dev.yml b/Zhibo/zhibo-h/crmeb-admin/src/main/resources/application-dev.yml
index 132ef696..70994c76 100644
--- a/Zhibo/zhibo-h/crmeb-admin/src/main/resources/application-dev.yml
+++ b/Zhibo/zhibo-h/crmeb-admin/src/main/resources/application-dev.yml
@@ -29,6 +29,16 @@ spring:
url: jdbc:mysql://1.15.149.240:3306/zhibo?characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=GMT%2B8
username: zhibo
password: zCETFpGMwYN3CNeH
+ # JPA 配置 - 只新增字段,不删除已有字段
+ jpa:
+ hibernate:
+ ddl-auto: update # update: 只新增表/字段,不删除
+ show-sql: false
+ open-in-view: false
+ properties:
+ hibernate:
+ dialect: org.hibernate.dialect.MySQL5InnoDBDialect
+ physical_naming_strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
redis:
host: 127.0.0.1 #地址
port: 6379 #端口
diff --git a/Zhibo/zhibo-h/crmeb-common/pom.xml b/Zhibo/zhibo-h/crmeb-common/pom.xml
index bb1eef62..d2016853 100644
--- a/Zhibo/zhibo-h/crmeb-common/pom.xml
+++ b/Zhibo/zhibo-h/crmeb-common/pom.xml
@@ -79,6 +79,12 @@
mybatis-plus-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
org.springframework.boot
diff --git a/Zhibo/zhibo-h/crmeb-common/src/main/java/com/zbkj/common/model/chat/Conversation.java b/Zhibo/zhibo-h/crmeb-common/src/main/java/com/zbkj/common/model/chat/Conversation.java
index 7d6aee5c..6588b67f 100644
--- a/Zhibo/zhibo-h/crmeb-common/src/main/java/com/zbkj/common/model/chat/Conversation.java
+++ b/Zhibo/zhibo-h/crmeb-common/src/main/java/com/zbkj/common/model/chat/Conversation.java
@@ -9,16 +9,20 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
+import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
/**
* 私聊会话实体类
+ * 同时支持 MyBatis-Plus 和 JPA
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("eb_conversation")
+@Entity
+@Table(name = "eb_conversation")
@ApiModel(value = "Conversation对象", description = "私聊会话")
public class Conversation implements Serializable {
@@ -26,41 +30,55 @@ public class Conversation implements Serializable {
@ApiModelProperty(value = "会话ID")
@TableId(value = "id", type = IdType.AUTO)
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ApiModelProperty(value = "用户1的ID")
+ @Column(name = "user1_id", nullable = false)
private Integer user1Id;
@ApiModelProperty(value = "用户2的ID")
+ @Column(name = "user2_id", nullable = false)
private Integer user2Id;
@ApiModelProperty(value = "最后一条消息内容")
+ @Column(name = "last_message", length = 500)
private String lastMessage;
@ApiModelProperty(value = "最后一条消息时间")
+ @Column(name = "last_message_time")
private Date lastMessageTime;
@ApiModelProperty(value = "用户1的未读数量")
+ @Column(name = "user1_unread_count", columnDefinition = "INT DEFAULT 0")
private Integer user1UnreadCount;
@ApiModelProperty(value = "用户2的未读数量")
+ @Column(name = "user2_unread_count", columnDefinition = "INT DEFAULT 0")
private Integer user2UnreadCount;
@ApiModelProperty(value = "用户1是否删除会话")
+ @Column(name = "user1_deleted", columnDefinition = "TINYINT(1) DEFAULT 0")
private Boolean user1Deleted;
@ApiModelProperty(value = "用户2是否删除会话")
+ @Column(name = "user2_deleted", columnDefinition = "TINYINT(1) DEFAULT 0")
private Boolean user2Deleted;
@ApiModelProperty(value = "用户1是否静音")
+ @Column(name = "user1_muted", columnDefinition = "TINYINT(1) DEFAULT 0")
private Boolean user1Muted;
@ApiModelProperty(value = "用户2是否静音")
+ @Column(name = "user2_muted", columnDefinition = "TINYINT(1) DEFAULT 0")
private Boolean user2Muted;
@ApiModelProperty(value = "创建时间")
+ @Column(name = "create_time")
private Date createTime;
@ApiModelProperty(value = "更新时间")
+ @Column(name = "update_time")
private Date updateTime;
}
diff --git a/Zhibo/zhibo-h/crmeb-common/src/main/java/com/zbkj/common/model/chat/PrivateMessage.java b/Zhibo/zhibo-h/crmeb-common/src/main/java/com/zbkj/common/model/chat/PrivateMessage.java
index 8fc18ab7..758dbc6f 100644
--- a/Zhibo/zhibo-h/crmeb-common/src/main/java/com/zbkj/common/model/chat/PrivateMessage.java
+++ b/Zhibo/zhibo-h/crmeb-common/src/main/java/com/zbkj/common/model/chat/PrivateMessage.java
@@ -9,16 +9,25 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
+import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
/**
* 私信消息实体类
+ * 同时支持 MyBatis-Plus 和 JPA
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("eb_private_message")
+@Entity
+@Table(name = "eb_private_message", indexes = {
+ @Index(name = "idx_conversation_id", columnList = "conversation_id"),
+ @Index(name = "idx_sender_id", columnList = "sender_id"),
+ @Index(name = "idx_receiver_id", columnList = "receiver_id"),
+ @Index(name = "idx_create_time", columnList = "create_time")
+})
@ApiModel(value = "PrivateMessage对象", description = "私信消息")
public class PrivateMessage implements Serializable {
@@ -26,35 +35,47 @@ public class PrivateMessage implements Serializable {
@ApiModelProperty(value = "消息ID")
@TableId(value = "id", type = IdType.AUTO)
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ApiModelProperty(value = "会话ID")
+ @Column(name = "conversation_id", nullable = false)
private Long conversationId;
@ApiModelProperty(value = "发送者用户ID")
+ @Column(name = "sender_id", nullable = false)
private Integer senderId;
@ApiModelProperty(value = "接收者用户ID")
+ @Column(name = "receiver_id", nullable = false)
private Integer receiverId;
@ApiModelProperty(value = "消息内容")
+ @Column(name = "content", columnDefinition = "TEXT")
private String content;
@ApiModelProperty(value = "消息类型: text, image, file")
+ @Column(name = "message_type", length = 20, columnDefinition = "VARCHAR(20) DEFAULT 'text'")
private String messageType;
@ApiModelProperty(value = "消息状态: sending, sent, read")
+ @Column(name = "status", length = 20, columnDefinition = "VARCHAR(20) DEFAULT 'sent'")
private String status;
@ApiModelProperty(value = "是否已删除(发送者)")
+ @Column(name = "sender_deleted", columnDefinition = "TINYINT(1) DEFAULT 0")
private Boolean senderDeleted;
@ApiModelProperty(value = "是否已删除(接收者)")
+ @Column(name = "receiver_deleted", columnDefinition = "TINYINT(1) DEFAULT 0")
private Boolean receiverDeleted;
@ApiModelProperty(value = "创建时间")
+ @Column(name = "create_time")
private Date createTime;
@ApiModelProperty(value = "已读时间")
+ @Column(name = "read_time")
private Date readTime;
}
diff --git a/Zhibo/zhibo-h/crmeb-common/src/main/java/com/zbkj/common/model/coupon/StoreCoupon.java b/Zhibo/zhibo-h/crmeb-common/src/main/java/com/zbkj/common/model/coupon/StoreCoupon.java
index ecc4bb8e..ab514f58 100644
--- a/Zhibo/zhibo-h/crmeb-common/src/main/java/com/zbkj/common/model/coupon/StoreCoupon.java
+++ b/Zhibo/zhibo-h/crmeb-common/src/main/java/com/zbkj/common/model/coupon/StoreCoupon.java
@@ -39,6 +39,7 @@ public class StoreCoupon implements Serializable {
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
+
@ApiModelProperty(value = "优惠券名称")
private String name;
diff --git a/Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/CrmebFrontApplication.java b/Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/CrmebFrontApplication.java
index f2e8a69a..902205b6 100644
--- a/Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/CrmebFrontApplication.java
+++ b/Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/CrmebFrontApplication.java
@@ -4,8 +4,10 @@ import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@@ -31,6 +33,8 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class) //去掉数据源
@ComponentScan(basePackages = {"com.zbkj", "com.zbkj.front"})
@MapperScan(basePackages = {"com.zbkj.**.dao"})
+@EntityScan(basePackages = {"com.zbkj.common.model"}) // JPA实体扫描
+@EnableJpaRepositories(basePackages = {"com.zbkj.service.repository"}) // JPA仓库扫描(可选)
public class CrmebFrontApplication {
public static void main(String[] args) {
SpringApplication.run(CrmebFrontApplication.class, args);
diff --git a/Zhibo/zhibo-h/crmeb-front/src/main/resources/application.yml b/Zhibo/zhibo-h/crmeb-front/src/main/resources/application.yml
index 094358aa..d41cbc6d 100644
--- a/Zhibo/zhibo-h/crmeb-front/src/main/resources/application.yml
+++ b/Zhibo/zhibo-h/crmeb-front/src/main/resources/application.yml
@@ -51,6 +51,19 @@ spring:
url: jdbc:mysql://1.15.149.240:3306/zhibo?characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=GMT%2B8
username: zhibo
password: zCETFpGMwYN3CNeH
+ # JPA 配置 - 只新增字段,不删除已有字段
+ jpa:
+ hibernate:
+ ddl-auto: update # update: 只新增表/字段,不删除;none: 不做任何操作
+ show-sql: false # 生产环境建议关闭
+ open-in-view: false # 关闭懒加载视图
+ properties:
+ hibernate:
+ format_sql: true
+ dialect: org.hibernate.dialect.MySQL5InnoDBDialect
+ # 命名策略:将驼峰转为下划线
+ physical_naming_strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
+ implicit_naming_strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
redis:
host: 127.0.0.1 #地址
port: 6379 #端口
diff --git a/Zhibo/zhibo-h/pom.xml b/Zhibo/zhibo-h/pom.xml
index 7bb7b86b..0a64429d 100644
--- a/Zhibo/zhibo-h/pom.xml
+++ b/Zhibo/zhibo-h/pom.xml
@@ -100,6 +100,13 @@
3.3.1
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+ 2.2.6.RELEASE
+
+
com.baomidou
diff --git a/android-app/app/src/main/java/com/example/livestreaming/ConversationActivity.java b/android-app/app/src/main/java/com/example/livestreaming/ConversationActivity.java
index 47ba27dc..9db18dc2 100644
--- a/android-app/app/src/main/java/com/example/livestreaming/ConversationActivity.java
+++ b/android-app/app/src/main/java/com/example/livestreaming/ConversationActivity.java
@@ -45,6 +45,7 @@ public class ConversationActivity extends AppCompatActivity {
private static final String EXTRA_CONVERSATION_TITLE = "extra_conversation_title";
private static final String EXTRA_UNREAD_COUNT = "extra_unread_count";
private static final int PAGE_SIZE = 20;
+ private static final long POLL_INTERVAL = 3000; // 3秒轮询一次
private ActivityConversationBinding binding;
private final OkHttpClient httpClient = new OkHttpClient();
@@ -52,6 +53,8 @@ public class ConversationActivity extends AppCompatActivity {
private ConversationMessagesAdapter adapter;
private final List messages = new ArrayList<>();
private Handler handler;
+ private Runnable pollRunnable;
+ private boolean isPolling = false;
private String conversationId;
private int currentPage = 1;
@@ -78,7 +81,15 @@ public class ConversationActivity extends AppCompatActivity {
conversationId = getIntent() != null ? getIntent().getStringExtra(EXTRA_CONVERSATION_ID) : null;
initialUnreadCount = getIntent() != null ? getIntent().getIntExtra(EXTRA_UNREAD_COUNT, 0) : 0;
+
+ // 先尝试从 AuthStore 获取 userId
currentUserId = AuthStore.getUserId(this);
+ Log.d(TAG, "从AuthStore获取的用户ID: " + currentUserId);
+
+ // 如果 userId 为空,尝试从用户信息接口获取
+ if (currentUserId == null || currentUserId.isEmpty()) {
+ fetchCurrentUserId();
+ }
binding.backButton.setOnClickListener(new DebounceClickListener() {
@Override
@@ -99,6 +110,42 @@ public class ConversationActivity extends AppCompatActivity {
@Override
protected void onPause() {
super.onPause();
+ stopPolling();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ startPolling();
+ }
+
+ /**
+ * 开始轮询新消息
+ */
+ private void startPolling() {
+ if (isPolling) return;
+ isPolling = true;
+
+ pollRunnable = new Runnable() {
+ @Override
+ public void run() {
+ if (!isPolling || isFinishing() || isDestroyed()) return;
+ loadMessagesFromServer();
+ handler.postDelayed(this, POLL_INTERVAL);
+ }
+ };
+ // 延迟开始轮询,避免和初始加载冲突
+ handler.postDelayed(pollRunnable, POLL_INTERVAL);
+ }
+
+ /**
+ * 停止轮询
+ */
+ private void stopPolling() {
+ isPolling = false;
+ if (pollRunnable != null && handler != null) {
+ handler.removeCallbacks(pollRunnable);
+ }
}
private void setupMessages() {
@@ -116,6 +163,58 @@ public class ConversationActivity extends AppCompatActivity {
}
+ /**
+ * 从服务器获取当前用户ID
+ */
+ private void fetchCurrentUserId() {
+ String token = AuthStore.getToken(this);
+ if (token == null) {
+ Log.w(TAG, "未登录,无法获取用户ID");
+ return;
+ }
+
+ String url = ApiConfig.getBaseUrl() + "/api/front/user/info";
+ Log.d(TAG, "获取用户信息: " + url);
+
+ Request request = new Request.Builder()
+ .url(url)
+ .addHeader("Authori-zation", token)
+ .get()
+ .build();
+
+ httpClient.newCall(request).enqueue(new Callback() {
+ @Override
+ public void onFailure(Call call, IOException e) {
+ Log.e(TAG, "获取用户信息失败", e);
+ }
+
+ @Override
+ public void onResponse(Call call, Response response) throws IOException {
+ String body = response.body() != null ? response.body().string() : "";
+ Log.d(TAG, "用户信息响应: " + body);
+ try {
+ JSONObject json = new JSONObject(body);
+ if (json.optInt("code", -1) == 200) {
+ JSONObject data = json.optJSONObject("data");
+ if (data != null) {
+ int uid = data.optInt("uid", 0);
+ if (uid > 0) {
+ currentUserId = String.valueOf(uid);
+ // 保存到 AuthStore
+ AuthStore.setUserInfo(ConversationActivity.this, currentUserId, data.optString("nickname", ""));
+ Log.d(TAG, "从服务器获取到用户ID: " + currentUserId);
+ // 重新加载消息以正确显示
+ runOnUiThread(() -> loadMessagesFromServer());
+ }
+ }
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "解析用户信息失败", e);
+ }
+ }
+ });
+ }
+
/**
* 从服务器加载消息列表
*/
@@ -182,7 +281,7 @@ public class ConversationActivity extends AppCompatActivity {
private ChatMessage parseChatMessage(JSONObject item) {
try {
String messageId = item.optString("messageId", "");
- int userId = item.optInt("userId", 0);
+ int senderId = item.optInt("userId", 0); // 后端返回的 userId 实际是 senderId
String username = item.optString("username", "未知用户");
String message = item.optString("message", "");
long timestamp = item.optLong("timestamp", System.currentTimeMillis());
@@ -191,7 +290,20 @@ public class ConversationActivity extends AppCompatActivity {
boolean isSystem = item.optBoolean("isSystemMessage", false);
// 判断是否是自己发送的消息
- boolean isMine = currentUserId != null && currentUserId.equals(String.valueOf(userId));
+ // 每次都重新从 AuthStore 获取最新的 userId,确保登录后能正确获取
+ String myUserId = AuthStore.getUserId(this);
+ if (myUserId == null || myUserId.isEmpty()) {
+ myUserId = currentUserId;
+ } else {
+ currentUserId = myUserId; // 同步更新
+ }
+
+ boolean isMine = false;
+ if (myUserId != null && !myUserId.isEmpty() && senderId > 0) {
+ isMine = myUserId.equals(String.valueOf(senderId));
+ }
+ Log.d(TAG, "消息判断: myUserId=" + myUserId + ", senderId=" + senderId + ", isMine=" + isMine);
+
String displayName = isMine ? "我" : username;
ChatMessage.MessageStatus msgStatus;
@@ -457,6 +569,7 @@ public class ConversationActivity extends AppCompatActivity {
@Override
protected void onDestroy() {
super.onDestroy();
+ stopPolling();
handler = null;
}
}
diff --git a/android-app/app/src/main/java/com/example/livestreaming/ConversationMessagesAdapter.java b/android-app/app/src/main/java/com/example/livestreaming/ConversationMessagesAdapter.java
index b6711049..22255597 100644
--- a/android-app/app/src/main/java/com/example/livestreaming/ConversationMessagesAdapter.java
+++ b/android-app/app/src/main/java/com/example/livestreaming/ConversationMessagesAdapter.java
@@ -300,17 +300,17 @@ public class ConversationMessagesAdapter extends ListAdapter {
- handleDemoModeLogin(account);
- }, 500); // 延迟500ms,模拟网络请求
-
- // 以下代码在测试模式下被注释,接入后端后可以恢复
- /*
- // TODO: 接入后端接口 - 用户登录
- // 接口路径: POST /api/front/login(ApiService中已定义)
- // 请求参数: LoginRequest {account: string, password: string}
- // 返回数据格式: ApiResponse
- // LoginResponse对象应包含: token, userId, nickname, avatarUrl等字段
- // 登录成功后,保存token到AuthStore,并更新用户信息到本地SharedPreferences
+ // 调用后端登录接口
ApiClient.getService(getApplicationContext()).login(new LoginRequest(account, password))
.enqueue(new Callback>() {
@Override
@@ -128,15 +112,8 @@ public class LoginActivity extends AppCompatActivity {
ApiResponse body = response.body();
LoginResponse loginData = body != null ? body.getData() : null;
- // 如果响应不成功或数据无效,检查是否是后端未接入的情况
+ // 如果响应不成功或数据无效
if (!response.isSuccessful() || body == null || !body.isOk() || loginData == null) {
- // 如果是404、500等错误,可能是后端未接入,使用演示模式
- if (!response.isSuccessful() && (response.code() == 404 || response.code() == 500 || response.code() == 502 || response.code() == 503)) {
- // 后端服务未启动或未接入,使用演示模式
- handleDemoModeLogin(account);
- return;
- }
-
String errorMsg = "登录失败";
if (body != null && !TextUtils.isEmpty(body.getMessage())) {
errorMsg = body.getMessage();
@@ -158,9 +135,10 @@ public class LoginActivity extends AppCompatActivity {
}
// 保存用户信息到 AuthStore
- AuthStore.setUserInfo(getApplicationContext(),
- loginData.getUid(),
- loginData.getNikeName());
+ String uid = loginData.getUid();
+ String nickname = loginData.getNikeName();
+ android.util.Log.d("LoginActivity", "登录返回的 uid: " + uid + ", nickname: " + nickname);
+ AuthStore.setUserInfo(getApplicationContext(), uid, nickname);
// 保存用户信息到本地 SharedPreferences
SharedPreferences prefs = getSharedPreferences("profile_prefs", MODE_PRIVATE);
@@ -171,8 +149,7 @@ public class LoginActivity extends AppCompatActivity {
prefs.edit().putString("profile_phone", loginData.getPhone()).apply();
}
- // 登录成功,返回上一页(如果是从其他页面跳转过来的)
- // 如果是直接打开登录页面,则跳转到主页面
+ // 登录成功
Toast.makeText(LoginActivity.this, "登录成功", Toast.LENGTH_SHORT).show();
// 检查是否有上一个Activity
@@ -194,74 +171,14 @@ public class LoginActivity extends AppCompatActivity {
binding.loginButton.setEnabled(true);
binding.loadingProgress.setVisibility(View.GONE);
- // 检测是否是网络连接错误(后端未启动)
- boolean isNetworkError = false;
String errorMsg = "网络错误";
- if (t != null) {
- String msg = t.getMessage();
- if (msg != null) {
- if (msg.contains("Unable to resolve host") ||
- msg.contains("timeout") ||
- msg.contains("Connection refused") ||
- msg.contains("Failed to connect")) {
- isNetworkError = true;
- errorMsg = "无法连接到服务器,已切换到演示模式";
- } else {
- errorMsg = "网络错误:" + msg;
- }
- }
- }
-
- // 如果是网络连接错误(后端未接入),使用演示模式登录
- if (isNetworkError) {
- handleDemoModeLogin(account);
- } else {
- Toast.makeText(LoginActivity.this, errorMsg, Toast.LENGTH_LONG).show();
+ if (t != null && t.getMessage() != null) {
+ errorMsg = "网络错误:" + t.getMessage();
}
+ Toast.makeText(LoginActivity.this, errorMsg, Toast.LENGTH_LONG).show();
}
});
- */
}
- /**
- * 处理演示模式登录(测试模式:直接登录成功)
- */
- private void handleDemoModeLogin(String account) {
- // 恢复UI状态
- isLoggingIn = false;
- binding.loginButton.setEnabled(true);
- binding.loadingProgress.setVisibility(View.GONE);
-
- // 测试模式:允许任意账号密码登录(仅用于开发测试)
- // 生成一个演示token(基于账号)
- String demoToken = "demo_token_" + account.hashCode();
- android.util.Log.d("LoginActivity", "演示模式 - 生成 token: " + demoToken);
- AuthStore.setToken(getApplicationContext(), demoToken);
-
- // 保存用户信息到本地
- SharedPreferences prefs = getSharedPreferences("profile_prefs", MODE_PRIVATE);
- String displayName = account.length() > 0 ? account : "演示用户";
- prefs.edit()
- .putString("profile_name", displayName)
- .putString("user_id", "demo_user_" + account.hashCode())
- .apply();
-
- // 登录成功提示
- Toast.makeText(this, "登录成功", Toast.LENGTH_SHORT).show();
-
- // 登录成功,返回上一页(如果是从其他页面跳转过来的)
- // 如果是直接打开登录页面,则跳转到主页面
- // 检查是否有上一个Activity
- if (isTaskRoot()) {
- // 如果没有上一个Activity,跳转到主页面
- Intent intent = new Intent(this, MainActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
- startActivity(intent);
- finish();
- } else {
- // 有上一个Activity,直接返回
- finish();
- }
- }
}
diff --git a/android-app/app/src/main/java/com/example/livestreaming/net/AuthStore.java b/android-app/app/src/main/java/com/example/livestreaming/net/AuthStore.java
index 4cbff908..cbc551d0 100644
--- a/android-app/app/src/main/java/com/example/livestreaming/net/AuthStore.java
+++ b/android-app/app/src/main/java/com/example/livestreaming/net/AuthStore.java
@@ -51,6 +51,7 @@ public final class AuthStore {
public static void setUserInfo(Context context, @Nullable String userId, @Nullable String nickname) {
if (context == null) return;
+ Log.d(TAG, "setUserInfo: userId=" + userId + ", nickname=" + nickname);
context.getSharedPreferences(PREFS, Context.MODE_PRIVATE)
.edit()
.putString(KEY_USER_ID, userId)
@@ -61,8 +62,14 @@ public final class AuthStore {
@Nullable
public static String getUserId(Context context) {
if (context == null) return null;
- return context.getSharedPreferences(PREFS, Context.MODE_PRIVATE)
- .getString(KEY_USER_ID, "");
+ String userId = context.getSharedPreferences(PREFS, Context.MODE_PRIVATE)
+ .getString(KEY_USER_ID, null);
+ // 确保空字符串也返回 null
+ if (userId != null && userId.trim().isEmpty()) {
+ userId = null;
+ }
+ Log.d(TAG, "getUserId: " + userId);
+ return userId;
}
@Nullable