Strapi 个人账本系统设计
本文介绍如何使用 Strapi 设计一个简单的个人账本系统,满足以下需求:
需求分析
用户(User)
- 用户可以注册、登录
- 系统默认使用 Strapi 自带的用户管理
类别(Category)
- 用户可以新建、编辑、删除自己的类别
- 示例类别:吃饭、教育
- 每个类别只能归属于创建者
类型(Type)
- 系统固定:收入(Income)和支出(Expense)
- 不允许用户修改或删除
入账记录(Transaction)
- 记录金额、类别、类型和日期
- 用户只能操作自己的记录
数据模型设计
用户(User)
Strapi 默认提供:
usernameemailpassword
无需额外建表。
类型(Type)
系统固定枚举:
- Collection Name:
Type - 字段:
name(枚举):income/expense
- 系统初始化时创建两条数据
- 只读,不允许用户修改
类别(Category)
用户自定义:
- Collection Name:
Category - 字段:
name(string):类别名称user(relation):User→Category(many-to-one)
- 权限:
- 用户只能操作自己的类别
- 查询只返回自己的类别
入账记录(Transaction)
记录每笔账目:
- Collection Name:
Transaction - 字段:
amount(number):金额category(relation):Category→Transaction(many-to-one)type(relation):Type→Transaction(many-to-one)user(relation):User→Transaction(many-to-one)date(date):日期,默认当前时间note(string,可选):备注
- 权限:
- 用户只能查看、编辑、删除自己的交易
type只能选择系统已有的“收入/支出”
权限控制
Category
- 创建、更新、删除:仅允许自己操作
- 查询:仅返回自己的数据
Transaction
- 创建、更新、删除:仅允许自己操作
- 查询:仅返回自己的数据
Type
- 只读,所有用户可查询
Strapi 实现细节
枚举类型
在 Transaction 中可直接使用枚举:
json
{
"type": "enumeration",
"enum": ["income", "expense"]
}Policy 示例(限制用户操作自己的类别)
js
// ./src/policies/isOwner.js
module.exports = async (ctx, next) => {
const { id } = ctx.params;
const entity = await strapi.db.query('api::category.category').findOne({ where: { id } });
if (!entity || entity.user.id !== ctx.state.user.id) {
return ctx.unauthorized('You can only access your own data');
}
await next();
};系统初始化
创建 Type 数据:
incomeexpense
用户注册后,可创建自己的 Category
数据访问示例
查询用户交易
js
const transactions = await strapi.db.query('api::transaction.transaction').findMany({
where: { user: { id: ctx.state.user.id } },
populate: ['category', 'type']
});创建交易
js
await strapi.db.query('api::transaction.transaction').create({
data: {
amount: 100,
category: 1, // 自己的 category id
type: 1, // income 或 expense id
user: ctx.state.user.id
}
});这样就完成了一个 基于 Strapi 的个人账本系统设计,实现了用户注册、类别管理、入账记录及收入/支出类型控制。