refactor(TransmitModal): 简化联系人数据结构并优化状态管理
移除冗余的Contact接口,直接使用原始数据类型 使用组件内部状态替代zustand store管理选中联系人 优化搜索和选择逻辑,减少不必要的转换
This commit is contained in:
@@ -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} />
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user