|
@@ -1,9 +1,9 @@
|
|
"use client";
|
|
"use client";
|
|
-import { getApiUrl } from "@/utils/common";
|
|
|
|
|
|
+import { getApiUrl, isMobile } from "@/utils/common";
|
|
import { getUserSession } from "@/utils/user";
|
|
import { getUserSession } from "@/utils/user";
|
|
import { useState, useEffect } from "react";
|
|
import { useState, useEffect } from "react";
|
|
import type { PopconfirmProps } from "antd";
|
|
import type { PopconfirmProps } from "antd";
|
|
-import { theme, Popconfirm } from "antd";
|
|
|
|
|
|
+import { theme, Popconfirm, Button, Card, Result } from "antd";
|
|
import { ThemeProvider, css, cx } from "antd-style";
|
|
import { ThemeProvider, css, cx } from "antd-style";
|
|
import { useTheme } from "next-themes";
|
|
import { useTheme } from "next-themes";
|
|
import { ProChat, ProChatInstance } from "@ant-design/pro-chat";
|
|
import { ProChat, ProChatInstance } from "@ant-design/pro-chat";
|
|
@@ -16,12 +16,15 @@ import {
|
|
RiDeleteBinLine,
|
|
RiDeleteBinLine,
|
|
RiCloseFill,
|
|
RiCloseFill,
|
|
RiArrowDropRightLine,
|
|
RiArrowDropRightLine,
|
|
|
|
+ RiDraftLine,
|
|
} from "react-icons/ri";
|
|
} from "react-icons/ri";
|
|
import {
|
|
import {
|
|
getChatSession,
|
|
getChatSession,
|
|
getChatMessage,
|
|
getChatMessage,
|
|
getEmployeeDetail,
|
|
getEmployeeDetail,
|
|
getUserBalance,
|
|
getUserBalance,
|
|
|
|
+ deleteChatSession,
|
|
|
|
+ renameChatSession,
|
|
} from "@/api/client";
|
|
} from "@/api/client";
|
|
import { ChatSessionResult, EmployeeSearchResult } from "@/utils/clientsApis";
|
|
import { ChatSessionResult, EmployeeSearchResult } from "@/utils/clientsApis";
|
|
|
|
|
|
@@ -42,7 +45,7 @@ import {
|
|
Storage_getConversationId,
|
|
Storage_getConversationId,
|
|
} from "@/utils/chat";
|
|
} from "@/utils/chat";
|
|
import { useGlobalContext } from "@/providers/GlobalProvider";
|
|
import { useGlobalContext } from "@/providers/GlobalProvider";
|
|
-import VipPage from "@/app/vip/page";
|
|
|
|
|
|
+import VipBoxPage from "@/app/vip-box/page";
|
|
|
|
|
|
export default function Dialogue() {
|
|
export default function Dialogue() {
|
|
const themeBig = useTheme();
|
|
const themeBig = useTheme();
|
|
@@ -57,12 +60,14 @@ export default function Dialogue() {
|
|
|
|
|
|
const [chatAiModelList, setChatAiModelList] = useState<ChatAiModel[]>([]);
|
|
const [chatAiModelList, setChatAiModelList] = useState<ChatAiModel[]>([]);
|
|
const [chatSessionLastId, setChatSessionLastId] = useState<string>("");
|
|
const [chatSessionLastId, setChatSessionLastId] = useState<string>("");
|
|
|
|
+ const [chatSessionRenameId, setChatSessionRenameId] = useState<string>("");
|
|
const [chatSessionList, setChatSessionList] = useState<ChatSessionResult[]>(
|
|
const [chatSessionList, setChatSessionList] = useState<ChatSessionResult[]>(
|
|
[]
|
|
[]
|
|
);
|
|
);
|
|
const [showVip, setShowVip] = useState(false);
|
|
const [showVip, setShowVip] = useState(false);
|
|
const [showLeftBox, setShowLeftBox] = useState(false);
|
|
const [showLeftBox, setShowLeftBox] = useState(false);
|
|
const [balance, setBalance] = useState<number>(0);
|
|
const [balance, setBalance] = useState<number>(0);
|
|
|
|
+ const [rename, setRename] = useState<string>("");
|
|
|
|
|
|
//历史记录和智能体列表 显示隐藏
|
|
//历史记录和智能体列表 显示隐藏
|
|
const handlShowLeftLetter = () => {
|
|
const handlShowLeftLetter = () => {
|
|
@@ -133,21 +138,22 @@ export default function Dialogue() {
|
|
//新对话
|
|
//新对话
|
|
const newChat = () => {
|
|
const newChat = () => {
|
|
var newConversationId = "guid_0000_" + new Date().getTime();
|
|
var newConversationId = "guid_0000_" + new Date().getTime();
|
|
- setChatSessionList((chatSessionList) => [
|
|
|
|
- ...[
|
|
|
|
- {
|
|
|
|
- id: newConversationId,
|
|
|
|
- name: "新对话",
|
|
|
|
- createdAt: new Date().getTime(),
|
|
|
|
- inputs: {},
|
|
|
|
- },
|
|
|
|
- ],
|
|
|
|
- ...chatSessionList,
|
|
|
|
- ]);
|
|
|
|
- Storage_setListType(0);
|
|
|
|
|
|
+ // setChatSessionList((chatSessionList) => [
|
|
|
|
+ // ...[
|
|
|
|
+ // {
|
|
|
|
+ // id: newConversationId,
|
|
|
|
+ // name: "新对话",
|
|
|
|
+ // createdAt: new Date().getTime(),
|
|
|
|
+ // inputs: {},
|
|
|
|
+ // },
|
|
|
|
+ // ],
|
|
|
|
+ // ...chatSessionList,
|
|
|
|
+ // ]);
|
|
|
|
+ Storage_setListType(1);
|
|
Storage_setConversationId(newConversationId);
|
|
Storage_setConversationId(newConversationId);
|
|
setHistoryOrChatList(0);
|
|
setHistoryOrChatList(0);
|
|
setShowComponent(false);
|
|
setShowComponent(false);
|
|
|
|
+ setHistoryOrChatList(1);
|
|
setIniChatMessage([]);
|
|
setIniChatMessage([]);
|
|
setTimeout(() => {
|
|
setTimeout(() => {
|
|
setShowComponent(true);
|
|
setShowComponent(true);
|
|
@@ -181,7 +187,7 @@ export default function Dialogue() {
|
|
//加载助手对应的历史会话
|
|
//加载助手对应的历史会话
|
|
const loadChatSession = (agentId: number, last_id: string) => {
|
|
const loadChatSession = (agentId: number, last_id: string) => {
|
|
setTimeout(() => {
|
|
setTimeout(() => {
|
|
- setShowComponent(false);
|
|
|
|
|
|
+ //setShowComponent(false);
|
|
getChatSession({ agentId: agentId, last_id: last_id, limit: 100 }).then(
|
|
getChatSession({ agentId: agentId, last_id: last_id, limit: 100 }).then(
|
|
(data) => {
|
|
(data) => {
|
|
if (data.code === 0 && data.data.data !== null) {
|
|
if (data.code === 0 && data.data.data !== null) {
|
|
@@ -196,7 +202,7 @@ export default function Dialogue() {
|
|
} else {
|
|
} else {
|
|
setChatSessionList([]);
|
|
setChatSessionList([]);
|
|
}
|
|
}
|
|
- setShowComponent(true);
|
|
|
|
|
|
+ //setShowComponent(true);
|
|
}
|
|
}
|
|
);
|
|
);
|
|
});
|
|
});
|
|
@@ -221,6 +227,46 @@ export default function Dialogue() {
|
|
}
|
|
}
|
|
});
|
|
});
|
|
};
|
|
};
|
|
|
|
+ //删除聊天会话
|
|
|
|
+ const confirmDeletChatSession = (id: string) => {
|
|
|
|
+ deleteChatSession({
|
|
|
|
+ conversationId: id,
|
|
|
|
+ agentId: Storage_getAgentId(),
|
|
|
|
+ }).then((res) => {
|
|
|
|
+ if (res.code == 0) {
|
|
|
|
+ if (id == Storage_getConversationId()) {
|
|
|
|
+ newChat();
|
|
|
|
+ }
|
|
|
|
+ setChatSessionList(chatSessionList.filter((v) => v.id !== id));
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ };
|
|
|
|
+ //重命名聊天会话
|
|
|
|
+ const renameChatSessionUi = (id: string, name: string) => {
|
|
|
|
+ renameChatSession({
|
|
|
|
+ conversationId: id,
|
|
|
|
+ agentId: Storage_getAgentId(),
|
|
|
|
+ name: name,
|
|
|
|
+ }).then((res) => {
|
|
|
|
+ if (res.code == 0) {
|
|
|
|
+ setChatSessionList(
|
|
|
|
+ chatSessionList.map((v) => (v.id === id ? { ...v, name: name } : v))
|
|
|
|
+ );
|
|
|
|
+ setChatSessionRenameId("");
|
|
|
|
+ setRename("");
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ };
|
|
|
|
+ //开启重命名输入框
|
|
|
|
+ const editChatSessionRenameId = (id: string, name: string) => {
|
|
|
|
+ if (chatSessionRenameId === id) {
|
|
|
|
+ setChatSessionRenameId("");
|
|
|
|
+ setRename("");
|
|
|
|
+ } else {
|
|
|
|
+ setChatSessionRenameId(id);
|
|
|
|
+ setRename(name);
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
|
|
useEffect(() => {
|
|
useEffect(() => {
|
|
changeMenuIndex(1);
|
|
changeMenuIndex(1);
|
|
@@ -272,7 +318,7 @@ export default function Dialogue() {
|
|
loadChatSession(agentId, chatSessionLastId);
|
|
loadChatSession(agentId, chatSessionLastId);
|
|
|
|
|
|
getBalance();
|
|
getBalance();
|
|
- }, [loginShow, chatSessionLastId]);
|
|
|
|
|
|
+ }, [loginShow]);
|
|
|
|
|
|
//样式覆盖
|
|
//样式覆盖
|
|
const BarkCustomClassName = cx(
|
|
const BarkCustomClassName = cx(
|
|
@@ -373,6 +419,15 @@ export default function Dialogue() {
|
|
setShowVip(false);
|
|
setShowVip(false);
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+ const NeedBuyVip = () => {
|
|
|
|
+ return (
|
|
|
|
+ <>
|
|
|
|
+ 当前智能体需要会员才能使用,去开通:
|
|
|
|
+ <a onClick={() => setShowVip(true)}>会员套餐</a>
|
|
|
|
+ </>
|
|
|
|
+ );
|
|
|
|
+ };
|
|
|
|
+
|
|
return (
|
|
return (
|
|
<>
|
|
<>
|
|
<div className="flex justify-between items-center bg-[slate-200] dark:bg-[#000] h-full">
|
|
<div className="flex justify-between items-center bg-[slate-200] dark:bg-[#000] h-full">
|
|
@@ -440,19 +495,64 @@ export default function Dialogue() {
|
|
<div
|
|
<div
|
|
className="w-full mt-3 cursor-pointer"
|
|
className="w-full mt-3 cursor-pointer"
|
|
key={item.id}
|
|
key={item.id}
|
|
- onClick={() => changeChatSession(item.id)}
|
|
|
|
>
|
|
>
|
|
<div
|
|
<div
|
|
- className={`flex rounded border ${
|
|
|
|
|
|
+ className={`flex rounded border group ${
|
|
Storage_getConversationId() == item.id &&
|
|
Storage_getConversationId() == item.id &&
|
|
Storage_getListType() === historyOrChatList
|
|
Storage_getListType() === historyOrChatList
|
|
? "dark:border-[#0061ff] bg-blue-50 dark:bg-gray-800 text-[#0061ff]"
|
|
? "dark:border-[#0061ff] bg-blue-50 dark:bg-gray-800 text-[#0061ff]"
|
|
: "border-gray-200 dark:border-gray-700 text-gray-600 dark:text-gray-400"
|
|
: "border-gray-200 dark:border-gray-700 text-gray-600 dark:text-gray-400"
|
|
} p-3 sm:flex-row flex-col`}
|
|
} p-3 sm:flex-row flex-col`}
|
|
>
|
|
>
|
|
- <div className="flex-grow text-ellipsis line-clamp-2">
|
|
|
|
- <h2 className="pb-2">{item.name}</h2>
|
|
|
|
- <p className="text-sm text-gray-400">
|
|
|
|
|
|
+ <div className="flex-grow text-ellipsis line-clamp-2 relative">
|
|
|
|
+ <Popconfirm
|
|
|
|
+ title="删除提醒"
|
|
|
|
+ description="确定删除当前历史会话吗?"
|
|
|
|
+ onConfirm={() =>
|
|
|
|
+ confirmDeletChatSession(item.id)
|
|
|
|
+ }
|
|
|
|
+ okText="确定"
|
|
|
|
+ cancelText="取消"
|
|
|
|
+ >
|
|
|
|
+ <RiDeleteBinLine className="absolute top-0.5 right-0.5 cursor-pointer group-hover:block hidden" />
|
|
|
|
+ </Popconfirm>
|
|
|
|
+ <RiDraftLine
|
|
|
|
+ className="absolute top-0.5 right-6 cursor-pointer group-hover:block hidden"
|
|
|
|
+ onClick={() =>
|
|
|
|
+ editChatSessionRenameId(item.id, item.name)
|
|
|
|
+ }
|
|
|
|
+ />
|
|
|
|
+
|
|
|
|
+ {chatSessionRenameId && (
|
|
|
|
+ <p>
|
|
|
|
+ <input
|
|
|
|
+ value={rename}
|
|
|
|
+ onChange={(e) => setRename(e.target.value)}
|
|
|
|
+ onKeyDown={(e) => {
|
|
|
|
+ if (e.key === "Enter") {
|
|
|
|
+ renameChatSessionUi(item.id, rename);
|
|
|
|
+ }
|
|
|
|
+ if (e.key === "Escape") {
|
|
|
|
+ setChatSessionRenameId("");
|
|
|
|
+ setRename("");
|
|
|
|
+ }
|
|
|
|
+ }}
|
|
|
|
+ className="h-8 bg-gray-50 dark:bg-[#202123] bg-opacity-50 rounded border border-gray-300 dark:border-slate-700 text-base outline-none text-gray-700 py-1 leading-8 transition-colors duration-200 ease-in-out"
|
|
|
|
+ />
|
|
|
|
+ </p>
|
|
|
|
+ )}
|
|
|
|
+ {!chatSessionRenameId && (
|
|
|
|
+ <h2
|
|
|
|
+ className="pb-2"
|
|
|
|
+ onClick={() => changeChatSession(item.id)}
|
|
|
|
+ >
|
|
|
|
+ {item.name}
|
|
|
|
+ </h2>
|
|
|
|
+ )}
|
|
|
|
+ <p
|
|
|
|
+ className="text-sm text-gray-400"
|
|
|
|
+ onClick={() => changeChatSession(item.id)}
|
|
|
|
+ >
|
|
{new Date(item.createdAt).toLocaleString()}
|
|
{new Date(item.createdAt).toLocaleString()}
|
|
</p>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
@@ -481,8 +581,7 @@ export default function Dialogue() {
|
|
<div className="w-full mt-3" key={item.id}>
|
|
<div className="w-full mt-3" key={item.id}>
|
|
<div
|
|
<div
|
|
className={`flex rounded border group ${
|
|
className={`flex rounded border group ${
|
|
- Storage_getAgentId() == item.id &&
|
|
|
|
- Storage_getListType() === historyOrChatList
|
|
|
|
|
|
+ Storage_getAgentId() == item.id
|
|
? "dark:border-[#0061ff] bg-blue-50 dark:bg-gray-800 text-[#0061ff]"
|
|
? "dark:border-[#0061ff] bg-blue-50 dark:bg-gray-800 text-[#0061ff]"
|
|
: "border-gray-200 dark:border-gray-700 text-gray-600 dark:text-gray-400"
|
|
: "border-gray-200 dark:border-gray-700 text-gray-600 dark:text-gray-400"
|
|
} p-3 sm:flex-row flex-col`}
|
|
} p-3 sm:flex-row flex-col`}
|
|
@@ -584,19 +683,32 @@ export default function Dialogue() {
|
|
//helloMessage ={helloMessage}
|
|
//helloMessage ={helloMessage}
|
|
actions={{
|
|
actions={{
|
|
render: (defaultDoms) => {
|
|
render: (defaultDoms) => {
|
|
- if (showLeftLetter) {
|
|
|
|
- return defaultDoms;
|
|
|
|
|
|
+ if (isMobile()) {
|
|
|
|
+ return [
|
|
|
|
+ <a
|
|
|
|
+ key="handlShowLeftBox"
|
|
|
|
+ className="text-gray-400 hover:text-blue-600"
|
|
|
|
+ onClick={() => setShowLeftBox(true)}
|
|
|
|
+ >
|
|
|
|
+ <RiBookReadLine className="text-2xl" />
|
|
|
|
+ </a>,
|
|
|
|
+ ...defaultDoms,
|
|
|
|
+ ];
|
|
|
|
+ } else {
|
|
|
|
+ if (showLeftLetter) {
|
|
|
|
+ return defaultDoms;
|
|
|
|
+ }
|
|
|
|
+ return [
|
|
|
|
+ <a
|
|
|
|
+ key="handlShowLeftLetter"
|
|
|
|
+ className="text-gray-400 hover:text-blue-600"
|
|
|
|
+ onClick={handlShowLeftLetter}
|
|
|
|
+ >
|
|
|
|
+ <RiBookReadLine className="text-2xl" />
|
|
|
|
+ </a>,
|
|
|
|
+ ...defaultDoms,
|
|
|
|
+ ];
|
|
}
|
|
}
|
|
- return [
|
|
|
|
- <a
|
|
|
|
- key="handlShowLeftLetter"
|
|
|
|
- className="text-gray-400 hover:text-blue-600"
|
|
|
|
- onClick={handlShowLeftLetter}
|
|
|
|
- >
|
|
|
|
- <RiBookReadLine className="text-2xl" />
|
|
|
|
- </a>,
|
|
|
|
- ...defaultDoms,
|
|
|
|
- ];
|
|
|
|
},
|
|
},
|
|
flexConfig: {
|
|
flexConfig: {
|
|
gap: 24,
|
|
gap: 24,
|
|
@@ -604,6 +716,13 @@ export default function Dialogue() {
|
|
justify: "space-start",
|
|
justify: "space-start",
|
|
},
|
|
},
|
|
}}
|
|
}}
|
|
|
|
+ chatItemRenderConfig={{
|
|
|
|
+ contentRender: (item) => {
|
|
|
|
+ if (item?.originData?.role === "need_pay") {
|
|
|
|
+ return <NeedBuyVip />;
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ }}
|
|
request={async (messages) => {
|
|
request={async (messages) => {
|
|
const response = await fetch(
|
|
const response = await fetch(
|
|
getApiUrl() + "/gpts/chat/submit",
|
|
getApiUrl() + "/gpts/chat/submit",
|
|
@@ -662,19 +781,20 @@ export default function Dialogue() {
|
|
if (parsed.finish) {
|
|
if (parsed.finish) {
|
|
setConversationId(parsed.conversation_id);
|
|
setConversationId(parsed.conversation_id);
|
|
getBalance();
|
|
getBalance();
|
|
|
|
+ loadChatSession(Storage_getAgentId(), "");
|
|
}
|
|
}
|
|
if (parsed.need_login) {
|
|
if (parsed.need_login) {
|
|
- changeLoginShow(true);
|
|
|
|
controller.enqueue(
|
|
controller.enqueue(
|
|
encoder.encode("请登录后使用")
|
|
encoder.encode("请登录后使用")
|
|
);
|
|
);
|
|
|
|
+ setTimeout(() => {changeLoginShow(true);}, 200);
|
|
} else if (parsed.need_pay) {
|
|
} else if (parsed.need_pay) {
|
|
controller.enqueue(
|
|
controller.enqueue(
|
|
encoder.encode(
|
|
encoder.encode(
|
|
- "当前智能体需要会员才能使用,去开通:[会员套餐](/vip)"
|
|
|
|
|
|
+ "当前智能体需要会员才能使用"
|
|
)
|
|
)
|
|
);
|
|
);
|
|
- setShowVip(true);
|
|
|
|
|
|
+ setTimeout(() => {setShowVip(true);}, 200);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -777,15 +897,6 @@ export default function Dialogue() {
|
|
)}
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
|
|
- <div
|
|
|
|
- className="absolute -left-5 top-1/2 transform -translate-y-1/2 rounded-full bg-[#ecf1f9] p-1 shadow-lg md:hidden block dark:bg-blue-950"
|
|
|
|
- onClick={() => {
|
|
|
|
- setShowLeftBox(true);
|
|
|
|
- }}
|
|
|
|
- >
|
|
|
|
- <RiArrowDropRightLine className="text-3xl text-[#0061ff] ml-3" />
|
|
|
|
- </div>
|
|
|
|
-
|
|
|
|
{showLeftBox && (
|
|
{showLeftBox && (
|
|
<div className="pay-box">
|
|
<div className="pay-box">
|
|
<div className="pay-mask"></div>
|
|
<div className="pay-mask"></div>
|
|
@@ -985,13 +1096,13 @@ export default function Dialogue() {
|
|
{showVip && (
|
|
{showVip && (
|
|
<div className="pay-box">
|
|
<div className="pay-box">
|
|
<div className="pay-mask"></div>
|
|
<div className="pay-mask"></div>
|
|
- <div className="pay-div pt-12 md:p-7 bg-white dark:bg-gray-900 text-base rounded w-full md:container h-screen">
|
|
|
|
|
|
+ <div className="pay-div pt-12 md:p-7 bg-white dark:bg-gray-900 text-base rounded w-full md:h-5/6 md:container h-screen">
|
|
<RiCloseFill
|
|
<RiCloseFill
|
|
className="absolute right-2.5 top-2.5 w-8 h-8 cursor-pointer transform duration-500 ease-in-out hover:scale-125 text-gray-500"
|
|
className="absolute right-2.5 top-2.5 w-8 h-8 cursor-pointer transform duration-500 ease-in-out hover:scale-125 text-gray-500"
|
|
onClick={closeVipBox}
|
|
onClick={closeVipBox}
|
|
></RiCloseFill>
|
|
></RiCloseFill>
|
|
<div className="h-full overflow-y-auto">
|
|
<div className="h-full overflow-y-auto">
|
|
- <VipPage></VipPage>
|
|
|
|
|
|
+ <VipBoxPage></VipBoxPage>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|