色彩调整
All checks were successful
Docker Build & Deploy / Build Docker Image (push) Successful in 24s
Docker Build & Deploy / Deploy to Production (push) Successful in 10s
Docker Build & Deploy / Cleanup Dangling Images (push) Successful in 1s
Docker Build & Deploy / WeChat Notification (push) Successful in 1s

This commit is contained in:
孙诚
2026-01-13 17:00:44 +08:00
parent 556fc5af20
commit c5c3b56200
25 changed files with 182 additions and 339 deletions

View File

@@ -354,15 +354,14 @@ public class BudgetService(
var dataPrompt = $""" var dataPrompt = $"""
报告周期:{year}年{month}月 报告周期:{year}年{month}月
账单数据说明支出金额已取绝对值TotalAmount 为正数表示支出/收入的总量)。
1. 预算执行数据JSON 1. 预算执行数据JSON
{JsonSerializer.Serialize(archiveData)} {JsonSerializer.Serialize(archiveData)}
2. 本月消费明细(按分类, JSON 2. 本月账单类目明细(按分类, JSON
{JsonSerializer.Serialize(monthTransactions)} {JsonSerializer.Serialize(monthTransactions)}
3. 全年累计消费概况(按分类, JSON 3. 全年累计账单类目明细(按分类, JSON
{JsonSerializer.Serialize(yearTransactions)} {JsonSerializer.Serialize(yearTransactions)}
4. 未被任何预算覆盖的支出分类JSON 4. 未被任何预算覆盖的支出分类JSON
@@ -377,7 +376,7 @@ public class BudgetService(
4. 消费透视:针对“未被预算覆盖的支出”提供分析建议。分析这些账单产生的合理性,并评估是否需要为其中的大额或频发分类建立新预算。 4. 消费透视:针对“未被预算覆盖的支出”提供分析建议。分析这些账单产生的合理性,并评估是否需要为其中的大额或频发分类建立新预算。
5. 改进建议:根据当前时间进度和预算完成进度,基于本月整体收入支出情况,给出下月预算调整或消费改进的专业化建议。 5. 改进建议:根据当前时间进度和预算完成进度,基于本月整体收入支出情况,给出下月预算调整或消费改进的专业化建议。
6. 语言风格:专业、清晰、简洁,适合财务报告阅读。 6. 语言风格:专业、清晰、简洁,适合财务报告阅读。
7. 7. 如果报告月份是12月需要报告年度预算的执行情况。
【格式要求】 【格式要求】
1. 使用HTML格式移动端H5页面风格 1. 使用HTML格式移动端H5页面风格

View File

@@ -1,54 +1,25 @@
/* color palette from <https://github.com/vuejs/theme> */ /* color palette from <https://github.com/vuejs/theme> */
/*
Most variables are replaced by Vant CSS variables.
Keeping only what's necessary or mapping to Vant.
*/
:root { :root {
--vt-c-white: #ffffff; --van-danger-color: rgb(255, 107, 107) !important; /* 覆盖默认的深红色 #ee0a24 */
--vt-c-white-soft: #f8f8f8; --color-background: var(--van-background);
--vt-c-white-mute: #f2f2f2; --color-background-soft: var(--van-background-2);
--color-background-mute: var(--van-gray-1);
--vt-c-black: #181818; --color-border: var(--van-border-color);
--vt-c-black-soft: #222222; --color-border-hover: var(--van-gray-5);
--vt-c-black-mute: #282828;
--vt-c-indigo: #2c3e50; --color-heading: var(--van-text-color);
--color-text: var(--van-text-color);
--vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
--vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
--vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
--vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
--vt-c-text-light-1: var(--vt-c-indigo);
--vt-c-text-light-2: rgba(60, 60, 60, 0.66);
--vt-c-text-dark-1: var(--vt-c-white);
--vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
}
/* semantic color variables for this project */
:root {
--color-background: var(--vt-c-white);
--color-background-soft: var(--vt-c-white-soft);
--color-background-mute: var(--vt-c-white-mute);
--color-border: var(--vt-c-divider-light-2);
--color-border-hover: var(--vt-c-divider-light-1);
--color-heading: var(--vt-c-text-light-1);
--color-text: var(--vt-c-text-light-1);
--section-gap: 160px; --section-gap: 160px;
} }
@media (prefers-color-scheme: dark) { /* Removed manual dark mode media query as Vant handles it */
:root {
--color-background: var(--vt-c-black);
--color-background-soft: var(--vt-c-black-soft);
--color-background-mute: var(--vt-c-black-mute);
--color-border: var(--vt-c-divider-dark-2);
--color-border-hover: var(--vt-c-divider-dark-1);
--color-heading: var(--vt-c-text-dark-1);
--color-text: var(--vt-c-text-dark-2);
}
}
*, *,
*::before, *::before,
@@ -60,8 +31,8 @@
body { body {
min-height: 100vh; min-height: 100vh;
color: var(--color-text); color: var(--van-text-color);
background: var(--color-background); background: var(--van-background);
transition: transition:
color 0.5s, color 0.5s,
background-color 0.5s; background-color 0.5s;

View File

@@ -47,7 +47,7 @@
<!-- 分类 --> <!-- 分类 -->
<van-field name="category" label="分类"> <van-field name="category" label="分类">
<template #input> <template #input>
<span v-if="!categoryName" style="color: #c8c9cc;">请选择分类</span> <span v-if="!categoryName" style="color: var(--van-text-color-3);">请选择分类</span>
<span v-else>{{ categoryName }}</span> <span v-else>{{ categoryName }}</span>
</template> </template>
</van-field> </van-field>

View File

@@ -121,6 +121,6 @@ const handleSave = async (payload) => {
margin-bottom: 16px; margin-bottom: 16px;
border-radius: 8px; border-radius: 8px;
overflow: hidden; overflow: hidden;
border: 1px solid #ebedf0; border: 1px solid var(--van-border-color);
} }
</style> </style>

View File

@@ -120,7 +120,7 @@
<van-progress <van-progress
:percentage="timePercentage" :percentage="timePercentage"
stroke-width="4" stroke-width="4"
color="#969799" color="var(--van-gray-6)"
:show-pivot="false" :show-pivot="false"
/> />
<span class="percent">{{ timePercentage }}%</span> <span class="percent">{{ timePercentage }}%</span>
@@ -168,7 +168,7 @@ const props = defineProps({
}, },
progressColor: { progressColor: {
type: String, type: String,
default: '#1989fa' default: 'var(--van-primary-color)'
}, },
percentClass: { percentClass: {
type: [String, Object], type: [String, Object],
@@ -332,7 +332,7 @@ const timePercentage = computed(() => {
.compact-label { .compact-label {
font-size: 12px; font-size: 12px;
color: #969799; color: var(--van-text-color-2);
line-height: 1.2; line-height: 1.2;
} }
@@ -346,22 +346,22 @@ const timePercentage = computed(() => {
} }
.compact-value.warning { .compact-value.warning {
color: #ff976a; color: var(--van-warning-color);
} }
.compact-value.income { .compact-value.income {
color: #07c160; color: var(--van-success-color);
} }
.expand-icon { .expand-icon {
color: #1989fa; color: var(--van-primary-color);
font-size: 14px; font-size: 14px;
transition: transform 0.3s ease; transition: transform 0.3s ease;
flex-shrink: 0; flex-shrink: 0;
} }
.collapse-icon { .collapse-icon {
color: #1989fa; color: var(--van-primary-color);
font-size: 16px; font-size: 16px;
cursor: pointer; cursor: pointer;
} }
@@ -386,7 +386,7 @@ const timePercentage = computed(() => {
.card-subtitle { .card-subtitle {
font-size: 12px; font-size: 12px;
color: #969799; color: var(--van-text-color-2);
font-weight: normal; font-weight: normal;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
@@ -420,7 +420,7 @@ const timePercentage = computed(() => {
:deep(.info-item) .label { :deep(.info-item) .label {
font-size: 12px; font-size: 12px;
color: #969799; color: var(--van-text-color-2);
margin-bottom: 2px; margin-bottom: 2px;
} }
@@ -430,11 +430,11 @@ const timePercentage = computed(() => {
} }
:deep(.value.expense) { :deep(.value.expense) {
color: #ee0a24; color: var(--van-danger-color);
} }
:deep(.value.income) { :deep(.value.income) {
color: #07c160; color: var(--van-success-color);
} }
.progress-section { .progress-section {
@@ -443,7 +443,7 @@ const timePercentage = computed(() => {
gap: 12px; gap: 12px;
margin-bottom: 12px; margin-bottom: 12px;
font-size: 13px; font-size: 13px;
color: #646566; color: var(--van-gray-6);
} }
.progress-section :deep(.van-progress) { .progress-section :deep(.van-progress) {
@@ -462,12 +462,12 @@ const timePercentage = computed(() => {
} }
.percent.warning { .percent.warning {
color: #ff976a; color: var(--van-warning-color);
font-weight: bold; font-weight: bold;
} }
.percent.income { .percent.income {
color: #07c160; color: var(--van-success-color);
font-weight: bold; font-weight: bold;
} }
@@ -483,26 +483,26 @@ const timePercentage = computed(() => {
.budget-description { .budget-description {
margin-top: 8px; margin-top: 8px;
background-color: #f7f8fa; background-color: var(--van-background);
border-radius: 4px; border-radius: 4px;
padding: 8px; padding: 8px;
} }
.description-content { .description-content {
font-size: 11px; font-size: 11px;
color: #646566; color: var(--van-gray-6);
line-height: 1.4; line-height: 1.4;
} }
@media (prefers-color-scheme: dark) { /* @media (prefers-color-scheme: dark) {
.budget-description { .budget-description {
background-color: #2c2c2c; background-color: var(--van-background-2);
} }
.description-content { .description-content {
color: #969799; color: var(--van-text-color-2);
} }
.collapsed-row .value { .collapsed-row .value {
color: #f5f5f5; color: var(--van-text-color);
} }
} } */
</style> </style>

View File

@@ -40,7 +40,7 @@
</van-field> </van-field>
<van-field label="相关分类"> <van-field label="相关分类">
<template #input> <template #input>
<div v-if="form.selectedCategories.length === 0" style="color: #c8c9cc;">可多选分类</div> <div v-if="form.selectedCategories.length === 0" style="color: var(--van-text-color-3);">可多选分类</div>
<div v-else class="selected-categories"> <div v-else class="selected-categories">
<span class="ellipsis-text"> <span class="ellipsis-text">
{{ form.selectedCategories.join('、') }} {{ form.selectedCategories.join('、') }}
@@ -176,7 +176,7 @@ const getCategoryName = (category) => {
.ellipsis-text { .ellipsis-text {
font-size: 14px; font-size: 14px;
color: #323233; color: var(--van-text-color);
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
@@ -185,7 +185,7 @@ const getCategoryName = (category) => {
.no-data { .no-data {
font-size: 13px; font-size: 13px;
color: #969799; color: var(--van-text-color-2);
padding: 8px 16px; padding: 8px 16px;
} }
</style> </style>

View File

@@ -130,7 +130,7 @@ const formatMoney = (val) => {
justify-content: center; justify-content: center;
align-items: center; align-items: center;
font-size: 18px; font-size: 18px;
color: #c8c9cc; color: var(--van-gray-5);
cursor: pointer; cursor: pointer;
transition: all 0.2s; transition: all 0.2s;
z-index: 1; z-index: 1;
@@ -150,7 +150,7 @@ const formatMoney = (val) => {
} }
.nav-arrow.disabled { .nav-arrow.disabled {
color: #f2f3f5; color: var(--van-gray-3);
cursor: not-allowed; cursor: not-allowed;
} }
@@ -200,26 +200,26 @@ const formatMoney = (val) => {
.summary-item .label { .summary-item .label {
font-size: 12px; font-size: 12px;
color: #969799; color: var(--van-text-color-2);
margin-bottom: 6px; margin-bottom: 6px;
} }
.summary-item .value { .summary-item .value {
font-size: 20px; font-size: 20px;
font-weight: bold; font-weight: bold;
color: #323233; color: var(--van-text-color);
} }
.summary-item :deep(.value.expense) { .summary-item :deep(.value.expense) {
color: #ee0a24; color: var(--van-danger-color);
} }
.summary-item :deep(.value.income) { .summary-item :deep(.value.income) {
color: #07c160; color: var(--van-success-color);
} }
.summary-item :deep(.value.warning) { .summary-item :deep(.value.warning) {
color: #ff976a; color: var(--van-warning-color);
} }
.summary-item .unit { .summary-item .unit {
@@ -230,7 +230,7 @@ const formatMoney = (val) => {
.summary-item .sub-info { .summary-item .sub-info {
font-size: 12px; font-size: 12px;
color: #c8c9cc; color: var(--van-text-color-3);
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
@@ -238,35 +238,35 @@ const formatMoney = (val) => {
} }
.summary-item .amount { .summary-item .amount {
color: #646566; color: var(--van-text-color-2);
} }
.summary-item .separator { .summary-item .separator {
color: #c8c9cc; color: var(--van-text-color-3);
} }
.divider { .divider {
width: 1px; width: 1px;
height: 24px; height: 24px;
background-color: #ebedf0; background-color: var(--van-border-color);
margin: 0 4px; margin: 0 4px;
} }
@media (prefers-color-scheme: dark) { /* @media (prefers-color-scheme: dark) {
.nav-arrow:active { .nav-arrow:active {
background-color: rgba(255, 255, 255, 0.05); background-color: rgba(255, 255, 255, 0.05);
} }
.nav-arrow.disabled { .nav-arrow.disabled {
color: #323233; color: var(--van-text-color);
} }
.summary-item .value { .summary-item .value {
color: #f5f5f5; color: var(--van-text-color);
} }
.summary-item .amount { .summary-item .amount {
color: #c8c9cc; color: var(--van-text-color-3);
} }
.divider { .divider {
background-color: #2c2c2c; background-color: var(--van-border-color);
} }
} } */
</style> </style>

View File

@@ -91,7 +91,7 @@ const onSubmit = async () => {
.subtitle { .subtitle {
font-size: 14px; font-size: 14px;
color: #969799; color: var(--van-text-color-2);
margin: 0; margin: 0;
} }
@@ -103,7 +103,7 @@ const onSubmit = async () => {
.no-data { .no-data {
text-align: center; text-align: center;
color: #969799; color: var(--van-text-color-2);
width: 100%; width: 100%;
padding: 20px 0; padding: 20px 0;
} }

View File

@@ -79,6 +79,6 @@ const handleSuccess = () => {
position: sticky; position: sticky;
top: 0; top: 0;
z-index: 10; z-index: 10;
background-color: #fff; background-color: var(--van-background-2);
} }
</style> </style>

View File

@@ -91,8 +91,8 @@ const hasActions = computed(() => !!slots['header-actions'])
.popup-header-fixed { .popup-header-fixed {
flex-shrink: 0; flex-shrink: 0;
padding: 16px; padding: 16px;
background-color: var(--van-background-2, #f7f8fa); background-color: var(--van-background-2);
border-bottom: 1px solid var(--van-border-color, #ebedf0); border-bottom: 1px solid var(--van-border-color);
position: sticky; position: sticky;
top: 0; top: 0;
z-index: 10; z-index: 10;
@@ -121,7 +121,7 @@ const hasActions = computed(() => !!slots['header-actions'])
font-weight: 500; font-weight: 500;
margin: 0; margin: 0;
text-align: center; text-align: center;
color: var(--van-text-color, #323233); color: var(--van-text-color);
/*超出长度*/ /*超出长度*/
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
@@ -139,7 +139,7 @@ const hasActions = computed(() => !!slots['header-actions'])
.stats-text { .stats-text {
margin: 0; margin: 0;
font-size: 14px; font-size: 14px;
color: var(--van-text-color-2, #646566); color: var(--van-text-color-2);
grid-column: 2; grid-column: 2;
text-align: center; text-align: center;
} }
@@ -159,8 +159,8 @@ const hasActions = computed(() => !!slots['header-actions'])
.popup-footer-fixed { .popup-footer-fixed {
flex-shrink: 0; flex-shrink: 0;
border-top: 1px solid var(--van-border-color, #ebedf0); border-top: 1px solid var(--van-border-color);
background-color: var(--van-background-2, #f7f8fa); background-color: var(--van-background-2);
padding: 12px 16px; padding: 12px 16px;
} }
</style> </style>

View File

@@ -627,13 +627,13 @@ defineExpose({
.count-text { .count-text {
font-size: 13px; font-size: 13px;
color: #969799; color: var(--van-text-color-2);
} }
.amount-text { .amount-text {
font-size: 14px; font-size: 14px;
font-weight: 500; font-weight: 500;
color: #ff976a; color: var(--van-orange);
} }
:deep(.van-cell-group--inset) { :deep(.van-cell-group--inset) {

View File

@@ -80,7 +80,7 @@
</span> </span>
<div class="suggestion-apply">应用</div> <div class="suggestion-apply">应用</div>
</div> </div>
<span v-else-if="!editForm.classify" style="color: #c8c9cc;">请选择交易分类</span> <span v-else-if="!editForm.classify" style="color: var(--van-gray-5);">请选择交易分类</span>
<span v-else>{{ editForm.classify }}</span> <span v-else>{{ editForm.classify }}</span>
</div> </div>
</template> </template>
@@ -377,17 +377,18 @@ const handleCandidateSelect = (candidate) => {
display: flex; display: flex;
align-items: center; align-items: center;
padding: 6px 10px; padding: 6px 10px;
background: #ecf9ff; background: var(--van-active-color);
color: #1989fa; color: var(--van-primary-color);
border-radius: 8px; border-radius: 8px;
cursor: pointer; cursor: pointer;
transition: opacity 0.2s; transition: opacity 0.2s;
border: 1px solid rgba(25, 137, 250, 0.1); border: 1px solid var(--van-primary-color);
width: fit-content; width: fit-content;
opacity: 0.1;
} }
.suggestion-tip:active { .suggestion-tip:active {
opacity: 0.7; opacity: 0.2;
} }
.suggestion-icon { .suggestion-icon {
@@ -402,23 +403,12 @@ const handleCandidateSelect = (candidate) => {
.suggestion-apply { .suggestion-apply {
margin-left: 8px; margin-left: 8px;
padding: 0 6px; padding: 0 6px;
background: #1989fa; background: var(--van-primary-color);
color: #fff; color: var(--van-white);
border-radius: 4px; border-radius: 4px;
font-size: 10px; font-size: 10px;
height: 18px; height: 18px;
line-height: 18px; line-height: 18px;
font-weight: bold; font-weight: bold;
} }
@media (prefers-color-scheme: dark) {
.suggestion-tip {
background: rgba(25, 137, 250, 0.15);
border-color: rgba(25, 137, 250, 0.2);
color: #58a6ff;
}
.suggestion-apply {
background: #58a6ff;
}
}
</style> </style>

View File

@@ -33,7 +33,7 @@
<span v-if="transaction.classify"> <span v-if="transaction.classify">
分类: {{ transaction.classify }} 分类: {{ transaction.classify }}
</span> </span>
<span v-if="transaction.upsetedClassify && transaction.upsetedClassify !== transaction.classify" style="color: #ff976a"> <span v-if="transaction.upsetedClassify && transaction.upsetedClassify !== transaction.classify" style="color: var(--van-warning-color)">
{{ transaction.upsetedClassify }} {{ transaction.upsetedClassify }}
</span> </span>
@@ -74,7 +74,7 @@
退款: {{ formatMoney(transaction.refundAmount) }} 退款: {{ formatMoney(transaction.refundAmount) }}
</div> </div>
</div> </div>
<van-icon name="arrow" size="16" color="#c8c9cc" /> <van-icon name="arrow" size="16" color="var(--van-gray-5)" />
</div> </div>
</div> </div>
</div> </div>
@@ -315,12 +315,12 @@ const formatDate = (dateString) => {
.transaction-info { .transaction-info {
font-size: 12px; font-size: 12px;
color: #969799; color: var(--van-text-color-2);
line-height: 1.6; line-height: 1.6;
} }
.original-info { .original-info {
color: #ff976a; color: var(--van-orange);
font-style: italic; font-style: italic;
display: flex; display: flex;
align-items: center; align-items: center;
@@ -343,16 +343,16 @@ const formatDate = (dateString) => {
} }
.amount.expense { .amount.expense {
color: #ee0a24; color: var(--van-danger-color);
} }
.amount.income { .amount.income {
color: #07c160; color: var(--van-success-color);
} }
.balance { .balance {
font-size: 12px; font-size: 12px;
color: #969799; color: var(--van-text-color-2);
white-space: nowrap; white-space: nowrap;
} }

View File

@@ -4,16 +4,10 @@
overflow-y: auto; overflow-y: auto;
-webkit-overflow-scrolling: touch; -webkit-overflow-scrolling: touch;
overscroll-behavior: contain; /* 防止滚动链传播到 body */ overscroll-behavior: contain; /* 防止滚动链传播到 body */
background: #f7f8fa; background: var(--van-background);
padding-bottom: env(safe-area-inset-bottom, 0px); padding-bottom: env(safe-area-inset-bottom, 0px);
} }
@media (prefers-color-scheme: dark) {
.page-container {
background: #141414;
}
}
/* 页面内容区域 */ /* 页面内容区域 */
.page-content { .page-content {
padding: 16px 0 0 0; padding: 16px 0 0 0;
@@ -26,20 +20,12 @@
/* 统一卡片样式 */ /* 统一卡片样式 */
.common-card { .common-card {
background: #ffffff; background: var(--van-background-2);
margin: 0 12px 16px; margin: 0 12px 16px;
padding: 16px; padding: 16px;
border-radius: 16px; border-radius: 16px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08); box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
border: 1px solid #ebedf0; border: 1px solid var(--van-border-color);
}
@media (prefers-color-scheme: dark) {
.common-card {
background: #1f1f1f;
border-color: #2c2c2c;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
}
} }
/* 卡片头部 */ /* 卡片头部 */
@@ -60,31 +46,16 @@
/* 增加卡片组的对比度 */ /* 增加卡片组的对比度 */
:deep(.van-cell-group--inset) { :deep(.van-cell-group--inset) {
margin: 10px 16px; margin: 10px 16px;
background: #ffffff; background: var(--van-background-2);
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08); box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
border: 1px solid #ebedf0; border: 1px solid var(--van-border-color);
border-radius: 16px; border-radius: 16px;
} }
@media (prefers-color-scheme: dark) {
:deep(.van-cell-group--inset) {
background: #1f1f1f;
border-color: #2c2c2c;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
}
}
/* 单元格样式 */ /* 单元格样式 */
:deep(.van-cell) { :deep(.van-cell) {
background: #ffffff; background: var(--van-background-2);
border-bottom: 1px solid #ebedf0; border-bottom: 1px solid var(--van-border-color);
}
@media (prefers-color-scheme: dark) {
:deep(.van-cell) {
background: #1f1f1f;
border-bottom: 1px solid #2c2c2c;
}
} }
:deep(.van-cell:last-child) { :deep(.van-cell:last-child) {
@@ -96,31 +67,17 @@
padding: 16px; padding: 16px;
height: 100%; height: 100%;
overflow-y: auto; overflow-y: auto;
background: #f7f8fa; background: var(--van-background);
}
@media (prefers-color-scheme: dark) {
.detail-popup {
background: #141414;
}
} }
/* 弹出层内的卡片组样式 */ /* 弹出层内的卡片组样式 */
.detail-popup :deep(.van-cell-group--inset) { .detail-popup :deep(.van-cell-group--inset) {
background: #ffffff; background: var(--van-background-2);
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08); box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
border: 1px solid #ebedf0; border: 1px solid var(--van-border-color);
border-radius: 16px; border-radius: 16px;
} }
@media (prefers-color-scheme: dark) {
.detail-popup :deep(.van-cell-group--inset) {
background: #1f1f1f;
border-color: #2c2c2c;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
}
}
/* 详情头部样式 */ /* 详情头部样式 */
.detail-header { .detail-header {
margin-bottom: 16px; margin-bottom: 16px;
@@ -136,7 +93,7 @@
.detail-header p { .detail-header p {
margin: 0; margin: 0;
font-size: 14px; font-size: 14px;
color: #969799; color: var(--van-text-color-2);
font-weight: normal; font-weight: normal;
} }
@@ -216,17 +173,11 @@
padding: 12px 16px; padding: 12px 16px;
margin: 0 12px; margin: 0 12px;
margin-top: 12px; margin-top: 12px;
background: #ffffff; background: var(--van-background-2);
border-radius: 12px; border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
} }
@media (prefers-color-scheme: dark) {
.sticky-header {
background: #1f1f1f;
}
}
.sticky-header-text { .sticky-header-text {
font-size: 16px; font-size: 16px;
font-weight: 600; font-weight: 600;
@@ -240,11 +191,11 @@
/* ===== 颜色工具类 ===== */ /* ===== 颜色工具类 ===== */
.text-expense { .text-expense {
color: #ff6b6b; color: var(--van-danger-color);
} }
.text-income { .text-income {
color: #51cf66; color: var(--van-success-color);
} }
/* 底部操作栏 */ /* 底部操作栏 */
@@ -256,18 +207,11 @@
display: flex; display: flex;
gap: 12px; gap: 12px;
padding: 12px; padding: 12px;
background-color: var(--van-background-2, #fff); background-color: var(--van-background-2);
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.08); box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.08);
z-index: 100; z-index: 100;
} }
@media (prefers-color-scheme: dark) {
.bottom-button {
background-color: var(--van-background-2, #2c2c2c);
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.3);
}
}
/* ===== 统一弹窗样式 ===== */ /* ===== 统一弹窗样式 ===== */
/* 弹窗容器 - 使用 flex 布局,确保标题固定,内容可滚动 */ /* 弹窗容器 - 使用 flex 布局,确保标题固定,内容可滚动 */
.popup-container { .popup-container {
@@ -304,15 +248,5 @@
overflow-y: auto; overflow-y: auto;
-webkit-overflow-scrolling: touch; -webkit-overflow-scrolling: touch;
overscroll-behavior: contain; overscroll-behavior: contain;
background: var(--van-background);
} }
/* 深色模式适配 */
@media (prefers-color-scheme: dark) {
.popup-header-fixed {
background: #1f1f1f;
}
.popup-scroll-content {
background: #141414;
}
}

View File

@@ -108,27 +108,27 @@
/* 业务特定样式:收入、支出、高亮 */ /* 业务特定样式:收入、支出、高亮 */
.rich-html-content .income-value { .rich-html-content .income-value {
color: #07c160 !important; color: var(--van-success-color) !important;
font-weight: 600; font-weight: 600;
} }
.rich-html-content .expense-value { .rich-html-content .expense-value {
color: #ee0a24 !important; color: var(--van-danger-color) !important;
font-weight: 600; font-weight: 600;
} }
.rich-html-content .highlight { .rich-html-content .highlight {
background-color: #fffbe6; background-color: var(--van-orange-light);
color: #ed6a0c; color: var(--van-orange-dark);
padding: 2px 6px; padding: 2px 6px;
border-radius: 4px; border-radius: 4px;
font-weight: bold; font-weight: bold;
border: 1px solid #ffe58f; border: 1px solid var(--van-orange);
margin: 0 2px; margin: 0 2px;
} }
/* 暗色模式适配 */ /* 暗色模式适配 */
@media (prefers-color-scheme: dark) { /* @media (prefers-color-scheme: dark) {
.rich-html-content .highlight { .rich-html-content .highlight {
background-color: rgba(255, 243, 205, 0.2); background-color: rgba(255, 243, 205, 0.2);
color: #ffc107; color: #ffc107;
@@ -156,4 +156,4 @@
.rich-html-content td { .rich-html-content td {
border-bottom: 1px solid #2c2c2c; border-bottom: 1px solid #2c2c2c;
} }
} } */

View File

@@ -274,21 +274,14 @@ const startAnalysis = async () => {
/* 输入区域 */ /* 输入区域 */
.input-section { .input-section {
background: #ffffff; background: var(--van-background-2);
padding: 20px; padding: 20px;
border-radius: 16px; border-radius: 16px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08); box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
border: 1px solid #ebedf0; border: 1px solid var(--van-border-color);
margin-bottom: 16px; margin-bottom: 16px;
} }
@media (prefers-color-scheme: dark) {
.input-section {
background: #1f1f1f;
border-color: #2c2c2c;
}
}
.input-header h3 { .input-header h3 {
font-size: 18px; font-size: 18px;
font-weight: 600; font-weight: 600;
@@ -355,7 +348,7 @@ const startAnalysis = async () => {
} }
.error-message { .error-message {
color: #ff6b6b; color: var(--van-danger-color);
text-align: center; text-align: center;
padding: 20px; padding: 20px;
} }

View File

@@ -8,7 +8,7 @@
&& !isArchive" && !isArchive"
name="warning-o" name="warning-o"
size="20" size="20"
color="#ee0a24" color="var(--van-danger-color)"
style="margin-right: 12px" style="margin-right: 12px"
title="查看未覆盖预算的分类" title="查看未覆盖预算的分类"
@click="showUncoveredDetails = true" @click="showUncoveredDetails = true"
@@ -149,7 +149,7 @@
v-for="budget in savingsBudgets" v-for="budget in savingsBudgets"
:key="budget.id" :key="budget.id"
:budget="budget" :budget="budget"
progress-color="#07c160" progress-color="var(--van-success-color)"
:percent-class="{ 'income': (budget.current / budget.limit) >= 1 }" :percent-class="{ 'income': (budget.current / budget.limit) >= 1 }"
:period-label="getPeriodLabel(budget.type)" :period-label="getPeriodLabel(budget.type)"
style="margin: 0 12px 12px;" style="margin: 0 12px 12px;"
@@ -418,15 +418,15 @@ const getPeriodLabel = (type) => {
const getProgressColor = (budget) => { const getProgressColor = (budget) => {
const ratio = budget.current / budget.limit const ratio = budget.current / budget.limit
if (ratio >= 1) return '#ee0a24' if (ratio >= 1) return 'var(--van-danger-color)'
if (ratio > 0.8) return '#ff976a' if (ratio > 0.8) return 'var(--van-warning-color)'
return '#1989fa' return 'var(--van-primary-color)'
} }
const getIncomeProgressColor = (budget) => { const getIncomeProgressColor = (budget) => {
const ratio = budget.current / budget.limit const ratio = budget.current / budget.limit
if (ratio >= 1) return '#07c160' if (ratio >= 1) return 'var(--van-success-color)'
return '#1989fa' return 'var(--van-primary-color)'
} }
const handleDelete = (budget) => { const handleDelete = (budget) => {
@@ -535,7 +535,7 @@ const handleSaveSummary = async () => {
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding: 16px; padding: 16px;
background-color: var(--van-background-2, #ffffff); background-color: var(--van-background-2);
border-radius: 12px; border-radius: 12px;
margin-bottom: 12px; margin-bottom: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
@@ -549,13 +549,13 @@ const handleSaveSummary = async () => {
.category-name { .category-name {
font-size: 16px; font-size: 16px;
font-weight: 500; font-weight: 500;
color: var(--van-text-color, #323233); color: var(--van-text-color);
margin-bottom: 4px; margin-bottom: 4px;
} }
.transaction-count { .transaction-count {
font-size: 12px; font-size: 12px;
color: var(--van-text-color-2, #969799); color: var(--van-text-color-2);
} }
.item-right { .item-right {

View File

@@ -398,11 +398,11 @@ onMounted(() => {
} }
/* 深色模式 */ /* 深色模式 */
@media (prefers-color-scheme: dark) { /* @media (prefers-color-scheme: dark) {
.level-container { .level-container {
background: #1a1a1a; background: var(--van-background);
} }
} } */
/* 设置页面容器背景色 */ /* 设置页面容器背景色 */
:deep(.van-nav-bar) { :deep(.van-nav-bar) {

View File

@@ -64,7 +64,7 @@
title="交易记录列表" title="交易记录列表"
height="75%" height="75%"
> >
<div style="background: var(--van-background, #f7f8fa);"> <div style="background: var(--van-background);">
<!-- 批量操作按钮 --> <!-- 批量操作按钮 -->
<div class="batch-actions"> <div class="batch-actions">
<van-button <van-button
@@ -320,7 +320,7 @@ const handleSubmit = async () => {
display: flex; display: flex;
gap: 8px; gap: 8px;
padding: 12px 16px; padding: 12px 16px;
background-color: var(--van-background-2, #fff); background-color: var(--van-background-2);
margin-bottom: 8px; margin-bottom: 8px;
} }

View File

@@ -346,7 +346,7 @@ onMounted(async () => {
.stats-info { .stats-info {
padding: 12px 12px 0 16px; padding: 12px 12px 0 16px;
font-size: 14px; font-size: 14px;
color: #969799; color: var(--van-text-color-2);
} }
.stats-value { .stats-value {

View File

@@ -102,7 +102,7 @@
</div> </div>
<div v-else class="content-body empty-content"> <div v-else class="content-body empty-content">
暂无邮件内容 暂无邮件内容
<div style="font-size: 12px; margin-top: 8px; color: #999;"> <div style="font-size: 12px; margin-top: 8px; color: var(--van-gray-6);">
Debug: {{ Object.keys(currentEmail).join(', ') }} Debug: {{ Object.keys(currentEmail).join(', ') }}
</div> </div>
</div> </div>
@@ -487,7 +487,7 @@ defineExpose({
.email-date { .email-date {
font-size: 12px; font-size: 12px;
color: #969799; color: var(--van-text-color-2);
padding-right: 10px; padding-right: 10px;
} }
@@ -513,12 +513,12 @@ defineExpose({
margin: 0 20px; margin: 0 20px;
} }
@media (prefers-color-scheme: dark) { /* @media (prefers-color-scheme: dark) {
.content-body { .content-body {
background-color: #2c2c2c; background-color: var(--van-background-2);
border: 1px solid #3a3a3a; border: 1px solid var(--van-border-color);
} }
} } */
.delete-button { .delete-button {
height: 100%; height: 100%;

View File

@@ -292,27 +292,27 @@ onMounted(() => {
<style scoped> <style scoped>
.log-view { .log-view {
height: 100vh; height: 100vh;
background-color: #f5f5f5; background-color: var(--van-background);
} }
@media (prefers-color-scheme: dark) { /* @media (prefers-color-scheme: dark) {
.log-view { .log-view {
background-color: #1a1a1a; background-color: #1a1a1a;
} }
} } */
.filter-section { .filter-section {
background-color: #ffffff; background-color: var(--van-background-2);
position: sticky; position: sticky;
top: 0; top: 0;
z-index: 10; z-index: 10;
} }
@media (prefers-color-scheme: dark) { /* @media (prefers-color-scheme: dark) {
.filter-section { .filter-section {
background-color: #2c2c2c; background-color: #2c2c2c;
} }
} } */
.filter-row { .filter-row {
padding: 0; padding: 0;
@@ -323,8 +323,8 @@ onMounted(() => {
} }
.log-item { .log-item {
background-color: #ffffff; background-color: var(--van-background-2);
border-left: 3px solid #1989fa; border-left: 3px solid var(--van-primary-color);
margin-bottom: 4px; margin-bottom: 4px;
padding: 6px 10px; padding: 6px 10px;
border-radius: 3px; border-radius: 3px;
@@ -338,7 +338,7 @@ onMounted(() => {
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
} }
@media (prefers-color-scheme: dark) { /* @media (prefers-color-scheme: dark) {
.log-item { .log-item {
background-color: #2c2c2c; background-color: #2c2c2c;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
@@ -347,7 +347,7 @@ onMounted(() => {
.log-item:hover { .log-item:hover {
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
} }
} } */
.log-header { .log-header {
display: flex; display: flex;
@@ -398,20 +398,20 @@ onMounted(() => {
} }
.level-debug .log-level { .level-debug .log-level {
background-color: #1989fa; background-color: var(--van-primary-color);
} }
.level-info .log-level { .level-info .log-level {
background-color: #07c160; background-color: var(--van-success-color);
} }
.level-warning .log-level { .level-warning .log-level {
background-color: #ff976a; background-color: var(--van-orange);
border-left-color: #ff976a; border-left-color: var(--van-orange);
} }
.level-error .log-level { .level-error .log-level {
background-color: #ee0a24; background-color: var(--van-danger-color);
} }
.level-fatal .log-level { .level-fatal .log-level {
@@ -419,7 +419,7 @@ onMounted(() => {
} }
.level-default .log-level { .level-default .log-level {
background-color: #646566; background-color: var(--van-gray-6);
} }
.level-verbose { .level-verbose {
@@ -427,19 +427,19 @@ onMounted(() => {
} }
.level-debug { .level-debug {
border-left-color: #1989fa; border-left-color: var(--van-primary-color);
} }
.level-info { .level-info {
border-left-color: #07c160; border-left-color: var(--van-success-color);
} }
.level-warning { .level-warning {
border-left-color: #ff976a; border-left-color: var(--van-orange);
} }
.level-error { .level-error {
border-left-color: #ee0a24; border-left-color: var(--van-danger-color);
} }
.level-fatal { .level-fatal {
@@ -447,7 +447,7 @@ onMounted(() => {
} }
.level-default { .level-default {
border-left-color: #646566; border-left-color: var(--van-gray-6);
} }
/* 优化下拉菜单样式 */ /* 优化下拉菜单样式 */
@@ -455,9 +455,9 @@ onMounted(() => {
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
} }
@media (prefers-color-scheme: dark) { /* @media (prefers-color-scheme: dark) {
:deep(.van-dropdown-menu) { :deep(.van-dropdown-menu) {
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
} }
} } */
</style> </style>

View File

@@ -188,7 +188,7 @@
</van-field> </van-field>
<van-field name="classify" label="分类"> <van-field name="classify" label="分类">
<template #input> <template #input>
<span v-if="!form.classify" style="color: #c8c9cc;">请选择交易分类</span> <span v-if="!form.classify" style="color: var(--van-gray-5);">请选择交易分类</span>
<span v-else>{{ form.classify }}</span> <span v-else>{{ form.classify }}</span>
</template> </template>
</van-field> </van-field>

View File

@@ -306,28 +306,15 @@ const handleScheduledTasks = () => {
<style scoped> <style scoped>
/* 页面背景色 */ /* 页面背景色 */
:deep(body) { :deep(body) {
background-color: #f5f5f5; background-color: var(--van-background);
}
@media (prefers-color-scheme: dark) {
:deep(body) {
background-color: #1a1a1a;
}
} }
/* 增加卡片对比度 */ /* 增加卡片对比度 */
:deep(.van-cell-group--inset) { :deep(.van-cell-group--inset) {
background-color: #ffffff; background-color: var(--van-background-2);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
} }
@media (prefers-color-scheme: dark) {
:deep(.van-cell-group--inset) {
background-color: #2c2c2c;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}
}
.detail-header { .detail-header {
padding: 16px 16px 5px 16px; padding: 16px 16px 5px 16px;
margin-bottom: 5px; margin-bottom: 5px;
@@ -336,7 +323,7 @@ const handleScheduledTasks = () => {
.detail-header p { .detail-header p {
margin: 0; margin: 0;
font-size: 14px; font-size: 14px;
color: #969799; color: var(--van-text-color-2);
font-weight: normal; font-weight: normal;
} }

View File

@@ -1001,19 +1001,12 @@ onBeforeUnmount(() => {
display: flex; display: flex;
justify-content: space-around; justify-content: space-around;
align-items: center; align-items: center;
background: #ffffff; background: var(--van-background-2);
margin: 0 12px 16px; margin: 0 12px 16px;
padding: 24px 12px; padding: 24px 12px;
border-radius: 16px; border-radius: 16px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08); box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
border: 1px solid #ebedf0; border: 1px solid var(--van-border-color);
}
@media (prefers-color-scheme: dark) {
.overview-card {
background: #1f1f1f;
border-color: #2c2c2c;
}
} }
.nav-arrow { .nav-arrow {
@@ -1025,7 +1018,7 @@ onBeforeUnmount(() => {
justify-content: center; justify-content: center;
align-items: center; align-items: center;
font-size: 18px; font-size: 18px;
color: #c8c9cc; color: var(--van-gray-5);
cursor: pointer; cursor: pointer;
transition: all 0.2s; transition: all 0.2s;
z-index: 1; z-index: 1;
@@ -1149,11 +1142,11 @@ onBeforeUnmount(() => {
} }
.expense { .expense {
color: #ff6b6b; color: var(--van-danger-color);
} }
.income { .income {
color: #51cf66; color: var(--van-success-color);
} }
/* 环形图 */ /* 环形图 */
@@ -1207,17 +1200,11 @@ onBeforeUnmount(() => {
display: flex; display: flex;
align-items: center; align-items: center;
padding: 12px 0; padding: 12px 0;
border-bottom: 1px solid #ebedf0; border-bottom: 1px solid var(--van-border-color);
transition: background-color 0.2s; transition: background-color 0.2s;
gap: 12px; gap: 12px;
} }
@media (prefers-color-scheme: dark) {
.category-item {
border-bottom: 1px solid #2c2c2c;
}
}
.category-item:last-child { .category-item:last-child {
border-bottom: none; border-bottom: none;
} }
@@ -1227,13 +1214,7 @@ onBeforeUnmount(() => {
} }
.category-item.clickable:active { .category-item.clickable:active {
background-color: #f7f8fa; background-color: var(--van-background);
}
@media (prefers-color-scheme: dark) {
.category-item.clickable:active {
background-color: #141414;
}
} }
.category-info { .category-info {
@@ -1289,36 +1270,30 @@ onBeforeUnmount(() => {
.category-percent { .category-percent {
font-size: 12px; font-size: 12px;
color: var(--van-text-color-3); color: var(--van-text-color-3);
background: #f7f8fa; background: var(--van-background);
padding: 2px 8px; padding: 2px 8px;
border-radius: 10px; border-radius: 10px;
} }
@media (prefers-color-scheme: dark) {
.category-percent {
background: #141414;
}
}
.income-color { .income-color {
background-color: #51cf66; background-color: var(--van-success-color);
} }
.income-text { .income-text {
color: #51cf66; color: var(--van-success-color);
} }
/* 不计收支颜色 */ /* 不计收支颜色 */
.none-color { .none-color {
background-color: #909399; background-color: var(--van-gray-6);
} }
.none-text { .none-text {
color: #909399; color: var(--van-gray-6);
} }
.expense-color { .expense-color {
background-color: #ff6b6b; background-color: var(--van-danger-color);
} }
/* 趋势图 */ /* 趋势图 */
@@ -1387,16 +1362,10 @@ onBeforeUnmount(() => {
.trend-legend { .trend-legend {
display: flex; display: flex;
justify-content: center; justify-content: space-center;
gap: 24px; gap: 24px;
padding-top: 12px; padding-top: 12px;
border-top: 1px solid #ebedf0; border-top: 1px solid var(--van-border-color);
}
@media (prefers-color-scheme: dark) {
.trend-legend {
border-top: 1px solid #2c2c2c;
}
} }
.legend-item { .legend-item {
@@ -1422,17 +1391,17 @@ onBeforeUnmount(() => {
} }
.stat-item { .stat-item {
background: #f7f8fa; background: var(--van-background-2);
padding: 16px; padding: 16px;
border-radius: 12px; border-radius: 12px;
text-align: center; text-align: center;
} }
@media (prefers-color-scheme: dark) { /* @media (prefers-color-scheme: dark) {
.stat-item { .stat-item {
background: #141414; background: var(--van-background-2);
} }
} } */
.stat-label { .stat-label {
font-size: 13px; font-size: 13px;