feat: 移除预算相关的停止状态属性和相关功能,简化预算管理逻辑
All checks were successful
Docker Build & Deploy / Build Docker Image (push) Successful in 24s
Docker Build & Deploy / Deploy to Production (push) Successful in 11s
Docker Build & Deploy / Cleanup Dangling Images (push) Successful in 1s
Docker Build & Deploy / WeChat Notification (push) Successful in 1s
All checks were successful
Docker Build & Deploy / Build Docker Image (push) Successful in 24s
Docker Build & Deploy / Deploy to Production (push) Successful in 11s
Docker Build & Deploy / Cleanup Dangling Images (push) Successful in 1s
Docker Build & Deploy / WeChat Notification (push) Successful in 1s
This commit is contained in:
@@ -30,11 +30,6 @@ public class BudgetRecord : BaseEntity
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string SelectedCategories { get; set; } = string.Empty;
|
public string SelectedCategories { get; set; } = string.Empty;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 是否停止
|
|
||||||
/// </summary>
|
|
||||||
public bool IsStopped { get; set; } = false;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 开始日期
|
/// 开始日期
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -161,9 +161,9 @@ public class BudgetService(
|
|||||||
Count = 0
|
Count = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
// 获取当前分类下所有未停止的预算
|
// 获取当前分类下所有预算
|
||||||
var relevant = budgets
|
var relevant = budgets
|
||||||
.Where(b => b.Category == category && !b.IsStopped)
|
.Where(b => b.Category == category)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
if (relevant.Count == 0)
|
if (relevant.Count == 0)
|
||||||
@@ -409,8 +409,6 @@ public class BudgetService(
|
|||||||
|
|
||||||
private async Task<decimal> CalculateCurrentAmountAsync(BudgetRecord budget, DateTime? now = null)
|
private async Task<decimal> CalculateCurrentAmountAsync(BudgetRecord budget, DateTime? now = null)
|
||||||
{
|
{
|
||||||
if (budget.IsStopped) return 0;
|
|
||||||
|
|
||||||
var referenceDate = now ?? DateTime.Now;
|
var referenceDate = now ?? DateTime.Now;
|
||||||
var (startDate, endDate) = GetPeriodRange(budget.StartDate, budget.Type, referenceDate);
|
var (startDate, endDate) = GetPeriodRange(budget.StartDate, budget.Type, referenceDate);
|
||||||
|
|
||||||
@@ -468,7 +466,7 @@ public class BudgetService(
|
|||||||
|
|
||||||
foreach (var b in allBudgets)
|
foreach (var b in allBudgets)
|
||||||
{
|
{
|
||||||
if (b.IsStopped || b.Category == BudgetCategory.Savings) continue;
|
if (b.Category == BudgetCategory.Savings) continue;
|
||||||
|
|
||||||
// 折算系数:根据当前请求的 periodType (Year 或 Month),将预算 b 的 Limit 折算过来
|
// 折算系数:根据当前请求的 periodType (Year 或 Month),将预算 b 的 Limit 折算过来
|
||||||
decimal factor = 1.0m;
|
decimal factor = 1.0m;
|
||||||
@@ -589,7 +587,6 @@ public record BudgetResult
|
|||||||
public decimal Current { get; set; }
|
public decimal Current { get; set; }
|
||||||
public BudgetCategory Category { get; set; }
|
public BudgetCategory Category { get; set; }
|
||||||
public string[] SelectedCategories { get; set; } = Array.Empty<string>();
|
public string[] SelectedCategories { get; set; } = Array.Empty<string>();
|
||||||
public bool IsStopped { get; set; }
|
|
||||||
public string StartDate { get; set; } = string.Empty;
|
public string StartDate { get; set; } = string.Empty;
|
||||||
public string Period { get; set; } = string.Empty;
|
public string Period { get; set; } = string.Empty;
|
||||||
public DateTime? PeriodStart { get; set; }
|
public DateTime? PeriodStart { get; set; }
|
||||||
@@ -617,7 +614,6 @@ public record BudgetResult
|
|||||||
SelectedCategories = string.IsNullOrEmpty(entity.SelectedCategories)
|
SelectedCategories = string.IsNullOrEmpty(entity.SelectedCategories)
|
||||||
? Array.Empty<string>()
|
? Array.Empty<string>()
|
||||||
: entity.SelectedCategories.Split(','),
|
: entity.SelectedCategories.Split(','),
|
||||||
IsStopped = entity.IsStopped,
|
|
||||||
StartDate = entity.StartDate.ToString("yyyy-MM-dd"),
|
StartDate = entity.StartDate.ToString("yyyy-MM-dd"),
|
||||||
Period = entity.Type switch
|
Period = entity.Type switch
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -60,18 +60,6 @@ export function deleteBudget(id) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 切换预算状态 (停止/恢复)
|
|
||||||
* @param {number} id 预算ID
|
|
||||||
*/
|
|
||||||
export function toggleStopBudget(id) {
|
|
||||||
return request({
|
|
||||||
url: '/Budget/ToggleStop',
|
|
||||||
method: 'post',
|
|
||||||
params: { id }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取分类统计信息(月度和年度)
|
* 获取分类统计信息(月度和年度)
|
||||||
* @param {string} category 分类 (Expense/Income/Savings)
|
* @param {string} category 分类 (Expense/Income/Savings)
|
||||||
|
|||||||
@@ -78,12 +78,6 @@
|
|||||||
plain
|
plain
|
||||||
@click.stop="$emit('click', budget)"
|
@click.stop="$emit('click', budget)"
|
||||||
/>
|
/>
|
||||||
<van-button
|
|
||||||
:icon="budget.isStopped ? 'play' : 'pause'"
|
|
||||||
size="small"
|
|
||||||
plain
|
|
||||||
@click.stop="$emit('toggle-stop', budget)"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
</slot>
|
</slot>
|
||||||
@@ -196,7 +190,7 @@ const props = defineProps({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['toggle-stop', 'switch-period', 'click'])
|
const emit = defineEmits(['switch-period', 'click'])
|
||||||
|
|
||||||
const isExpanded = ref(props.budget.category === 2)
|
const isExpanded = ref(props.budget.category === 2)
|
||||||
const transitionName = ref('slide-left')
|
const transitionName = ref('slide-left')
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
|
|
||||||
<van-form style="margin-top: 12px;">
|
<van-form style="margin-top: 12px;">
|
||||||
<van-cell-group inset>
|
<van-cell-group inset>
|
||||||
|
|
||||||
<van-cell title="记录时间" :value="formatDate(transaction.createTime)" />
|
<van-cell title="记录时间" :value="formatDate(transaction.createTime)" />
|
||||||
</van-cell-group>
|
</van-cell-group>
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,6 @@
|
|||||||
:progress-color="getProgressColor(budget)"
|
:progress-color="getProgressColor(budget)"
|
||||||
:percent-class="{ 'warning': (budget.current / budget.limit) > 0.8 }"
|
:percent-class="{ 'warning': (budget.current / budget.limit) > 0.8 }"
|
||||||
:period-label="getPeriodLabel(budget.type)"
|
:period-label="getPeriodLabel(budget.type)"
|
||||||
@toggle-stop="handleToggleStop"
|
|
||||||
@switch-period="(dir) => handleSwitchPeriod(budget, dir)"
|
@switch-period="(dir) => handleSwitchPeriod(budget, dir)"
|
||||||
@click="budgetEditRef.open({
|
@click="budgetEditRef.open({
|
||||||
data: budget,
|
data: budget,
|
||||||
@@ -86,7 +85,6 @@
|
|||||||
:progress-color="getIncomeProgressColor(budget)"
|
:progress-color="getIncomeProgressColor(budget)"
|
||||||
: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)"
|
||||||
@toggle-stop="handleToggleStop"
|
|
||||||
@switch-period="(dir) => handleSwitchPeriod(budget, dir)"
|
@switch-period="(dir) => handleSwitchPeriod(budget, dir)"
|
||||||
@click="budgetEditRef.open({
|
@click="budgetEditRef.open({
|
||||||
data: budget,
|
data: budget,
|
||||||
@@ -175,7 +173,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, onMounted, watch } from 'vue'
|
import { ref, computed, onMounted, watch } from 'vue'
|
||||||
import { showToast, showConfirmDialog } from 'vant'
|
import { showToast, showConfirmDialog } from 'vant'
|
||||||
import { getBudgetList, deleteBudget, toggleStopBudget, getBudgetStatistics, getCategoryStats } from '@/api/budget'
|
import { getBudgetList, deleteBudget, getBudgetStatistics, getCategoryStats } from '@/api/budget'
|
||||||
import { BudgetPeriodType, BudgetCategory } from '@/constants/enums'
|
import { BudgetPeriodType, BudgetCategory } from '@/constants/enums'
|
||||||
import BudgetCard from '@/components/Budget/BudgetCard.vue'
|
import BudgetCard from '@/components/Budget/BudgetCard.vue'
|
||||||
import BudgetSummary from '@/components/Budget/BudgetSummary.vue'
|
import BudgetSummary from '@/components/Budget/BudgetSummary.vue'
|
||||||
@@ -332,19 +330,6 @@ const handleDelete = (budget) => {
|
|||||||
}
|
}
|
||||||
}).catch(() => {})
|
}).catch(() => {})
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleToggleStop = async (budget) => {
|
|
||||||
try {
|
|
||||||
const res = await toggleStopBudget(budget.id)
|
|
||||||
if (res.success) {
|
|
||||||
showToast(budget.isStopped ? '已恢复' : '已停止')
|
|
||||||
fetchBudgetList()
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
showToast('操作失败')
|
|
||||||
console.error('切换预算状态失败', err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ public class BudgetController(
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
return (await budgetService.GetListAsync(referenceDate))
|
return (await budgetService.GetListAsync(referenceDate))
|
||||||
.OrderBy(b => b.IsStopped)
|
|
||||||
.OrderBy(b => b.Category)
|
.OrderBy(b => b.Category)
|
||||||
.ThenBy(b => b.Type)
|
.ThenBy(b => b.Type)
|
||||||
.ThenByDescending(b => b.Limit > 0 ? b.Current / b.Limit : 0)
|
.ThenByDescending(b => b.Limit > 0 ? b.Current / b.Limit : 0)
|
||||||
@@ -151,7 +150,6 @@ public class BudgetController(
|
|||||||
budget.Limit = dto.Limit;
|
budget.Limit = dto.Limit;
|
||||||
budget.Category = dto.Category;
|
budget.Category = dto.Category;
|
||||||
budget.SelectedCategories = dto.SelectedCategories != null ? string.Join(",", dto.SelectedCategories) : string.Empty;
|
budget.SelectedCategories = dto.SelectedCategories != null ? string.Join(",", dto.SelectedCategories) : string.Empty;
|
||||||
budget.IsStopped = dto.IsStopped;
|
|
||||||
if (dto.StartDate.HasValue)
|
if (dto.StartDate.HasValue)
|
||||||
{
|
{
|
||||||
budget.StartDate = dto.StartDate.Value;
|
budget.StartDate = dto.StartDate.Value;
|
||||||
@@ -173,33 +171,6 @@ public class BudgetController(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 切换预算暂停状态
|
|
||||||
/// </summary>
|
|
||||||
[HttpPost]
|
|
||||||
public async Task<BaseResponse> ToggleStopAsync([FromQuery] long id)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var budget = await budgetRepository.GetByIdAsync(id);
|
|
||||||
|
|
||||||
if (budget == null)
|
|
||||||
{
|
|
||||||
return "预算不存在".Fail();
|
|
||||||
}
|
|
||||||
|
|
||||||
budget.IsStopped = !budget.IsStopped;
|
|
||||||
|
|
||||||
var success = await budgetRepository.UpdateAsync(budget);
|
|
||||||
return success ? BaseResponse.Done() : "操作失败".Fail();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
logger.LogError(ex, "切换预算状态失败, Id: {Id}", id);
|
|
||||||
return $"操作失败: {ex.Message}".Fail();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 归档预算
|
/// 归档预算
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -13,6 +13,5 @@ public class CreateBudgetDto
|
|||||||
public class UpdateBudgetDto : CreateBudgetDto
|
public class UpdateBudgetDto : CreateBudgetDto
|
||||||
{
|
{
|
||||||
public long Id { get; set; }
|
public long Id { get; set; }
|
||||||
public bool IsStopped { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user