diff --git a/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/ProfileCard/components/ProfileModules/components/detailValue.tsx b/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/ProfileCard/components/ProfileModules/components/detailValue.tsx index 4966a863..a986f5cb 100644 --- a/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/ProfileCard/components/ProfileModules/components/detailValue.tsx +++ b/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/ProfileCard/components/ProfileModules/components/detailValue.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useState, useEffect } from "react"; +import React, { useCallback, useState, useEffect, useRef } from "react"; import { Input, message } from "antd"; import { Button } from "antd-mobile"; import { EditOutlined } from "@ant-design/icons"; @@ -56,8 +56,32 @@ const DetailValue: React.FC = ({ useState>(value); const [changedKeys, setChangedKeys] = useState([]); + // 使用 useRef 存储上一次的 value,用于深度比较 + const prevValueRef = useRef>(value); + + // 深度比较函数:比较两个对象的值是否真的变化了 + const isValueChanged = useCallback( + (prev: Record, next: Record) => { + const allKeys = new Set([...Object.keys(prev), ...Object.keys(next)]); + for (const key of allKeys) { + if (prev[key] !== next[key]) { + return true; + } + } + return false; + }, + [], + ); + // 当外部value变化时,更新内部状态 + // 优化:只有当值真正变化时才重置编辑状态,避免因对象引用变化导致编辑状态丢失 useEffect(() => { + // 深度比较,只有当值真正变化时才更新 + if (!isValueChanged(prevValueRef.current, value)) { + return; + } + + // 只有在值真正变化时才更新状态 setFieldValues(value); setOriginalValues(value); setChangedKeys([]); @@ -67,7 +91,10 @@ const DetailValue: React.FC = ({ newEditingFields[field.key] = false; }); setEditingFields(newEditingFields); - }, [value, fields]); + + // 更新 ref + prevValueRef.current = value; + }, [value, fields, isValueChanged]); const handleFieldChange = useCallback( (fieldKey: string, nextVal: string) => { diff --git a/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/ProfileCard/components/ProfileModules/index.tsx b/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/ProfileCard/components/ProfileModules/index.tsx index 6f40e175..951b5bcc 100644 --- a/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/ProfileCard/components/ProfileModules/index.tsx +++ b/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/ProfileCard/components/ProfileModules/index.tsx @@ -210,14 +210,34 @@ const Person: React.FC = ({ contract }) => { // 构建联系人或群聊详细信息 - const customerList = useCustomerStore(state => state.customerList); - const kfSelectedUser = useMemo(() => { - if (!contract.wechatAccountId) return null; - const matchedCustomer = customerList.find( - customer => customer.id === contract.wechatAccountId, - ); - return matchedCustomer || null; - }, [customerList, contract.wechatAccountId]); + // 优化:使用选择器函数直接订阅匹配的客服对象,避免订阅整个 customerList + // 添加相等性比较,只有当匹配的客服对象或其 labels 真正变化时才触发重新渲染 + const kfSelectedUser = useCustomerStore( + state => { + if (!contract.wechatAccountId) return null; + return ( + state.customerList.find( + customer => customer.id === contract.wechatAccountId, + ) || null + ); + }, + (prev, next) => { + // 如果都是 null,认为相等 + if (!prev && !next) return true; + // 如果一个是 null 另一个不是,认为不相等 + if (!prev || !next) return false; + // 比较关键字段:id 和 labels(因为 useEffect 中使用了 labels) + if (prev.id !== next.id) return false; + // 比较 labels 数组是否真的变化了 + const prevLabels = prev.labels || []; + const nextLabels = next.labels || []; + if (prevLabels.length !== nextLabels.length) return false; + // 深度比较 labels 数组内容(先复制再排序,避免修改原数组) + const prevLabelsStr = JSON.stringify([...prevLabels].sort()); + const nextLabelsStr = JSON.stringify([...nextLabels].sort()); + return prevLabelsStr === nextLabelsStr; + }, + ); // 不再需要从useContactStore获取getContactsByCustomer