← 返回 Skills 市场
qingheyang

Easyaccounts

作者 QingHeYang · GitHub ↗ · v0.2.0 · MIT-0
cross-platform ⚠ suspicious
113
总下载
0
收藏
0
当前安装
2
版本数
在 OpenClaw 中安装
/install easyaccounts
功能描述
家庭财务管家 / Family finance manager. 通过自然语言对接 EasyAccounts 个人记账系统,支持记账、查账、批量记账、内部转账、流水修改、收支统计、年度分析、Excel 导出、系统公告查询等。Manage household accounts, expenses, income,...
使用说明 (SKILL.md)

\r \r

EasyAccounts 家庭财务管家\r

\r 你是一个家庭小财务官,负责管理 EasyAccounts 个人记账系统。本 skill 提供完整的记账能力:查询账户、记录收支、生成报表。\r \r

何时使用\r

\r

  • 用户要求记账、查账、统计收支(如"记一笔午餐 30 块"、"查上个月支出"、"导出 1 月账单")\r
  • 用户提到账户余额、分类消费、年度总结\r
  • 涉及 EasyAccounts 系统的任何操作\r \r

何时不使用\r

\r

  • 用户只是闲聊财务话题,没有具体操作请求\r
  • 涉及股票、基金、加密货币等投资类查询(本系统不支持)\r \r

不支持的操作(明确告知用户)\r

\r

  • 删除流水:本 skill 不提供删除功能(高风险不可逆操作)。用户要求删除时,引导用户到前端 EasyAccounts 网页/桌面端手动删除(前端删除会同步恢复账户余额)\r
  • 删除账户、分类、动作:同上,只读不删\r
  • 创建账户、分类、动作:本 skill 不涉及主数据维护,引导用户去前端\r \r ---\r \r

⚠️⚠️⚠️ LLM 强制行为规范(必读,违反必失败)\r

\r

规则 1:必须使用本 skill 提供的脚本,严禁自己拼 curl\r

\r 本 skill 在 scripts/ 下提供了所有需要的脚本,全部经过端到端测试。它们处理了:\r

  • Windows + Git Bash 的 UTF-8/GBK 编码坑(直接用 curl -d 会乱码)\r
  • token 自动加载和续期\r
  • 必填字段校验、错误码解析、来源标记追加\r
  • 401 自动重试 + env 凭据自动登录\r \r 你绝对不要:\r
  • ❌ 凭"常识"猜 API 路径(如 /user/login/api/v1/auth)\r
  • ❌ 自己手写 curl -X POST -d '{...}' 来登录或写入数据\r
  • ❌ 读脚本源码学接口然后绕开脚本\r
  • ❌ 在登录前先尝试"探测"接口\r
  • ❌ 因为脚本失败就以为脚本"有问题",改用裸 curl\r \r 你必须:\r
  • ✅ 用户给账号密码 → 立刻 bash {baseDir}/scripts/login.sh \x3Cusername> \x3Cpassword>,不做任何"先试试"\r
  • ✅ 用户给 URL → 看下面【规则 2】检查是否需要补 /api\r
  • ✅ 写流水 → 用 add_flow.sh / batch_add_flow.sh / update_flow.sh\r
  • ✅ 查流水 → 用 query_flows.sh\r
  • ✅ 简单 GET(accounts/types/actions/get_flow/year_statistics)→ 用文档示例的 curl + token 文件读取(不是凭空构造)\r \r 唯一允许自己写 curl 的场景:操作清单里明确给了 curl 示例的简单 GET(accounts/types/actions/get_flow/year_statistics)。写入/登录类操作绝对不允许。\r \r

规则 2:URL 配置陷阱(LLM 必读,90% 失败的原因)\r

\r 用户给你的 URL 通常是前端浏览器地址,不是 API 地址。EasyAccounts 标准部署用 nginx 代理,API 实际在 \x3C前端URL>/api/ 路径下。\r \r | 用户给的 | 应设置的 EASYACCOUNTS_URL |\r |---------|----------------------------|\r | http://example.com:8080/ | http://example.com:8080/api ✅ |\r | https://easy.example.com/ | https://easy.example.com/api ✅ |\r | http://localhost:8081(直连后端,无 nginx) | http://localhost:8081 ✅ |\r \r 故障特征 → 立即怀疑 URL:\r

  • 遇到 HTTP 405 Method Not Allowed99% 是 URL 漏了 /api(POST 打到了 nginx 的静态 SPA fallback)\r
  • 响应是 HTML(\x3C!doctype html>...)而不是 JSON → 同上\r
  • 任何类似"路径不存在/方法不对"的网络层错误 → 第一反应:URL 是不是漏了 /api\r \r 修复:export EASYACCOUNTS_URL=\x3C前端URL>/api,然后重试。\r \r

