"use client"; import { useCallback, useEffect, useState } from "react"; import { readApiResponse } from "./wecom-user-picker"; type CustomerChat = { chatId: string; name: string; ownerUserId: string; memberCount: number; status: number; }; type BindResult = { customerChatId: string; customerChatName: string; joinConfigId: string; joinQrCode: string; qrError?: string; }; export function TaskCustomerChatModal({ task, onClose, onBound, }: { task: { id: string; name: string; customerChatId: string; customerChatName: string }; onClose: () => void; onBound: () => void; }) { const [chats, setChats] = useState([]); const [boundChatId, setBoundChatId] = useState(task.customerChatId); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); const [error, setError] = useState(""); const [notice, setNotice] = useState(""); const [selectedChatId, setSelectedChatId] = useState(task.customerChatId); const [bindResult, setBindResult] = useState(null); const loadChats = useCallback(async () => { setLoading(true); setError(""); try { const response = await fetch("/api/action", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ action: "task_customer_chats", taskId: task.id }), }); const parsed = await readApiResponse<{ chats?: CustomerChat[]; boundChatId?: string; error?: string; }>(response, "获取客户群列表失败"); if (!response.ok) { throw new Error(parsed.error || "获取客户群列表失败"); } setChats(Array.isArray(parsed.chats) ? parsed.chats : []); const bound = String(parsed.boundChatId ?? ""); setBoundChatId(bound); setSelectedChatId(bound); } catch (reason) { setError(reason instanceof Error ? reason.message : "获取客户群列表失败"); } finally { setLoading(false); } }, [task.id]); useEffect(() => { const timer = window.setTimeout(() => { void loadChats(); }, 0); return () => window.clearTimeout(timer); }, [loadChats]); const submitBind = async (chatId: string) => { const chat = chats.find((item) => item.chatId === chatId); setSaving(true); setError(""); setNotice(""); try { const response = await fetch("/api/action", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ action: "task_bind_customer_chat", taskId: task.id, chatId, chatName: chat?.name ?? "", }), }); const parsed = await readApiResponse<{ task?: BindResult; error?: string }>( response, "绑定客户群失败", ); if (!response.ok) { throw new Error(parsed.error || "绑定客户群失败"); } const result = parsed.task ?? null; setBindResult(result); setBoundChatId(chatId); setSelectedChatId(chatId); setNotice( chatId ? result?.qrError ? `已绑定,但${result.qrError},可重新保存刷新` : `已绑定「${result?.customerChatName || chat?.name || chatId}」,认领人扫码即可进群` : "已解绑,认领页不再展示进群二维码", ); onBound(); } catch (reason) { setError(reason instanceof Error ? reason.message : "绑定客户群失败"); } finally { setSaving(false); } }; const unbind = async () => { if (!window.confirm("解绑后认领页将不再展示进群二维码,确定解绑?")) return; await submitBind(""); }; return (
event.stopPropagation()} >

绑定客户群

列出任务负责人名下的企业微信客户群,绑定后生成进群活码,认领人在领取页扫码进群。

任务:{task.name} {boundChatId ? ` · 当前绑定:${task.customerChatName || boundChatId}` : " · 未绑定"}
{error &&

{error}

} {notice &&

{notice}

} {bindResult?.joinQrCode && (
进群活码 进群活码(已同步展示在认领页)
)}
{loading ? (
正在拉取负责人名下客户群…
) : chats.length === 0 ? (
未拉取到客户群——请任务负责人先在企微客户端创建客户群(内外部成员都可拉入), 再点击「刷新列表」。
) : ( chats.map((chat) => { const isBound = chat.chatId === boundChatId; return ( ); }) )}
{boundChatId ? ( ) : null}
); }