diff --git a/.opencode/skills/bug-fix/SKILL.md b/.opencode/skills/bug-fix/SKILL.md index 19ded36..4627c32 100644 --- a/.opencode/skills/bug-fix/SKILL.md +++ b/.opencode/skills/bug-fix/SKILL.md @@ -1,12 +1,13 @@ --- name: bug-fix description: Bug诊断与修复技能 - 强调交互式确认和影响分析 -tags: - - bug-fix - - debugging - - troubleshooting - - interactive -version: 1.0.1 +metadata: + tags: + - bug-fix + - debugging + - troubleshooting + - interactive + version: 1.0.1 --- # Bug修复技能 diff --git a/.opencode/skills/code-refactoring/SKILL.md b/.opencode/skills/code-refactoring/SKILL.md index 0be8dce..f0ca616 100644 --- a/.opencode/skills/code-refactoring/SKILL.md +++ b/.opencode/skills/code-refactoring/SKILL.md @@ -1,12 +1,13 @@ --- name: code-refactoring description: 代码重构技能 - 强调保持功能不变的前提下优化代码结构,充分理解需求和交互式确认 -tags: - - refactoring - - code-quality - - clean-code - - interactive -version: 1.0.0 +metadata: + tags: + - refactoring + - code-quality + - clean-code + - interactive + version: 1.0.0 --- # 代码重构技能 diff --git a/.pans/images/generated-1770203108037.png b/.pans/images/generated-1770203108037.png new file mode 100644 index 0000000..30b5d76 Binary files /dev/null and b/.pans/images/generated-1770203108037.png differ diff --git a/.pans/images/generated-1770203115588.png b/.pans/images/generated-1770203115588.png new file mode 100644 index 0000000..6342c73 Binary files /dev/null and b/.pans/images/generated-1770203115588.png differ diff --git a/.pans/images/generated-1770203140554.png b/.pans/images/generated-1770203140554.png new file mode 100644 index 0000000..1349507 Binary files /dev/null and b/.pans/images/generated-1770203140554.png differ diff --git a/.pans/images/generated-1770203148526.png b/.pans/images/generated-1770203148526.png new file mode 100644 index 0000000..7b5ce65 Binary files /dev/null and b/.pans/images/generated-1770203148526.png differ diff --git a/.pans/images/generated-1770203336617.png b/.pans/images/generated-1770203336617.png new file mode 100644 index 0000000..ca6c679 Binary files /dev/null and b/.pans/images/generated-1770203336617.png differ diff --git a/.pans/images/generated-1770203344337.png b/.pans/images/generated-1770203344337.png new file mode 100644 index 0000000..6ac2013 Binary files /dev/null and b/.pans/images/generated-1770203344337.png differ diff --git a/.pans/v2.pen b/.pans/v2.pen index 1094ed3..8c8c6c8 100644 --- a/.pans/v2.pen +++ b/.pans/v2.pen @@ -1,1804 +1,6 @@ { - "version": "2.6", + "version": "2.7", "children": [ - { - "type": "frame", - "id": "jF3SD", - "x": -983, - "y": 369, - "name": "Statistics - Overview - Light", - "clip": true, - "width": 375, - "fill": "#FFFFFF", - "layout": "vertical", - "children": [ - { - "type": "frame", - "id": "HdrL1", - "name": "header", - "width": "fill_container", - "gap": 4, - "padding": [ - 8, - 24 - ], - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "HdrC1", - "name": "headerContent", - "width": 142, - "height": 39, - "layout": "vertical", - "gap": 4, - "children": [ - { - "type": "text", - "id": "TxtL1", - "name": "subtitle", - "fill": "#1a1a1a", - "content": "2026年", - "fontFamily": "DM Sans", - "fontSize": 24, - "fontWeight": "500" - } - ] - }, - { - "type": "frame", - "id": "BtnL1", - "name": "notifBtn", - "width": 44, - "height": 44, - "fill": "#F5F5F5", - "cornerRadius": 22, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "IcnL1", - "name": "icon", - "width": 20, - "height": 20, - "iconFontName": "bell", - "iconFontFamily": "lucide", - "fill": "#1A1A1A" - } - ] - } - ] - }, - { - "type": "frame", - "id": "AMTax", - "name": "contentWrapper", - "width": "fill_container", - "layout": "vertical", - "gap": 24, - "padding": 24, - "children": [ - { - "type": "frame", - "id": "vfuYD", - "name": "periodSection", - "width": "fill_container", - "layout": "vertical", - "gap": 16, - "children": [ - { - "type": "frame", - "id": "oTdXY", - "name": "segmentControl", - "width": "fill_container", - "height": 44, - "fill": "#F0F0F0", - "cornerRadius": 8, - "gap": 4, - "padding": 4, - "children": [ - { - "type": "frame", - "id": "wmlqF", - "name": "daySegment", - "width": "fill_container", - "height": "fill_container", - "fill": "#FFFFFF", - "cornerRadius": 6, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "H0yK4", - "name": "dayLabel", - "fill": "#1A1A1A", - "content": "周", - "fontFamily": "DM Sans", - "fontSize": 13, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "R5SrL", - "name": "weekSegment", - "width": "fill_container", - "height": "fill_container", - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "qMr9M", - "name": "weekLabel", - "fill": "#888888", - "content": "月", - "fontFamily": "DM Sans", - "fontSize": 13, - "fontWeight": "500" - } - ] - }, - { - "type": "frame", - "id": "1yyvY", - "name": "monthSegment", - "width": "fill_container", - "height": "fill_container", - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "NJAly", - "name": "monthLabel", - "fill": "#888888", - "content": "年", - "fontFamily": "DM Sans", - "fontSize": 13, - "fontWeight": "500" - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "wxhYu", - "name": "metricsSection", - "width": "fill_container", - "layout": "vertical", - "gap": 16, - "children": [ - { - "type": "text", - "id": "uRrgm", - "name": "metricsHeader", - "fill": "#888888", - "content": "核心指标", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600", - "letterSpacing": 2 - }, - { - "type": "frame", - "id": "29VOa", - "name": "metricsRow", - "width": "fill_container", - "gap": 16, - "children": [ - { - "type": "frame", - "id": "uI5xe", - "name": "card1", - "width": "fill_container", - "height": 146, - "fill": "#FFFFFF", - "cornerRadius": 12, - "stroke": { - "thickness": 1, - "fill": "#E5E5E5" - }, - "layout": "vertical", - "gap": 12, - "padding": 24, - "justifyContent": "space_between", - "children": [ - { - "type": "frame", - "id": "FmWfR", - "name": "card1Top", - "width": "fill_container", - "layout": "vertical", - "gap": 12, - "children": [ - { - "type": "frame", - "id": "fAZoH", - "name": "card1Header", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "hxA0w", - "name": "card1Label", - "fill": "#888888", - "content": "总支出", - "fontFamily": "DM Sans", - "fontSize": 12, - "fontWeight": "500" - }, - { - "type": "text", - "id": "GcqI5", - "name": "card1Badge", - "fill": "#E07B54", - "content": "-15%", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "600" - } - ] - }, - { - "type": "text", - "id": "LzO5o", - "name": "card1Value", - "fill": "#1A1A1A", - "content": "¥1,248.50", - "lineHeight": 0.85, - "fontFamily": "JetBrains Mono", - "fontSize": 32, - "fontWeight": "700" - } - ] - }, - { - "type": "text", - "id": "pYHqx", - "name": "card1Bottom", - "fill": "#666666", - "content": "较上期减少", - "fontFamily": "Newsreader", - "fontSize": 13, - "fontWeight": "normal", - "fontStyle": "italic" - } - ] - }, - { - "type": "frame", - "id": "hJgnc", - "name": "card2", - "width": "fill_container", - "height": 146, - "fill": "#FFFFFF", - "cornerRadius": 12, - "stroke": { - "thickness": 1, - "fill": "#E5E5E5" - }, - "layout": "vertical", - "gap": 12, - "padding": 24, - "justifyContent": "space_between", - "children": [ - { - "type": "frame", - "id": "8McqI", - "name": "card2Top", - "width": "fill_container", - "layout": "vertical", - "gap": 12, - "children": [ - { - "type": "frame", - "id": "pdjzv", - "name": "card2Header", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "blBHp", - "name": "card2Label", - "fill": "#888888", - "content": "交易笔数", - "fontFamily": "DM Sans", - "fontSize": 12, - "fontWeight": "500" - }, - { - "type": "text", - "id": "pR4il", - "name": "card2Badge", - "fill": "#0D6E6E", - "content": "+8", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "600" - } - ] - }, - { - "type": "text", - "id": "jBKa6", - "name": "card2Value", - "fill": "#1A1A1A", - "content": "127", - "lineHeight": 0.85, - "fontFamily": "JetBrains Mono", - "fontSize": 32, - "fontWeight": "700" - } - ] - }, - { - "type": "frame", - "id": "DEuSA", - "name": "card2Bottom", - "width": "fill_container", - "height": 24, - "gap": 4, - "alignItems": "end", - "children": [ - { - "type": "rectangle", - "cornerRadius": 2, - "id": "Bbiv4", - "name": "bar1", - "fill": "#E5E5E5", - "width": "fill_container", - "height": 8 - }, - { - "type": "rectangle", - "cornerRadius": 2, - "id": "6wkI0", - "name": "bar2", - "fill": "#E5E5E5", - "width": "fill_container", - "height": 12 - }, - { - "type": "rectangle", - "cornerRadius": 2, - "id": "Orujn", - "name": "bar3", - "fill": "#E5E5E5", - "width": "fill_container", - "height": 16 - }, - { - "type": "rectangle", - "cornerRadius": 2, - "id": "JLpTY", - "name": "bar4", - "fill": "#E5E5E5", - "width": "fill_container", - "height": 14 - }, - { - "type": "rectangle", - "cornerRadius": 2, - "id": "hjMuU", - "name": "bar5", - "fill": "#E5E5E5", - "width": "fill_container", - "height": 20 - }, - { - "type": "rectangle", - "cornerRadius": 2, - "id": "OQWag", - "name": "bar6", - "fill": "#E5E5E5", - "width": "fill_container", - "height": 18 - }, - { - "type": "rectangle", - "cornerRadius": 2, - "id": "5bqxw", - "name": "bar7", - "fill": "#0D6E6E", - "width": "fill_container", - "height": 24 - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "Pq97G", - "name": "incomeRow", - "width": "fill_container", - "gap": 16, - "children": [ - { - "type": "frame", - "id": "L3XxO", - "name": "incomeCard", - "width": "fill_container", - "height": 146, - "fill": "#FFFFFF", - "cornerRadius": 12, - "stroke": { - "thickness": 1, - "fill": "#E5E5E5" - }, - "layout": "vertical", - "gap": 12, - "padding": 24, - "justifyContent": "space_between", - "children": [ - { - "type": "frame", - "id": "V83CL", - "name": "incomeTop", - "width": "fill_container", - "layout": "vertical", - "gap": 12, - "children": [ - { - "type": "frame", - "id": "bzN0J", - "name": "incomeHeader", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "feyMh", - "name": "incomeLabel", - "fill": "#888888", - "content": "总收入", - "fontFamily": "DM Sans", - "fontSize": 12, - "fontWeight": "500" - }, - { - "type": "text", - "id": "LiGoC", - "name": "incomeBadge", - "fill": "#0D6E6E", - "content": "+2", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "600" - } - ] - }, - { - "type": "text", - "id": "FiPju", - "name": "incomeValue", - "fill": "#0D6E6E", - "content": "¥3,200", - "lineHeight": 0.85, - "fontFamily": "JetBrains Mono", - "fontSize": 32, - "fontWeight": "700" - } - ] - }, - { - "type": "text", - "id": "J0zG7", - "name": "incomeBottom", - "fill": "#666666", - "content": "工资、红包等", - "fontFamily": "Newsreader", - "fontSize": 13, - "fontWeight": "normal", - "fontStyle": "italic" - } - ] - }, - { - "type": "frame", - "id": "XICsc", - "name": "balanceCard", - "width": "fill_container", - "height": 146, - "fill": "#FFFFFF", - "cornerRadius": 12, - "stroke": { - "thickness": 1, - "fill": "#E5E5E5" - }, - "layout": "vertical", - "gap": 12, - "padding": 24, - "justifyContent": "space_between", - "children": [ - { - "type": "frame", - "id": "lNqoA", - "name": "balanceTop", - "width": "fill_container", - "layout": "vertical", - "gap": 12, - "children": [ - { - "type": "frame", - "id": "j1gDj", - "name": "balanceHeader", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "w3hrq", - "name": "balanceLabel", - "fill": "#888888", - "content": "净收支", - "fontFamily": "DM Sans", - "fontSize": 12, - "fontWeight": "500" - }, - { - "type": "icon_font", - "id": "ZBAuV", - "name": "balanceIcon", - "width": 16, - "height": 16, - "iconFontName": "trending-up", - "iconFontFamily": "lucide", - "fill": "#0D6E6E" - } - ] - }, - { - "type": "text", - "id": "OpVvd", - "name": "balanceValue", - "fill": "#0D6E6E", - "content": "+¥1,951.50", - "lineHeight": 0.85, - "fontFamily": "JetBrains Mono", - "fontSize": 32, - "fontWeight": "700" - } - ] - }, - { - "type": "frame", - "id": "ZIv4a", - "name": "balanceBottom", - "width": "fill_container", - "gap": 8, - "alignItems": "center", - "children": [ - { - "type": "ellipse", - "id": "gSAEu", - "name": "balanceCircle", - "fill": "#0D6E6E", - "width": 8, - "height": 8 - }, - { - "type": "text", - "id": "U9nHM", - "name": "balanceDesc", - "fill": "#666666", - "content": "收入大于支出", - "fontFamily": "Newsreader", - "fontSize": 13, - "fontWeight": "normal", - "fontStyle": "italic" - } - ] - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "6u89w", - "name": "categorySection", - "width": "fill_container", - "layout": "vertical", - "gap": 16, - "children": [ - { - "type": "frame", - "id": "CFPdk", - "name": "categoryHeader", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "9xSWi", - "name": "categoryLabel", - "fill": "#888888", - "content": "分类支出", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600", - "letterSpacing": 2 - }, - { - "type": "frame", - "id": "qiiAk", - "name": "categoryLink", - "gap": 4, - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "wbNMw", - "name": "linkText", - "fill": "#0D6E6E", - "content": "查看全部", - "fontFamily": "DM Sans", - "fontSize": 13, - "fontWeight": "500" - }, - { - "type": "icon_font", - "id": "Sp6J9", - "name": "linkIcon", - "width": 16, - "height": 16, - "iconFontName": "arrow-right", - "iconFontFamily": "lucide", - "fill": "#0D6E6E" - } - ] - } - ] - }, - { - "type": "frame", - "id": "MWFx7", - "name": "categoryCard", - "width": "fill_container", - "fill": "#FFFFFF", - "cornerRadius": 12, - "stroke": { - "thickness": 1, - "fill": "#E5E5E5" - }, - "layout": "vertical", - "gap": 16, - "padding": 24, - "children": [ - { - "type": "frame", - "id": "M1LpC", - "name": "catRow1", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "dQLhW", - "name": "cat1Left", - "gap": 12, - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "2W5IT", - "name": "cat1Icon", - "width": 40, - "height": 40, - "fill": "#0D6E6E15", - "cornerRadius": 10, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "2PlOJ", - "name": "cat1IconSym", - "width": 20, - "height": 20, - "iconFontName": "utensils", - "iconFontFamily": "lucide", - "fill": "#0D6E6E" - } - ] - }, - { - "type": "frame", - "id": "ICEQX", - "name": "cat1Info", - "layout": "vertical", - "gap": 2, - "children": [ - { - "type": "text", - "id": "rYGlx", - "name": "cat1Name", - "fill": "#1A1A1A", - "content": "餐饮美食", - "fontFamily": "Newsreader", - "fontSize": 16, - "fontWeight": "500" - }, - { - "type": "text", - "id": "wi8W4", - "name": "cat1Count", - "fill": "#888888", - "content": "32笔交易", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "text", - "id": "pEJ93", - "name": "cat1Amount", - "fill": "#1A1A1A", - "content": "¥486.50", - "fontFamily": "JetBrains Mono", - "fontSize": 16, - "fontWeight": "600" - } - ] - }, - { - "type": "rectangle", - "id": "xFr2V", - "name": "divider1", - "fill": "#F0F0F0", - "width": "fill_container", - "height": 1 - }, - { - "type": "frame", - "id": "ejkcy", - "name": "catRow2", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "CBW2D", - "name": "cat2Left", - "gap": 12, - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "a97fQ", - "name": "cat2Icon", - "width": 40, - "height": 40, - "fill": "#E07B5415", - "cornerRadius": 10, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "jsVbp", - "name": "cat2IconSym", - "width": 20, - "height": 20, - "iconFontName": "shopping-cart", - "iconFontFamily": "lucide", - "fill": "#E07B54" - } - ] - }, - { - "type": "frame", - "id": "N9z8c", - "name": "cat2Info", - "layout": "vertical", - "gap": 2, - "children": [ - { - "type": "text", - "id": "wnAL4", - "name": "cat2Name", - "fill": "#1A1A1A", - "content": "购物消费", - "fontFamily": "Newsreader", - "fontSize": 16, - "fontWeight": "500" - }, - { - "type": "text", - "id": "avPO2", - "name": "cat2Count", - "fill": "#888888", - "content": "18笔交易", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "text", - "id": "aazVN", - "name": "cat2Amount", - "fill": "#1A1A1A", - "content": "¥324.80", - "fontFamily": "JetBrains Mono", - "fontSize": 16, - "fontWeight": "600" - } - ] - }, - { - "type": "rectangle", - "id": "bnSr4", - "name": "divider2", - "fill": "#F0F0F0", - "width": "fill_container", - "height": 1 - }, - { - "type": "frame", - "id": "mmlYG", - "name": "catRow3", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "vrfgt", - "name": "cat3Left", - "gap": 12, - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "rZ4xo", - "name": "cat3Icon", - "width": 40, - "height": 40, - "fill": "#88888815", - "cornerRadius": 10, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "szqRZ", - "name": "cat3IconSym", - "width": 20, - "height": 20, - "iconFontName": "car", - "iconFontFamily": "lucide", - "fill": "#888888" - } - ] - }, - { - "type": "frame", - "id": "2KvA5", - "name": "cat3Info", - "layout": "vertical", - "gap": 2, - "children": [ - { - "type": "text", - "id": "NI2Nw", - "name": "cat3Name", - "fill": "#1A1A1A", - "content": "交通出行", - "fontFamily": "Newsreader", - "fontSize": 16, - "fontWeight": "500" - }, - { - "type": "text", - "id": "PdHJV", - "name": "cat3Count", - "fill": "#888888", - "content": "24笔交易", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "text", - "id": "YPa77", - "name": "cat3Amount", - "fill": "#1A1A1A", - "content": "¥187.20", - "fontFamily": "JetBrains Mono", - "fontSize": 16, - "fontWeight": "600" - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "5Cssz", - "name": "trendSection", - "width": "fill_container", - "layout": "vertical", - "gap": 16, - "children": [ - { - "type": "frame", - "id": "UtABZ", - "name": "trendHeader", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "Cokqp", - "name": "trendLabel", - "fill": "#888888", - "content": "支出趋势", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600", - "letterSpacing": 2 - }, - { - "type": "frame", - "id": "JjJFZ", - "name": "trendPercent", - "gap": 4, - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "wrTCS", - "name": "percentValue", - "fill": "#1A1A1A", - "content": "86", - "fontFamily": "JetBrains Mono", - "fontSize": 28, - "fontWeight": "700" - }, - { - "type": "text", - "id": "nI76B", - "name": "percentSign", - "fill": "#888888", - "content": "%", - "fontFamily": "JetBrains Mono", - "fontSize": 14, - "fontWeight": "500" - } - ] - } - ] - }, - { - "type": "rectangle", - "id": "d1Wpj", - "name": "hrLine", - "fill": "#E5E5E5", - "width": "fill_container", - "height": 1 - }, - { - "type": "frame", - "id": "ZAt9z", - "name": "trendCard", - "width": "fill_container", - "fill": "#FFFFFF", - "cornerRadius": 12, - "stroke": { - "thickness": 1, - "fill": "#E5E5E5" - }, - "layout": "vertical", - "gap": 16, - "padding": 24, - "children": [ - { - "type": "frame", - "id": "oQN8p", - "name": "weekChart", - "width": "fill_container", - "height": 80, - "justifyContent": "space_between", - "alignItems": "end", - "children": [ - { - "type": "frame", - "id": "rGmYG", - "name": "day1Col", - "layout": "vertical", - "gap": 8, - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "VBLqg", - "name": "day1Bar", - "width": 32, - "height": 60, - "fill": "#F0F0F0", - "cornerRadius": 4, - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "rectangle", - "cornerRadius": 4, - "id": "giaMe", - "name": "day1Fill", - "fill": "#0D6E6E", - "width": "fill_container", - "height": 42 - } - ] - }, - { - "type": "text", - "id": "8V2aH", - "name": "day1Label", - "fill": "#888888", - "content": "一", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "2SPdd", - "name": "day2Col", - "layout": "vertical", - "gap": 8, - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "o698c", - "name": "day2Bar", - "width": 32, - "height": 60, - "fill": "#F0F0F0", - "cornerRadius": 4, - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "rectangle", - "cornerRadius": 4, - "id": "OvCvr", - "name": "day2Fill", - "fill": "#0D6E6E", - "width": "fill_container", - "height": 48 - } - ] - }, - { - "type": "text", - "id": "AC1au", - "name": "day2Label", - "fill": "#888888", - "content": "二", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "IxwaU", - "name": "day3Col", - "layout": "vertical", - "gap": 8, - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "Oo15B", - "name": "day3Bar", - "width": 32, - "height": 60, - "fill": "#F0F0F0", - "cornerRadius": 4, - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "rectangle", - "cornerRadius": 4, - "id": "G7nXy", - "name": "day3Fill", - "fill": "#0D6E6E", - "width": "fill_container", - "height": 36 - } - ] - }, - { - "type": "text", - "id": "frOgm", - "name": "day3Label", - "fill": "#888888", - "content": "三", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "RyQhQ", - "name": "day4Col", - "layout": "vertical", - "gap": 8, - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "KFgWz", - "name": "day4Bar", - "width": 32, - "height": 60, - "fill": "#F0F0F0", - "cornerRadius": 4, - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "rectangle", - "cornerRadius": 4, - "id": "caHh7", - "name": "day4Fill", - "fill": "#0D6E6E", - "width": "fill_container", - "height": 52 - } - ] - }, - { - "type": "text", - "id": "UIVDa", - "name": "day4Label", - "fill": "#888888", - "content": "四", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "AgoKW", - "name": "day5Col", - "layout": "vertical", - "gap": 8, - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "3n3r3", - "name": "day5Bar", - "width": 32, - "height": 60, - "fill": "#F0F0F0", - "cornerRadius": 4, - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "rectangle", - "cornerRadius": 4, - "id": "9JowQ", - "name": "day5Fill", - "fill": "#0D6E6E", - "width": "fill_container", - "height": 44 - } - ] - }, - { - "type": "text", - "id": "x8QUC", - "name": "day5Label", - "fill": "#888888", - "content": "五", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "uur3l", - "name": "day6Col", - "layout": "vertical", - "gap": 8, - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "0GTEq", - "name": "day6Bar", - "width": 32, - "height": 60, - "fill": "#F0F0F0", - "cornerRadius": 4, - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "rectangle", - "cornerRadius": 4, - "id": "VPwIR", - "name": "day6Fill", - "fill": "#E07B54", - "width": "fill_container", - "height": 56 - } - ] - }, - { - "type": "text", - "id": "D9aGt", - "name": "day6Label", - "fill": "#E07B54", - "content": "六", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "700" - } - ] - }, - { - "type": "frame", - "id": "maBOK", - "name": "day7Col", - "layout": "vertical", - "gap": 8, - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "xEqwT", - "name": "day7Bar", - "width": 32, - "height": 60, - "fill": "#F0F0F0", - "cornerRadius": 4, - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "rectangle", - "cornerRadius": 4, - "id": "rXtYK", - "name": "day7Fill", - "fill": "#CCCCCC", - "width": "fill_container", - "height": 0 - } - ] - }, - { - "type": "text", - "id": "zEcGr", - "name": "day7Label", - "fill": "#CCCCCC", - "content": "日", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - } - ] - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "1aLmf", - "name": "budgetSection", - "width": "fill_container", - "layout": "vertical", - "gap": 16, - "children": [ - { - "type": "frame", - "id": "oXx0E", - "name": "budgetHeader", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "iQUv1", - "name": "budgetLabel", - "fill": "#888888", - "content": "预算使用", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600", - "letterSpacing": 2 - }, - { - "type": "frame", - "id": "BNyDN", - "name": "budgetLink", - "gap": 4, - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "4nB71", - "name": "budgetLinkText", - "fill": "#0D6E6E", - "content": "管理预算", - "fontFamily": "DM Sans", - "fontSize": 13, - "fontWeight": "500" - }, - { - "type": "icon_font", - "id": "TP5CO", - "name": "budgetLinkIcon", - "width": 16, - "height": 16, - "iconFontName": "arrow-right", - "iconFontFamily": "lucide", - "fill": "#0D6E6E" - } - ] - } - ] - }, - { - "type": "frame", - "id": "dcxOW", - "name": "budgetCard", - "width": "fill_container", - "fill": "#FFFFFF", - "cornerRadius": 12, - "stroke": { - "thickness": 1, - "fill": "#E5E5E5" - }, - "layout": "vertical", - "gap": 16, - "padding": 24, - "children": [ - { - "type": "frame", - "id": "9vWpI", - "name": "budgetRow1", - "width": "fill_container", - "layout": "vertical", - "gap": 8, - "children": [ - { - "type": "frame", - "id": "h2xbA", - "name": "budget1Header", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "a8xDa", - "name": "budget1Name", - "fill": "#1A1A1A", - "content": "餐饮预算", - "fontFamily": "Newsreader", - "fontSize": 16, - "fontWeight": "500" - }, - { - "type": "frame", - "id": "wOn5D", - "name": "budget1Stats", - "gap": 8, - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "9OAb6", - "name": "budget1Current", - "fill": "#1A1A1A", - "content": "¥486.50", - "fontFamily": "JetBrains Mono", - "fontSize": 14, - "fontWeight": "600" - }, - { - "type": "text", - "id": "wyfo4", - "name": "budget1Separator", - "fill": "#CCCCCC", - "content": "/", - "fontFamily": "JetBrains Mono", - "fontSize": 14, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "9LJg4", - "name": "budget1Limit", - "fill": "#888888", - "content": "¥800", - "fontFamily": "JetBrains Mono", - "fontSize": 14, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "Qpq8z", - "name": "budget1Progress", - "width": "fill_container", - "height": 8, - "fill": "#F0F0F0", - "cornerRadius": 4, - "children": [ - { - "type": "rectangle", - "cornerRadius": 4, - "id": "FevR2", - "name": "budget1Fill", - "fill": "#0D6E6E", - "width": "fit_content(0)", - "height": "fill_container" - } - ] - } - ] - }, - { - "type": "rectangle", - "id": "2Mhkm", - "name": "dividerBudget1", - "fill": "#F0F0F0", - "width": "fill_container", - "height": 1 - }, - { - "type": "frame", - "id": "Zmsql", - "name": "budgetRow2", - "width": "fill_container", - "layout": "vertical", - "gap": 8, - "children": [ - { - "type": "frame", - "id": "wMpH4", - "name": "budget2Header", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "c3G6O", - "name": "budget2Name", - "fill": "#1A1A1A", - "content": "购物预算", - "fontFamily": "Newsreader", - "fontSize": 16, - "fontWeight": "500" - }, - { - "type": "frame", - "id": "zvFPU", - "name": "budget2Stats", - "gap": 8, - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "bIdRZ", - "name": "budget2Current", - "fill": "#1A1A1A", - "content": "¥324.80", - "fontFamily": "JetBrains Mono", - "fontSize": 14, - "fontWeight": "600" - }, - { - "type": "text", - "id": "4UWiB", - "name": "budget2Separator", - "fill": "#CCCCCC", - "content": "/", - "fontFamily": "JetBrains Mono", - "fontSize": 14, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "mI9U4", - "name": "budget2Limit", - "fill": "#888888", - "content": "¥500", - "fontFamily": "JetBrains Mono", - "fontSize": 14, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "brX2g", - "name": "budget2Progress", - "width": "fill_container", - "height": 8, - "fill": "#F0F0F0", - "cornerRadius": 4, - "children": [ - { - "type": "rectangle", - "cornerRadius": 4, - "id": "GroRL", - "name": "budget2Fill", - "fill": "#0D6E6E", - "width": "fit_content(0)", - "height": "fill_container" - } - ] - } - ] - }, - { - "type": "rectangle", - "id": "3XhJP", - "name": "dividerBudget2", - "fill": "#F0F0F0", - "width": "fill_container", - "height": 1 - }, - { - "type": "frame", - "id": "3xCe8", - "name": "budgetRow3", - "width": "fill_container", - "layout": "vertical", - "gap": 8, - "children": [ - { - "type": "frame", - "id": "heXyN", - "name": "budget3Header", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "AyvRg", - "name": "budget3Name", - "fill": "#1A1A1A", - "content": "交通预算", - "fontFamily": "Newsreader", - "fontSize": 16, - "fontWeight": "500" - }, - { - "type": "frame", - "id": "tiM8M", - "name": "budget3Stats", - "gap": 8, - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "kfSvd", - "name": "budget3Current", - "fill": "#1A1A1A", - "content": "¥187.20", - "fontFamily": "JetBrains Mono", - "fontSize": 14, - "fontWeight": "600" - }, - { - "type": "text", - "id": "ErldM", - "name": "budget3Separator", - "fill": "#CCCCCC", - "content": "/", - "fontFamily": "JetBrains Mono", - "fontSize": 14, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "RedAa", - "name": "budget3Limit", - "fill": "#888888", - "content": "¥300", - "fontFamily": "JetBrains Mono", - "fontSize": 14, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "5V1SC", - "name": "budget3Progress", - "width": "fill_container", - "height": 8, - "fill": "#F0F0F0", - "cornerRadius": 4, - "children": [ - { - "type": "rectangle", - "cornerRadius": 4, - "id": "UwJJ5", - "name": "budget3Fill", - "fill": "#0D6E6E", - "width": "fit_content(0)", - "height": "fill_container" - } - ] - } - ] - }, - { - "type": "rectangle", - "id": "9BN3m", - "name": "dividerBudget3", - "fill": "#F0F0F0", - "width": "fill_container", - "height": 1 - }, - { - "type": "frame", - "id": "bSH2j", - "name": "budgetRow4", - "width": "fill_container", - "layout": "vertical", - "gap": 8, - "children": [ - { - "type": "frame", - "id": "9wyNg", - "name": "budget4Header", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "zm8sI", - "name": "budget4Name", - "fill": "#1A1A1A", - "content": "月度总预算", - "fontFamily": "Newsreader", - "fontSize": 16, - "fontWeight": "500" - }, - { - "type": "frame", - "id": "SkudG", - "name": "budget4Stats", - "gap": 8, - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "TFK8I", - "name": "budget4Current", - "fill": "#E07B54", - "content": "¥1,248.50", - "fontFamily": "JetBrains Mono", - "fontSize": 14, - "fontWeight": "600" - }, - { - "type": "text", - "id": "uhqb0", - "name": "budget4Separator", - "fill": "#CCCCCC", - "content": "/", - "fontFamily": "JetBrains Mono", - "fontSize": 14, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "ahL7W", - "name": "budget4Limit", - "fill": "#888888", - "content": "¥2,500", - "fontFamily": "JetBrains Mono", - "fontSize": 14, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "xDskg", - "name": "budget4Progress", - "width": "fill_container", - "height": 8, - "fill": "#F0F0F0", - "cornerRadius": 4, - "children": [ - { - "type": "rectangle", - "cornerRadius": 4, - "id": "W56Qb", - "name": "budget4Fill", - "fill": "#0D6E6E", - "width": "fit_content(0)", - "height": "fill_container" - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - }, { "type": "frame", "id": "PlVHb", @@ -3262,20 +1464,10 @@ "id": "KQpEH", "name": "statsTitle", "fill": "#f4f4f5", - "content": "每日统计", + "content": "2026年1月12日", "fontFamily": "Bricolage Grotesque", "fontSize": 18, "fontWeight": "700" - }, - { - "type": "text", - "id": "pCjJG", - "name": "statsDate", - "fill": "#a1a1aa", - "content": "2026年1月12日", - "fontFamily": "DM Sans", - "fontSize": 13, - "fontWeight": "500" } ] }, @@ -5368,3232 +3560,6 @@ } ] }, - { - "type": "frame", - "id": "SNGbj", - "x": -538, - "y": 369, - "name": "Statistics - Overview - Dark", - "clip": true, - "width": 375, - "fill": "#09090B", - "layout": "vertical", - "children": [ - { - "type": "frame", - "id": "HdrD1", - "name": "header", - "width": "fill_container", - "gap": 4, - "padding": [ - 8, - 24 - ], - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "HdrCD1", - "name": "headerContent", - "width": 142, - "height": 39, - "layout": "vertical", - "gap": 4, - "children": [ - { - "type": "text", - "id": "TxtD1", - "name": "subtitle", - "fill": "#a1a1aa", - "content": "2026年", - "fontFamily": "DM Sans", - "fontSize": 24, - "fontWeight": "500" - } - ] - }, - { - "type": "frame", - "id": "BtnD1", - "name": "notifBtn", - "width": 44, - "height": 44, - "fill": "#27272a", - "cornerRadius": 22, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "IcnD1", - "name": "icon", - "width": 20, - "height": 20, - "iconFontName": "bell", - "iconFontFamily": "lucide", - "fill": "#f4f4f5" - } - ] - } - ] - }, - { - "type": "frame", - "id": "Ne4V3", - "name": "contentWrapper", - "width": "fill_container", - "layout": "vertical", - "gap": 24, - "padding": 24, - "children": [ - { - "type": "frame", - "id": "S2B4K", - "name": "periodSection", - "width": "fill_container", - "layout": "vertical", - "gap": 16, - "children": [ - { - "type": "frame", - "id": "aMTNG", - "name": "segmentControl", - "width": "fill_container", - "height": 44, - "fill": "#1A1A1A", - "cornerRadius": 8, - "gap": 4, - "padding": 4, - "children": [ - { - "type": "frame", - "id": "GcWPV", - "name": "daySegment", - "width": "fill_container", - "height": "fill_container", - "fill": "#2A2A2A", - "cornerRadius": 6, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "yjM7I", - "name": "dayLabel", - "fill": "#1A1A1A", - "content": "日", - "fontFamily": "DM Sans", - "fontSize": 13, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "iXgdY", - "name": "weekSegment", - "width": "fill_container", - "height": "fill_container", - "fill": "#1A1A1A", - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "KSuk0", - "name": "weekLabel", - "fill": "#888888", - "content": "周", - "fontFamily": "DM Sans", - "fontSize": 13, - "fontWeight": "500" - } - ] - }, - { - "type": "frame", - "id": "sVB0J", - "name": "monthSegment", - "width": "fill_container", - "height": "fill_container", - "fill": "#1A1A1A", - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "2PpIp", - "name": "monthLabel", - "fill": "#888888", - "content": "月", - "fontFamily": "DM Sans", - "fontSize": 13, - "fontWeight": "500" - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "eRNCW", - "name": "metricsSection", - "width": "fill_container", - "layout": "vertical", - "gap": 16, - "children": [ - { - "type": "text", - "id": "REhdK", - "name": "metricsHeader", - "fill": "#888888", - "content": "核心指标", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600", - "letterSpacing": 2 - }, - { - "type": "frame", - "id": "rRNpr", - "name": "metricsRow", - "width": "fill_container", - "gap": 16, - "children": [ - { - "type": "frame", - "id": "gzLwV", - "name": "card1", - "width": "fill_container", - "height": 146, - "fill": "#1A1A1A", - "cornerRadius": 12, - "stroke": { - "thickness": 1, - "fill": "#2A2A2A" - }, - "layout": "vertical", - "gap": 12, - "padding": 24, - "justifyContent": "space_between", - "children": [ - { - "type": "frame", - "id": "blVoz", - "name": "card1Top", - "width": "fill_container", - "layout": "vertical", - "gap": 12, - "children": [ - { - "type": "frame", - "id": "9MqCU", - "name": "card1Header", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "MbMbz", - "name": "card1Label", - "fill": "#888888", - "content": "总支出", - "fontFamily": "DM Sans", - "fontSize": 12, - "fontWeight": "500" - }, - { - "type": "text", - "id": "8ceLw", - "name": "card1Badge", - "fill": "#E07B54", - "content": "-15%", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "600" - } - ] - }, - { - "type": "text", - "id": "yAPmi", - "name": "card1Value", - "fill": "#1A1A1A", - "content": "¥1,248.50", - "lineHeight": 0.85, - "fontFamily": "JetBrains Mono", - "fontSize": 32, - "fontWeight": "700" - } - ] - }, - { - "type": "text", - "id": "N1Qt4", - "name": "card1Bottom", - "fill": "#666666", - "content": "较上期减少", - "fontFamily": "Newsreader", - "fontSize": 13, - "fontWeight": "normal", - "fontStyle": "italic" - } - ] - }, - { - "type": "frame", - "id": "eiGbX", - "name": "card2", - "width": "fill_container", - "height": 146, - "fill": "#1A1A1A", - "cornerRadius": 12, - "stroke": { - "thickness": 1, - "fill": "#2A2A2A" - }, - "layout": "vertical", - "gap": 12, - "padding": 24, - "justifyContent": "space_between", - "children": [ - { - "type": "frame", - "id": "2LWDK", - "name": "card2Top", - "width": "fill_container", - "layout": "vertical", - "gap": 12, - "children": [ - { - "type": "frame", - "id": "LEFHn", - "name": "card2Header", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "cpuUR", - "name": "card2Label", - "fill": "#888888", - "content": "交易笔数", - "fontFamily": "DM Sans", - "fontSize": 12, - "fontWeight": "500" - }, - { - "type": "text", - "id": "Kaya5", - "name": "card2Badge", - "fill": "#0D6E6E", - "content": "+8", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "600" - } - ] - }, - { - "type": "text", - "id": "cwcBx", - "name": "card2Value", - "fill": "#1A1A1A", - "content": "127", - "lineHeight": 0.85, - "fontFamily": "JetBrains Mono", - "fontSize": 32, - "fontWeight": "700" - } - ] - }, - { - "type": "frame", - "id": "Ps49o", - "name": "card2Bottom", - "width": "fill_container", - "height": 24, - "gap": 4, - "alignItems": "end", - "children": [ - { - "type": "rectangle", - "cornerRadius": 2, - "id": "BJ6jY", - "name": "bar1", - "fill": "#E5E5E5", - "width": "fill_container", - "height": 8 - }, - { - "type": "rectangle", - "cornerRadius": 2, - "id": "nRTiE", - "name": "bar2", - "fill": "#E5E5E5", - "width": "fill_container", - "height": 12 - }, - { - "type": "rectangle", - "cornerRadius": 2, - "id": "xGdPL", - "name": "bar3", - "fill": "#E5E5E5", - "width": "fill_container", - "height": 16 - }, - { - "type": "rectangle", - "cornerRadius": 2, - "id": "Ui6Yh", - "name": "bar4", - "fill": "#E5E5E5", - "width": "fill_container", - "height": 14 - }, - { - "type": "rectangle", - "cornerRadius": 2, - "id": "W6JsE", - "name": "bar5", - "fill": "#E5E5E5", - "width": "fill_container", - "height": 20 - }, - { - "type": "rectangle", - "cornerRadius": 2, - "id": "jey1R", - "name": "bar6", - "fill": "#E5E5E5", - "width": "fill_container", - "height": 18 - }, - { - "type": "rectangle", - "cornerRadius": 2, - "id": "9qTWP", - "name": "bar7", - "fill": "#0D6E6E", - "width": "fill_container", - "height": 24 - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "kuG9h", - "name": "incomeRow", - "width": "fill_container", - "gap": 16, - "children": [ - { - "type": "frame", - "id": "0JHPv", - "name": "incomeCard", - "width": "fill_container", - "height": 146, - "fill": "#1A1A1A", - "cornerRadius": 12, - "stroke": { - "thickness": 1, - "fill": "#2A2A2A" - }, - "layout": "vertical", - "gap": 12, - "padding": 24, - "justifyContent": "space_between", - "children": [ - { - "type": "frame", - "id": "d6TLE", - "name": "incomeTop", - "width": "fill_container", - "layout": "vertical", - "gap": 12, - "children": [ - { - "type": "frame", - "id": "N1n4g", - "name": "incomeHeader", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "CuedQ", - "name": "incomeLabel", - "fill": "#888888", - "content": "总收入", - "fontFamily": "DM Sans", - "fontSize": 12, - "fontWeight": "500" - }, - { - "type": "text", - "id": "i3Mpg", - "name": "incomeBadge", - "fill": "#0D6E6E", - "content": "+2", - "fontFamily": "JetBrains Mono", - "fontSize": 10, - "fontWeight": "600" - } - ] - }, - { - "type": "text", - "id": "Vk4jR", - "name": "incomeValue", - "fill": "#0D6E6E", - "content": "¥3,200", - "lineHeight": 0.85, - "fontFamily": "JetBrains Mono", - "fontSize": 32, - "fontWeight": "700" - } - ] - }, - { - "type": "text", - "id": "hKOg2", - "name": "incomeBottom", - "fill": "#666666", - "content": "工资、红包等", - "fontFamily": "Newsreader", - "fontSize": 13, - "fontWeight": "normal", - "fontStyle": "italic" - } - ] - }, - { - "type": "frame", - "id": "DwFMn", - "name": "balanceCard", - "width": "fill_container", - "height": 146, - "fill": "#1A1A1A", - "cornerRadius": 12, - "stroke": { - "thickness": 1, - "fill": "#2A2A2A" - }, - "layout": "vertical", - "gap": 12, - "padding": 24, - "justifyContent": "space_between", - "children": [ - { - "type": "frame", - "id": "hZw8Y", - "name": "balanceTop", - "width": "fill_container", - "layout": "vertical", - "gap": 12, - "children": [ - { - "type": "frame", - "id": "If37j", - "name": "balanceHeader", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "MbbIn", - "name": "balanceLabel", - "fill": "#888888", - "content": "净收支", - "fontFamily": "DM Sans", - "fontSize": 12, - "fontWeight": "500" - }, - { - "type": "icon_font", - "id": "Up2rP", - "name": "balanceIcon", - "width": 16, - "height": 16, - "iconFontName": "trending-up", - "iconFontFamily": "lucide", - "fill": "#0D6E6E" - } - ] - }, - { - "type": "text", - "id": "pV54w", - "name": "balanceValue", - "fill": "#0D6E6E", - "content": "+¥1,951.50", - "lineHeight": 0.85, - "fontFamily": "JetBrains Mono", - "fontSize": 32, - "fontWeight": "700" - } - ] - }, - { - "type": "frame", - "id": "tDVfb", - "name": "balanceBottom", - "width": "fill_container", - "gap": 8, - "alignItems": "center", - "children": [ - { - "type": "ellipse", - "id": "Cog7D", - "name": "balanceCircle", - "fill": "#0D6E6E", - "width": 8, - "height": 8 - }, - { - "type": "text", - "id": "4FyE8", - "name": "balanceDesc", - "fill": "#666666", - "content": "收入大于支出", - "fontFamily": "Newsreader", - "fontSize": 13, - "fontWeight": "normal", - "fontStyle": "italic" - } - ] - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "WlDc7", - "name": "categorySection", - "width": "fill_container", - "layout": "vertical", - "gap": 16, - "children": [ - { - "type": "frame", - "id": "lB56E", - "name": "categoryHeader", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "PGCma", - "name": "categoryLabel", - "fill": "#888888", - "content": "分类支出", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600", - "letterSpacing": 2 - }, - { - "type": "frame", - "id": "Buslb", - "name": "categoryLink", - "gap": 4, - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "DSq5h", - "name": "linkText", - "fill": "#0D6E6E", - "content": "查看全部", - "fontFamily": "DM Sans", - "fontSize": 13, - "fontWeight": "500" - }, - { - "type": "icon_font", - "id": "LCRZw", - "name": "linkIcon", - "width": 16, - "height": 16, - "iconFontName": "arrow-right", - "iconFontFamily": "lucide", - "fill": "#0D6E6E" - } - ] - } - ] - }, - { - "type": "frame", - "id": "YCfml", - "name": "categoryCard", - "width": "fill_container", - "fill": "#1A1A1A", - "cornerRadius": 12, - "stroke": { - "thickness": 1, - "fill": "#2A2A2A" - }, - "layout": "vertical", - "gap": 16, - "padding": 24, - "children": [ - { - "type": "frame", - "id": "smukQ", - "name": "catRow1", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "BOwbE", - "name": "cat1Left", - "gap": 12, - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "xzE05", - "name": "cat1Icon", - "width": 40, - "height": 40, - "fill": "#0D6E6E15", - "cornerRadius": 10, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "GN2eX", - "name": "cat1IconSym", - "width": 20, - "height": 20, - "iconFontName": "utensils", - "iconFontFamily": "lucide", - "fill": "#0D6E6E" - } - ] - }, - { - "type": "frame", - "id": "sood7", - "name": "cat1Info", - "layout": "vertical", - "gap": 2, - "children": [ - { - "type": "text", - "id": "PwM2t", - "name": "cat1Name", - "fill": "#1A1A1A", - "content": "餐饮美食", - "fontFamily": "Newsreader", - "fontSize": 16, - "fontWeight": "500" - }, - { - "type": "text", - "id": "FYYrX", - "name": "cat1Count", - "fill": "#888888", - "content": "32笔交易", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "text", - "id": "cHFM8", - "name": "cat1Amount", - "fill": "#1A1A1A", - "content": "¥486.50", - "fontFamily": "JetBrains Mono", - "fontSize": 16, - "fontWeight": "600" - } - ] - }, - { - "type": "rectangle", - "id": "03fSF", - "name": "divider1", - "fill": "#2A2A2A", - "width": "fill_container", - "height": 1 - }, - { - "type": "frame", - "id": "F7dYQ", - "name": "catRow2", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "c7YYD", - "name": "cat2Left", - "gap": 12, - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "iD8Sn", - "name": "cat2Icon", - "width": 40, - "height": 40, - "fill": "#E07B5415", - "cornerRadius": 10, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "y30Px", - "name": "cat2IconSym", - "width": 20, - "height": 20, - "iconFontName": "shopping-cart", - "iconFontFamily": "lucide", - "fill": "#E07B54" - } - ] - }, - { - "type": "frame", - "id": "9D72D", - "name": "cat2Info", - "layout": "vertical", - "gap": 2, - "children": [ - { - "type": "text", - "id": "eYYED", - "name": "cat2Name", - "fill": "#1A1A1A", - "content": "购物消费", - "fontFamily": "Newsreader", - "fontSize": 16, - "fontWeight": "500" - }, - { - "type": "text", - "id": "diPzi", - "name": "cat2Count", - "fill": "#888888", - "content": "18笔交易", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "text", - "id": "Mv7iS", - "name": "cat2Amount", - "fill": "#1A1A1A", - "content": "¥324.80", - "fontFamily": "JetBrains Mono", - "fontSize": 16, - "fontWeight": "600" - } - ] - }, - { - "type": "rectangle", - "id": "GkSAw", - "name": "divider2", - "fill": "#2A2A2A", - "width": "fill_container", - "height": 1 - }, - { - "type": "frame", - "id": "AIgT8", - "name": "catRow3", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "9jWrK", - "name": "cat3Left", - "gap": 12, - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "wAJ8N", - "name": "cat3Icon", - "width": 40, - "height": 40, - "fill": "#88888815", - "cornerRadius": 10, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "Rw9Zw", - "name": "cat3IconSym", - "width": 20, - "height": 20, - "iconFontName": "car", - "iconFontFamily": "lucide", - "fill": "#888888" - } - ] - }, - { - "type": "frame", - "id": "pwPQl", - "name": "cat3Info", - "layout": "vertical", - "gap": 2, - "children": [ - { - "type": "text", - "id": "ImCqZ", - "name": "cat3Name", - "fill": "#1A1A1A", - "content": "交通出行", - "fontFamily": "Newsreader", - "fontSize": 16, - "fontWeight": "500" - }, - { - "type": "text", - "id": "D4LiL", - "name": "cat3Count", - "fill": "#888888", - "content": "24笔交易", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "text", - "id": "3wuUv", - "name": "cat3Amount", - "fill": "#1A1A1A", - "content": "¥187.20", - "fontFamily": "JetBrains Mono", - "fontSize": 16, - "fontWeight": "600" - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "5Y9IO", - "name": "trendSection", - "width": "fill_container", - "layout": "vertical", - "gap": 16, - "children": [ - { - "type": "frame", - "id": "RUR1j", - "name": "trendHeader", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "2rRGK", - "name": "trendLabel", - "fill": "#888888", - "content": "支出趋势", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600", - "letterSpacing": 2 - }, - { - "type": "frame", - "id": "DoySY", - "name": "trendPercent", - "gap": 4, - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "owHq2", - "name": "percentValue", - "fill": "#1A1A1A", - "content": "86", - "fontFamily": "JetBrains Mono", - "fontSize": 28, - "fontWeight": "700" - }, - { - "type": "text", - "id": "RHN2S", - "name": "percentSign", - "fill": "#888888", - "content": "%", - "fontFamily": "JetBrains Mono", - "fontSize": 14, - "fontWeight": "500" - } - ] - } - ] - }, - { - "type": "rectangle", - "id": "jseUG", - "name": "hrLine", - "fill": "#2A2A2A", - "width": "fill_container", - "height": 1 - }, - { - "type": "frame", - "id": "4xrJ0", - "name": "trendCard", - "width": "fill_container", - "fill": "#1A1A1A", - "cornerRadius": 12, - "stroke": { - "thickness": 1, - "fill": "#2A2A2A" - }, - "layout": "vertical", - "gap": 16, - "padding": 24, - "children": [ - { - "type": "frame", - "id": "pBKSz", - "name": "weekChart", - "width": "fill_container", - "height": 80, - "justifyContent": "space_between", - "alignItems": "end", - "children": [ - { - "type": "frame", - "id": "eX19l", - "name": "day1Col", - "layout": "vertical", - "gap": 8, - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "j1Gsc", - "name": "day1Bar", - "width": 32, - "height": 60, - "fill": "#F0F0F0", - "cornerRadius": 4, - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "rectangle", - "cornerRadius": 4, - "id": "icOhJ", - "name": "day1Fill", - "fill": "#0D6E6E", - "width": "fill_container", - "height": 42 - } - ] - }, - { - "type": "text", - "id": "3o3SE", - "name": "day1Label", - "fill": "#888888", - "content": "一", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "dSWac", - "name": "day2Col", - "layout": "vertical", - "gap": 8, - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "HfP3M", - "name": "day2Bar", - "width": 32, - "height": 60, - "fill": "#F0F0F0", - "cornerRadius": 4, - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "rectangle", - "cornerRadius": 4, - "id": "HOFPd", - "name": "day2Fill", - "fill": "#0D6E6E", - "width": "fill_container", - "height": 48 - } - ] - }, - { - "type": "text", - "id": "owYO0", - "name": "day2Label", - "fill": "#888888", - "content": "二", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "RiZ7L", - "name": "day3Col", - "layout": "vertical", - "gap": 8, - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "mFjvc", - "name": "day3Bar", - "width": 32, - "height": 60, - "fill": "#F0F0F0", - "cornerRadius": 4, - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "rectangle", - "cornerRadius": 4, - "id": "ZT5zP", - "name": "day3Fill", - "fill": "#0D6E6E", - "width": "fill_container", - "height": 36 - } - ] - }, - { - "type": "text", - "id": "gnymK", - "name": "day3Label", - "fill": "#888888", - "content": "三", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "kikrs", - "name": "day4Col", - "layout": "vertical", - "gap": 8, - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "o8Ops", - "name": "day4Bar", - "width": 32, - "height": 60, - "fill": "#F0F0F0", - "cornerRadius": 4, - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "rectangle", - "cornerRadius": 4, - "id": "an8NN", - "name": "day4Fill", - "fill": "#0D6E6E", - "width": "fill_container", - "height": 52 - } - ] - }, - { - "type": "text", - "id": "JUkjU", - "name": "day4Label", - "fill": "#888888", - "content": "四", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "VLzOR", - "name": "day5Col", - "layout": "vertical", - "gap": 8, - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "bQgJe", - "name": "day5Bar", - "width": 32, - "height": 60, - "fill": "#F0F0F0", - "cornerRadius": 4, - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "rectangle", - "cornerRadius": 4, - "id": "2AgUH", - "name": "day5Fill", - "fill": "#0D6E6E", - "width": "fill_container", - "height": 44 - } - ] - }, - { - "type": "text", - "id": "qOQ4p", - "name": "day5Label", - "fill": "#888888", - "content": "五", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "MPgAT", - "name": "day6Col", - "layout": "vertical", - "gap": 8, - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "7G3ar", - "name": "day6Bar", - "width": 32, - "height": 60, - "fill": "#F0F0F0", - "cornerRadius": 4, - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "rectangle", - "cornerRadius": 4, - "id": "fzBSL", - "name": "day6Fill", - "fill": "#E07B54", - "width": "fill_container", - "height": 56 - } - ] - }, - { - "type": "text", - "id": "gGSUR", - "name": "day6Label", - "fill": "#E07B54", - "content": "六", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "700" - } - ] - }, - { - "type": "frame", - "id": "TeAAb", - "name": "day7Col", - "layout": "vertical", - "gap": 8, - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "nczaG", - "name": "day7Bar", - "width": 32, - "height": 60, - "fill": "#F0F0F0", - "cornerRadius": 4, - "justifyContent": "end", - "alignItems": "center", - "children": [ - { - "type": "rectangle", - "cornerRadius": 4, - "id": "lQQkB", - "name": "day7Fill", - "fill": "#CCCCCC", - "width": "fill_container", - "height": 0 - } - ] - }, - { - "type": "text", - "id": "6A1gG", - "name": "day7Label", - "fill": "#CCCCCC", - "content": "日", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600" - } - ] - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "o7KQR", - "name": "budgetSection", - "width": "fill_container", - "layout": "vertical", - "gap": 16, - "children": [ - { - "type": "frame", - "id": "qyU0F", - "name": "budgetHeader", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "TNee1", - "name": "budgetLabel", - "fill": "#888888", - "content": "预算使用", - "fontFamily": "JetBrains Mono", - "fontSize": 11, - "fontWeight": "600", - "letterSpacing": 2 - }, - { - "type": "frame", - "id": "xDdF3", - "name": "budgetLink", - "gap": 4, - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "hsFsL", - "name": "budgetLinkText", - "fill": "#0D6E6E", - "content": "管理预算", - "fontFamily": "DM Sans", - "fontSize": 13, - "fontWeight": "500" - }, - { - "type": "icon_font", - "id": "X3FVP", - "name": "budgetLinkIcon", - "width": 16, - "height": 16, - "iconFontName": "arrow-right", - "iconFontFamily": "lucide", - "fill": "#0D6E6E" - } - ] - } - ] - }, - { - "type": "frame", - "id": "lTC30", - "name": "budgetCard", - "width": "fill_container", - "fill": "#1A1A1A", - "cornerRadius": 12, - "stroke": { - "thickness": 1, - "fill": "#2A2A2A" - }, - "layout": "vertical", - "gap": 16, - "padding": 24, - "children": [ - { - "type": "frame", - "id": "yGTsJ", - "name": "budgetRow1", - "width": "fill_container", - "layout": "vertical", - "gap": 8, - "children": [ - { - "type": "frame", - "id": "hGg0o", - "name": "budget1Header", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "lahdF", - "name": "budget1Name", - "fill": "#1A1A1A", - "content": "餐饮预算", - "fontFamily": "Newsreader", - "fontSize": 16, - "fontWeight": "500" - }, - { - "type": "frame", - "id": "sFvuo", - "name": "budget1Stats", - "gap": 8, - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "PlfTc", - "name": "budget1Current", - "fill": "#1A1A1A", - "content": "¥486.50", - "fontFamily": "JetBrains Mono", - "fontSize": 14, - "fontWeight": "600" - }, - { - "type": "text", - "id": "EEz17", - "name": "budget1Separator", - "fill": "#CCCCCC", - "content": "/", - "fontFamily": "JetBrains Mono", - "fontSize": 14, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "vjUSm", - "name": "budget1Limit", - "fill": "#888888", - "content": "¥800", - "fontFamily": "JetBrains Mono", - "fontSize": 14, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "9OO3J", - "name": "budget1Progress", - "width": "fill_container", - "height": 8, - "fill": "#F0F0F0", - "cornerRadius": 4, - "children": [ - { - "type": "rectangle", - "cornerRadius": 4, - "id": "cP0JF", - "name": "budget1Fill", - "fill": "#0D6E6E", - "width": "fit_content(0)", - "height": "fill_container" - } - ] - } - ] - }, - { - "type": "rectangle", - "id": "hosNk", - "name": "dividerBudget1", - "fill": "#2A2A2A", - "width": "fill_container", - "height": 1 - }, - { - "type": "frame", - "id": "SWb0B", - "name": "budgetRow2", - "width": "fill_container", - "layout": "vertical", - "gap": 8, - "children": [ - { - "type": "frame", - "id": "fUy3x", - "name": "budget2Header", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "9kPuT", - "name": "budget2Name", - "fill": "#1A1A1A", - "content": "购物预算", - "fontFamily": "Newsreader", - "fontSize": 16, - "fontWeight": "500" - }, - { - "type": "frame", - "id": "TA08z", - "name": "budget2Stats", - "gap": 8, - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "vcOPi", - "name": "budget2Current", - "fill": "#1A1A1A", - "content": "¥324.80", - "fontFamily": "JetBrains Mono", - "fontSize": 14, - "fontWeight": "600" - }, - { - "type": "text", - "id": "OtoDw", - "name": "budget2Separator", - "fill": "#CCCCCC", - "content": "/", - "fontFamily": "JetBrains Mono", - "fontSize": 14, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "pvuCY", - "name": "budget2Limit", - "fill": "#888888", - "content": "¥500", - "fontFamily": "JetBrains Mono", - "fontSize": 14, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "UHVdS", - "name": "budget2Progress", - "width": "fill_container", - "height": 8, - "fill": "#F0F0F0", - "cornerRadius": 4, - "children": [ - { - "type": "rectangle", - "cornerRadius": 4, - "id": "brzAn", - "name": "budget2Fill", - "fill": "#0D6E6E", - "width": "fit_content(0)", - "height": "fill_container" - } - ] - } - ] - }, - { - "type": "rectangle", - "id": "Smd3M", - "name": "dividerBudget2", - "fill": "#2A2A2A", - "width": "fill_container", - "height": 1 - }, - { - "type": "frame", - "id": "oesDd", - "name": "budgetRow3", - "width": "fill_container", - "layout": "vertical", - "gap": 8, - "children": [ - { - "type": "frame", - "id": "luQLm", - "name": "budget3Header", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "vLrts", - "name": "budget3Name", - "fill": "#1A1A1A", - "content": "交通预算", - "fontFamily": "Newsreader", - "fontSize": 16, - "fontWeight": "500" - }, - { - "type": "frame", - "id": "h6em3", - "name": "budget3Stats", - "gap": 8, - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "Rd3K0", - "name": "budget3Current", - "fill": "#1A1A1A", - "content": "¥187.20", - "fontFamily": "JetBrains Mono", - "fontSize": 14, - "fontWeight": "600" - }, - { - "type": "text", - "id": "w41uC", - "name": "budget3Separator", - "fill": "#CCCCCC", - "content": "/", - "fontFamily": "JetBrains Mono", - "fontSize": 14, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "FO1ni", - "name": "budget3Limit", - "fill": "#888888", - "content": "¥300", - "fontFamily": "JetBrains Mono", - "fontSize": 14, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "i69zI", - "name": "budget3Progress", - "width": "fill_container", - "height": 8, - "fill": "#F0F0F0", - "cornerRadius": 4, - "children": [ - { - "type": "rectangle", - "cornerRadius": 4, - "id": "7Wqfo", - "name": "budget3Fill", - "fill": "#0D6E6E", - "width": "fit_content(0)", - "height": "fill_container" - } - ] - } - ] - }, - { - "type": "rectangle", - "id": "QVVZp", - "name": "dividerBudget3", - "fill": "#2A2A2A", - "width": "fill_container", - "height": 1 - }, - { - "type": "frame", - "id": "2lMDf", - "name": "budgetRow4", - "width": "fill_container", - "layout": "vertical", - "gap": 8, - "children": [ - { - "type": "frame", - "id": "fLjAV", - "name": "budget4Header", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "aV4TW", - "name": "budget4Name", - "fill": "#1A1A1A", - "content": "月度总预算", - "fontFamily": "Newsreader", - "fontSize": 16, - "fontWeight": "500" - }, - { - "type": "frame", - "id": "HU972", - "name": "budget4Stats", - "gap": 8, - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "MVaQV", - "name": "budget4Current", - "fill": "#E07B54", - "content": "¥1,248.50", - "fontFamily": "JetBrains Mono", - "fontSize": 14, - "fontWeight": "600" - }, - { - "type": "text", - "id": "QBuB5", - "name": "budget4Separator", - "fill": "#CCCCCC", - "content": "/", - "fontFamily": "JetBrains Mono", - "fontSize": 14, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "KF5Xu", - "name": "budget4Limit", - "fill": "#888888", - "content": "¥2,500", - "fontFamily": "JetBrains Mono", - "fontSize": 14, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "ZCnLU", - "name": "budget4Progress", - "width": "fill_container", - "height": 8, - "fill": "#F0F0F0", - "cornerRadius": 4, - "children": [ - { - "type": "rectangle", - "cornerRadius": 4, - "id": "8bKDB", - "name": "budget4Fill", - "fill": "#0D6E6E", - "width": "fit_content(0)", - "height": "fill_container" - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "BCxxA", - "x": -100, - "y": 369, - "name": "Budget - Statistics - Light", - "width": 375, - "fill": "#FFFFFF", - "layout": "vertical", - "children": [ - { - "type": "frame", - "id": "HdrL2", - "name": "header", - "width": "fill_container", - "gap": 4, - "padding": [ - 8, - 24 - ], - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "HdrCL2", - "name": "headerContent", - "width": 142, - "height": 39, - "layout": "vertical", - "gap": 4, - "children": [ - { - "type": "text", - "id": "TxtL2", - "name": "subtitle", - "fill": "#1a1a1a", - "content": "2026年1月", - "fontFamily": "DM Sans", - "fontSize": 24, - "fontWeight": "500" - } - ] - }, - { - "type": "frame", - "id": "BtnL2", - "name": "notifBtn", - "width": 44, - "height": 44, - "fill": "#F5F5F5", - "cornerRadius": 22, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "IcnL2", - "name": "icon", - "width": 20, - "height": 20, - "iconFontName": "bell", - "iconFontFamily": "lucide", - "fill": "#1A1A1A" - } - ] - } - ] - }, - { - "type": "frame", - "id": "LXM6A", - "name": "navbar", - "width": "fill_container", - "layout": "vertical", - "children": [ - { - "type": "frame", - "id": "SRWHt", - "name": "tabs", - "width": "fill_container", - "fill": "#F0F0F0", - "cornerRadius": 8, - "gap": 4, - "padding": 4, - "children": [ - { - "type": "frame", - "id": "3NS3r", - "name": "tab1", - "width": "fill_container", - "fill": "#FFFFFF", - "cornerRadius": 6, - "padding": [ - 8, - 16 - ], - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "gTGQU", - "name": "tab1Text", - "fill": "#1A1A1A", - "content": "支出", - "fontFamily": "DM Sans", - "fontSize": 13, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "0rM11", - "name": "tab2", - "width": "fill_container", - "fill": "transparent", - "padding": [ - 8, - 16 - ], - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "WXb0h", - "name": "tab2Text", - "fill": "#888888", - "content": "收入", - "fontFamily": "DM Sans", - "fontSize": 13, - "fontWeight": "500" - } - ] - }, - { - "type": "frame", - "id": "xHs0t", - "name": "tab3", - "width": "fill_container", - "fill": "transparent", - "padding": [ - 8, - 16 - ], - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "Kjbjx", - "name": "tab3Text", - "fill": "#888888", - "content": "计划", - "fontFamily": "DM Sans", - "fontSize": 13, - "fontWeight": "500" - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "ijHRX", - "name": "content", - "width": "fill_container", - "layout": "vertical", - "gap": 16, - "padding": 16, - "children": [ - { - "type": "frame", - "id": "1KJTP", - "name": "overallCard", - "width": "fill_container", - "fill": "#F6F7F8", - "cornerRadius": 16, - "layout": "vertical", - "gap": 16, - "padding": 24, - "children": [ - { - "type": "text", - "id": "vjNOX", - "name": "overallTitle", - "fill": "#71717A", - "content": "本月预算", - "fontFamily": "DM Sans", - "fontSize": 14, - "fontWeight": "normal" - }, - { - "type": "frame", - "id": "qxXwx", - "name": "overallAmount", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "hIESL", - "name": "overallLeft", - "layout": "vertical", - "gap": 4, - "children": [ - { - "type": "text", - "id": "D5K0P", - "name": "overallCurrent", - "fill": "#18181B", - "content": "¥8,523", - "fontFamily": "Bricolage Grotesque", - "fontSize": 28, - "fontWeight": "700" - }, - { - "type": "text", - "id": "0qnF1", - "name": "overallLimit", - "fill": "#71717A", - "content": "/ ¥15,000", - "fontFamily": "DM Sans", - "fontSize": 16, - "fontWeight": "normal" - } - ] - }, - { - "type": "text", - "id": "tGKF4", - "name": "overallPercent", - "fill": "#18181B", - "content": "56.8%", - "fontFamily": "Bricolage Grotesque", - "fontSize": 24, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "EQZGM", - "name": "progressBar", - "width": "fill_container", - "height": 8, - "fill": "#E5E7EB", - "cornerRadius": 4, - "children": [ - { - "type": "rectangle", - "cornerRadius": 4, - "id": "7tGdo", - "name": "progressFill", - "fill": "#3B82F6", - "width": 213, - "height": 8 - } - ] - } - ] - }, - { - "type": "frame", - "id": "9jYaf", - "name": "budgetList", - "width": "fill_container", - "layout": "vertical", - "gap": 12, - "children": [ - { - "type": "frame", - "id": "Kxe0g", - "name": "card1", - "width": "fill_container", - "fill": "#F6F7F8", - "cornerRadius": 16, - "layout": "vertical", - "gap": 12, - "padding": 16, - "children": [ - { - "type": "frame", - "id": "7yVaP", - "name": "cardHeader1", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "FgKnu", - "name": "cardTitle1", - "fill": "#18181B", - "content": "餐饮美食", - "fontFamily": "DM Sans", - "fontSize": 16, - "fontWeight": "600" - }, - { - "type": "frame", - "id": "bGgcT", - "name": "cardBadge1", - "fill": "#DBEAFE", - "cornerRadius": 12, - "padding": [ - 4, - 12 - ], - "children": [ - { - "type": "text", - "id": "xnmMK", - "name": "cardBadgeText1", - "fill": "#3B82F6", - "content": "月度", - "fontFamily": "DM Sans", - "fontSize": 12, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "fDVpP", - "name": "cardProgress1", - "width": "fill_container", - "height": 6, - "fill": "#E5E7EB", - "cornerRadius": 3, - "children": [ - { - "type": "rectangle", - "cornerRadius": 3, - "id": "Vm6T4", - "name": "cardProgressFill1", - "fill": "#EF4444", - "width": 243, - "height": 6 - } - ] - }, - { - "type": "frame", - "id": "pGt5L", - "name": "cardInfo1", - "width": "fill_container", - "justifyContent": "space_between", - "children": [ - { - "type": "frame", - "id": "hQrSj", - "name": "cardLeft1", - "layout": "vertical", - "gap": 4, - "children": [ - { - "type": "text", - "id": "tOSb6", - "name": "cardLabel1", - "fill": "#71717A", - "content": "已支出", - "fontFamily": "DM Sans", - "fontSize": 12, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "IqTXx", - "name": "cardAmount1", - "fill": "#EF4444", - "content": "¥2,456", - "fontFamily": "DM Sans", - "fontSize": 18, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "vgDBH", - "name": "cardRight1", - "layout": "vertical", - "gap": 4, - "alignItems": "end", - "children": [ - { - "type": "text", - "id": "VDt6P", - "name": "cardLabel2", - "fill": "#71717A", - "content": "余额", - "fontFamily": "DM Sans", - "fontSize": 12, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "OkeZ1", - "name": "cardAmount2", - "fill": "#10B981", - "content": "¥544", - "fontFamily": "DM Sans", - "fontSize": 18, - "fontWeight": "600" - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "sMUQr", - "name": "card2", - "width": "fill_container", - "fill": "#F6F7F8", - "cornerRadius": 16, - "layout": "vertical", - "gap": 12, - "padding": 16, - "children": [ - { - "type": "frame", - "id": "wLy7P", - "name": "cardHeader2", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "vkYqi", - "name": "cardTitle2", - "fill": "#18181B", - "content": "交通出行", - "fontFamily": "DM Sans", - "fontSize": 16, - "fontWeight": "600" - }, - { - "type": "frame", - "id": "cPTG6", - "name": "cardBadge2", - "fill": "#FEF3C7", - "cornerRadius": 12, - "padding": [ - 4, - 12 - ], - "children": [ - { - "type": "text", - "id": "ZuZPD", - "name": "cardBadgeText2", - "fill": "#F59E0B", - "content": "年度", - "fontFamily": "DM Sans", - "fontSize": 12, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "X5vjX", - "name": "cardProgress2", - "width": "fill_container", - "height": 6, - "fill": "#E5E7EB", - "cornerRadius": 3, - "children": [ - { - "type": "rectangle", - "cornerRadius": 3, - "id": "h0qT6", - "name": "cardProgressFill2", - "fill": "#10B981", - "width": 150, - "height": 6 - } - ] - }, - { - "type": "frame", - "id": "UD9xG", - "name": "cardInfo2", - "width": "fill_container", - "justifyContent": "space_between", - "children": [ - { - "type": "frame", - "id": "8iZa6", - "name": "cardLeft2", - "layout": "vertical", - "gap": 4, - "children": [ - { - "type": "text", - "id": "vixYd", - "name": "cardLabel3", - "fill": "#71717A", - "content": "已支出", - "fontFamily": "DM Sans", - "fontSize": 12, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "0vzMF", - "name": "cardAmount3", - "fill": "#EF4444", - "content": "¥1,280", - "fontFamily": "DM Sans", - "fontSize": 18, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "V53Pn", - "name": "cardRight2", - "layout": "vertical", - "gap": 4, - "alignItems": "end", - "children": [ - { - "type": "text", - "id": "iIrVf", - "name": "cardLabel4", - "fill": "#71717A", - "content": "余额", - "fontFamily": "DM Sans", - "fontSize": 12, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "2sPht", - "name": "cardAmount4", - "fill": "#10B981", - "content": "¥3,720", - "fontFamily": "DM Sans", - "fontSize": 18, - "fontWeight": "600" - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "JXSeL", - "name": "card3", - "width": "fill_container", - "fill": "#F6F7F8", - "cornerRadius": 16, - "layout": "vertical", - "gap": 12, - "padding": 16, - "children": [ - { - "type": "frame", - "id": "YpvwO", - "name": "cardHeader3", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "2toIA", - "name": "cardTitle3", - "fill": "#18181B", - "content": "购物消费", - "fontFamily": "DM Sans", - "fontSize": 16, - "fontWeight": "600" - }, - { - "type": "frame", - "id": "BYZaj", - "name": "cardBadge3", - "fill": "#DBEAFE", - "cornerRadius": 12, - "padding": [ - 4, - 12 - ], - "children": [ - { - "type": "text", - "id": "4cJ7S", - "name": "cardBadgeText3", - "fill": "#3B82F6", - "content": "月度", - "fontFamily": "DM Sans", - "fontSize": 12, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "RCpe6", - "name": "cardProgress3", - "width": "fill_container", - "height": 6, - "fill": "#E5E7EB", - "cornerRadius": 3, - "children": [ - { - "type": "rectangle", - "cornerRadius": 3, - "id": "lWE88", - "name": "cardProgressFill3", - "fill": "#F59E0B", - "width": 280, - "height": 6 - } - ] - }, - { - "type": "frame", - "id": "rgPwW", - "name": "cardInfo3", - "width": "fill_container", - "justifyContent": "space_between", - "children": [ - { - "type": "frame", - "id": "qPicR", - "name": "cardLeft3", - "layout": "vertical", - "gap": 4, - "children": [ - { - "type": "text", - "id": "yLFQq", - "name": "cardLabel5", - "fill": "#71717A", - "content": "已支出", - "fontFamily": "DM Sans", - "fontSize": 12, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "833pE", - "name": "cardAmount5", - "fill": "#EF4444", - "content": "¥1,850", - "fontFamily": "DM Sans", - "fontSize": 18, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "c4S9v", - "name": "cardRight3", - "layout": "vertical", - "gap": 4, - "alignItems": "end", - "children": [ - { - "type": "text", - "id": "syI2C", - "name": "cardLabel6", - "fill": "#71717A", - "content": "余额", - "fontFamily": "DM Sans", - "fontSize": 12, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "AXTAE", - "name": "cardAmount6", - "fill": "#10B981", - "content": "¥650", - "fontFamily": "DM Sans", - "fontSize": 18, - "fontWeight": "600" - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "zYTEk", - "x": 402, - "y": 369, - "name": "Budget - Statistics - Dark", - "width": 375, - "fill": "#09090B", - "layout": "vertical", - "children": [ - { - "type": "frame", - "id": "HdrD2", - "name": "header", - "width": "fill_container", - "gap": 4, - "padding": [ - 8, - 24 - ], - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "HdrCD2", - "name": "headerContent", - "width": 142, - "height": 39, - "layout": "vertical", - "gap": 4, - "children": [ - { - "type": "text", - "id": "TxtD2", - "name": "subtitle", - "fill": "#a1a1aa", - "content": "2026年1月", - "fontFamily": "DM Sans", - "fontSize": 24, - "fontWeight": "500" - } - ] - }, - { - "type": "frame", - "id": "BtnD2", - "name": "notifBtn", - "width": 44, - "height": 44, - "fill": "#27272a", - "cornerRadius": 22, - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "icon_font", - "id": "IcnD2", - "name": "icon", - "width": 20, - "height": 20, - "iconFontName": "bell", - "iconFontFamily": "lucide", - "fill": "#f4f4f5" - } - ] - } - ] - }, - { - "type": "frame", - "id": "UcVry", - "name": "navbar", - "width": "fill_container", - "layout": "vertical", - "children": [ - { - "type": "frame", - "id": "TmjqN", - "name": "tabs", - "width": "fill_container", - "fill": "#1A1A1A", - "cornerRadius": 8, - "gap": 4, - "padding": 4, - "children": [ - { - "type": "frame", - "id": "C7JdO", - "name": "tab1", - "width": "fill_container", - "fill": "#2A2A2A", - "cornerRadius": 6, - "padding": [ - 8, - 16 - ], - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "P0UrT", - "name": "tab1Text", - "fill": "#FFFFFF", - "content": "支出", - "fontFamily": "DM Sans", - "fontSize": 13, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "JEEJO", - "name": "tab2", - "width": "fill_container", - "fill": "transparent", - "padding": [ - 8, - 16 - ], - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "eXJme", - "name": "tab2Text", - "fill": "#888888", - "content": "收入", - "fontFamily": "DM Sans", - "fontSize": 13, - "fontWeight": "500" - } - ] - }, - { - "type": "frame", - "id": "5IBt7", - "name": "tab3", - "width": "fill_container", - "fill": "transparent", - "padding": [ - 8, - 16 - ], - "justifyContent": "center", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "OXd9d", - "name": "tab3Text", - "fill": "#888888", - "content": "计划", - "fontFamily": "DM Sans", - "fontSize": 13, - "fontWeight": "500" - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "nSkwQ", - "name": "content", - "width": "fill_container", - "layout": "vertical", - "gap": 16, - "padding": 16, - "children": [ - { - "type": "frame", - "id": "aGMhW", - "name": "overallCard", - "width": "fill_container", - "fill": "#18181B", - "cornerRadius": 16, - "layout": "vertical", - "gap": 16, - "padding": 24, - "children": [ - { - "type": "text", - "id": "K5cvF", - "name": "overallTitle", - "fill": "#A1A1AA", - "content": "本月预算", - "fontFamily": "DM Sans", - "fontSize": 14, - "fontWeight": "normal" - }, - { - "type": "frame", - "id": "Jadr2", - "name": "overallAmount", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "frame", - "id": "a9J0e", - "name": "overallLeft", - "layout": "vertical", - "gap": 4, - "children": [ - { - "type": "text", - "id": "4xkoW", - "name": "overallCurrent", - "fill": "#FAFAFA", - "content": "¥8,523", - "fontFamily": "Bricolage Grotesque", - "fontSize": 28, - "fontWeight": "700" - }, - { - "type": "text", - "id": "4TscQ", - "name": "overallLimit", - "fill": "#A1A1AA", - "content": "/ ¥15,000", - "fontFamily": "DM Sans", - "fontSize": 16, - "fontWeight": "normal" - } - ] - }, - { - "type": "text", - "id": "9NVyM", - "name": "overallPercent", - "fill": "#FAFAFA", - "content": "56.8%", - "fontFamily": "Bricolage Grotesque", - "fontSize": 24, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "cwd7i", - "name": "progressBar", - "width": "fill_container", - "height": 8, - "fill": "#27272A", - "cornerRadius": 4, - "children": [ - { - "type": "rectangle", - "cornerRadius": 4, - "id": "nsG9r", - "name": "progressFill", - "fill": "#3B82F6", - "width": 213, - "height": 8 - } - ] - } - ] - }, - { - "type": "frame", - "id": "gdyAB", - "name": "budgetList", - "width": "fill_container", - "layout": "vertical", - "gap": 12, - "children": [ - { - "type": "frame", - "id": "I6ghu", - "name": "card1", - "width": "fill_container", - "fill": "#18181B", - "cornerRadius": 16, - "layout": "vertical", - "gap": 12, - "padding": 16, - "children": [ - { - "type": "frame", - "id": "a4Nmj", - "name": "cardHeader1", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "bM4Ya", - "name": "cardTitle1", - "fill": "#FAFAFA", - "content": "餐饮美食", - "fontFamily": "DM Sans", - "fontSize": 16, - "fontWeight": "600" - }, - { - "type": "frame", - "id": "Yc78t", - "name": "cardBadge1", - "fill": "#1E3A8A", - "cornerRadius": 12, - "padding": [ - 4, - 12 - ], - "children": [ - { - "type": "text", - "id": "u4nWW", - "name": "cardBadgeText1", - "fill": "#60A5FA", - "content": "月度", - "fontFamily": "DM Sans", - "fontSize": 12, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "dZutK", - "name": "cardProgress1", - "width": "fill_container", - "height": 6, - "fill": "#27272A", - "cornerRadius": 3, - "children": [ - { - "type": "rectangle", - "cornerRadius": 3, - "id": "h9gGM", - "name": "cardProgressFill1", - "fill": "#EF4444", - "width": 243, - "height": 6 - } - ] - }, - { - "type": "frame", - "id": "8QFZK", - "name": "cardInfo1", - "width": "fill_container", - "justifyContent": "space_between", - "children": [ - { - "type": "frame", - "id": "oq7HH", - "name": "cardLeft1", - "layout": "vertical", - "gap": 4, - "children": [ - { - "type": "text", - "id": "q7ncv", - "name": "cardLabel1", - "fill": "#A1A1AA", - "content": "已支出", - "fontFamily": "DM Sans", - "fontSize": 12, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "OnWIK", - "name": "cardAmount1", - "fill": "#EF4444", - "content": "¥2,456", - "fontFamily": "DM Sans", - "fontSize": 18, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "v6EKH", - "name": "cardRight1", - "layout": "vertical", - "gap": 4, - "alignItems": "end", - "children": [ - { - "type": "text", - "id": "zUjxT", - "name": "cardLabel2", - "fill": "#A1A1AA", - "content": "余额", - "fontFamily": "DM Sans", - "fontSize": 12, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "txCP6", - "name": "cardAmount2", - "fill": "#10B981", - "content": "¥544", - "fontFamily": "DM Sans", - "fontSize": 18, - "fontWeight": "600" - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "DXlJt", - "name": "card2", - "width": "fill_container", - "fill": "#18181B", - "cornerRadius": 16, - "layout": "vertical", - "gap": 12, - "padding": 16, - "children": [ - { - "type": "frame", - "id": "T7ozA", - "name": "cardHeader2", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "F5AoP", - "name": "cardTitle2", - "fill": "#FAFAFA", - "content": "交通出行", - "fontFamily": "DM Sans", - "fontSize": 16, - "fontWeight": "600" - }, - { - "type": "frame", - "id": "MbkXg", - "name": "cardBadge2", - "fill": "#78350F", - "cornerRadius": 12, - "padding": [ - 4, - 12 - ], - "children": [ - { - "type": "text", - "id": "AZvQ9", - "name": "cardBadgeText2", - "fill": "#FCD34D", - "content": "年度", - "fontFamily": "DM Sans", - "fontSize": 12, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "C4B6A", - "name": "cardProgress2", - "width": "fill_container", - "height": 6, - "fill": "#27272A", - "cornerRadius": 3, - "children": [ - { - "type": "rectangle", - "cornerRadius": 3, - "id": "5velO", - "name": "cardProgressFill2", - "fill": "#10B981", - "width": 150, - "height": 6 - } - ] - }, - { - "type": "frame", - "id": "OJuXL", - "name": "cardInfo2", - "width": "fill_container", - "justifyContent": "space_between", - "children": [ - { - "type": "frame", - "id": "aS0rL", - "name": "cardLeft2", - "layout": "vertical", - "gap": 4, - "children": [ - { - "type": "text", - "id": "7hZe7", - "name": "cardLabel3", - "fill": "#A1A1AA", - "content": "已支出", - "fontFamily": "DM Sans", - "fontSize": 12, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "aNOYV", - "name": "cardAmount3", - "fill": "#EF4444", - "content": "¥1,280", - "fontFamily": "DM Sans", - "fontSize": 18, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "qqfZK", - "name": "cardRight2", - "layout": "vertical", - "gap": 4, - "alignItems": "end", - "children": [ - { - "type": "text", - "id": "WmkCh", - "name": "cardLabel4", - "fill": "#A1A1AA", - "content": "余额", - "fontFamily": "DM Sans", - "fontSize": 12, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "yzLpr", - "name": "cardAmount4", - "fill": "#10B981", - "content": "¥3,720", - "fontFamily": "DM Sans", - "fontSize": 18, - "fontWeight": "600" - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "Hq7B3", - "name": "card3", - "width": "fill_container", - "fill": "#18181B", - "cornerRadius": 16, - "layout": "vertical", - "gap": 12, - "padding": 16, - "children": [ - { - "type": "frame", - "id": "HVGmg", - "name": "cardHeader3", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "6ssRH", - "name": "cardTitle3", - "fill": "#FAFAFA", - "content": "购物消费", - "fontFamily": "DM Sans", - "fontSize": 16, - "fontWeight": "600" - }, - { - "type": "frame", - "id": "sujfh", - "name": "cardBadge3", - "fill": "#1E3A8A", - "cornerRadius": 12, - "padding": [ - 4, - 12 - ], - "children": [ - { - "type": "text", - "id": "wRv58", - "name": "cardBadgeText3", - "fill": "#60A5FA", - "content": "月度", - "fontFamily": "DM Sans", - "fontSize": 12, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "OnHhB", - "name": "cardProgress3", - "width": "fill_container", - "height": 6, - "fill": "#27272A", - "cornerRadius": 3, - "children": [ - { - "type": "rectangle", - "cornerRadius": 3, - "id": "bd4VL", - "name": "cardProgressFill3", - "fill": "#F59E0B", - "width": 280, - "height": 6 - } - ] - }, - { - "type": "frame", - "id": "Sd4ny", - "name": "cardInfo3", - "width": "fill_container", - "justifyContent": "space_between", - "children": [ - { - "type": "frame", - "id": "bkP14", - "name": "cardLeft3", - "layout": "vertical", - "gap": 4, - "children": [ - { - "type": "text", - "id": "crUvx", - "name": "cardLabel5", - "fill": "#A1A1AA", - "content": "已支出", - "fontFamily": "DM Sans", - "fontSize": 12, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "RxoOl", - "name": "cardAmount5", - "fill": "#EF4444", - "content": "¥1,850", - "fontFamily": "DM Sans", - "fontSize": 18, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "UPf5R", - "name": "cardRight3", - "layout": "vertical", - "gap": 4, - "alignItems": "end", - "children": [ - { - "type": "text", - "id": "h51tP", - "name": "cardLabel6", - "fill": "#A1A1AA", - "content": "余额", - "fontFamily": "DM Sans", - "fontSize": 12, - "fontWeight": "normal" - }, - { - "type": "text", - "id": "04f8k", - "name": "cardAmount6", - "fill": "#10B981", - "content": "¥650", - "fontFamily": "DM Sans", - "fontSize": 18, - "fontWeight": "600" - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - }, { "type": "frame", "id": "JJ9L0", @@ -9203,6 +4169,961 @@ ] } ] + }, + { + "type": "frame", + "id": "63qh8", + "x": -938, + "y": 369, + "name": "Statistics - Main View - Light", + "width": 375, + "height": 921, + "fill": "#FFFFFF", + "layout": "vertical", + "children": [ + { + "type": "frame", + "id": "wKI4I", + "name": "Header", + "width": "fill_container", + "height": 60, + "padding": [ + 8, + 24 + ], + "justifyContent": "space_between", + "alignItems": "center", + "children": [ + { + "type": "frame", + "id": "D6izC", + "name": "lightLeft", + "layout": "vertical", + "gap": 4, + "children": [ + { + "type": "text", + "id": "wGmPj", + "fill": "#1A1A1A", + "content": "2026年1月", + "fontFamily": "DM Sans", + "fontSize": 24, + "fontWeight": "500" + } + ] + }, + { + "type": "frame", + "id": "U3MqO", + "name": "lightBtn", + "width": 44, + "height": 44, + "fill": "#F5F5F5", + "cornerRadius": 22, + "justifyContent": "center", + "alignItems": "center", + "children": [ + { + "type": "icon_font", + "id": "yPEEN", + "name": "icon", + "rotation": 3.8825130388958945e-19, + "width": 20, + "height": 20, + "iconFontName": "bell", + "iconFontFamily": "lucide", + "fill": "#1A1A1A" + }, + { + "type": "icon_font", + "id": "0vn19", + "width": 0, + "height": 0, + "iconFontName": "sliders-horizontal", + "iconFontFamily": "lucide", + "fill": "#1A1A1A" + } + ] + } + ] + }, + { + "type": "frame", + "id": "NDWwE", + "name": "TabsWrapper", + "width": "fill_container", + "layout": "vertical", + "padding": [ + 8, + 24 + ], + "children": [ + { + "type": "frame", + "id": "4iQfn", + "name": "SegmentedControl", + "width": "fill_container", + "height": 40, + "fill": "#F4F4F5", + "cornerRadius": 8, + "gap": 4, + "padding": 4, + "children": [ + { + "type": "frame", + "id": "7LCL4", + "name": "lTab1", + "width": "fill_container", + "height": "fill_container", + "cornerRadius": 6, + "justifyContent": "center", + "alignItems": "center", + "children": [ + { + "type": "text", + "id": "0rfwC", + "fill": "#71717A", + "content": "周", + "fontFamily": "DM Sans", + "fontSize": 13, + "fontWeight": "500" + } + ] + }, + { + "type": "frame", + "id": "LN1iU", + "name": "lTab2", + "width": "fill_container", + "height": "fill_container", + "fill": "#FFFFFF", + "cornerRadius": 6, + "justifyContent": "center", + "alignItems": "center", + "children": [ + { + "type": "text", + "id": "Ynuf1", + "fill": "#1A1A1A", + "content": "月", + "fontFamily": "DM Sans", + "fontSize": 13, + "fontWeight": "600" + } + ] + }, + { + "type": "frame", + "id": "7VSH1", + "name": "lTab3", + "width": "fill_container", + "height": "fill_container", + "cornerRadius": 6, + "justifyContent": "center", + "alignItems": "center", + "children": [ + { + "type": "text", + "id": "3iRvD", + "fill": "#71717A", + "content": "年", + "fontFamily": "DM Sans", + "fontSize": 13, + "fontWeight": "500" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "hSo7j", + "name": "Content", + "width": "fill_container", + "layout": "vertical", + "gap": 24, + "padding": 24, + "children": [ + { + "type": "frame", + "id": "tSGZ8", + "name": "SummaryCard", + "width": "fill_container", + "fill": "#F6F7F8", + "cornerRadius": 20, + "layout": "vertical", + "gap": 16, + "padding": 20, + "children": [ + { + "type": "frame", + "id": "C8hTu", + "name": "sumHeader", + "width": "fill_container", + "justifyContent": "space_between", + "alignItems": "center", + "children": [ + { + "type": "text", + "id": "AZiKe", + "name": "sumTitle", + "fill": "#71717A", + "content": "本月支出", + "fontFamily": "DM Sans", + "fontSize": 14, + "fontWeight": "600" + } + ] + }, + { + "type": "text", + "id": "yECWx", + "name": "sumAmount", + "fill": "#1A1A1A", + "content": "¥ 4,285.00", + "fontFamily": "Bricolage Grotesque", + "fontSize": 32, + "fontWeight": "800" + }, + { + "type": "frame", + "id": "4r51d", + "name": "sumRow", + "width": "fill_container", + "gap": 24, + "children": [ + { + "type": "frame", + "id": "Upnea", + "name": "incomeCol", + "layout": "vertical", + "gap": 4, + "children": [ + { + "type": "text", + "id": "Gcnc1", + "name": "incomeLabel", + "fill": "#71717A", + "content": "本月收入", + "fontFamily": "DM Sans", + "fontSize": 12, + "fontWeight": "500" + }, + { + "type": "text", + "id": "fXTBh", + "name": "incomeVal", + "fill": "#10B981", + "content": "¥ 8,500.00", + "fontFamily": "DM Sans", + "fontSize": 15, + "fontWeight": "600" + } + ] + }, + { + "type": "frame", + "id": "ehVZP", + "name": "balanceCol", + "layout": "vertical", + "gap": 4, + "children": [ + { + "type": "text", + "id": "vI0VZ", + "name": "balanceLabel", + "fill": "#71717A", + "content": "结余", + "fontFamily": "DM Sans", + "fontSize": 12, + "fontWeight": "500" + }, + { + "type": "text", + "id": "qojoG", + "name": "balanceVal", + "fill": "#3B82F6", + "content": "¥ 4,215.00", + "fontFamily": "DM Sans", + "fontSize": 15, + "fontWeight": "600" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "kFJym", + "name": "lChartSec", + "width": "fill_container", + "layout": "vertical", + "gap": 16, + "children": [ + { + "type": "text", + "id": "s7B2q", + "fill": "#1A1A1A", + "content": "每日趋势 (收支)", + "fontFamily": "Bricolage Grotesque", + "fontSize": 18, + "fontWeight": "700" + }, + { + "type": "frame", + "id": "y4Bc5", + "name": "lChartCard", + "width": "fill_container", + "height": 180, + "fill": { + "type": "image", + "enabled": true, + "url": "./images/generated-1770203108037.png", + "mode": "fill" + }, + "cornerRadius": 20 + } + ] + }, + { + "type": "frame", + "id": "sOimP", + "name": "lPieSec", + "width": "fill_container", + "layout": "vertical", + "gap": 16, + "children": [ + { + "type": "text", + "id": "57rue", + "fill": "#1A1A1A", + "content": "支出排行榜", + "fontFamily": "Bricolage Grotesque", + "fontSize": 18, + "fontWeight": "700" + }, + { + "type": "frame", + "id": "7yjkg", + "name": "lPieCard", + "width": "fill_container", + "fill": "#F6F7F8", + "cornerRadius": 20, + "gap": 20, + "padding": 20, + "alignItems": "center", + "children": [ + { + "type": "frame", + "id": "H96si", + "name": "lPieVisual", + "width": 100, + "height": 100, + "fill": { + "type": "image", + "enabled": true, + "url": "./images/generated-1770203115588.png", + "mode": "fill" + } + }, + { + "type": "frame", + "id": "TxKHf", + "name": "lPieLegend", + "width": "fill_container", + "layout": "vertical", + "gap": 8, + "children": [ + { + "type": "text", + "id": "hgh16", + "fill": "#1A1A1A", + "content": "1. 餐饮 - 40%", + "fontFamily": "DM Sans", + "fontSize": 14, + "fontWeight": "normal" + }, + { + "type": "text", + "id": "oEYBs", + "fill": "#1A1A1A", + "content": "2. 购物 - 35%", + "fontFamily": "DM Sans", + "fontSize": 14, + "fontWeight": "normal" + }, + { + "type": "text", + "id": "0mFr1", + "fill": "#1A1A1A", + "content": "3. 交通 - 25%", + "fontFamily": "DM Sans", + "fontSize": 14, + "fontWeight": "normal" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "bugNe", + "name": "lBotRow", + "width": "fill_container", + "gap": 15, + "children": [ + { + "type": "frame", + "id": "xuQs9", + "name": "lIncCard", + "width": "fill_container", + "height": 100, + "fill": "#F0FDF4", + "cornerRadius": 16, + "layout": "vertical", + "padding": 16, + "justifyContent": "space_between", + "children": [ + { + "type": "text", + "id": "HAa4Z", + "fill": "#15803d", + "content": "收入", + "fontFamily": "DM Sans", + "fontSize": 14, + "fontWeight": "600" + }, + { + "type": "text", + "id": "7mEL2", + "fill": "#15803d", + "content": "¥ 8,500", + "fontFamily": "DIN Alternate", + "fontSize": 20, + "fontWeight": "700" + } + ] + }, + { + "type": "frame", + "id": "vODpx", + "name": "lNonCard", + "width": "fill_container", + "height": 100, + "fill": "#F4F4F5", + "cornerRadius": 16, + "layout": "vertical", + "padding": 16, + "justifyContent": "space_between", + "children": [ + { + "type": "text", + "id": "guryF", + "fill": "#52525B", + "content": "不记收支", + "fontFamily": "DM Sans", + "fontSize": 14, + "fontWeight": "600" + }, + { + "type": "text", + "id": "FVMEg", + "fill": "#52525B", + "content": "¥ 1,200", + "fontFamily": "DIN Alternate", + "fontSize": 20, + "fontWeight": "700" + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "6w9CT", + "x": -513, + "y": 369, + "name": "Statistics - Main View - Dark", + "width": 375, + "height": 921, + "fill": "#09090B", + "layout": "vertical", + "children": [ + { + "type": "frame", + "id": "wULJO", + "name": "Header", + "width": "fill_container", + "height": 60, + "padding": [ + 8, + 24 + ], + "justifyContent": "space_between", + "alignItems": "center", + "children": [ + { + "type": "frame", + "id": "oRlK6", + "name": "darkLeft", + "layout": "vertical", + "gap": 4, + "children": [ + { + "type": "text", + "id": "eCsfk", + "fill": "#f4f4f5", + "content": "2026年1月", + "fontFamily": "DM Sans", + "fontSize": 24, + "fontWeight": "500" + } + ] + }, + { + "type": "frame", + "id": "fmOkM", + "name": "darkBtn", + "width": 44, + "height": 44, + "fill": "#27272a", + "cornerRadius": 22, + "justifyContent": "center", + "alignItems": "center", + "children": [ + { + "type": "icon_font", + "id": "frb7w", + "name": "icon", + "width": 20, + "height": 20, + "iconFontName": "bell", + "iconFontFamily": "lucide", + "fill": "#f4f4f5" + }, + { + "type": "icon_font", + "id": "d34II", + "width": 0, + "height": 0, + "iconFontName": "sliders-horizontal", + "iconFontFamily": "lucide", + "fill": "#f4f4f5" + } + ] + } + ] + }, + { + "type": "frame", + "id": "1Q3hy", + "name": "TabsWrapper", + "width": "fill_container", + "layout": "vertical", + "padding": [ + 8, + 24 + ], + "children": [ + { + "type": "frame", + "id": "lVBvN", + "name": "SegmentedControl", + "width": "fill_container", + "height": 40, + "fill": "#27272A", + "cornerRadius": 8, + "gap": 4, + "padding": 4, + "children": [ + { + "type": "frame", + "id": "KJqGU", + "name": "dTab1", + "width": "fill_container", + "height": "fill_container", + "cornerRadius": 6, + "justifyContent": "center", + "alignItems": "center", + "children": [ + { + "type": "text", + "id": "nDVPC", + "fill": "#A1A1AA", + "content": "周", + "fontFamily": "DM Sans", + "fontSize": 13, + "fontWeight": "500" + } + ] + }, + { + "type": "frame", + "id": "C3LZv", + "name": "dTab2", + "width": "fill_container", + "height": "fill_container", + "fill": "#3F3F46", + "cornerRadius": 6, + "justifyContent": "center", + "alignItems": "center", + "children": [ + { + "type": "text", + "id": "kNapi", + "fill": "#FFFFFF", + "content": "月", + "fontFamily": "DM Sans", + "fontSize": 13, + "fontWeight": "600" + } + ] + }, + { + "type": "frame", + "id": "Abefg", + "name": "dTab3", + "width": "fill_container", + "height": "fill_container", + "cornerRadius": 6, + "justifyContent": "center", + "alignItems": "center", + "children": [ + { + "type": "text", + "id": "4EPZv", + "fill": "#A1A1AA", + "content": "年", + "fontFamily": "DM Sans", + "fontSize": 13, + "fontWeight": "500" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "CuLCX", + "name": "Content", + "width": "fill_container", + "layout": "vertical", + "gap": 24, + "padding": 24, + "children": [ + { + "type": "frame", + "id": "nYStq", + "name": "SummaryCard", + "width": "fill_container", + "fill": "#18181b", + "cornerRadius": 20, + "layout": "vertical", + "gap": 16, + "padding": 20, + "children": [ + { + "type": "frame", + "id": "JpCZq", + "name": "sumHeader", + "width": "fill_container", + "justifyContent": "space_between", + "alignItems": "center", + "children": [ + { + "type": "text", + "id": "RkdY9", + "name": "sumTitle", + "fill": "#a1a1aa", + "content": "本月支出", + "fontFamily": "DM Sans", + "fontSize": 14, + "fontWeight": "600" + } + ] + }, + { + "type": "text", + "id": "hV5bm", + "name": "sumAmount", + "fill": "#f4f4f5", + "content": "¥ 4,285.00", + "fontFamily": "Bricolage Grotesque", + "fontSize": 32, + "fontWeight": "800" + }, + { + "type": "frame", + "id": "Uxj2N", + "name": "sumRow", + "width": "fill_container", + "gap": 24, + "children": [ + { + "type": "frame", + "id": "03RzW", + "name": "incomeCol", + "layout": "vertical", + "gap": 4, + "children": [ + { + "type": "text", + "id": "USmZ1", + "name": "incomeLabel", + "fill": "#a1a1aa", + "content": "本月收入", + "fontFamily": "DM Sans", + "fontSize": 12, + "fontWeight": "500" + }, + { + "type": "text", + "id": "2kxDk", + "name": "incomeVal", + "fill": "#10B981", + "content": "¥ 8,500.00", + "fontFamily": "DM Sans", + "fontSize": 15, + "fontWeight": "600" + } + ] + }, + { + "type": "frame", + "id": "RuePx", + "name": "balanceCol", + "layout": "vertical", + "gap": 4, + "children": [ + { + "type": "text", + "id": "dEm2R", + "name": "balanceLabel", + "fill": "#a1a1aa", + "content": "结余", + "fontFamily": "DM Sans", + "fontSize": 12, + "fontWeight": "500" + }, + { + "type": "text", + "id": "mWW6i", + "name": "balanceVal", + "fill": "#3B82F6", + "content": "¥ 4,215.00", + "fontFamily": "DM Sans", + "fontSize": 15, + "fontWeight": "600" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "x2BA0", + "name": "dChartSec", + "width": "fill_container", + "layout": "vertical", + "gap": 16, + "children": [ + { + "type": "text", + "id": "0tGZM", + "fill": "#F4F4F5", + "content": "每日趋势 (收支)", + "fontFamily": "Bricolage Grotesque", + "fontSize": 18, + "fontWeight": "700" + }, + { + "type": "frame", + "id": "ybzdP", + "name": "dChartCard", + "width": "fill_container", + "height": 180, + "fill": { + "type": "image", + "enabled": true, + "url": "./images/generated-1770203140554.png", + "mode": "fill" + }, + "cornerRadius": 20 + } + ] + }, + { + "type": "frame", + "id": "p0aLn", + "name": "dPieSec", + "width": "fill_container", + "layout": "vertical", + "gap": 16, + "children": [ + { + "type": "text", + "id": "1OZeI", + "fill": "#F4F4F5", + "content": "支出排行榜", + "fontFamily": "Bricolage Grotesque", + "fontSize": 18, + "fontWeight": "700" + }, + { + "type": "frame", + "id": "S0qgq", + "name": "dPieCard", + "width": "fill_container", + "fill": "#18181b", + "cornerRadius": 20, + "gap": 20, + "padding": 20, + "alignItems": "center", + "children": [ + { + "type": "frame", + "id": "vMSEO", + "name": "dPieVisual", + "width": 100, + "height": 100, + "fill": { + "type": "image", + "enabled": true, + "url": "./images/generated-1770203148526.png", + "mode": "fill" + } + }, + { + "type": "frame", + "id": "9KL7W", + "name": "dPieLegend", + "width": "fill_container", + "layout": "vertical", + "gap": 8, + "children": [ + { + "type": "text", + "id": "cqpeA", + "fill": "#A1A1AA", + "content": "1. 餐饮 - 40%", + "fontFamily": "DM Sans", + "fontSize": 14, + "fontWeight": "normal" + }, + { + "type": "text", + "id": "5HB7G", + "fill": "#A1A1AA", + "content": "2. 购物 - 35%", + "fontFamily": "DM Sans", + "fontSize": 14, + "fontWeight": "normal" + }, + { + "type": "text", + "id": "pykGL", + "fill": "#A1A1AA", + "content": "3. 交通 - 25%", + "fontFamily": "DM Sans", + "fontSize": 14, + "fontWeight": "normal" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "SViwD", + "name": "dBotRow", + "width": "fill_container", + "gap": 15, + "children": [ + { + "type": "frame", + "id": "XCp9Y", + "name": "dIncCard", + "width": "fill_container", + "height": 100, + "fill": "#064E3B", + "cornerRadius": 16, + "layout": "vertical", + "padding": 16, + "justifyContent": "space_between", + "children": [ + { + "type": "text", + "id": "8dsEN", + "fill": "#D1FAE5", + "content": "收入", + "fontFamily": "DM Sans", + "fontSize": 14, + "fontWeight": "600" + }, + { + "type": "text", + "id": "NbHIA", + "fill": "#D1FAE5", + "content": "¥ 8,500", + "fontFamily": "DM Sans", + "fontSize": 20, + "fontWeight": "700" + } + ] + }, + { + "type": "frame", + "id": "vH6Cv", + "name": "dNonCard", + "width": "fill_container", + "height": 100, + "fill": "#27272A", + "cornerRadius": 16, + "layout": "vertical", + "padding": 16, + "justifyContent": "space_between", + "children": [ + { + "type": "text", + "id": "OHD8V", + "fill": "#A1A1AA", + "content": "不记收支", + "fontFamily": "DM Sans", + "fontSize": 14, + "fontWeight": "600" + }, + { + "type": "text", + "id": "effcU", + "fill": "#A1A1AA", + "content": "¥ 1,200", + "fontFamily": "DM Sans", + "fontSize": 20, + "fontWeight": "700" + } + ] + } + ] + } + ] + } + ] } ] } \ No newline at end of file diff --git a/Service/Transaction/TransactionStatisticsService.cs b/Service/Transaction/TransactionStatisticsService.cs index 952c706..53afcf9 100644 --- a/Service/Transaction/TransactionStatisticsService.cs +++ b/Service/Transaction/TransactionStatisticsService.cs @@ -10,6 +10,11 @@ public interface ITransactionStatisticsService Task> GetCategoryStatisticsAsync(int year, int month, TransactionType type); + /// + /// 按日期范围获取分类统计数据 + /// + Task> GetCategoryStatisticsByDateRangeAsync(DateTime startDate, DateTime endDate, TransactionType type); + Task> GetTrendStatisticsAsync(int startYear, int startMonth, int monthCount); Task<(List list, int total)> GetReasonGroupsAsync(int pageIndex = 1, int pageSize = 20); @@ -145,6 +150,40 @@ public class TransactionStatisticsService( return categoryGroups; } + /// + /// 按日期范围获取分类统计数据 + /// + public async Task> GetCategoryStatisticsByDateRangeAsync(DateTime startDate, DateTime endDate, TransactionType type) + { + var records = await transactionRepository.QueryAsync( + startDate: startDate, + endDate: endDate, + type: type, + pageSize: int.MaxValue); + + var categoryGroups = records + .GroupBy(t => t.Classify) + .Select(g => new CategoryStatistics + { + Classify = g.Key, + Amount = g.Sum(t => Math.Abs(t.Amount)), + Count = g.Count() + }) + .OrderByDescending(c => c.Amount) + .ToList(); + + var total = categoryGroups.Sum(c => c.Amount); + if (total > 0) + { + foreach (var category in categoryGroups) + { + category.Percent = Math.Round((category.Amount / total) * 100, 1); + } + } + + return categoryGroups; + } + public async Task> GetTrendStatisticsAsync(int startYear, int startMonth, int monthCount) { var trends = new List(); diff --git a/Web/src/App.vue b/Web/src/App.vue index 57e80a3..a777822 100644 --- a/Web/src/App.vue +++ b/Web/src/App.vue @@ -94,6 +94,7 @@ const cachedViews = ref([ 'CalendarV2', // 日历V2页面 'CalendarView', // 日历V1页面 'StatisticsView', // 统计页面 + 'StatisticsV2View', // 统计V2页面 'BalanceView', // 账单页面 'BudgetView' // 预算页面 ]) diff --git a/Web/src/api/statistics.js b/Web/src/api/statistics.js index 8311512..aa75fbd 100644 --- a/Web/src/api/statistics.js +++ b/Web/src/api/statistics.js @@ -20,7 +20,7 @@ import request from './request' */ export const getMonthlyStatistics = (params) => { return request({ - url: '/TransactionRecord/GetMonthlyStatistics', + url: '/TransactionStatistics/GetMonthlyStatistics', method: 'get', params }) @@ -41,7 +41,28 @@ export const getMonthlyStatistics = (params) => { */ export const getCategoryStatistics = (params) => { return request({ - url: '/TransactionRecord/GetCategoryStatistics', + url: '/TransactionStatistics/GetCategoryStatistics', + method: 'get', + params + }) +} + +/** + * 按日期范围获取分类统计数据 + * @param {Object} params - 查询参数 + * @param {string} params.startDate - 开始日期 (格式: YYYY-MM-DD) + * @param {string} params.endDate - 结束日期 (格式: YYYY-MM-DD) + * @param {number} params.type - 交易类型 (0:支出, 1:收入, 2:不计入收支) + * @returns {Promise<{success: boolean, data: Array}>} + * @returns {Array} data - 分类统计列表 + * @returns {string} data[].classify - 分类名称 + * @returns {number} data[].amount - 金额 + * @returns {number} data[].percent - 百分比 + * @returns {number} data[].count - 交易笔数 + */ +export const getCategoryStatisticsByDateRange = (params) => { + return request({ + url: '/TransactionStatistics/GetCategoryStatisticsByDateRange', method: 'get', params }) @@ -62,7 +83,7 @@ export const getCategoryStatistics = (params) => { */ export const getTrendStatistics = (params) => { return request({ - url: '/TransactionRecord/GetTrendStatistics', + url: '/TransactionStatistics/GetTrendStatistics', method: 'get', params }) @@ -81,7 +102,7 @@ export const getTrendStatistics = (params) => { */ export const getDailyStatistics = (params) => { return request({ - url: '/TransactionRecord/GetDailyStatistics', + url: '/TransactionStatistics/GetDailyStatistics', method: 'get', params }) @@ -99,7 +120,47 @@ export const getDailyStatistics = (params) => { */ export const getBalanceStatistics = (params) => { return request({ - url: '/TransactionRecord/GetBalanceStatistics', + url: '/TransactionStatistics/GetBalanceStatistics', + method: 'get', + params + }) +} + +/** + * 获取指定周范围的每天的消费统计 + * @param {Object} params - 查询参数 + * @param {string} params.startDate - 开始日期 (yyyy-MM-dd) + * @param {string} params.endDate - 结束日期 (yyyy-MM-dd) + * @returns {Promise<{success: boolean, data: Array}>} + * @returns {Array} data - 每日统计列表 + * @returns {string} data[].date - 日期 + * @returns {number} data[].count - 交易笔数 + * @returns {number} data[].amount - 交易金额 + */ +export const getWeeklyStatistics = (params) => { + return request({ + url: '/TransactionStatistics/GetWeeklyStatistics', + method: 'get', + params + }) +} + +/** + * 获取指定日期范围的统计汇总数据 + * @param {Object} params - 查询参数 + * @param {string} params.startDate - 开始日期 (yyyy-MM-dd) + * @param {string} params.endDate - 结束日期 (yyyy-MM-dd) + * @returns {Promise<{success: boolean, data: Object}>} + * @returns {Object} data.totalExpense - 总支出 + * @returns {Object} data.totalIncome - 总收入 + * @returns {Object} data.balance - 结余 + * @returns {Object} data.expenseCount - 支出笔数 + * @returns {Object} data.incomeCount - 收入笔数 + * @returns {Object} data.totalCount - 总笔数 + */ +export const getRangeStatistics = (params) => { + return request({ + url: '/TransactionStatistics/GetRangeStatistics', method: 'get', params }) diff --git a/Web/src/api/transactionRecord.js b/Web/src/api/transactionRecord.js index e57d32a..10c0cbd 100644 --- a/Web/src/api/transactionRecord.js +++ b/Web/src/api/transactionRecord.js @@ -189,7 +189,7 @@ export const batchUpdateClassify = (items) => { */ export const getReasonGroups = (pageIndex = 1, pageSize = 20) => { return request({ - url: '/TransactionRecord/GetReasonGroups', + url: '/TransactionStatistics/GetReasonGroups', method: 'get', params: { pageIndex, pageSize } }) diff --git a/Web/src/components/CategoryBillPopup.vue b/Web/src/components/CategoryBillPopup.vue new file mode 100644 index 0000000..1f82d4e --- /dev/null +++ b/Web/src/components/CategoryBillPopup.vue @@ -0,0 +1,504 @@ + + + + + diff --git a/Web/src/components/DateSelectHeader.vue b/Web/src/components/DateSelectHeader.vue new file mode 100644 index 0000000..9f3cd0b --- /dev/null +++ b/Web/src/components/DateSelectHeader.vue @@ -0,0 +1,183 @@ + + + + + diff --git a/Web/src/components/GlassBottomNav.vue b/Web/src/components/GlassBottomNav.vue new file mode 100644 index 0000000..8ed48ce --- /dev/null +++ b/Web/src/components/GlassBottomNav.vue @@ -0,0 +1,313 @@ + + + + + \ No newline at end of file diff --git a/Web/src/components/ModernEmpty.vue b/Web/src/components/ModernEmpty.vue new file mode 100644 index 0000000..93f9db5 --- /dev/null +++ b/Web/src/components/ModernEmpty.vue @@ -0,0 +1,345 @@ + + + + + diff --git a/Web/src/components/TimePeriodTabs.vue b/Web/src/components/TimePeriodTabs.vue new file mode 100644 index 0000000..2fe5d14 --- /dev/null +++ b/Web/src/components/TimePeriodTabs.vue @@ -0,0 +1,90 @@ + + + + + \ No newline at end of file diff --git a/Web/src/router/index.js b/Web/src/router/index.js index d628a3c..9253cf3 100644 --- a/Web/src/router/index.js +++ b/Web/src/router/index.js @@ -68,7 +68,13 @@ const router = createRouter({ { path: '/', name: 'statistics', - component: () => import('../views/StatisticsView.vue'), + component: () => import('../views/statisticsV1/Index.vue'), + meta: { requiresAuth: true } + }, + { + path: '/statistics-v2', + name: 'statistics-v2', + component: () => import('../views/statisticsV2/Index.vue'), meta: { requiresAuth: true } }, { diff --git a/Web/src/utils/format.js b/Web/src/utils/format.js new file mode 100644 index 0000000..6d56a43 --- /dev/null +++ b/Web/src/utils/format.js @@ -0,0 +1,44 @@ +/** + * 格式化金额 + * @param {number} value 金额数值 + * @returns {string} 格式化后的金额字符串 + */ +export const formatMoney = (value) => { + if (!value && value !== 0) { + return '0' + } + return Number(value) + .toFixed(0) + .replace(/\B(?=(\d{3})+(?!\d))/g, ',') +} + +/** + * 格式化日期 + * @param {Date|string} date 日期 + * @param {string} format 格式化模板 + * @returns {string} 格式化后的日期字符串 + */ +export const formatDate = (date, format = 'YYYY-MM-DD') => { + const d = new Date(date) + const year = d.getFullYear() + const month = String(d.getMonth() + 1).padStart(2, '0') + const day = String(d.getDate()).padStart(2, '0') + + return format + .replace('YYYY', year) + .replace('MM', month) + .replace('DD', day) +} + +/** + * 格式化百分比 + * @param {number} value 数值 + * @param {number} decimals 小数位数 + * @returns {string} 格式化后的百分比字符串 + */ +export const formatPercent = (value, decimals = 1) => { + if (!value && value !== 0) { + return '0%' + } + return `${Number(value).toFixed(decimals)}%` +} \ No newline at end of file diff --git a/Web/src/views/BalanceView.vue b/Web/src/views/BalanceView.vue index dbd6574..9572e7e 100644 --- a/Web/src/views/BalanceView.vue +++ b/Web/src/views/BalanceView.vue @@ -55,6 +55,12 @@ ref="messageViewRef" :is-component="true" /> + + + @@ -64,8 +70,17 @@ import { useRoute } from 'vue-router' import TransactionsRecord from './TransactionsRecord.vue' import EmailRecord from './EmailRecord.vue' import MessageView from './MessageView.vue' +import GlassBottomNav from '@/components/GlassBottomNav.vue' const route = useRoute() + +// 底部导航栏 +const activeNavTab = ref('balance') +const handleNavTabClick = (item, index) => { + console.log('Tab clicked:', item.name, index) + // 导航逻辑已在组件内部处理 +} + const tabActive = ref(route.query.tab || 'balance') // 监听路由参数变化,用于从 tabbar 点击时切换 tab diff --git a/Web/src/views/BudgetView.vue b/Web/src/views/BudgetView.vue index fa60020..65ad90f 100644 --- a/Web/src/views/BudgetView.vue +++ b/Web/src/views/BudgetView.vue @@ -497,6 +497,12 @@ @cancel="showDatePicker = false" /> + + + @@ -518,6 +524,14 @@ import BudgetEditPopup from '@/components/Budget/BudgetEditPopup.vue' import SavingsConfigPopup from '@/components/Budget/SavingsConfigPopup.vue' import BudgetChartAnalysis from '@/components/Budget/BudgetChartAnalysis.vue' import PopupContainer from '@/components/PopupContainer.vue' +import GlassBottomNav from '@/components/GlassBottomNav.vue' + +// 底部导航栏 +const navActiveTab = ref('budget') +const handleNavTabClick = (item, index) => { + console.log('Tab clicked:', item.name, index) + // 导航逻辑已在组件内部处理 +} const activeTab = ref(BudgetCategory.Expense) const selectedDate = ref(new Date()) diff --git a/Web/src/views/CalendarView.vue b/Web/src/views/CalendarView.vue index ccf1ada..4ded914 100644 --- a/Web/src/views/CalendarView.vue +++ b/Web/src/views/CalendarView.vue @@ -44,6 +44,12 @@ :transaction="currentTransaction" @save="onDetailSave" /> + + + @@ -56,6 +62,14 @@ import TransactionList from '@/components/TransactionList.vue' import TransactionDetail from '@/components/TransactionDetail.vue' import SmartClassifyButton from '@/components/SmartClassifyButton.vue' import PopupContainer from '@/components/PopupContainer.vue' +import GlassBottomNav from '@/components/GlassBottomNav.vue' + +// 底部导航栏 +const activeTab = ref('calendar') +const handleTabClick = (item, index) => { + console.log('Tab clicked:', item.name, index) + // 导航逻辑已在组件内部处理 +} const dailyStatistics = ref({}) const listVisible = ref(false) diff --git a/Web/src/views/SettingView.vue b/Web/src/views/SettingView.vue index 4d62249..ed58a36 100644 --- a/Web/src/views/SettingView.vue +++ b/Web/src/views/SettingView.vue @@ -139,6 +139,12 @@
+ + + @@ -151,10 +157,19 @@ import { useAuthStore } from '@/stores/auth' import { useVersionStore } from '@/stores/version' import { getVapidPublicKey, subscribe, testNotification } from '@/api/notification' import { updateServiceWorker } from '@/registerServiceWorker' +import GlassBottomNav from '@/components/GlassBottomNav.vue' const router = useRouter() const authStore = useAuthStore() const versionStore = useVersionStore() + +// 底部导航栏 +const activeTab = ref('setting') +const handleTabClick = (item, index) => { + console.log('Tab clicked:', item.name, index) + // 导航逻辑已在组件内部处理 +} + const fileInputRef = ref(null) const currentType = ref('') const notificationEnabled = ref(false) diff --git a/Web/src/views/calendarV2/Index.vue b/Web/src/views/calendarV2/Index.vue index d235c04..89e3eac 100644 --- a/Web/src/views/calendarV2/Index.vue +++ b/Web/src/views/calendarV2/Index.vue @@ -1,34 +1,14 @@ + + \ No newline at end of file diff --git a/Web/src/views/statisticsV1/modules/IncomeNoneCategoryCard.vue b/Web/src/views/statisticsV1/modules/IncomeNoneCategoryCard.vue new file mode 100644 index 0000000..6c3978a --- /dev/null +++ b/Web/src/views/statisticsV1/modules/IncomeNoneCategoryCard.vue @@ -0,0 +1,272 @@ + + + + + \ No newline at end of file diff --git a/Web/src/views/statisticsV2/Index.vue b/Web/src/views/statisticsV2/Index.vue new file mode 100644 index 0000000..96b7e85 --- /dev/null +++ b/Web/src/views/statisticsV2/Index.vue @@ -0,0 +1,766 @@ + + + + + \ No newline at end of file diff --git a/Web/src/views/statisticsV2/modules/DailyTrendChart.vue b/Web/src/views/statisticsV2/modules/DailyTrendChart.vue new file mode 100644 index 0000000..8dfdde2 --- /dev/null +++ b/Web/src/views/statisticsV2/modules/DailyTrendChart.vue @@ -0,0 +1,361 @@ + + + + + \ No newline at end of file diff --git a/Web/src/views/statisticsV2/modules/ExpenseCategoriesCard.vue b/Web/src/views/statisticsV2/modules/ExpenseCategoriesCard.vue new file mode 100644 index 0000000..7e8fea6 --- /dev/null +++ b/Web/src/views/statisticsV2/modules/ExpenseCategoriesCard.vue @@ -0,0 +1,27 @@ + + + \ No newline at end of file diff --git a/Web/src/views/statisticsV2/modules/ExpenseCategoryCard.vue b/Web/src/views/statisticsV2/modules/ExpenseCategoryCard.vue new file mode 100644 index 0000000..7903931 --- /dev/null +++ b/Web/src/views/statisticsV2/modules/ExpenseCategoryCard.vue @@ -0,0 +1,407 @@ + + + + + \ No newline at end of file diff --git a/Web/src/views/statisticsV2/modules/IncomeBalanceCard.vue b/Web/src/views/statisticsV2/modules/IncomeBalanceCard.vue new file mode 100644 index 0000000..5687d45 --- /dev/null +++ b/Web/src/views/statisticsV2/modules/IncomeBalanceCard.vue @@ -0,0 +1,93 @@ + + + + + \ No newline at end of file diff --git a/Web/src/views/statisticsV2/modules/IncomeCategoriesCard.vue b/Web/src/views/statisticsV2/modules/IncomeCategoriesCard.vue new file mode 100644 index 0000000..7068300 --- /dev/null +++ b/Web/src/views/statisticsV2/modules/IncomeCategoriesCard.vue @@ -0,0 +1,27 @@ + + + \ No newline at end of file diff --git a/Web/src/views/statisticsV2/modules/IncomeNoneCategoryCard.vue b/Web/src/views/statisticsV2/modules/IncomeNoneCategoryCard.vue new file mode 100644 index 0000000..6c3978a --- /dev/null +++ b/Web/src/views/statisticsV2/modules/IncomeNoneCategoryCard.vue @@ -0,0 +1,272 @@ + + + + + \ No newline at end of file diff --git a/Web/src/views/statisticsV2/modules/MonthlyExpenseCard.vue b/Web/src/views/statisticsV2/modules/MonthlyExpenseCard.vue new file mode 100644 index 0000000..884cc83 --- /dev/null +++ b/Web/src/views/statisticsV2/modules/MonthlyExpenseCard.vue @@ -0,0 +1,504 @@ + + + + + diff --git a/WebApi/Controllers/TransactionRecordController.cs b/WebApi/Controllers/TransactionRecordController.cs index 793cd3a..40c6efe 100644 --- a/WebApi/Controllers/TransactionRecordController.cs +++ b/WebApi/Controllers/TransactionRecordController.cs @@ -7,10 +7,8 @@ namespace WebApi.Controllers; [Route("api/[controller]/[action]")] public class TransactionRecordController( ITransactionRecordRepository transactionRepository, - ITransactionStatisticsService transactionStatisticsService, ISmartHandleService smartHandleService, - ILogger logger, - IConfigService configService + ILogger logger ) : ControllerBase { /// @@ -262,147 +260,6 @@ public class TransactionRecordController( } } - /// - /// 获取累积余额统计数据(用于余额卡片图表) - /// - [HttpGet] - public async Task>> GetBalanceStatisticsAsync( - [FromQuery] int year, - [FromQuery] int month - ) - { - try - { - // 获取存款分类 - var savingClassify = await configService.GetConfigByKeyAsync("SavingsCategories"); - - // 获取每日统计数据 - var statistics = await transactionStatisticsService.GetDailyStatisticsAsync(year, month, savingClassify); - - // 按日期排序并计算累积余额 - var sortedStats = statistics.OrderBy(s => s.Key).ToList(); - var result = new List(); - decimal cumulativeBalance = 0; - - foreach (var item in sortedStats) - { - var dailyBalance = item.Value.income - item.Value.expense; - cumulativeBalance += dailyBalance; - - result.Add(new BalanceStatisticsDto( - item.Key, - cumulativeBalance - )); - } - - return result.Ok(); - } - catch (Exception ex) - { - logger.LogError(ex, "获取累积余额统计失败,年份: {Year}, 月份: {Month}", year, month); - return $"获取累积余额统计失败: {ex.Message}".Fail>(); - } - } - - /// - /// 获取指定月份每天的消费统计 - /// - [HttpGet] - public async Task>> GetDailyStatisticsAsync( - [FromQuery] int year, - [FromQuery] int month - ) - { - try - { - // 获取存款分类 - var savingClassify = await configService.GetConfigByKeyAsync("SavingsCategories"); - - var statistics = await transactionStatisticsService.GetDailyStatisticsAsync(year, month, savingClassify); - var result = statistics.Select(s => new DailyStatisticsDto( - s.Key, - s.Value.count, - s.Value.expense, - s.Value.income, - s.Value.saving - )).ToList(); - - return result.Ok(); - } - catch (Exception ex) - { - logger.LogError(ex, "获取日历统计数据失败,年份: {Year}, 月份: {Month}", year, month); - return $"获取日历统计数据失败: {ex.Message}".Fail>(); - } - } - - - - /// - /// 获取月度统计数据 - /// - [HttpGet] - public async Task> GetMonthlyStatisticsAsync( - [FromQuery] int year, - [FromQuery] int month - ) - { - try - { - var statistics = await transactionStatisticsService.GetMonthlyStatisticsAsync(year, month); - return statistics.Ok(); - } - catch (Exception ex) - { - logger.LogError(ex, "获取月度统计数据失败,年份: {Year}, 月份: {Month}", year, month); - return $"获取月度统计数据失败: {ex.Message}".Fail(); - } - } - - /// - /// 获取分类统计数据 - /// - [HttpGet] - public async Task>> GetCategoryStatisticsAsync( - [FromQuery] int year, - [FromQuery] int month, - [FromQuery] TransactionType type - ) - { - try - { - var statistics = await transactionStatisticsService.GetCategoryStatisticsAsync(year, month, type); - return statistics.Ok(); - } - catch (Exception ex) - { - logger.LogError(ex, "获取分类统计数据失败,年份: {Year}, 月份: {Month}, 类型: {Type}", year, month, type); - return $"获取分类统计数据失败: {ex.Message}".Fail>(); - } - } - - /// - /// 获取趋势统计数据 - /// - [HttpGet] - public async Task>> GetTrendStatisticsAsync( - [FromQuery] int startYear, - [FromQuery] int startMonth, - [FromQuery] int monthCount = 6 - ) - { - try - { - var statistics = await transactionStatisticsService.GetTrendStatisticsAsync(startYear, startMonth, monthCount); - return statistics.Ok(); - } - catch (Exception ex) - { - logger.LogError(ex, "获取趋势统计数据失败,开始年份: {Year}, 开始月份: {Month}, 月份数: {Count}", startYear, startMonth, - monthCount); - return $"获取趋势统计数据失败: {ex.Message}".Fail>(); - } - } /// /// 智能分析账单(流式输出) @@ -627,30 +484,6 @@ public class TransactionRecordController( } } - /// - /// 获取按交易摘要分组的统计信息(支持分页) - /// - [HttpGet] - public async Task> GetReasonGroupsAsync( - [FromQuery] int pageIndex = 1, - [FromQuery] int pageSize = 20) - { - try - { - var (list, total) = await transactionStatisticsService.GetReasonGroupsAsync(pageIndex, pageSize); - return new PagedResponse - { - Success = true, - Data = list.ToArray(), - Total = total - }; - } - catch (Exception ex) - { - logger.LogError(ex, "获取交易摘要分组失败"); - return PagedResponse.Fail($"获取交易摘要分组失败: {ex.Message}"); - } - } /// /// 按摘要批量更新分类 @@ -738,24 +571,7 @@ public record UpdateTransactionDto( string? OccurredAt = null ); -/// -/// 日历统计响应DTO -/// -public record DailyStatisticsDto( - string Date, - int Count, - decimal Expense, - decimal Income, - decimal Balance -); -/// -/// 累积余额统计DTO -/// -public record BalanceStatisticsDto( - string Date, - decimal CumulativeBalance -); /// /// 智能分类请求DTO diff --git a/WebApi/Controllers/TransactionStatisticsController.cs b/WebApi/Controllers/TransactionStatisticsController.cs new file mode 100644 index 0000000..fae5542 --- /dev/null +++ b/WebApi/Controllers/TransactionStatisticsController.cs @@ -0,0 +1,315 @@ +using Service.Transaction; + +namespace WebApi.Controllers; + +/// +/// 交易统计控制器 +/// +[ApiController] +[Route("api/[controller]/[action]")] +public class TransactionStatisticsController( + ITransactionRecordRepository transactionRepository, + ITransactionStatisticsService transactionStatisticsService, + ILogger logger, + IConfigService configService +) : ControllerBase +{ + /// + /// 获取累积余额统计数据(用于余额卡片图表) + /// + [HttpGet] + public async Task>> GetBalanceStatisticsAsync( + [FromQuery] int year, + [FromQuery] int month + ) + { + try + { + // 获取存款分类 + var savingClassify = await configService.GetConfigByKeyAsync("SavingsCategories"); + + // 获取每日统计数据 + var statistics = await transactionStatisticsService.GetDailyStatisticsAsync(year, month, savingClassify); + + // 按日期排序并计算累积余额 + var sortedStats = statistics.OrderBy(s => s.Key).ToList(); + var result = new List(); + decimal cumulativeBalance = 0; + + foreach (var item in sortedStats) + { + var dailyBalance = item.Value.income - item.Value.expense; + cumulativeBalance += dailyBalance; + + result.Add(new BalanceStatisticsDto( + item.Key, + cumulativeBalance + )); + } + + return result.Ok(); + } + catch (Exception ex) + { + logger.LogError(ex, "获取累积余额统计失败,年份: {Year}, 月份: {Month}", year, month); + return $"获取累积余额统计失败: {ex.Message}".Fail>(); + } + } + + /// + /// 获取指定月份每天的消费统计 + /// + [HttpGet] + public async Task>> GetDailyStatisticsAsync( + [FromQuery] int year, + [FromQuery] int month + ) + { + try + { + // 获取存款分类 + var savingClassify = await configService.GetConfigByKeyAsync("SavingsCategories"); + + var statistics = await transactionStatisticsService.GetDailyStatisticsAsync(year, month, savingClassify); + var result = statistics.Select(s => new DailyStatisticsDto( + s.Key, + s.Value.count, + s.Value.expense, + s.Value.income, + s.Value.saving + )).ToList(); + + return result.Ok(); + } + catch (Exception ex) + { + logger.LogError(ex, "获取日历统计数据失败,年份: {Year}, 月份: {Month}", year, month); + return $"获取日历统计数据失败: {ex.Message}".Fail>(); + } + } + + /// + /// 获取周统计数据 + /// + [HttpGet] + public async Task>> GetWeeklyStatisticsAsync( + [FromQuery] DateTime startDate, + [FromQuery] DateTime endDate + ) + { + try + { + // 获取存款分类 + var savingClassify = await configService.GetConfigByKeyAsync("SavingsCategories"); + + var statistics = await transactionStatisticsService.GetDailyStatisticsByRangeAsync(startDate, endDate, savingClassify); + var result = statistics.Select(s => new DailyStatisticsDto( + s.Key, + s.Value.count, + s.Value.expense, + s.Value.income, + s.Value.saving + )).ToList(); + + return result.Ok(); + } + catch (Exception ex) + { + logger.LogError(ex, "获取周统计数据失败,开始日期: {StartDate}, 结束日期: {EndDate}", startDate, endDate); + return $"获取周统计数据失败: {ex.Message}".Fail>(); + } + } + + /// + /// 获取指定日期范围的统计汇总数据 + /// + [HttpGet] + public async Task> GetRangeStatisticsAsync( + [FromQuery] DateTime startDate, + [FromQuery] DateTime endDate + ) + { + try + { + // 通过日期范围查询数据 + var records = await transactionRepository.QueryAsync( + startDate: startDate, + endDate: endDate, + pageSize: int.MaxValue); + + var statistics = new MonthlyStatistics + { + Year = startDate.Year, + Month = startDate.Month + }; + + foreach (var record in records) + { + var amount = Math.Abs(record.Amount); + + if (record.Type == TransactionType.Expense) + { + statistics.TotalExpense += amount; + statistics.ExpenseCount++; + } + else if (record.Type == TransactionType.Income) + { + statistics.TotalIncome += amount; + statistics.IncomeCount++; + } + } + + statistics.Balance = statistics.TotalIncome - statistics.TotalExpense; + statistics.TotalCount = records.Count; + + return statistics.Ok(); + } + catch (Exception ex) + { + logger.LogError(ex, "获取时间范围统计数据失败,开始日期: {StartDate}, 结束日期: {EndDate}", startDate, endDate); + return $"获取时间范围统计数据失败: {ex.Message}".Fail(); + } + } + + /// + /// 获取月度统计数据 + /// + [HttpGet] + public async Task> GetMonthlyStatisticsAsync( + [FromQuery] int year, + [FromQuery] int month + ) + { + try + { + var statistics = await transactionStatisticsService.GetMonthlyStatisticsAsync(year, month); + return statistics.Ok(); + } + catch (Exception ex) + { + logger.LogError(ex, "获取月度统计数据失败,年份: {Year}, 月份: {Month}", year, month); + return $"获取月度统计数据失败: {ex.Message}".Fail(); + } + } + + /// + /// 获取分类统计数据 + /// + [HttpGet] + public async Task>> GetCategoryStatisticsAsync( + [FromQuery] int year, + [FromQuery] int month, + [FromQuery] TransactionType type + ) + { + try + { + var statistics = await transactionStatisticsService.GetCategoryStatisticsAsync(year, month, type); + return statistics.Ok(); + } + catch (Exception ex) + { + logger.LogError(ex, "获取分类统计数据失败,年份: {Year}, 月份: {Month}, 类型: {Type}", year, month, type); + return $"获取分类统计数据失败: {ex.Message}".Fail>(); + } + } + + /// + /// 按日期范围获取分类统计数据 + /// + [HttpGet] + public async Task>> GetCategoryStatisticsByDateRangeAsync( + [FromQuery] string startDate, + [FromQuery] string endDate, + [FromQuery] TransactionType type + ) + { + try + { + if (!DateTime.TryParse(startDate, out var start)) + { + return "开始日期格式错误".Fail>(); + } + + if (!DateTime.TryParse(endDate, out var end)) + { + return "结束日期格式错误".Fail>(); + } + + var statistics = await transactionStatisticsService.GetCategoryStatisticsByDateRangeAsync(start, end, type); + return statistics.Ok(); + } + catch (Exception ex) + { + logger.LogError(ex, "获取分类统计数据失败,开始日期: {StartDate}, 结束日期: {EndDate}, 类型: {Type}", startDate, endDate, type); + return $"获取分类统计数据失败: {ex.Message}".Fail>(); + } + } + + /// + /// 获取趋势统计数据 + /// + [HttpGet] + public async Task>> GetTrendStatisticsAsync( + [FromQuery] int startYear, + [FromQuery] int startMonth, + [FromQuery] int monthCount = 6 + ) + { + try + { + var statistics = await transactionStatisticsService.GetTrendStatisticsAsync(startYear, startMonth, monthCount); + return statistics.Ok(); + } + catch (Exception ex) + { + logger.LogError(ex, "获取趋势统计数据失败,开始年份: {Year}, 开始月份: {Month}, 月份数: {Count}", startYear, startMonth, + monthCount); + return $"获取趋势统计数据失败: {ex.Message}".Fail>(); + } + } + + /// + /// 获取按交易摘要分组的统计信息(支持分页) + /// + [HttpGet] + public async Task> GetReasonGroupsAsync( + [FromQuery] int pageIndex = 1, + [FromQuery] int pageSize = 20) + { + try + { + var (list, total) = await transactionStatisticsService.GetReasonGroupsAsync(pageIndex, pageSize); + return new PagedResponse + { + Success = true, + Data = list.ToArray(), + Total = total + }; + } + catch (Exception ex) + { + logger.LogError(ex, "获取交易摘要分组失败"); + return PagedResponse.Fail($"获取交易摘要分组失败: {ex.Message}"); + } + } +} + +/// +/// 日历统计响应DTO +/// +public record DailyStatisticsDto( + string Date, + int Count, + decimal Expense, + decimal Income, + decimal Balance +); + +/// +/// 累积余额统计DTO +/// +public record BalanceStatisticsDto( + string Date, + decimal CumulativeBalance +); \ No newline at end of file