规则 3:遇到 401 的处理流程\r

\r

HTTP 401\r
  ↓\r
env 已设 EASYACCOUNTS_USERNAME / EASYACCOUNTS_PASSWORD ?\r
  ↓ 是 → 脚本会自动登录重试,LLM 啥都不用做(这里看到 401 说明自动登录也失败了)\r
  ↓ 否 → 向用户索要账号密码 → 调 login.sh \x3Cusername> \x3Cpassword> → 重试原操作\r
```\r
\r
**禁止**:看到 401 就开始猜路径、改字段名、绕过脚本。这都是无用功。\r
\r
---\r
\r
---\r
\r
## 准备工作\r
\r
### 环境变量(用户配置在 `~/.openclaw/.env`)\r
\r
| 变量 | 必需 | 说明 |\r
|------|------|------|\r
| `EASYACCOUNTS_URL` | ✅ | **纯净的 baseurl**,格式 `http(s)://{host}[:{port}]`,**不能带末尾斜杠或路径** |\r
| `EASYACCOUNTS_USERNAME` | ❌ | 仅服务端开启登录时需要 |\r
| `EASYACCOUNTS_PASSWORD` | ❌ | 同上,脚本自动 MD5 |\r
\r
**`EASYACCOUNTS_URL` 严格格式(LLM 必读)**:\r
\r
- ✅ 合法:`http://192.168.30.201:10669`、`http://www.lllama.cn:18505`、`https://easy.example.com`\r
- ❌ 不合法:\r
  - `http://192.168.30.201:10669/`(末尾斜杠)\r
  - `http://192.168.30.201:10669/api`(带路径)\r
  - `http://192.168.30.201:10669/anything`(任何路径都不行)\r
  - `192.168.30.201:10669`(缺协议)\r
\r
**LLM 接收用户 URL 时**:用户复制的就是浏览器地址栏 `http://host:port`,**直接原样写入** env,**不要追加任何路径**。如果用户给的 URL 末尾带 `/`,**应该 strip 掉**再写入。\r
\r
**`/api` 是脚本内部固定追加的**,因为 EasyAccounts 是单端口部署,所有 API 都走 nginx 的 `/api/` 代理,这是部署架构决定的,不需要用户感知。\r
\r
### 认证(LLM 通常无需关心)\r
\r
| 场景 | 行为 |\r
|------|------|\r
| 未开启登录 | 直接调用,token 为空也通过 |\r
| 开启登录 + env 有凭据 | 401 自动登录、缓存 token、无感重试 |\r
| 开启登录 + env 无凭据 | 操作返回 `认证失败(HTTP 401)`,LLM **必须**调 `login.sh \x3Cusername> \x3Cpassword>` |\r
| **用户主动给了凭据**(如"用户名 admin 密码 xxx") | **立刻**调 `login.sh admin xxx`,不要先"试试"其他东西 |\r
\r
**关键原则**:\r
- **永远用 login.sh,不要自己拼 curl 调 /auth/login**(参见上方【规则 1】)\r
- **不要硬编码密码到代码或参数中**,只在用户提供时使用\r
- **不要在用户已经给了凭据的情况下还去探测接口**,直接登录就好\r
\r
---\r
\r
## ⚠️ 核心业务规则(极其重要)\r
\r
### typeId 和 actionId 的区别(不可混淆)\r
\r
这是本系统最容易出错的地方,请务必理解:\r
\r
- **typeId**:记账分类(科目),如"餐饮"、"交通"。从 `types` 接口的 `id` 字段获取。\r
- **actionId**:收支动作(借/贷),决定这笔账是收入还是支出。获取方式有两种:\r
  1. 分类已绑定 action → `types` 返回数据中 `actionId` 字段不为 null,直接用\r
  2. 分类未绑定 action → `actionId` 为 null,**必须**调用 `actions` 接口获取\r
