(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[929],{6308:function(e,t,r){Promise.resolve().then(r.bind(r,628))},628:function(e,t,r){"use strict";r.r(t),r.d(t,{default:function(){return s}});var n=r(7437),a=r(2265),o=r(1837);let c=["今日市场怎么样?","有哪些推荐股票?","哪些板块最热门?"];function s(){var e;let[t,r]=(0,a.useState)([]),[s,i]=(0,a.useState)(""),[l,d]=(0,a.useState)(!1),[u,x]=(0,a.useState)(""),h=(0,a.useRef)(null),f=(0,a.useRef)(null),m=()=>{var e;null===(e=h.current)||void 0===e||e.scrollTo({top:h.current.scrollHeight,behavior:"smooth"})};(0,a.useEffect)(()=>{m()},[t,u]);let p=async e=>{if(!e.trim()||l)return;let n=[...t,{role:"user",content:e.trim()}];r(n),i(""),d(!0),x(""),r([...n,{role:"assistant",content:""}]);try{let e=n.map(e=>({role:e.role,content:e.content})),t="";for await(let a of(0,o.ov)(e))"status"===a.type?x(a.content):"content"===a.type&&(t+=a.content,r([...n,{role:"assistant",content:t}]),x(""))}catch(e){console.error("Chat error:",e),r([...n,{role:"assistant",content:"连接失败,请检查网络后重试。"}])}finally{d(!1),x("")}};return(0,n.jsxs)("div",{className:"max-w-3xl mx-auto flex flex-col md:h-[calc(100dvh)]",children:[(0,n.jsxs)("div",{className:"flex items-center justify-between px-5 py-3.5 border-b border-white/[0.04] bg-bg-primary/80 backdrop-blur-xl",children:[(0,n.jsxs)("div",{className:"flex items-center gap-3",children:[(0,n.jsx)("div",{className:"w-7 h-7 rounded-lg bg-gradient-to-br from-accent-cyan/30 to-accent-cyan/10 flex items-center justify-center border border-accent-cyan/20",children:(0,n.jsx)("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.8",className:"text-accent-cyan/70",children:(0,n.jsx)("path",{d:"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"})})}),(0,n.jsxs)("div",{children:[(0,n.jsx)("h1",{className:"text-sm font-semibold",children:"AI 投资顾问"}),(0,n.jsx)("p",{className:"text-xs text-text-muted",children:"基于实时市场数据的智能问答"})]})]}),t.length>0&&(0,n.jsx)("button",{onClick:()=>r([]),className:"text-xs text-text-muted hover:text-text-primary px-3 py-1.5 rounded-lg hover:bg-white/[0.04] transition-all duration-200",children:"清空对话"})]}),(0,n.jsx)("div",{ref:h,className:"flex-1 overflow-y-auto px-5 py-5 space-y-4",children:0===t.length?(0,n.jsxs)("div",{className:"flex flex-col items-center justify-center h-full text-center animate-fade-in-up",children:[(0,n.jsx)("div",{className:"w-14 h-14 rounded-2xl bg-gradient-to-br from-accent-cyan/15 to-accent-cyan/5 flex items-center justify-center mb-5 border border-accent-cyan/10",children:(0,n.jsx)("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",className:"text-accent-cyan/50",children:(0,n.jsx)("path",{d:"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"})})}),(0,n.jsx)("h2",{className:"text-sm font-semibold mb-1.5",children:"有什么想了解的?"}),(0,n.jsx)("p",{className:"text-xs text-text-muted mb-8 max-w-[240px] leading-relaxed",children:"我可以查询市场数据,分析个股走势,解读板块热度"}),(0,n.jsx)("div",{className:"flex flex-col gap-2 w-full max-w-[280px]",children:c.map(e=>(0,n.jsx)("button",{onClick:()=>p(e),className:"text-xs px-4 py-2.5 bg-white/[0.03] rounded-xl text-text-secondary hover:text-text-primary hover:bg-white/[0.06] transition-all duration-200 border border-white/[0.04] text-left",children:e},e))})]}):(0,n.jsxs)(n.Fragment,{children:[t.map((e,r)=>{let a;return(0,n.jsx)("div",{className:"flex ".concat("user"===e.role?"justify-end":"justify-start"," animate-fade-in-up"),children:(0,n.jsxs)("div",{className:"max-w-[85%] rounded-2xl px-4 py-2.5 text-[13px] leading-relaxed ".concat("user"===e.role?"bg-gradient-to-r from-orange-500/20 to-amber-500/15 text-orange-100 border border-orange-500/10":"glass-card-static"),children:["assistant"===e.role?e.content?(0,n.jsx)("div",{className:"prose prose-invert prose-sm max-w-none [&_p]:my-1 [&_ul]:my-1 [&_li]:my-0.5 [&_strong]:text-orange-300",dangerouslySetInnerHTML:{__html:e.content.replace(/&/g,"&").replace(//g,">").replace(/\*\*(.+?)\*\*/g,"$1").replace(/^\s*[-*]\s+(.+)/gm,"
$1").replace(/\n/g,"
").replace(/(.*?<\/li>(
)?)+/g,e=>"")}}):(0,n.jsx)("span",{className:"text-text-muted/50 text-xs",children:u||"思考中..."}):(0,n.jsx)("span",{children:e.content}),l&&r===t.length-1&&"assistant"===e.role&&e.content&&(0,n.jsx)("span",{className:"inline-block w-1.5 h-4 bg-accent-cyan/60 ml-0.5 animate-pulse rounded-full"})]})},r)}),l&&u&&(null===(e=t[t.length-1])||void 0===e?void 0:e.content)&&(0,n.jsx)("div",{className:"flex justify-start",children:(0,n.jsxs)("div",{className:"text-xs text-accent-cyan/50 flex items-center gap-2 px-3",children:[(0,n.jsx)("span",{className:"inline-block w-2.5 h-2.5 border border-accent-cyan/30 border-t-accent-cyan/70 rounded-full animate-spin"}),u]})})]})}),(0,n.jsxs)("div",{className:"px-5 py-3 pb-[max(0.75rem,env(safe-area-inset-bottom))] md:pb-3 border-t border-white/[0.04] bg-bg-primary/80 backdrop-blur-xl",children:[(0,n.jsxs)("div",{className:"flex items-end gap-2",children:[(0,n.jsx)("textarea",{ref:f,value:s,onChange:e=>i(e.target.value),onKeyDown:e=>{"Enter"!==e.key||e.shiftKey||(e.preventDefault(),p(s))},placeholder:"输入问题...",rows:1,className:"flex-1 bg-white/[0.03] rounded-xl px-4 py-2.5 text-sm resize-none focus:outline-none focus:ring-1 focus:ring-accent-cyan/30 placeholder-text-muted/40 border border-white/[0.04] transition-all duration-200",disabled:l}),(0,n.jsx)("button",{onClick:()=>p(s),disabled:!s.trim()||l,className:"px-4 py-2.5 bg-gradient-to-r from-accent-cyan/20 to-accent-cyan/10 text-accent-cyan rounded-xl text-sm hover:from-accent-cyan/30 hover:to-accent-cyan/20 disabled:opacity-20 transition-all duration-200 shrink-0 border border-accent-cyan/10 font-medium",children:"发送"})]}),(0,n.jsx)("div",{className:"text-xs text-text-muted/30 text-center mt-2",children:"AI 分析仅供参考,不构成投资建议"})]})]})}},1837:function(e,t,r){"use strict";function n(){return localStorage.getItem("auth_token")}function a(){localStorage.removeItem("auth_token"),localStorage.removeItem("auth_user"),window.location.href="/login"}async function o(e){let t=n(),r={};t&&(r.Authorization="Bearer ".concat(t));let o=await fetch("".concat("").concat(e),{headers:r});if(401===o.status)throw a(),Error("Unauthorized");if(!o.ok)throw Error("API error: ".concat(o.status));return o.json()}async function c(e,t){let r=n(),o={"Content-Type":"application/json"};r&&(o.Authorization="Bearer ".concat(r));let c=await fetch("".concat("").concat(e),{method:"POST",headers:o,body:t?JSON.stringify(t):void 0});if(401===c.status)throw a(),Error("Unauthorized");if(!c.ok)throw Error("API error: ".concat(c.status));return c.json()}async function s(e){let t=n(),r={};t&&(r.Authorization="Bearer ".concat(t));let o=await fetch("".concat("").concat(e),{method:"DELETE",headers:r});if(401===o.status)throw a(),Error("Unauthorized");if(!o.ok)throw Error((await o.json().catch(()=>({}))).detail||"API error: ".concat(o.status));return o.json()}async function*i(e){let t=n(),r={"Content-Type":"application/json"};t&&(r.Authorization="Bearer ".concat(t));let o=await fetch("".concat("","/api/chat/stream"),{method:"POST",headers:r,body:JSON.stringify({messages:e})});if(401===o.status)throw a(),Error("Unauthorized");if(!o.ok)throw Error("Chat API error: ".concat(o.status));if(!o.body)throw Error("No response body");let c=o.body.getReader(),s=new TextDecoder,i="";for(;;){let{done:e,value:t}=await c.read();if(e)break;let r=(i+=s.decode(t,{stream:!0})).split("\n");for(let e of(i=r.pop()||"",r))if(e.startsWith("data: ")){let t=e.slice(6).trim();if("[DONE]"===t)return;try{let e=JSON.parse(t);yield e}catch(e){}}}}async function l(e,t){let r=await fetch("".concat("","/api/auth/login"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:e,password:t})});if(!r.ok)throw Error((await r.json().catch(()=>({}))).detail||"Login failed: ".concat(r.status));return r.json()}async function d(){return o("/api/auth/users")}async function u(e,t){return c("/api/auth/users",{username:e,role:t})}async function x(e){return s("/api/auth/users/".concat(e))}async function h(e){return c("/api/auth/users/".concat(e,"/reset-password"))}async function f(e,t){return c("/api/auth/change-password",{old_password:e,new_password:t})}r.d(t,{Io:function(){return o},Pj:function(){return u},UO:function(){return l},Ul:function(){return f},fK:function(){return x},jK:function(){return d},l8:function(){return c},oQ:function(){return h},ov:function(){return i}})}},function(e){e.O(0,[971,117,744],function(){return e(e.s=6308)}),_N_E=e.O()}]);