"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({ list: [], isGetHistory: false, }); 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 [sendding, setSendding] = 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(() => { // debugger; // console.log("oldMessages[0]", oldMessages[0]); if (oldMessages.list[0]) { updateMessages(oldMessages.list[0]?.id, 0, oldMessages.list); // toScrollBottom.current = 1; } }, 3000); // 间隔时间为3秒 // 在组件卸载时清除定时器 return () => { clearInterval(intervalId); }; }, [oldMessages.list]); useEffect(() => { // debugger; if (toScrollBottom.current && !oldMessages.isGetHistory) { scrollBox.current?.scrollTo(0, scrollBox.current.scrollHeight + 50); toScrollBottom.current = 0; } }, [oldMessages.list, oldMessages.isGetHistory]); useEffect(() => { if (typeof sessionId === "number" && 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; } const data2 = await requireAPI( "POST", "/api/contact_customer_service/read_all", { body: { session_id: sessionId, }, } ); if (data2.ret === -1) { Toast.show({ icon: "fail", content: data2.msg, position: "top", }); return; } setOffset(data.data.offset); setMore(data.data.more); let mathNewMessages = handleData( [...oldMessages.list, ...data.data.list], oldMessages.list.length > 0 ); // 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); //请求接口发送私信 setSendding(true); try { const data = await requireAPI( "POST", "/api/contact_customer_service/create", { body: { session_id: sessionId, predicate: 0, message, }, } ); setSendding(false); if (data.ret === -1) { Toast.show({ icon: "error", content: data.msg, position: "top", }); return; } // updateLatestHistory(); updateMessages(lastId, 0, oldArr).then((res) => { setNewMessage(""); toScrollBottom.current = 1; }); } catch (error) { // console.error(error); setSendding(false); } // //每次发送都缓存信息到本地 // 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 (typeof sessionId === "number" && userInfo.mid && offset && more) { const append = await loadEarlierHistory(); if (append) { // setMessages((val) => [...val, ...append]); setMessages(append); // setHasMore(append.length > 0); } } } const handleData = (list, isGetHistory) => { // 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, m_type: item.m_type, 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, m_type: item.m_type, user: { _id: 0, name: "客服", avatar: process.env.NEXT_PUBLIC_WEB_ASSETS_URL + "/images/icon_border.png", }, }; } }); // console.log("handledmessages......", handledmessages); // console.log("[...messages, ...temMessages]", temMessages); setHandledmessages(temMessages); setOldMessages((old) => { // debugger; if (old.list.length === list.length) { return old; } else { // debugger; return { list, isGetHistory: !!isGetHistory }; } }); 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, oldArr); const newMessages = [...newData, ...oldArr].filter( (item, index, self) => index === self.findIndex((t) => t.id === item.id) ); let mathNewMessages = handleData([...newMessages]); setMessages((old) => { toScrollBottom.current = 1; return mathNewMessages; }); if (mathNewMessages.length > messages.length) { const data2 = await requireAPI( "POST", "/api/contact_customer_service/read_all", { body: { session_id: sessionId, }, } ); if (data2.ret === -1) { Toast.show({ icon: "fail", content: data2.msg, position: "top", }); return; } } return; } catch (error) { console.error(error); } }; const getAutoMessage = useCallback( (data) => { if (data.m_type === 1) { const autoAnswerStrs = data.text.split("|"); const btns = autoAnswerStrs[1].split(","); return (
{autoAnswerStrs[0]}
{!searchParams.get("mid") ? "在线客服" : messages?.[0]?.[0].user.name}
{formatDeadline(item[0].createdAt)}