import React, { useState, useEffect, useMemo, useRef } from 'react'; import { useThemeStore } from '../stores/themeStore'; import { Newspaper, MessageSquareOff } from 'lucide-react'; import './BizPage.scss'; export interface BizAccount { username: string; name: string; avatar: string; type: number; last_time: number; formatted_last_time: string; } export const BizAccountList: React.FC<{ onSelect: (account: BizAccount) => void; selectedUsername?: string; searchKeyword?: string; }> = ({ onSelect, selectedUsername, searchKeyword }) => { const [accounts, setAccounts] = useState([]); const [loading, setLoading] = useState(false); const [myWxid, setMyWxid] = useState(''); useEffect(() => { const initWxid = async () => { try { const wxid = await window.electronAPI.config.get('myWxid'); if (wxid) { setMyWxid(wxid as string); } } catch (e) { console.error("获取 myWxid 失败:", e); } }; initWxid().then(_r => { }); }, []); useEffect(() => { const fetch = async () => { if (!myWxid) { return; } setLoading(true); try { const res = await window.electronAPI.biz.listAccounts(myWxid) setAccounts(res || []); } catch (err) { console.error('获取服务号列表失败:', err); } finally { setLoading(false); } }; fetch().then(_r => { } ); }, [myWxid]); const filtered = useMemo(() => { if (!searchKeyword) return accounts; const q = searchKeyword.toLowerCase(); return accounts.filter(a => (a.name && a.name.toLowerCase().includes(q)) || (a.username && a.username.toLowerCase().includes(q)) ); }, [accounts, searchKeyword]); if (loading) return
加载中...
; return (
{filtered.map(item => (
onSelect(item)} className={`biz-account-item ${selectedUsername === item.username ? 'active' : ''} ${item.username === 'gh_3dfda90e39d6' ? 'pay-account' : ''}`} >
{item.name || item.username} {item.formatted_last_time}
{item.type === 1 ? '服务号' : item.type === 0 ? '订阅号' : item.type === 2 ? '企业号' : '未知'}
))}
); }; // 2. 公众号消息区域组件 export const BizMessageArea: React.FC<{ account: BizAccount | null; }> = ({ account }) => { const themeMode = useThemeStore((state) => state.themeMode); const [messages, setMessages] = useState([]); const [loading, setLoading] = useState(false); const [offset, setOffset] = useState(0); const [hasMore, setHasMore] = useState(true); const limit = 20; const messageListRef = useRef(null); const [myWxid, setMyWxid] = useState(''); useEffect(() => { const initWxid = async () => { try { const wxid = await window.electronAPI.config.get('myWxid'); if (wxid) { setMyWxid(wxid as string); } } catch (e) { } }; initWxid(); }, []); const isDark = useMemo(() => { if (themeMode === 'dark') return true; if (themeMode === 'system') { return window.matchMedia('(prefers-color-scheme: dark)').matches; } return false; }, [themeMode]); useEffect(() => { if (account && myWxid) { setMessages([]); setOffset(0); setHasMore(true); loadMessages(account.username, 0); } }, [account, myWxid]); const loadMessages = async (username: string, currentOffset: number) => { if (loading || !myWxid) return; setLoading(true); try { let res; if (username === 'gh_3dfda90e39d6') { res = await window.electronAPI.biz.listPayRecords(myWxid, limit, currentOffset); } else { res = await window.electronAPI.biz.listMessages(username, myWxid, limit, currentOffset); } if (res) { if (res.length < limit) setHasMore(false); setMessages(prev => currentOffset === 0 ? res : [...prev, ...res]); setOffset(currentOffset + limit); } } catch (err) { console.error('加载消息失败:', err); } finally { setLoading(false); } }; const handleScroll = (e: React.UIEvent) => { const target = e.currentTarget; if (target.scrollHeight - Math.abs(target.scrollTop) - target.clientHeight < 50) { if (!loading && hasMore && account) { loadMessages(account.username, offset); } } }; if (!account) { return (

请选择一个服务号查看消息

); } const defaultImage = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0MDAiIGhlaWdodD0iMTgwIj48cmVjdCB3aWR0aD0iNDAwIiBoZWlnaHQ9IjE4MCIgZmlsbD0iI2Y1ZjVmNSIvPjwvc3ZnPg=='; return (

{account.name}

{!loading && messages.length === 0 && (

暂无本地记录

该公众号在当前数据库中没有可显示的聊天历史

)} {messages.map((msg) => (
{account.username === 'gh_3dfda90e39d6' ? (
{msg.merchant_icon ? :
¥
} {msg.merchant_name || '微信支付'}
{msg.title}
{msg.description}
{msg.formatted_time}
) : (
window.electronAPI.shell.openExternal(msg.url)} className="main-article">

{msg.title}

{msg.des &&
{msg.des}
} {msg.content_list && msg.content_list.length > 1 && (
{msg.content_list.slice(1).map((item: any, idx: number) => (
window.electronAPI.shell.openExternal(item.url)} className="sub-item"> {item.title} {item.cover && }
))}
)}
)}
))} {loading &&
加载中...
}
); }; const BizPage: React.FC = () => { const [selectedAccount, setSelectedAccount] = useState(null); return (
); } export default BizPage;