1.0.0:first commit

This commit is contained in:
2026-03-26 01:23:19 +08:00
commit f8d5b11567
23562 changed files with 2853775 additions and 0 deletions

1
client/dist/assets/CalendarView-W0Yungyo.js vendored Executable file
View File

@@ -0,0 +1 @@
import{i as T}from"./echarts-Bn9PLWWT.js";import{_ as j,r as V,s as E}from"./index-jY687wPe.js";import{j as B,k as N,a3 as P,H as n,L as l,P as e,M as x,O as U,V as I,Z as i,X as b,F as Y,ab as H,I as W,n as X,e as c,ag as _,ah as Z,c as y,R as F}from"./vue-Gs2e-20-.js";import"./element-plus-JbJMPIks.js";const q={class:"calendar-view app-page"},G={class:"calendar-container card"},J={class:"date-text"},K={key:0,class:"date-dots"},Q={class:"day-panel"},ee={class:"section-label"},te={class:"today-summary-grid"},se={class:"today-card income"},ae={class:"today-icon"},oe={class:"today-info"},ne={class:"today-amount mono-number"},ie={class:"today-card expense"},le={class:"today-icon"},de={class:"today-info"},ce={class:"today-amount mono-number"},re={key:0,class:"card chart-card mt-20"},ue={class:"card list-card mt-20"},me={key:0,class:"mobile-record-list"},pe={class:"item-left"},ve={class:"item-category"},_e={class:"item-sub"},ye={class:"item-user"},he={key:0,class:"item-note"},ge={class:"item-right"},fe={__name:"CalendarView",setup(xe){const p=c(new Date),M=c(null),h=c(!1),r=c({income:0,expense:0,userStats:{}}),g=c([]),S=c(new Set),f=c(null);let o=null;const z=y(()=>{const s=p.value;return`${s.getFullYear()}${s.getMonth()+1}${s.getDate()}`}),v=y(()=>{const s=p.value,t=s.getFullYear(),d=String(s.getMonth()+1).padStart(2,"0"),u=String(s.getDate()).padStart(2,"0");return`${t}-${d}-${u}`}),k=y(()=>v.value.substring(0,7)),D=y(()=>r.value.income>0||r.value.expense>0);function C(s){return S.value.has(s)}function $(){if(!f.value)return;o||(o=T(f.value));const s=r.value.userStats||{},t=Object.keys(s);if(t.length===0){o.clear();return}const d=t.map(m=>s[m].income||0),u=t.map(m=>s[m].expense||0);o.setOption({tooltip:{trigger:"axis",confine:!0,axisPointer:{type:"shadow"}},legend:{data:["收入","支出"],bottom:0},grid:{left:12,right:12,bottom:52,top:24,containLabel:!0},xAxis:{type:"category",data:t,axisTick:{alignWithLabel:!0},axisLabel:{interval:0,rotate:0,margin:10,color:"#64748b"}},yAxis:{type:"value",axisLabel:{formatter:"¥{value}",margin:12,color:"#64748b"},splitLine:{lineStyle:{color:"#e2e8f0"}}},series:[{name:"收入",type:"bar",data:d,itemStyle:{color:"#10b981",borderRadius:[4,4,0,0]}},{name:"支出",type:"bar",data:u,itemStyle:{color:"#f43f5e",borderRadius:[4,4,0,0]}}]},{notMerge:!0})}async function R(){h.value=!0;try{const[s,t]=await Promise.all([E.daily(v.value),V.getByDate(v.value)]);r.value=s||{income:0,expense:0,userStats:{}},g.value=t||[],D.value&&(await X(),$())}finally{h.value=!1}}async function w(){try{const t=(await V.getByMonth(k.value)).map(d=>d.date);S.value=new Set(t)}catch{}}B(v,()=>{R()}),B(k,()=>{w()});function L(){o==null||o.resize()}return N(()=>{w(),R(),window.addEventListener("resize",L)}),P(()=>{o==null||o.dispose(),window.removeEventListener("resize",L)}),(s,t)=>{const d=_("el-calendar"),u=_("Top"),m=_("Bottom"),A=_("el-empty"),O=Z("loading");return n(),l("div",q,[t[6]||(t[6]=e("div",{class:"page-header"},[e("h2",{class:"page-title"},"日历查账")],-1)),e("div",G,[x(d,{modelValue:p.value,"onUpdate:modelValue":t[0]||(t[0]=a=>p.value=a),ref_key:"calendarRef",ref:M},{"date-cell":U(({data:a})=>[e("div",{class:F(["date-cell",{"is-selected":a.isSelected}])},[e("span",J,i(a.day.split("-").pop()),1),C(a.day)?(n(),l("div",K,[...t[1]||(t[1]=[e("div",{class:"dot expense"},null,-1)])])):b("",!0)],2)]),_:1},8,["modelValue"])]),I((n(),l("div",Q,[e("div",ee,i(z.value)+" 收支概览",1),e("div",te,[e("div",se,[e("div",ae,[x(u)]),e("div",oe,[t[2]||(t[2]=e("span",{class:"today-label"},"收入",-1)),e("span",ne,"¥"+i(r.value.income.toFixed(2)),1)])]),e("div",ie,[e("div",le,[x(m)]),e("div",de,[t[3]||(t[3]=e("span",{class:"today-label"},"支出",-1)),e("span",ce,"¥"+i(r.value.expense.toFixed(2)),1)])])]),D.value?(n(),l("div",re,[t[4]||(t[4]=e("div",{class:"chart-header"},"各用户收支分布",-1)),e("div",{ref_key:"userChartRef",ref:f,style:{height:"260px"}},null,512)])):b("",!0),e("div",ue,[t[5]||(t[5]=e("div",{class:"list-header"},"当日记录明细",-1)),g.value.length>0?(n(),l("div",me,[(n(!0),l(Y,null,H(g.value,a=>(n(),l("div",{key:a.id,class:"mobile-record-item"},[e("div",pe,[e("div",ve,i(a.category_name),1),e("div",_e,[e("span",ye,i(a.user),1)]),a.note?(n(),l("div",he,i(a.note),1)):b("",!0)]),e("div",ge,[e("div",{class:F(["item-amount mono-number",a.type==="income"?"text-income":"text-expense"])},i(a.type==="income"?"+":"-")+"¥"+i(a.amount.toFixed(2)),3)])]))),128))])):(n(),W(A,{key:1,description:"当日无记录","image-size":60}))])])),[[O,h.value]])])}}},Re=j(fe,[["__scopeId","data-v-5b421604"]]);export{Re as default};

