import { useEffect, useState } from 'react' import { SpinLoading, Empty, Toast, SearchBar } from 'antd-mobile' import { SummaryCard, SummaryItem } from './components/SummaryCard' import { ChatMessageList, ChatMessage } from './components/ChatMessageList' import { noCacheFetch } from './services/http' const CORPID = 'wwd483c2fba24ae30a' const AGENTID = '1000021' const REDIRECT_URI = encodeURIComponent('https://ai.9artedu.com/sidebar/summary-search.html') interface CustomerSummaryGroup { customerId?: string customerName?: string phone?: string wechatId?: string list?: SummaryItem[] } function SummarySearchApp() { const [loading, setLoading] = useState(true) const [searching, setSearching] = useState(false) const [keyword, setKeyword] = useState('') const [groups, setGroups] = useState(null) const [needLogin, setNeedLogin] = useState(false) const [error, setError] = useState('') useEffect(() => { const init = async () => { const urlParams = new URLSearchParams(window.location.search) const code = urlParams.get('code') // 1. URL 中有 code → 先登录 if (code) { const cleanUrl = window.location.pathname + window.location.hash window.history.replaceState({}, document.title, cleanUrl) const ok = await tryCodeLogin(code) if (!ok) { setLoading(false) setNeedLogin(true) setError('登录失败,请重试') return } } // 2. 检查员工登录态 const staffId = urlParams.get('staffId') || localStorage.getItem('staff_user_id') || '' if (!staffId) { setLoading(false) setNeedLogin(true) setError('未获取到员工ID,请先登录') return } setLoading(false) } init() }, []) const tryCodeLogin = async (code: string): Promise => { try { const res = await noCacheFetch(`/api/v1/auth/login?code=${encodeURIComponent(code)}`, { method: 'POST' }) const data = await res.json() if (data.code === 0 && data.data) { const info = data.data localStorage.setItem('staff_token', info.token) localStorage.setItem('staff_user_id', info.userId) localStorage.setItem('staff_user_name', info.userName || '') localStorage.setItem('staff_avatar', info.avatar || '') localStorage.setItem('staff_role', info.role || 'SEAT') console.log('OAuth 登录成功:', info.userId, info.userName) return true } console.error('OAuth login failed:', data.message) } catch (e) { console.error('Code login error:', e) } return false } const redirectToWeComOAuth = () => { const oauthUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${CORPID}&redirect_uri=${REDIRECT_URI}&response_type=code&scope=snsapi_base&agentid=${AGENTID}&state=summarySearch#wechat_redirect` console.log('跳转企微 OAuth:', oauthUrl) window.location.href = oauthUrl } const doSearch = async () => { const kw = keyword.trim() if (!kw) { Toast.show({ content: '请输入手机号或微信号', icon: 'fail' }) return } setSearching(true) try { const res = await noCacheFetch(`/api/v1/archive/daily-summary/by-contact?keyword=${encodeURIComponent(kw)}`) const data = await res.json() if (data.code === 0 && Array.isArray(data.data)) { setGroups(data.data) if (data.data.length === 0) { Toast.show({ content: '未找到绑定该联系方式的客户', icon: 'fail' }) } } else { const msg = data.message || '查询失败' Toast.show({ content: msg, icon: 'fail' }) } } catch (e) { console.error('查询每日总结失败:', e) Toast.show({ content: '网络错误', icon: 'fail' }) } finally { setSearching(false) } } if (loading) { return (
加载中...
) } if (needLogin) { return (
{error || '未获取到员工ID,请先登录'}
) } const totalCount = (groups || []).reduce((sum, g) => sum + (g.list?.length || 0), 0) // 昵称缺失(仍是企微外部联系人ID)时,显示 ID 尾号而不是整串 ID const displayName = (g: CustomerSummaryGroup) => { const name = (g.customerName || '').trim() if (name && name !== g.customerId) return name const id = g.customerId || '' return id ? `客户 …${id.slice(-6)}` : '未命名客户' } return (
🔍 客户总结查询
false} style={{ '--border-radius': '8px', padding: 0 } as any} /> {groups !== null && groups.length > 0 && (
共 {groups.length} 个客户 · {totalCount} 条总结
)}
{groups !== null && groups.length === 0 && ( )} {(groups || []).map((group, gi) => (
👤 {displayName(group)}
{group.phone &&
📱 {group.phone}
} {group.wechatId &&
💬 {group.wechatId}
}
{(group.list || []).length === 0 ? ( ) : ( (group.list || []).map((item, index) => ( )) )}
))}
) } export default SummarySearchApp /** * 客户暂无每日总结时的兜底:加载最近 10 条单聊消息 */ function RecentChatFallback({ customerId }: { customerId: string }) { const [chatMessages, setChatMessages] = useState(null) useEffect(() => { if (!customerId) { setChatMessages([]) return } const load = async () => { try { const res = await noCacheFetch( `/api/v1/archive/messages/recent-chat?customerId=${encodeURIComponent(customerId)}&limit=10` ) const data = await res.json() setChatMessages(data.code === 0 && Array.isArray(data.data) ? data.data : []) } catch (e) { console.error('加载最近聊天记录失败:', e) setChatMessages([]) } } load() }, [customerId]) if (chatMessages === null) { return (
) } if (chatMessages.length === 0) { return } return ( <>
暂无每日总结,展示最近 {chatMessages.length} 条聊天
) }