(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[890],{4125:function(e,t,n){Promise.resolve().then(n.bind(n,7698))},9376:function(e,t,n){"use strict";var a=n(5475);n.o(a,"useParams")&&n.d(t,{useParams:function(){return a.useParams}}),n.o(a,"usePathname")&&n.d(t,{usePathname:function(){return a.usePathname}}),n.o(a,"useRouter")&&n.d(t,{useRouter:function(){return a.useRouter}})},7698:function(e,t,n){"use strict";n.r(t),n.d(t,{default:function(){return u}});var a=n(7437),r=n(2265),s=n(9376),o=n(1837),i=n(3448);function l(e){let{data:t}=e,s=(0,r.useRef)(null);return(0,r.useEffect)(()=>{if(!s.current||!t.length)return;let e=null;return n.e(614).then(n.bind(n,9614)).then(n=>{if(!s.current)return;e=n.init(s.current,"dark");let a=t.map(e=>e.trade_date),r=t.map(e=>[e.open,e.close,e.low,e.high]),o=t.map(e=>e.vol),i=t.map(e=>e.ma5),l=t.map(e=>e.ma10),c=t.map(e=>e.ma20);e.setOption({backgroundColor:"transparent",tooltip:{trigger:"axis",axisPointer:{type:"cross"}},grid:[{left:"8%",right:"3%",top:"5%",height:"55%"},{left:"8%",right:"3%",top:"68%",height:"22%"}],xAxis:[{type:"category",data:a,axisLine:{lineStyle:{color:"#475569"}},axisLabel:{fontSize:10,color:"#94a3b8"}},{type:"category",gridIndex:1,data:a,axisLabel:{show:!1},axisLine:{lineStyle:{color:"#475569"}}}],yAxis:[{scale:!0,splitLine:{lineStyle:{color:"#1e293b"}},axisLabel:{fontSize:10,color:"#94a3b8"}},{scale:!0,gridIndex:1,splitNumber:2,splitLine:{lineStyle:{color:"#1e293b"}},axisLabel:{fontSize:10,color:"#94a3b8"}}],series:[{type:"candlestick",data:r,itemStyle:{color:"#ef4444",color0:"#22c55e",borderColor:"#ef4444",borderColor0:"#22c55e"}},{name:"MA5",type:"line",data:i,smooth:!0,lineStyle:{width:1,color:"#eab308"},symbol:"none"},{name:"MA10",type:"line",data:l,smooth:!0,lineStyle:{width:1,color:"#3b82f6"},symbol:"none"},{name:"MA20",type:"line",data:c,smooth:!0,lineStyle:{width:1,color:"#a855f7"},symbol:"none"},{name:"成交量",type:"bar",xAxisIndex:1,yAxisIndex:1,data:o,itemStyle:{color:e=>{let n=t[e.dataIndex];return n.close>=n.open?"#ef4444":"#22c55e"}}}],dataZoom:[{type:"inside",xAxisIndex:[0,1],start:60,end:100}]});let d=()=>null==e?void 0:e.resize();return window.addEventListener("resize",d),()=>window.removeEventListener("resize",d)}),()=>{null==e||e.dispose()}},[t]),(0,a.jsxs)("div",{className:"bg-bg-card rounded-xl p-4",children:[(0,a.jsx)("h2",{className:"text-sm font-medium text-text-secondary mb-2",children:"K线图"}),(0,a.jsx)("div",{ref:s,className:"w-full h-64 md:h-80"})]})}function c(e){let{data:t}=e,s=(0,r.useRef)(null);return(0,r.useEffect)(()=>{if(!s.current||!t.length)return;let e=null;return n.e(614).then(n.bind(n,9614)).then(n=>{if(!s.current)return;e=n.init(s.current,"dark");let a=t.map(e=>e.trade_date),r=t.map(e=>e.main_net_inflow);e.setOption({backgroundColor:"transparent",tooltip:{trigger:"axis",formatter:e=>{let t=e[0];return"".concat(t.name,"
主力净流入: ").concat(t.value.toFixed(0),"万")}},grid:{left:"12%",right:"5%",top:"10%",bottom:"15%"},xAxis:{type:"category",data:a,axisLine:{lineStyle:{color:"#475569"}},axisLabel:{fontSize:10,color:"#94a3b8",rotate:30}},yAxis:{type:"value",splitLine:{lineStyle:{color:"#1e293b"}},axisLabel:{fontSize:10,color:"#94a3b8",formatter:e=>Math.abs(e)>=1e4?(e/1e4).toFixed(1)+"亿":e+"万"}},series:[{type:"bar",data:r.map(e=>({value:e,itemStyle:{color:e>0?"#ef4444":"#22c55e"}}))}]});let o=()=>null==e?void 0:e.resize();return window.addEventListener("resize",o),()=>window.removeEventListener("resize",o)}),()=>{null==e||e.dispose()}},[t]),(0,a.jsxs)("div",{className:"bg-bg-card rounded-xl p-4",children:[(0,a.jsx)("h2",{className:"text-sm font-medium text-text-secondary mb-2",children:"资金流向"}),(0,a.jsx)("div",{ref:s,className:"w-full h-48"})]})}function d(e){let{signals:t}=e,s=(0,r.useRef)(null);return(0,r.useEffect)(()=>{if(!s.current)return;let e=null;return n.e(614).then(n.bind(n,9614)).then(n=>{if(!s.current)return;e=n.init(s.current,"dark");let a=[t.ma_bullish?15:0,t.volume_breakout?20:0,t.macd_golden?15:0,t.rsi_healthy?10:0,t.pullback_support?15:0,t.big_yang?15:0,t.boll_support?10:0];e.setOption({backgroundColor:"transparent",radar:{indicator:[{name:"均线多头",max:15},{name:"放量突破",max:20},{name:"MACD金叉",max:15},{name:"RSI健康",max:10},{name:"缩量回踩",max:15},{name:"放量长阳",max:15},{name:"布林支撑",max:10}],shape:"polygon",splitNumber:3,axisName:{color:"#94a3b8",fontSize:10},splitLine:{lineStyle:{color:"#334155"}},splitArea:{areaStyle:{color:["transparent"]}},axisLine:{lineStyle:{color:"#475569"}}},series:[{type:"radar",data:[{value:a,name:"技术信号",areaStyle:{color:"rgba(249, 115, 22, 0.2)"},lineStyle:{color:"#f97316"},itemStyle:{color:"#f97316"}}]}]});let r=()=>null==e?void 0:e.resize();return window.addEventListener("resize",r),()=>window.removeEventListener("resize",r)}),()=>{null==e||e.dispose()}},[t]),(0,a.jsxs)("div",{className:"bg-bg-card rounded-xl p-4",children:[(0,a.jsx)("h2",{className:"text-sm font-medium text-text-secondary mb-2",children:"信号雷达"}),(0,a.jsx)("div",{ref:s,className:"w-full h-56"})]})}function u(){var e,t,n,u,f,h,p,b;let g=(0,s.useParams)().code,[y,v]=(0,r.useState)(null),[j,w]=(0,r.useState)(null),[N,_]=(0,r.useState)([]),[S,k]=(0,r.useState)([]);return(0,r.useEffect)(()=>{g&&Promise.all([(0,o.Io)("/api/stocks/".concat(g,"/quote")).catch(()=>null),(0,o.Io)("/api/stocks/".concat(g,"/signals")).catch(()=>null),(0,o.Io)("/api/stocks/".concat(g,"/kline?days=60")).catch(()=>[]),(0,o.Io)("/api/stocks/".concat(g,"/capital_flow?days=10")).catch(()=>[])]).then(e=>{let[t,n,a,r]=e;v(t),w(n),_(a),k(r)})},[g]),(0,a.jsxs)("div",{className:"max-w-6xl mx-auto px-4 md:px-8 pt-6 pb-20 md:pb-10 space-y-5",children:[(0,a.jsxs)("a",{href:"/",className:"inline-flex items-center gap-1.5 text-xs text-text-muted hover:text-text-primary transition-colors animate-fade-in-up",children:[(0,a.jsx)("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:(0,a.jsx)("path",{d:"M19 12H5M12 19l-7-7 7-7"})}),"返回"]}),(0,a.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-4 animate-fade-in-up",children:[y&&(0,a.jsxs)("div",{className:"glass-card-static p-5 md:col-span-2",children:[(0,a.jsx)("div",{className:"flex items-center justify-between mb-3",children:(0,a.jsxs)("div",{className:"flex items-center gap-3",children:[(0,a.jsx)("span",{className:"text-lg font-bold tracking-tight",children:y.name}),(0,a.jsx)("span",{className:"text-xs text-text-muted font-mono tabular-nums",children:y.ts_code})]})}),(0,a.jsxs)("div",{className:"flex items-baseline gap-3",children:[(0,a.jsx)("span",{className:"text-3xl font-bold font-mono tabular-nums tracking-tight ".concat(y.pct_chg>0?"text-red-400":y.pct_chg<0?"text-emerald-400":"text-text-primary"),children:y.price.toFixed(2)}),(0,a.jsxs)("span",{className:"text-sm font-mono tabular-nums font-medium ".concat(y.pct_chg>0?"text-red-400":"text-emerald-400"),children:[y.pct_chg>0?"+":"",y.pct_chg.toFixed(2),"%"]})]}),(0,a.jsxs)("div",{className:"grid grid-cols-4 gap-3 mt-4",children:[(0,a.jsx)(x,{label:"换手率",value:"".concat(null===(e=y.turnover_rate)||void 0===e?void 0:e.toFixed(2),"%")}),(0,a.jsx)(x,{label:"市盈率",value:null!==(u=null===(t=y.pe)||void 0===t?void 0:t.toFixed(1))&&void 0!==u?u:"-"}),(0,a.jsx)(x,{label:"市净率",value:null!==(f=null===(n=y.pb)||void 0===n?void 0:n.toFixed(2))&&void 0!==f?f:"-"}),(0,a.jsx)(x,{label:"流通市值",value:y.circ_mv?"".concat(y.circ_mv.toFixed(0),"亿"):"-"})]})]}),j&&(0,a.jsx)("div",{className:"hidden md:block",children:(0,a.jsx)(d,{signals:j})})]}),j&&(0,a.jsxs)("div",{className:"glass-card-static p-5 animate-fade-in-up delay-75",children:[(0,a.jsxs)("div",{className:"flex items-center justify-between mb-4",children:[(0,a.jsx)("h2",{className:"text-xs font-semibold text-text-muted uppercase tracking-wider",children:"技术面信号"}),(0,a.jsxs)("div",{className:"text-lg font-bold font-mono tabular-nums ".concat((0,i.Uz)(j.score)),children:[j.score,(0,a.jsx)("span",{className:"text-xs text-text-muted ml-0.5",children:"分"})]})]}),(0,a.jsxs)("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-2",children:[(0,a.jsx)(m,{label:"均线多头",active:j.ma_bullish,points:15}),(0,a.jsx)(m,{label:"放量突破",active:j.volume_breakout,points:20}),(0,a.jsx)(m,{label:"MACD金叉",active:j.macd_golden,points:15}),(0,a.jsx)(m,{label:"RSI健康",active:j.rsi_healthy,points:10}),(0,a.jsx)(m,{label:"缩量回踩",active:j.pullback_support,points:15}),(0,a.jsx)(m,{label:"放量长阳",active:j.big_yang,points:15}),(0,a.jsx)(m,{label:"布林支撑",active:j.boll_support,points:10})]}),(0,a.jsxs)("div",{className:"flex justify-between mt-4 pt-4 border-t border-white/[0.04] text-xs",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("span",{className:"text-text-muted",children:"支撑位 "}),(0,a.jsx)("span",{className:"text-orange-400 font-mono tabular-nums",children:null!==(h=j.support_price)&&void 0!==h?h:"-"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("span",{className:"text-text-muted",children:"压力位 "}),(0,a.jsx)("span",{className:"text-red-400 font-mono tabular-nums",children:null!==(p=j.resist_price)&&void 0!==p?p:"-"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("span",{className:"text-text-muted",children:"止损位 "}),(0,a.jsx)("span",{className:"text-emerald-400 font-mono tabular-nums",children:null!==(b=j.stop_loss_price)&&void 0!==b?b:"-"})]})]})]}),(0,a.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4 animate-fade-in-up delay-150",children:[N.length>0&&(0,a.jsx)(l,{data:N}),S.length>0&&(0,a.jsx)(c,{data:S})]}),j&&(0,a.jsx)("div",{className:"md:hidden animate-fade-in-up delay-225",children:(0,a.jsx)(d,{signals:j})})]})}function x(e){let{label:t,value:n}=e;return(0,a.jsxs)("div",{className:"bg-white/[0.02] rounded-lg px-3 py-2 border border-white/[0.03]",children:[(0,a.jsx)("div",{className:"text-xs text-text-muted mb-0.5",children:t}),(0,a.jsx)("div",{className:"text-xs font-mono tabular-nums",children:n})]})}function m(e){let{label:t,active:n,points:r}=e;return(0,a.jsxs)("div",{className:"flex items-center justify-between px-3 py-2 rounded-xl text-xs transition-all duration-200 ".concat(n?"bg-red-500/[0.08] text-red-400 border border-red-500/10":"bg-white/[0.02] text-text-muted border border-transparent"),children:[(0,a.jsx)("span",{className:"font-medium",children:t}),(0,a.jsx)("span",{className:"font-mono tabular-nums ".concat(n?"font-semibold":""),children:n?"+".concat(r):"0"})]})}},1837:function(e,t,n){"use strict";function a(){return localStorage.getItem("auth_token")}function r(){localStorage.removeItem("auth_token"),localStorage.removeItem("auth_user"),window.location.href="/login"}async function s(e){let t=a(),n={};t&&(n.Authorization="Bearer ".concat(t));let s=await fetch("".concat("").concat(e),{headers:n});if(401===s.status)throw r(),Error("Unauthorized");if(!s.ok)throw Error("API error: ".concat(s.status));return s.json()}async function o(e,t){let n=a(),s={"Content-Type":"application/json"};n&&(s.Authorization="Bearer ".concat(n));let o=await fetch("".concat("").concat(e),{method:"POST",headers:s,body:t?JSON.stringify(t):void 0});if(401===o.status)throw r(),Error("Unauthorized");if(!o.ok)throw Error("API error: ".concat(o.status));return o.json()}async function i(e){let t=a(),n={};t&&(n.Authorization="Bearer ".concat(t));let s=await fetch("".concat("").concat(e),{method:"DELETE",headers:n});if(401===s.status)throw r(),Error("Unauthorized");if(!s.ok)throw Error((await s.json().catch(()=>({}))).detail||"API error: ".concat(s.status));return s.json()}async function*l(e){let t=a(),n={"Content-Type":"application/json"};t&&(n.Authorization="Bearer ".concat(t));let s=await fetch("".concat("","/api/chat/stream"),{method:"POST",headers:n,body:JSON.stringify({messages:e})});if(401===s.status)throw r(),Error("Unauthorized");if(!s.ok)throw Error("Chat API error: ".concat(s.status));if(!s.body)throw Error("No response body");let o=s.body.getReader(),i=new TextDecoder,l="";for(;;){let{done:e,value:t}=await o.read();if(e)break;let n=(l+=i.decode(t,{stream:!0})).split("\n");for(let e of(l=n.pop()||"",n))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 c(e,t){let n=await fetch("".concat("","/api/auth/login"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:e,password:t})});if(!n.ok)throw Error((await n.json().catch(()=>({}))).detail||"Login failed: ".concat(n.status));return n.json()}async function d(){return s("/api/auth/users")}async function u(e,t){return o("/api/auth/users",{username:e,role:t})}async function x(e){return i("/api/auth/users/".concat(e))}async function m(e){return o("/api/auth/users/".concat(e,"/reset-password"))}async function f(e,t){return o("/api/auth/change-password",{old_password:e,new_password:t})}n.d(t,{Io:function(){return s},Pj:function(){return u},UO:function(){return c},Ul:function(){return f},fK:function(){return x},jK:function(){return d},l8:function(){return o},oQ:function(){return m},ov:function(){return l}})},3448:function(e,t,n){"use strict";function a(e){return Math.abs(e)>=1e4?(e/1e4).toFixed(2)+"亿":Math.abs(e)>=1?e.toFixed(2)+"万":e.toFixed(2)}function r(e){return e>=80?"text-red-400":e>=60?"text-orange-400":e>=40?"text-yellow-400":"text-gray-400"}function s(e){switch(e){case"强烈推荐":return{bg:"bg-red-500/20",text:"text-red-400"};case"推荐":return{bg:"bg-orange-500/20",text:"text-orange-400"};case"观望":return{bg:"bg-yellow-500/20",text:"text-yellow-400"};default:return{bg:"bg-gray-500/20",text:"text-gray-400"}}}function o(e){return"BUY"===e?"text-red-400":"SELL"===e?"text-green-400":"text-gray-400"}function i(e){return e>=70?"#ff6b6b":e>=50?"#f59e0b":e>=30?"#fbbf24":"#34d399"}function l(e){return e>=70?"火热":e>=50?"温和":e>=30?"偏冷":"冰点"}n.d(t,{R8:function(){return o},Uz:function(){return r},Zd:function(){return l},jD:function(){return i},ny:function(){return s},uf:function(){return a}})}},function(e){e.O(0,[971,117,744],function(){return e(e.s=4125)}),_N_E=e.O()}]);