diff --git a/Touchkebao/src/pages/pc/ckbox/data.ts b/Touchkebao/src/pages/pc/ckbox/data.ts index 037a4367..9b8aa285 100644 --- a/Touchkebao/src/pages/pc/ckbox/data.ts +++ b/Touchkebao/src/pages/pc/ckbox/data.ts @@ -146,7 +146,7 @@ export interface ContractData { labels: string[]; signature: string; accountId: number; - extendFields: null; + extendFields?: Record | null; city?: string; lastUpdateTime: string; isPassed: boolean; diff --git a/Touchkebao/src/pages/pc/ckbox/weChat/components/SidebarMenu/MessageList/data.ts b/Touchkebao/src/pages/pc/ckbox/weChat/components/SidebarMenu/MessageList/data.ts index 5aa5c726..bf431076 100644 --- a/Touchkebao/src/pages/pc/ckbox/weChat/components/SidebarMenu/MessageList/data.ts +++ b/Touchkebao/src/pages/pc/ckbox/weChat/components/SidebarMenu/MessageList/data.ts @@ -15,7 +15,7 @@ export interface ContractData { labels: string[]; signature: string; accountId: number; - extendFields: null; + extendFields?: Record | null; city?: string; lastUpdateTime: string; isPassed: boolean; diff --git a/Touchkebao/src/pages/pc/ckbox/weChat/components/SidebarMenu/WechatFriends/extend.ts b/Touchkebao/src/pages/pc/ckbox/weChat/components/SidebarMenu/WechatFriends/extend.ts index 220c4d56..cf2b8117 100644 --- a/Touchkebao/src/pages/pc/ckbox/weChat/components/SidebarMenu/WechatFriends/extend.ts +++ b/Touchkebao/src/pages/pc/ckbox/weChat/components/SidebarMenu/WechatFriends/extend.ts @@ -82,6 +82,20 @@ export const getAllGroups = async () => { } }; +const serializeExtendFields = (value: any) => { + if (typeof value === "string") { + return value.trim() ? value : "{}"; + } + if (value && typeof value === "object") { + try { + return JSON.stringify(value); + } catch (error) { + console.warn("序列化 extendFields 失败:", error); + } + } + return "{}"; +}; + /** * 将好友数据转换为统一的 Contact 格式 */ @@ -95,11 +109,21 @@ export const convertFriendsToContacts = ( id: friend.id, type: "friend" as const, wechatAccountId: friend.wechatAccountId, + wechatFriendId: friend.id, wechatId: friend.wechatId, nickname: friend.nickname || "", conRemark: friend.conRemark || "", avatar: friend.avatar || "", + alias: friend.alias || "", + gender: friend.gender, + aiType: friend.aiType ?? 0, + phone: friend.phone ?? "", + region: friend.region ?? "", + quanPin: friend.quanPin || "", + signature: friend.signature || "", + config: friend.config || {}, groupId: friend.groupId, // 保留标签ID + extendFields: serializeExtendFields(friend.extendFields), lastUpdateTime: new Date().toISOString(), sortKey: "", searchKey: "", @@ -120,10 +144,19 @@ export const convertGroupsToContacts = ( type: "group" as const, wechatAccountId: group.wechatAccountId, wechatId: group.chatroomId || "", + chatroomId: group.chatroomId || "", + chatroomOwner: group.chatroomOwner || "", nickname: group.nickname || "", conRemark: group.conRemark || "", avatar: group.chatroomAvatar || group.avatar || "", + selfDisplayName: group.selfDisplyName || "", + notice: group.notice || "", + aiType: group.aiType ?? 0, + phone: group.phone ?? "", + region: group.region ?? "", + config: group.config || {}, groupId: group.groupId, // 保留标签ID + extendFields: serializeExtendFields(group.extendFields), lastUpdateTime: new Date().toISOString(), sortKey: "", searchKey: "", diff --git a/Touchkebao/src/pages/pc/ckbox/weChat/data.ts b/Touchkebao/src/pages/pc/ckbox/weChat/data.ts index 7b0a7aca..d69fe801 100644 --- a/Touchkebao/src/pages/pc/ckbox/weChat/data.ts +++ b/Touchkebao/src/pages/pc/ckbox/weChat/data.ts @@ -144,7 +144,7 @@ export interface ContractData { labels: string[]; signature: string; accountId: number; - extendFields: null; + extendFields?: Record | null; city?: string; lastUpdateTime: string; isPassed: boolean; diff --git a/Touchkebao/src/store/module/weChat/contacts.data.ts b/Touchkebao/src/store/module/weChat/contacts.data.ts index 0ef039e1..c0769fd9 100644 --- a/Touchkebao/src/store/module/weChat/contacts.data.ts +++ b/Touchkebao/src/store/module/weChat/contacts.data.ts @@ -50,7 +50,7 @@ export interface ContractData { labels: string[]; signature: string; accountId: number; - extendFields: null; + extendFields?: Record | null; city?: string; lastUpdateTime: string; isPassed: boolean; diff --git a/Touchkebao/src/utils/db.ts b/Touchkebao/src/utils/db.ts index 836d9b46..69da02e2 100644 --- a/Touchkebao/src/utils/db.ts +++ b/Touchkebao/src/utils/db.ts @@ -62,6 +62,7 @@ export interface ChatSession { notice?: string; // 群公告 phone?: string; // 联系人电话 region?: string; // 联系人地区 + extendFields?: string; // 扩展字段(JSON 字符串) } // ==================== 统一联系人表(兼容好友和群聊) ==================== @@ -92,6 +93,7 @@ export interface Contact { signature?: string; // 个性签名 phone?: string; // 手机号 quanPin?: string; // 全拼 + extendFields?: string; // 扩展字段(JSON 字符串) // 群聊特有字段(type='group'时有效) chatroomId?: string; // 群聊ID @@ -147,6 +149,41 @@ class CunkebaoDatabase extends Dexie { userLoginRecords: "serverId, userId, lastLoginTime, loginCount, createTime, lastActiveTime", }); + + this.version(2) + .stores({ + chatSessions: + "serverId, userId, id, type, wechatAccountId, [userId+type], [userId+wechatAccountId], [userId+lastUpdateTime], [userId+aiType], sortKey, nickname, conRemark, avatar, content, lastUpdateTime, aiType, phone, region, extendFields", + contactsUnified: + "serverId, userId, id, type, wechatAccountId, [userId+type], [userId+wechatAccountId], [userId+aiType], sortKey, searchKey, nickname, conRemark, avatar, lastUpdateTime, groupId, aiType, phone, region, extendFields", + contactLabelMap: + "serverId, userId, labelId, contactId, contactType, [userId+labelId], [userId+contactId], [userId+labelId+sortKey], sortKey, searchKey, avatar, nickname, conRemark, unreadCount, lastUpdateTime", + userLoginRecords: + "serverId, userId, lastLoginTime, loginCount, createTime, lastActiveTime", + }) + .upgrade(async tx => { + await tx + .table("chatSessions") + .toCollection() + .modify(session => { + if (!("extendFields" in session) || session.extendFields == null) { + session.extendFields = "{}"; + } else if (typeof session.extendFields !== "string") { + session.extendFields = JSON.stringify(session.extendFields); + } + }); + + await tx + .table("contactsUnified") + .toCollection() + .modify(contact => { + if (!("extendFields" in contact) || contact.extendFields == null) { + contact.extendFields = "{}"; + } else if (typeof contact.extendFields !== "string") { + contact.extendFields = JSON.stringify(contact.extendFields); + } + }); + }); } } @@ -295,18 +332,18 @@ export class DatabaseService { // 基础 CRUD 操作 - 使用serverId作为主键 async create(data: Omit): Promise { - return await this.table.add(data as T); + return await this.table.add(this.prepareDataForWrite(data) as T); } // 创建数据(直接使用接口数据) // 接口数据的id字段直接作为serverId主键,原id字段保留 async createWithServerId(data: any): Promise { - const dataToInsert = { + const dataToInsert = this.prepareDataForWrite({ ...data, serverId: data.id, // 使用接口的id作为serverId主键 phone: data.phone ?? "", region: data.region ?? "", - }; + }); return await this.table.add(dataToInsert as T); } @@ -325,7 +362,10 @@ export class DatabaseService { } async update(serverId: string | number, data: Partial): Promise { - return await this.table.update(serverId, data as any); + return await this.table.update( + serverId, + this.prepareDataForWrite(data) as any, + ); } async updateMany( @@ -334,7 +374,7 @@ export class DatabaseService { return await this.table.bulkUpdate( dataList.map(item => ({ key: item.serverId, - changes: item.data as any, + changes: this.prepareDataForWrite(item.data) as any, })), ); } @@ -342,7 +382,8 @@ export class DatabaseService { async createMany( dataList: Omit[], ): Promise<(string | number)[]> { - return await this.table.bulkAdd(dataList as T[], { allKeys: true }); + const processed = dataList.map(item => this.prepareDataForWrite(item)); + return await this.table.bulkAdd(processed as T[], { allKeys: true }); } // 批量创建数据(直接使用接口数据) @@ -366,12 +407,14 @@ export class DatabaseService { return []; } - const processedData = newData.map(item => ({ - ...item, - serverId: item.id, // 使用接口的id作为serverId主键 - phone: item.phone ?? "", - region: item.region ?? "", - })); + const processedData = newData.map(item => + this.prepareDataForWrite({ + ...item, + serverId: item.id, // 使用接口的id作为serverId主键 + phone: item.phone ?? "", + region: item.region ?? "", + }), + ); return await this.table.bulkAdd(processedData as T[], { allKeys: true }); } @@ -545,6 +588,27 @@ export class DatabaseService { .equals(value) .count(); } + + private prepareDataForWrite(data: any) { + if (!data || typeof data !== "object") { + return data; + } + + const prepared = { ...data }; + + if ("extendFields" in prepared) { + const value = prepared.extendFields; + if (typeof value === "string" && value.trim() !== "") { + prepared.extendFields = value; + } else if (value && typeof value === "object") { + prepared.extendFields = JSON.stringify(value); + } else { + prepared.extendFields = "{}"; + } + } + + return prepared; + } } // 创建统一表的服务实例 diff --git a/Touchkebao/src/utils/dbAction/contact.ts b/Touchkebao/src/utils/dbAction/contact.ts index 5630d4d4..abbb7fdb 100644 --- a/Touchkebao/src/utils/dbAction/contact.ts +++ b/Touchkebao/src/utils/dbAction/contact.ts @@ -186,7 +186,8 @@ export class ContactManager { local.wechatAccountId !== server.wechatAccountId || (local.aiType ?? 0) !== (server.aiType ?? 0) || // 添加 aiType 比较 (local.phone ?? "") !== (server.phone ?? "") || - (local.region ?? "") !== (server.region ?? "") + (local.region ?? "") !== (server.region ?? "") || + (local.extendFields ?? "{}") !== (server.extendFields ?? "{}") ); } @@ -194,10 +195,12 @@ export class ContactManager { * 获取联系人分组列表 */ static async getContactGroups( - userId: number, - customerId?: number, + _userId: number, + _customerId?: number, ): Promise { try { + void _userId; + void _customerId; // 这里应该根据实际的标签系统来实现 // 暂时返回空数组,实际实现需要根据标签表来查询 return []; diff --git a/Touchkebao/src/utils/dbAction/message.ts b/Touchkebao/src/utils/dbAction/message.ts index 9df03116..d42289bf 100644 --- a/Touchkebao/src/utils/dbAction/message.ts +++ b/Touchkebao/src/utils/dbAction/message.ts @@ -11,6 +11,20 @@ import Dexie from "dexie"; import { db, chatSessionService, ChatSession } from "../db"; import { ContractData, weChatGroup } from "@/pages/pc/ckbox/data"; +const serializeExtendFields = (value: any) => { + if (typeof value === "string") { + return value.trim() ? value : "{}"; + } + if (value && typeof value === "object") { + try { + return JSON.stringify(value); + } catch (error) { + console.warn("序列化 extendFields 失败:", error); + } + } + return "{}"; +}; + export class MessageManager { private static updateCallbacks = new Set<(sessions: ChatSession[]) => void>(); @@ -103,6 +117,7 @@ export class MessageManager { wechatFriendId: friend.id, wechatId: friend.wechatId, alias: friend.alias, + extendFields: serializeExtendFields((friend as any).extendFields), }; } @@ -139,6 +154,7 @@ export class MessageManager { chatroomOwner: group.chatroomOwner, selfDisplayName: group.selfDisplyName, notice: group.notice, + extendFields: serializeExtendFields((group as any).extendFields), }; } @@ -205,6 +221,7 @@ export class MessageManager { "aiType", // 添加aiType比较 "phone", "region", + "extendFields", ]; for (const field of fieldsToCompare) {