"use client"; import React, { useState, useRef, useEffect, useCallback } from "react"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faAngleLeft } from "@fortawesome/free-solid-svg-icons"; import { Input, Button, Toast, Avatar, DotLoading } from "antd-mobile"; import { useRouter, useSearchParams } from "next/navigation"; import { get } from "@/utils/storeInfo"; import requireAPI from "@/utils/requireAPI"; import { formatDeadline } from "@/utils/tools"; import { getStreamerDetailInfo } from "@/api/space"; /* params格式: { mid: item.mid, } */ export default function MessageDetail({}) { // const [hasMore, setHasMore] = useState(true); const router = useRouter(); const searchParams = useSearchParams(); const [oldMessages, setOldMessages] = useState([]); const [messages, setMessages] = useState([]); const [handledmessages, setHandledmessages] = useState([]); const [sessionId, setSessionId] = useState(); const [userInfo, setUserInfo] = useState(null); const [newMessage, setNewMessage] = useState(""); const [loading, setLoading] = useState(false); const [offset, setOffset] = useState(0); const [more, setMore] = useState(1); const scrollBox = useRef(); const toScrollBottom = useRef(0); useEffect(() => { const userData = get("account"); const mid = searchParams.get("mid") if (mid) { getStreamerDetailInfo(Number(mid)).then(data=>{ setMessages([[{ predicate: 1, _id: 1, createdAt: new Date()/1000, text: data?.streamer_ext.auto_response_message, user: { _id: 0, name: data?.streamer_ext.name, avatar: data?.streamer_ext?.avatar?.images[0]?.urls[0], }, }]]); }) } else { setUserInfo(userData); getSession(userData.mid); } }, []); useEffect(() => { const intervalId = setInterval(() => { // console.log("oldMessages[0]", oldMessages[0]); if (oldMessages[0]) { updateMessages(oldMessages[0]?.id, 0, oldMessages); // toScrollBottom.current = 1; } }, 3000); // 间隔时间为3秒 // 在组件卸载时清除定时器 return () => { clearInterval(intervalId); }; }, [oldMessages]); useEffect(() => { if (toScrollBottom.current) { scrollBox.current?.scrollTo(0, scrollBox.current.scrollHeight + 50); toScrollBottom.current = 0; } }, [messages]); // useEffect(() => { // if (offset == 12) { // console.log("offset--------", offset); // scrollBox.current?.scrollTo(0, scrollBox.current.scrollHeight); // // console.log("scrollBox.current",scrollBox.current.scrollHeight,scrollBox.current.scrollTop) // } // }, [offset]); useEffect(() => { if (sessionId && userInfo.mid) { loadEarlierHistory().then((res) => { setMessages((old) => { toScrollBottom.current = 1; return res; }); }); } }, [sessionId]); //查询session const getSession = async (mid) => { setLoading(true); try { const data = await requireAPI( "POST", "/api/contact_customer_service_session/list_by_mid", { body: { mid: Number(mid), }, } ); if (data.ret === -1) { Toast.show({ icon: "fail", content: data.msg, position: "top", }); } setLoading(false); if (data.data.session) { setSessionId(data.data.session.id); } else { //如果是第一次发送,需要创建session createSession(mid); } } catch (error) { console.error(error); } }; //创建session const createSession = async (mid) => { setLoading(true); try { const data = await requireAPI( "POST", "/api/contact_customer_service_session/create", { body: { sub_mid: Number(mid), obj_mid: 0, }, } ); if (data.ret === -1) { Toast.show({ icon: "fail", content: data.msg, position: "top", }); } setSessionId(data.data.session_id); setLoading(false); } catch (error) { console.error(error); } }; //请求历史记录 const loadEarlierHistory = async () => { if (!more) return; try { setLoading(true); const data = await requireAPI( "POST", "/api/contact_customer_service/list_by_session_id", { body: { session_id: sessionId, offset: offset, limit: 12, }, } ); if (data.ret === -1) { Toast.show({ icon: "fail", content: data.msg, position: "top", }); return; } setOffset(data.data.offset); setMore(data.data.more); let mathNewMessages = handleData([...oldMessages, ...data.data.list]); // setMessages((prev) => [...prev, ...temMessages]); setLoading(false); return mathNewMessages; } catch (error) { console.error(error); } }; //发送私信功能 const onSend = useCallback( async (message, lastId, oldArr) => { if (message == "") { // Toast.show({ // icon: "error", // content: "不可发送空内容", // position: "top", // }); return; } //查询历史记录的时候后移一位,防止记录重复 setOffset((prev) => prev + 1); //请求接口发送私信 try { const data = await requireAPI( "POST", "/api/contact_customer_service/create", { body: { session_id: sessionId, predicate: 0, message, }, } ); if (data.ret === -1) { Toast.show({ icon: "error", content: data.msg, position: "top", }); return; } // updateLatestHistory(); // console.log("oldArr", oldArr); updateMessages(lastId, 0, oldArr).then((res) => { setNewMessage(""); toScrollBottom.current = 1; }); } catch (error) { console.error(error); } // //每次发送都缓存信息到本地 // addArr(`${selfData.mid}_to_${params.mid}_messages`, messages); }, [userInfo, sessionId] ); // async function doRefresh() { // await sleep(1000); // Toast.show({ // icon: "fail", // content: "刷新失败", // }); // throw new Error("刷新失败"); // } async function loadMore() { if (sessionId && userInfo.mid && offset && more) { const append = await loadEarlierHistory(); if (append) { // setMessages((val) => [...val, ...append]); setMessages(append); // setHasMore(append.length > 0); } } } const handleData = (list) => { // console.log("list", list); const account = get("account"); const temMessages = list.map((item) => { if (item.predicate === 0) { return { predicate: item.predicate, _id: item.id, // createdAt: new Date(item.ct * 1000).toISOString(), createdAt: item.ct, text: item.message, user: { _id: account?.mid, name: account?.name, avatar: account?.avatar?.images[0]?.urls[0], }, }; } else { return { predicate: item.predicate, _id: item.id, createdAt: item.ct, text: item.message, user: { _id: 0, name: "客服", avatar: process.env.NEXT_PUBLIC_WEB_ASSETS_URL + "/images/icon.png", }, }; } }); // console.log("handledmessages......", handledmessages); // console.log("[...messages, ...temMessages]", temMessages); setHandledmessages(temMessages); setOldMessages(list); let newMessages = temMessages.reverse(); let mathNewMessages = newMessages.reduce( (accumulator, currentValue, index, sourceArray) => { // console.log( // accumulator.time, // "----", // currentValue.createdAt, // "---", // index // ); if (accumulator.time > currentValue.createdAt) { let newData = { ...accumulator, time: accumulator.time, messages: [...accumulator.messages, currentValue], totalArr: index == sourceArray.length - 1 ? [ ...accumulator.totalArr, [...accumulator.messages, currentValue], ] : [...accumulator.totalArr], }; return newData; } else { let newData = { ...accumulator, time: currentValue.createdAt + 60 * 3, messages: [currentValue], totalArr: index == sourceArray.length - 1 ? [ ...accumulator.totalArr, accumulator.messages, [currentValue], ] : [...accumulator.totalArr, accumulator.messages], }; return newData; } }, { time: newMessages[0]?.createdAt + 60 * 3, messages: [], totalArr: [] } ); return mathNewMessages.totalArr; }; const updateMessages = async (lastId, currentOffset, oldArr) => { // console.log("lastId", lastId); try { const data = await requireAPI( "POST", "/api/contact_customer_service/list_by_session_id", { body: { session_id: sessionId, offset: currentOffset, limit: 12, }, } ); if (data.ret === -1) { Toast.show({ icon: "fail", content: data.msg, position: "top", }); return; } let newData = data.data.list.filter((element) => { return element.id > lastId; }); // console.log("[...messages,...newData]", [...newData]); let mathNewMessages = handleData([...newData, ...oldArr]); setMessages((old) => { toScrollBottom.current = 1; return mathNewMessages; }); return; } catch (error) { console.error(error); } }; return (
{!searchParams.get("mid")?"在线客服":messages?.[0]?.[0].user.name}
{formatDeadline(item[0].createdAt)}