第一次上传

This commit is contained in:
xxk
2026-06-11 09:53:11 +08:00
commit e257f2009e
89 changed files with 4336 additions and 0 deletions
@@ -0,0 +1 @@
"use strict";const e=require("../../common/vendor.js"),t=require("../../utils/store.js"),a=require("../../utils/date.js"),u=require("../../utils/money.js");Math||(r+n)();const r=()=>"../../components/SectionCard.js",n=()=>"../../components/AppTabBar.js",o={__name:"index",setup(r){const n=t.useAppStore(),o=e.computed((()=>a.toMonthKey())),s=e.computed((()=>"dark"===n.state.settings.theme?"theme-dark":"")),l=e.ref(String(n.state.budgets.total||"")),d=e.reactive({}),c=e.computed((()=>n.state.bills.filter((e=>"expense"===e.type&&a.isSameMonth(e.date,o.value))))),i=e.computed((()=>c.value.reduce(((e,t)=>e+Number(t.amount)),0))),m=e.computed((()=>Number(n.state.budgets.total)||0)),p=e.computed((()=>m.value-i.value)),v=e.computed((()=>Math.max(p.value,0)/Math.max(1,a.getDaysLeftInMonth(o.value)))),g=e.computed((()=>m.value?u.formatPercent(i.value/Math.max(m.value,1)):"未设置")),f=e.computed((()=>u.clampPercent(i.value/Math.max(m.value||1,1)))),b=e.computed((()=>n.state.categories.expense.map((e=>{const t=c.value.filter((t=>t.categoryId===e.id)).reduce(((e,t)=>e+Number(t.amount)),0),a=Number(n.state.budgets.categoryBudgets[e.id]||0);return{...e,spent:t,budget:a,progressLabel:a?u.formatPercent(t/Math.max(a,1)):"未设置",progressWidth:u.clampPercent(t/Math.max(a||1,1))}})))),h=e.computed((()=>b.value.filter((e=>e.budget>0&&e.spent>e.budget))));function y(){n.setBudgetTotal(l.value),e.index.showToast({title:"总预算已保存",icon:"none"})}return e.watch((()=>n.state.budgets.total),(e=>{l.value=String(e||"")}),{immediate:!0}),e.watch(b,(e=>{e.forEach((e=>{d[e.id]=String(e.budget||"")}))}),{immediate:!0}),(t,a)=>e.e({a:e.t(e.unref(u.formatCurrency)(m.value)),b:e.t(e.unref(u.formatCurrency)(i.value)),c:f.value,d:e.t(g.value),e:e.t(p.value>=0?`剩余 ${e.unref(u.formatCurrency)(p.value)}`:`已超支 ${e.unref(u.formatCurrency)(Math.abs(p.value))}`),f:e.t(m.value?`日均可用 ${e.unref(u.formatCurrency)(v.value)}`:"设置预算后可查看剩余额度分配"),g:l.value,h:e.o((e=>l.value=e.detail.value)),i:e.o(y),j:e.p({title:"月度预算",subtitle:"设置总预算与分类预算,控制消费节奏"}),k:h.value.length},h.value.length?{l:e.f(h.value,((t,a,r)=>({a:e.t(t.name),b:e.t(e.unref(u.formatCurrency)(t.budget)),c:e.t(e.unref(u.formatCurrency)(t.spent)),d:t.id}))),m:e.p({title:"超支提醒",subtitle:"当前分类预算已被突破,建议尽快调整"})}:{},{n:e.f(b.value,((t,a,r)=>({a:t.color,b:e.t(t.name),c:e.t(e.unref(u.formatCurrency)(t.spent)),d:t.progressWidth,e:e.t(e.unref(u.formatCurrency)(t.budget)),f:e.t(t.progressLabel),g:e.n(t.budget>0&&t.spent>t.budget?"negative":""),h:d[t.id],i:e.o((e=>d[t.id]=e.detail.value),t.id),j:e.o((a=>{return u=t.id,n.setCategoryBudget(u,d[u]),void e.index.showToast({title:"分类预算已保存",icon:"none"});var u}),t.id),k:t.id}))),o:e.p({title:"分类预算",subtitle:"为高频分类分别设置预算,减少超支风险"}),p:e.p({current:"budget"}),q:e.n(s.value)})}},s=e._export_sfc(o,[["__scopeId","data-v-a56ca0c4"]]);wx.createPage(s);
@@ -0,0 +1,7 @@
{
"navigationBarTitleText": "预算管理",
"usingComponents": {
"section-card": "../../components/SectionCard",
"app-tab-bar": "../../components/AppTabBar"
}
}
@@ -0,0 +1 @@
<view class="{{['app-page', 'data-v-a56ca0c4', q]}}"><section-card wx:if="{{j}}" class="data-v-a56ca0c4" u-s="{{['d']}}" u-i="a56ca0c4-0" bind:__l="__l" u-p="{{j}}"><view class="budget-hero surface-strong data-v-a56ca0c4"><view class="data-v-a56ca0c4"><text class="tiny-text data-v-a56ca0c4">本月总预算</text><text class="budget-number data-v-a56ca0c4">{{a}}</text></view><view class="data-v-a56ca0c4"><text class="tiny-text data-v-a56ca0c4">本月已支出</text><text class="budget-number negative data-v-a56ca0c4">{{b}}</text></view></view><view class="progress-track data-v-a56ca0c4"><view class="progress-fill data-v-a56ca0c4" style="{{'width:' + c}}"></view></view><view class="budget-foot data-v-a56ca0c4"><text class="tiny-text data-v-a56ca0c4">使用进度 {{d}}</text><text class="tiny-text data-v-a56ca0c4">{{e}}</text></view><view class="budget-foot secondary-foot data-v-a56ca0c4"><text class="tiny-text data-v-a56ca0c4">{{f}}</text></view><view class="editor-row data-v-a56ca0c4"><view class="input-shell data-v-a56ca0c4"><input class="data-v-a56ca0c4" type="digit" placeholder="输入本月总预算" value="{{g}}" bindinput="{{h}}"/></view><view class="primary-button save-btn data-v-a56ca0c4" bindtap="{{i}}">保存</view></view></section-card><section-card wx:if="{{k}}" class="data-v-a56ca0c4" u-s="{{['d']}}" u-i="a56ca0c4-1" bind:__l="__l" u-p="{{m}}"><view class="alert-list data-v-a56ca0c4"><view wx:for="{{l}}" wx:for-item="item" wx:key="d" class="alert-item data-v-a56ca0c4"><text class="alert-title data-v-a56ca0c4">{{item.a}}</text><text class="alert-text data-v-a56ca0c4">预算 {{item.b}},已支出 {{item.c}}</text></view></view></section-card><section-card wx:if="{{o}}" class="data-v-a56ca0c4" u-s="{{['d']}}" u-i="a56ca0c4-2" bind:__l="__l" u-p="{{o}}"><view class="category-list data-v-a56ca0c4"><view wx:for="{{n}}" wx:for-item="item" wx:key="k" class="category-card surface-strong data-v-a56ca0c4"><view class="category-head data-v-a56ca0c4"><view class="category-title-row data-v-a56ca0c4"><view class="category-dot data-v-a56ca0c4" style="{{'background:' + item.a}}"></view><text class="category-title data-v-a56ca0c4">{{item.b}}</text></view><text class="tiny-text data-v-a56ca0c4">已花 {{item.c}}</text></view><view class="progress-track thin-track data-v-a56ca0c4"><view class="progress-fill data-v-a56ca0c4" style="{{'width:' + item.d}}"></view></view><view class="budget-foot data-v-a56ca0c4"><text class="tiny-text data-v-a56ca0c4">预算 {{item.e}}</text><text class="{{['tiny-text', 'data-v-a56ca0c4', item.g]}}">{{item.f}}</text></view><view class="editor-row data-v-a56ca0c4"><view class="input-shell data-v-a56ca0c4"><input class="data-v-a56ca0c4" type="digit" placeholder="设置分类预算" value="{{item.h}}" bindinput="{{item.i}}"/></view><view class="ghost-button save-btn data-v-a56ca0c4" bindtap="{{item.j}}">保存</view></view></view></view></section-card><app-tab-bar wx:if="{{p}}" class="data-v-a56ca0c4" u-i="a56ca0c4-3" bind:__l="__l" u-p="{{p}}"/></view>
@@ -0,0 +1 @@
.budget-hero.data-v-a56ca0c4,.category-card.data-v-a56ca0c4{padding:24rpx;border-radius:24rpx}.budget-hero.data-v-a56ca0c4,.category-head.data-v-a56ca0c4,.category-title-row.data-v-a56ca0c4,.budget-foot.data-v-a56ca0c4,.editor-row.data-v-a56ca0c4{display:flex;align-items:center;justify-content:space-between;gap:16rpx}.secondary-foot.data-v-a56ca0c4{margin-top:10rpx}.budget-number.data-v-a56ca0c4{display:block;margin-top:10rpx;font-size:34rpx;font-weight:700;color:var(--text-primary)}.progress-track.data-v-a56ca0c4{overflow:hidden;height:18rpx;margin:24rpx 0 16rpx;border-radius:999rpx;background:var(--surface-muted)}.thin-track.data-v-a56ca0c4{height:14rpx;margin:18rpx 0 14rpx}.progress-fill.data-v-a56ca0c4{height:100%;border-radius:inherit;background:linear-gradient(90deg,#5f8df5,#1f6f5f)}.editor-row.data-v-a56ca0c4{margin-top:20rpx}.editor-row .input-shell.data-v-a56ca0c4{flex:1}.save-btn.data-v-a56ca0c4{flex:0 0 180rpx}.alert-list.data-v-a56ca0c4,.category-list.data-v-a56ca0c4{display:flex;flex-direction:column;gap:18rpx}.alert-item.data-v-a56ca0c4{padding:20rpx 22rpx;border-radius:22rpx;background:var(--danger-soft)}.alert-title.data-v-a56ca0c4{font-size:28rpx;font-weight:600;color:var(--danger)}.alert-text.data-v-a56ca0c4{display:block;margin-top:8rpx;font-size:22rpx;color:var(--danger)}.category-dot.data-v-a56ca0c4{width:16rpx;height:16rpx;border-radius:50%}.category-title.data-v-a56ca0c4{font-size:28rpx;font-weight:600;color:var(--text-primary)}