View File

@@ -0,0 +1 @@
.app-page[data-v-5b421604]{padding-bottom:40px}.page-header[data-v-5b421604]{margin-bottom:20px}.page-title[data-v-5b421604]{font-size:22px;font-weight:800}.calendar-container[data-v-5b421604]{padding:12px;margin-bottom:24px}.calendar-container[data-v-5b421604] .el-calendar__header{padding:12px 0;border-bottom:1px solid var(--border-color)}.calendar-container[data-v-5b421604] .el-calendar-table .el-calendar-day{height:60px;padding:4px;display:flex;justify-content:center;align-items:center}.date-cell[data-v-5b421604]{position:relative;width:36px;height:36px;display:flex;justify-content:center;align-items:center;border-radius:50%;font-weight:500;color:var(--text-main);transition:all .2s}.calendar-container[data-v-5b421604] .el-calendar-table td.is-selected .date-cell{background:var(--primary-color);color:#fff;box-shadow:0 4px 10px #2b59ff4d}.date-dots[data-v-5b421604]{position:absolute;bottom:2px;display:flex;gap:2px}.dot[data-v-5b421604]{width:4px;height:4px;border-radius:50%}.dot.expense[data-v-5b421604]{background-color:var(--danger-color)}.calendar-container[data-v-5b421604] .el-calendar-table td.is-selected .dot.expense{background-color:#fff}.section-label[data-v-5b421604]{font-size:16px;font-weight:700;color:var(--text-main);margin-bottom:16px}.today-summary-grid[data-v-5b421604]{display:grid;grid-template-columns:1fr 1fr;gap:16px}.today-card[data-v-5b421604]{background:var(--card-bg);border-radius:var(--radius-md);padding:16px;display:flex;align-items:center;gap:12px;box-shadow:var(--shadow-sm);border:1px solid var(--border-color)}.today-icon[data-v-5b421604]{width:36px;height:36px;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:18px}.income .today-icon[data-v-5b421604]{background:#ecfdf5;color:var(--success-color)}.expense .today-icon[data-v-5b421604]{background:#fff1f2;color:var(--danger-color)}.today-info[data-v-5b421604]{display:flex;flex-direction:column}.today-label[data-v-5b421604]{font-size:12px;color:var(--text-secondary)}.today-amount[data-v-5b421604]{font-size:16px;font-weight:700}.mt-20[data-v-5b421604]{margin-top:20px}.chart-card[data-v-5b421604]{padding:20px}.chart-header[data-v-5b421604]{font-size:14px;font-weight:600;margin-bottom:12px}.list-card[data-v-5b421604]{padding:16px}.list-header[data-v-5b421604]{font-size:14px;font-weight:600;margin-bottom:16px;border-bottom:1px solid var(--border-color);padding-bottom:8px}.mobile-record-list[data-v-5b421604]{display:flex;flex-direction:column;gap:10px}.mobile-record-item[data-v-5b421604]{display:flex;justify-content:space-between;align-items:center;padding:12px;background:var(--bg-color);border-radius:var(--radius-md);border:1px solid var(--border-color)}.item-left[data-v-5b421604]{display:flex;flex-direction:column;gap:2px}.item-category[data-v-5b421604]{font-weight:700;font-size:14px;color:var(--text-main)}.item-sub[data-v-5b421604]{display:flex;gap:8px;font-size:12px;color:var(--primary-color);font-weight:600}.item-note[data-v-5b421604]{font-size:11px;color:var(--text-secondary);margin-top:2px;max-width:180px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.item-right[data-v-5b421604]{text-align:right}.item-amount[data-v-5b421604]{font-size:16px;font-weight:800}@media (max-width: 768px){.app-page[data-v-5b421604]{padding-bottom:100px}.today-summary-grid[data-v-5b421604]{grid-template-columns:1fr;gap:10px}.calendar-container[data-v-5b421604] .el-calendar-table .el-calendar-day{height:44px}.date-cell[data-v-5b421604]{width:30px;height:30px;font-size:14px}}

View File

@@ -0,0 +1 @@
.summary-container[data-v-e3532072]{display:grid;grid-template-columns:1fr 1fr;gap:16px}.summary-card[data-v-e3532072]{background:var(--card-bg);border-radius:var(--radius-lg);padding:20px;display:flex;align-items:flex-start;gap:16px;box-shadow:var(--shadow-md);transition:all .3s ease;border:1px solid var(--border-color);overflow:hidden;position:relative}.summary-card[data-v-e3532072]:after{content:"";position:absolute;top:0;right:0;width:60px;height:60px;background:currentColor;opacity:.03;border-radius:0 0 0 100%}.summary-card[data-v-e3532072]:hover{transform:translateY(-2px);box-shadow:var(--shadow-lg)}.card-icon[data-v-e3532072]{width:44px;height:44px;border-radius:12px;display:flex;align-items:center;justify-content:center;font-size:20px;flex-shrink:0}.income .card-icon[data-v-e3532072]{background:#ecfdf5;color:var(--success-color)}.expense .card-icon[data-v-e3532072]{background:#fff1f2;color:var(--danger-color)}.card-content[data-v-e3532072]{flex:1;min-width:0}.card-label[data-v-e3532072]{font-size:13px;color:var(--text-secondary);font-weight:500;margin-bottom:4px}.card-amount[data-v-e3532072]{font-size:22px;font-weight:700;margin-bottom:12px}.income .card-amount[data-v-e3532072]{color:var(--success-color)}.expense .card-amount[data-v-e3532072]{color:var(--danger-color)}.symbol[data-v-e3532072]{font-size:14px;margin-right:2px}.user-pills[data-v-e3532072]{display:flex;flex-wrap:wrap;gap:6px}.pill[data-v-e3532072]{font-size:10px;padding:2px 8px;border-radius:10px;background:var(--bg-color);color:var(--text-secondary);border:1px solid var(--border-color);white-space:nowrap}@media (max-width: 640px){.summary-container[data-v-e3532072]{grid-template-columns:1fr;gap:12px}.summary-card[data-v-e3532072]{padding:16px}.card-amount[data-v-e3532072]{font-size:20px}}.pie-chart[data-v-aa9b5da6]{padding:16px}

View File

@@ -0,0 +1 @@
import{ax as O,e as v,H as f,L as m,P as s,M as _,O as w,Z as u,Y as C,F as k,ab as z,X as B,ag as x,j as $,k as N,a3 as I}from"./vue-Gs2e-20-.js";import{b as g,s as h,_ as F}from"./index-jY687wPe.js";import{i as M}from"./echarts-Bn9PLWWT.js";const Q=O("statistics",()=>{const t=v({initial_balance:0,total_income:0,total_expense:0,current_balance:0,userBalances:[]}),c=v(null),n=v(!1);async function a(){const e=await g.get();t.value=e}async function d(e){const l=await g.update(e);t.value={...t.value,...l},await a()}async function y(e,l){await g.updateUser(e,l),await a()}async function i(e){n.value=!0;try{c.value=await h.monthly(e)}finally{n.value=!1}}async function r(e){return await h.daily(e)}async function b(e){return await h.weekly(e)}async function S(e){return await h.yearly(e)}async function o(e,l){return await h.trend(e,l)}return{balanceInfo:t,monthlyStats:c,loading:n,fetchBalance:a,updateInitialBalance:d,updateUserInitialBalance:y,fetchMonthlyStats:i,fetchDailyStats:r,fetchWeeklyStats:b,fetchYearlyStats:S,fetchTrend:o}}),R={class:"summary-container"},j={class:"summary-card income"},E={class:"card-icon"},T={class:"card-content"},V={class:"card-label"},W={class:"card-amount mono-number"},A={key:0,class:"user-pills"},P={class:"summary-card expense"},U={class:"card-icon"},D={class:"card-content"},Y={class:"card-label"},H={class:"card-amount mono-number"},X={key:0,class:"user-pills"},Z={__name:"SummaryCards",props:{income:{type:Number,default:0},expense:{type:Number,default:0},userStats:{type:Object,default:()=>({})},periodLabel:{type:String,default:"本月"}},setup(t){return(c,n)=>{const a=x("Top"),d=x("el-icon"),y=x("Bottom");return f(),m("div",R,[s("div",j,[s("div",E,[_(d,null,{default:w(()=>[_(a)]),_:1})]),s("div",T,[s("div",V,u(t.periodLabel)+"收入",1),s("div",W,[n[0]||(n[0]=s("span",{class:"symbol"},"¥",-1)),C(u(t.income.toFixed(2)),1)]),Object.keys(t.userStats).length>0?(f(),m("div",A,[(f(!0),m(k,null,z(t.userStats,(i,r)=>(f(),m("span",{key:r,class:"pill"},u(r)+": ¥"+u(i.income.toFixed(0)),1))),128))])):B("",!0)])]),s("div",P,[s("div",U,[_(d,null,{default:w(()=>[_(y)]),_:1})]),s("div",D,[s("div",Y,u(t.periodLabel)+"支出",1),s("div",H,[n[1]||(n[1]=s("span",{class:"symbol"},"¥",-1)),C(u(t.expense.toFixed(2)),1)]),Object.keys(t.userStats).length>0?(f(),m("div",X,[(f(!0),m(k,null,z(t.userStats,(i,r)=>(f(),m("span",{key:r,class:"pill"},u(r)+": ¥"+u(i.expense.toFixed(0)),1))),128))])):B("",!0)])])])}}},ee=F(Z,[["__scopeId","data-v-e3532072"]]),q={__name:"CategoryPieChart",props:{data:{type:Array,default:()=>[]},title:{type:String,default:"支出分类"}},setup(t){const c=t,n=v(null);let a=null;function d(){if(!n.value)return;a||(a=M(n.value));const i=window.innerWidth<=768,r=i?{orient:"horizontal",bottom:0,left:"center",textStyle:{fontSize:11},type:"scroll"}:{orient:"vertical",right:10,top:"center",textStyle:{fontSize:12}},b=i?["35%","55%"]:["40%","70%"],S=i?["50%","45%"]:["40%","55%"];a.setOption({title:{text:c.title,left:"center",textStyle:{fontSize:14,color:"#606266"}},tooltip:{trigger:"item",confine:!0,formatter:o=>{const e=c.data.find(p=>p.name===o.name);let l=`${o.name}: ¥${o.value.toFixed(2)} (${o.percent}%)`;return e&&e.users&&e.users.length>0&&(l+="<br/>",e.users.forEach(p=>{if(p.total>0){const L=o.value>0?(p.total/o.value*100).toFixed(1):"0.0";l+=`&nbsp;&nbsp;${p.user}: ¥${p.total.toFixed(2)} (${L}%)<br/>`}})),l}},legend:r,series:[{type:"pie",radius:b,center:S,avoidLabelOverlap:!0,itemStyle:{borderRadius:6,borderColor:"#fff",borderWidth:2},label:{show:!1},emphasis:{label:{show:!0,fontSize:14,fontWeight:"bold"}},data:c.data.map(o=>({name:o.name,value:o.total}))}]},{notMerge:!0})}function y(){a&&(a.resize(),d())}return $(()=>c.data,d,{deep:!0}),N(()=>{d(),window.addEventListener("resize",y)}),I(()=>{a==null||a.dispose(),window.removeEventListener("resize",y)}),(i,r)=>(f(),m("div",{class:"pie-chart card",ref_key:"chartRef",ref:n,style:{height:"100%","min-height":"320px"}},null,512))}},te=F(q,[["__scopeId","data-v-aa9b5da6"]]);export{te as C,ee as S,Q as u};

1
client/dist/assets/DailyInput-Brf7hque.css vendored Executable file
View File

@@ -0,0 +1 @@
.record-form-container[data-v-aacbca7e]{padding:24px}.form-header[data-v-aacbca7e]{margin-bottom:24px;display:flex;justify-content:center}.type-selector[data-v-aacbca7e] .el-radio-button__inner{padding:12px 32px;font-weight:600}.form-grid[data-v-aacbca7e]{display:grid;grid-template-columns:1fr 1fr;gap:24px}.full-width[data-v-aacbca7e]{width:100%}.amount-input[data-v-aacbca7e]{width:100%!important}.amount-input[data-v-aacbca7e] .el-input__inner{font-family:var(--mono-number);font-size:18px;font-weight:700;color:var(--primary-color)}.category-option[data-v-aacbca7e]{display:flex;align-items:center;gap:8px}.form-footer[data-v-aacbca7e]{margin-top:24px;display:flex;justify-content:center}.submit-btn[data-v-aacbca7e]{width:200px;height:48px;border-radius:var(--radius-md);background:var(--primary-gradient);border:none;font-weight:700;box-shadow:0 4px 15px #2b59ff4d}.submit-btn[data-v-aacbca7e]:hover{transform:translateY(-2px);box-shadow:0 6px 20px #2b59ff66}@media (max-width: 640px){.form-grid[data-v-aacbca7e]{grid-template-columns:1fr;gap:0}.submit-btn[data-v-aacbca7e]{width:100%}.type-selector[data-v-aacbca7e] .el-radio-button__inner{padding:10px 24px;flex:1}.type-selector[data-v-aacbca7e]{display:flex;width:100%}}.category-cell[data-v-3db1c182]{display:flex;align-items:center;gap:8px}.cat-icon[data-v-3db1c182]{font-size:16px}.cat-name[data-v-3db1c182]{font-weight:500}.table-amount[data-v-3db1c182]{font-size:15px;font-weight:700}.mobile-list[data-v-3db1c182]{display:flex;flex-direction:column;gap:12px}.mobile-record-card[data-v-3db1c182]{background:var(--bg-color);border-radius:var(--radius-md);padding:12px;border:1px solid var(--border-color)}.card-main[data-v-3db1c182]{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:8px}.card-left[data-v-3db1c182]{display:flex;gap:12px}.cat-avatar[data-v-3db1c182]{width:40px;height:40px;background:#fff;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:20px;box-shadow:var(--shadow-sm)}.cat-info[data-v-3db1c182]{display:flex;flex-direction:column;gap:2px}.cat-title[data-v-3db1c182]{font-weight:700;color:var(--text-main);font-size:15px}.cat-user-note[data-v-3db1c182]{display:flex;align-items:center;gap:6px;font-size:12px}.user-pill[data-v-3db1c182]{color:var(--primary-color);background:var(--primary-light);padding:1px 6px;border-radius:4px;font-weight:600}.note-text[data-v-3db1c182]{color:var(--text-secondary);max-width:120px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.card-amount[data-v-3db1c182]{font-size:17px;font-weight:800}.card-actions[data-v-3db1c182]{display:flex;justify-content:flex-end;gap:12px;border-top:1px solid var(--border-color);padding-top:8px}.edit-grid[data-v-3db1c182]{display:flex;flex-direction:column;gap:12px}.app-page[data-v-295aaf08]{padding-bottom:40px}.page-header[data-v-295aaf08]{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px}.page-title[data-v-295aaf08]{font-size:22px;font-weight:800}.date-picker-section[data-v-295aaf08]{padding:16px}.date-nav[data-v-295aaf08]{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}.date-display[data-v-295aaf08]{flex:1;display:flex;justify-content:center;min-width:140px}.custom-date-picker[data-v-295aaf08]{width:100%!important;max-width:200px}.nav-btn[data-v-295aaf08]{border:none;background:var(--bg-color);color:var(--text-main)}.nav-btn[data-v-295aaf08]:hover{background:var(--primary-light);color:var(--primary-color)}.today-btn[data-v-295aaf08]{margin-left:auto}.section-title-small[data-v-295aaf08]{font-size:16px;font-weight:700;margin-bottom:16px;padding-bottom:12px;border-bottom:1px solid var(--border-color)}.user-list[data-v-295aaf08]{display:flex;flex-direction:column;gap:12px;min-height:60px;max-height:40vh;overflow-y:auto}.user-row[data-v-295aaf08]{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:12px;background:var(--bg-color);border-radius:var(--radius-md);transition:background .2s}.user-row[data-v-295aaf08]:hover{background:var(--primary-light)}.user-info-display[data-v-295aaf08]{display:flex;align-items:center;gap:12px}.user-avatar-small[data-v-295aaf08]{width:32px;height:32px;background:var(--primary-color);color:#fff;border-radius:50%;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:14px}.user-name-text[data-v-295aaf08]{font-size:15px;font-weight:500;color:var(--text-main)}.user-actions[data-v-295aaf08]{display:flex;gap:8px}.divider[data-v-295aaf08]{height:1px;background:var(--border-color);margin:20px 0}.add-user-row[data-v-295aaf08]{display:flex;align-items:center;gap:12px}@media (max-width: 768px){.app-page[data-v-295aaf08]{padding-bottom:100px}.page-header[data-v-295aaf08]{margin-top:10px}.user-row[data-v-295aaf08]{flex-direction:column;align-items:stretch}.user-actions[data-v-295aaf08]{margin-top:8px;justify-content:flex-end}}

1
client/dist/assets/DailyInput-CC7D6jO9.js vendored Executable file

File diff suppressed because one or more lines are too long

1
client/dist/assets/Dashboard-33HOkI16.css vendored Executable file

File diff suppressed because one or more lines are too long

1
client/dist/assets/Dashboard-BMzKp874.js vendored Executable file

File diff suppressed because one or more lines are too long

1
client/dist/assets/Login-DdLftJUa.js vendored Executable file
View File

@@ -0,0 +1 @@
import{H as p,L,P as e,M as o,O as r,I as A,X as S,a9 as z,u as m,ag as a,e as f,m as B,ay as N,az as W,Y as C}from"./vue-Gs2e-20-.js";import{u as M,k as R}from"./element-plus-JbJMPIks.js";import{_ as D,u as I}from"./index-jY687wPe.js";const P={class:"login-page"},U={class:"login-shell"},q={class:"login-hero"},E={class:"hero-badge"},H={class:"hero-grid"},O={class:"hero-card"},T={class:"hero-card-icon"},X={class:"hero-card"},Y={class:"hero-card-icon secondary"},j={class:"login-panel"},F={class:"login-card"},G={__name:"Login",setup(J){const _=N(),g=W(),v=I(),t=B({username:"admin",password:""}),i=f(!1),n=f("");function w(){const l=g.query.redirect;return typeof l=="string"&&l.startsWith("/")&&!l.startsWith("//")?l:"/"}async function y(){if(!t.username.trim()||!t.password){n.value="请输入用户名和密码";return}i.value=!0,n.value="";try{await v.login(t.username.trim(),t.password),await _.replace(w())}catch(l){n.value=l.message||"登录失败,请稍后重试"}finally{i.value=!1}}return(l,s)=>{const h=a("Lock"),u=a("el-icon"),b=a("Wallet"),x=a("DataAnalysis"),V=a("el-alert"),c=a("el-input"),k=a("el-button");return p(),L("div",P,[e("div",U,[e("section",q,[e("div",E,[o(u,null,{default:r(()=>[o(h)]),_:1}),s[2]||(s[2]=e("span",null,"Secure Access",-1))]),s[5]||(s[5]=e("h1",{class:"hero-title"},"登录后继续使用记账助手",-1)),s[6]||(s[6]=e("p",{class:"hero-text"}," 进入后可以查看余额、每日流水、月度趋势和分类统计,所有记账数据都只在登录成功后开放。 ",-1)),e("div",H,[e("article",O,[e("div",T,[o(u,null,{default:r(()=>[o(b)]),_:1})]),s[3]||(s[3]=e("div",null,[e("h2",null,"统一入口"),e("p",null,"总览、记账、日历和统计页面统一受登录态保护。")],-1))]),e("article",X,[e("div",Y,[o(u,null,{default:r(()=>[o(x)]),_:1})]),s[4]||(s[4]=e("div",null,[e("h2",null,"远程部署可用"),e("p",null,"登录校验已接入后端接口,部署到服务器后依然生效。")],-1))])])]),e("section",j,[e("div",F,[s[10]||(s[10]=e("div",{class:"login-card-header"},[e("p",{class:"eyebrow"},"Administrator Login"),e("h2",null,"输入账号密码"),e("p",{class:"subtext"},"验证通过后才会进入记账系统。")],-1)),n.value?(p(),A(V,{key:0,title:n.value,type:"error",closable:!1,"show-icon":"",class:"login-alert"},null,8,["title"])):S("",!0),e("form",{class:"login-form",onSubmit:z(y,["prevent"])},[s[8]||(s[8]=e("label",{class:"field-label",for:"username"},"用户名",-1)),o(c,{id:"username",modelValue:t.username,"onUpdate:modelValue":s[0]||(s[0]=d=>t.username=d),size:"large",placeholder:"请输入用户名","prefix-icon":m(M),autocomplete:"username"},null,8,["modelValue","prefix-icon"]),s[9]||(s[9]=e("label",{class:"field-label",for:"password"},"密码",-1)),o(c,{id:"password",modelValue:t.password,"onUpdate:modelValue":s[1]||(s[1]=d=>t.password=d),size:"large",type:"password","show-password":"",placeholder:"请输入密码","prefix-icon":m(R),autocomplete:"current-password"},null,8,["modelValue","prefix-icon"]),o(k,{class:"submit-button","native-type":"submit",type:"primary",size:"large",loading:i.value},{default:r(()=>[...s[7]||(s[7]=[C(" 登录并进入 ",-1)])]),_:1},8,["loading"])],32),s[11]||(s[11]=e("p",{class:"login-tip"}," 默认管理员账号已启用,部署时也可以通过服务端环境变量覆盖默认用户名和密码。 ",-1))])])])])}}},$=D(G,[["__scopeId","data-v-d2aa554d"]]);export{$ as default};

1
client/dist/assets/Login-h0FXweFc.css vendored Executable file
View File

@@ -0,0 +1 @@
.login-page[data-v-d2aa554d]{min-height:100vh;display:flex;align-items:stretch;justify-content:center;background:radial-gradient(circle at top left,rgba(43,89,255,.22),transparent 34%),radial-gradient(circle at bottom right,rgba(16,185,129,.18),transparent 30%),linear-gradient(135deg,#eff4ff,#f8fafc 40%,#eefbf7)}.login-shell[data-v-d2aa554d]{width:min(1180px,100%);min-height:100vh;display:grid;grid-template-columns:1.15fr .85fr}.login-hero[data-v-d2aa554d]{padding:72px 56px;display:flex;flex-direction:column;justify-content:center;gap:28px}.hero-badge[data-v-d2aa554d]{width:fit-content;display:inline-flex;align-items:center;gap:8px;padding:8px 14px;border-radius:999px;background:#ffffffb8;border:1px solid rgba(43,89,255,.14);color:var(--primary-color);font-size:13px;font-weight:700;letter-spacing:.04em;text-transform:uppercase}.hero-title[data-v-d2aa554d]{max-width:560px;font-size:clamp(36px,5vw,58px);line-height:1.04;letter-spacing:-.05em;font-weight:800;color:#10213f}.hero-text[data-v-d2aa554d]{max-width:560px;font-size:17px;line-height:1.8;color:#4f6280}.hero-grid[data-v-d2aa554d]{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px}.hero-card[data-v-d2aa554d]{display:flex;gap:14px;padding:22px;border-radius:24px;background:#ffffffb8;border:1px solid rgba(255,255,255,.86);box-shadow:0 18px 45px #1c355e14}.hero-card h2[data-v-d2aa554d]{margin-bottom:6px;font-size:18px;color:#10213f}.hero-card p[data-v-d2aa554d]{color:#5f708b;font-size:14px;line-height:1.7}.hero-card-icon[data-v-d2aa554d]{width:48px;height:48px;flex-shrink:0;display:flex;align-items:center;justify-content:center;border-radius:16px;background:linear-gradient(135deg,#2b59ff,#2551e8);color:#fff;font-size:22px;box-shadow:0 12px 22px #2b59ff47}.hero-card-icon.secondary[data-v-d2aa554d]{background:linear-gradient(135deg,#10b981,#059669);box-shadow:0 12px 22px #05966938}.login-panel[data-v-d2aa554d]{display:flex;align-items:center;justify-content:center;padding:40px 32px}.login-card[data-v-d2aa554d]{width:min(460px,100%);padding:34px;border-radius:30px;background:#ffffffe6;border:1px solid rgba(255,255,255,.92);box-shadow:0 28px 60px #0f172a24;backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px)}.login-card-header[data-v-d2aa554d]{margin-bottom:22px}.eyebrow[data-v-d2aa554d]{margin-bottom:8px;color:var(--primary-color);font-size:12px;font-weight:700;letter-spacing:.12em;text-transform:uppercase}.login-card-header h2[data-v-d2aa554d]{font-size:28px;line-height:1.2;margin-bottom:8px;color:#10213f}.subtext[data-v-d2aa554d]{color:#63748b;font-size:14px}.login-alert[data-v-d2aa554d]{margin-bottom:18px}.login-form[data-v-d2aa554d]{display:grid;gap:12px}.field-label[data-v-d2aa554d]{margin-top:4px;font-size:13px;font-weight:700;color:#31435f}.submit-button[data-v-d2aa554d]{width:100%;height:48px;margin-top:10px;border:none;background:linear-gradient(135deg,#2b59ff,#1d4ed8);box-shadow:0 14px 30px #2b59ff47}.submit-button[data-v-d2aa554d]:hover{filter:brightness(1.02)}.login-tip[data-v-d2aa554d]{margin-top:16px;color:#6b7280;font-size:13px;line-height:1.7}@media (max-width: 960px){.login-shell[data-v-d2aa554d]{grid-template-columns:1fr}.login-hero[data-v-d2aa554d]{padding:40px 24px 18px}.hero-grid[data-v-d2aa554d]{grid-template-columns:1fr}.login-panel[data-v-d2aa554d]{padding:0 16px 28px}.login-card[data-v-d2aa554d]{padding:26px 22px;border-radius:24px}}@media (max-width: 640px){.hero-title[data-v-d2aa554d]{font-size:34px}.hero-text[data-v-d2aa554d]{font-size:15px;line-height:1.7}}

1
client/dist/assets/Statistics-BLocXSk3.css vendored Executable file
View File

@@ -0,0 +1 @@
.app-page[data-v-462e5f0a]{padding-bottom:40px}.page-header[data-v-462e5f0a]{display:flex;justify-content:space-between;align-items:center;margin-bottom:24px}.page-title[data-v-462e5f0a]{font-size:24px;font-weight:800}.user-select[data-v-462e5f0a]{width:140px}.filter-card[data-v-462e5f0a]{padding:12px 20px}.filter-container[data-v-462e5f0a]{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:16px}.dimension-tabs[data-v-462e5f0a] .el-radio-button__inner{border:none;background:transparent;padding:8px 16px;font-weight:600}.dimension-tabs[data-v-462e5f0a] .el-radio-button__original-radio:checked+.el-radio-button__inner{background:var(--primary-color);border-radius:var(--radius-md);box-shadow:var(--shadow-sm)}.date-picker-wrapper[data-v-462e5f0a]{flex-shrink:0}.custom-picker[data-v-462e5f0a]{width:130px!important}.main-chart-card[data-v-462e5f0a]{padding:24px}.chart-box[data-v-462e5f0a]{height:320px;width:100%;margin-top:20px}.charts-grid[data-v-462e5f0a]{display:grid;grid-template-columns:1fr 1.2fr;gap:20px}.side-chart-card[data-v-462e5f0a]{padding:20px}.chart-box-small[data-v-462e5f0a]{height:280px;width:100%;margin-top:12px}.section-title-small[data-v-462e5f0a]{font-size:16px;font-weight:700;color:var(--text-main)}.table-card[data-v-462e5f0a]{padding:0;overflow:hidden}.section-header[data-v-462e5f0a]{padding:20px 24px;border-bottom:1px solid var(--border-color)}.table-container[data-v-462e5f0a]{padding:0 12px}.record-info[data-v-462e5f0a]{display:flex;flex-direction:column;gap:4px}.record-main[data-v-462e5f0a]{display:flex;align-items:center;gap:8px}.cat-tag[data-v-462e5f0a]{font-size:11px;padding:2px 8px;border-radius:4px;font-weight:600}.cat-tag.expense[data-v-462e5f0a]{background:#fff1f2;color:var(--danger-color)}.cat-tag.income[data-v-462e5f0a]{background:#ecfdf5;color:var(--success-color)}.record-date[data-v-462e5f0a]{font-size:11px;color:var(--text-light)}.record-note[data-v-462e5f0a]{font-size:12px;color:var(--text-secondary);opacity:.8}.user-pill-small[data-v-462e5f0a]{width:22px;height:22px;background:var(--bg-color);border-radius:4px;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:700;color:var(--text-secondary)}.amount-text[data-v-462e5f0a]{font-size:16px;font-weight:700}@media (max-width: 1024px){.charts-grid[data-v-462e5f0a]{grid-template-columns:1fr}}@media (max-width: 768px){.app-page[data-v-462e5f0a]{padding-bottom:100px}.page-header[data-v-462e5f0a]{flex-direction:column;align-items:flex-start;gap:16px;margin-top:10px}.filter-container[data-v-462e5f0a]{flex-direction:column;align-items:stretch}.dimension-tabs[data-v-462e5f0a]{display:flex;width:100%}.dimension-tabs[data-v-462e5f0a] .el-radio-button{flex:1}.dimension-tabs[data-v-462e5f0a] .el-radio-button__inner,.date-picker-wrapper[data-v-462e5f0a]{width:100%}.custom-picker[data-v-462e5f0a]{width:100%!important;max-width:none}}

1
client/dist/assets/Statistics-BMDw4pEJ.js vendored Executable file

File diff suppressed because one or more lines are too long

1
client/dist/assets/date-CWsjnySd.js vendored Executable file
View File

@@ -0,0 +1 @@
function c(t=new Date){const a=t instanceof Date?t:new Date(t),e=a.getFullYear(),n=String(a.getMonth()+1).padStart(2,"0"),o=String(a.getDate()).padStart(2,"0");return`${e}-${n}-${o}`}function s(t=new Date){return c(t).slice(0,7)}function i(t=new Date){return String((t instanceof Date?t:new Date(t)).getFullYear())}function D(t,a){const[e,n,o]=String(t).split("-").map(Number),r=new Date(e,n-1,o);return r.setDate(r.getDate()+a),c(r)}export{c as a,i as b,s as f,D as s};

60
client/dist/assets/echarts-Bn9PLWWT.js vendored Executable file

File diff suppressed because one or more lines are too long

63
client/dist/assets/element-plus-JbJMPIks.js vendored Executable file

File diff suppressed because one or more lines are too long

1
client/dist/assets/index-COAiqWc_.css vendored Executable file

File diff suppressed because one or more lines are too long

7
client/dist/assets/index-jY687wPe.js vendored Executable file

File diff suppressed because one or more lines are too long

1
client/dist/assets/records-rp0LN8a-.js vendored Executable file
View File

@@ -0,0 +1 @@
import{ax as p,e as c}from"./vue-Gs2e-20-.js";import{c as h,r}from"./index-jY687wPe.js";const x=p("records",()=>{const a=c([]),o=c([]),n=c(!1);async function u(){o.value=await h.getAll()}async function l(e){n.value=!0;try{a.value=await r.getByDate(e)}finally{n.value=!1}}async function f(e){n.value=!0;try{a.value=await r.getByMonth(e)}finally{n.value=!1}}async function d(e){const t=await r.create(e);return a.value.unshift(t),t}async function y(e,t){const s=await r.update(e,t),i=a.value.findIndex(g=>g.id===e);return i!==-1&&(a.value[i]=s),s}async function v(e){await r.delete(e),a.value=a.value.filter(t=>t.id!==e)}return{records:a,categories:o,loading:n,fetchCategories:u,fetchByDate:l,fetchByMonth:f,addRecord:d,updateRecord:y,deleteRecord:v}});export{x as u};

29
client/dist/assets/vue-Gs2e-20-.js vendored Executable file

File diff suppressed because one or more lines are too long

15
client/dist/index.html vendored Executable file
View File

@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>记账助手</title>
<script type="module" crossorigin src="/assets/index-jY687wPe.js"></script>
<link rel="modulepreload" crossorigin href="/assets/vue-Gs2e-20-.js">
<link rel="modulepreload" crossorigin href="/assets/element-plus-JbJMPIks.js">
<link rel="stylesheet" crossorigin href="/assets/index-COAiqWc_.css">
</head>
<body>
<div id="app"></div>
</body>
</html>