样式调整
Some checks failed
Docker Build & Deploy / Build Docker Image (push) Failing after 19s
Docker Build & Deploy / Deploy to Production (push) Has been skipped

This commit is contained in:
2025-12-28 10:23:57 +08:00
parent 832015cd22
commit 1b011309d2
12 changed files with 227 additions and 64 deletions

View File

@@ -6,14 +6,14 @@
<van-tabbar-item name="ccalendar" icon="notes" to="/calendar">
日历
</van-tabbar-item>
<van-tabbar-item name="statistics" icon="chart-trending-o" to="/statistics">
<van-tabbar-item name="statistics" icon="chart-trending-o" to="/" @click="handleTabClick('/statistics')">
统计
</van-tabbar-item>
<van-tabbar-item name="balance" icon="balance-list" to="/" @click="handleTabClick('/')">
<van-tabbar-item name="balance" icon="balance-list" to="/balance" @click="handleTabClick('/balance')">
账单
</van-tabbar-item>
<van-tabbar-item name="email" icon="records" to="/email" @click="handleTabClick('/email')">
邮件
<van-tabbar-item name="message" icon="comment" to="/message" @click="handleTabClick('/message')">
消息
</van-tabbar-item>
<van-tabbar-item name="setting" icon="setting" to="/setting">
设置
@@ -56,9 +56,9 @@ const route = useRoute()
const showTabbar = computed(() => {
return route.path === '/' ||
route.path === '/calendar' ||
route.path === '/email' ||
route.path === '/message' ||
route.path === '/setting' ||
route.path === '/statistics'
route.path === '/balance'
})
const active = ref('')
@@ -89,14 +89,14 @@ const setActive = (path) => {
switch (path) {
case '/calendar':
return 'ccalendar'
case '/statistics':
return 'statistics'
case '/email':
return 'email'
case '/balance':
return 'balance'
case '/message':
return 'message'
case '/setting':
return 'setting'
default:
return 'balance'
return 'statistics'
}
})()
console.log(active.value, path)

View File