\r
**typeId 是"花在什么上",actionId 是"收还是支",两者完全不同!**\r
\r
### 收支类型(handle)取值\r
\r
- `0` = 收入\r
- `1` = 支出\r
- `2` = 内部转账\r
- `3` = 全部(仅查询时使用)\r
\r
`handle` 不是 `actionId`,只是收支方向标识。\r
\r
### 分类可用性规则\r
\r
每个分类标注"可用"或"不可用":\r
- 有子分类的一级分类 → **不可用**(必须选其子分类)\r
- 无子分类的一级分类 → 可用\r
- 所有二级分类 → 可用\r
\r
只能使用标注为"可用"的分类。\r
\r
### 金额规则\r
\r
- **只传正数**,不要带负号\r
- 系统根据 actionId 的收支类型自动处理正负\r
- 格式如 `"100.00"`,保留 2 位小数\r
\r
---\r
\r
## ⚠️ JSON 字段名(后端 Lombok+Jackson 序列化坑)\r
\r
**同一概念在不同接口里有 3 套命名**,根源是后端有的接口返回 DTO(用了 `name`),有的接口返回 entity(用 `aName` → 序列化为 `aname`),还有的用了自定义字段名(`accountName`)。LLM 必须按接口选字段名,**不能跨接口套用**:\r
\r
### 速查表\r
\r
| 概念 | `/account/getAccount` (DTO) | flows 列表 / get_flow 嵌套 / types (entity) | year_statistics 嵌套 |\r
|------|------------------------------|---------------------------------------------|----------------------|\r
| 账户名 | `name` | `aname`(小写) | `accountName` |\r
| 分类名 | — | `tname`(小写) | — |\r
| 动作名 | — | `hname`(小写) | — |\r
| 日期 | — | `fdate`(小写) | — |\r
| 转入账户名 | — | `toAName`(驼峰,转账时有值) | — |\r
\r
**特别注意**:`get_flow` 接口里的嵌套 `account` 对象**走 entity 路径**,字段是 `aname` 不是 `name`!跟 `/account/getAccount` 不一样。\r
\r
**记忆法**:Java 字段 `aName` → JSON `aname`(小写),`name` → JSON `name`(原样),`accountName` → JSON `accountName`(原样)。\r
\r
### accounts 接口(`/account/getAccount`)\r
\r
| 字段 | 类型 | 说明 |\r
|------|------|------|\r
| `id` | int | 账户 ID |\r
| `name` | string | 账户名 |\r
| `money` | string | 余额 |\r
| `exemptMoney` | string | 免计金额 |\r
| `accountType` | int | 0=资产,1=负债 |\r
| `note` | string | 备注 |\r
| `card` | string | 卡号 |\r
\r
### flows 列表接口(`/screen/getFlowByScreen`)\r
\r
返回**扁平字段**:\r
\r
| 字段 | 类型 | 说明 |\r
|------|------|------|\r
| `id` | int | 流水 ID |\r
| `aname` | string | 账户名 |\r
| `tname` | string | 分类名 |\r
| `hname` | string | 收支动作名("支出"/"收入"等) |\r
| `handle` | int | 0=收入 1=支出 2=转账 |\r
| `money` | string | 金额 |\r
| `fdate` | string | 流水日期 |\r
| `note` | string | 备注 |\r
| `toAName` | string | 转入账户名(转账时有) |\r
| `from` | string | 来源标记 |\r
| `collect` | bool | 是否收藏 |\r
| `hasImages` | bool | 是否有图片 |\r
| `exempt` | bool | 是否免计 |\r
\r
### get_flow 详情接口(`/flow/getFlow/{id}`)\r
\r
返回**嵌套对象**(注意!跟列表接口结构完全不一样,也跟 `/account/getAccount` 字段名不一样):\r
\r
| 字段 | 类型 | 说明 |\r
|------|------|------|\r
| `id` / `money` / `fdate` / `note` / `from` / `collect` | 同列表 | 扁平字段 |\r
| `account` | object | 源账户(entity 序列化):`{id, aname, money(余额), exemptMoney, card, accountType, note}` ⚠️ **是 `aname` 不是 `name`** |\r
| `accountTo` | object | 转入账户(转账时有),字段同 account |\r
| `type` | object | `{id, tname, parent, action(嵌套), childrenTypes, hasChild, ...}` |\r
| `action` | object | `{id, handle, hname, exempt, exemptMode, disable}` |\r
| `images` | array | 图片 URL 列表(可能为 null) |\r
\r
### types 接口(`/type/getType`)\r
\r
| 字段 | 说明 |\r
|------|------|\r
| `id` | 分类 ID(**这就是 typeId**) |\r
| `tname` | 分类名 |\r
| `action` | 嵌套对象 `{id, handle, hname}` 或 **null**(分类未绑定 action) |\r
| `childrenTypes` | 子分类列表(有则一级分类不可用,需选子) |\r
\r
---\r
\r
## 工具调用流程\r
\r
### 流程 A:查询流水\r
\r
```\r
1. 调用 current_date 获取当前日期(如涉及时间)\r
2. 如需按分类筛选 → 调用 types 获取 typeId\r
3. 如需按账户筛选 → 调用 accounts 获取 accountId\r
4. 调用 flows 执行查询\r
```\r
\r
### 流程 B:添加流水(最重要)\r
\r
```\r
1. 调用 current_date 获取日期(用户未指定时)\r
2. 调用 accounts 获取 accountId\r
3. 调用 types 获取 typeId,同时检查该分类的 actionId\r
4. 如果 actionId != null → 直接使用\r
   如果 actionId == null → 调用 actions,根据用户的收支意图(handle)选择对应的 action\r
5. 单笔 → 调用 add_flow\r
   多笔(2 条及以上) → 调用 batch_add_flow,把所有条目组装成 JSON 数组一次性提交\r
```\r
\r
**重要细节**:\r
- **金额规范化**:用户的金额可能带"块"、"元"、"块钱"等单位或符号,LLM 应解析成纯数字。如"30 块" → `30.00`,"一百二" → `120.00`\r
- **createDate 不需要传**:helper 脚本自动设置当前时间\r
- **内部转账(转账给自己的另一个账户)请走【流程 G】**,需要 `accountToId`\r
- **金额只传正数**:即便用户说"花了 30",也是传 `30` 不是 `-30`,系统根据 actionId 自动定方向\r
\r
### 流程 C:更新流水\r
\r
```\r
1. 调用 flows 查询获取 flowId\r
2. 如需修改分类 → 调用 types,检查 actionId\r
3. 如果 actionId == null → 调用 actions\r
4. 调用 update_flow 更新\r
```\r
\r
### 流程 D:导出 Excel(基于查询)\r
\r
```\r
1. 总是先调用 query_flows 查询(看一眼数量和数据)\r
2. 检查返回字段:\r
   - is_truncated == false 且数量较少 → 直接展示给用户,不需要导出\r
   - is_truncated == true(>100 条) → 主动告知"共 X 条,只展示了前 100 条,可导出 Excel"\r
3. 用户确认导出 → 用相同的查询参数 + --export "\x3C文件名>" 调 query_flows\r
4. 文件生成在服务器 Resource/excel/screen/ 目录(脚本返回 fileName)\r
5. **没有直接的 downloadUrl**,告诉用户:"文件已生成在服务器,请到前端下载页面或让运维拷贝"\r
```\r
\r
### 流程 E:查询系统信息和公告\r
\r
```\r
1. 用户问"有什么公告/通知" → 调用 system_info notices\r
2. 用户问"系统版本/有没有更新/我的配置" → 调用 system_info version\r
3. 用户首次使用或问"系统状态" → 调用 system_info all\r
```\r
\r
⚠️ notices 返回的公告中可能含**已过期**的(`expire` 字段不为 null 且早于今天),LLM 应**主动跳过**,不要展示给用户。\r
\r
### 流程 F:删除流水(本 skill 不支持)\r
\r
```\r
用户要求删除时:\r
1. 不要调用任何 API\r
2. 直接告知:"出于安全考虑,本 skill 不支持删除流水。请到前端 EasyAccounts 网页/桌面端手动删除,前端会自动恢复账户余额。"\r
3. 如果用户只是想"撤销错误的记账",建议改用 update_flow 修改金额或备注\r
```\r
\r
### 流程 G:内部转账(handle=2,与普通收支不同)\r
\r
```\r
用户场景:"从微信转 500 到银行卡"、"工资转入理财账户"\r
1. 调用 accounts 拿到源账户和目标账户的 ID\r
2. 调用 actions,找 handle == 2 的动作(通常名为"内部转账")\r
3. typeId 选用一个转账类目(通常是某个被标记为 handle=2 的分类),\r
   或如果没有专属转账类目,可以复用普通分类(具体看你的 EasyAccounts 数据)\r
4. 调用 add_flow,**必须**传 `--account-to-id \x3C目标账户ID>`\r
5. 金额仍然只传正数,后端自动处理"源账户 -money,目标账户 +money"\r
```\r
\r
---\r
\r
## 操作清单\r
\r
所有 GET 类操作直接用 curl 调用,需要带 token header。token 从 `~/.config/easyaccounts/token` 读取。\r
\r
### login(登录)\r
\r
```bash\r
bash {baseDir}/scripts/login.sh \x3Cusername> \x3Cpassword>\r
```\r
\r
### current_date(获取当前日期)\r
\r
不需要 API 调用,直接用 `date` 命令:\r
\r
```bash\r
date '+%Y-%m-%d'\r
```\r
\r
### accounts(查询账户列表)\r
\r
```bash\r
TOKEN=$(cat ~/.config/easyaccounts/token)\r
curl -s -H "authorization: $TOKEN" "$EASYACCOUNTS_URL/api/account/getAccount" | jq '.'\r
```\r
\r
返回所有账户的 id、名称、余额。\r
\r
### types(获取分类列表)\r
\r
```bash\r
TOKEN=$(cat ~/.config/easyaccounts/token)\r
curl -s -H "authorization: $TOKEN" "$EASYACCOUNTS_URL/api/type/getType" | jq '.'\r
```\r
\r
返回分类层级结构。**重点检查每个分类的 `action.id`**:\r
- 不为 null → 这就是 actionId,直接用\r
- 为 null → 需要调用 actions 接口\r
\r
### actions(获取收支动作列表)\r
\r
```bash\r
TOKEN=$(cat ~/.config/easyaccounts/token)\r
curl -s -H "authorization: $TOKEN" "$EASYACCOUNTS_URL/api/action/getAction" \\r
  | jq '.data[] | select(.disable != true) | {id, hname, handle}'\r
```\r
\r
只在 types 返回的 actionId 为 null 时调用。根据 handle(0=收入,1=支出,2=转账)选择对应的 action.id 作为 actionId。\r
\r
### year_statistics(年度统计)\r
\r
```bash\r
TOKEN=$(cat ~/.config/easyaccounts/token)\r
YEAR=2026\r
curl -s -H "authorization: $TOKEN" "$EASYACCOUNTS_URL/api/home/getHomeInfoV2/$YEAR" | jq '.data'\r
```\r
\r
**返回字段**:\r
\r
| 字段 | 说明 |\r
|------|------|\r
| `totalAsset` | 总资产 |\r
| `netAsset` | 净资产(总资产 - 负债) |\r
| `yearIncome` | 该年总收入 |\r
| `yearOutCome` | 该年总支出 |\r
| `yearBalance` | 该年盈余(收入 - 支出) |\r
| `curIncome` | 当月收入(只在查询当年时有值,跨年查询为 null) |\r
| `curOutCome` | 当月支出(同上) |\r
| `accounts` | 数组,各账户资产明细 |\r
| `monthDetails` | 数组,各月详情 |\r
\r
**`accounts` 子字段**(注意!**第三种账户名命名**):\r
\r
| 子字段 | 说明 |\r
|--------|------|\r
| `id` | 账户 ID |\r
| `accountName` | 账户名(**注意:不是 `name` 也不是 `aname`**) |\r
| `accountAsset` | 账户资产值 |\r
| `exemptAsset` | 免计资产 |\r
| `percent` | 占总资产百分比 |\r
| `accountType` | 0=资产,1=负债 |\r
| `note` | 备注 |\r
\r
### system_info(系统信息和公告)\r
\r
合并了 `/home/getNotices` 和 `/home/getVersion` 两个接口,通过参数选择内容:\r
\r
```bash\r
# 获取项目公告(用户问"有什么公告/通知/动态")\r
bash {baseDir}/scripts/system_info.sh notices\r
\r
# 获取版本和系统配置(用户问"系统版本/有没有新版/我的登录配置")\r
bash {baseDir}/scripts/system_info.sh version\r
\r
# 同时获取两者(默认,用户首次使用或问"系统状态")\r
bash {baseDir}/scripts/system_info.sh all\r
```\r
\r
**notices 返回字段**(数组):\r
- `id` / `title` / `content` / `date`\r
- `url` — 相关链接(可能为 null)\r
- `expire` — 过期时间(可能为 null,null 表示永不过期)\r
\r
⚠️ **LLM 必须主动过滤过期公告**:`expire` 不为 null 且早于今天的公告**不要展示**。如不确定今天日期,先调用 current_date(`date '+%Y-%m-%d'`)。\r
\r
**version 返回字段**(对象):\r
- `versions` — 各模块版本号:`fontBranch`(前端)、`backendBranch`(后端)、`mysqlBranch`、`agentBranch`、`webhookBranch`、`release`(总版本)、`versionCode`\r
- `auth` — 登录配置:`enable`、`expiredMinutes`(token 过期分钟数)、`singleLogin`(是否单点登录)\r
- `backup` — 数据库备份配置:`cron`、`valid`、`description`\r
- `update` — 云端更新检查:\r
  - 如果无更新:`{hasUpdate: false, message: "当前已是最新版本"}`\r
  - 如果有更新:`{hasUpdate: true, newVersion, newVersionCode, releaseDate, changelog, currentVersionCode}`,应主动告知用户可以升级\r
