diff --git a/app/globals.css b/app/globals.css index 8c56ddb..9f396ef 100644 --- a/app/globals.css +++ b/app/globals.css @@ -123,7 +123,11 @@ body{ background-color: #07050A; color: #ffffff88; } -.adm-jumbo-tabs-header .adm-jumbo-tabs-tab-list{ +.spaceBoxTwo .adm-jumbo-tabs-header .adm-jumbo-tabs-tab-list{ + display: grid; + grid-template-columns: repeat(2, 1fr); +} +.spaceBoxThree .adm-jumbo-tabs-header .adm-jumbo-tabs-tab-list{ display: grid; grid-template-columns: repeat(3, 1fr); } diff --git a/app/messageDetail/page.js b/app/messageDetail/page.js index baa19a6..94ae99b 100644 --- a/app/messageDetail/page.js +++ b/app/messageDetail/page.js @@ -1,22 +1,17 @@ "use client"; -import React, { useState, useCallback, useEffect } from "react"; +import React, { useState, useRef, useEffect, useCallback } from "react"; import baseRequest from "@/utils/baseRequest"; import { generateSignature } from "@/utils/crypto"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faAngleLeft } from "@fortawesome/free-solid-svg-icons"; -import { - Input, - Button, - PullToRefresh, - List, - InfiniteScroll, - Toast -} from "antd-mobile"; +import { Input, Button, Toast, Avatar } from "antd-mobile"; import { useRouter } from "next/navigation"; const blurhash = "LcKUTa%gOYWBYRt6xuoJo~s8V@fk"; - +import { get } from "@/utils/storeInfo"; +import require from "@/utils/require"; +import { formatDeadline } from "@/utils/tools"; /* params格式: { @@ -25,32 +20,117 @@ params格式: */ export default function MessageDetail({}) { - const [hasMore, setHasMore] = useState(true); + // const [hasMore, setHasMore] = useState(true); const router = useRouter(); - const getSession = async () => { - const apiUrl = process.env.EXPO_PUBLIC_API_URL; - try { - const base = baseRequest(); - const account = await get("account"); - const signature = generateSignature({ - mid: account.mid, - ...base, + 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 [offset, setOffset] = useState(0); + const [more, setMore] = useState(1); + const scrollBox = useRef(); + const toScrollBottom = useRef(0); + useEffect(() => { + const userData = get("account"); + setUserInfo(userData); + getSession(userData.mid); + + }, []); + useEffect(() => { + if (toScrollBottom.current) { + scrollBox.current?.scrollTo(0, scrollBox.current.scrollHeight); + toScrollBottom.current = 0; + } + }, [toScrollBottom.current]); + // 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; + }); }); - const detailResponse = await fetch( - `${apiUrl}/api/contact_customer_service_session/list_by_mid?signature=${signature}`, - { - method: "POST", - headers: { - "Content-Type": "application/json", + } + const intervalId = setInterval(() => { + updateMessages(); + }, 3000); // 间隔时间为3秒 + + // 在组件卸载时清除定时器 + return () => { + clearInterval(intervalId); + }; + }, [sessionId]); + //查询session + const getSession = async (mid) => { + try { + const data = + await require("POST", "/api/contact_customer_service_session/list_by_mid", { + body: { + mid: Number(mid), }, - body: JSON.stringify({ - mid: account.mid, - ...base, - }), - } - ); - const detailData = await detailResponse.json(); - if (detailData.ret === -1) { + }); + if (data.ret === -1) { + Toast.show({ + icon: "fail", + content: data.msg, + position: "top", + }); + } + if (data.data.session) { + setSessionId(data.data.session.id); + return; + } + } catch (error) { + console.error(error); + } + }; + //创建session + const createSession = async () => { + try { + const data = + await require("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); + } catch (error) { + console.error(error); + } + }; + //请求历史记录 + const loadEarlierHistory = async () => { + if (!more) return; + try { + const data = + await require("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, @@ -58,29 +138,198 @@ export default function MessageDetail({}) { }); return; } - if (detailData.data.session) { - setSessionId(detailData.data.session.id); - return; - } + setOffset(data.data.offset); + setMore(data.data.more); + let mathNewMessages = handleData(data.data.list); + // setMessages((prev) => [...prev, ...temMessages]); + return mathNewMessages; } catch (error) { console.error(error); } }; - async function doRefresh() { - await sleep(1000); - Toast.show({ - icon: "fail", - content: "刷新失败", - }); - throw new Error("刷新失败"); - } + //发送私信功能 + const onSend = useCallback( + async (message, lastId, oldArr) => { + if (message == "") { + Toast.show({ + icon: "error", + content: "不可发送空内容", + position: "top", + }); + return; + } + + //如果是第一次发送,需要创建session + if (!sessionId) await createSession(); + + //查询历史记录的时候后移一位,防止记录重复 + setOffset((prev) => prev + 1); + //请求接口发送私信 + try { + const data = + await require("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); + } 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() { - const append = await mockRequest(); - setData((val) => [...val, ...append]); - setHasMore(append.length > 0); + 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: "images/icon.png", + }, + }; + } + }); + // console.log("[...messages, ...temMessages]", [ + // ...handledmessages, + // ...temMessages, + // ]); + setHandledmessages([...handledmessages, ...temMessages]); + setOldMessages([...oldMessages, ...list]); + let newMessages = [...handledmessages, ...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 require("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]); + let mathNewMessages = handleData([...newData, ...oldArr]); + setMessages((old) => { + toScrollBottom.current = 1; + setNewMessage(""); + return mathNewMessages; + }); + } catch (error) { + console.error(error); + } + }; return ( -
+ {more ? "查看更早" : "无更早消息"} +
++ {formatDeadline(item[0].createdAt)} +
+0/299
*/}空间设置
测试账号
-{streamerInfo?.name}
+