Easyaccounts
/install easyaccounts
\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 Allowed → 99% 是 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
- 确保已安装 OpenClaw(本地或 Docker 部署)
- 在对话框中输入安装命令:
/install easyaccounts - 安装完成后,直接呼叫该 Skill 的名称或使用
/easyaccounts触发 - 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
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。