diff --git a/src/Notes-master/src/net/micode/notes/data/Notes.java b/src/Notes-master/src/net/micode/notes/data/Notes.java index 0ee1e98..1a7d510 100644 --- a/src/Notes-master/src/net/micode/notes/data/Notes.java +++ b/src/Notes-master/src/net/micode/notes/data/Notes.java @@ -201,6 +201,61 @@ public class Notes { * Type: TEXT */ public static final String EXPAND_1 = "expand_1"; + + /** + * 新增:同步状态 (0:已同步, 1:待同步/脏数据, 2:待删除) + * Type: INTEGER + */ + public static final String SYNC_STATE = "sync_state"; + + /** + * 新增:云端唯一ID (Firebase Document ID) + * Type: TEXT + */ + public static final String SERVER_ID = "server_id"; + + /** + * 新增:是否为日程 (0:普通便签, 1:日程) + * Type: INTEGER + */ + public static final String IS_AGENDA = "is_agenda"; + + /** + * 新增:日程时间戳 (毫秒) + * Type: INTEGER + */ + public static final String AGENDA_DATE = "agenda_date"; + + /** + * 新增:日程是否已完成 (0:未完成, 1:已完成) + * Type: INTEGER + */ + public static final String IS_COMPLETED = "is_completed"; + + /** + * 新增:AI 分析的情绪标签 (Happy, Sad, Urgent...) + * Type: TEXT + */ + public static final String EMOTION_TAG = "emotion_tag"; + } + + // [新增] 用户账号表列名定义 + public interface AccountColumns { + public static final String UID = "uid"; // Firebase UID + public static final String EMAIL = "email"; + public static final String TOKEN = "token"; // Sync Token + public static final String AVATAR_URL = "avatar_url"; + } + + // [新增] 聊天消息表列名定义 + public interface ChatColumns { + public static final String ID = "_id"; + public static final String SESSION_ID = "session_id"; + public static final String SENDER_TYPE = "sender_type"; // 0: User, 1: AI + public static final String CONTENT = "content"; + public static final String MSG_TYPE = "msg_type"; // 0: Text, 1: Agenda Card + public static final String CREATED_AT = "created_at"; + public static final String SYNC_STATE = "sync_state"; } public interface DataColumns { diff --git a/src/Notes-master/src/net/micode/notes/data/NotesDatabaseHelper.java b/src/Notes-master/src/net/micode/notes/data/NotesDatabaseHelper.java index 95b8200..4a6799a 100644 --- a/src/Notes-master/src/net/micode/notes/data/NotesDatabaseHelper.java +++ b/src/Notes-master/src/net/micode/notes/data/NotesDatabaseHelper.java @@ -30,12 +30,14 @@ import net.micode.notes.data.Notes.NoteColumns; public class NotesDatabaseHelper extends SQLiteOpenHelper { private static final String DB_NAME = "note.db"; - private static final int DB_VERSION = 6; + private static final int DB_VERSION = 9; public interface TABLE { public static final String NOTE = "note"; - public static final String DATA = "data"; + // [新增] + public static final String USER_ACCOUNT = "user_account"; + public static final String CHAT_MESSAGES = "chat_messages"; } private static final String TAG = "NotesDatabaseHelper"; @@ -67,8 +69,36 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { NoteColumns.VIEW_MODE + " INTEGER NOT NULL DEFAULT 0," + NoteColumns.CUSTOM_BG_URI + " TEXT NOT NULL DEFAULT ''," + NoteColumns.EXPAND_1 + " TEXT NOT NULL DEFAULT ''" + + // [新增字段 v9] + NoteColumns.SYNC_STATE + " INTEGER DEFAULT 1," + + NoteColumns.SERVER_ID + " TEXT," + + NoteColumns.IS_AGENDA + " INTEGER DEFAULT 0," + + NoteColumns.AGENDA_DATE + " INTEGER DEFAULT 0," + + NoteColumns.IS_COMPLETED + " INTEGER DEFAULT 0," + + NoteColumns.EMOTION_TAG + " TEXT" + ")"; + // [新增] 用户表建表语句 + private static final String CREATE_USER_TABLE_SQL = + "CREATE TABLE " + TABLE.USER_ACCOUNT + "(" + + Notes.AccountColumns.UID + " TEXT PRIMARY KEY," + + Notes.AccountColumns.EMAIL + " TEXT," + + Notes.AccountColumns.TOKEN + " TEXT," + + Notes.AccountColumns.AVATAR_URL + " TEXT" + + ")"; + + // [新增] 聊天消息表建表语句 + private static final String CREATE_CHAT_TABLE_SQL = + "CREATE TABLE " + TABLE.CHAT_MESSAGES + "(" + + Notes.ChatColumns.ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + + Notes.ChatColumns.SESSION_ID + " TEXT," + + Notes.ChatColumns.SENDER_TYPE + " INTEGER DEFAULT 0," + + Notes.ChatColumns.CONTENT + " TEXT," + + Notes.ChatColumns.MSG_TYPE + " INTEGER DEFAULT 0," + + Notes.ChatColumns.CREATED_AT + " INTEGER," + + Notes.ChatColumns.SYNC_STATE + " INTEGER DEFAULT 1" + + ")"; + private static final String CREATE_DATA_TABLE_SQL = "CREATE TABLE " + TABLE.DATA + "(" + DataColumns.ID + " INTEGER PRIMARY KEY," + @@ -304,6 +334,9 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { public void onCreate(SQLiteDatabase db) { createNoteTable(db); createDataTable(db); + // [新增] + db.execSQL(CREATE_USER_TABLE_SQL); + db.execSQL(CREATE_CHAT_TABLE_SQL); } @Override @@ -341,6 +374,12 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { oldVersion++; } + // [新增] 核心升级逻辑:从 v6 直接跳到 v9,或者逐步升级 + if (oldVersion < 9) { + upgradeToV9(db); + oldVersion = 9; + } + if (reCreateTriggers) { reCreateNoteTableTriggers(db); reCreateDataTableTriggers(db); @@ -396,4 +435,21 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.CUSTOM_BG_URI + " TEXT NOT NULL DEFAULT ''"); db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.EXPAND_1 + " TEXT NOT NULL DEFAULT ''"); } + + private void upgradeToV9(SQLiteDatabase db) { + Log.d(TAG, "Upgrading database to version 9..."); + + // 1. 为 NOTE 表增加新列 + // 使用 try-catch 包裹每个 ALTER 语句,防止部分列已存在的异常 + try { db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.SYNC_STATE + " INTEGER DEFAULT 1"); } catch(Exception e){} + try { db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.SERVER_ID + " TEXT"); } catch(Exception e){} + try { db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.IS_AGENDA + " INTEGER DEFAULT 0"); } catch(Exception e){} + try { db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.AGENDA_DATE + " INTEGER DEFAULT 0"); } catch(Exception e){} + try { db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.IS_COMPLETED + " INTEGER DEFAULT 0"); } catch(Exception e){} + try { db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.EMOTION_TAG + " TEXT"); } catch(Exception e){} + + // 2. 创建新表 + try { db.execSQL(CREATE_USER_TABLE_SQL); } catch(Exception e){ Log.e(TAG, "Create user table failed: " + e); } + try { db.execSQL(CREATE_CHAT_TABLE_SQL); } catch(Exception e){ Log.e(TAG, "Create chat table failed: " + e); } + } } diff --git a/src/Notes-master/src/net/micode/notes/data/NotesProvider.java b/src/Notes-master/src/net/micode/notes/data/NotesProvider.java index edb0a60..0db1b5b 100644 --- a/src/Notes-master/src/net/micode/notes/data/NotesProvider.java +++ b/src/Notes-master/src/net/micode/notes/data/NotesProvider.java @@ -49,6 +49,7 @@ public class NotesProvider extends ContentProvider { private static final int URI_SEARCH = 5; private static final int URI_SEARCH_SUGGEST = 6; + private static final int URI_USER_ACCOUNT = 7; // 新增编号 static { mMatcher = new UriMatcher(UriMatcher.NO_MATCH); @@ -59,6 +60,7 @@ public class NotesProvider extends ContentProvider { mMatcher.addURI(Notes.AUTHORITY, "search", URI_SEARCH); mMatcher.addURI(Notes.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, URI_SEARCH_SUGGEST); mMatcher.addURI(Notes.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", URI_SEARCH_SUGGEST); + mMatcher.addURI(Notes.AUTHORITY, "user_account", URI_USER_ACCOUNT); } /** @@ -163,6 +165,9 @@ public class NotesProvider extends ContentProvider { } insertedId = dataId = db.insert(TABLE.DATA, null, values); break; + case URI_USER_ACCOUNT: + insertedId = db.insert(TABLE.USER_ACCOUNT, null, values); + break; default: throw new IllegalArgumentException("Unknown URI " + uri); } diff --git a/src/Notes-master/src/net/micode/notes/ui/NotesListActivity.java b/src/Notes-master/src/net/micode/notes/ui/NotesListActivity.java index 6eab673..2958c6a 100644 --- a/src/Notes-master/src/net/micode/notes/ui/NotesListActivity.java +++ b/src/Notes-master/src/net/micode/notes/ui/NotesListActivity.java @@ -501,6 +501,7 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe mSwipeRefreshLayout.setRefreshing(false); } }); + dialog.show(); } @@ -580,8 +581,7 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe } @Override - public void getItemOffsets(Rect outRect, View view, androidx.recyclerview.widget.RecyclerView parent, - androidx.recyclerview.widget.RecyclerView.State state) { + public void getItemOffsets(Rect outRect, View view, androidx.recyclerview.widget.RecyclerView parent, androidx.recyclerview.widget.RecyclerView.State state) { // 获取当前条目的布局参数 androidx.recyclerview.widget.StaggeredGridLayoutManager.LayoutParams lp = (androidx.recyclerview.widget.StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams(); @@ -1381,6 +1381,17 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe enterRecycleBin(); break; } + case R.id.menu_account_logout: + // 1. Firebase 注销 + com.google.firebase.auth.FirebaseAuth.getInstance().signOut(); + // 2. 清除本地账号表记录 (可选,建议保留以便离线查看) + // getContentResolver().delete(...); + // 3. 强制跳转回登录页 + Intent logoutIntent = new Intent(this, LoginActivity.class); + logoutIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + startActivity(logoutIntent); + finish(); + break; default: break; }