3712 lines
142 KiB
HTML
Executable File
3712 lines
142 KiB
HTML
Executable File
<!DOCTYPE html>
|
||
<html lang="zh">
|
||
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0,user-scalable=no" />
|
||
<meta http-equiv="Cache-Control" content="no-store, no-cache, must-revalidate">
|
||
<meta http-equiv="Pragma" content="no-cache">
|
||
<meta http-equiv="Expires" content="Thu, 01 Jan 1970 00:00:00 GMT">
|
||
<meta property=" og:title" content="飒沓光伏智能体">
|
||
<meta property="og:description" content="SataBot Agent 是一款由人工智能驱动的光伏场景AI应用程序。">
|
||
<meta property="og:image" content="http://1.95.137.212:19000/mbzn/16%3A33%3A49123.png">
|
||
|
||
<title>飒沓光伏智能体</title>
|
||
<link rel="icon" href="./img/logo.png" type="image/x-icon">
|
||
<!-- <script src=" https://res.wx.qq.com/connect/zh_CN/htmledition/js/wxopensdk.js"> -->
|
||
<!-- </script> -->
|
||
<script src="./marked.min.js"></script>
|
||
|
||
<script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
|
||
<style>
|
||
* {
|
||
touch-action: manipulation;
|
||
/* 允许平移和捏合缩放,但禁用双击缩放和长按 */
|
||
-webkit-tap-highlight-color: transparent;
|
||
/* 移除点击时的默认高亮(可选,优化体验) */
|
||
}
|
||
|
||
body {
|
||
margin: 0;
|
||
font-family: "Segoe UI", "PingFang SC", Arial, sans-serif;
|
||
height: 100vh;
|
||
display: flex;
|
||
background: #f0f6fb;
|
||
color: #333;
|
||
width: 100%;
|
||
|
||
}
|
||
|
||
.toast {
|
||
position: fixed;
|
||
top: 20%;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
background: rgba(0, 0, 0, 0.8);
|
||
color: #fff;
|
||
padding: 10px 18px;
|
||
border-radius: 8px;
|
||
font-size: 15px;
|
||
opacity: 0;
|
||
transition: opacity 0.3s ease;
|
||
z-index: 9999999999;
|
||
}
|
||
|
||
.toast.show {
|
||
opacity: 1;
|
||
}
|
||
|
||
.toast.success {
|
||
background-color: #09db45;
|
||
}
|
||
|
||
|
||
/* 侧边栏 */
|
||
.sidebar {
|
||
width: 240px;
|
||
background: #ffffff;
|
||
border-right: 1px solid #e3eaf2;
|
||
display: flex;
|
||
flex-direction: column;
|
||
transition: all 0.3s ease;
|
||
box-shadow: 2px 0 5px rgba(0, 0, 0, 0.04);
|
||
z-index: 10;
|
||
height: 100%;
|
||
left: 0px;
|
||
transition: all 0.3s ease;
|
||
|
||
}
|
||
|
||
.sidebar.collapsed {
|
||
left: -260px;
|
||
/* width: 0; */
|
||
overflow: hidden;
|
||
position: absolute;
|
||
}
|
||
|
||
.sidebar-header {
|
||
padding: 16px;
|
||
padding-left: 20px;
|
||
font-size: 16px;
|
||
font-weight: bold;
|
||
border-bottom: 1px solid #f0f4f8;
|
||
display: flex;
|
||
justify-content: flex-start;
|
||
}
|
||
|
||
.sidebar-header img {
|
||
width: 24px;
|
||
margin-right: 10px;
|
||
}
|
||
|
||
.sidebar-actions {
|
||
padding: 0px 12px;
|
||
}
|
||
|
||
.sidebar-actions button {
|
||
width: 100%;
|
||
padding: 10px;
|
||
border: none;
|
||
border-radius: 8px;
|
||
background: #f5f5f5;
|
||
color: #000;
|
||
font-size: 14px;
|
||
cursor: pointer;
|
||
transition: background 0.2s;
|
||
}
|
||
|
||
|
||
.chat-list {
|
||
flex: 1;
|
||
overflow-y: auto;
|
||
padding: 0px 10px;
|
||
}
|
||
|
||
.chat-item {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 8px 16px;
|
||
border-bottom: 1px solid #f7f9fb;
|
||
cursor: pointer;
|
||
transition: background 0.2s;
|
||
text-align: center;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.chat-item:hover {
|
||
background: #f2f8fd;
|
||
}
|
||
|
||
.chat-item.active {
|
||
background: #f5f5f5;
|
||
font-weight: bold;
|
||
color: #000;
|
||
border-radius: 8px;
|
||
}
|
||
|
||
.chat-title {
|
||
flex: 1;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.delete-btn {
|
||
margin-left: 8px;
|
||
color: #aaa;
|
||
cursor: pointer;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.delete-btn:hover {
|
||
color: #e74c3c;
|
||
}
|
||
|
||
/* 收起按钮(独立漂浮在左边) */
|
||
.toggle-btn {
|
||
position: fixed;
|
||
display: none;
|
||
justify-content: center;
|
||
align-items: center;
|
||
position: absolute;
|
||
top: 7px;
|
||
left: 10px;
|
||
|
||
color: #fff;
|
||
border: none;
|
||
border-radius: 50%;
|
||
width: 28px;
|
||
height: 28px;
|
||
font-size: 18px;
|
||
cursor: pointer;
|
||
z-index: 20;
|
||
transition: background 0.2s;
|
||
background: transparent !important;
|
||
padding: 5px;
|
||
}
|
||
|
||
.sidebar.collapsed>.toggle-btn {
|
||
position: fixed;
|
||
}
|
||
|
||
.toggle-btn:hover {
|
||
background: #999;
|
||
}
|
||
|
||
/* 右侧聊天区域 */
|
||
.chat-container {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: space-between;
|
||
width: calc(100% - 240px);
|
||
height: 100%;
|
||
background-color: #fff;
|
||
}
|
||
|
||
.chat-input.mobile {
|
||
padding-bottom: 30px;
|
||
}
|
||
|
||
.chat-container .content {
|
||
height: 70%;
|
||
overflow-y: auto;
|
||
scrollbar-width: none;
|
||
/* overflow-y: auto; */
|
||
}
|
||
|
||
.chat-header {
|
||
height: 50px;
|
||
|
||
background: #fff;
|
||
font-size: 16px;
|
||
color: #000;
|
||
display: flex;
|
||
justify-content: center;
|
||
}
|
||
|
||
.chat-header .userinfo {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
gap: 5px;
|
||
color: #666;
|
||
font-weight: 400;
|
||
font-family: fangsong;
|
||
|
||
}
|
||
|
||
.chat-header .userinfo .logout {
|
||
color: #666;
|
||
font-weight: 400;
|
||
font-family: fangsong;
|
||
/* text-decoration: underline; */
|
||
cursor: pointer
|
||
}
|
||
|
||
.price {
|
||
text-decoration: none;
|
||
}
|
||
|
||
.price:hover,
|
||
.logout:hover {
|
||
color: #999 !important;
|
||
}
|
||
|
||
.chat-header .back {
|
||
display: none;
|
||
}
|
||
|
||
.chat-messages {
|
||
flex: 1;
|
||
padding: 20px;
|
||
overflow-y: scroll;
|
||
position: relative;
|
||
height: 100%;
|
||
scrollbar-width: thin;
|
||
}
|
||
|
||
.message {
|
||
|
||
|
||
max-width: 70%;
|
||
margin-bottom: 16px;
|
||
padding: 12px 16px;
|
||
border-radius: 14px;
|
||
font-size: 16px;
|
||
line-height: 1.5;
|
||
/* white-space: pre-wrap;*/
|
||
white-space: normal;
|
||
word-wrap: break-word;
|
||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
|
||
animation: fadeIn 0.3s ease;
|
||
}
|
||
|
||
.message.user {
|
||
display: block;
|
||
background: #d4e5ff;
|
||
color: #000;
|
||
align-self: flex-end;
|
||
border-bottom-right-radius: 4px;
|
||
|
||
display: block;
|
||
width: fit-content;
|
||
}
|
||
|
||
.message.assistant {
|
||
max-width: 100%;
|
||
background: #fff;
|
||
color: #333;
|
||
align-self: flex-start;
|
||
box-shadow: none;
|
||
position: relative;
|
||
padding-left: 0px;
|
||
/* border: 1px solid #e6eaf0;
|
||
border-bottom-left-radius: 4px; */
|
||
}
|
||
|
||
.message.assistant .avatar {
|
||
|
||
width: 22px;
|
||
height: 22px;
|
||
position: absolute;
|
||
left: -10px;
|
||
top: 15px;
|
||
|
||
|
||
}
|
||
|
||
.message img {
|
||
max-width: 200px;
|
||
border-radius: 8px;
|
||
margin-top: 8px;
|
||
}
|
||
|
||
.message.assistant .avatar img {
|
||
|
||
width: 100%;
|
||
height: 100%;
|
||
margin-top: 0px;
|
||
}
|
||
|
||
|
||
.chat-input {
|
||
padding: 12px;
|
||
background: #fff;
|
||
border-top: 1px solid #e3eaf2;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 8px;
|
||
box-shadow: 0 -1px 3px rgba(0, 0, 0, 0.04);
|
||
}
|
||
|
||
.message.thinking {
|
||
width: auto;
|
||
/* 宽度自适应内容 */
|
||
max-width: 40%;
|
||
/* 限制最大宽度 */
|
||
}
|
||
|
||
.input-row {
|
||
display: flex;
|
||
align-items: center;
|
||
flex-direction: column;
|
||
justify-content: space-between;
|
||
gap: 8px;
|
||
}
|
||
|
||
.none {
|
||
display: none;
|
||
}
|
||
|
||
.input-row .img-row {
|
||
width: 100%;
|
||
min-width: 0px;
|
||
min-height: 0px;
|
||
box-sizing: border-box;
|
||
padding: 10px;
|
||
|
||
}
|
||
|
||
.input-row .img-box .delete-btn {
|
||
position: absolute;
|
||
right: -5px;
|
||
top: -5px;
|
||
|
||
}
|
||
|
||
.input-row .img-box {
|
||
width: 40px;
|
||
position: relative
|
||
}
|
||
|
||
|
||
|
||
.input-row img {
|
||
width: 40px;
|
||
height: 40px;
|
||
border-radius: 5px;
|
||
|
||
}
|
||
|
||
|
||
.chat-input textarea {
|
||
flex: 1;
|
||
resize: none;
|
||
padding: 10px;
|
||
border-radius: 20px;
|
||
border: 1px solid #d9e4f0;
|
||
font-size: 14px;
|
||
outline: none;
|
||
background: #f9fcff;
|
||
transition: border 0.2s;
|
||
width: 100%;
|
||
}
|
||
|
||
.chat-input textarea:focus {
|
||
/* border-color: #0057ff; */
|
||
}
|
||
|
||
.chat-input button {
|
||
padding: 10px 16px;
|
||
border: none;
|
||
border-radius: 8px;
|
||
background: #0057ff;
|
||
color: #fff;
|
||
font-size: 14px;
|
||
cursor: pointer;
|
||
transition: background 0.2s;
|
||
}
|
||
|
||
.chat-input button:hover {
|
||
background: #0046cc;
|
||
}
|
||
|
||
.options-row {
|
||
display: flex;
|
||
gap: 10px;
|
||
align-items: center;
|
||
font-size: 13px;
|
||
}
|
||
|
||
select,
|
||
input[type="file"] {
|
||
font-size: 13px;
|
||
padding: 4px 6px;
|
||
border: 1px solid #d9e4f0;
|
||
border-radius: 6px;
|
||
background: #fff;
|
||
}
|
||
|
||
@keyframes fadeIn {
|
||
from {
|
||
opacity: 0;
|
||
transform: translateY(5px);
|
||
}
|
||
|
||
to {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
}
|
||
|
||
|
||
/* 修改后的输入框样式 - 豆包/腾讯元宝风格 */
|
||
.chat-input {
|
||
padding: 16px;
|
||
background: #fff;
|
||
border-top: 1px solid #e8e8e8;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 12px;
|
||
}
|
||
|
||
.input-row {
|
||
display: flex;
|
||
align-items: flex-end;
|
||
justify-content: flex-end;
|
||
/* 底部对齐 */
|
||
gap: 8px;
|
||
border: 1px solid #e5e5e5;
|
||
border-radius: 20px;
|
||
}
|
||
|
||
.input-row .button-row {
|
||
display: flex;
|
||
flex-direction: row;
|
||
align-items: flex-end;
|
||
justify-content: space-between;
|
||
gap: 12px;
|
||
width: 100%;
|
||
margin-right: 10px;
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.input-row .button-row>div {
|
||
cursor: pointer;
|
||
width: 40px;
|
||
height: 40px;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
margin-left: 12px;
|
||
}
|
||
|
||
.chat-input textarea {
|
||
flex: 1;
|
||
resize: none;
|
||
padding: 12px 16px;
|
||
|
||
|
||
font-size: 14px;
|
||
outline: none;
|
||
background: #fff;
|
||
transition: all 0.2s;
|
||
min-height: 44px;
|
||
max-height: 200px;
|
||
box-shadow: none;
|
||
border: none !important;
|
||
box-sizing: border-box
|
||
}
|
||
|
||
.chat-input textarea:focus {
|
||
/* border-color: #0057ff; */
|
||
/* box-shadow: 0 0 0 2px rgba(0, 87, 255, 0.1); */
|
||
}
|
||
|
||
.chat-input button {
|
||
padding: 10px 16px;
|
||
height: 44px;
|
||
border: none;
|
||
border-radius: 8px;
|
||
background: #0057ff;
|
||
color: #fff;
|
||
font-size: 14px;
|
||
cursor: pointer;
|
||
transition: all 0.2s;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.chat-input button:hover {
|
||
background: #0046cc;
|
||
}
|
||
|
||
/* 文件选择和模型选择样式调整 */
|
||
.options-row {
|
||
display: flex;
|
||
gap: 8px;
|
||
align-items: center;
|
||
font-size: 13px;
|
||
}
|
||
|
||
select,
|
||
input[type="file"] {
|
||
font-size: 13px;
|
||
padding: 6px 8px;
|
||
border: 1px solid #e5e5e5;
|
||
border-radius: 6px;
|
||
background: #fff;
|
||
transition: all 0.2s;
|
||
}
|
||
|
||
select:focus,
|
||
input[type="file"]:focus {
|
||
border-color: #0057ff;
|
||
outline: none;
|
||
}
|
||
|
||
#fileInput {
|
||
display: none;
|
||
}
|
||
|
||
.mobilelogo {
|
||
display: none;
|
||
}
|
||
|
||
.userinfo-wrapper {
|
||
position: relative;
|
||
display: flex;
|
||
justify-content: flex-start;
|
||
align-items: center;
|
||
height: 49px;
|
||
margin-bottom: 10px;
|
||
padding: 0px 26px;
|
||
margin-top: 10px;
|
||
}
|
||
|
||
.userinfo-wrapper img {
|
||
max-width: 30px;
|
||
max-height: 30px;
|
||
margin-right: 4px;
|
||
border-radius: 50%;
|
||
}
|
||
|
||
|
||
|
||
.userinfo-panel {
|
||
position: absolute;
|
||
bottom: 50px;
|
||
left: 0;
|
||
width: 150px;
|
||
background: #fff;
|
||
border-radius: 12px;
|
||
padding: 8px 8px;
|
||
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 0px;
|
||
opacity: 0;
|
||
transform: translateY(-10px);
|
||
pointer-events: none;
|
||
transition: all 0.3s ease;
|
||
z-index: 1000;
|
||
font-size: 14px;
|
||
}
|
||
|
||
/* 展开状态 */
|
||
.userinfo-panel.show {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
pointer-events: auto;
|
||
}
|
||
|
||
/* 面板内部元素 */
|
||
.userinfo-panel span,
|
||
.userinfo-panel a,
|
||
.userinfo-panel p {
|
||
padding: 8px 12px;
|
||
border-radius: 8px;
|
||
text-decoration: none;
|
||
color: #333;
|
||
text-align: left;
|
||
transition: background 0.2s;
|
||
border-bottom: 1px solid #f5f5f5;
|
||
display: flex;
|
||
justify-content: flex-start;
|
||
align-items: center;
|
||
gap: 5px;
|
||
}
|
||
|
||
.userinfo-panel p>span {
|
||
padding: 0px;
|
||
|
||
}
|
||
|
||
|
||
.userinfo-panel span:hover,
|
||
.userinfo-panel a:hover,
|
||
.userinfo-panel p:hover {
|
||
background: #f5f5f5 !important;
|
||
}
|
||
|
||
.userinfo-panel span:active,
|
||
.userinfo-panel a:active,
|
||
.userinfo-panel p:active {
|
||
background: #f5f5f5 !important;
|
||
}
|
||
|
||
/* 手机端适配 */
|
||
@media (max-width: 768px) {
|
||
|
||
.mobilelogo {
|
||
|
||
display: flex;
|
||
width: 28px;
|
||
height: 28px;
|
||
margin-right: 10px;
|
||
}
|
||
|
||
.sidebar {
|
||
/* position: absolute;
|
||
top: 10px; */
|
||
/* display: none; */
|
||
width: 240px;
|
||
background: #ffffff;
|
||
border-right: 1px solid #e3eaf2;
|
||
display: flex;
|
||
flex-direction: column;
|
||
transition: all 0.3s ease;
|
||
box-shadow: 8px 0 60px rgba(0, 0, 0, 0.04);
|
||
z-index: 1000;
|
||
position: absolute;
|
||
top: 0px;
|
||
height: 100%;
|
||
left: 0px;
|
||
}
|
||
|
||
.sidebar.collapsed>.toggle-btn {
|
||
position: fixed;
|
||
right: 10px !important;
|
||
width: 28px;
|
||
height: 28px;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
}
|
||
|
||
.chat-container {
|
||
width: 100%;
|
||
height: 100vh;
|
||
}
|
||
|
||
|
||
.chat-input {
|
||
/* position: fixed; */
|
||
bottom: 0;
|
||
left: 0;
|
||
right: 0;
|
||
z-index: 100;
|
||
}
|
||
|
||
|
||
.chat-header .back {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
margin-right: 20px;
|
||
|
||
}
|
||
|
||
|
||
|
||
.chat-container .content {
|
||
overflow-y: auto;
|
||
/* scrollbar-width: none; */
|
||
}
|
||
|
||
/* 按钮样式 */
|
||
|
||
|
||
|
||
/* 折叠面板 */
|
||
|
||
|
||
.userinfo {
|
||
display: none !important;
|
||
}
|
||
|
||
}
|
||
|
||
|
||
.fourquestion {
|
||
display: flex;
|
||
flex-direction: row;
|
||
flex-wrap: wrap;
|
||
justify-content: center;
|
||
align-items: center;
|
||
gap: 10px;
|
||
|
||
}
|
||
|
||
.fourquestion>div {
|
||
display: flex;
|
||
flex-direction: column;
|
||
flex-wrap: wrap;
|
||
justify-content: center;
|
||
align-items: center;
|
||
gap: 10px;
|
||
|
||
}
|
||
|
||
.fourquestion .question {
|
||
box-sizing: border-box;
|
||
width: 172px;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
font-size: 14px;
|
||
color: #999;
|
||
border: 1px solid #e5e5e5;
|
||
border-radius: 14px;
|
||
padding: 10px 10px;
|
||
cursor: pointer;
|
||
flex-direction: row;
|
||
|
||
|
||
|
||
}
|
||
|
||
.fourquestion .question:hover {
|
||
background-color: #e5e5e5;
|
||
color: #0057ff;
|
||
|
||
|
||
|
||
}
|
||
|
||
.fourquestion .question img {
|
||
width: 28px;
|
||
height: 28px;
|
||
margin-right: 5px;
|
||
|
||
}
|
||
|
||
.sidequestion {
|
||
display: flex;
|
||
flex-direction: column;
|
||
flex-wrap: wrap;
|
||
width: 100%;
|
||
display: none;
|
||
|
||
}
|
||
|
||
.sidequestion>div {
|
||
width: 100%;
|
||
|
||
}
|
||
|
||
.sidequestion>div .question {
|
||
width: 80%;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
font-size: 16px;
|
||
color: #999;
|
||
border: 1px solid #e5e5e5;
|
||
border-radius: 10px;
|
||
padding: 15px -16px !important;
|
||
cursor: pointer;
|
||
|
||
}
|
||
|
||
.mobile .fourquestionmain {
|
||
flex-wrap: nowrap;
|
||
overflow-x: scroll;
|
||
scrollbar-width: none;
|
||
/* 安卓端滚动条不显示 */
|
||
-ms-overflow-style: none;
|
||
justify-content: flex-start;
|
||
}
|
||
|
||
.mobile .fourquestionmain::-webkit-scrollbar {
|
||
display: none;
|
||
}
|
||
|
||
.mobile .fourquestionmain .question {
|
||
min-width: 137px;
|
||
font-size: 10px;
|
||
gap: 6px
|
||
}
|
||
|
||
|
||
/* .stopBtn {
|
||
width: 36px;
|
||
height: 36px;
|
||
} */
|
||
|
||
.none {
|
||
display: none !important;
|
||
}
|
||
|
||
.input-group {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 0px 5px;
|
||
border: 1px solid #ccc;
|
||
border-radius: 8px;
|
||
margin-bottom: 10px;
|
||
|
||
}
|
||
|
||
.area-select {
|
||
width: 130px;
|
||
font-size: 14px;
|
||
color: #333;
|
||
cursor: pointer;
|
||
}
|
||
|
||
input {
|
||
/* flex: 1; */
|
||
border: none;
|
||
outline: none;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.chat-input.pc {
|
||
border: none;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
box-shadow: none;
|
||
}
|
||
|
||
.chat-input.pc .input-row {
|
||
width: 70%;
|
||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||
}
|
||
|
||
|
||
/* 获取验证码按钮 */
|
||
.code-btn {
|
||
border: none;
|
||
/* border: 1px solid #1890ff; */
|
||
background: white;
|
||
padding: 5px 12px;
|
||
border-radius: 6px;
|
||
color: #1890ff;
|
||
cursor: pointer;
|
||
font-size: 14px;
|
||
width: 135px;
|
||
}
|
||
|
||
/* 登录按钮 */
|
||
.login-btn {
|
||
margin-top: 25px;
|
||
width: 100%;
|
||
background: #1890ff;
|
||
color: white;
|
||
padding: 12px 0;
|
||
border-radius: 10px;
|
||
border: none;
|
||
font-size: 17px;
|
||
cursor: pointer;
|
||
}
|
||
|
||
/* 协议 */
|
||
.agreement {
|
||
margin-top: 15px;
|
||
font-size: 12px;
|
||
color: #777;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
}
|
||
|
||
.pctitle {
|
||
font-size: 20px;
|
||
}
|
||
|
||
/* 微信登录 */
|
||
.wechat-login {
|
||
text-align: center;
|
||
font-size: 14px;
|
||
color: #555;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.wechat-login>div {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
gap: 2px;
|
||
|
||
}
|
||
|
||
.wechat-login img {
|
||
width: 38px;
|
||
display: block;
|
||
margin: 0 auto 5px;
|
||
}
|
||
|
||
/* 区号选择框 */
|
||
.mask {
|
||
display: none;
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background: rgba(0, 0, 0, 0.4);
|
||
}
|
||
|
||
.area-box {
|
||
background: #fff;
|
||
position: absolute;
|
||
bottom: 0;
|
||
width: 100%;
|
||
max-height: 300px;
|
||
overflow-y: auto;
|
||
border-radius: 10px 10px 0 0;
|
||
}
|
||
|
||
.area-item {
|
||
padding: 15px;
|
||
border-bottom: 1px solid #eee;
|
||
font-size: 16px;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.area-item:hover {
|
||
background: #f5f5f5;
|
||
}
|
||
|
||
.toggle-eye {
|
||
position: absolute;
|
||
right: 10px;
|
||
top: 10px;
|
||
}
|
||
|
||
.link {
|
||
color: #1677ff;
|
||
cursor: pointer;
|
||
}
|
||
|
||
|
||
.wechat-login {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
font-size: 12px;
|
||
color: #666;
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.wechat-login span:nth-child(1) {
|
||
margin-right: 8px;
|
||
}
|
||
|
||
.popbox {
|
||
position: fixed;
|
||
top: 0px;
|
||
left: 0px;
|
||
width: 100%;
|
||
height: 100%;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
background-color: rgba(0, 0, 0, 0.4);
|
||
z-index: 999999;
|
||
}
|
||
|
||
.popbox .loading-box {
|
||
position: absolute;
|
||
top: 0px;
|
||
left: 0px;
|
||
width: 100%;
|
||
height: 100%;
|
||
z-index: 999999999;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
background-color: #fff;
|
||
opacity: 0.7;
|
||
|
||
}
|
||
|
||
.popbox .loading-box.none {
|
||
display: none;
|
||
}
|
||
|
||
.popbox .loading-box .loading {
|
||
border: solid #e2e8f0;
|
||
/* 浅灰色边框 */
|
||
border-top-color: #165DFF;
|
||
/* 蓝色顶部边框 */
|
||
border-radius: 50%;
|
||
animation: spin 1s linear infinite;
|
||
/* 旋转动画 */
|
||
display: inline-block;
|
||
margin-bottom: 20px;
|
||
width: 30px;
|
||
height: 30px;
|
||
|
||
}
|
||
|
||
#sms-form {
|
||
background-color: #fff;
|
||
border-radius: 8px;
|
||
padding: 10px;
|
||
position: relative;
|
||
}
|
||
|
||
.userinfo-toggle {
|
||
position: relative;
|
||
cursor: pointer;
|
||
}
|
||
|
||
/* 隐藏 after(退出按钮) */
|
||
</style>
|
||
<style>
|
||
body {
|
||
font-family: Arial, sans-serif;
|
||
background: #f5f5f5;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
height: 100vh;
|
||
}
|
||
|
||
.no-after::after {
|
||
content: none !important;
|
||
display: none !important;
|
||
}
|
||
|
||
|
||
.popbgc {
|
||
background-color: rgba(0, 0, 0, 0.4);
|
||
position: fixed;
|
||
left: 0px;
|
||
right: 0px;
|
||
width: 100%;
|
||
height: 100%;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
z-index: 999999;
|
||
transition: all 0.3s ease-in-out;
|
||
backdrop-filter: blur(2px);
|
||
/* position: relative; */
|
||
|
||
}
|
||
|
||
#sms-button {
|
||
padding: 12px;
|
||
}
|
||
|
||
.popbgc .loading-box {
|
||
position: absolute;
|
||
top: 0px;
|
||
left: 0px;
|
||
width: 100%;
|
||
height: 100%;
|
||
z-index: 999999999;
|
||
|
||
}
|
||
|
||
.popbgc .loading-box.none {
|
||
display: none;
|
||
}
|
||
|
||
.popbgc .loading-box .loading {
|
||
border: solid #e2e8f0;
|
||
/* 浅灰色边框 */
|
||
border-top-color: #165DFF;
|
||
/* 蓝色顶部边框 */
|
||
border-radius: 50%;
|
||
animation: spin 1s linear infinite;
|
||
/* 旋转动画 */
|
||
display: inline-block;
|
||
margin-bottom: 20px;
|
||
width: 30px;
|
||
height: 30px;
|
||
|
||
}
|
||
|
||
.popup {
|
||
background: #fff;
|
||
padding: 20px;
|
||
border-radius: 8px;
|
||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
|
||
width: 400px;
|
||
|
||
}
|
||
|
||
.popup h2 {
|
||
margin-top: 0;
|
||
font-size: 18px;
|
||
margin-bottom: 15px;
|
||
}
|
||
|
||
input,
|
||
select,
|
||
button {
|
||
width: 100%;
|
||
padding: 8px;
|
||
margin: 5px 0;
|
||
border-radius: 4px;
|
||
border: 1px solid #ccc;
|
||
}
|
||
|
||
input {
|
||
border: none;
|
||
}
|
||
|
||
#popupForm input {
|
||
border: 1px solid #ccc !important;
|
||
width: 94%;
|
||
}
|
||
|
||
.options {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 5px;
|
||
margin: 10px 0;
|
||
}
|
||
|
||
.option {
|
||
/* flex: 1 1 calc(50% - 5px); */
|
||
width: 28%;
|
||
text-align: center;
|
||
padding: 8px;
|
||
background: #f0f0f0;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
user-select: none;
|
||
}
|
||
|
||
.option.selected {
|
||
background: #007bff;
|
||
color: white;
|
||
}
|
||
|
||
button {
|
||
background: #007bff;
|
||
color: white;
|
||
border: none;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.popbgc.none {
|
||
display: none;
|
||
}
|
||
|
||
|
||
.userinfo-toggle {
|
||
padding: 4px 2px;
|
||
border: none;
|
||
color: #fff;
|
||
font-weight: 500;
|
||
cursor: pointer;
|
||
overflow-x: hidden;
|
||
color: #000;
|
||
text-overflow: ellipsis;
|
||
background-color: transparent !important;
|
||
}
|
||
|
||
.collapsed .toggle-btn {
|
||
display: flex;
|
||
}
|
||
|
||
.thinking-loading {
|
||
color: #888;
|
||
font-size: 13px;
|
||
position: relative;
|
||
background: #f7f7f7;
|
||
border: 1px dashed #ddd;
|
||
border-radius: 6px;
|
||
}
|
||
|
||
.ai-thinking {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
/* gap: 10px; */
|
||
width: 100%;
|
||
padding: 6px 10px;
|
||
}
|
||
|
||
/* =========================
|
||
Icon (thinking)
|
||
========================= */
|
||
.ai-loading {
|
||
width: 22px;
|
||
height: 22px;
|
||
position: relative;
|
||
animation: breathe 1.8s cubic-bezier(.42, 0, .58, 1) infinite;
|
||
filter:
|
||
drop-shadow(0 1px 1px rgba(0, 0, 0, 0.10)) drop-shadow(0 0 7px rgba(0, 0, 0, 0.08));
|
||
margin-top: 0px !important;
|
||
position: relative;
|
||
top: 4px;
|
||
margin-right: 4px;
|
||
}
|
||
|
||
.ai-thinking .ai-loading {
|
||
top: 0px;
|
||
}
|
||
|
||
@keyframes breathe {
|
||
0% {
|
||
transform: scale(0.93);
|
||
}
|
||
|
||
36% {
|
||
transform: scale(1.06);
|
||
}
|
||
|
||
62% {
|
||
transform: scale(1.00);
|
||
}
|
||
|
||
100% {
|
||
transform: scale(0.93);
|
||
}
|
||
}
|
||
|
||
.ai-loading::before {
|
||
content: "";
|
||
position: absolute;
|
||
inset: -4px;
|
||
border-radius: 50%;
|
||
border: 1.2px solid rgba(0, 0, 0, 0.18);
|
||
animation: pulse 2.4s ease-out infinite;
|
||
pointer-events: none;
|
||
}
|
||
|
||
@keyframes pulse {
|
||
0% {
|
||
transform: scale(0.82);
|
||
opacity: 0.55;
|
||
}
|
||
|
||
100% {
|
||
transform: scale(1.38);
|
||
opacity: 0;
|
||
}
|
||
}
|
||
|
||
/* =========================
|
||
Text (thinking)
|
||
========================= */
|
||
.ai-text {
|
||
font-size: 13px;
|
||
letter-spacing: 0.14em;
|
||
text-transform: uppercase;
|
||
opacity: 0.7;
|
||
animation: text-step 1.8s steps(3, end) infinite;
|
||
}
|
||
|
||
@keyframes text-step {
|
||
0% {
|
||
opacity: 0.35;
|
||
}
|
||
|
||
45% {
|
||
opacity: 0.6;
|
||
}
|
||
|
||
100% {
|
||
opacity: 0.95;
|
||
}
|
||
}
|
||
|
||
/* =========================
|
||
✅ 完成态(常驻)
|
||
========================= */
|
||
.ai-thinking.is-complete .ai-loading,
|
||
.ai-thinking.is-complete .ai-loading::before {
|
||
animation: none;
|
||
transform: scale(1);
|
||
}
|
||
|
||
.is-complete .ai-text {
|
||
animation: none;
|
||
text-transform: none;
|
||
letter-spacing: 0.08em;
|
||
opacity: 0.85;
|
||
}
|
||
|
||
.is-complete .ai-loading {
|
||
animation: none;
|
||
text-transform: none;
|
||
|
||
}
|
||
|
||
|
||
|
||
@keyframes dots {
|
||
0% {
|
||
content: '';
|
||
}
|
||
|
||
25% {
|
||
content: '.';
|
||
}
|
||
|
||
50% {
|
||
content: '..';
|
||
}
|
||
|
||
75% {
|
||
content: '...';
|
||
}
|
||
}
|
||
|
||
.thinking-box {
|
||
margin-bottom: 12px;
|
||
border: 1px dashed #ddd;
|
||
border-radius: 6px;
|
||
font-size: 13px;
|
||
color: #666;
|
||
}
|
||
|
||
.thinking-box .thinking-header {
|
||
padding: 6px 10px;
|
||
cursor: pointer;
|
||
background: #f7f7f7;
|
||
|
||
user-select: none;
|
||
position: relative;
|
||
}
|
||
|
||
.thinking-title {
|
||
/* position: absolute; */
|
||
top: 3px;
|
||
left: -27px;
|
||
}
|
||
|
||
.thinking-title img {
|
||
margin-top: 0px !important;
|
||
margin-right: 6px;
|
||
}
|
||
|
||
.thinking-content {
|
||
padding: 8px 10px;
|
||
line-height: 1.6;
|
||
}
|
||
|
||
.thinking-content.collapsed {
|
||
display: none;
|
||
}
|
||
|
||
.answer-box {
|
||
font-size: 15px;
|
||
line-height: 1.7;
|
||
}
|
||
|
||
|
||
|
||
@media (max-width: 768px) {
|
||
.popbgc {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
.popup {
|
||
position: absolute;
|
||
top: 50px;
|
||
width: 90%;
|
||
}
|
||
|
||
.weixin-loading {
|
||
width: 100%;
|
||
height: 100%;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
position: fixed;
|
||
z-index: 99999;
|
||
background-color: #fff;
|
||
top: 0px;
|
||
left: 0px;
|
||
opacity: 0.7;
|
||
}
|
||
|
||
.weixin-loading.none {
|
||
display: none;
|
||
}
|
||
|
||
.weixin-loading .loading {
|
||
border: solid #e2e8f0;
|
||
/* 浅灰色边框 */
|
||
border-top-color: #165DFF;
|
||
/* 蓝色顶部边框 */
|
||
border-radius: 50%;
|
||
animation: spin 1s linear infinite;
|
||
/* 旋转动画 */
|
||
display: inline-block;
|
||
margin-bottom: 20px;
|
||
width: 30px;
|
||
height: 30px;
|
||
}
|
||
|
||
.chatboxmobile {
|
||
width: 100%;
|
||
display: flex;
|
||
justify-content: flex-start;
|
||
gap: 0px;
|
||
|
||
}
|
||
|
||
.chatboxmobile .button-row {
|
||
width: 62px !important;
|
||
margin-bottom: 0px !important;
|
||
gap: 8px !important;
|
||
margin-right: 5px;
|
||
justify-content: flex-end;
|
||
}
|
||
|
||
.input-row img {
|
||
width: 20px !important;
|
||
height: 20px !important;
|
||
}
|
||
|
||
#sendFileBtn img {
|
||
width: 16px !important;
|
||
height: 16px !important;
|
||
}
|
||
|
||
.input-row .button-row>div {
|
||
margin-left: 0px !important;
|
||
}
|
||
|
||
@keyframes spin {
|
||
to {
|
||
transform: rotate(360deg);
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
.loading-dots {
|
||
display: flex;
|
||
justify-content: flex-start;
|
||
align-items: center;
|
||
font-size: 20px;
|
||
}
|
||
|
||
.dot {
|
||
width: 8px;
|
||
height: 8px;
|
||
margin: 0 5px;
|
||
border-radius: 50%;
|
||
background-color: #ccc;
|
||
animation: dot-blink 1s infinite alternate;
|
||
}
|
||
|
||
.dot:nth-child(1) {
|
||
animation-delay: 0s;
|
||
}
|
||
|
||
.dot:nth-child(2) {
|
||
animation-delay: 0.5s;
|
||
}
|
||
|
||
@keyframes dot-blink {
|
||
0% {
|
||
background-color: #ccc;
|
||
}
|
||
|
||
50% {
|
||
background-color: #333;
|
||
/* 高亮颜色 */
|
||
}
|
||
|
||
100% {
|
||
background-color: #ccc;
|
||
}
|
||
}
|
||
</style>
|
||
</head>
|
||
|
||
<body>
|
||
<div class="weixin-loading ">
|
||
<div class="loading">
|
||
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<!-- 左侧侧边栏 -->
|
||
<div class="sidebar" id="sidebar">
|
||
<button class="toggle-btn" id="toggleBtn" onclick="toggleSidebar()"><svg width="50" height="24"
|
||
viewBox="0 0 30 18" xmlns="http://www.w3.org/2000/svg">
|
||
<!-- 上面较粗的横线 -->
|
||
<rect x="2" y="3" width="26" height="3.2" rx="1.6" fill="#222" />
|
||
|
||
<!-- 下面较细的横线 -->
|
||
<rect x="6" y="12" width="18" height="2.6" rx="1.3" fill="#222" />
|
||
</svg>
|
||
</button>
|
||
<div class="sidebar-header"><img src="./img/logo.png">会话列表</div>
|
||
<div class="sidebar-actions">
|
||
<button onclick="newChat()">+ 新建会话</button>
|
||
</div>
|
||
<div class="chat-list" id="chatList"></div>
|
||
<div class="fourquestion sidequestion">
|
||
<div>
|
||
<div class='question' data-value='分析这个场站' data-pre-value="详细分析这个光伏场站,根据图片给出详细的运维方案"><img
|
||
src="./img/1.png" alt="">分析这个场站</div>
|
||
<div class='question' data-value='详细的割草计划' data-pre-value="如果这个光伏场站需要割草怎么做,给出一份详细的计划"><img
|
||
src="./img/3.png" alt="">详细的割草计划</div>
|
||
<div class='question' data-value='详细的清洗计划' data-pre-value="如果这个光伏场站需要用无人机清洗怎么做,给出一份详细的计划"><img
|
||
src="./img/4.png" alt="">详细的清洗计划</div>
|
||
</div>
|
||
<div>
|
||
<div class='question' data-value='详细的巡检计划' data-pre-value="如果这个光伏场站需要巡检怎么做,给出一份详细的计划"><img
|
||
src="./img/2.png" alt="">详细的巡检计划</div>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
</div>
|
||
<div class="userinfo-wrapper">
|
||
<img src="" alt="">
|
||
<!-- 初始按钮 -->
|
||
<p class="userinfo-toggle username" onclick="toggleUserInfo()">用户</p>
|
||
<!-- 折叠面板 -->
|
||
<div class="userinfo-panel">
|
||
<!-- <p style="margin:0px"><img src="" alt=""><span class="username">用户</span></p> -->
|
||
<span class="logout logout1" onclick="logout()"><svg t="1764305134824" class="icon"
|
||
viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="20125" width="16"
|
||
height="16">
|
||
<path
|
||
d="M874.666667 855.744a19.093333 19.093333 0 0 1-19.136 18.922667H168.469333A19.2 19.2 0 0 1 149.333333 855.530667V168.469333A19.2 19.2 0 0 1 168.469333 149.333333h687.061334c10.581333 0 19.136 8.533333 19.136 18.922667V320h42.666666V168.256A61.717333 61.717333 0 0 0 855.530667 106.666667H168.469333A61.866667 61.866667 0 0 0 106.666667 168.469333v687.061334A61.866667 61.866667 0 0 0 168.469333 917.333333h687.061334A61.76 61.76 0 0 0 917.333333 855.744V704h-42.666666v151.744zM851.84 533.333333l-131.797333 131.754667a21.141333 21.141333 0 0 0 0.213333 29.973333 21.141333 21.141333 0 0 0 29.973333 0.192l165.589334-165.589333a20.821333 20.821333 0 0 0 6.122666-14.976 21.44 21.44 0 0 0-6.314666-14.997333l-168.533334-168.533334a21.141333 21.141333 0 0 0-29.952-0.213333 21.141333 21.141333 0 0 0 0.213334 29.973333L847.296 490.666667H469.333333v42.666666h382.506667z"
|
||
fill="#3D3D3D" p-id="20126"></path>
|
||
</svg>退出</span>
|
||
<a class="logout price" href="./modal.html"><svg t="1764305265690" class="icon" viewBox="0 0 1024 1024"
|
||
version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="22408" width="16" height="16">
|
||
<path
|
||
d="M799.785 63.785h-576c-88 0-160 72-160 160v112.129l64.205 57.653V217.99c0-49.5 40.5-90 90-90h588.184c49.5 0 90 40.5 90 90v343.62l63.611 57.119V223.785c0-88-72-160-160-160z m96.389 741.854c0 49.5-40.5 90-90 90H217.99c-49.5 0-90-40.5-90-90V518.558l-64.205-57.653v338.88c0 88 72 160 160 160h576c88 0 160-72 160-160V743.72l-63.611-57.119v119.038z"
|
||
p-id="22409" fill="#333333"></path>
|
||
<path
|
||
d="M63.873 460.682l106.776 89.295 0.118 71.213-106.776-89.294zM853.053 461.433l106.776 89.295 0.118 71.214-106.776-89.295zM656.41 500.181h-312c-6.6 0-12-5.4-12-12v-31c0-6.6 5.4-12 12-12h312c6.6 0 12 5.4 12 12v31c0 6.6-5.4 12-12 12zM655.247 611.809h-312c-6.6 0-12-5.4-12-12v-31c0-6.6 5.4-12 12-12h312c6.6 0 12 5.4 12 12v31c0 6.6-5.4 12-12 12z"
|
||
p-id="22410" fill="#333333"></path>
|
||
<path
|
||
d="M512.826 752.07h-31c-6.6 0-12-5.4-12-12v-330c0-6.6 5.4-12 12-12h31c6.6 0 12 5.4 12 12v330c0 6.6-5.4 12-12 12z"
|
||
p-id="22411" fill="#333333"></path>
|
||
<path
|
||
d="M633.558 327.984l-107.48 107.48c-4.667 4.667-12.304 4.667-16.971 0l-21.92-21.92c-4.667-4.667-4.667-12.304 0-16.971l107.48-107.48c4.667-4.667 12.304-4.667 16.971 0l21.92 21.92c4.667 4.668 4.667 12.304 0 16.971z"
|
||
p-id="22412" fill="#333333"></path>
|
||
<path
|
||
d="M397.984 289.07l107.48 107.48c4.667 4.667 4.667 12.304 0 16.971l-21.92 21.92c-4.667 4.667-12.304 4.667-16.971 0l-107.48-107.48c-4.667-4.667-4.667-12.304 0-16.971l21.92-21.92c4.668-4.667 12.304-4.667 16.971 0z"
|
||
p-id="22413" fill="#333333"></path>
|
||
</svg>服务价格</a>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
</div>
|
||
|
||
<!-- 收起按钮 -->
|
||
|
||
|
||
<!-- 右侧聊天区 -->
|
||
<div class="chat-container">
|
||
<div class="chat-header">
|
||
<!-- <div class='back' onclick="handleBack()">
|
||
<svg t="1748925372585" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||
p-id="4688" width="16" height="16">
|
||
<path
|
||
d="M395.21518 513.604544l323.135538-312.373427c19.052938-18.416442 19.052938-48.273447 0-66.660212-19.053961-18.416442-49.910737-18.416442-68.964698 0L291.75176 480.290811c-19.052938 18.416442-19.052938 48.273447 0 66.660212l357.633237 345.688183c9.525957 9.207709 22.01234 13.796214 34.497699 13.796214 12.485359 0 24.971741-4.588505 34.466999-13.82896 19.052938-18.416442 19.052938-48.242747 0-66.660212L395.21518 513.604544z"
|
||
fill="#999" p-id="4689"></path>
|
||
</svg>
|
||
</div> -->
|
||
<div style="
|
||
display: flex;
|
||
justify-content: flex-start;
|
||
align-items: center;
|
||
">
|
||
|
||
<span class="pctitle">新能源智能体</span><span style="font-size:20px" class="pctitleeng">satabot</span>
|
||
</div>
|
||
|
||
|
||
|
||
</div>
|
||
<div class="content" id='content'>
|
||
<div id="chatMessages" class="chat-messages"></div>
|
||
|
||
</div>
|
||
|
||
|
||
<div class="chat-input pc">
|
||
<div class="fourquestion fourquestionmain">
|
||
<div class='question mainauestion' data-value='分析这个场站' data-pre-value="详细分析这个光伏场站,根据图片给出详细的运维方案"><img
|
||
src="./img/1.png" alt="">分析这个场站</div>
|
||
<div class='question mainauestion' data-value='详细的割草计划' data-pre-value="如果这个光伏场站需要割草怎么做,给出一份详细的计划"><img
|
||
src="./img/3.png" alt="">详细的割草计划</div>
|
||
<div class='question mainauestion' data-value='详细的清洗计划' data-pre-value="如果这个光伏场站需要用无人机清洗怎么做,给出一份详细的计划">
|
||
<img src="./img/4.png" alt="">详细的清洗计划</div>
|
||
<div class='question mainauestion' data-value='详细的巡检计划' data-pre-value="如果这个光伏场站需要巡检怎么做,给出一份详细的计划"><img
|
||
src="./img/2.png" alt="">详细的巡检计划</div>
|
||
|
||
|
||
|
||
|
||
</div>
|
||
<div class="input-row">
|
||
<div class="img-row none">
|
||
<div class="img-box">
|
||
<img src="" alt="">
|
||
<span class="delete-btn" onclick="deleteImg()"><svg t="1757836617046" class="icon"
|
||
viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="16945"
|
||
width="16" height="16">
|
||
<path d="M512 512m-512 0a512 512 0 1 0 1024 0 512 512 0 1 0-1024 0Z" fill="#EF4631"
|
||
p-id="16946">
|
||
</path>
|
||
<path
|
||
d="M733.6 733.6c-16.7 16.7-43.7 16.6-60.2 0.1l-151-151-151 151c-16.6 16.6-43.4 16.6-60.2-0.1-16.7-16.7-16.6-43.7-0.1-60.2l151-151-151-151c-16.6-16.6-16.6-43.4 0.1-60.2 16.7-16.7 43.7-16.6 60.2-0.1l151 151 151-151c16.6-16.6 43.4-16.6 60.2 0.1 16.7 16.7 16.6 43.7 0.1 60.2l-151 151 151 151c16.6 16.6 16.7 43.4-0.1 60.2z"
|
||
fill="#FFFFFF" p-id="16947"></path>
|
||
</svg></span>
|
||
</div>
|
||
|
||
|
||
</div>
|
||
|
||
<textarea class="chatInput" rows="1" placeholder="询问任何问题..." name="quespc"></textarea>
|
||
<div class="button-row">
|
||
|
||
<div id="sendFileBtn" style="position: relative; width: 40px; height: 40px; cursor: pointer;">
|
||
<input type="file" id="fileInput" style="position: absolute;
|
||
left: -20px; top: 0; width: 0px; height: 50%;
|
||
opacity: 0; cursor: pointer;" />
|
||
<span class="sendfileimg">
|
||
<svg t="1764306578537" class="icon" viewBox="0 0 1025 1024" version="1.1"
|
||
xmlns="http://www.w3.org/2000/svg" p-id="26780" width="24" height="24">
|
||
<path
|
||
d="M852.812 166.713c-92.715-89.28-212.9-140.789-339.954-140.789s-250.672 51.509-339.953 140.79c-188.863 188.862-188.863 491.043 0 679.906 89.28 89.28 212.9 140.789 339.953 140.789S763.531 935.9 852.812 846.62c188.863-188.863 188.863-491.044 0-679.907m-48.074 631.833c-78.98 78.979-181.996 120.185-291.88 120.185s-212.9-41.206-291.879-120.185c-161.392-161.392-161.392-422.367 0-583.759 78.98-78.979 181.996-120.185 291.88-120.185s212.9 41.206 291.879 120.185c161.392 161.392 161.392 422.367 0 583.759"
|
||
fill="#515151" p-id="26781"></path>
|
||
<path
|
||
d="M547.197 472.328V297.2c0-20.603-13.735-34.338-34.339-34.338S478.52 276.597 478.52 297.2v175.128H303.392c-20.603 0-34.339 13.735-34.339 34.339 0 10.301 3.434 17.169 10.302 24.037s13.736 10.301 24.037 10.301H478.52v175.128c0 10.302 3.434 17.17 10.301 24.037 6.868 6.868 13.736 10.302 24.037 10.302 20.604 0 34.34-13.736 34.34-34.34V541.006h175.127c20.603 0 34.338-13.735 34.338-34.338s-13.735-34.34-34.338-34.34H547.197z"
|
||
fill="#515151" p-id="26782"></path>
|
||
</svg>
|
||
</span>
|
||
</div>
|
||
<div id="sendBtn" class="sendBtn">
|
||
<span class="sendMsgImg">
|
||
<svg t="1764306257999" class="icon" viewBox="0 0 1024 1024" version="1.1"
|
||
xmlns="http://www.w3.org/2000/svg" p-id="24697" width="24" height="24">
|
||
<path
|
||
d="M691.84 1014.4l-271.36-244.16v79.68l10.24-10.24 44.48 46.08-118.72 115.52V626.24l304.64 274.56 252.8-787.2-786.56 280.96 168.96 164.48 325.76-246.72 38.72 50.88L291.2 643.2 9.28 368.64 1014.72 9.6 691.84 1014.4z"
|
||
fill="#2A2A3B" p-id="24698"></path>
|
||
</svg>
|
||
</span>
|
||
<div class="stopBtn none" id="stopBtn1">
|
||
<svg t="1764310210804" class="icon" viewBox="0 0 1024 1024" version="1.1"
|
||
xmlns="http://www.w3.org/2000/svg" p-id="28649" width="24" height="24">
|
||
<path
|
||
d="M365.014704 657.815846H657.084939V365.74561H365.014704V657.815846z m584.140471-146.035118c0-240.906781-197.125482-438.105353-438.105353-438.105353-240.979872 0-438.105353 197.198572-438.105354 438.105353 0 240.979872 197.125482 438.178444 438.105354 438.178444 240.979872 0 438.105353-197.198572 438.105353-438.178444zM511.634547 0.730906c281.399001 0 511.634547 230.235546 511.634547 511.634547s-230.235546 511.634547-511.634547 511.634547-511.634547-230.235546-511.634547-511.634547 230.235546-511.634547 511.634547-511.634547z"
|
||
p-id="28650" fill="#000000"></path>
|
||
</svg>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
<div class="chat-input mobile">
|
||
<div class="fourquestion fourquestionmain">
|
||
<div class='question mainauestion' data-value='分析这个场站' data-pre-value="详细分析这个光伏场站,根据图片给出详细的运维方案"><img
|
||
src="./img/1.png" alt="">分析这个场站</div>
|
||
<div class='question mainauestion' data-value='详细的割草计划' data-pre-value="如果这个光伏场站需要割草怎么做,给出一份详细的计划"><img
|
||
src="./img/3.png" alt="">详细的割草计划</div>
|
||
|
||
<div class='question mainauestion' data-value='详细的清洗计划' data-pre-value="如果这个光伏场站需要用无人机清洗怎么做,给出一份详细的计划">
|
||
<img src="./img/4.png" alt="">详细的清洗计划</div>
|
||
<div class='question mainauestion' data-value='详细的巡检计划' data-pre-value="如果这个光伏场站需要巡检怎么做,给出一份详细的计划"><img
|
||
src="./img/2.png" alt="">详细的巡检计划</div>
|
||
|
||
|
||
|
||
</div>
|
||
<div class="input-row">
|
||
<div class="img-row none">
|
||
<div class="img-box">
|
||
<img src="" alt="">
|
||
<span class="delete-btn" onclick="deleteImg()"><svg t="1757836617046" class="icon"
|
||
viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="16945"
|
||
width="16" height="16">
|
||
<path d="M512 512m-512 0a512 512 0 1 0 1024 0 512 512 0 1 0-1024 0Z" fill="#EF4631"
|
||
p-id="16946">
|
||
</path>
|
||
<path
|
||
d="M733.6 733.6c-16.7 16.7-43.7 16.6-60.2 0.1l-151-151-151 151c-16.6 16.6-43.4 16.6-60.2-0.1-16.7-16.7-16.6-43.7-0.1-60.2l151-151-151-151c-16.6-16.6-16.6-43.4 0.1-60.2 16.7-16.7 43.7-16.6 60.2-0.1l151 151 151-151c16.6-16.6 43.4-16.6 60.2 0.1 16.7 16.7 16.6 43.7 0.1 60.2l-151 151 151 151c16.6 16.6 16.7 43.4-0.1 60.2z"
|
||
fill="#FFFFFF" p-id="16947"></path>
|
||
</svg></span>
|
||
</div>
|
||
|
||
|
||
</div>
|
||
<div class="chatboxmobile">
|
||
<textarea class="chatInput1" rows="1" placeholder="询问任何问题..." name="quesmobile"></textarea>
|
||
<div class="button-row">
|
||
|
||
<div id="sendFileBtn" style="position: relative; width: 40px; height: 40px; cursor: pointer;">
|
||
<input type="file" id="fileInput1" style="position: absolute;
|
||
left: -30px; top: 0; width: 0px; height:50%;
|
||
opacity: 0; cursor: pointer;" />
|
||
<span class="sendfileimg">
|
||
<svg t="1764306578537" class="icon" viewBox="0 0 1025 1024" version="1.1"
|
||
xmlns="http://www.w3.org/2000/svg" p-id="26780" width="24" height="24">
|
||
<path
|
||
d="M852.812 166.713c-92.715-89.28-212.9-140.789-339.954-140.789s-250.672 51.509-339.953 140.79c-188.863 188.862-188.863 491.043 0 679.906 89.28 89.28 212.9 140.789 339.953 140.789S763.531 935.9 852.812 846.62c188.863-188.863 188.863-491.044 0-679.907m-48.074 631.833c-78.98 78.979-181.996 120.185-291.88 120.185s-212.9-41.206-291.879-120.185c-161.392-161.392-161.392-422.367 0-583.759 78.98-78.979 181.996-120.185 291.88-120.185s212.9 41.206 291.879 120.185c161.392 161.392 161.392 422.367 0 583.759"
|
||
fill="#515151" p-id="26781"></path>
|
||
<path
|
||
d="M547.197 472.328V297.2c0-20.603-13.735-34.338-34.339-34.338S478.52 276.597 478.52 297.2v175.128H303.392c-20.603 0-34.339 13.735-34.339 34.339 0 10.301 3.434 17.169 10.302 24.037s13.736 10.301 24.037 10.301H478.52v175.128c0 10.302 3.434 17.17 10.301 24.037 6.868 6.868 13.736 10.302 24.037 10.302 20.604 0 34.34-13.736 34.34-34.34V541.006h175.127c20.603 0 34.338-13.735 34.338-34.338s-13.735-34.34-34.338-34.34H547.197z"
|
||
fill="#515151" p-id="26782"></path>
|
||
</svg>
|
||
</span>
|
||
|
||
|
||
|
||
</div>
|
||
<div id="sendBtn" class="mobilesendbtn none sendBtn1">
|
||
<span class="sendMsgImg1">
|
||
<svg t="1764306257999" class="icon" viewBox="0 0 1024 1024" version="1.1"
|
||
xmlns="http://www.w3.org/2000/svg" p-id="24697" width="24" height="24">
|
||
<path
|
||
d="M691.84 1014.4l-271.36-244.16v79.68l10.24-10.24 44.48 46.08-118.72 115.52V626.24l304.64 274.56 252.8-787.2-786.56 280.96 168.96 164.48 325.76-246.72 38.72 50.88L291.2 643.2 9.28 368.64 1014.72 9.6 691.84 1014.4z"
|
||
fill="#2A2A3B" p-id="24698"></path>
|
||
</svg>
|
||
</span>
|
||
|
||
<div class="stopBtn none" id="stopBtn">
|
||
<svg t="1764310210804" class="icon" viewBox="0 0 1024 1024" version="1.1"
|
||
xmlns="http://www.w3.org/2000/svg" p-id="28649" width="24" height="24">
|
||
<path
|
||
d="M365.014704 657.815846H657.084939V365.74561H365.014704V657.815846z m584.140471-146.035118c0-240.906781-197.125482-438.105353-438.105353-438.105353-240.979872 0-438.105353 197.198572-438.105354 438.105353 0 240.979872 197.125482 438.178444 438.105354 438.178444 240.979872 0 438.105353-197.198572 438.105353-438.178444zM511.634547 0.730906c281.399001 0 511.634547 230.235546 511.634547 511.634547s-230.235546 511.634547-511.634547 511.634547-511.634547-230.235546-511.634547-511.634547 230.235546-511.634547 511.634547-511.634547z"
|
||
p-id="28650" fill="#000000"></path>
|
||
</svg>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="popbgc none">
|
||
|
||
<div class="popup">
|
||
<h2>开启光伏运维智能化!</h2>
|
||
<form id="popupForm">
|
||
<input type="text" name="company" placeholder="请输入您的公司" required>
|
||
|
||
<!-- <select name="need" required>
|
||
<option value="">您的需求是什么?</option>
|
||
<option value="杂草清理">杂草清理</option>
|
||
<option value="组件积灰清扫">组件积灰清扫</option>
|
||
<option value="EL/IR缺陷识别">EL/IR缺陷识别</option>
|
||
<option value="热斑检测">热斑检测</option>
|
||
<option value="需要运维机器人">需要运维机器人</option>
|
||
<option value="定制机器人">定制机器人</option>
|
||
</select> -->
|
||
|
||
<div>
|
||
<p>您对以下哪些场景感兴趣?</p>
|
||
<div class="options" id="scenes">
|
||
<div class="option">山地光伏</div>
|
||
<div class="option">荒漠 / 戈壁</div>
|
||
<div class="option">农光互补电站</div>
|
||
<div class="option">渔光互补电站</div>
|
||
<div class="option">滩涂 / 盐碱地</div>
|
||
<div class="option">平原 / 草原</div>
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<p>您的需求?</p>
|
||
<div class="options" id="needs">
|
||
<div class="option">杂草清理</div>
|
||
<div class="option">组件积灰清扫</div>
|
||
<div class="option">EL/IR缺陷识别</div>
|
||
<div class="option">热斑检测</div>
|
||
<div class="option">需要运维机器人</div>
|
||
<div class="option">定制机器人</div>
|
||
</div>
|
||
</div>
|
||
|
||
<button type="submit">立即使用</button>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
</div>
|
||
|
||
<!-- <script>
|
||
// 开启 vConsole 调试面板
|
||
var vConsole = new VConsole();
|
||
|
||
console.log("✅ vConsole 已经启动");
|
||
</script> -->
|
||
<script src="./canvas.js"></script>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<script>
|
||
|
||
|
||
|
||
const sidebar = document.getElementById("sidebar");
|
||
const chatMessages = document.getElementById("chatMessages");
|
||
const chatInput = isMobile() ? document.querySelector(".chatInput1") : document.querySelector(".chatInput");
|
||
const fileInput = isMobile() ? document.getElementById("fileInput1") : document.getElementById("fileInput");
|
||
const chatList = document.getElementById("chatList");
|
||
const sendmsgbox = isMobile() ? document.querySelector('.sendBtn1') : document.querySelector('.sendBtn1');
|
||
const sendBtnImg = isMobile() ? document.querySelector('.sendBtn1 .sendMsgImg1') : document.querySelector('.sendBtn .sendMsgImg');
|
||
const stopBtn = document.querySelectorAll('.stopBtn');
|
||
const weixinloading = document.querySelector(".weixin-loading")
|
||
let controller = null;
|
||
let sessIdList = [];
|
||
let isStopped = false;//是否停止输出
|
||
let isUpload = {};
|
||
let hasImage = false;
|
||
let isPre = false;//是否点击了预设问题
|
||
// let sessIdList = JSON.parse(localStorage.getItem("sessId")) || [];
|
||
let sessId;
|
||
let activeChatId = '';
|
||
const params = new URLSearchParams(window.location.search);
|
||
console.log(params.get("userId"), 644, params.get("nickname"), params.get("headingimg"));
|
||
|
||
const encodedUserId = params.get("userId");
|
||
let openId = params.get("openid") ? params.get("openid") : '';
|
||
|
||
const from = params.get("from");
|
||
let token = params.get("token");//app的token
|
||
let localtoken = params.get("localtoken");//公众号的localtoken
|
||
|
||
function clearOldRootDomainCookies() {
|
||
const names = ['Admin-Token', 'token', 'userId', 'username', 'nickname', 'headimgurl', 'headingimg'];
|
||
const parts = location.hostname.split('.');
|
||
const rootDomain = parts.length >= 2 ? '.' + parts.slice(-2).join('.') : '';
|
||
if (!rootDomain || rootDomain === '.') return;
|
||
names.forEach(name => {
|
||
document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=' + rootDomain + ';';
|
||
});
|
||
console.log('[cookie] 已清除旧 root-domain cookie:', rootDomain);
|
||
}
|
||
clearOldRootDomainCookies();
|
||
|
||
|
||
// app会得到token;
|
||
// 手机端会验证token
|
||
|
||
|
||
if ((!getCookie("token") || localtoken != getCookie("token")) && isMobile() && !token) {
|
||
window.location.href = './middle.html';
|
||
}
|
||
|
||
if (!isMobile() && !getCookie("token") && !token && !params.get("nickname")) {
|
||
location.replace('./login.html');
|
||
}
|
||
// }
|
||
// else if (!isMobile() && !getCookie('sharetoken')) {//网页端token
|
||
// //
|
||
// location.replace('https://ri.satabot.com/#/login?goRemote=1&clear=1');
|
||
// }
|
||
|
||
// if (!isMobile() && !getCookie('sharetoken')) {
|
||
// location.replace('https://ri.satabot.com/#/login?goRemote=1&clear=1');
|
||
// }
|
||
|
||
|
||
|
||
// ✅ 先 URL 解码,再 Base64 解码,再 UTF-8 解码
|
||
let userId;
|
||
if (params.get("nickname") || getcookie("nickname")) {
|
||
console.log(getcookie("headingimg"), 888888, document.cookie, params.get("nickname"))
|
||
|
||
document.querySelectorAll('.logout1').forEach(el => {
|
||
el.style.display = 'none';
|
||
});
|
||
|
||
document.querySelectorAll('.username').forEach((e) => {
|
||
e.textContent = params.get("nickname") || getcookie("nickname");
|
||
})
|
||
|
||
document.querySelector(".userinfo-wrapper img").src = getcookie("headimgurl") || params.get("headingimg");
|
||
userId = decodeURIComponent(Number(escape(atob(encodedUserId))));
|
||
|
||
|
||
} else {
|
||
userId = decodeURIComponent(Number(escape(atob(encodedUserId))));
|
||
}
|
||
// 微信授权的码
|
||
if (userId && userId != "NaN") {
|
||
setCookie("userId", userId);
|
||
}
|
||
getUserName(userId);
|
||
|
||
// const userId = encodedUserId;
|
||
let sendParam = {
|
||
imageBase64: '',
|
||
userId: userId,
|
||
sessionId: '',
|
||
userPrompt: '',
|
||
requestId: ''
|
||
}
|
||
if (isMobile()) {
|
||
toggleSidebar();
|
||
document.querySelector(".pctitle").textContent = '';
|
||
document.querySelector(".chat-input.pc").classList.add('none');
|
||
|
||
} else {
|
||
document.querySelector(".pctitleeng").textContent = '';
|
||
document.querySelector(".chat-input.mobile").classList.add('none');
|
||
document.querySelector('.userinfo-panel').classList.add('pc')
|
||
document.querySelector('.price').classList.add('pc');
|
||
document.querySelector('.userinfo-toggle').classList.add('pc')
|
||
|
||
}
|
||
// if (isWeChat()) {
|
||
// if (code) {
|
||
// // gotoWeiXin();
|
||
// // 用 code 换取 openid 和 access_token
|
||
// fetch(`https://api.weixin.qq.com/sns/oauth2/access_token?appid=${appid}&secret=SECRET&code=CODE&grant_type=authorization_code?code=${code}`)
|
||
// .then(res => res.json())
|
||
// .then(data => {
|
||
// // data 里返回 userId / openid
|
||
|
||
// setCookie("userId", data.userId);
|
||
// window.location.href = "/"; // 回到首页
|
||
// });
|
||
// } else {
|
||
// // 没拿到 code,再次走 gotoWeiXin()
|
||
// gotoWeiXin();
|
||
// }
|
||
|
||
// } else {
|
||
getSessionList();
|
||
|
||
|
||
|
||
function isMobile() {
|
||
// 获取UA字符串
|
||
const userAgent = navigator.userAgent;
|
||
// 匹配主流手机相关关键词,忽略大小写
|
||
const mobileRegex = /iPhone|Android|BlackBerry|IEMobile|Opera Mini|RedMi|Huawei|Vivo/i;
|
||
// 返回匹配结果
|
||
return mobileRegex.test(userAgent);
|
||
}
|
||
function bindToLogin() {
|
||
document.querySelector('.popbox .loading-box').classList.remove('none');
|
||
const data = {
|
||
sourceType: 5,
|
||
openId: openId,
|
||
phonenumber: document.getElementById('sys-phone').value,
|
||
smsCode: document.getElementById('code').value,
|
||
loginPlatForm: 3,
|
||
userId: Number(userId)
|
||
|
||
}
|
||
retryFetch("https://serviceri.satabot.com/login", {
|
||
// fetch("/api/remote/login", {
|
||
method: "POST", // 必选:指定请求方法为 POST
|
||
headers: {
|
||
"Content-Type": "application/json", // 声明请求体是 JSON 格式
|
||
// 可选:如果接口需要 Token 前置验证,可添加 Authorization 头
|
||
// "Authorization": "Bearer 你的前置 Token"
|
||
},
|
||
// 必选:请求体,将参数对象转为 JSON 字符串(不能直接传对象)
|
||
body: JSON.stringify(data)
|
||
}).then(res => {
|
||
console.log(res, "绑定信息")
|
||
if (res.code == 200) {
|
||
if (document.querySelector('.popbox .loading-box')) {
|
||
document.querySelector('.popbox .loading-box').classList.add('none');
|
||
}
|
||
// userId = res.userId;
|
||
// setCookie('token', res.token);
|
||
unshowpop();
|
||
// getSessionList();
|
||
refreshAiChatNum()
|
||
} else {
|
||
showToast(res.msg)
|
||
}
|
||
|
||
// } else {
|
||
// showToast(res.msg + "denglucuowu");
|
||
// setTimeout(() => {
|
||
// // window.location.reload();
|
||
// }, 2000);
|
||
|
||
// return;
|
||
// }
|
||
}).catch(err => {
|
||
|
||
// 捕获异步异常(如网络错误、接口报错、代码报错)
|
||
console.error("请求异常:", err);
|
||
showToast("登录失败,请重试" + err); // 给用户友好提示
|
||
})
|
||
.finally(() => {
|
||
|
||
if (document.querySelector('.popbox .loading-box')) {
|
||
document.querySelector('.popbox .loading-box').classList.add('none');
|
||
}
|
||
|
||
});
|
||
// try {
|
||
// handleLogin(data).then(res => {
|
||
// if (res.code == 200) {
|
||
// if (document.querySelector('.popbox .loading-box')) {
|
||
// document.querySelector('.popbox .loading-box').classList.add('none');
|
||
// }
|
||
// userId = res.userId;
|
||
// setCookie('token', res.token);
|
||
// unshowpop();
|
||
// getSessionList();
|
||
|
||
// } else {
|
||
// showToast(res.msg + "denglucuowu");
|
||
// window.location.reload();
|
||
// return;
|
||
// }
|
||
// }).catch(err => {
|
||
|
||
// // 捕获异步异常(如网络错误、接口报错、代码报错)
|
||
// console.error("请求异常:", err);
|
||
// showToast("登录失败,请重试" + err); // 给用户友好提示
|
||
// })
|
||
// .finally(() => {
|
||
// unshowpop();
|
||
// if (document.querySelector('.popbox .loading-box')) {
|
||
// document.querySelector('.popbox .loading-box').classList.add('none');
|
||
// }
|
||
|
||
// });
|
||
|
||
// } catch (err) {
|
||
// console.error("请求异常:", err);
|
||
// }
|
||
}
|
||
async function retryFetch(url, options, maxRetry = 10) {
|
||
let lastError;
|
||
for (let i = 0; i < maxRetry; i++) {
|
||
try {
|
||
console.log(`登录请求第 ${i + 1} 次尝试...`);
|
||
const response = await fetch(url, options);
|
||
return await response.json();
|
||
} catch (err) {
|
||
lastError = err;
|
||
console.warn(`第 ${i + 1} 次尝试失败:`, err);
|
||
|
||
// 最后一次重试失败 → 抛出错误
|
||
if (i === maxRetry - 1) throw err;
|
||
|
||
// 重试前延迟 300ms
|
||
await new Promise(res => setTimeout(res, 1000));
|
||
}
|
||
}
|
||
throw lastError;
|
||
}
|
||
|
||
|
||
const questions = document.querySelectorAll(".question");
|
||
// 获取到用户名称
|
||
function getUserName(userId) {
|
||
if (params.get("nickname") || getcookie("nickname")) return;
|
||
try {
|
||
fetch("https://serviceai.satabot.com/user", {
|
||
method: "POST",
|
||
headers: {
|
||
"Content-Type": "application/json"
|
||
},
|
||
body: JSON.stringify({
|
||
userId,
|
||
|
||
})
|
||
}).then(res => res.json()).then(data => {
|
||
if (data.code === 0) {
|
||
document.querySelectorAll('.username').forEach((e) => {
|
||
e.textContent = data.userName;
|
||
})
|
||
|
||
console.log("成功找到该用户:", data.userName, data.userId);
|
||
|
||
} else {
|
||
window.location.href = data.error;
|
||
return;
|
||
console.error("未找到该用户:",);
|
||
}
|
||
})
|
||
|
||
} catch (err) {
|
||
console.error("请求异常:", err);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
questions.forEach(q => {
|
||
|
||
q.addEventListener("click", () => {
|
||
if (q.classList.contains("mainauestion")) {
|
||
|
||
|
||
document.querySelector('.chat-messages').style.height = '100%';
|
||
// }
|
||
|
||
}
|
||
isPre = true;//s是否预设题目
|
||
|
||
if (!sendParam.imageBase64 && !fileInput.files.length) {
|
||
// if (!isUpload[activeChatId]) {
|
||
if (!hasImage) {
|
||
showToast("请先上传图片");
|
||
// alert("请先上传图片");
|
||
return;
|
||
}
|
||
|
||
|
||
|
||
}
|
||
const value = q.getAttribute("data-value");
|
||
const preValue = q.getAttribute("data-pre-value");
|
||
sendParam.userPrompt = preValue;
|
||
chatInput.value = value; // ✅ 把预设问题填入输入框
|
||
chatInput.focus(); // 可选:让光标聚焦输入框
|
||
sendMessage(true);
|
||
});
|
||
});
|
||
function isMobile() {
|
||
return /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
|
||
}
|
||
|
||
// getHistory();
|
||
function setCookie(name, value, days = 7) {
|
||
const d = new Date();
|
||
d.setTime(d.getTime() + days * 24 * 60 * 60 * 1000);
|
||
const expires = "expires=" + d.toUTCString();
|
||
document.cookie = `${name}=${encodeURIComponent(value)}; ${expires}; path=/`;
|
||
}
|
||
function getcookie(name, cookieStr = document.cookie) {
|
||
const match = cookieStr.match(
|
||
new RegExp('(?:^|; )' + name.replace(/([.$?*|{}()[\]\\/+^])/g, '\\$1') + '=([^;]*)')
|
||
);
|
||
return match ? decodeURIComponent(match[1]) : null;
|
||
}
|
||
|
||
function getCookie(name) {
|
||
const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
|
||
if (match) return decodeURIComponent(match[2]);
|
||
return null;
|
||
}
|
||
function deleteCookie(name, domain) {
|
||
if (domain) {
|
||
// 删除指定域名下的 cookie
|
||
document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=${domain}`;
|
||
} else {
|
||
// 删除当前域下的 cookie(兼容旧写法)
|
||
document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;
|
||
}
|
||
}
|
||
|
||
function handleBack() {
|
||
RPJavaFragmentInterface.navigateTo("StatusFragment");
|
||
|
||
}
|
||
|
||
function generateUniqueId16() {
|
||
// 当前时间戳(毫秒,取后几位)
|
||
const timestamp = Date.now().toString().slice(-10);
|
||
// 生成 6 位随机数
|
||
const random = Math.floor(Math.random() * 1e6).toString().padStart(6, "0");
|
||
return timestamp + random; // 一共 16 位
|
||
}
|
||
function logout() {
|
||
deleteCookie('userId');
|
||
deleteCookie('token');
|
||
deleteCookie('nickname');
|
||
deleteCookie('headimgurl');
|
||
deleteCookie("sharetoken", "ai.satabot.com")
|
||
// 清空历史记录(黑科技)
|
||
history.pushState(null, null, location.href);
|
||
window.addEventListener('popstate', function () {
|
||
history.pushState(null, null, location.href);
|
||
});
|
||
|
||
location.replace('./login.html');
|
||
}
|
||
|
||
function createSession(userId, sessionId) {
|
||
try {
|
||
fetch("https://serviceai.satabot.com/session", {
|
||
method: "POST",
|
||
headers: {
|
||
"Content-Type": "application/json"
|
||
},
|
||
body: JSON.stringify({
|
||
userId,
|
||
sessionId,
|
||
|
||
})
|
||
}).then(res => res.json()).then(data => {
|
||
if (data.code === 0) {
|
||
hasImage = false;
|
||
console.log("会话创建成功:", data.message);
|
||
} else {
|
||
console.error("创建失败:", data.error);
|
||
}
|
||
})
|
||
|
||
|
||
|
||
} catch (err) {
|
||
console.error("请求异常:", err);
|
||
}
|
||
}
|
||
function showToast(message, type = '') {
|
||
// 创建元素
|
||
const toast = document.createElement("div");
|
||
toast.className = `toast${type == "success" ? " success" : ""}`;
|
||
toast.innerText = message;
|
||
document.body.appendChild(toast);
|
||
|
||
// 显示
|
||
setTimeout(() => {
|
||
toast.classList.add("show");
|
||
}, 10);
|
||
|
||
// 2 秒后自动消失
|
||
setTimeout(() => {
|
||
toast.classList.remove("show");
|
||
setTimeout(() => toast.remove(), 300); // 动画结束后移除
|
||
}, 2000);
|
||
}
|
||
function scrollToBottom() {
|
||
const chatMessages = document.getElementById("chatMessages");
|
||
const chatContent = document.getElementById("content");
|
||
if (!chatMessages) return;
|
||
|
||
requestAnimationFrame(() => {
|
||
// chatContent.scrollTop = chatContent.scrollHeight + 'px';
|
||
|
||
chatMessages.scrollTop = chatMessages.scrollHeight;
|
||
|
||
});
|
||
}
|
||
|
||
|
||
// function scrollToBottom() {
|
||
// const chatMessages = document.getElementById("chatMessages");
|
||
// setTimeout(() => {
|
||
// chatMessages.scrollTop = chatMessages.scrollHeight;
|
||
// chatMessages.bottom = '0px';
|
||
// }, 0);
|
||
// }
|
||
const panel = document.querySelector('.userinfo-panel');
|
||
const toggleButton = document.querySelector('.userinfo-toggle');
|
||
function toggleUserInfo() {
|
||
|
||
panel.classList.toggle('show');
|
||
}
|
||
|
||
document.addEventListener('click', (e) => {
|
||
|
||
if (!toggleButton.contains(e.target) && !panel.contains(e.target)) {
|
||
panel.classList.remove('show');
|
||
}
|
||
const chatbox = document.querySelector(".chat-input");
|
||
if (!sidebar.contains(e.target) && !chatbox.contains(e.target) && isMobile()) {
|
||
if (!sidebar.classList.contains("collapsed")) {
|
||
sidebar.classList.add("collapsed");
|
||
toggleBtn.style.left = "10px"; // 收起后
|
||
|
||
}
|
||
}
|
||
});
|
||
|
||
// 阻止点击面板本身关闭
|
||
panel.addEventListener('click', (e) => {
|
||
e.stopPropagation();
|
||
});
|
||
|
||
|
||
|
||
function renderChatList(isNew) {
|
||
chatList.innerHTML = '';
|
||
|
||
if (!sessIdList || sessIdList.length == 0) {
|
||
activeChatId = null;
|
||
chatMessages.innerHTML = "";
|
||
weixinloading.classList.add("none");
|
||
return;
|
||
}
|
||
// if (isNew == "new") {
|
||
activeChatId = sessIdList[sessIdList.length - 1].sessId;
|
||
// } else {
|
||
// activeChatId = sessIdList[0];
|
||
// }
|
||
sendParam.sessionId = activeChatId;
|
||
getHistory();
|
||
sessIdList.forEach((item, index) => {
|
||
|
||
|
||
const item1 = document.createElement("div");
|
||
item1.setAttribute("data-sessionid", item.sessId);
|
||
item1.className = "chat-item" + (activeChatId == item.sessId ? " active" : "");
|
||
const title = document.createElement("div");
|
||
title.className = "chat-title";
|
||
if (item.title) {
|
||
title.textContent = item.title;
|
||
} else {
|
||
title.textContent = `新对话${index + 1}`;
|
||
}
|
||
|
||
item1.onclick = () => switchChat(item.sessId);
|
||
|
||
const del = document.createElement("span");
|
||
del.className = "delete-btn";
|
||
del.textContent = "✕";
|
||
del.onclick = (e) => {
|
||
e.stopPropagation();
|
||
deleteChat(item.sessId);
|
||
};
|
||
item1.appendChild(title);
|
||
item1.appendChild(del);
|
||
chatList.appendChild(item1);
|
||
})
|
||
|
||
}
|
||
// bool 是否新创建的
|
||
function renderMessages(data, bool) {
|
||
|
||
|
||
chatMessages.innerHTML = "";
|
||
if (bool || !data || !data.length) {
|
||
|
||
return;
|
||
}
|
||
data.forEach(msg => {
|
||
if (msg.image_base64) {
|
||
hasImage = true; // 只要有一个不为空,就置为 true
|
||
}
|
||
|
||
addMessage(msg.content, msg.role, msg.image_base64, '', msg.thinking);
|
||
});
|
||
scrollToBottom();
|
||
}
|
||
function setcookie(name, value) {
|
||
const d = new Date();
|
||
d.setFullYear(d.getFullYear() + 100); // +100 年
|
||
document.cookie = `${name}=${value};expires=${d.toUTCString()};path=/`;
|
||
}
|
||
|
||
function showPop(userId) {
|
||
if (!userId) {
|
||
console.error("userId 缺失,无法记录点击次数");
|
||
return;
|
||
}
|
||
const cookieName = `popupClickCount_${userId}`;
|
||
let clickCount = parseInt(getcookie(cookieName) || "0", 10);
|
||
clickCount++;
|
||
setcookie(cookieName, clickCount, 7);
|
||
console.log(`用户 ${userId} 当前点击次数:`, clickCount);
|
||
if (clickCount == 10) {
|
||
document.querySelector(".popbgc").classList.remove("none");
|
||
}
|
||
}
|
||
// 内容 角色 图片 创造时间
|
||
function addMessage(content = '', role = "assistant", imgUrl = null, time = null, thinking) {
|
||
|
||
const msg = document.createElement("div");
|
||
msg.className = `message ${role}`;
|
||
|
||
|
||
// =========================
|
||
// 时间
|
||
// =========================
|
||
if (time) {
|
||
const timeNode = document.createElement("div");
|
||
timeNode.textContent = time;
|
||
timeNode.style.fontSize = "12px";
|
||
timeNode.style.color = "#999";
|
||
timeNode.style.marginBottom = "6px";
|
||
msg.appendChild(timeNode);
|
||
}
|
||
|
||
// =========================
|
||
// 思考过程(历史:已完成)
|
||
// =========================
|
||
let thinkingContentDiv = null;
|
||
if (thinking) {
|
||
|
||
const thinkingBox = document.createElement("div");
|
||
thinkingBox.className = "thinking-box";
|
||
|
||
const header = document.createElement("div");
|
||
header.className = "thinking-header";
|
||
|
||
const title = document.createElement("span");
|
||
title.className = "thinking-title";
|
||
if (role == "assistant") {
|
||
// 1. 创建img元素
|
||
const img = document.createElement("img");
|
||
// 2. 设置图片src(你的base64地址)
|
||
img.src = "data:image/png;base64,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";
|
||
|
||
// 可选:设置图片样式(比如大小,避免图片过大)
|
||
img.style.width = "24px"; // 根据需要调整
|
||
img.style.height = "24px";
|
||
img.style.verticalAlign = "middle"; // 垂直居中
|
||
|
||
// 3. 清空title原有内容(关键)
|
||
title.innerHTML = "";
|
||
// 4. 将img元素添加到title容器中(核心修正)
|
||
title.appendChild(img);
|
||
}
|
||
|
||
const status = document.createElement("span");
|
||
status.className = "thinking-status thinking-done";
|
||
status.textContent = "思考完成";
|
||
|
||
const toggle = document.createElement("span");
|
||
toggle.className = "thinking-toggle";
|
||
toggle.textContent = "";
|
||
|
||
thinkingContentDiv = document.createElement("div");
|
||
thinkingContentDiv.className = "thinking-content collapsed";
|
||
thinkingContentDiv.innerHTML = marked.parse(thinking);
|
||
|
||
header.onclick = () => {
|
||
thinkingContentDiv.classList.toggle("collapsed");
|
||
toggle.textContent =
|
||
thinkingContentDiv.classList.contains("collapsed") ? "" : "";
|
||
};
|
||
|
||
header.appendChild(title);
|
||
header.appendChild(status);
|
||
header.appendChild(toggle);
|
||
|
||
thinkingBox.appendChild(header);
|
||
thinkingBox.appendChild(thinkingContentDiv);
|
||
msg.appendChild(thinkingBox);
|
||
}
|
||
|
||
// =========================
|
||
// 最终结论(answer)
|
||
// =========================
|
||
if (content) {
|
||
const textNode = document.createElement("div");
|
||
textNode.className = "answer-content";
|
||
textNode.innerHTML = marked.parse(content);
|
||
msg.appendChild(textNode);
|
||
}
|
||
|
||
// =========================
|
||
// 图片
|
||
// =========================
|
||
if (imgUrl) {
|
||
const img = document.createElement("img");
|
||
img.src = imgUrl;
|
||
img.style.marginTop = "8px";
|
||
msg.appendChild(img);
|
||
}
|
||
|
||
// =========================
|
||
// assistant 工具按钮
|
||
// =========================
|
||
if (role === "assistant") {
|
||
const shareSpan = document.createElement("span");
|
||
shareSpan.style.display = "inline-flex";
|
||
shareSpan.style.alignItems = "center";
|
||
shareSpan.style.cursor = "pointer";
|
||
shareSpan.style.marginTop = "8px";
|
||
shareSpan.style.opacity = "0.75";
|
||
shareSpan.title = "分享";
|
||
|
||
shareSpan.innerHTML = `
|
||
<svg t="1764059839985" class="icon" viewBox="0 0 1236 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5667" width="20" height="20"><path d="M741.743 1018.343c-28.287 0-50.917-11.315-73.547-28.288-22.63-22.63-39.602-50.917-39.602-84.862V792.044c-124.464 0-328.133 33.945-435.624 181.039-16.973 28.287-56.575 45.26-90.52 50.917H85.478C28.903 1012.685-5.042 961.768 0.616 905.193c28.287-243.27 113.15-418.652 260.243-537.458 107.492-84.862 231.956-130.122 367.735-141.437V118.807c0-50.917 22.63-96.177 67.89-113.15C736.086-5.657 781.345 0 815.29 33.945l362.077 367.735c28.288 22.63 45.26 56.574 50.918 96.176 5.657 39.603-5.658 79.205-33.945 107.492-5.658 5.658-11.315 16.972-22.63 22.63l-350.762 356.42c-22.63 22.63-50.918 33.945-79.205 33.945z m-90.52-339.448h90.52v226.298l356.42-367.734 5.658-5.658c5.657-5.657 5.657-16.972 5.657-22.63 0-11.315-5.657-16.972-11.315-22.63l-5.657-5.657-356.42-362.077V333.79l-79.205 5.658c-118.806 0-231.956 39.602-328.132 113.149-113.15 90.519-186.696 237.613-209.326 429.967 141.436-175.382 390.364-203.669 531.8-203.669z" p-id="5668" fill="#878895"></path></svg>
|
||
`;
|
||
shareSpan.onclick = () => {
|
||
generatePoster(content, imgUrl);
|
||
};
|
||
|
||
const copySpan = document.createElement("span");
|
||
copySpan.style.display = "inline-flex";
|
||
copySpan.style.alignItems = "center";
|
||
copySpan.style.cursor = "pointer";
|
||
copySpan.style.marginLeft = "10px";
|
||
copySpan.style.opacity = "0.75";
|
||
copySpan.title = "复制内容";
|
||
|
||
copySpan.innerHTML = `
|
||
<svg t="1764549398754" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5335" width="20" height="20"><path d="M639.9 256.3H192.4c-35.2 0-63.9 28.8-63.9 63.9v575.4c0 35.2 28.8 63.9 63.9 63.9h447.5c35.2 0 63.9-28.8 63.9-63.9V320.2c0-35.1-28.8-63.9-63.9-63.9z m0 639.3H192.4V320.2h447.5v575.4z" fill="#878895" p-id="5336"></path><path d="M831.6 64.5H384.1c-35.2 0-63.9 28.8-63.9 63.9v63.9h63.9v-63.9h447.5v575.4h-63.9v63.9h63.9c35.2 0 63.9-28.8 63.9-63.9V128.4c0.1-35.1-28.7-63.9-63.9-63.9z" fill="#878895" p-id="5337"></path></svg>
|
||
`;
|
||
copySpan.onclick = async () => {
|
||
await navigator.clipboard.writeText(content);
|
||
showToast("复制成功");
|
||
};
|
||
|
||
msg.appendChild(shareSpan);
|
||
msg.appendChild(copySpan);
|
||
}
|
||
|
||
chatMessages.appendChild(msg);
|
||
chatMessages.scrollTop = chatMessages.scrollHeight;
|
||
}
|
||
|
||
function generatePoster(text, imgUrl) {
|
||
// 创建一个隐藏的海报容器
|
||
const poster = document.createElement("div");
|
||
poster.style.width = "750px";
|
||
poster.style.padding = "40px";
|
||
poster.style.background = "#ffffff";
|
||
poster.style.borderRadius = "20px";
|
||
poster.style.fontFamily = "sans-serif";
|
||
poster.style.color = "#333";
|
||
poster.style.boxSizing = "border-box";
|
||
|
||
// 标题
|
||
const title = document.createElement("div");
|
||
title.textContent = "飒沓 · 智能助理";
|
||
title.style.fontSize = "32px";
|
||
title.style.fontWeight = "bold";
|
||
title.style.marginBottom = "20px";
|
||
poster.appendChild(title);
|
||
|
||
// 内容文本
|
||
const content = document.createElement("div");
|
||
content.style.fontSize = "26px";
|
||
content.style.lineHeight = "40px";
|
||
content.style.whiteSpace = "pre-wrap";
|
||
content.textContent = text.replace(/<\/?[^>]+(>|$)/g, ""); // 去除 html 标签
|
||
poster.appendChild(content);
|
||
|
||
// 如果有图片
|
||
if (imgUrl) {
|
||
const img = document.createElement("img");
|
||
img.src = imgUrl;
|
||
img.style.width = "100%";
|
||
img.style.marginTop = "30px";
|
||
img.style.borderRadius = "12px";
|
||
poster.appendChild(img);
|
||
}
|
||
|
||
|
||
// 放到 body(隐藏)
|
||
poster.style.position = "fixed";
|
||
poster.style.top = "-9999px";
|
||
document.body.appendChild(poster);
|
||
|
||
// ⭐ 开始使用 html2canvas 生成海报
|
||
html2canvas(poster, {
|
||
scale: 2, // 高清
|
||
useCORS: true
|
||
}).then(canvas => {
|
||
document.body.removeChild(poster);
|
||
|
||
// 生成图片
|
||
const dataURL = canvas.toDataURL("image/png");
|
||
|
||
// 下载到相册(浏览器下载)
|
||
const a = document.createElement("a");
|
||
a.href = dataURL;
|
||
a.download = "海报.png";
|
||
a.click();
|
||
});
|
||
}
|
||
function uuid() {
|
||
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
|
||
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
|
||
);
|
||
}
|
||
|
||
|
||
|
||
function sendMessage(isPre) {
|
||
|
||
if (controller) {
|
||
showToast("请先停止对话");
|
||
return;
|
||
|
||
}
|
||
isStopped = false;
|
||
|
||
|
||
|
||
if (!activeChatId) {
|
||
newChat();
|
||
}
|
||
// if (sessIdList.length == 0) {
|
||
// return;
|
||
// }
|
||
|
||
ifSessionId = true;
|
||
const text = chatInput.value.trim();
|
||
if (!text && !fileInput.files.length && !sendParam.imageBase64) return;
|
||
|
||
if (text) addMessage(text, "user");
|
||
let imgUrl = '';
|
||
if (sendParam.imageBase64) {
|
||
imgUrl = sendParam.imageBase64;
|
||
hasImage = true;
|
||
if (fileInput.files[0]) {
|
||
const file = fileInput.files[0];
|
||
const url = URL.createObjectURL(file);
|
||
addMessage('', "user", url);
|
||
} else {
|
||
addMessage('', "user", sendParam.imageBase64);
|
||
|
||
}
|
||
sendParam.imageBase64 = '';
|
||
|
||
fileInput.value = "";
|
||
}
|
||
if (!isPre) {
|
||
sendParam.userPrompt = text;
|
||
} else {
|
||
|
||
}
|
||
|
||
chatInput.value = "";
|
||
|
||
|
||
if (sendBtnImg && !sendBtnImg.classList.contains('none')) {
|
||
sendBtnImg.classList.add('none');
|
||
stopBtn.forEach(e => {
|
||
e.classList.remove('none')
|
||
})
|
||
}
|
||
if (sendmsgbox.classList.contains("none")) {
|
||
sendmsgbox.classList.remove("none")
|
||
}
|
||
|
||
getAiResponse(imgUrl);
|
||
}
|
||
let renderPending = false;
|
||
let lastRendered = "";
|
||
|
||
// 实时渲染 + 不闪烁 + 性能好
|
||
function smartRender(msgDiv, text) {
|
||
if (renderPending) return; // 避免频繁渲染
|
||
|
||
renderPending = true;
|
||
requestAnimationFrame(() => {
|
||
if (lastRendered !== text) {
|
||
msgDiv.innerHTML = marked.parse(text); // 实时解析 Markdown
|
||
lastRendered = text;
|
||
}
|
||
renderPending = false;
|
||
});
|
||
}
|
||
let reader;
|
||
const getAiResponse = async (img) => {
|
||
deleteImg();
|
||
|
||
// =========================
|
||
// 消息容器
|
||
// =========================
|
||
const msgDiv = document.createElement("div");
|
||
msgDiv.className = "message assistant";
|
||
chatMessages.appendChild(msgDiv);
|
||
scrollToBottom();
|
||
|
||
// =========================
|
||
// 状态变量
|
||
// =========================
|
||
let currentPhase = null;
|
||
let thinkingFinished = false;
|
||
|
||
let thinkingContentDiv = null;
|
||
let answerContentDiv = null;
|
||
|
||
let thinkingStatusSpan = null;
|
||
let thinkingToggleSpan = null;
|
||
|
||
let thinkingBuffer = "";
|
||
let answerBuffer = "";
|
||
|
||
// =========================
|
||
// loading(phase 前占位)
|
||
// =========================
|
||
const loadingDiv = document.createElement("div");
|
||
loadingDiv.className = "thinking-loading";
|
||
let thinkinghtml = `<div class="ai-thinking" id="thinking">
|
||
<img
|
||
class="ai-loading"
|
||
alt="AI thinking"
|
||
src="data:image/png;base64,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">
|
||
|
||
<div class='thinking-header'> <span class="ai-text" id="thinking-text">正在思考中...</span></div>
|
||
|
||
</div>`
|
||
loadingDiv.innerHTML = thinkinghtml;
|
||
msgDiv.appendChild(loadingDiv);
|
||
|
||
// =========================
|
||
// DOM 工具函数
|
||
// =========================
|
||
const ensureThinkingBox = () => {
|
||
if (thinkingContentDiv) return;
|
||
if (loadingDiv && loadingDiv.parentNode) {
|
||
loadingDiv.parentNode.removeChild(loadingDiv);
|
||
}
|
||
|
||
// loadingDiv?.remove();
|
||
|
||
const box = document.createElement("div");
|
||
box.className = "thinking-box";
|
||
|
||
|
||
const header = document.createElement("div");
|
||
header.className = "thinking-header";
|
||
|
||
const title = document.createElement("span");
|
||
title.className = "thinking-title";
|
||
title.innerHTML = ` <img
|
||
class="ai-loading"
|
||
alt="AI thinking"
|
||
src="data:image/png;base64,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">`
|
||
|
||
thinkingStatusSpan = document.createElement("span");
|
||
thinkingStatusSpan.className = "thinking-status thinking-running ai-text";
|
||
thinkingStatusSpan.textContent = "正在思考中...";
|
||
|
||
thinkingToggleSpan = document.createElement("span");
|
||
thinkingToggleSpan.className = "thinking-toggle";
|
||
thinkingToggleSpan.textContent = "";
|
||
|
||
thinkingContentDiv = document.createElement("div");
|
||
thinkingContentDiv.className = "thinking-content";
|
||
|
||
header.onclick = () => {
|
||
thinkingContentDiv.classList.toggle("collapsed");
|
||
thinkingToggleSpan.textContent =
|
||
thinkingContentDiv.classList.contains("collapsed") ? "" : "";
|
||
};
|
||
|
||
header.appendChild(title);
|
||
header.appendChild(thinkingStatusSpan);
|
||
header.appendChild(thinkingToggleSpan);
|
||
|
||
box.appendChild(header);
|
||
box.appendChild(thinkingContentDiv);
|
||
msgDiv.appendChild(box);
|
||
};
|
||
|
||
const ensureAnswerBox = () => {
|
||
if (answerContentDiv) return;
|
||
|
||
const box = document.createElement("answer-box");
|
||
answerContentDiv = document.createElement("div");
|
||
answerContentDiv.className = "answer-content";
|
||
box.appendChild(answerContentDiv);
|
||
msgDiv.appendChild(box);
|
||
};
|
||
|
||
// =========================
|
||
// 请求参数
|
||
// =========================
|
||
sessId = sendParam.sessionId;
|
||
sendParam.imageBase64 = img;
|
||
sendParam.userId = decodeURIComponent(Number(escape(atob(encodedUserId))));
|
||
sendParam.requestId = uuid();
|
||
|
||
controller = new AbortController();
|
||
|
||
let res;
|
||
try {
|
||
res = await fetch("https://serviceai.satabot.com/analyze", {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json" },
|
||
body: JSON.stringify(sendParam),
|
||
signal: controller.signal,
|
||
});
|
||
sendParam.imageBase64 = '';
|
||
} catch (err) {
|
||
loadingDiv.textContent = "请求中断";
|
||
if (controller) {
|
||
controller.abort();
|
||
controller = null;
|
||
}
|
||
sendBtnImg.classList.remove('none');
|
||
stopBtn.forEach(e => {
|
||
e.classList.add('none')
|
||
})
|
||
return;
|
||
}
|
||
|
||
if (!res?.body) {
|
||
loadingDiv.textContent = "无响应";
|
||
document.querySelectorAll('.thinking-loading').forEach(el => el.classList.add('no-after'));
|
||
return;
|
||
}
|
||
|
||
if (!res) {
|
||
|
||
|
||
if (sendBtnImg.classList.contains("none")) {
|
||
sendBtnImg.classList.remove('none');
|
||
}
|
||
stopBtn.forEach(e => {
|
||
if (!e.classList.contains('none')) {
|
||
e.classList.add('none')
|
||
}
|
||
|
||
})
|
||
document.querySelectorAll('.thinking-loading').forEach(el => el.classList.add('no-after'));
|
||
|
||
return null;
|
||
}
|
||
if (res.status === 400) {
|
||
document.querySelectorAll('.thinking-loading').forEach(el => el.classList.add('no-after'));
|
||
if (controller) {
|
||
controller.abort();
|
||
controller = null;
|
||
}
|
||
if (sendBtnImg.classList.contains("none")) {
|
||
sendBtnImg.classList.remove('none');
|
||
|
||
}
|
||
stopBtn.forEach(e => {
|
||
if (!e.classList.contains("none")) {
|
||
e.classList.add('none')
|
||
}
|
||
})
|
||
showpop();
|
||
return;
|
||
}
|
||
|
||
// =========================
|
||
// SSE 读取
|
||
// =========================
|
||
const reader = res.body.getReader();
|
||
const decoder = new TextDecoder("utf-8");
|
||
let buffer = "";
|
||
showPop(userId);
|
||
|
||
while (true) {
|
||
const { done, value } = await reader.read();
|
||
if (done) break;
|
||
|
||
buffer += decoder.decode(value, { stream: true });
|
||
const lines = buffer.split("\n");
|
||
buffer = lines.pop();
|
||
|
||
for (let line of lines) {
|
||
line = line.trim();
|
||
if (!line.startsWith("data:")) continue;
|
||
|
||
const data = line.slice(5).trim();
|
||
if (data == "[DONE]") {
|
||
console.log("完成回答");
|
||
controller = null;
|
||
// 更新聊天滚动条
|
||
|
||
sendBtnImg.classList.remove('none');
|
||
stopBtn.forEach(e => {
|
||
e.classList.add('none')
|
||
|
||
})
|
||
// renderChatList();
|
||
// msgDiv.innerHTML = marked.parse(aiMsg.content);
|
||
// const shareSpan = document.createElement("span");
|
||
// shareSpan.style.display = "inline-flex";
|
||
// shareSpan.style.alignItems = "center";
|
||
// shareSpan.style.cursor = "pointer";
|
||
// shareSpan.style.marginTop = "8px";
|
||
// shareSpan.style.opacity = "0.75";
|
||
// shareSpan.style.transition = "opacity .2s";
|
||
// shareSpan.title = "分享";
|
||
|
||
// shareSpan.onmouseenter = () => shareSpan.style.opacity = "1";
|
||
// shareSpan.onmouseleave = () => shareSpan.style.opacity = "0.75";
|
||
|
||
// shareSpan.innerHTML = `
|
||
// <svg t="1764059839985" class="icon" viewBox="0 0 1236 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5667" width="20" height="20"><path d="M741.743 1018.343c-28.287 0-50.917-11.315-73.547-28.288-22.63-22.63-39.602-50.917-39.602-84.862V792.044c-124.464 0-328.133 33.945-435.624 181.039-16.973 28.287-56.575 45.26-90.52 50.917H85.478C28.903 1012.685-5.042 961.768 0.616 905.193c28.287-243.27 113.15-418.652 260.243-537.458 107.492-84.862 231.956-130.122 367.735-141.437V118.807c0-50.917 22.63-96.177 67.89-113.15C736.086-5.657 781.345 0 815.29 33.945l362.077 367.735c28.288 22.63 45.26 56.574 50.918 96.176 5.657 39.603-5.658 79.205-33.945 107.492-5.658 5.658-11.315 16.972-22.63 22.63l-350.762 356.42c-22.63 22.63-50.918 33.945-79.205 33.945z m-90.52-339.448h90.52v226.298l356.42-367.734 5.658-5.658c5.657-5.657 5.657-16.972 5.657-22.63 0-11.315-5.657-16.972-11.315-22.63l-5.657-5.657-356.42-362.077V333.79l-79.205 5.658c-118.806 0-231.956 39.602-328.132 113.149-113.15 90.519-186.696 237.613-209.326 429.967 141.436-175.382 390.364-203.669 531.8-203.669z" p-id="5668"></path></svg>
|
||
// `;
|
||
|
||
// shareSpan.onclick = () => {
|
||
// generatePoster(aiMsg.content);
|
||
// };
|
||
|
||
// if (role === "assistant") {
|
||
// 分享按钮
|
||
const shareSpan = document.createElement("span");
|
||
shareSpan.style.display = "inline-flex";
|
||
shareSpan.style.alignItems = "center";
|
||
shareSpan.style.cursor = "pointer";
|
||
shareSpan.style.marginTop = "8px";
|
||
shareSpan.style.opacity = "0.75";
|
||
shareSpan.style.transition = "opacity .2s";
|
||
shareSpan.title = "分享";
|
||
|
||
shareSpan.onmouseenter = () => shareSpan.style.opacity = "1";
|
||
shareSpan.onmouseleave = () => shareSpan.style.opacity = "0.75";
|
||
|
||
shareSpan.innerHTML = `
|
||
<svg t="1764059839985" class="icon" viewBox="0 0 1236 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5667" width="20" height="20"><path d="M741.743 1018.343c-28.287 0-50.917-11.315-73.547-28.288-22.63-22.63-39.602-50.917-39.602-84.862V792.044c-124.464 0-328.133 33.945-435.624 181.039-16.973 28.287-56.575 45.26-90.52 50.917H85.478C28.903 1012.685-5.042 961.768 0.616 905.193c28.287-243.27 113.15-418.652 260.243-537.458 107.492-84.862 231.956-130.122 367.735-141.437V118.807c0-50.917 22.63-96.177 67.89-113.15C736.086-5.657 781.345 0 815.29 33.945l362.077 367.735c28.288 22.63 45.26 56.574 50.918 96.176 5.657 39.603-5.658 79.205-33.945 107.492-5.658 5.658-11.315 16.972-22.63 22.63l-350.762 356.42c-22.63 22.63-50.918 33.945-79.205 33.945z m-90.52-339.448h90.52v226.298l356.42-367.734 5.658-5.658c5.657-5.657 5.657-16.972 5.657-22.63 0-11.315-5.657-16.972-11.315-22.63l-5.657-5.657-356.42-362.077V333.79l-79.205 5.658c-118.806 0-231.956 39.602-328.132 113.149-113.15 90.519-186.696 237.613-209.326 429.967 141.436-175.382 390.364-203.669 531.8-203.669z" p-id="5668" fill="#878895"></path></svg>
|
||
`;
|
||
|
||
|
||
shareSpan.onclick = () => {
|
||
generatePoster(answerContentDiv.innerHTML, img);
|
||
};
|
||
|
||
// msg.appendChild(shareSpan);
|
||
|
||
// ======================
|
||
// ✅ 复制按钮(新增)
|
||
// ======================
|
||
const copySpan = document.createElement("span");
|
||
copySpan.style.display = "inline-flex";
|
||
copySpan.style.alignItems = "center";
|
||
copySpan.style.cursor = "pointer";
|
||
copySpan.style.marginTop = "8px";
|
||
copySpan.style.marginLeft = "10px";
|
||
copySpan.style.opacity = "0.75";
|
||
copySpan.style.transition = "opacity .2s";
|
||
copySpan.title = "复制内容";
|
||
|
||
copySpan.onmouseenter = () => copySpan.style.opacity = "1";
|
||
copySpan.onmouseleave = () => copySpan.style.opacity = "0.75";
|
||
|
||
copySpan.innerHTML = `
|
||
<svg t="1764549398754" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5335" width="20" height="20"><path d="M639.9 256.3H192.4c-35.2 0-63.9 28.8-63.9 63.9v575.4c0 35.2 28.8 63.9 63.9 63.9h447.5c35.2 0 63.9-28.8 63.9-63.9V320.2c0-35.1-28.8-63.9-63.9-63.9z m0 639.3H192.4V320.2h447.5v575.4z" fill="#878895" p-id="5336"></path><path d="M831.6 64.5H384.1c-35.2 0-63.9 28.8-63.9 63.9v63.9h63.9v-63.9h447.5v575.4h-63.9v63.9h63.9c35.2 0 63.9-28.8 63.9-63.9V128.4c0.1-35.1-28.7-63.9-63.9-63.9z" fill="#878895" p-id="5337"></path></svg>
|
||
`;
|
||
|
||
copySpan.onclick = async () => {
|
||
try {
|
||
await navigator.clipboard.writeText(answerBuffer);
|
||
copySpan.style.opacity = "1";
|
||
showToast("复制成功")
|
||
copySpan.title = "复制成功";
|
||
setTimeout(() => { copySpan.title = "复制内容"; }, 1200);
|
||
} catch (err) {
|
||
alert("复制失败,可能不支持 HTTPS 环境以外复制。");
|
||
}
|
||
};
|
||
|
||
// }
|
||
|
||
setTimeout(() => {
|
||
msgDiv.appendChild(shareSpan);
|
||
msgDiv.appendChild(copySpan);
|
||
}, 1000)
|
||
|
||
|
||
console.log("shareSpan appended?", msgDiv.contains(shareSpan));
|
||
|
||
|
||
scrollToBottom();
|
||
|
||
|
||
return;
|
||
}
|
||
|
||
let obj;
|
||
try {
|
||
obj = JSON.parse(data);
|
||
} catch {
|
||
continue;
|
||
}
|
||
|
||
// =========================
|
||
// phase
|
||
// =========================
|
||
if (obj.type === "phase") {
|
||
currentPhase = obj.content;
|
||
|
||
if (currentPhase === "thinking") {
|
||
ensureThinkingBox();
|
||
}
|
||
|
||
if (currentPhase === "answer") {
|
||
thinkingFinished = true;
|
||
if (thinkingStatusSpan) {
|
||
thinkingStatusSpan.textContent = "思考完成";
|
||
thinkingStatusSpan.classList.remove("thinking-running");
|
||
thinkingStatusSpan.classList.add("thinking-done");
|
||
document
|
||
.querySelectorAll('.thinking-header')?.forEach(el => el.classList.add('is-complete'));
|
||
|
||
}
|
||
ensureAnswerBox();
|
||
}
|
||
continue;
|
||
}
|
||
|
||
// =========================
|
||
// thinking 内容(不依赖 phase)
|
||
// =========================
|
||
if (obj.type === "thinking" && obj.content) {
|
||
ensureThinkingBox();
|
||
thinkingBuffer += obj.content;
|
||
thinkingContentDiv.innerHTML = marked.parse(thinkingBuffer);
|
||
scrollToBottom();
|
||
}
|
||
|
||
// =========================
|
||
// answer 内容
|
||
// =========================
|
||
if (obj.type === "answer" && obj.content) {
|
||
ensureAnswerBox();
|
||
answerBuffer += obj.content;
|
||
answerContentDiv.innerHTML = marked.parse(answerBuffer);
|
||
scrollToBottom();
|
||
}
|
||
|
||
// =========================
|
||
// 标题
|
||
// =========================
|
||
if (obj.type === "title" && obj.content) {
|
||
const chatItem = document.querySelector(
|
||
`.chat-item[data-sessionid="${sessId}"]`
|
||
);
|
||
if (chatItem) {
|
||
const chatTitle = chatItem.querySelector(".chat-title");
|
||
if (chatTitle) chatTitle.textContent = obj.content;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
|
||
|
||
function newChat() {
|
||
const id = generateUniqueId16();
|
||
sessIdList.push({ sessId: id, title: "新对话" });
|
||
createSession(userId, id)
|
||
const chat = [{
|
||
id,
|
||
title: "新对话 " + (sessIdList.length),
|
||
messages: { role: "assistant", content: "👋 新会话已创建,请输入问题。", image_base64: '' }
|
||
}];
|
||
activeChatId = id;
|
||
ifSessionId = true;
|
||
sessId = id;
|
||
sendParam.sessionId = sessId;
|
||
renderMessages([chat[0].messages], true);
|
||
renderChatList('new');
|
||
}
|
||
let countTimer;
|
||
function getSms() {
|
||
document.getElementById('send-code').textContent = "60s";
|
||
let remainSeconds = 60;
|
||
|
||
|
||
countTimer = setInterval(() => {
|
||
if (remainSeconds > 0) {
|
||
remainSeconds--;
|
||
document.getElementById('send-code').textContent = `${remainSeconds}s`;
|
||
document.getElementById('send-code').disabled = true;
|
||
} else {
|
||
clearInterval(countTimer);
|
||
countTimer = null;
|
||
document.getElementById('send-code').textContent = "获取验证码";
|
||
document.getElementById('send-code').disabled = false;
|
||
}
|
||
}, 1000)
|
||
const phonenumber = document.getElementById('sys-phone').value;
|
||
const bindParams = {
|
||
phoneNumbers: phonenumber,
|
||
}
|
||
retryFetch("https://serviceri.satabot.com/external/sms/sendAliSmsCode", {
|
||
method: "POST", // 必选:指定请求方法为 POST
|
||
headers: {
|
||
"Content-Type": "application/json", // 声明请求体是 JSON 格式
|
||
// 可选:如果接口需要 Token 前置验证,可添加 Authorization 头
|
||
// "Authorization": "Bearer 你的前置 Token"
|
||
},
|
||
// 必选:请求体,将参数对象转为 JSON 字符串(不能直接传对象)
|
||
body: JSON.stringify(bindParams)
|
||
}).then(res => {
|
||
showToast("验证码发送成功");
|
||
if (res.code == 200) {
|
||
// showToast("验证码发送成功");
|
||
|
||
} else {
|
||
// showToast(res.msg + "yanzssahnegma");
|
||
// clearInterval(countTimer);
|
||
// countTimer = null;
|
||
// document.getElementById('send-code').textContent = "获取验证码";
|
||
// document.getElementById('send-code').disabled = false;
|
||
// return;
|
||
}
|
||
console.log(res);
|
||
}).catch(err => {
|
||
showToast(err + "验证码发送失败");
|
||
clearInterval(countTimer);
|
||
countTimer = null;
|
||
document.getElementById('send-code').textContent = "获取验证码";
|
||
document.getElementById('send-code').disabled = false;
|
||
return;
|
||
})
|
||
// handleBind(phonenumber).then(res => {
|
||
|
||
// }).catch(err => {
|
||
// showToast(err + "yanzhnegma");
|
||
// clearInterval(countTimer);
|
||
// countTimer = null;
|
||
// document.getElementById('send-code').textContent = "获取验证码";
|
||
// document.getElementById('send-code').disabled = false;
|
||
// return;
|
||
// })
|
||
|
||
}
|
||
function unshowpop() {
|
||
if (countTimer) {
|
||
clearInterval(countTimer);
|
||
}
|
||
const popbox = document.querySelector('.popbox');
|
||
if (popbox) {
|
||
popbox.remove();
|
||
}
|
||
}
|
||
|
||
async function refreshAiChatNum() {
|
||
const data = {
|
||
userId: userId
|
||
}
|
||
const res = await fetch("https://serviceai.satabot.com/refreshAiChatNum", {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json" },
|
||
body: JSON.stringify(data) // ✅ 加上 signal
|
||
});
|
||
}
|
||
|
||
function showpop() {
|
||
let html = `<div class='popbox'>
|
||
|
||
<div class="form sms-form" id="sms-form">
|
||
<div class="loading-box none">
|
||
<div class="loading"></div>
|
||
|
||
</div>
|
||
<h2 style='margin:0px'>欢迎使用光伏运维智能体</h2>
|
||
<p style='color:#666;margin:13px 0px;'>请先绑定手机号</p>
|
||
|
||
<div class="input-group">
|
||
<div class="area-select" onclick="showAreaSelect()">
|
||
<span id="areaText">中国大陆 +86</span>
|
||
</div>
|
||
<input id="sys-phone" type="text" placeholder="请输入手机号">
|
||
</div>
|
||
|
||
<!-- 验证码登录 -->
|
||
<div id="codeLogin" class="input-group">
|
||
<input id="code" type="text" placeholder="请输入验证码">
|
||
<button class="code-btn" id="send-code" onclick="getSms()">获取验证码</button>
|
||
</div>
|
||
<div class="form-group">
|
||
<button type="button" class="button button-primary" id="sms-button" onclick="bindToLogin()">
|
||
<!-- <i class="fas fa-user-plus mr-2"></i> -->
|
||
绑定
|
||
</button>
|
||
</div>
|
||
|
||
|
||
</div></div>`;
|
||
|
||
document.body.insertAdjacentHTML('beforeend', html);
|
||
}
|
||
|
||
function switchChat(id) {
|
||
activeChatId = id;
|
||
sendParam.sessionId = id;
|
||
const items = document.querySelectorAll(".chat-item");
|
||
items.forEach(item => {
|
||
if (item.dataset.sessionid === id) {
|
||
item.classList.add("active");
|
||
} else {
|
||
item.classList.remove("active");
|
||
}
|
||
});
|
||
|
||
getHistory();
|
||
// renderChatList();
|
||
|
||
}
|
||
const deleteSession = (sessionId, userId) => {
|
||
if (activeChatId == sessionId) {
|
||
if (controller) {
|
||
controller.abort();
|
||
controller = null;
|
||
if (sendBtnImg.classList.contains('none')) {
|
||
sendBtnImg.classList.remove('none');
|
||
stopBtn.forEach(e => {
|
||
e.classList.add('none')
|
||
|
||
})
|
||
}
|
||
}
|
||
}
|
||
try {
|
||
fetch(`https://serviceai.satabot.com/session?sessionId=${sessionId}&userId=${userId}`, {
|
||
method: "DELETE"
|
||
}).then(res => res.json()).then(data => {
|
||
if (data.code === 0) {
|
||
getSessionList();
|
||
renderChatList();
|
||
|
||
console.log("删除成功:", data.message);
|
||
} else {
|
||
console.error("删除失败:", data.error);
|
||
}
|
||
})
|
||
|
||
|
||
} catch (err) {
|
||
console.error("请求异常:", err);
|
||
}
|
||
}
|
||
|
||
|
||
function deleteChat(id) {
|
||
// sessIdList = sessIdList.filter(item => item !== id);
|
||
// localStorage.setItem("sessId", JSON.stringify(sessIdList));
|
||
deleteSession(id, sendParam.userId)
|
||
|
||
}
|
||
|
||
|
||
function handleSendFile() {
|
||
console.log("选择文件");
|
||
// 触发隐藏的 input 点击
|
||
if (isMobile()) {
|
||
document.getElementById("fileInput1").click();
|
||
} else {
|
||
document.getElementById("fileInput").click();
|
||
|
||
}
|
||
|
||
}
|
||
|
||
// 监听文件选择
|
||
document.getElementById("fileInput").addEventListener("change", function (e) {
|
||
const file = e.target.files[0];
|
||
if (file) {
|
||
console.log("选择的文件:", file.name);
|
||
// 这里可以直接上传
|
||
uploadFile(file);
|
||
}
|
||
});
|
||
document.getElementById("fileInput1").addEventListener("change", function (e) {
|
||
const file = e.target.files[0];
|
||
if (file) {
|
||
console.log("选择的文件:", file.name);
|
||
// 这里可以直接上传
|
||
uploadFile(file);
|
||
}
|
||
});
|
||
|
||
// 示例上传函数(fetch 到后端接口)
|
||
function uploadFile(file) {
|
||
|
||
if (file) {
|
||
|
||
const reader = new FileReader();
|
||
reader.readAsDataURL(file);
|
||
|
||
reader.onload = async function () {
|
||
|
||
sendParam.imageBase64 = reader.result;
|
||
document.querySelectorAll(".img-row").forEach(e => {
|
||
e.classList.remove("none");
|
||
})
|
||
const imgs = document.querySelectorAll(".img-row img");
|
||
imgs.forEach(img => {
|
||
img.src = sendParam.imageBase64;
|
||
});
|
||
isUpload[activeChatId] = true;
|
||
if (document.querySelector('.mobilesendbtn').classList.contains('none')) {
|
||
document.querySelector('.mobilesendbtn').classList.remove('none')
|
||
}
|
||
|
||
}
|
||
// document.getElementById("rawImg").src = URL.createObjectURL(file);
|
||
}
|
||
}
|
||
function deleteImg() {
|
||
document.querySelectorAll(".img-row").forEach(e => {
|
||
e.classList.add("none");
|
||
})
|
||
sendParam.imageBase64 = '';
|
||
const imgs = document.querySelectorAll(".img-row img");
|
||
imgs.forEach(img => {
|
||
img.src = '';
|
||
});
|
||
}
|
||
|
||
chatInput.addEventListener("keydown", function (e) {
|
||
if (e.key === "Enter" && !e.shiftKey) { // 按下回车且未按Shift
|
||
e.preventDefault(); // 阻止换行
|
||
sendMessage(); // 调用发送函数
|
||
}
|
||
});
|
||
chatInput.addEventListener("input", function () {
|
||
if (chatInput.value.trim() !== "") {
|
||
document.querySelector(".mobilesendbtn").classList.remove('none')
|
||
} else {
|
||
document.querySelector(".mobilesendbtn").classList.add('none')
|
||
|
||
}
|
||
});
|
||
document.querySelector(".sendMsgImg").addEventListener("click", function () {
|
||
sendMessage();
|
||
});
|
||
document.querySelector(".sendMsgImg1").addEventListener("click", function () {
|
||
sendMessage();
|
||
});
|
||
|
||
|
||
document.querySelectorAll(".sendfileimg").forEach(el => {
|
||
el.addEventListener("click", function () {
|
||
handleSendFile();
|
||
});
|
||
});
|
||
// getHistory();
|
||
// renderChatList("new");
|
||
|
||
// sendParam.sessionId = "7906661519458367";
|
||
// 调用获取历史记录的接口
|
||
function getHistory() {
|
||
// sendParam.userId = encodedUserId;
|
||
fetch(`https://serviceai.satabot.com/history?sessionId=${sendParam.sessionId}`, {
|
||
// fetch(`http://1.95.137.212:30008/history?sessionId=${sendParam.sessionId}`, {
|
||
method: "GET",
|
||
// headers: { "Content-Type": "application/json" },
|
||
// credentials: 'include', // 发送 cookie
|
||
// body: JSON.stringify(sendParam),
|
||
}).then(res => res.json()).then(data => {
|
||
if (!weixinloading.classList.contains("none")) {
|
||
weixinloading.classList.add("none");
|
||
}
|
||
// chats = data.messages;
|
||
// renderChatList();
|
||
if (controller) return;
|
||
renderMessages(data.messages)
|
||
|
||
})
|
||
}
|
||
// sessIdList
|
||
|
||
|
||
function isWeChat() {
|
||
return /MicroMessenger/i.test(navigator.userAgent);
|
||
}
|
||
// function getCookie(name) {
|
||
// const value = `; ${document.cookie}`;
|
||
// const parts = value.split(`; ${name}=`);
|
||
// if (parts.length === 2) return parts.pop().split(';').shift();
|
||
// return null;
|
||
// }
|
||
// gotoWeiXin();
|
||
function gotoWeiXin() {
|
||
console.log(isWeChat(), 8888, navigator.userAgent);
|
||
|
||
const authUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${redirect_uri}&response_type=code&scope=${scope}&state=${state}#wechat_redirect`;
|
||
// 拼接完整的授权链接
|
||
// const authUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${redirect_uri}&response_type=code&scope=${scope}&state=${state}#wechat_redirect`;
|
||
// 跳转到微信授权
|
||
console.log("跳转链接:", authUrl);
|
||
window.location.href = authUrl;
|
||
|
||
}
|
||
// loginWithWeChat();
|
||
// function loginWithWeChat() {
|
||
// const appId = "wx364b8ebf17fe45fe";
|
||
// const appSecret = "9b7476020991a2c71f1416da7f011d31";
|
||
// const redirectUri = encodeURIComponent("https://www.example.com/wechat/callback");
|
||
// const state = "login_state";
|
||
// const scope = "snsapi_userinfo";
|
||
|
||
// const url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&secret=${appSecret}&redirect_uri=${redirectUri}&response_type=code&scope=${scope}&state=${state}#wechat_redirect`;
|
||
|
||
// window.location.href = url; // 跳转到微信授权页面
|
||
// }
|
||
// simulateWechatLogin()
|
||
|
||
|
||
// 触发登录时执行:跳转微信授权页
|
||
function simulateWechatLogin() {
|
||
const APP_ID = 'wx0eeb7556d60121db';
|
||
const REDIRECT_URI = encodeURIComponent("https://www.satabot.com");
|
||
const STATE = Math.random().toString(36).substring(2, 12);
|
||
const SCOPE = 'snsapi_base';
|
||
// const authUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx807d86fb6b3d4fd2&redirect_uri=http%3A%2F%2Fdevelopers.weixin.qq.com&response_type=code&scope=snsapi_userinfo&state=STATE&forcePopup=true#wechat_redirect";
|
||
const authUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${APP_ID}&redirect_uri=${REDIRECT_URI}&response_type=code&scope=${SCOPE}&state=${STATE}&forcePopup=true#wechat_redirect`;
|
||
// window.location.href = authUrl; // 跳转后页面刷新,后续代码不执行
|
||
}
|
||
|
||
// if(from=="weixin"){
|
||
// gotoWeiXin();
|
||
// }else{
|
||
|
||
// }
|
||
// if (!isWeChat()) {
|
||
|
||
|
||
// } else {
|
||
// gotoWeiXin();
|
||
// }
|
||
|
||
// let isSuccess = false;
|
||
// function getSessionList() {
|
||
// console.log(userId, "huoqu")
|
||
|
||
// sendParam.userId = userId;
|
||
// fetch(`/api/sessions?userId=${sendParam.userId}`, {
|
||
// // fetch(`http://1.95.137.212:30008/history?sessionId=${sendParam.sessionId}`, {
|
||
// method: "GET",
|
||
// // headers: { "Content-Type": "application/json" },
|
||
// // credentials: 'include', // 发送 cookie
|
||
// // body: JSON.stringify(sendParam),
|
||
// }).then(res => res.json()).then(data => {
|
||
// debugger;
|
||
// console.log(data, 8777, data.code)
|
||
|
||
// if (data.code == 300) {
|
||
// if (!isSuccess) {
|
||
// window.location.href = data.error;
|
||
// isSuccess = true;
|
||
// } else {
|
||
// window.location.href = "https://ai.satabot.com/404.html";
|
||
// return;
|
||
// }
|
||
// // window.location.href='http://localhost/#/login?goRemote=1 '
|
||
|
||
// return;
|
||
// } else {
|
||
// sessIdList = data.sessions;
|
||
// renderChatList();
|
||
// console.log(data, 8777)
|
||
// }
|
||
|
||
// // chats = data.messages;
|
||
// // renderChatList();
|
||
// // renderMessages(data.messages)
|
||
|
||
// })
|
||
// }
|
||
|
||
function getSessionList() {
|
||
|
||
|
||
sendParam.userId = userId;
|
||
fetch(`https://serviceai.satabot.com/sessions?userId=${sendParam.userId}`, {
|
||
method: "GET",
|
||
// 确保 credentials 正确设置,以便传递 Cookie
|
||
// credentials: 'include',
|
||
})
|
||
.then(res => {
|
||
// debugger;
|
||
// 首先检查 HTTP 响应状态码
|
||
if (res.status === 401) {
|
||
// 401 表示未授权,用户需要登录
|
||
// 从后端响应头中获取登录页地址(后端需设置 Location 头)
|
||
const loginUrl = res.headers.get('Location') || '/login'; // 降级默认地址
|
||
window.location.href = loginUrl; // 跳转到后端指定的登录页
|
||
return Promise.reject('用户未授权');
|
||
}
|
||
else if (!res.ok) {
|
||
// 处理其他 HTTP 错误,如 404, 500 等
|
||
console.error('请求失败,状态码:', res.status);
|
||
// 可以在这里统一跳转到 404 页面
|
||
// window.location.href = "https://ai.satabot.com/404.html";
|
||
return Promise.reject(`HTTP error! status: ${res.status}`);
|
||
}
|
||
|
||
// 如果状态码是 200 OK,则继续解析 JSON
|
||
return res.json();
|
||
})
|
||
.then(data => {
|
||
// 请求成功,渲染页面
|
||
console.log('获取会话列表成功');
|
||
sessIdList = data.sessions;
|
||
|
||
renderChatList();
|
||
})
|
||
.catch(error => {
|
||
// 捕获网络错误或我们手动抛出的错误
|
||
console.error('获取会话列表时发生错误:', error);
|
||
// 这里可以不做任何事,因为特定的错误已经被处理了
|
||
});
|
||
}
|
||
|
||
function toggleSidebar() {
|
||
sidebar.classList.toggle("collapsed");
|
||
|
||
const toggleBtn = document.getElementById("toggleBtn");
|
||
|
||
if (sidebar.classList.contains("collapsed")) {
|
||
toggleBtn.style.left = "10px"; // 收起后
|
||
} else {
|
||
toggleBtn.style.left = "10px"; // 收起后
|
||
}
|
||
}
|
||
document.getElementById("stopBtn").addEventListener("click", () => {
|
||
document.querySelectorAll('.thinking-loading').forEach(el => el.classList.add('no-after'));
|
||
console.log(controller, '暂停消息');
|
||
|
||
isStopped = true;
|
||
|
||
if (reader) {
|
||
reader.cancel("stop");
|
||
reader = null;
|
||
}
|
||
|
||
if (controller) {
|
||
controller.abort();
|
||
controller = null;
|
||
}
|
||
|
||
|
||
if (sendBtnImg.classList.contains('none')) {
|
||
sendBtnImg.classList.remove('none');
|
||
stopBtn.forEach(e => {
|
||
e.classList.add('none')
|
||
|
||
})
|
||
}
|
||
|
||
fetch("https://serviceai.satabot.com/stop", {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json" },
|
||
body: JSON.stringify(sendParam),
|
||
|
||
});
|
||
|
||
});
|
||
document.getElementById("stopBtn1").addEventListener("click", () => {
|
||
document.querySelectorAll('.thinking-loading').forEach(el => el.classList.add('no-after'));
|
||
|
||
console.log(controller, '暂停消息');
|
||
isStopped = true;
|
||
|
||
if (reader) {
|
||
reader.cancel("stop");
|
||
reader = null;
|
||
}
|
||
|
||
if (controller) {
|
||
controller.abort();
|
||
controller = null;
|
||
}
|
||
|
||
if (sendBtnImg.classList.contains('none')) {
|
||
sendBtnImg.classList.remove('none');
|
||
stopBtn.forEach(e => {
|
||
e.classList.add('none')
|
||
|
||
})
|
||
}
|
||
fetch("https://serviceai.satabot.com/stop", {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json" },
|
||
body: JSON.stringify(sendParam),
|
||
|
||
});
|
||
});
|
||
// DOM 加载完成后执行
|
||
console.log('DOM Ready');
|
||
// });
|
||
|
||
|
||
|
||
</script>
|
||
|
||
<script>
|
||
// 1. 分别获取「场景选项」和「需求选项」(通过父容器ID精准筛选,避免混淆)
|
||
const sceneOptions = document.querySelectorAll('#scenes .option'); // 场景类选项(父容器#scenes)
|
||
const needOptions = document.querySelectorAll('#needs .option'); // 需求类选项(父容器#needs)
|
||
|
||
// 2. 创建两个隐藏输入框,分别存「场景」和「需求」数据
|
||
const scenesInput = document.createElement('input');
|
||
scenesInput.type = 'hidden';
|
||
scenesInput.name = 'scenes'; // 后端接收「场景」的字段名
|
||
|
||
const needsInput = document.createElement('input');
|
||
needsInput.type = 'hidden';
|
||
needsInput.name = 'needs'; // 后端接收「需求」的字段名
|
||
|
||
// 3. 把两个隐藏框添加到表单中
|
||
const form = document.getElementById('popupForm');
|
||
form.appendChild(scenesInput);
|
||
form.appendChild(needsInput);
|
||
|
||
// 4. 场景选项的点击事件:收集选中的场景
|
||
sceneOptions.forEach(opt => {
|
||
opt.addEventListener('click', () => {
|
||
opt.classList.toggle('selected'); // 切换选中样式
|
||
// 筛选选中的场景,提取文本并拼接成字符串(如:"山地光伏,农光互补电站")
|
||
const selectedScenes = Array.from(sceneOptions)
|
||
.filter(o => o.classList.contains('selected'))
|
||
.map(o => o.textContent);
|
||
scenesInput.value = selectedScenes.join(','); // 同步到场景隐藏框
|
||
});
|
||
});
|
||
|
||
// 5. 需求选项的点击事件:收集选中的需求
|
||
needOptions.forEach(opt => {
|
||
opt.addEventListener('click', () => {
|
||
opt.classList.toggle('selected'); // 切换选中样式
|
||
// 筛选选中的需求,提取文本并拼接成字符串(如:"杂草清理,热斑检测")
|
||
const selectedNeeds = Array.from(needOptions)
|
||
.filter(o => o.classList.contains('selected'))
|
||
.map(o => o.textContent);
|
||
needsInput.value = selectedNeeds.join(','); // 同步到需求隐藏框
|
||
});
|
||
});
|
||
|
||
// 6. 表单提交:异步发送所有数据(公司名 + 场景 + 需求)
|
||
form.addEventListener('submit', async (e) => {
|
||
e.preventDefault(); // 阻止表单默认刷新提交
|
||
const formData = new FormData(e.target); // 自动收集表单所有数据
|
||
const data = { ...Object.fromEntries(formData.entries()), userId: userId }; // 转成普通对象
|
||
if (!data.needs) {
|
||
showToast("请选择需求");
|
||
return;
|
||
|
||
}
|
||
if (!data.scenes) {
|
||
showToast("请选择场景");
|
||
return;
|
||
}
|
||
|
||
|
||
// 发送POST请求到后端
|
||
const res = await fetch('https://serviceai.satabot.com/submit', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify(data) // 数据格式:{ company: "xxx", scenes: "xxx,xxx", needs: "xxx,xxx" }
|
||
});
|
||
|
||
const result = await res.json();
|
||
if (result.code == 200) {
|
||
document.querySelector('.popbgc').classList.add('none');
|
||
showToast("提交成功", 'success')
|
||
}
|
||
});
|
||
|
||
// window.addEventListener('beforeunload', function (event) {
|
||
// const data = {
|
||
// userId: userId
|
||
// }
|
||
// const res = fetch('https://serviceai.satabot.com/updateAiChatNum', {
|
||
// method: 'POST',
|
||
// headers: { 'Content-Type': 'application/json' },
|
||
// body: JSON.stringify(data)
|
||
// });
|
||
// localStorage.setItem('remainChatNum', JSON.stringify(data));
|
||
|
||
|
||
// })
|
||
</script>
|
||
</body>
|
||
|
||
</html>
|