1 line
12 KiB
JavaScript
1 line
12 KiB
JavaScript
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[185],{7164:function(e,t,r){Promise.resolve().then(r.t.bind(r,2778,23)),Promise.resolve().then(r.bind(r,7182)),Promise.resolve().then(r.bind(r,3331)),Promise.resolve().then(r.bind(r,5315)),Promise.resolve().then(r.bind(r,8145))},7182:function(e,t,r){"use strict";r.d(t,{AuthGuard:function(){return c}});var n=r(7437),o=r(2265),a=r(9376),s=r(8145);let i=["/login"];function c(e){let{children:t}=e,{user:r,loading:c}=(0,s.a)(),l=(0,a.usePathname)(),u=(0,a.useRouter)(),d=i.includes(l);return((0,o.useEffect)(()=>{c||r||d||u.replace("/login")},[c,r,d,u]),(0,o.useEffect)(()=>{!c&&r&&"/login"===l&&u.replace("/")},[c,r,l,u]),c)?(0,n.jsx)("div",{className:"min-h-screen flex items-center justify-center bg-bg-primary",children:(0,n.jsx)("div",{className:"w-6 h-6 border border-amber-500/30 border-t-amber-500 rounded-full animate-spin"})}):(r||d)&&(!r||"/login"!==l)?(0,n.jsx)(n.Fragment,{children:t}):null}},3331:function(e,t,r){"use strict";r.d(t,{MobileBottomNav:function(){return m},SidebarNav:function(){return x}});var n=r(7437),o=r(8145),a=r(7648),s=r(9376);function i(){return(0,n.jsxs)("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.8",strokeLinecap:"round",strokeLinejoin:"round",children:[(0,n.jsx)("rect",{x:"3",y:"3",width:"7",height:"7",rx:"1.5"}),(0,n.jsx)("rect",{x:"14",y:"3",width:"7",height:"7",rx:"1.5"}),(0,n.jsx)("rect",{x:"3",y:"14",width:"7",height:"7",rx:"1.5"}),(0,n.jsx)("rect",{x:"14",y:"14",width:"7",height:"7",rx:"1.5"})]})}function c(){return(0,n.jsxs)("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.8",strokeLinecap:"round",strokeLinejoin:"round",children:[(0,n.jsx)("circle",{cx:"12",cy:"12",r:"10"}),(0,n.jsx)("circle",{cx:"12",cy:"12",r:"6"}),(0,n.jsx)("circle",{cx:"12",cy:"12",r:"2"})]})}function l(){return(0,n.jsx)("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.8",strokeLinecap:"round",strokeLinejoin:"round",children:(0,n.jsx)("path",{d:"M12 2c.5 2.5-.5 5-2 7 1 0 2.5.5 3 2.5.5-2 2-3 3-4-1 3-1 6-4 8.5-1.5 1-3.5 1.5-5 1-1.5-.5-2.5-2-2.5-3.5 0-3 3-5 5-7.5C10 5 11 3.5 12 2z"})})}function u(){return(0,n.jsx)("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.8",strokeLinecap:"round",strokeLinejoin:"round",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"})})}function d(){return(0,n.jsxs)("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.8",strokeLinecap:"round",strokeLinejoin:"round",children:[(0,n.jsx)("path",{d:"M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"}),(0,n.jsx)("circle",{cx:"9",cy:"7",r:"4"}),(0,n.jsx)("path",{d:"M23 21v-2a4 4 0 0 0-3-3.87"}),(0,n.jsx)("path",{d:"M16 3.13a4 4 0 0 1 0 7.75"})]})}function h(e){let{href:t,icon:r,label:o}=e,i=(0,s.usePathname)(),c="/"===t?"/"===i:i.startsWith(t);return(0,n.jsxs)(a.default,{href:t,className:"flex items-center gap-3 px-4 py-2.5 rounded-xl text-sm transition-all duration-200 ".concat(c?"text-text-primary bg-white/[0.06]":"text-text-secondary hover:text-text-primary hover:bg-white/[0.04]"),children:[(0,n.jsx)("span",{className:"text-base opacity-70",children:r}),(0,n.jsx)("span",{className:"font-medium",children:o})]})}function x(){let{user:e}=(0,o.a)();return(0,n.jsxs)("nav",{className:"flex-1 py-5 px-3 space-y-1",children:[(0,n.jsx)(h,{href:"/",icon:(0,n.jsx)(i,{}),label:"总览"}),(0,n.jsx)(h,{href:"/recommendations",icon:(0,n.jsx)(c,{}),label:"推荐列表"}),(0,n.jsx)(h,{href:"/sectors",icon:(0,n.jsx)(l,{}),label:"板块分析"}),(0,n.jsx)(h,{href:"/chat",icon:(0,n.jsx)(u,{}),label:"AI 对话"}),(null==e?void 0:e.role)==="admin"&&(0,n.jsx)(h,{href:"/users",icon:(0,n.jsx)(d,{}),label:"用户管理"})]})}function f(e){let{href:t,label:r,children:o}=e,i=(0,s.usePathname)(),c="/"===t?"/"===i:i.startsWith(t);return(0,n.jsxs)(a.default,{href:t,className:"flex flex-col items-center gap-1 transition-colors active:scale-95 ".concat(c?"text-amber-400":"text-text-muted hover:text-text-primary"),children:[(0,n.jsx)("span",{className:"text-lg",children:o}),(0,n.jsx)("span",{className:"text-xs font-medium",children:r})]})}function m(){return(0,n.jsx)("nav",{className:"fixed bottom-0 left-0 right-0 md:hidden z-50 bg-bg-secondary/95 backdrop-blur-xl border-t border-white/[0.04]",children:(0,n.jsxs)("div",{className:"flex justify-around py-2 pb-[max(0.5rem,env(safe-area-inset-bottom))]",children:[(0,n.jsx)(f,{href:"/",label:"总览",children:(0,n.jsx)(i,{})}),(0,n.jsx)(f,{href:"/recommendations",label:"推荐",children:(0,n.jsx)(c,{})}),(0,n.jsx)(f,{href:"/sectors",label:"板块",children:(0,n.jsx)(l,{})}),(0,n.jsx)(f,{href:"/chat",label:"对话",children:(0,n.jsx)(u,{})})]})})}},5315:function(e,t,r){"use strict";r.d(t,{UserMenu:function(){return c}});var n=r(7437),o=r(2265),a=r(8145),s=r(1837);function i(e){let{open:t,onClose:r}=e,[a,i]=(0,o.useState)(""),[c,l]=(0,o.useState)(""),[u,d]=(0,o.useState)(""),[h,x]=(0,o.useState)(!1),[f,m]=(0,o.useState)(""),[p,b]=(0,o.useState)(!1);if(!t)return null;function j(){i(""),l(""),d(""),m(""),b(!1),x(!1),r()}async function g(e){if(e.preventDefault(),m(""),!a||!c||!u){m("请填写所有字段");return}if(c.length<6){m("新密码至少 6 位");return}if(c!==u){m("两次输入的新密码不一致");return}x(!0);try{await (0,s.Ul)(a,c),b(!0)}catch(e){m(e instanceof Error?e.message:"修改失败")}finally{x(!1)}}return(0,n.jsxs)("div",{className:"fixed inset-0 z-[60] flex items-center justify-center",children:[(0,n.jsx)("div",{className:"absolute inset-0 bg-black/60 backdrop-blur-sm",onClick:j}),(0,n.jsxs)("div",{className:"relative w-full max-w-sm mx-4 p-6 rounded-2xl bg-bg-card border border-white/[0.06] shadow-card",children:[(0,n.jsx)("h3",{className:"text-base font-semibold text-text-primary mb-5",children:"修改密码"}),p?(0,n.jsxs)("div",{className:"space-y-4",children:[(0,n.jsx)("p",{className:"text-sm text-emerald-400",children:"密码修改成功,下次登录请使用新密码。"}),(0,n.jsx)("button",{onClick:j,className:"w-full py-2.5 rounded-xl text-sm font-medium bg-white/[0.04] border border-white/[0.06] text-text-secondary hover:text-text-primary hover:bg-white/[0.06] transition-all",children:"关闭"})]}):(0,n.jsxs)("form",{onSubmit:g,className:"space-y-3",children:[(0,n.jsx)("input",{type:"password",placeholder:"旧密码",value:a,onChange:e=>i(e.target.value),className:"w-full bg-white/[0.03] border border-white/[0.06] rounded-xl px-4 py-2.5 text-sm text-text-primary focus:outline-none focus:ring-1 focus:ring-amber-500/30 placeholder-text-muted/40",autoComplete:"current-password"}),(0,n.jsx)("input",{type:"password",placeholder:"新密码(至少 6 位)",value:c,onChange:e=>l(e.target.value),className:"w-full bg-white/[0.03] border border-white/[0.06] rounded-xl px-4 py-2.5 text-sm text-text-primary focus:outline-none focus:ring-1 focus:ring-amber-500/30 placeholder-text-muted/40",autoComplete:"new-password"}),(0,n.jsx)("input",{type:"password",placeholder:"确认新密码",value:u,onChange:e=>d(e.target.value),className:"w-full bg-white/[0.03] border border-white/[0.06] rounded-xl px-4 py-2.5 text-sm text-text-primary focus:outline-none focus:ring-1 focus:ring-amber-500/30 placeholder-text-muted/40",autoComplete:"new-password"}),f&&(0,n.jsx)("p",{className:"text-xs text-amber-400/80",children:f}),(0,n.jsxs)("div",{className:"flex gap-3 pt-2",children:[(0,n.jsx)("button",{type:"button",onClick:j,className:"flex-1 py-2.5 rounded-xl text-sm font-medium bg-white/[0.04] border border-white/[0.06] text-text-secondary hover:text-text-primary hover:bg-white/[0.06] transition-all",children:"取消"}),(0,n.jsx)("button",{type:"submit",disabled:h,className:"flex-1 py-2.5 rounded-xl text-sm font-medium bg-gradient-to-r from-amber-500/20 to-amber-600/15 text-amber-400 border border-amber-500/10 hover:from-amber-500/30 hover:to-amber-600/25 transition-all disabled:opacity-50",children:h?"提交中...":"确认修改"})]})]})]})]})}function c(){let{user:e,logout:t}=(0,a.a)(),[r,s]=(0,o.useState)(!1);return e?(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)("div",{className:"space-y-3",children:[(0,n.jsxs)("div",{className:"flex items-center justify-between",children:[(0,n.jsx)("span",{className:"text-xs text-text-muted",children:e.username}),(0,n.jsx)("span",{className:"text-[10px] px-1.5 py-0.5 rounded bg-amber-500/10 text-amber-400/80",children:e.role})]}),(0,n.jsxs)("div",{className:"flex items-center gap-3",children:[(0,n.jsx)("button",{onClick:()=>s(!0),className:"text-xs text-text-muted hover:text-text-secondary transition-colors",children:"修改密码"}),(0,n.jsx)("button",{onClick:t,className:"text-xs text-amber-400/60 hover:text-amber-400 transition-colors",children:"退出登录"})]})]}),(0,n.jsx)(i,{open:r,onClose:()=>s(!1)})]}):null}},8145:function(e,t,r){"use strict";r.d(t,{AuthProvider:function(){return i},a:function(){return c}});var n=r(7437),o=r(2265),a=r(1837);let s=(0,o.createContext)({user:null,loading:!0,login:async()=>{},logout:()=>{}});function i(e){let{children:t}=e,[r,i]=(0,o.useState)(null),[c,l]=(0,o.useState)(!0);(0,o.useEffect)(()=>{let e=localStorage.getItem("auth_token"),t=localStorage.getItem("auth_user");if(e&&t)try{i(JSON.parse(t))}catch(e){localStorage.removeItem("auth_token"),localStorage.removeItem("auth_user")}l(!1)},[]);let u=(0,o.useCallback)(async(e,t)=>{let r=await (0,a.UO)(e,t);localStorage.setItem("auth_token",r.token),localStorage.setItem("auth_user",JSON.stringify(r.user)),i(r.user)},[]),d=(0,o.useCallback)(()=>{localStorage.removeItem("auth_token"),localStorage.removeItem("auth_user"),i(null),window.location.href="/login"},[]);return(0,n.jsx)(s.Provider,{value:{user:r,loading:c,login:u,logout:d},children:t})}function c(){return(0,o.useContext)(s)}},1837:function(e,t,r){"use strict";function n(){return localStorage.getItem("auth_token")}function o(){localStorage.removeItem("auth_token"),localStorage.removeItem("auth_user"),window.location.href="/login"}async function a(e){let t=n(),r={};t&&(r.Authorization="Bearer ".concat(t));let a=await fetch("".concat("").concat(e),{headers:r});if(401===a.status)throw o(),Error("Unauthorized");if(!a.ok)throw Error("API error: ".concat(a.status));return a.json()}async function s(e,t){let r=n(),a={"Content-Type":"application/json"};r&&(a.Authorization="Bearer ".concat(r));let s=await fetch("".concat("").concat(e),{method:"POST",headers:a,body:t?JSON.stringify(t):void 0});if(401===s.status)throw o(),Error("Unauthorized");if(!s.ok)throw Error("API error: ".concat(s.status));return s.json()}async function i(e){let t=n(),r={};t&&(r.Authorization="Bearer ".concat(t));let a=await fetch("".concat("").concat(e),{method:"DELETE",headers:r});if(401===a.status)throw o(),Error("Unauthorized");if(!a.ok)throw Error((await a.json().catch(()=>({}))).detail||"API error: ".concat(a.status));return a.json()}async function*c(e){let t=n(),r={"Content-Type":"application/json"};t&&(r.Authorization="Bearer ".concat(t));let a=await fetch("".concat("","/api/chat/stream"),{method:"POST",headers:r,body:JSON.stringify({messages:e})});if(401===a.status)throw o(),Error("Unauthorized");if(!a.ok)throw Error("Chat API error: ".concat(a.status));if(!a.body)throw Error("No response body");let s=a.body.getReader(),i=new TextDecoder,c="";for(;;){let{done:e,value:t}=await s.read();if(e)break;let r=(c+=i.decode(t,{stream:!0})).split("\n");for(let e of(c=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 u(){return a("/api/auth/users")}async function d(e,t){return s("/api/auth/users",{username:e,role:t})}async function h(e){return i("/api/auth/users/".concat(e))}async function x(e){return s("/api/auth/users/".concat(e,"/reset-password"))}async function f(e,t){return s("/api/auth/change-password",{old_password:e,new_password:t})}r.d(t,{Io:function(){return a},Pj:function(){return d},UO:function(){return l},Ul:function(){return f},fK:function(){return h},jK:function(){return u},l8:function(){return s},oQ:function(){return x},ov:function(){return c}})},2778:function(){}},function(e){e.O(0,[461,448,971,117,744],function(){return e(e.s=7164)}),_N_E=e.O()}]); |