Actual Budget - 开源个人财务管理工具
Actual Budget
Actual Budget是一款本地优先的个人财务管理工具,采用NodeJS开发,100%免费且开源。它具有同步功能,可以在设备间无缝同步所有更改,无需复杂的配置。
功能特性
- 信封预算方法:采用经典的信封预算系统,帮助您有效管理资金
- 跨设备同步:所有更改可以在多个设备间自动同步
- 交易管理:完整的交易记录和管理功能
- 预算分析:提供详细的预算执行情况分析报表
- 多账户支持:支持管理多个银行账户和信用卡账户
- API接口:提供完整的JavaScript API用于扩展开发
- 本地优先:数据首先存储在本地,确保隐私和安全
- 多平台支持:支持Windows、Mac和Linux桌面应用
安装指南
系统要求
- Node.js版本需满足package.json中指定的引擎要求
- 支持Windows、macOS和Linux操作系统
安装方式
npm安装(API使用):
npm install @actual-app/api
桌面应用:
从官方网站下载对应平台的桌面应用
Docker部署:
# 使用官方Docker镜像
docker pull actualbudget/actual
托管部署:
- PikaPods一键部署(约1.40美元/月)
- Fly.io托管部署(约1.50美元/月)
使用说明
基本API使用
import { init, loadBudget, getBudgetMonths } from '@actual-app/api';
// 初始化应用
await init({
dataDir: '/path/to/budgets'
});
// 加载预算文件
await loadBudget('my-budget');
// 获取预算月份数据
const months = await getBudgetMonths();
console.log(months);
查询功能
import { q, aqlQuery } from '@actual-app/api';
// 构建查询
const query = q('transactions')
.select(['id', 'amount', 'date'])
.filter({ date: { $gte: '2023-01-01' } })
.orderBy([{ date: 'desc' }]);
// 执行查询
const results = await aqlQuery(query);
金额处理工具
import { amountToInteger, integerToAmount } from '@actual-app/api';
// 金额与整数的转换
const amount = 123.45;
const integer = amountToInteger(amount); // 12345
const convertedBack = integerToAmount(integer); // 123.45
核心代码
API初始化模块
// index.ts - 核心初始化逻辑
import { validateNodeVersion } from './validateNodeVersion';
let actualApp: null | typeof bundle.lib;
export async function init(config: InitConfig = {}) {
if (actualApp) {
return;
}
validateNodeVersion();
if (!globalThis.fetch) {
globalThis.fetch = (url: URL | RequestInfo, init?: RequestInit) => {
return import('node-fetch').then(({ default: fetch }) =>
fetch(url as unknown as FetchInfo, init as unknown as FetchInit),
) as unknown as Promise<Response>;
};
}
await bundle.init(config);
actualApp = bundle.lib;
injected.override(bundle.lib.send);
return bundle.lib;
}
查询构建器
// query.js - 强大的查询构建器
class Query {
constructor(state) {
this.state = {
filterExpressions: state.filterExpressions || [],
selectExpressions: state.selectExpressions || [],
groupExpressions: state.groupExpressions || [],
orderExpressions: state.orderExpressions || [],
calculation: false,
rawMode: false,
withDead: false,
validateRefs: true,
limit: null,
offset: null,
...state,
};
}
filter(expr) {
return new Query({
...this.state,
filterExpressions: [...this.state.filterExpressions, expr],
});
}
select(exprs = []) {
if (!Array.isArray(exprs)) {
exprs = [exprs];
}
const query = new Query({ ...this.state, selectExpressions: exprs });
query.state.calculation = false;
return query;
}
}
export function q(table) {
return new Query({ table });
}
版本管理工具
// get-next-package-version.js - 智能版本管理
export function getNextVersion({
currentVersion,
type,
currentDate = new Date(),
}) {
const { versionYear, versionMonth, versionHotfix } =
parseVersion(currentVersion);
const { nextVersionYear, nextVersionMonth } = computeNextMonth(
versionYear,
versionMonth,
);
const resolvedType = resolveType(
type,
currentDate,
versionYear,
versionMonth,
);
const currentDateString = currentDate
.toISOString()
.split('T')[0]
.replaceAll('-', '');
switch (resolvedType) {
case 'nightly':
return `${nextVersionYear}.${nextVersionMonth}.0-nightly.${currentDateString}`;
case 'hotfix':
return `${versionYear}.${versionMonth}.${versionHotfix + 1}`;
case 'monthly':
return `${nextVersionYear}.${nextVersionMonth}.0`;
default:
throw new Error(
'Invalid type specified. Use "auto", "nightly", "hotfix", or "monthly".',
);
}
}
UI组件库
// Button组件 - 统一的按钮设计
export function Button({
variant = 'normal',
isDisabled = false,
children,
...props
}) {
const variantStyle = {
normal: {
backgroundColor: theme.buttonNormalBackground,
color: theme.buttonNormalText,
borderColor: theme.buttonNormalBorder,
},
primary: {
backgroundColor: theme.buttonPrimaryBackground,
color: theme.buttonPrimaryText,
borderColor: theme.buttonPrimaryBorder,
},
bare: {
backgroundColor: 'transparent',
color: theme.buttonBareText,
border: 'none',
}
};
return (
<button
disabled={isDisabled}
style={variantStyle[variant]}
{...props}
>
{children}
</button>
);
}
Actual Budget提供了完整的个人财务管理解决方案,从核心的预算引擎到用户友好的界面组件,都体现了其专业性和易用性。无论是个人使用还是开发扩展,都能满足各种需求。
更多精彩内容 请关注我的个人公众号 公众号(办公AI智能小助手)
公众号二维码