You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Ionic+Angular中实现禁用支出分类的百分比转移逻辑?

优化方案

1. 配置化管理分类与关联规则

先把所有分类的默认占比、关联关系、转移目标用配置对象统一管理,彻底告别硬编码:

// 分类配置接口
interface CategoryConfig {
  key: string; // 对应用户设置中的字段名(如'home')
  defaultPercent: number; // 默认占比(小数形式,如0.15)
  transferTarget?: string; // 禁用时的转移目标分类键
}

// 关联组配置:管理一组关联分类的全禁用拆分规则
interface RelationGroup {
  categories: string[]; // 关联的分类键集合
  splitToSavingsRatio: number; // 全禁用时,组总占比中转给储蓄的比例(如20/49≈0.408)
}

// 初始化所有分类配置
const categoryConfigs: Record<string, CategoryConfig> = {
  home: { key: 'home', defaultPercent: 0.15, transferTarget: 'shopping' },
  shopping: { key: 'shopping', defaultPercent: 0.06, transferTarget: 'home' },
  food: { key: 'food', defaultPercent: 0.28, transferTarget: 'shopping' },
  others: { key: 'others', defaultPercent: 0.05 },
  pets: { key: 'pets', defaultPercent: 0.05, transferTarget: 'others' },
  debts: { key: 'debts', defaultPercent: 0.05, transferTarget: 'others' },
  subscription: { key: 'subscription', defaultPercent: 0.04, transferTarget: 'others' },
  transportation: { key: 'transportation', defaultPercent: 0.08, transferTarget: 'others' },
  education: { key: 'education', defaultPercent: 0.05, transferTarget: 'others' },
  entertainment: { key: 'entertainment', defaultPercent: 0.05, transferTarget: 'others' },
  savings: { key: 'savings', defaultPercent: 0.10 }
};

// 初始化关联组(比如家庭、购物、餐饮为一组)
const relationGroups: RelationGroup[] = [
  { categories: ['home', 'shopping', 'food'], splitToSavingsRatio: 20 / 49 }
];

2. 编写通用计算逻辑

通过遍历配置和用户设置,自动计算各分类的建议金额,无需逐个场景写判断:

calculateSuggestedAmounts(userSettings: any, totalIncome: number): Record<string, string> {
  // 1. 初始化结果:默认使用各分类的默认占比计算金额
  const result: Record<string, string> = {};
  Object.keys(categoryConfigs).forEach(key => {
    // 生成对应属性名(如home → sumaCatHome)
    const propName = `sumaCat${key.charAt(0).toUpperCase() + key.slice(1)}`;
    result[propName] = (totalIncome * categoryConfigs[key].defaultPercent).toFixed(2);
  });

  // 2. 处理关联组的转移逻辑
  relationGroups.forEach(group => {
    const enabledCats = group.categories.filter(cat => userSettings[cat]);
    const disabledCats = group.categories.filter(cat => !userSettings[cat]);
    const totalDisabledPercent = disabledCats.reduce((sum, cat) => sum + categoryConfigs[cat].defaultPercent, 0);

    switch (enabledCats.length) {
      case 2:
        // 1个分类禁用:转移到配置的目标分类
        const disabledCat = disabledCats[0];
        const targetCat = categoryConfigs[disabledCat].transferTarget!;
        const targetProp = `sumaCat${targetCat.charAt(0).toUpperCase() + targetCat.slice(1)}`;
        result[targetProp] = (parseFloat(result[targetProp]) + totalIncome * categoryConfigs[disabledCat].defaultPercent).toFixed(2);
        break;
      case 1:
        // 2个分类禁用:全部转移到唯一启用的分类
        const soleEnabledCat = enabledCats[0];
        const soleProp = `sumaCat${soleEnabledCat.charAt(0).toUpperCase() + soleEnabledCat.slice(1)}`;
        result[soleProp] = (parseFloat(result[soleProp]) + totalIncome * totalDisabledPercent).toFixed(2);
        break;
      case 0:
        // 全禁用:拆分到储蓄和其他
        const savingsAdd = totalIncome * totalDisabledPercent * group.splitToSavingsRatio;
        const othersAdd = totalIncome * totalDisabledPercent * (1 - group.splitToSavingsRatio);
        result.sumaCatSavings = (parseFloat(result.sumaCatSavings) + savingsAdd).toFixed(2);
        result.sumaCatOthers = (parseFloat(result.sumaCatOthers) + othersAdd).toFixed(2);
        break;
    }
  });

  // 3. 处理非关联组的独立分类(禁用后默认转其他)
  const independentCats = Object.keys(categoryConfigs).filter(cat => 
    !relationGroups.some(group => group.categories.includes(cat)) && cat !== 'savings' && cat !== 'others'
  );
  independentCats.forEach(cat => {
    if (!userSettings[cat]) {
      result.sumaCatOthers = (parseFloat(result.sumaCatOthers) + totalIncome * categoryConfigs[cat].defaultPercent).toFixed(2);
    }
  });

  return result;
}

3. 调用示例

// 从数据库读取的用户设置示例
const userSettings = {
  home: false,
  shopping: true,
  food: true,
  others: true,
  pets: true,
  debts: true,
  subscription: true,
  transportation: true,
  education: true,
  entertainment: true
};

const totalIncome = 1000; // 示例总收入
const suggestedAmounts = this.calculateSuggestedAmounts(userSettings, totalIncome);
console.log(suggestedAmounts.sumaCatShopping); // 输出 "210.00"(1000*(0.06+0.15))

方案优势

  • 配置化驱动:所有规则、占比、关联关系都在配置中定义,新增或修改分类只需调整配置,无需修改逻辑代码。
  • 逻辑复用:通过遍历和计算自动覆盖所有场景,彻底消除海量重复的条件判断。
  • 扩展性强:新增关联组、调整转移规则或分类占比时,只需更新配置即可,核心逻辑无需改动。

内容的提问来源于stack exchange,提问作者Setter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 12:05:20