You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2 lines
47 KiB
2 lines
47 KiB
var ChatbotSDK=function(){"use strict";const n="[ChatbotSDK]";let e=!0;const t={},r={info(t,r){e&&console.log(n,t,void 0!==r?r:"")},warn(t,r){e&&console.warn(n,t,void 0!==r?r:"")},error(e,t){console.error(n,e,void 0!==t?t:"")},time(n){t[n]=Date.now()},timeEnd(r,o){const s=t[r];if(void 0!==s){const i=Date.now()-s;if(delete t[r],e){const e=o?`${o} ${i}ms`:`${r} ${i}ms`;console.log(n,e)}return i}return 0},lifecycleInit(n,e){this.info(`初始化完成 integrateId=${n} requestDomain=${e}`)},lifecycleDestroy(n){this.info(`销毁实例 integrateId=${n}`)},lifecycleSend(n,e){this.info(`发送消息 integrateId=${n} length=${e}`),this.time(`send_${n}`)},lifecycleReply(n,e){const t=this.timeEnd(`send_${n}`,"AI 回复");this.info(`AI 回复 integrateId=${n} length=${e} duration=${t}ms`)},lifecycleError(n,e,t){this.timeEnd(`send_${n}`),this.error(`请求失败 integrateId=${n} status=${e} message=${t}`)},lifecycleClear(n){this.info(`清空会话 integrateId=${n}`)},lifecycleStreamDone(n,e){const t=this.timeEnd(`send_${n}`,"流式回复");this.info(`流式回复完成 integrateId=${n} length=${e} duration=${t}ms`)},lifecycleCategoryChange(n){this.info(`切换知识库分类 categoryId=${n}`)}};const o={"zh-CN":{title:"AI 智能助手",minimize:"最小化",close:"关闭",placeholder:"输入您的问题...",send:"发送",loading:"正在思考...",stream_interrupted:"回复被中断",stream_unstable:"网络不稳定,内容可能不完整",category_placeholder:"选择知识库分类",category_all:"全部分类",category_load_error:"加载分类失败",source_title:"参考来源",source_count:"{n} 条参考来源",source_loading:"加载来源中...",clear:"清空对话",clear_confirm:"确定清空所有对话记录?",history_title:"历史会话",history_empty:"暂无历史会话",history_load_error:"加载会话列表失败",history_delete_confirm:"确定删除该会话?",history_export:"导出",history_delete:"删除",error_network:"网络连接失败,请检查网络",error_timeout:"请求超时,请稍后重试",error_server:"服务器异常,请稍后重试",error_cors:"跨域请求被拦截,请联系管理员将当前域名加入 API 白名单",error_auth:"鉴权失败,请联系管理员",error_forbidden:"无访问权限,请联系管理员配置",error_not_found:"请求的资源不存在",error_rate_limit:"请求过于频繁,请稍后重试",error_unavailable:"服务暂不可用,请稍后重试",error_unknown:"请求发生未知错误",error_send:"发送失败,请稍后重试",error_stream_unsupported:"浏览器不支持流式读取"},en:{title:"AI Assistant",minimize:"Minimize",close:"Close",placeholder:"Type your question...",send:"Send",loading:"Thinking...",stream_interrupted:"Response interrupted",stream_unstable:"Network unstable, content may be incomplete",category_placeholder:"Select category",category_all:"All categories",category_load_error:"Failed to load categories",source_title:"Sources",source_count:"{n} source(s)",source_loading:"Loading sources...",clear:"Clear chat",clear_confirm:"Clear all conversation history?",history_title:"History",history_empty:"No conversations yet",history_load_error:"Failed to load conversations",history_delete_confirm:"Delete this conversation?",history_export:"Export",history_delete:"Delete",error_network:"Network connection failed",error_timeout:"Request timed out, please try again",error_server:"Server error, please try again later",error_cors:"CORS request blocked. Please contact admin to whitelist your domain",error_auth:"Authentication failed, please contact admin",error_forbidden:"Access denied, please contact admin",error_not_found:"Resource not found",error_rate_limit:"Too many requests, please try again later",error_unavailable:"Service temporarily unavailable",error_unknown:"Unknown request error",error_send:"Failed to send, please try again",error_stream_unsupported:"Browser does not support streaming"}};let s="zh-CN";function i(n,e){let t=(o[s]||o["zh-CN"])[n]||o["zh-CN"][n]||n;if(e)for(const[n,r]of Object.entries(e))t=t.replace(`{${n}}`,String(r));return t}let a=null;function c(n){if(!a)throw new Error("API 配置未初始化");return`${a.requestDomain.replace(/\/+$/,"")}${n.startsWith("/")?n:`/${n}`}`}function l(n,e,t){null!=t&&("string"==typeof t&&""===t.trim()||n.set(e,String(t)))}async function d(n,e={},t=3e4){const r=new AbortController,o=setTimeout(()=>r.abort(),t);try{return await fetch(n,Object.assign(Object.assign({},e),{signal:r.signal,mode:"cors",credentials:"include"}))}catch(n){if(n instanceof DOMException&&"AbortError"===n.name)throw new u(i("error_timeout"),"timeout");if(n instanceof TypeError&&n.message.includes("Failed to fetch"))throw new u(i("error_cors"),"cors");throw new u(i("error_network"),"network")}finally{clearTimeout(o)}}class u extends Error{constructor(n,e){super(n),this.name="CskError",this.type=e}}function p(n){switch(n){case 401:return i("error_auth");case 403:return i("error_forbidden");case 404:return i("error_not_found");case 429:return i("error_rate_limit");case 500:return i("error_server");case 502:case 503:return i("error_unavailable");default:return`${i("error_unknown")}(${n})`}}async function m(n){const e=function(n){const e=new URLSearchParams;return e.set("message",n),e.set("chatId",a.chatId),l(e,"roleId",a.integrateId),l(e,"accountId",a.userId),c(`/ai/assistant_app/chat/sync?${e.toString()}`)}(n);r.lifecycleSend(a.integrateId,n.length);try{const n=await d(e);if(!n.ok){const e=p(n.status);throw r.lifecycleError(a.integrateId,String(n.status),e),new u(e,`http_${n.status}`)}const t=await n.text();return r.lifecycleReply(a.integrateId,t.length),t}catch(n){if(n instanceof u)throw n;throw r.lifecycleError(a.integrateId,"unknown",String(n)),new u(i("error_unknown"),"unknown")}}async function h(n,e,t,o,s,m){var h;const g=m?function(n,e){const t=new URLSearchParams;return t.set("message",n),t.set("chatId",a.chatId),t.set("rewriteStrategy","REWRITE"),l(t,"roleId",a.integrateId),l(t,"accountId",a.userId),l(t,"categoryId",null!=e?e:a.categoryId),c(`/ai/assistant_app/chat/rag/sse?${t.toString()}`)}(n,s):function(n,e){const t=new URLSearchParams;return t.set("message",n),t.set("chatId",a.chatId),l(t,"roleId",a.integrateId),l(t,"accountId",a.userId),l(t,"categoryId",null!=e?e:a.categoryId),c(`/ai/assistant_app/chat/sse?${t.toString()}`)}(n,s);let k="";r.lifecycleSend(a.integrateId,n.length);try{const n=await d(g,{},6e4);if(!n.ok){const e=p(n.status);return r.lifecycleError(a.integrateId,String(n.status),e),void o(new u(e,`http_${n.status}`))}const s=null===(h=n.body)||void 0===h?void 0:h.getReader();if(!s)return void o(new u(i("error_stream_unsupported"),"stream_unsupported"));const c=new TextDecoder("utf-8",{stream:!0});let l="";try{for(;;){const{done:n,value:t}=await s.read();if(n)break;l+=c.decode(t,{stream:!0});const r=l.split("\n");l=r.pop()||"";for(const n of r){const t=n.trim();if(t&&!t.startsWith(":"))if(t.startsWith("data:")){const n=t.substring(5).trim();n&&(k+=n,e(n))}else{if("[DONE]"===t)break;t.startsWith("event:")||t.startsWith("id:")||t.startsWith("retry:")||(k+=t,e(t))}}}if(l.trim()){const n=l.trim();if(n.startsWith("data:")){const t=n.substring(5).trim();t&&(k+=t,e(t))}else"[DONE]"!==n&&(k+=n,e(n))}}catch(n){if(!(k.length>0))throw n;e("\n\n"+i("stream_unstable"))}finally{s.releaseLock()}r.lifecycleStreamDone(a.integrateId,k.length),t()}catch(n){n instanceof u?o(n):(r.lifecycleError(a.integrateId,"unknown",String(n)),o(new u(i("error_network"),"network")))}}async function g(n,e){const t=function(n,e){const t=new URLSearchParams;return t.set("message",n),t.set("chatId",a.chatId),t.set("rewriteStrategy","REWRITE"),l(t,"roleId",a.integrateId),l(t,"accountId",a.userId),l(t,"categoryId",null!=e?e:a.categoryId),c(`/ai/assistant_app/rag/sources?${t.toString()}`)}(n,e);try{const n=await d(t);if(!n.ok)throw new u(p(n.status),`http_${n.status}`);const e=await n.json();return e.success&&Array.isArray(e.data)?(r.info(`获取引用来源 count=${e.data.length}`),e.data):[]}catch(n){return r.error("获取引用来源失败",n),[]}}async function k(n=1,e=20,t,o){let s=`/conversation/list?page=${n}&size=${e}`;t&&(s+=`&accountId=${encodeURIComponent(t)}`),o&&(s+=`&roleId=${encodeURIComponent(o)}`);const i=c(s);try{const n=await d(i);if(!n.ok)throw new u(p(n.status),`http_${n.status}`);const e=await n.json();return{list:e.success&&Array.isArray(e.data)?e.data:[],total:e.total||0,pages:e.pages||0}}catch(n){return r.error("加载会话列表失败",n),{list:[],total:0,pages:0}}}async function f(){if(!a)return"";const n=function(n,e){try{return localStorage.getItem(y(n,e))||""}catch(n){return""}}(a.integrateId,a.userId);if(n)return a.chatId=n,r.info(`从缓存恢复 chatId=${n}`),n;try{const n=await k(1,5,a.userId,a.integrateId);if(n.list.length>0){const e=n.list[0],t=e.conversationId||e.chatId||"";if(t)return a.chatId=t,b(a.integrateId,a.userId,t),r.info(`从后端恢复会话 chatId=${t} messageCount=${e.messageCount}`),t}}catch(n){r.warn("查询后端会话列表失败,将生成新 chatId",n)}const e=function(){const n="undefined"!=typeof crypto&&crypto.randomUUID?crypto.randomUUID().substring(0,8):Math.random().toString(36).substring(2,10);return`sdk_${Date.now()}_${n}`}();return a.chatId=e,b(a.integrateId,a.userId,e),r.info(`生成新 chatId=${e}`),e}function y(n,e){return`csk_chatId_${n}${e?"_"+e:""}`}function b(n,e,t){try{t?localStorage.setItem(y(n,e),t):localStorage.removeItem(y(n,e))}catch(n){}}let x=null;function _(n){const e=function(n,e){const t=n.match(/^#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/);if(!t)return n;const r=n=>Math.max(0,Math.min(255,n)),o=r(parseInt(t[1],16)+e),s=r(parseInt(t[2],16)+e),i=r(parseInt(t[3],16)+e);return`#${o.toString(16).padStart(2,"0")}${s.toString(16).padStart(2,"0")}${i.toString(16).padStart(2,"0")}`}(n.primaryColor,-15);return`\n --csk-primary: ${n.primaryColor};\n --csk-primary-hover: ${e};\n --csk-bg-user: var(--csk-primary);\n --csk-bg-ai: #F3F4F6;\n --csk-text-user: #FFFFFF;\n --csk-text-ai: #1F2937;\n --csk-window-width: ${n.width}px;\n `}function w(n){document.querySelector("style[data-csk-sdk]")||(x=document.createElement("style"),x.setAttribute("data-csk-sdk",""),x.textContent=function(n){return`\n/* ChatbotSDK 样式 - csk- 命名空间 */\n.csk-root {\n ${_(n)}\n font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans SC", sans-serif;\n font-size: 14px;\n line-height: 1.5;\n color: #1F2937;\n}\n\n/* ========== 悬浮按钮 ========== */\n.csk-launcher {\n position: fixed;\n bottom: 20px;\n z-index: 9998;\n width: 56px;\n height: 56px;\n border-radius: 50%;\n background: #fff;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.2s ease;\n border: none;\n color: var(--csk-primary);\n user-select: none;\n}\n.csk-launcher--right {\n right: 20px;\n}\n.csk-launcher--left {\n left: 20px;\n}\n.csk-launcher:hover {\n transform: scale(1.1);\n box-shadow: 0 6px 24px rgba(0, 0, 0, 0.2);\n}\n.csk-launcher:active {\n transform: scale(0.95);\n}\n\n/* ========== 聊天弹窗 ========== */\n.csk-window {\n position: fixed;\n bottom: 20px;\n z-index: 9999;\n width: var(--csk-window-width);\n height: 560px;\n background: #fff;\n border-radius: 12px;\n box-shadow: 0 8px 40px rgba(0, 0, 0, 0.18);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n transition: opacity 0.2s ease, transform 0.2s ease;\n}\n.csk-window--right {\n right: 20px;\n}\n.csk-window--left {\n left: 20px;\n}\n.csk-window--hidden {\n display: none;\n}\n\n/* ========== 头部 ========== */\n.csk-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0 16px;\n height: 48px;\n min-height: 48px;\n background: var(--csk-primary);\n color: #fff;\n border-radius: 12px 12px 0 0;\n cursor: move;\n user-select: none;\n}\n.csk-header__title {\n font-size: 15px;\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.csk-header__actions {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n.csk-header__btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n color: #fff;\n cursor: pointer;\n border-radius: 6px;\n transition: background 0.15s;\n}\n.csk-header__btn:hover {\n background: rgba(255, 255, 255, 0.2);\n}\n\n/* ========== 消息区 ========== */\n.csk-messages {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n background: #FAFAFA;\n scroll-behavior: smooth;\n}\n.csk-messages::-webkit-scrollbar {\n width: 5px;\n}\n.csk-messages::-webkit-scrollbar-track {\n background: transparent;\n}\n.csk-messages::-webkit-scrollbar-thumb {\n background: #D1D5DB;\n border-radius: 3px;\n}\n\n/* 消息气泡 */\n.csk-msg {\n display: flex;\n flex-direction: column;\n margin-bottom: 16px;\n max-width: 85%;\n word-break: break-word;\n}\n.csk-msg--user {\n margin-left: auto;\n align-items: flex-end;\n}\n.csk-msg--ai {\n margin-right: auto;\n align-items: flex-start;\n}\n.csk-msg__bubble {\n padding: 10px 14px;\n border-radius: 12px;\n font-size: 14px;\n line-height: 1.6;\n}\n.csk-msg--user .csk-msg__bubble {\n background: var(--csk-bg-user);\n color: var(--csk-text-user);\n border-radius: 12px 12px 4px 12px;\n}\n.csk-msg--ai .csk-msg__bubble {\n background: var(--csk-bg-ai);\n color: var(--csk-text-ai);\n border-radius: 12px 12px 12px 4px;\n}\n.csk-msg__time {\n font-size: 11px;\n color: #9CA3AF;\n margin-top: 4px;\n padding: 0 4px;\n}\n\n/* ========== Loading 动画 ========== */\n.csk-loading {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 12px 14px;\n margin-bottom: 16px;\n}\n.csk-loading__dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: #D1D5DB;\n animation: csk-bounce 1.4s ease-in-out infinite both;\n}\n.csk-loading__dot:nth-child(1) { animation-delay: 0s; }\n.csk-loading__dot:nth-child(2) { animation-delay: 0.16s; }\n.csk-loading__dot:nth-child(3) { animation-delay: 0.32s; }\n\n@keyframes csk-bounce {\n 0%, 80%, 100% { transform: scale(0.6); }\n 40% { transform: scale(1); }\n}\n\n/* ========== 输入区 ========== */\n.csk-input-area {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n border-top: 1px solid #E5E7EB;\n background: #fff;\n gap: 8px;\n}\n.csk-input {\n flex: 1;\n border: 1px solid #E5E7EB;\n border-radius: 8px;\n padding: 10px 12px;\n font-size: 14px;\n outline: none;\n transition: border-color 0.2s;\n font-family: inherit;\n resize: none;\n min-height: 20px;\n max-height: 100px;\n}\n.csk-input:focus {\n border-color: var(--csk-primary);\n}\n.csk-input::placeholder {\n color: #9CA3AF;\n}\n.csk-send-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n min-width: 40px;\n border: none;\n border-radius: 8px;\n background: var(--csk-primary);\n color: #fff;\n cursor: pointer;\n transition: background 0.2s;\n}\n.csk-send-btn:hover {\n background: var(--csk-primary-hover);\n}\n.csk-send-btn:disabled {\n background: #D1D5DB;\n cursor: not-allowed;\n}\n\n/* ========== 清空按钮 ========== */\n.csk-clear-btn {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 6px 12px;\n border: 1px solid #E5E7EB;\n border-radius: 6px;\n background: #fff;\n color: #6B7280;\n font-size: 12px;\n cursor: pointer;\n margin: 0 auto 8px;\n transition: all 0.15s;\n}\n.csk-clear-btn:hover {\n background: #FEE2E2;\n border-color: #FCA5A5;\n color: #DC2626;\n}\n\n/* ========== P1: 知识库分类下拉 ========== */\n.csk-category-bar {\n display: flex;\n align-items: center;\n padding: 6px 12px;\n border-top: 1px solid #E5E7EB;\n background: #F9FAFB;\n gap: 8px;\n}\n.csk-category-bar__label {\n font-size: 12px;\n color: #6B7280;\n white-space: nowrap;\n}\n.csk-category-select {\n flex: 1;\n padding: 5px 8px;\n border: 1px solid #E5E7EB;\n border-radius: 6px;\n font-size: 12px;\n color: #374151;\n background: #fff;\n outline: none;\n cursor: pointer;\n font-family: inherit;\n transition: border-color 0.2s;\n max-width: 200px;\n}\n.csk-category-select:focus {\n border-color: var(--csk-primary);\n}\n\n/* ========== P1: RAG 引用来源卡片 ========== */\n.csk-sources {\n margin-top: 8px;\n border: 1px solid #E5E7EB;\n border-radius: 8px;\n overflow: hidden;\n font-size: 12px;\n max-width: 100%;\n}\n.csk-sources__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 12px;\n background: #F9FAFB;\n cursor: pointer;\n user-select: none;\n transition: background 0.15s;\n}\n.csk-sources__header:hover {\n background: #F3F4F6;\n}\n.csk-sources__title {\n display: flex;\n align-items: center;\n gap: 4px;\n font-weight: 500;\n color: #374151;\n}\n.csk-sources__arrow {\n transition: transform 0.2s;\n color: #9CA3AF;\n}\n.csk-sources--collapsed .csk-sources__arrow {\n transform: rotate(-90deg);\n}\n.csk-sources__body {\n border-top: 1px solid #E5E7EB;\n padding: 0;\n}\n.csk-sources--collapsed .csk-sources__body {\n display: none;\n}\n.csk-source-item {\n padding: 8px 12px;\n border-bottom: 1px solid #F3F4F6;\n transition: background 0.15s;\n}\n.csk-source-item:last-child {\n border-bottom: none;\n}\n.csk-source-item:hover {\n background: #F9FAFB;\n}\n.csk-source-item__name {\n font-weight: 500;\n color: #1F2937;\n margin-bottom: 2px;\n}\n.csk-source-item__snippet {\n color: #6B7280;\n line-height: 1.4;\n overflow: hidden;\n text-overflow: ellipsis;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n}\n.csk-source-item__meta {\n font-size: 11px;\n color: #9CA3AF;\n margin-top: 2px;\n}\n\n/* ========== P1: Markdown 渲染样式 ========== */\n.csk-msg--ai .csk-msg__bubble .csk-md-p {\n margin: 0 0 8px;\n}\n.csk-msg--ai .csk-msg__bubble .csk-md-p:last-child {\n margin-bottom: 0;\n}\n.csk-msg--ai .csk-msg__bubble .csk-md-h1,\n.csk-msg--ai .csk-msg__bubble .csk-md-h2,\n.csk-msg--ai .csk-msg__bubble .csk-md-h3,\n.csk-msg--ai .csk-msg__bubble .csk-md-h4,\n.csk-msg--ai .csk-msg__bubble .csk-md-h5,\n.csk-msg--ai .csk-msg__bubble .csk-md-h6 {\n margin: 12px 0 6px;\n font-weight: 600;\n line-height: 1.3;\n}\n.csk-msg--ai .csk-msg__bubble .csk-md-h1 { font-size: 20px; }\n.csk-msg--ai .csk-msg__bubble .csk-md-h2 { font-size: 17px; }\n.csk-msg--ai .csk-msg__bubble .csk-md-h3 { font-size: 15px; }\n.csk-msg--ai .csk-msg__bubble .csk-md-h4 { font-size: 14px; }\n\n.csk-md-code-block {\n background: #1E293B;\n color: #E2E8F0;\n padding: 12px 14px;\n border-radius: 8px;\n overflow-x: auto;\n margin: 8px 0;\n font-size: 13px;\n line-height: 1.5;\n font-family: 'SF Mono', 'Consolas', 'Menlo', monospace;\n}\n.csk-md-code-block code {\n background: none;\n padding: 0;\n border-radius: 0;\n font-size: inherit;\n color: inherit;\n}\n.csk-md-inline-code {\n background: #E5E7EB;\n color: #DC2626;\n padding: 1px 6px;\n border-radius: 4px;\n font-size: 13px;\n font-family: 'SF Mono', 'Consolas', 'Menlo', monospace;\n}\n.csk-msg--ai .csk-msg__bubble .csk-md-ul,\n.csk-msg--ai .csk-msg__bubble .csk-md-ol {\n padding-left: 20px;\n margin: 6px 0;\n}\n.csk-msg--ai .csk-msg__bubble .csk-md-ul li,\n.csk-msg--ai .csk-msg__bubble .csk-md-ol li {\n margin-bottom: 4px;\n}\n.csk-md-blockquote {\n border-left: 3px solid var(--csk-primary);\n padding-left: 12px;\n margin: 8px 0;\n color: #6B7280;\n}\n.csk-md-link {\n color: var(--csk-primary);\n text-decoration: none;\n}\n.csk-md-link:hover {\n text-decoration: underline;\n}\n.csk-md-hr {\n border: none;\n border-top: 1px solid #E5E7EB;\n margin: 12px 0;\n}\n\n/* ========== P2: 会话管理面板 ========== */\n.csk-history-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n color: #fff;\n cursor: pointer;\n border-radius: 6px;\n transition: background 0.15s;\n}\n.csk-history-btn:hover {\n background: rgba(255, 255, 255, 0.2);\n}\n.csk-history-panel {\n position: absolute;\n top: 48px;\n left: 0;\n right: 0;\n bottom: 0;\n background: #fff;\n z-index: 10;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n.csk-history-panel--hidden {\n display: none;\n}\n.csk-history-panel__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n border-bottom: 1px solid #E5E7EB;\n background: #F9FAFB;\n}\n.csk-history-panel__title {\n font-size: 14px;\n font-weight: 600;\n color: #1F2937;\n}\n.csk-history-panel__back {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n border: 1px solid #E5E7EB;\n border-radius: 6px;\n background: #fff;\n color: #374151;\n font-size: 12px;\n cursor: pointer;\n transition: all 0.15s;\n}\n.csk-history-panel__back:hover {\n background: #F3F4F6;\n}\n.csk-history-panel__list {\n flex: 1;\n overflow-y: auto;\n padding: 8px;\n}\n.csk-history-panel__list::-webkit-scrollbar {\n width: 4px;\n}\n.csk-history-panel__list::-webkit-scrollbar-thumb {\n background: #E5E7EB;\n border-radius: 2px;\n}\n.csk-history-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 12px;\n border-radius: 8px;\n cursor: pointer;\n transition: background 0.15s;\n margin-bottom: 4px;\n}\n.csk-history-item:hover {\n background: #F3F4F6;\n}\n.csk-history-item__info {\n flex: 1;\n min-width: 0;\n}\n.csk-history-item__id {\n font-size: 13px;\n font-weight: 500;\n color: #1F2937;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.csk-history-item__meta {\n font-size: 11px;\n color: #9CA3AF;\n margin-top: 2px;\n}\n.csk-history-item__actions {\n display: flex;\n gap: 4px;\n margin-left: 8px;\n opacity: 0;\n transition: opacity 0.15s;\n}\n.csk-history-item:hover .csk-history-item__actions {\n opacity: 1;\n}\n.csk-history-action {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n font-size: 12px;\n transition: all 0.15s;\n}\n.csk-history-action--export {\n background: #EFF6FF;\n color: #2563EB;\n}\n.csk-history-action--export:hover {\n background: #DBEAFE;\n}\n.csk-history-action--delete {\n background: #FEF2F2;\n color: #DC2626;\n}\n.csk-history-action--delete:hover {\n background: #FEE2E2;\n}\n.csk-history-panel__empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n color: #9CA3AF;\n font-size: 13px;\n text-align: center;\n}\n.csk-history-panel__empty-icon {\n font-size: 32px;\n margin-bottom: 8px;\n opacity: 0.5;\n}\n.csk-history-panel__loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 20px;\n color: #9CA3AF;\n font-size: 13px;\n}\n.csk-history-panel__loadmore {\n display: block;\n width: 100%;\n padding: 10px;\n border: none;\n background: #F9FAFB;\n color: #6B7280;\n font-size: 12px;\n cursor: pointer;\n text-align: center;\n transition: background 0.15s;\n}\n.csk-history-panel__loadmore:hover {\n background: #F3F4F6;\n}\n\n/* ========== 移动端适配 ========== */\n@media (max-width: 480px) {\n .csk-window {\n width: 100vw !important;\n height: 100vh !important;\n bottom: 0 !important;\n right: 0 !important;\n left: 0 !important;\n border-radius: 0;\n }\n .csk-header {\n border-radius: 0;\n }\n}\n`}(n),document.head.appendChild(x))}function v(){return"undefined"!=typeof crypto&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{const e=16*Math.random()|0;return("x"===n?e:3&e|8).toString(16)})}function E(n){const e={"&":"&","<":"<",">":">",'"':""","'":"'"};return n.replace(/[&<>"']/g,n=>e[n]||n)}function I(){return Date.now()}function C(n,e){const t=document.createElement("div");t.id="csk-launcher",t.className="csk-launcher csk-launcher--"+("left-bottom"===n.position?"left":"right"),t.setAttribute("title",n.title),t.setAttribute("aria-label",n.title),t.setAttribute("role","button"),t.setAttribute("tabindex","0"),t.innerHTML=n.launcherIcon;const r=function(n,e){let t=null;return function(...r){null!==t&&clearTimeout(t),t=setTimeout(()=>{n.apply(this,r),t=null},e)}}(e,300);return t.addEventListener("click",r),t.addEventListener("keydown",n=>{"Enter"!==n.key&&" "!==n.key||(n.preventDefault(),r())}),t}function $(n,e,t){const r=document.createElement("div");r.className="csk-msg csk-msg--user";const o=document.createElement("div");o.className="csk-msg__bubble",o.textContent=e;const s=document.createElement("div");return s.className="csk-msg__time",s.textContent=N(t),r.appendChild(o),r.appendChild(s),n.appendChild(r),r}function S(n,e,t,r){const o=document.createElement("div");o.className="csk-msg csk-msg--ai";const s=document.createElement("div");s.className="csk-msg__bubble",r?s.innerHTML=r(e):s.textContent=e;const i=document.createElement("div");return i.className="csk-msg__time",i.textContent=N(t),o.appendChild(s),o.appendChild(i),n.appendChild(o),o}function A(n,e){const t=n.querySelector(".csk-sources");if(t&&t.remove(),!e||0===e.length)return;const r=document.createElement("div");r.className="csk-sources csk-sources--collapsed";const o=document.createElement("div");o.className="csk-sources__header";const s=document.createElement("span");s.className="csk-sources__title",s.textContent=`📚 ${i("source_count",{n:e.length})}`;const a=document.createElement("span");a.className="csk-sources__arrow",a.textContent="▼",o.appendChild(s),o.appendChild(a),o.addEventListener("click",()=>{r.classList.toggle("csk-sources--collapsed")});const c=document.createElement("div");c.className="csk-sources__body";for(const n of e){const e=document.createElement("div");e.className="csk-source-item";const t=document.createElement("div");if(t.className="csk-source-item__name",t.textContent=n.title||n.sourceName||"未知文档",n.snippet){const t=document.createElement("div");t.className="csk-source-item__snippet",t.textContent=n.snippet,e.appendChild(t)}const r=document.createElement("div");r.className="csk-source-item__meta";const o=[];n.sourceName&&o.push(n.sourceName),void 0!==n.chunkIndex&&o.push(`分块 #${n.chunkIndex}`),void 0!==n.score&&o.push(`相关度 ${(100*n.score).toFixed(0)}%`),r.textContent=o.join(" · "),e.appendChild(t),e.appendChild(r),c.appendChild(e)}r.appendChild(o),r.appendChild(c);const l=n.querySelector(".csk-msg__time");l?n.insertBefore(r,l):n.appendChild(r)}function F(n){n.scrollTop=n.scrollHeight}function N(n){const e=new Date(n);return`${String(e.getHours()).padStart(2,"0")}:${String(e.getMinutes()).padStart(2,"0")}`}function L(n){return`csk_history_${n}`}function D(n,e){try{let t=e;t.length>200&&(t=t.slice(50),r.warn(`消息数量达到上限,已裁剪最早 50 条,当前 ${t.length} 条`));const o={messages:t,updatedAt:Date.now()};localStorage.setItem(L(n),JSON.stringify(o))}catch(n){n instanceof Error&&"QuotaExceededError"===n.name?r.error("localStorage 空间不足,会话历史保存失败。建议清空历史记录。"):r.error("保存会话历史失败",n)}}function B(n){try{localStorage.removeItem(L(n))}catch(n){r.warn("清空会话历史失败",n)}}const M="\0CODEBLOCK_",z="\0INLINECODE_";function T(n){if(!n||"string"!=typeof n)return"";const e=[];let t=n;t=t.replace(/```(\w*)\n([\s\S]*?)```/g,(n,t,r)=>{const o=e.length,s=E(r.trimEnd()),i=t?` class="language-${E(t)}"`:"";return e.push(`<pre class="csk-md-code-block"><code${i}>${s}</code></pre>`),`${M}${o}\0`});const r=[];t=t.replace(/`([^`\n]+)`/g,(n,e)=>{const t=r.length;return r.push(`<code class="csk-md-inline-code">${E(e)}</code>`),`${z}${t}\0`}),t=E(t),t=q(t,M,e),t=q(t,z,r);const o=t.split("\n"),s=[];let i=!1,a="",c=!1,l=[];for(let n=0;n<o.length;n++){const e=o[n];if(e.includes(M)||e.includes('<pre class="csk-md-code-block">')){u(),p(),m(),s.push(e);continue}const t=e.match(/^(#{1,6})\s+(.+)/);if(t){u(),p(),m();const n=t[1].length;s.push(`<h${n} class="csk-md-h${n}">${t[2]}</h${n}>`);continue}const r=e.match(/^>\s?(.*)/);if(r){u(),p(),c||(c=!0,s.push('<blockquote class="csk-md-blockquote">')),s.push(`<p>${d(r[1])}</p>`);continue}c&&m();const h=e.match(/^[\-\*]\s+(.+)/);if(h){u(),m(),i&&"ul"===a||(p(),i=!0,a="ul",s.push('<ul class="csk-md-ul">')),s.push(`<li>${d(h[1])}</li>`);continue}const g=e.match(/^\d+\.\s+(.+)/);g?(u(),m(),i&&"ol"===a||(p(),i=!0,a="ol",s.push('<ol class="csk-md-ol">')),s.push(`<li>${d(g[1])}</li>`)):""!==e.trim()?/^(\*{3,}|-{3,}|_{3,})$/.test(e.trim())?(u(),p(),m(),s.push('<hr class="csk-md-hr">')):(p(),m(),l.push(d(e))):(u(),p())}return u(),p(),m(),s.join("\n");function d(n){return n=(n=(n=(n=(n=(n=n.replace(/\*\*(.+?)\*\*/g,"<strong>$1</strong>")).replace(/__(.+?)__/g,"<strong>$1</strong>")).replace(/\*(.+?)\*/g,"<em>$1</em>")).replace(/(?<!\w)_(.+?)_(?!\w)/g,"<em>$1</em>")).replace(/~~(.+?)~~/g,"<del>$1</del>")).replace(/\[([^\]]+)\]\(([^)]+)\)/g,(n,e,t)=>`<a class="csk-md-link" href="${/^https?:\/\//i.test(t)?t:"#"}" target="_blank" rel="noopener noreferrer">${e}</a>`)}function u(){l.length>0&&(s.push(`<p class="csk-md-p">${l.join("<br>")}</p>`),l=[])}function p(){i&&(s.push("ul"===a?"</ul>":"</ol>"),i=!1,a="")}function m(){c&&(s.push("</blockquote>"),c=!1)}}function q(n,e,t){return n.replace(new RegExp(e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")+"(\\d+)\0","g"),(n,e)=>t[parseInt(e)]||"")}let j,H=null,R=[],U=null,P=null,O=null,W=null,K=null,V=null,J=null,X=null,Y=!1,G=!1;function Q(n,e){H=n,U=e.messagesContainer,P=e.inputEl,O=e.sendBtn,W=e.clearBtn,K=e.categorySelect,V=e.historyPanel,J=e.showLoading,X=e.hideLoading,j=n.categoryId,G=!!n.categoryId||!!n.showCategorySwitch,function(){if(!P||!O)return;O.addEventListener("click",()=>en()),P.addEventListener("keydown",n=>{"Enter"!==n.key||n.shiftKey||(n.preventDefault(),en())}),P.addEventListener("input",()=>nn()),W&&W.addEventListener("click",()=>function(){if(!H)return;if(!confirm(i("clear_confirm")))return;if(R=[],U){U.querySelectorAll(".csk-msg, .csk-loading").forEach(n=>n.remove())}W&&(W.style.display="none");B(H.integrateId);const n=function(){const n="undefined"!=typeof crypto&&crypto.randomUUID?crypto.randomUUID().substring(0,8):Math.random().toString(36).substring(2,10);return`sdk_${Date.now()}_${n}`}();e=n,a&&(a.chatId=e),b(H.integrateId,H.userId,n),r.lifecycleClear(H.integrateId),r.info(`新 chatId=${n}`);var e}())}(),n.showCategorySwitch&&K&&async function(){if(!K)return;try{const n=await async function(){const n=c("/category/tree");try{const e=await d(n);if(!e.ok)throw new u(p(e.status),`http_${e.status}`);const t=await e.json();return t.success&&Array.isArray(t.data)?(r.info(`加载分类树成功 count=${t.data.length}`),t.data):[]}catch(n){return n instanceof u?r.error(`加载分类树失败: ${n.message}`):r.error("加载分类树失败",n),[]}}();if(0===n.length)return;K.innerHTML=`<option value="">${i("category_all")}</option>`;const e=(n,t=0)=>{for(const r of n){const n=document.createElement("option");n.value=String(r.id),n.textContent=`${" ".repeat(t)}${r.name}`,void 0!==j&&String(r.id)===String(j)&&(n.selected=!0),K.appendChild(n),r.children&&r.children.length>0&&e(r.children,t+1)}};e(n),r.info(`知识库分类加载成功 count=${n.length}`)}catch(n){r.error(i("category_load_error"),n)}}()}async function Z(){if(H&&U&&(await f(),await async function(){if(!H||!U)return;const n=(null==a?void 0:a.chatId)||"";if(!n)return;try{const e=await async function(n){const e=c(`/conversation/${n}/messages`);try{const n=await d(e);if(!n.ok)throw new u(p(n.status),`http_${n.status}`);const t=await n.json();return{messages:t.success&&Array.isArray(t.data)?t.data:[],total:t.total||0}}catch(n){return r.error("加载会话消息失败",n),{messages:[],total:0}}}(n);e.messages.length>0&&(R=e.messages.map((n,e)=>({id:v(),role:"USER"===n.messageType?"user":"ai",content:n.content,timestamp:new Date(n.createTime).getTime()})),tn(),r.info(`从后端加载 ${R.length} 条历史消息`),D(H.integrateId,R))}catch(n){r.warn("从后端加载历史消息失败",n)}}(),0===R.length)){const n=function(n){try{const e=localStorage.getItem(L(n));if(!e)return[];const t=JSON.parse(e);return t&&Array.isArray(t.messages)?(r.info(`加载历史消息 integrateId=${n} count=${t.messages.length}`),t.messages):[]}catch(n){return r.warn("加载会话历史失败",n),[]}}(H.integrateId);n.length>0&&(R=n,tn(),r.info(`从本地缓存恢复 ${n.length} 条消息`))}}function nn(){if(!O||!P)return;P.value.trim().length>0&&!Y?O.removeAttribute("disabled"):O.setAttribute("disabled","true")}async function en(){if(!P||!H||Y)return;const n=P.value.trim();if(""===n)return;P.value="",nn(),P.style.height="auto",Y=!0,nn(),H.chatId||await f();const e=I();U&&$(U,n,e);const t={id:v(),role:"user",content:n,timestamp:e};R.push(t),W&&R.length>0&&(W.style.display="inline-flex"),U&&F(U),J&&J(),U&&F(U);try{let e;const t=I(),o=G&&(void 0!==j||void 0!==H.categoryId);e=H.streaming?await async function(n,e,t){return new Promise((r,o)=>{let s=null,a="",c=!1;h(n,n=>{if(a+=n,!c&&U){X&&X();const{bubble:n}=function(n,e){const t=document.createElement("div");t.className="csk-msg csk-msg--ai";const r=document.createElement("div");r.className="csk-msg__bubble",r.innerHTML="";const o=document.createElement("div");return o.className="csk-msg__time",o.textContent=N(e),t.appendChild(r),t.appendChild(o),n.appendChild(t),{wrapper:t,bubble:r}}(U,e);s=n,c=!0}s&&(s.textContent=a),U&&F(U)},()=>{c||""!==a?(s&&a&&(s.innerHTML=T(a)),r(a)):m(n).then(r).catch(o)},n=>{a.length>0?(s&&(s.innerHTML=T(a+"\n\n"+i("stream_interrupted"))),r(a)):o(n)},j,t)})}(n,t,o):await m(n),X&&X(),!H.streaming&&U&&S(U,e,t,T);const s={id:v(),role:"ai",content:e,timestamp:t};R.push(s),D(H.integrateId,R),U&&F(U),o&&async function(n,e){try{const t=await g(n,j);if(t.length>0){const n=t.map(n=>{var e,t;return{documentId:n.documentId||"",title:n.title||"",sourceName:n.sourceName||"",chunkIndex:null!==(e=n.chunkIndex)&&void 0!==e?e:0,score:null!==(t=n.score)&&void 0!==t?t:0,snippet:n.snippet||""}});if(e.sources=n,U){const e=U.querySelector(".csk-msg--ai:last-of-type");e&&A(e,n)}H&&D(H.integrateId,R)}}catch(n){r.warn("获取引用来源失败",n)}}(n,s)}catch(n){X&&X();const e=n instanceof u?n.message:i("error_send");if(U){const n=document.createElement("div");n.className="csk-msg csk-msg--ai";const t=document.createElement("div");t.className="csk-msg__bubble",t.style.color="#DC2626",t.textContent=`⚠ ${e}`,n.appendChild(t),U.appendChild(n)}r.error(`发送失败 integrateId=${H.integrateId}`,n)}finally{Y=!1,nn()}}function tn(){if(!U)return;const n=U.querySelector(".csk-history-panel");U.querySelectorAll(".csk-msg, .csk-loading").forEach(n=>n.remove());for(const n of R)if("user"===n.role)$(U,n.content,n.timestamp);else{const e=S(U,n.content,n.timestamp,T);n.sources&&n.sources.length>0&&A(e,n.sources)}F(U),W&&R.length>0&&(W.style.display="inline-flex"),n&&!U.contains(n)&&U.appendChild(n)}async function rn(){if(!V||!H)return;const n=V.querySelector("#csk-history-list");if(n){n.innerHTML='<div class="csk-history-panel__loading">加载中...</div>';try{const e=await k(1,50,H.userId,H.integrateId);!function(n,e,t,r){if(n.innerHTML="",0===e.length){const e=document.createElement("div");return e.className="csk-history-panel__empty",e.innerHTML=`\n <div class="csk-history-panel__empty-icon">💬</div>\n <div>${i("history_empty")}</div>\n `,void n.appendChild(e)}for(const o of e){const e=document.createElement("div");e.className="csk-history-item";const s=document.createElement("div");s.className="csk-history-item__info";const a=document.createElement("div");a.className="csk-history-item__id",a.textContent=o.chatId||o.id;const c=document.createElement("div");c.className="csk-history-item__meta";const l=[];void 0!==o.messageCount&&l.push(`${o.messageCount} 条消息`),o.lastMessageTime?l.push(o.lastMessageTime):o.createdAt&&l.push(o.createdAt),c.textContent=l.join(" · "),s.appendChild(a),s.appendChild(c);const d=document.createElement("div");d.className="csk-history-item__actions";const u=document.createElement("button");u.className="csk-history-action csk-history-action--export",u.setAttribute("title",i("history_export")),u.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>',u.addEventListener("click",n=>{n.stopPropagation(),t(o.id)});const p=document.createElement("button");p.className="csk-history-action csk-history-action--delete",p.setAttribute("title",i("history_delete")),p.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>',p.addEventListener("click",n=>{n.stopPropagation(),r(o.id)}),d.appendChild(u),d.appendChild(p),e.appendChild(s),e.appendChild(d),n.appendChild(e)}}(n,e.list.map(n=>({id:n.conversationId||n.chatId||"",chatId:n.conversationId||n.chatId||"",messageCount:n.messageCount,lastMessageTime:n.lastMessageTime,createdAt:n.firstMessageTime||n.createdAt})),n=>{window.open(c(`/conversation/${n}/export`),"_blank")},async n=>{if(!confirm(i("history_delete_confirm")))return;await async function(n){const e=c(`/conversation/${n}`);try{const t=await d(e,{method:"DELETE"});if(!t.ok)throw new u(p(t.status),`http_${t.status}`);const o=await t.json();return r.info(`删除会话 id=${n} success=${o.success}`),o.success||!1}catch(n){return r.error("删除会话失败",n),!1}}(n)&&rn()})}catch(e){r.error(i("history_load_error"),e),n.innerHTML=`<div class="csk-history-panel__empty"><div class="csk-history-panel__empty-icon">⚠</div><div>${i("history_load_error")}</div></div>`}}}let on=null,sn=!1,an=null,cn=null,ln=null,dn=null,un=null,pn=null,mn=null,hn=null,gn=null,kn=null,fn=null;function yn(){cn&&cn.classList.remove("csk-window--hidden")}function bn(){cn&&cn.classList.add("csk-window--hidden")}function xn(){cn&&(cn.classList.contains("csk-window--hidden")?(yn(),setTimeout(()=>{dn&&dn.focus()},100)):bn())}const _n={init:function(n){if(sn)return void r.warn("SDK 已初始化,请先调用 destroy() 再重新初始化");const t=function(n){var e,t,o,s,i,a;if(!n.integrateId||"string"!=typeof n.integrateId&&"number"!=typeof n.integrateId||"string"==typeof n.integrateId&&""===n.integrateId.trim())return r.error('integrateId 是必传参数(对应后端 roleId 客服角色 ID),请检查 init() 调用。示例:ChatbotSDK.init({ integrateId: 1, requestDomain: "https://api.example.com" })'),null;if(!n.requestDomain||"string"!=typeof n.requestDomain||""===n.requestDomain.trim())return r.error('requestDomain 是必传参数,请检查 init() 调用。示例:ChatbotSDK.init({ integrateId: 1, requestDomain: "https://api.example.com" })'),null;try{new URL(n.requestDomain)}catch(e){return r.error(`requestDomain 不是合法的 URL 格式:${n.requestDomain}。请提供完整的域名,如 https://api.example.com`),null}const c={integrateId:String(n.integrateId).trim(),requestDomain:n.requestDomain.replace(/\/+$/,""),userId:n.userId,categoryId:n.categoryId,showCategorySwitch:null!==(e=n.showCategorySwitch)&&void 0!==e&&e,title:n.title||"AI 智能助手",width:null!==(t=n.width)&&void 0!==t?t:380,position:"left-bottom"===n.position?"left-bottom":"right-bottom",primaryColor:n.primaryColor||"#4F46E5",launcherIcon:n.launcherIcon||'<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">\n <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>\n <path d="M8 9h8"/><path d="M8 13h6"/>\n</svg>',showClear:null===(o=n.showClear)||void 0===o||o,showAdminPanel:null!==(s=n.showAdminPanel)&&void 0!==s&&s,streaming:null===(i=n.streaming)||void 0===i||i,locale:n.locale||"zh-CN",debug:null===(a=n.debug)||void 0===a||a,chatId:""};return r.info(`配置解析完成 integrateId(=roleId)=${c.integrateId} userId(=accountId)=${c.userId||"(未设置)"} requestDomain=${c.requestDomain}`),c}(n);if(!t)return;var c;on=t,function(n){if(o[n])s=n;else{const e=n.split("-")[0],t=Object.keys(o).find(n=>n.startsWith(e));t&&(s=t)}}(on.locale),c=on.debug,e=c,function(n){a=n}(on),w(on),an=C(on,xn),document.body.appendChild(an);const l=function(n){const e=document.createElement("div");e.id="csk-window",e.className=`csk-root csk-window csk-window--${"left-bottom"===n.position?"left":"right"} csk-window--hidden`;const t=document.createElement("div");t.className="csk-header";const r=document.createElement("span");r.className="csk-header__title",r.textContent=n.title;const o=document.createElement("div");o.className="csk-header__actions";const s=document.createElement("button");s.className="csk-history-btn",s.setAttribute("title",i("history_title")),s.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>';const a=document.createElement("button");a.className="csk-header__btn csk-header__btn--minimize",a.setAttribute("title",i("minimize")),a.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="5" y1="12" x2="19" y2="12"/></svg>',a.addEventListener("click",()=>{e.classList.add("csk-window--hidden")});const c=document.createElement("button");c.className="csk-header__btn csk-header__btn--close",c.setAttribute("title",i("close")),c.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>',c.addEventListener("click",()=>{e.classList.add("csk-window--hidden")}),o.appendChild(s),o.appendChild(a),o.appendChild(c),t.appendChild(r),t.appendChild(o);const l=document.createElement("div");l.id="csk-messages",l.className="csk-messages";const d=document.createElement("div");d.className="csk-history-panel csk-history-panel--hidden",d.innerHTML=`\n <div class="csk-history-panel__header">\n <span class="csk-history-panel__title">${i("history_title")}</span>\n <button class="csk-history-panel__back" id="csk-history-back">\n <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="19" y1="12" x2="5" y2="12"/><polyline points="12 19 5 12 12 5"/></svg>\n ${i("close")}\n </button>\n </div>\n <div class="csk-history-panel__list" id="csk-history-list"></div>\n `,l.appendChild(d);const u=d.querySelector("#csk-history-back");u&&u.addEventListener("click",()=>{d.classList.add("csk-history-panel--hidden")}),s.addEventListener("click",n=>{n.stopPropagation();const t=d.classList.contains("csk-history-panel--hidden");d.classList.toggle("csk-history-panel--hidden"),t&&e.dispatchEvent(new CustomEvent("csk:loadHistory"))});let p=null;if(n.showCategorySwitch){const n=document.createElement("div");n.className="csk-category-bar";const r=document.createElement("span");r.className="csk-category-bar__label",r.textContent="📚",p=document.createElement("select"),p.id="csk-category-select",p.className="csk-category-select",p.innerHTML=`<option value="">${i("category_all")}</option>`,p.addEventListener("change",()=>{const n=p.value;e.dispatchEvent(new CustomEvent("csk:categoryChange",{detail:{categoryId:n?Number(n):void 0}}))}),n.appendChild(r),n.appendChild(p),e.appendChild(t),e.appendChild(l),e.appendChild(n)}else e.appendChild(t),e.appendChild(l);const m=document.createElement("div");m.className="csk-input-area";const h=document.createElement("textarea");h.id="csk-input",h.className="csk-input",h.setAttribute("placeholder",i("placeholder")),h.setAttribute("rows","1"),h.setAttribute("autofocus","");const g=document.createElement("button");g.id="csk-send-btn",g.className="csk-send-btn",g.setAttribute("title",i("send")),g.setAttribute("disabled","true"),g.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>',m.appendChild(h),m.appendChild(g),e.appendChild(m);let k=null;n.showClear&&(k=document.createElement("button"),k.className="csk-clear-btn",k.textContent=i("clear"),k.style.display="none",e.insertBefore(k,m));let f=null;return{window:e,messagesContainer:l,inputEl:h,sendBtn:g,clearBtn:k,categorySelect:p,historyPanel:d,showLoading:function(){if(f)return f.style.display="flex",f;const n=document.createElement("div");return n.className="csk-loading",n.innerHTML='\n <div class="csk-loading__dot"></div>\n <div class="csk-loading__dot"></div>\n <div class="csk-loading__dot"></div>\n ',l.appendChild(n),f=n,n},hideLoading:function(){f&&f.parentNode&&(f.parentNode.removeChild(f),f=null)}}}(on);cn=l.window,ln=l.messagesContainer,dn=l.inputEl,un=l.sendBtn,pn=l.clearBtn,mn=l.categorySelect,hn=l.historyPanel,gn=l.showLoading,kn=l.hideLoading,document.body.appendChild(cn);const d=cn.querySelector(".csk-header");d&&(fn=function(n,e){let t=!1,r=0,o=0,s=0,i=0;const a=n=>{t=!0,r=n.clientX,o=n.clientY;const a=e.getBoundingClientRect();s=r-a.left,i=o-a.top,document.addEventListener("mousemove",c),document.addEventListener("mouseup",l)},c=n=>{if(!t)return;const r=n.clientX-s,o=n.clientY-i,a=window.innerWidth-e.offsetWidth,c=window.innerHeight-e.offsetHeight;e.style.right="auto",e.style.bottom="auto",e.style.left=`${Math.max(0,Math.min(r,a))}px`,e.style.top=`${Math.max(0,Math.min(o,c))}px`},l=()=>{t=!1,document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",l)};return n.addEventListener("mousedown",a),()=>{n.removeEventListener("mousedown",a),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",l)}}(d,cn)),Q(on,{messagesContainer:ln,inputEl:dn,sendBtn:un,clearBtn:pn,categorySelect:mn,historyPanel:hn,showLoading:gn,hideLoading:kn}),cn.addEventListener("csk:categoryChange",n=>{var e;e=n.detail.categoryId,j=e,G=void 0!==e,r.lifecycleCategoryChange(null!=e?e:"全部")}),cn.addEventListener("csk:loadHistory",()=>{rn()}),sn=!0,r.lifecycleInit(on.integrateId,on.requestDomain),Z().catch(n=>{r.warn("chatId 初始化失败,将在发送消息时重试",n)})},destroy:function(){if(!sn)return;an&&an.parentNode&&(an.parentNode.removeChild(an),an=null),cn&&cn.parentNode&&(cn.parentNode.removeChild(cn),cn=null),fn&&(fn(),fn=null),x&&x.parentNode&&(x.parentNode.removeChild(x),x=null),document.querySelectorAll("style[data-csk-sdk]").forEach(n=>n.remove());const n=null==on?void 0:on.integrateId;on=null,sn=!1,ln=null,dn=null,un=null,pn=null,mn=null,hn=null,gn=null,kn=null,r.lifecycleDestroy(n||"")},open:yn,close:bn,toggle:xn,clearHistory:function(){on&&(pn?pn.click():confirm("确定清空所有对话记录?")&&B(on.integrateId))}};return"undefined"!=typeof window&&(window.ChatbotSDK=_n),_n}();
|
|
//# sourceMappingURL=chatbot-sdk.min.js.map
|