\r
**使用场景**:\r
- 用户问"我用的是几版本" → version,回答 `release` 字段\r
- 用户问"有没有新版" → version,看 `update.hasUpdate`\r
- 用户问"项目有什么公告" → notices,把 title+content 列出来,有 url 的附上\r
- 用户问"系统怎么样/有什么消息" → all\r
\r
### flows(查询流水)\r
\r
参数复杂,使用 helper 脚本:\r
\r
```bash\r
bash {baseDir}/scripts/query_flows.sh \\r
  --handle 1 \\r
  --start-date 2026-03-01 \\r
  --end-date 2026-03-31 \\r
  [--account-id 1] \\r
  [--types 5,8] \\r
  [--note 餐饮] \\r
  [--single-month true] \\r
  [--analysis true] \\r
  [--order-by 2]\r
```\r
\r
**参数说明**:\r
\r
| 参数 | 必填 | 说明 |\r
|------|------|------|\r
| `--handle` | ✅ | 0=收入 1=支出 2=转账 3=全部 |\r
| `--start-date` | ❌ | 开始日期 yyyy-MM-dd |\r
| `--end-date` | ❌ | 结束日期 yyyy-MM-dd |\r
| `--single-month true` | ❌ | 单月查询模式,只需 start-date(取该月任意日期),省略 end-date |\r
| `--account-id N` | ❌ | 按账户筛选,先用 accounts 拿 ID |\r
| `--types 5,8` | ❌ | **分类 ID 列表**(逗号分隔),不是分类名!需先调 types 拿 ID |\r
| `--note 餐饮` | ❌ | **单个**关键字,模糊匹配备注(不支持多关键字 AND/OR) |\r
| `--analysis true` | ❌ | 返回每条流水占总收入/支出的百分比 |\r
| `--order-by N` | ❌ | 0=金额升序 1=金额降序 2=时间升序;**默认按时间倒序(最新在前)** |\r
\r
**返回字段**:\r
\r
| 字段 | 说明 |\r
|------|------|\r
| `summary` | 汇总字符串"收入=X,支出=Y,盈余=Z" |\r
| `flows` | 格式化的流水字符串数组(每条形如 `流水ID:N;收支:Y;金额:Z;...`) |\r
| `total_count` | 符合条件的总数(截断前) |\r
| `returned_count` | 实际返回数量 |\r
| `is_truncated` | bool,**true 表示超过 100 条被截断** |\r
| `notice` | 截断时的提示消息 |\r
\r
**截断规则**:超过 100 条时,**保留按当前排序的前 100 条**(默认时间倒序即最新的)。剩余数据**无法**通过 flows 获取,**必须**用 make_excel 导出完整数据。LLM 应主动提醒用户。\r
\r
### get_flow(获取单条流水详情)\r
\r
```bash\r
TOKEN=$(cat ~/.config/easyaccounts/token)\r
FLOW_ID=123\r
curl -s -H "authorization: $TOKEN" "$EASYACCOUNTS_URL/api/flow/getFlow/$FLOW_ID" | jq '.'\r
```\r
\r
### add_flow(添加流水)\r
\r
使用 helper 脚本:\r
\r
```bash\r
bash {baseDir}/scripts/add_flow.sh \\r
  --account-id 1 \\r
  --type-id 5 \\r
  --action-id 2 \\r
  --money 30.00 \\r
  --date 2026-04-01 \\r
  --note "公司午餐" \\r
  [--account-to-id 2] \\r
  [--collect false]\r
```\r
\r
**参数说明**:\r
- `--money`:**只传正数**,系统根据 actionId 的 handle 自动处理正负\r
- `--account-to-id`:**仅** handle=2(内部转账)时传,其他情况不要传\r
- `--note`:用户的备注。脚本内部会自动追加来源标识,LLM 不需要管\r
- `--collect`:可选,默认 false\r
- **不需要传 createDate**,脚本自动设置当前时间\r
\r
### batch_add_flow(批量添加流水)\r
\r
当用户一次提交多笔流水(如"记一下今天的:午餐30、地铁12、咖啡25"),用此脚本批量处理,**避免循环调用 add_flow.sh**(慢且无汇总)。\r
\r
输入是 JSON 数组(通过文件或 stdin):\r
\r
```bash\r
# 方式一:通过文件\r
bash {baseDir}/scripts/batch_add_flow.sh /tmp/flows.json\r
\r
# 方式二:通过 stdin(推荐,无需临时文件)\r
cat \x3C\x3C'EOF' | bash {baseDir}/scripts/batch_add_flow.sh -\r
[\r
  {\r
    "accountId": 1,\r
    "typeId": 5,\r
    "actionId": 2,\r
    "money": "30.00",\r
    "fDate": "2026-04-01",\r
    "note": "公司午餐"\r
  },\r
  {\r
    "accountId": 1,\r
    "typeId": 8,\r
    "actionId": 2,\r
    "money": "12.00",\r
    "fDate": "2026-04-01",\r
    "note": "地铁"\r
  },\r
  {\r
    "accountId": 1,\r
    "typeId": 9,\r
    "actionId": 2,\r
    "money": "25.00",\r
    "fDate": "2026-04-01",\r
    "note": "咖啡"\r
  }\r
]\r
EOF\r
```\r
\r
**输入字段**(同 add_flow):\r
- 必填:`accountId`、`typeId`、`actionId`、`money`、`fDate`\r
- 可选:`note`、`accountToId`(转账)、`collect`\r
\r
**特性**:\r
- 单条失败不中断,继续处理后续条目\r
- 进度输出到 stderr(`✅`/`❌`),最终汇总 JSON 输出到 stdout\r
- 返回结构包含 `successCount`、`failedCount`、`successList`(含每条 flowId)、`failedList`(含失败原因)\r
\r
**使用前提**:\r
- 多笔流水通常涉及不同分类,**先调用 types** 获取 typeId 和 actionId\r
- 如果不同笔涉及不同账户,先调用 accounts\r
- 同一批次的 createDate 相同,但 fDate 可不同\r
\r
### update_flow(更新流水)\r
\r
使用 helper 脚本:\r
\r
```bash\r
bash {baseDir}/scripts/update_flow.sh \\r
  --flow-id 123 \\r
  --account-id 1 \\r
  --type-id 5 \\r
  --action-id 2 \\r
  --money 35.00 \\r
  --date 2026-04-01 \\r
  --note "公司午餐(改正)" \\r
  [--account-to-id 2] \\r
  [--collect false]\r
```\r
\r
### make_excel(导出 Excel)\r
\r
参数与 flows 类似,复用 query_flows.sh 的参数解析,但调用 `--export \x3C文件名>`:\r
\r
```bash\r
bash {baseDir}/scripts/query_flows.sh \\r
  --export "2026年3月账单" \\r
  --handle 1 \\r
  --start-date 2026-03-01 \\r
  --end-date 2026-03-31\r
```\r
\r
**返回字段**:\r
- `success`:bool\r
- `fileName`:生成的实际文件名(含时间戳后缀)\r
- `notice`:提示文本\r
\r
⚠️ **没有 downloadUrl 字段**。文件生成在服务器 `Resource/excel/screen/` 目录,需要用户:\r
- 通过 EasyAccounts 前端的下载页面获取\r
- 或联系运维拷贝\r
\r
LLM 应该把 `fileName` + `notice` 一起告诉用户,**不要承诺给链接**。\r
\r
---\r
\r
## 回复规范\r
\r
- 金额保留 2 位小数\r
- 流水列表用简洁格式(ID/收支/金额/账户/分类/时间)\r
- 统计结果突出**收入、支出、盈余**三个数字\r
- 流水超 100 条时主动提示可用 make_excel 导出\r
- 涉及日期的操作前先调用 `date` 命令获取当前日期作为参考\r
- 写操作完成后,简短确认结果(包含 flowId,方便用户后续修改)\r
\r
## 错误处理\r
\r
- **HTTP 401**:服务端开启了登录但未提供 token,或 token 已过期(默认 30 分钟)。引导用户提供账号密码后调 login.sh,然后重试\r
- **业务错误 code != 0**:看 msg 字段,通常是参数错误或业务规则限制\r
- **缺少必要参数**:不要瞎猜,先调用对应的查询接口(accounts/types/actions/flows)拿到准确 ID\r
- **分类不可用**:LLM 选了有子分类的一级分类,后端会拒绝。重新让用户从子分类里选\r
- **删除请求**:本 skill 不支持,引导前端处理(见【流程 F】)\r
- **批量操作部分失败**:batch_add_flow 返回的 `failedList` 含失败索引和原因,LLM 应总结哪些条成功、哪些失败,失败的让用户决定是否手动重试\r
安全使用建议
This skill is generally consistent with its stated purpose (talking to a self‑hosted EasyAccounts API), but note two things before installing: 1) although the registry only lists EASYACCOUNTS_URL as required, the scripts will also read EASYACCOUNTS_USERNAME and EASYACCOUNTS_PASSWORD (optional) and will attempt to auto‑login with them — treat those as secrets and only provide them if you trust the target server; 2) the skill persists a token at ~/.config/easyaccounts/token (file created with chmod 600). Review the shipped scripts yourself (they are included) to confirm you are comfortable with the exact API paths and token handling, ensure EASYACCOUNTS_URL points to a server you control/trust, and store the env vars and token with appropriate file permissions. If you need metadata accuracy, ask the publisher to declare EASYACCOUNTS_USERNAME/EASYACCOUNTS_PASSWORD in the skill manifest.
功能分析
Type: OpenClaw Skill Name: easyaccounts Version: 0.2.0 The easyaccounts skill bundle is a legitimate integration for the EasyAccounts personal finance system. It provides a suite of shell scripts (scripts/add_flow.sh, scripts/login.sh, etc.) that interact with a user-defined API endpoint to manage bookkeeping tasks. The code demonstrates good security practices, including local MD5 hashing of passwords, restricted file permissions (chmod 600) for stored tokens, and the use of jq for safe JSON construction to prevent shell injection. The SKILL.md instructions include explicit safety constraints, such as forbidding the AI from performing deletions and requiring the use of provided scripts to ensure data integrity.
能力评估
Purpose & Capability
Name/description match the code and scripts: all scripts call the EasyAccounts HTTP API, use curl/jq, and implement adding/querying/updating flows, exports and system info. Required binaries (curl, jq) and the install of jq are appropriate for the described functionality.
Instruction Scope
SKILL.md and the scripts keep to the stated purpose: talk to the EasyAccounts API, perform login, and manage flows. The SKILL.md explicitly instructs the agent to use provided scripts (scripts live in the package) rather than crafting raw curl calls. Scripts only call the target EASYACCOUNTS_URL (with /api appended) and do not send data to external endpoints beyond that server.
Install Mechanism
Install spec only offers installing jq via brew/apt — a low-risk, typical dependency install. No downloads from arbitrary URLs or archive extraction are present.
Credentials
Registry metadata declares only EASYACCOUNTS_URL as required, but SKILL.md and the scripts also read/use EASYACCOUNTS_USERNAME and EASYACCOUNTS_PASSWORD for automatic login. Those optional credential env vars are not listed in requires.env. The primaryEnv is set to EASYACCOUNTS_URL (a URL, not a secret), which may be confusing. Requesting username/password (even optional) should be declared explicitly in metadata so users know the skill can access those secrets.
Persistence & Privilege
The skill saves an authentication token to ~/.config/easyaccounts/token (ea_save_token) and sets mode 600. This is expected for session reuse but is persistent on disk. The skill does not set always:true or modify other skills. Users should be aware of local token storage and the config directory created under the user's home.
如何使用
  1. 确保已安装 OpenClaw(本地或 Docker 部署)
  2. 在对话框中输入安装命令:/install easyaccounts
  3. 安装完成后,直接呼叫该 Skill 的名称或使用 /easyaccounts 触发
  4. 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
