- Node.js backend server - Frontend application - Backup script - Project specification Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 line
9.2 KiB
JavaScript
1 line
9.2 KiB
JavaScript
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[662],{8356:function(n,e,t){(window.__NEXT_P=window.__NEXT_P||[]).push(["/settings",function(){return t(9301)}])},6248:function(n,e,t){"use strict";t.d(e,{Z:function(){return o}});var s=t(5893),c=t(7294),i=t(1163),a=t(9415);let r=[{href:"/",label:"首页",icon:"home"},{href:"/stats",label:"统计",icon:"chart"},{href:"/recurring",label:"周期",icon:"repeat"},{href:"/categories",label:"分类",icon:"tags"}];function o(n){let{title:e,subtitle:t,actions:o,headerContent:l,children:u,contentClassName:d="",hideNav:h=!1,compactHeader:p=!1}=n,f=(0,i.useRouter)(),m=(0,c.useMemo)(()=>{let n=r.find(n=>n.href===f.pathname);return(null==n?void 0:n.href)||null},[f.pathname]),g=l||(e?(0,s.jsxs)("div",{className:"app-header__text",children:[(0,s.jsx)("h1",{children:e}),t?(0,s.jsx)("p",{children:t}):null]}):null),j=["app-header",p?"app-header--compact":"",g?"app-header--with-content":"app-header--actions-only",o?"app-header--with-actions":""].filter(Boolean).join(" ");return(0,s.jsxs)("div",{className:"app-shell".concat(h?" app-shell--standalone":""),children:[(0,s.jsx)("header",{className:j,children:(0,s.jsxs)("div",{className:"app-shell__container app-header__inner",children:[g?(0,s.jsx)("div",{className:"app-header__main",children:g}):(0,s.jsx)("div",{className:"app-header__spacer","aria-hidden":"true"}),o?(0,s.jsx)("div",{className:"app-header__actions",children:o}):null]})}),(0,s.jsx)("main",{className:"app-content ".concat(d).trim(),children:(0,s.jsx)("div",{className:"app-shell__container app-content__inner",children:u})}),h?null:(0,s.jsx)("nav",{className:"bottom-nav","aria-label":"主导航",children:(0,s.jsx)("div",{className:"app-shell__container bottom-nav__inner",children:r.map(n=>{let e=m===n.href;return(0,s.jsxs)("button",{type:"button",className:"bottom-nav__item".concat(e?" is-active":""),onClick:()=>f.push(n.href),"aria-current":e?"page":void 0,children:[(0,s.jsx)(a.J,{name:n.icon,size:20}),(0,s.jsx)("span",{children:n.label})]},n.href)})})})]})}},610:function(n,e,t){"use strict";async function s(n){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},t=await fetch("".concat("").concat(n),{...e,headers:{"Content-Type":"application/json",...function(){let n=localStorage.getItem("token");return n?{Authorization:"Bearer ".concat(n)}:{}}(),...e.headers}}),s=await t.json();if(!t.ok)throw Error(s.error||"请求失败");return s}async function c(n,e){let t=await s("/api/auth/login",{method:"POST",body:JSON.stringify({username:n,password:e})});return localStorage.setItem("token",t.token),t}async function i(n,e){let t=await s("/api/auth/register",{method:"POST",body:JSON.stringify({username:n,password:e})});return localStorage.setItem("token",t.token),t}function a(){localStorage.removeItem("token")}function r(){return!!localStorage.getItem("token")}async function o(n){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"all",t="/api/records?month=".concat(n);return"all"!==e&&(t+="&type=".concat(e)),s(t)}async function l(n){return s("/api/stats?month=".concat(n))}async function u(n){return s("/api/records",{method:"POST",body:JSON.stringify(n)})}async function d(n,e){return s("/api/records/".concat(n),{method:"PUT",body:JSON.stringify(e)})}async function h(n){return s("/api/records/".concat(n),{method:"DELETE"})}async function p(n){return s("/api/records/search?q=".concat(encodeURIComponent(n)))}async function f(){let n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"month",e=arguments.length>1?arguments[1]:void 0,t="/api/stats/trend?period=".concat(n);return e&&(t+="&month=".concat(e)),s(t)}async function m(n){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"all",t="/api/stats/category?type=".concat(e);return n&&(t+="&month=".concat(n)),s(t)}async function g(){return s("/api/recurring")}async function j(n){return s("/api/recurring",{method:"POST",body:JSON.stringify(n)})}async function y(n,e){return s("/api/recurring/".concat(n),{method:"PUT",body:JSON.stringify(e)})}async function x(n){return s("/api/recurring/".concat(n),{method:"DELETE"})}async function N(n){return s("/api/recurring/".concat(n,"/apply"),{method:"POST"})}async function b(){return s("/api/categories")}async function v(n){return s("/api/categories",{method:"POST",body:JSON.stringify(n)})}async function _(n){return s("/api/categories/".concat(n),{method:"DELETE"})}async function S(){return s("/api/export")}async function k(n){return s("/api/import",{method:"POST",body:JSON.stringify(n)})}t.d(e,{Ap:function(){return m},CP:function(){return b},JS:function(){return h},Kp:function(){return p},Q6:function(){return o},TZ:function(){return x},Vn:function(){return g},Vs:function(){return d},Xu:function(){return N},ae:function(){return u},dk:function(){return k},fy:function(){return l},gR:function(){return f},jl:function(){return r},k4:function(){return v},kS:function(){return a},u1:function(){return S},uO:function(){return y},uu:function(){return _},x4:function(){return c},z0:function(){return j},z2:function(){return i}})},9301:function(n,e,t){"use strict";t.r(e),t.d(e,{default:function(){return d}});var s=t(5893),c=t(7294),i=t(1163),a=t(610),r=t(6248),o=t(9415),l=t(5546),u=t(8846);function d(){let n=(0,i.useRouter)(),e=(0,c.useRef)(null),{showToast:t}=(0,l.p)(),{confirm:d}=(0,u.N)(),[h,p]=(0,c.useState)(!1),[f,m]=(0,c.useState)(!1),[g,j]=(0,c.useState)(!1);(0,c.useEffect)(()=>{(0,a.jl)()||n.push("/login")},[n]);let y=async()=>{await d({title:"退出当前账号?",description:"退出后需要重新登录才能继续使用。",confirmText:"退出登录",tone:"info"})&&(j(!0),(0,a.kS)(),t("已退出登录",{tone:"success"}),n.push("/login"))},x=async()=>{p(!0);try{let n=await (0,a.u1)(),e=new Blob([JSON.stringify(n,null,2)],{type:"application/json"}),s=URL.createObjectURL(e),c=document.createElement("a");c.href=s,c.download="accountbook_backup_".concat(new Date().toISOString().split("T")[0],".json"),c.click(),URL.revokeObjectURL(s),t("导出成功",{tone:"success"})}catch(n){t("导出失败: ".concat(n.message),{tone:"error"})}finally{p(!1)}},N=async n=>{var e;let s=null===(e=n.target.files)||void 0===e?void 0:e[0];if(s){m(!0);try{let e=await s.text(),c=JSON.parse(e);await (0,a.dk)(c),t("导入成功",{tone:"success"}),n.target.value=""}catch(n){t("导入失败: ".concat(n.message),{tone:"error"})}finally{m(!1)}}};return(0,s.jsxs)(r.Z,{title:"设置",subtitle:"数据、账号与应用信息",compactHeader:!0,children:[(0,s.jsxs)("section",{className:"card settings-section settings-section--refresh",children:[(0,s.jsx)("div",{className:"section-heading section-heading--compact",children:(0,s.jsxs)("div",{children:[(0,s.jsx)("p",{className:"eyebrow",children:"数据管理"}),(0,s.jsx)("h2",{children:"导入与导出"})]})}),(0,s.jsxs)("div",{className:"settings-item",children:[(0,s.jsxs)("div",{className:"settings-info",children:[(0,s.jsx)("div",{className:"settings-title",children:"导出数据"}),(0,s.jsx)("div",{className:"settings-desc",children:"将所有账目导出为 JSON 文件,方便备份。"})]}),(0,s.jsx)("button",{type:"button",className:"btn btn-primary btn-inline",onClick:x,disabled:h||f,children:(0,s.jsxs)("span",{className:"button-content",children:[(0,s.jsx)(o.J,{name:"download",size:16}),h?"导出中...":"导出"]})})]}),(0,s.jsxs)("div",{className:"settings-item",children:[(0,s.jsxs)("div",{className:"settings-info",children:[(0,s.jsx)("div",{className:"settings-title",children:"导入数据"}),(0,s.jsx)("div",{className:"settings-desc",children:"从 JSON 文件恢复账目数据。"})]}),(0,s.jsx)("button",{type:"button",className:"btn btn-secondary btn-inline",onClick:()=>{var n;return null===(n=e.current)||void 0===n?void 0:n.click()},disabled:h||f,children:(0,s.jsxs)("span",{className:"button-content",children:[(0,s.jsx)(o.J,{name:"upload",size:16}),f?"导入中...":"导入"]})}),(0,s.jsx)("input",{type:"file",ref:e,onChange:N,accept:".json",style:{display:"none"}})]})]}),(0,s.jsxs)("section",{className:"card settings-section settings-section--refresh",children:[(0,s.jsx)("div",{className:"section-heading section-heading--compact",children:(0,s.jsxs)("div",{children:[(0,s.jsx)("p",{className:"eyebrow",children:"账号"}),(0,s.jsx)("h2",{children:"登录状态"})]})}),(0,s.jsxs)("div",{className:"settings-item settings-item--stacked",children:[(0,s.jsxs)("div",{className:"settings-info",children:[(0,s.jsx)("div",{className:"settings-title",children:"退出登录"}),(0,s.jsx)("div",{className:"settings-desc",children:"从当前设备安全退出,并返回登录页。"})]}),(0,s.jsx)("button",{type:"button",className:"btn btn-danger btn-inline",onClick:y,disabled:g,children:(0,s.jsxs)("span",{className:"button-content",children:[(0,s.jsx)(o.J,{name:"logout",size:16}),g?"退出中...":"退出登录"]})})]})]}),(0,s.jsxs)("section",{className:"card settings-section settings-section--refresh",children:[(0,s.jsx)("div",{className:"section-heading section-heading--compact",children:(0,s.jsxs)("div",{children:[(0,s.jsx)("p",{className:"eyebrow",children:"关于"}),(0,s.jsx)("h2",{children:"应用信息"})]})}),(0,s.jsxs)("div",{className:"about-info",children:[(0,s.jsx)("p",{children:"简易记账本 v1.0"}),(0,s.jsx)("p",{className:"sub",children:"基于 React + Next.js 开发"})]})]})]})}},1163:function(n,e,t){n.exports=t(3079)}},function(n){n.O(0,[888,774,179],function(){return n(n.s=8356)}),_N_E=n.O()}]); |