refactor(TransmitModal): 简化联系人数据结构并优化状态管理

移除冗余的Contact接口,直接使用原始数据类型
使用组件内部状态替代zustand store管理选中联系人
优化搜索和选择逻辑,减少不必要的转换
This commit is contained in:
超级老白兔
2025-09-19 14:18:52 +08:00
parent dd18b32a09
commit 8dc19a522f

View File

@@ -20,77 +20,40 @@ import { weChatGroupService, contractService } from "@/utils/db";
import { useWeChatStore } from "@/store/module/weChat/weChat";
import { ContractData, weChatGroup } from "@/pages/pc/ckbox/data";
export interface Contact {
id: string;
name: string;
avatar?: string;
type: "user" | "group";
pinyin?: string; // 用于搜索
originalData?: ContractData | weChatGroup; // 保存原始数据
}
export interface TransmitModalProps {
onConfirm?: (params: ContractData[] | weChatGroup[]) => void; // 可选因为会自动更新到store
}
const TransmitModal: React.FC<TransmitModalProps> = ({ onConfirm }) => {
const [searchValue, setSearchValue] = useState("");
const [allContacts, setAllContacts] = useState<Contact[]>([]);
const [allContacts, setAllContacts] = useState<
(ContractData | weChatGroup)[]
>([]);
const [selectedWechatFriend, setSelectedWechatFriend] = useState<
(ContractData | weChatGroup)[]
>([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string>("");
const selectedTransmitContact = useWeChatStore(
state => state.selectedTransmitContact,
);
// 从 Zustand store 获取更新方法
const { updateSelectedTransmitContact } = useWeChatStore();
const openTransmitModal = useWeChatStore(state => state.openTransmitModal);
const updateTransmitModal = useWeChatStore(
state => state.updateTransmitModal,
);
// 加载联系人数据
const loadContacts = async () => {
setLoading(true);
setError("");
try {
// 并行加载联系人和群组数据
const [contractsData, groupsData] = await Promise.all([
contractService.findAll(),
weChatGroupService.findAll(),
]);
// 转换联系人数据格式
const contacts: Contact[] = contractsData.map(
(contract: ContractData) => ({
id: contract.id.toString(),
name:
contract.nickname ||
contract.alias ||
contract.wechatId ||
"未知联系人",
avatar: contract.avatar,
type: "user" as const,
pinyin: contract.quanPin,
originalData: contract,
}),
);
// 转换群组数据格式
const groups: Contact[] = groupsData.map((group: weChatGroup) => ({
id: group.id.toString(),
name: group.nickname || group.conRemark || "未知群组",
avatar: group.chatroomAvatar,
type: "group" as const,
pinyin: group.nickname, // 群组可能没有拼音,使用昵称
originalData: group,
}));
// 合并并排序(联系人在前,群组在后)
const allContactsData = [...contacts, ...groups];
const allContactsData = [...contractsData, ...groupsData];
setAllContacts(allContactsData);
} catch (err) {
console.error("加载联系人数据失败:", err);
setError("加载联系人数据失败,请重试");
message.error("加载联系人数据失败");
} finally {
setLoading(false);
@@ -101,8 +64,7 @@ const TransmitModal: React.FC<TransmitModalProps> = ({ onConfirm }) => {
useEffect(() => {
if (openTransmitModal) {
setSearchValue("");
updateSelectedTransmitContact([]);
setError("");
setSelectedWechatFriend([]);
loadContacts();
}
}, [openTransmitModal]);
@@ -114,52 +76,36 @@ const TransmitModal: React.FC<TransmitModalProps> = ({ onConfirm }) => {
const keyword = searchValue.toLowerCase();
return allContacts.filter(
contact =>
contact.name.toLowerCase().includes(keyword) ||
contact.pinyin?.toLowerCase().includes(keyword) ||
contact.id.toLowerCase().includes(keyword),
contact.nickname.toLowerCase().includes(keyword) ||
contact.pinyin?.toLowerCase().includes(keyword),
);
}, [allContacts, searchValue]);
// 处理联系人选择
const handleContactSelect = (contact: Contact, checked: boolean) => {
console.log(contact);
console.log(checked);
const handleContactSelect = (contact: ContractData | weChatGroup) => {
setSelectedWechatFriend(prev => {
if (isContactSelected(contact.id)) {
return prev.filter(contact => contact.id !== contact.id);
}
return [...prev, contact];
});
};
// 移除已选择的联系人
const handleRemoveSelected = (contactId: string) => {
// updateSelectedTransmitContact(prev =>
// selectedTransmitContact.filter(item => item.id !== contactId),
// );
const handleRemoveSelected = (contactId: number) => {
setSelectedWechatFriend(prev =>
prev.filter(contact => contact.id !== contactId),
);
};
// 确认转发
const handleConfirm = () => {
if (selectedTransmitContact.length === 0) {
message.warning("请至少选择一个联系人");
return;
}
// 更新到 Zustand store
const originalDataList = selectedTransmitContact
.map(contact => contact.originalData)
.filter(Boolean) as (ContractData | weChatGroup)[];
// updateSelectedTransmitContact(originalDataList);
// 如果有外部回调,也调用它
if (onConfirm) {
onConfirm(selectedTransmitContact);
}
message.success(`已选择${selectedTransmitContact.length}个联系人`);
console.log("handleConfirm");
};
// 检查联系人是否已选择
const isContactSelected = (contactId: string) => {
console.log(selectedTransmitContact);
return selectedTransmitContact.some(contact => contact.id === contactId);
const isContactSelected = (contactId: number) => {
return selectedWechatFriend.some(contact => contact.id === contactId);
};
// 重试加载
@@ -182,12 +128,12 @@ const TransmitModal: React.FC<TransmitModalProps> = ({ onConfirm }) => {
key="confirm"
type="primary"
onClick={handleConfirm}
disabled={selectedTransmitContact.length === 0}
disabled={selectedWechatFriend.length === 0}
loading={loading}
>
{selectedTransmitContact.length > 0 &&
` (${selectedTransmitContact.length})`}
{selectedWechatFriend.length > 0 &&
` (${selectedWechatFriend.length})`}
</Button>,
]}
>
@@ -216,21 +162,12 @@ const TransmitModal: React.FC<TransmitModalProps> = ({ onConfirm }) => {
<Spin size="large" />
<span>...</span>
</div>
) : error ? (
<div className={styles.errorContainer}>
<span>{error}</span>
<Button size="small" onClick={handleRetry}>
</Button>
</div>
) : filteredContacts.length > 0 ? (
filteredContacts.map(contact => (
<div key={contact.id} className={styles.contactItem}>
<Checkbox
checked={isContactSelected(contact.id)}
onChange={e =>
handleContactSelect(contact, e.target.checked)
}
onChange={() => handleContactSelect(contact)}
disabled={isContactSelected(contact.id)}
>
<div className={styles.contactInfo}>
@@ -246,7 +183,7 @@ const TransmitModal: React.FC<TransmitModalProps> = ({ onConfirm }) => {
}
/>
<span className={styles.contactName}>
{contact.name}
{contact.nickname}
</span>
{contact.type === "group" && (
<TeamOutlined className={styles.groupIcon} />
@@ -269,11 +206,11 @@ const TransmitModal: React.FC<TransmitModalProps> = ({ onConfirm }) => {
{/* 右侧已选择列表 */}
<div className={styles.selectedList}>
<div className={styles.listHeader}>
<span> {selectedTransmitContact.length} </span>
<span> {selectedWechatFriend.length} </span>
</div>
<div className={styles.listContent}>
{selectedTransmitContact.length > 0 ? (
selectedTransmitContact.map(contact => (
{selectedWechatFriend.length > 0 ? (
selectedWechatFriend.map(contact => (
<div key={contact.id} className={styles.selectedItem}>
<div className={styles.contactInfo}>
<Avatar
@@ -287,7 +224,9 @@ const TransmitModal: React.FC<TransmitModalProps> = ({ onConfirm }) => {
)
}
/>
<span className={styles.contactName}>{contact.name}</span>
<span className={styles.contactName}>
{contact.nickname}
</span>
{contact.type === "group" && (
<TeamOutlined className={styles.groupIcon} />
)}