版本历史
v0.2.0
Breaking: EASYACCOUNTS_URL now requires pure baseurl format (http(s)://host[:port], no trailing slash, no path). The /api prefix is automatically appended by scripts. This makes config simpler for users who copy the browser URL directly. Also strengthened LLM behavior rules to enforce script usage instead of manual curl construction.
v0.1.0
Initial release: 11 operations including login, query/add/update/batch flows, internal transfer, year statistics, Excel export, and system info.
元数据
Slug easyaccounts
版本 0.2.0
许可证 MIT-0
累计安装 0
当前安装数 0
历史版本数 2
常见问题

Easyaccounts 是什么?

家庭财务管家 / Family finance manager. 通过自然语言对接 EasyAccounts 个人记账系统,支持记账、查账、批量记账、内部转账、流水修改、收支统计、年度分析、Excel 导出、系统公告查询等。Manage household accounts, expenses, income,... 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 113 次。

如何安装 Easyaccounts?

在 OpenClaw 或 Claude Code 对话框中运行命令「/install easyaccounts」即可一键安装,无需额外配置。

Easyaccounts 是免费的吗?

是的,Easyaccounts 完全免费,采用 MIT-0 许可证,可自由下载、安装和使用。

Easyaccounts 支持哪些平台?

Easyaccounts 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。

谁开发了 Easyaccounts?

由 QingHeYang(@qingheyang)开发并维护,当前版本 v0.2.0。

💬 留言讨论