From ad2d1c27abe33d327a9e3d93c91f34dc4915f374 Mon Sep 17 00:00:00 2001 From: wong <106998207@qq.com> Date: Fri, 28 Nov 2025 17:03:05 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cunkebao/controller/wechat/PostTransferFriends.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Server/application/cunkebao/controller/wechat/PostTransferFriends.php b/Server/application/cunkebao/controller/wechat/PostTransferFriends.php index 1839231a..6bb0007a 100644 --- a/Server/application/cunkebao/controller/wechat/PostTransferFriends.php +++ b/Server/application/cunkebao/controller/wechat/PostTransferFriends.php @@ -74,7 +74,7 @@ class PostTransferFriends extends BaseController $taskId = Db::name('customer_acquisition_task')->insertGetId([ 'name' => '迁移好友('. $wechat['nickname'] .')', - 'sceneId' => 1, + 'sceneId' => 10, 'sceneConf' => json_encode($sceneConf), 'reqConf' => json_encode($reqConf), 'tagConf' => json_encode([]), From 97fc9959bb5f50a1896ca1a4bc87ea01996ff2d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B6=85=E7=BA=A7=E8=80=81=E7=99=BD=E5=85=94?= Date: Fri, 28 Nov 2025 23:00:40 +0800 Subject: [PATCH 2/3] Refactor cache clearing functionality in settings page to improve user feedback and error handling. Update WeChat API functions to support debounce options for contact and group list retrieval. Enhance message rendering logic to include red packet messages and improve user identification in chat records. --- .../src/pages/mobile/mine/setting/index.tsx | 39 ++++- Cunkebao/src/utils/cacheCleaner.ts | 70 ++++++++ Moncter/src/utils/cacheCleaner.ts | 73 ++++++++ Touchkebao/src/pages/pc/ckbox/weChat/api.ts | 24 ++- .../RedPacketMessage.module.scss | 160 ++++++++++++++++++ .../components/RedPacketMessage/index.tsx | 62 +++++++ .../components/MessageRecord/index.tsx | 31 +++- .../SidebarMenu/WechatFriends/extend.ts | 4 +- Touchkebao/src/utils/dbAction/message.ts | 4 +- 9 files changed, 442 insertions(+), 25 deletions(-) create mode 100644 Cunkebao/src/utils/cacheCleaner.ts create mode 100644 Moncter/src/utils/cacheCleaner.ts create mode 100644 Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/MessageRecord/components/RedPacketMessage/RedPacketMessage.module.scss create mode 100644 Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/MessageRecord/components/RedPacketMessage/index.tsx diff --git a/Cunkebao/src/pages/mobile/mine/setting/index.tsx b/Cunkebao/src/pages/mobile/mine/setting/index.tsx index 1ddcf226..c002543f 100644 --- a/Cunkebao/src/pages/mobile/mine/setting/index.tsx +++ b/Cunkebao/src/pages/mobile/mine/setting/index.tsx @@ -8,7 +8,6 @@ import { LogoutOutlined, SettingOutlined, LockOutlined, - ReloadOutlined, } from "@ant-design/icons"; import Layout from "@/components/Layout/Layout"; import { useUserStore } from "@/store/module/user"; @@ -16,7 +15,7 @@ import { useSettingsStore } from "@/store/module/settings"; import style from "./index.module.scss"; import NavCommon from "@/components/NavCommon"; import { sendMessageToParent, TYPE_EMUE } from "@/utils/postApp"; -import { updateChecker } from "@/utils/updateChecker"; +import { clearApplicationCache } from "@/utils/cacheCleaner"; interface SettingItem { id: string; @@ -58,13 +57,35 @@ const Setting: React.FC = () => { const handleClearCache = () => { Dialog.confirm({ content: "确定要清除缓存吗?这将清除所有本地数据。", - onConfirm: () => { - sendMessageToParent( - { - action: "clearCache", - }, - TYPE_EMUE.FUNCTION, - ); + onConfirm: async () => { + const handler = Toast.show({ + icon: "loading", + content: "正在清理缓存...", + duration: 0, + }); + try { + await clearApplicationCache(); + sendMessageToParent( + { + action: "clearCache", + }, + TYPE_EMUE.FUNCTION, + ); + handler.close(); + Toast.show({ + icon: "success", + content: "缓存清理完成", + position: "top", + }); + } catch (error) { + console.error("clear cache failed", error); + handler.close(); + Toast.show({ + icon: "fail", + content: "缓存清理失败,请稍后再试", + position: "top", + }); + } }, }); }; diff --git a/Cunkebao/src/utils/cacheCleaner.ts b/Cunkebao/src/utils/cacheCleaner.ts new file mode 100644 index 00000000..3be09fbd --- /dev/null +++ b/Cunkebao/src/utils/cacheCleaner.ts @@ -0,0 +1,70 @@ +// 全局缓存清理工具:浏览器存储 + IndexedDB + Zustand store +import { clearAllPersistedData } from "@/store"; +import { useUserStore } from "@/store/module/user"; +import { useAppStore } from "@/store/module/app"; +import { useSettingsStore } from "@/store/module/settings"; + +const isBrowser = typeof window !== "undefined"; + +const safeStorageClear = (storage?: Storage) => { + if (!storage) return; + try { + storage.clear(); + } catch (error) { + console.warn("清理存储失败:", error); + } +}; + +export const clearBrowserStorage = () => { + if (!isBrowser) return; + safeStorageClear(window.localStorage); + safeStorageClear(window.sessionStorage); + try { + clearAllPersistedData(); + } catch (error) { + console.warn("清理持久化 store 失败:", error); + } +}; + +export const clearAllIndexedDB = async (): Promise => { + if (!isBrowser || !window.indexedDB || !indexedDB.databases) return; + + const databases = await indexedDB.databases(); + const deleteJobs = databases + .map(db => db.name) + .filter((name): name is string => Boolean(name)) + .map( + name => + new Promise((resolve, reject) => { + const request = indexedDB.deleteDatabase(name); + request.onsuccess = () => resolve(); + request.onerror = () => reject(new Error(`删除数据库 ${name} 失败`)); + request.onblocked = () => { + setTimeout(() => { + const retry = indexedDB.deleteDatabase(name); + retry.onsuccess = () => resolve(); + retry.onerror = () => + reject(new Error(`删除数据库 ${name} 失败`)); + }, 100); + }; + }), + ); + + await Promise.allSettled(deleteJobs); +}; + +export const resetAllStores = () => { + const userStore = useUserStore.getState(); + const appStore = useAppStore.getState(); + const settingsStore = useSettingsStore.getState(); + + userStore?.clearUser?.(); + appStore?.resetAppState?.(); + settingsStore?.resetSettings?.(); +}; + +export const clearApplicationCache = async () => { + clearBrowserStorage(); + await clearAllIndexedDB(); + resetAllStores(); +}; diff --git a/Moncter/src/utils/cacheCleaner.ts b/Moncter/src/utils/cacheCleaner.ts new file mode 100644 index 00000000..78f30c50 --- /dev/null +++ b/Moncter/src/utils/cacheCleaner.ts @@ -0,0 +1,73 @@ +// 缓存清理工具,统一处理浏览器存储与 Zustand store +import { clearAllPersistedData } from "@/store"; +import { useUserStore } from "@/store/module/user"; +import { useAppStore } from "@/store/module/app"; +import { useSettingsStore } from "@/store/module/settings"; + +const isBrowser = typeof window !== "undefined"; + +const safeStorageClear = (storage?: Storage) => { + if (!storage) return; + try { + storage.clear(); + } catch (error) { + console.warn("清理存储失败:", error); + } +}; + +export const clearBrowserStorage = () => { + if (!isBrowser) return; + safeStorageClear(window.localStorage); + safeStorageClear(window.sessionStorage); + // 清理自定义持久化数据 + try { + clearAllPersistedData(); + } catch (error) { + console.warn("清理持久化 store 失败:", error); + } +}; + +export const clearAllIndexedDB = async (): Promise => { + if (!isBrowser || !window.indexedDB || !indexedDB.databases) return; + + const databases = await indexedDB.databases(); + const deleteJobs = databases + .map(db => db.name) + .filter((name): name is string => Boolean(name)) + .map( + name => + new Promise((resolve, reject) => { + const request = indexedDB.deleteDatabase(name); + request.onsuccess = () => resolve(); + request.onerror = () => + reject(new Error(`删除数据库 ${name} 失败`)); + request.onblocked = () => { + setTimeout(() => { + const retry = indexedDB.deleteDatabase(name); + retry.onsuccess = () => resolve(); + retry.onerror = () => + reject(new Error(`删除数据库 ${name} 失败`)); + }, 100); + }; + }), + ); + + await Promise.allSettled(deleteJobs); +}; + +export const resetAllStores = () => { + const userStore = useUserStore.getState(); + const appStore = useAppStore.getState(); + const settingsStore = useSettingsStore.getState(); + + userStore?.clearUser?.(); + appStore?.resetAppState?.(); + settingsStore?.resetSettings?.(); +}; + +export const clearApplicationCache = async () => { + clearBrowserStorage(); + await clearAllIndexedDB(); + resetAllStores(); +}; + diff --git a/Touchkebao/src/pages/pc/ckbox/weChat/api.ts b/Touchkebao/src/pages/pc/ckbox/weChat/api.ts index 32bb9604..7e77433e 100644 --- a/Touchkebao/src/pages/pc/ckbox/weChat/api.ts +++ b/Touchkebao/src/pages/pc/ckbox/weChat/api.ts @@ -28,14 +28,30 @@ export function getTrafficPoolList() { "GET", ); } +type ListRequestOptions = { + debounceGap?: number; +}; + // 好友列表 -export function getContactList(params) { - return request("/v1/kefu/wechatFriend/list", params, "GET"); +export function getContactList(params, options?: ListRequestOptions) { + return request( + "/v1/kefu/wechatFriend/list", + params, + "GET", + undefined, + options?.debounceGap, + ); } // 群列表 -export function getGroupList(params) { - return request("/v1/kefu/wechatChatroom/list", params, "GET"); +export function getGroupList(params, options?: ListRequestOptions) { + return request( + "/v1/kefu/wechatChatroom/list", + params, + "GET", + undefined, + options?.debounceGap, + ); } // 分组列表 export function getLabelsListByGroup(params) { diff --git a/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/MessageRecord/components/RedPacketMessage/RedPacketMessage.module.scss b/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/MessageRecord/components/RedPacketMessage/RedPacketMessage.module.scss new file mode 100644 index 00000000..1d8603b0 --- /dev/null +++ b/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/MessageRecord/components/RedPacketMessage/RedPacketMessage.module.scss @@ -0,0 +1,160 @@ +// 红包消息样式 +.redPacketMessage { + background: transparent; + box-shadow: none; + max-width: 300px; +} + +.redPacketCard { + position: relative; + display: flex; + flex-direction: column; + padding: 16px 20px; + background: linear-gradient(135deg, #ff6b6b 0%, #ee5a6f 100%); + border-radius: 8px; + cursor: pointer; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + box-shadow: 0 4px 12px rgba(255, 107, 107, 0.3); + overflow: hidden; + + // 红包装饰背景 + &::before { + content: ""; + position: absolute; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: radial-gradient( + circle, + rgba(255, 215, 0, 0.15) 0%, + transparent 70% + ); + animation: shimmer 3s ease-in-out infinite; + } + + // 金色装饰边框 + &::after { + content: ""; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + border: 2px solid rgba(255, 215, 0, 0.4); + border-radius: 8px; + pointer-events: none; + } + + &:hover { + transform: translateY(-2px); + box-shadow: 0 6px 16px rgba(255, 107, 107, 0.4); + background: linear-gradient(135deg, #ff7b7b 0%, #ff6b7f 100%); + } + + &:active { + transform: translateY(0); + } +} + +@keyframes shimmer { + 0%, + 100% { + transform: rotate(0deg); + } + 50% { + transform: rotate(180deg); + } +} + +.redPacketHeader { + display: flex; + align-items: center; + gap: 12px; + margin-bottom: 12px; + position: relative; + z-index: 1; +} + +.redPacketIcon { + font-size: 32px; + line-height: 1; + filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2)); + animation: bounce 2s ease-in-out infinite; +} + +@keyframes bounce { + 0%, + 100% { + transform: translateY(0); + } + 50% { + transform: translateY(-4px); + } +} + +.redPacketTitle { + flex: 1; + font-size: 16px; + font-weight: 600; + color: #ffffff; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); + letter-spacing: 0.5px; + line-height: 1.4; + word-break: break-word; +} + +.redPacketFooter { + display: flex; + align-items: center; + justify-content: flex-end; + position: relative; + z-index: 1; + padding-top: 8px; + border-top: 1px solid rgba(255, 255, 255, 0.3); +} + +.redPacketLabel { + font-size: 12px; + color: rgba(255, 255, 255, 0.9); + font-weight: 500; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); + + &::before { + content: "💰"; + margin-right: 4px; + font-size: 14px; + } +} + +// 消息文本样式(用于错误提示) +.messageText { + line-height: 1.4; + white-space: pre-wrap; + word-break: break-word; + color: #8c8c8c; + font-size: 13px; +} + +// 响应式设计 +@media (max-width: 768px) { + .redPacketMessage { + max-width: 200px; + } + + .redPacketCard { + padding: 12px 16px; + } + + .redPacketIcon { + font-size: 28px; + } + + .redPacketTitle { + font-size: 14px; + } + + .redPacketLabel { + font-size: 11px; + } +} diff --git a/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/MessageRecord/components/RedPacketMessage/index.tsx b/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/MessageRecord/components/RedPacketMessage/index.tsx new file mode 100644 index 00000000..75bf86ff --- /dev/null +++ b/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/MessageRecord/components/RedPacketMessage/index.tsx @@ -0,0 +1,62 @@ +import React from "react"; +import styles from "./RedPacketMessage.module.scss"; + +interface RedPacketData { + nativeurl?: string; + paymsgid?: string; + sendertitle?: string; + [key: string]: any; +} + +interface RedPacketMessageProps { + content: string; +} + +const RedPacketMessage: React.FC = ({ content }) => { + const renderErrorMessage = (fallbackText: string) => ( +
{fallbackText}
+ ); + + if (typeof content !== "string" || !content.trim()) { + return renderErrorMessage("[红包消息 - 无效内容]"); + } + + try { + const trimmedContent = content.trim(); + const jsonData: RedPacketData = JSON.parse(trimmedContent); + + // 验证是否为红包消息 + const isRedPacket = + jsonData.nativeurl && + typeof jsonData.nativeurl === "string" && + jsonData.nativeurl.includes( + "wxpay://c2cbizmessagehandler/hongbao/receivehongbao", + ); + + if (!isRedPacket) { + return renderErrorMessage("[红包消息 - 格式错误]"); + } + + const title = jsonData.sendertitle || "恭喜发财,大吉大利"; + const paymsgid = jsonData.paymsgid || ""; + + return ( +
+
+
+
🧧
+
{title}
+
+
+ 微信红包 +
+
+
+ ); + } catch (e) { + console.warn("红包消息解析失败:", e); + return renderErrorMessage("[红包消息 - 解析失败]"); + } +}; + +export default RedPacketMessage; diff --git a/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/MessageRecord/index.tsx b/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/MessageRecord/index.tsx index bd5813d0..ccd4759b 100644 --- a/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/MessageRecord/index.tsx +++ b/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/MessageRecord/index.tsx @@ -7,6 +7,7 @@ import VideoMessage from "./components/VideoMessage"; import ClickMenu from "./components/ClickMeau"; import LocationMessage from "./components/LocationMessage"; import SystemRecommendRemarkMessage from "./components/SystemRecommendRemarkMessage/index"; +import RedPacketMessage from "./components/RedPacketMessage"; import { ChatRecord, ContractData, weChatGroup } from "@/pages/pc/ckbox/data"; import { formatWechatTime } from "@/utils/common"; import { getEmojiPath } from "@/components/EmojiSeclection/wechatEmoji"; @@ -254,6 +255,7 @@ const MessageRecord: React.FC = ({ contract }) => { msg?: ChatRecord, contract?: ContractData | weChatGroup, ) => { + console.log("红包"); if (isLegacyEmojiContent(trimmedContent)) { return renderEmojiContent(rawContent); } @@ -261,6 +263,17 @@ const MessageRecord: React.FC = ({ contract }) => { const jsonData = tryParseContentJson(trimmedContent); if (jsonData && typeof jsonData === "object") { + // 判断是否为红包消息 + if ( + jsonData.nativeurl && + typeof jsonData.nativeurl === "string" && + jsonData.nativeurl.includes( + "wxpay://c2cbizmessagehandler/hongbao/receivehongbao", + ) + ) { + return ; + } + if (jsonData.type === "file" && msg && contract) { return ( = ({ contract }) => { if (!msg) { return { avatar: "", nickname: "" }; } - const member = - groupRender.find(user => user?.identifier === msg?.sender?.wechatId) || - groupRender.find(user => user?.wechatId === msg?.sender?.wechatId); + + const member = groupRender.find( + user => user?.identifier === msg?.senderWechatId, + ); + console.log(member, "member"); return { - avatar: member?.avatar || msg?.sender?.avatar || "", - nickname: member?.nickname || msg?.sender?.nickname || "", + avatar: member?.avatar || msg?.avatar, + nickname: member?.nickname || msg?.senderNickname, }; }; @@ -615,7 +630,7 @@ const MessageRecord: React.FC = ({ contract }) => { const isOwn = msg?.isSend; const isGroup = !!contract.chatroomId; - const groupUser = isGroup ? renderGroupUser(msg) : null; + return (
= ({ contract }) => { )} } className={styles.messageAvatar} />
{!isOwn && (
- {groupUser?.nickname} + {renderGroupUser(msg)?.nickname}
)} <> 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 cf2b8117..fff567c7 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 @@ -18,7 +18,7 @@ export const getAllFriends = async () => { let hasMore = true; while (hasMore) { - const result = await getContactList({ page, limit }); + const result = await getContactList({ page, limit }, { debounceGap: 0 }); const friendList = result?.list || []; if ( @@ -56,7 +56,7 @@ export const getAllGroups = async () => { let hasMore = true; while (hasMore) { - const result = await getGroupList({ page, limit }); + const result = await getGroupList({ page, limit }, { debounceGap: 0 }); const groupList = result?.list || []; if (!groupList || !Array.isArray(groupList) || groupList.length === 0) { diff --git a/Touchkebao/src/utils/dbAction/message.ts b/Touchkebao/src/utils/dbAction/message.ts index 0d8f71d3..53610a63 100644 --- a/Touchkebao/src/utils/dbAction/message.ts +++ b/Touchkebao/src/utils/dbAction/message.ts @@ -659,7 +659,7 @@ export class MessageManager { updatedSession.sortKey = this.generateSortKey(updatedSession); await chatSessionService.update(serverId, updatedSession); - console.log(`会话时间已更新: ${serverId} -> ${newTime}`); + await this.triggerCallbacks(userId); } } catch (error) { console.error("更新会话时间失败:", error); @@ -830,7 +830,7 @@ export class MessageManager { }; await chatSessionService.create(sessionWithSortKey); - console.log(`创建新会话: ${session.nickname || session.wechatId}`); + await this.triggerCallbacks(userId); } catch (error) { console.error("创建会话失败:", error); throw error; From 43f6a061e11a0ceb2f1e15d838f36cdd32fb445f Mon Sep 17 00:00:00 2001 From: wong <106998207@qq.com> Date: Mon, 1 Dec 2025 10:05:26 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E5=86=B2=E7=AA=81=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wechat-accounts/detail/detail.module.scss | 95 +++++++++++++++++++ .../mine/wechat-accounts/detail/index.tsx | 56 +++++------ 2 files changed, 120 insertions(+), 31 deletions(-) diff --git a/Cunkebao/src/pages/mobile/mine/wechat-accounts/detail/detail.module.scss b/Cunkebao/src/pages/mobile/mine/wechat-accounts/detail/detail.module.scss index 354503b6..954921fc 100644 --- a/Cunkebao/src/pages/mobile/mine/wechat-accounts/detail/detail.module.scss +++ b/Cunkebao/src/pages/mobile/mine/wechat-accounts/detail/detail.module.scss @@ -1050,6 +1050,101 @@ height: 500px; overflow-y: auto; + // 健康分评估区域 + .health-score-section { + background: #ffffff; + border-radius: 12px; + padding: 16px; + margin-bottom: 16px; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); + + .health-score-title { + font-size: 16px; + font-weight: 600; + color: #333; + margin-bottom: 12px; + } + + .health-score-info { + .health-score-status { + display: flex; + justify-content: space-between; + margin-bottom: 12px; + + .status-tag { + background: #ffebeb; + color: #ff4d4f; + font-size: 12px; + padding: 2px 8px; + border-radius: 4px; + } + + .status-time { + font-size: 12px; + color: #999; + } + } + + .health-score-display { + display: flex; + align-items: center; + + .score-circle-wrapper { + width: 100px; + height: 100px; + margin-right: 24px; + position: relative; + + .score-circle { + width: 100%; + height: 100%; + border-radius: 50%; + background: #fff; + border: 8px solid #ff4d4f; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + + .score-number { + font-size: 28px; + font-weight: 700; + color: #ff4d4f; + line-height: 1; + } + + .score-label { + font-size: 12px; + color: #999; + margin-top: 4px; + } + } + } + + .health-score-stats { + flex: 1; + + .stats-row { + display: flex; + justify-content: space-between; + margin-bottom: 8px; + + .stats-label { + font-size: 14px; + color: #666; + } + + .stats-value { + font-size: 14px; + color: #333; + font-weight: 500; + } + } + } + } + } + } + .health-score-card { background: #ffffff; border-radius: 12px; diff --git a/Cunkebao/src/pages/mobile/mine/wechat-accounts/detail/index.tsx b/Cunkebao/src/pages/mobile/mine/wechat-accounts/detail/index.tsx index aeb10125..333eb353 100644 --- a/Cunkebao/src/pages/mobile/mine/wechat-accounts/detail/index.tsx +++ b/Cunkebao/src/pages/mobile/mine/wechat-accounts/detail/index.tsx @@ -611,29 +611,32 @@ const WechatAccountDetail: React.FC = () => {
- {/* 健康分数圆环 */} -
-
- 已添加加人 - 最后添加时间: {accountSummary?.healthScore?.lastAddTime || "18:36:06"} -
-
-
-
-
- {accountSummary?.healthScore?.score || 67} -
-
SCORE
-
+ {/* 健康分评估区域 */} +
+
健康分评估
+
+
+ {overviewData?.healthScoreAssessment?.statusTag || "已添加加人"} + 最后添加时间: {overviewData?.healthScoreAssessment?.lastAddTime || "18:44:14"}
-
-
-
每日限额
-
{accountSummary?.statistics.addLimit || 0} 人
+
+
+
+
+ {overviewData?.healthScoreAssessment?.score || 67} +
+
SCORE
+
-
-
今日已加
-
{accountSummary?.statistics.todayAdded || 0} 人
+
+
+
每日限额
+
{overviewData?.healthScoreAssessment?.dailyLimit || 0} 人
+
+
+
今日已加
+
{overviewData?.healthScoreAssessment?.todayAdded || 0} 人
+
@@ -790,16 +793,7 @@ const WechatAccountDetail: React.FC = () => {
{friend.nickname || "未知好友"}
-
- {friend.tags?.map((tag, index) => ( - - {typeof tag === "string" ? tag : tag.name} - - ))} -
+
ID: {friend.wechatId || "-"}