tiefen_space_h5/app/messageDetail/page.js

442 lines
13 KiB
JavaScript
Raw Normal View History

2024-07-03 19:59:39 +08:00
"use client";
2024-07-11 23:57:26 +08:00
import React, { useState, useRef, useEffect, useCallback } from "react";
2024-07-03 19:59:39 +08:00
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faAngleLeft } from "@fortawesome/free-solid-svg-icons";
2024-07-12 22:52:48 +08:00
import { Input, Button, Toast, Avatar, DotLoading } from "antd-mobile";
2024-07-03 19:59:39 +08:00
import { useRouter } from "next/navigation";
2024-07-11 23:57:26 +08:00
import { get } from "@/utils/storeInfo";
import require from "@/utils/require";
import { formatDeadline } from "@/utils/tools";
2024-07-03 19:59:39 +08:00
/*
params格式
{
mid: item.mid,
}
*/
export default function MessageDetail({}) {
2024-07-11 23:57:26 +08:00
// const [hasMore, setHasMore] = useState(true);
2024-07-03 19:59:39 +08:00
const router = useRouter();
2024-07-11 23:57:26 +08:00
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("");
2024-07-12 22:52:48 +08:00
const [loading, setLoading] = useState(false);
2024-07-11 23:57:26 +08:00
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);
}, []);
2024-07-12 22:52:48 +08:00
useEffect(() => {
const intervalId = setInterval(() => {
// console.log("oldMessages[0]", oldMessages[0]);
if (oldMessages[0]) {
updateMessages(oldMessages[0]?.id, 0, oldMessages);
// toScrollBottom.current = 1;
2024-07-12 22:52:48 +08:00
}
}, 3000); // 间隔时间为3秒
// 在组件卸载时清除定时器
return () => {
clearInterval(intervalId);
};
}, [oldMessages]);
2024-07-11 23:57:26 +08:00
useEffect(() => {
if (toScrollBottom.current) {
2024-07-12 22:52:48 +08:00
scrollBox.current?.scrollTo(0, scrollBox.current.scrollHeight+50);
2024-07-11 23:57:26 +08:00
toScrollBottom.current = 0;
}
2024-07-15 20:00:44 +08:00
}, [messages]);
2024-07-11 23:57:26 +08:00
// 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;
});
2024-07-03 19:59:39 +08:00
});
2024-07-11 23:57:26 +08:00
}
}, [sessionId]);
//查询session
const getSession = async (mid) => {
setLoading(true)
2024-07-11 23:57:26 +08:00
try {
const data =
await require("POST", "/api/contact_customer_service_session/list_by_mid", {
body: {
mid: Number(mid),
2024-07-03 19:59:39 +08:00
},
2024-07-11 23:57:26 +08:00
});
if (data.ret === -1) {
2024-07-03 19:59:39 +08:00
Toast.show({
2024-07-06 11:05:19 +08:00
icon: "fail",
content: data.msg,
position: "top",
2024-07-03 19:59:39 +08:00
});
2024-07-11 23:57:26 +08:00
}
setLoading(false)
2024-07-11 23:57:26 +08:00
if (data.data.session) {
setSessionId(data.data.session.id);
2024-07-03 19:59:39 +08:00
return;
}
2024-07-11 23:57:26 +08:00
} catch (error) {
console.error(error);
}
};
//创建session
const createSession = async () => {
setLoading(true)
2024-07-11 23:57:26 +08:00
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);
setLoading(false)
2024-07-11 23:57:26 +08:00
} catch (error) {
console.error(error);
}
};
//请求历史记录
const loadEarlierHistory = async () => {
if (!more) return;
try {
2024-07-12 22:52:48 +08:00
setLoading(true)
2024-07-11 23:57:26 +08:00
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,
position: "top",
});
2024-07-03 19:59:39 +08:00
return;
}
2024-07-11 23:57:26 +08:00
setOffset(data.data.offset);
setMore(data.data.more);
2024-07-12 22:52:48 +08:00
let mathNewMessages = handleData([...oldMessages,...data.data.list]);
2024-07-11 23:57:26 +08:00
// setMessages((prev) => [...prev, ...temMessages]);
2024-07-12 22:52:48 +08:00
setLoading(false)
2024-07-11 23:57:26 +08:00
return mathNewMessages;
2024-07-03 19:59:39 +08:00
} catch (error) {
console.error(error);
}
};
2024-07-11 23:57:26 +08:00
//发送私信功能
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();
2024-07-12 22:52:48 +08:00
// console.log("oldArr", oldArr);
updateMessages(lastId, 0, oldArr).then(res=>{
setNewMessage("");
toScrollBottom.current = 1;
});
2024-07-11 23:57:26 +08:00
} 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("刷新失败");
// }
2024-07-03 19:59:39 +08:00
async function loadMore() {
2024-07-11 23:57:26 +08:00
if (sessionId && userInfo.mid && offset && more) {
const append = await loadEarlierHistory();
if (append) {
// setMessages((val) => [...val, ...append]);
setMessages(append);
// setHasMore(append.length > 0);
}
}
2024-07-03 19:59:39 +08:00
}
2024-07-11 23:57:26 +08:00
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",
},
};
}
});
2024-07-12 22:52:48 +08:00
// console.log("handledmessages......", handledmessages);
// console.log("[...messages, ...temMessages]", temMessages);
setHandledmessages(temMessages);
setOldMessages(list);
let newMessages = temMessages.reverse();
2024-07-11 23:57:26 +08:00
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) => {
2024-07-12 22:52:48 +08:00
// console.log("lastId", lastId);
2024-07-11 23:57:26 +08:00
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;
});
2024-07-12 22:52:48 +08:00
// console.log("[...messages,...newData]", [...newData]);
let mathNewMessages = handleData([...newData,...oldArr]);
2024-07-11 23:57:26 +08:00
setMessages((old) => {
toScrollBottom.current = 1;
return mathNewMessages;
});
2024-07-12 22:52:48 +08:00
return
2024-07-11 23:57:26 +08:00
} catch (error) {
console.error(error);
}
};
2024-07-03 19:59:39 +08:00
return (
2024-07-11 23:57:26 +08:00
<div className="bg-[#13121F] h-screen overflow-y-auto" ref={scrollBox}>
2024-07-03 19:59:39 +08:00
<div className="p-4 fixed top-0 z-10 w-full bg-black">
<div className="flex items-center justify-center absolute">
<FontAwesomeIcon
icon={faAngleLeft}
size="xl"
onClick={() => {
router.back();
}}
/>
</div>
2024-07-15 20:00:44 +08:00
<p className="text-base text-center">在线客服</p>
2024-07-03 19:59:39 +08:00
</div>
<div>
2024-07-11 23:57:26 +08:00
<div className="my-[57px]">
<div className="flex justify-center py-2">
2024-07-12 22:52:48 +08:00
<div
2024-07-11 23:57:26 +08:00
className="px-3 py-2 rounded-full bg-[#FFFFFF1A]"
2024-07-12 22:52:48 +08:00
2024-07-11 23:57:26 +08:00
>
2024-07-12 22:52:48 +08:00
{loading? <DotLoading /> : more ? <span onClick={loadMore}>查看更早</span>:<span></span>}
</div>
2024-07-11 23:57:26 +08:00
</div>
<ul className="py-2">
{messages?.map((item, index) => (
<li key={index}>
<p className="my-2 text-center">
{formatDeadline(item[0].createdAt)}
</p>
<ul className="px-4 overflow-y-auto scrollbarBox_hidden">
{item.map((it) => (
<li key={it?._id} className="py-3 rounded-lg ">
<div className="flex w-full">
{it?.predicate == 1 ? (
<div className="flex justify-start w-full items-center">
<Avatar
className="mr-2"
style={{ "--border-radius": "50px" }}
width={32}
height={32}
src={it?.user.avatar}
/>
<div
className="block rounded-lg py-2 px-3 bg-blue-500"
style={{ borderTopLeftRadius: 0 }}
>
{it?.text}
</div>
</div>
) : (
<div className="flex justify-end w-full items-center">
<div
className="block rounded-lg py-2 px-3 bg-blue-500"
style={{ borderTopRightRadius: 0 }}
>
{it?.text}
</div>
<Avatar
className="ml-2"
style={{ "--border-radius": "50px" }}
width={32}
height={32}
src={it?.user?.avatar}
/>
</div>
)}
</div>
</li>
))}
</ul>
</li>
))}
{}
{/* <InfiniteScroll loadMore={loadMore} hasMore={more} /> */}
</ul>
2024-07-03 19:59:39 +08:00
</div>
2024-07-11 23:57:26 +08:00
<div className="w-full h-16 fixed bottom-0 grid grid-cols-[1fr_68px] bg-black items-center p-2 border-t-2 border-[#ffffff2a]">
2024-07-03 19:59:39 +08:00
<div className="rounded bg-[#222036] px-4 py-2 mr-2">
2024-07-11 23:57:26 +08:00
<Input
placeholder="输入新消息"
className=""
value={newMessage}
onChange={setNewMessage}
/>
2024-07-03 19:59:39 +08:00
</div>
<Button
size="middle"
block
2024-07-11 23:57:26 +08:00
onClick={() => onSend(newMessage, oldMessages[0].id, oldMessages)}
2024-07-03 19:59:39 +08:00
style={{ "--background-color": "#FF669E", color: "#FFFFFF" }}
>
发送
</Button>
</div>
</div>
</div>
);
}