@@ -11,9 +11,9 @@ const router = createRouter({
meta: { requiresAuth: false },
},
{
path: '/',
name: 'transactions',
component: () => import('../views/TransactionsRecord.vue'),
path: '/balance',
name: 'balance',
component: () => import('../views/BalanceView.vue'),
meta: { requiresAuth: true },
},
{
@@ -59,7 +59,7 @@ const router = createRouter({
meta: { requiresAuth: true },
},
{
path: '/statistics',
path: '/',
name: 'statistics',
component: () => import('../views/StatisticsView.vue'),
meta: { requiresAuth: true },
@@ -69,6 +69,12 @@ const router = createRouter({
name: 'bill-analysis',
component: () => import('../views/BillAnalysisView.vue'),
meta: { requiresAuth: true },
},
{
path: '/message',
name: 'message',
component: () => import('../views/MessageView.vue'),
meta: { requiresAuth: true },
}
],
})

View File

@@ -189,7 +189,7 @@
flex: 1;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
padding: 16px 0 0 0;
padding: 0 0 0 0;
}
/* ===== 粘性顶部元素样式 ===== */

View File

@@ -0,0 +1,57 @@
<template>
<div class="page-container-flex">
<!-- 顶部导航栏 -->
<van-nav-bar title="交易记录" placeholder>
<template #right>
<van-button
v-if="tabActive === 'balance'"
type="primary"
size="small"
@click="transactionsRecordRef.openAddDialog()"
>
手动录账
</van-button>
<van-button
v-if="tabActive === 'email'"
size="small"
type="primary"
:loading="syncing"
@click="emailRecordRef.handleSync()"
>
立即同步
</van-button>
</template>
</van-nav-bar>
<van-tabs v-model:active="tabActive" animated>
<van-tab title="账单记录" name="balance" />
<van-tab title="邮件记录" name="email" />
</van-tabs>
<TransactionsRecord v-if="tabActive === 'balance'" ref="transactionsRecordRef"/>
<EmailRecord v-else-if="tabActive === 'email'" ref="emailRecordRef" />
</div>
</template>
<script setup>
import { ref } from 'vue';
import TransactionsRecord from './TransactionsRecord.vue';
import EmailRecord from './EmailRecord.vue';
const tabActive = ref('balance');
const transactionsRecordRef = ref(null);
const emailRecordRef = ref(null);
</script>
<style scoped>
:deep(.van-pull-refresh) {
flex: 1;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
/* 设置页面容器背景色 */
:deep(.van-nav-bar) {
background: transparent !important;
}
</style>

View File

@@ -263,7 +263,8 @@ fetchDailyStatistics(now.getFullYear(), now.getMonth() + 1);
}
/* 设置页面容器背景色 */
:deep(.van-nav-bar) {
:deep(.van-calendar__header-title) {
background: transparent !important;
}
</style>

View File

@@ -52,18 +52,18 @@
</template>
</van-swipe-cell>
</van-cell-group>
</div>
<div class="action-bar">
<!-- 新增分类按钮 -->
<div class="add-button-container">
<van-button
type="primary"
size="large"
block
@click="handleAddCategory"
>
新增分类
</van-button>
</div>
<van-button
type="primary"
size="large"
block
@click="handleAddCategory"
>
新增分类
</van-button>
</div>
<!-- 新增分类对话框 -->
@@ -307,12 +307,11 @@ onMounted(() => {
<style scoped>
.level-container {
padding-top: 16px;
min-height: calc(100vh - 50px);
margin-top: 16px;
}
.breadcrumb {
margin-bottom: 16px;
padding: 8px 0;
}
@@ -320,15 +319,6 @@ onMounted(() => {
cursor: pointer;
}
/* 新增按钮 */
.add-button-container {
position: fixed;
bottom: calc(60px + env(safe-area-inset-bottom, 0px));
left: 16px;
right: 16px;
z-index: 10;
}
/* 深色模式 */
@media (prefers-color-scheme: dark) {
.level-container {
@@ -336,6 +326,27 @@ onMounted(() => {
}
}
/* 底部操作栏 */
.action-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
display: flex;
gap: 12px;
padding: 12px;
background-color: var(--van-background-2, #fff);
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.08);
z-index: 100;
}
@media (prefers-color-scheme: dark) {
.action-bar {
background-color: var(--van-background-2, #2c2c2c);
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.3);
}
}
/* 设置页面容器背景色 */
:deep(.van-nav-bar) {
background: transparent !important;

View File

@@ -24,6 +24,9 @@
@click="viewDetail"
@update:selected-ids="selectedIds = $event"
/>
<!-- 底部安全距离 -->
<div style="height: calc(50px + env(safe-area-inset-bottom, 0px))"></div>
</div>
<!-- 详情/编辑弹出层 -->

View File

@@ -1,26 +1,11 @@
<template>
<div class="page-container-flex">
<!-- 顶部导航栏 -->
<van-nav-bar title="邮件记录" placeholder>
<template #right>
<van-button
size="small"
type="primary"
:loading="syncing"
@click="handleSync"
>
立即同步
</van-button>
</template>
</van-nav-bar>
<!-- 下拉刷新区域 -->
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
<!-- 加载提示 -->
<van-loading v-if="loading && !(emailList && emailList.length)" vertical style="padding: 50px 0">
加载中...
</van-loading>
<!-- 邮件列表 -->
<van-list
v-model:loading="loading"
@@ -66,6 +51,9 @@
description="暂无邮件记录"
/>
</van-list>
<!-- 底部安全距离 -->
<div style="height: calc(50px + env(safe-area-inset-bottom, 0px))"></div>
</van-pull-refresh>
<!-- 详情弹出层 -->
@@ -405,6 +393,11 @@ const formatDate = (dateString) => {
onMounted(() => {
loadData(true)
})
// 暴露给父级方法调用
defineExpose({
handleSync
})
</script>
<style scoped>

View File

@@ -0,0 +1,9 @@
<template>
<div>
1
</div>
</template>
<script setup>
</script>

View File

@@ -1,14 +1,5 @@
<template>
<div class="page-container-flex">
<!-- 顶部导航栏 -->
<van-nav-bar title="交易记录" placeholder>
<template #right>
<van-button type="primary" size="small" @click="openAddDialog">
手动录账
</van-button>
</template>
</van-nav-bar>
<!-- 下拉刷新区域 -->
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
<!-- 加载提示 -->
@@ -25,6 +16,9 @@
@click="viewDetail"
@delete="handleDelete"
/>
<!-- 底部安全距离 -->
<div style="height: calc(50px + env(safe-area-inset-bottom, 0px))"></div>
</van-pull-refresh>
<!-- 详情/编辑弹出层 -->
@@ -517,6 +511,12 @@ onMounted(async () => {
await loadClassifyList()
// 不需要手动调用 loadDatavan-list 会自动触发 onLoad
})
// 暴露给父级方法调用
defineExpose({
openAddDialog
})
</script>
<style scoped>

View File

@@ -158,4 +158,89 @@ public class EmailMessageController(
return BaseResponse.Fail($"同步邮件失败: {ex.Message}");
}
}
/// <summary>
/// 标记邮件为已读
/// </summary>
[HttpPost]
public async Task<BaseResponse> MarkAsReadAsync([FromQuery] long id)
{
try
{
var email = await emailRepository.GetByIdAsync(id);
if (email == null)
{
return BaseResponse.Fail("邮件不存在");
}
email.IsRead = true;
email.UpdateTime = DateTime.Now;
var success = await emailRepository.UpdateAsync(email);
if (success)
{
return new BaseResponse
{
Success = true
};
}
else
{
return BaseResponse.Fail("标记失败");
}
}
catch (Exception ex)
{
logger.LogError(ex, "标记邮件为已读失败邮件ID: {EmailId}", id);
return BaseResponse.Fail($"标记失败: {ex.Message}");
}
}
/// <summary>
/// 将所有邮件标记为已读
/// </summary>
[HttpPost]
public async Task<BaseResponse> MarkAllAsReadAsync()
{
try
{
var emails = await emailRepository.GetAllAsync();
var unreadEmails = emails.Where(e => !e.IsRead).ToList();
if (unreadEmails.Count == 0)
{
return new BaseResponse
{
Success = true,
Message = "没有未读邮件"
};
}
foreach (var email in unreadEmails)
{
email.IsRead = true;
email.UpdateTime = DateTime.Now;
}
var success = await emailRepository.UpdateRangeAsync(unreadEmails);
if (success)
{
return new BaseResponse
{
Success = true,
Message = $"已将 {unreadEmails.Count} 封邮件标记为已读"
};
}
else
{
return BaseResponse.Fail("标记失败");
}
}
catch (Exception ex)
{
logger.LogError(ex, "将所有邮件标记为已读失败");
return BaseResponse.Fail($"标记失败: {ex.Message}");
}
}
}

View File

@@ -908,8 +908,6 @@ public class TransactionRecordController(
_ => "未知"
};
}
}
/// <summary>