跳转到正文

打造自己的业务系统

在 SetFN 工作空间中,可以亲手打造公司专属的群件、ERP 之类的系统。 把数据库结构设计和页面制作交给 AI,我们只需把生成的结果上传到工作空间即可。 需要制作的文件只有 2 个。要做的事只是上传和点击“部署”按钮。 下面以“制造现场的库存管理程序”为例来制作。

如果想跳过 AI 提示词,直接使用已完成的文件,可以在下载完整示例 ZIP一次性获取架构、index.html、mock-db-upload.html 和 README。


1. 创建用于生成数据库的 .sfn 文件

在 SetFN 工作空间中,可以用名为 .sfn 的文件创建 DB。把 .sfn 文件的示例复制给 Claude、GPT、Gemini 之类的 AI,并像“我想管理零件和产品的库存”这样说明需求,AI 就会生成文件。

复制下面的内容,修改下方的需求设计部分,然后发给 AI 试试。

你是为名为 SetFN 的无代码后端平台设计架构文件(.sfn)的工程师。
.sfn 是具有以下结构的 JSON 文件。 

{
  "content-type": "application/setfn-schema",
  "dbType": "sqlite3",
  "apiBuild": {
    "dbName": "英文_小写_下划线_db名称",
    "dbEngine": "sqlite",
    "includeClient": false,
    "features": {
      "realtime": { "enabled": false },
      "upload": { "enabled": false },
      "ai-chat": { "enabled": false }
    }
  },
  "data": [
    {
      "table": { "name": "表名", "cmt": "此表的说明" },
      "columns": [
        { "name": "id", "type": "serial4", "primary": true, "default": "auto_increment" },
        { "name": "列名", "type": "text", "notnull": true, "cmt": "列说明" },
        { "name": "数字列", "type": "int4", "notnull": true, "default": "0" },
        { "name": "_created_at", "type": "timestamp", "default": "now()" }
      ],
      "permissions": {
        "security": { "login": true },
        "ops": {
          "list": { "login": true },
          "view": { "login": true },
          "create": { "login": true },
          "update": { "login": true },
          "delete": { "login": true, "roles": ["admin"] }
        }
      }
    }
  ]
}

列的 type 只能使用 serial4(自增 PK)/ text / int4(整数)/ timestamp。
根据需要为列加上 notnull、default、unique、index、cmt。

现在请用这种格式,为制造企业设计一个“库存管理系统”DB。需求如下。

- 登记零件,并按零件管理当前库存数量。
- 登记产品,并按产品管理当前库存数量。
- 一个产品由多个零件组装而成。需要管理每个产品需要哪些零件、各需要多少个(BOM,物料清单)。
- 记录零件/产品的入库·出库历史。特别是当发生“组装零件生产产品”的事件时,当时使用的零件和生产的产品数量必须作为同一个事件一起追踪(以便日后能够查询“制造这个产品用了多少零件”)。

DB 名称(dbName)请设为 "inventory_management"。
请控制在 4 张表以内,设计得足够实用,可以直接在实际工作中使用。
不要附加其他说明,只输出完成的 .sfn JSON 代码。

下面是这样生成的 AI 回复示例。实际结果可能因 AI 和每次运行而略有不同——不必与此内容完全一致,只要是类似的结构即可。不过,必须是没有其他说明、以 { 开头并以 } 结尾的格式,才能把输出结果原样粘贴到编辑器中。

{
  "content-type": "application/setfn-schema",
  "dbType": "sqlite3",
  "apiBuild": {
    "dbName": "inventory_management",
    "dbEngine": "sqlite",
    "includeClient": false,
    "features": {
      "realtime": { "enabled": false },
      "upload": { "enabled": false },
      "ai-chat": { "enabled": false }
    }
  },
  "data": [
    {
      "table": { "name": "parts", "cmt": "零件主数据。任何成员都可以查看/登记/修改,只有管理员可以删除" },
      "columns": [
        { "name": "id", "type": "serial4", "primary": true, "default": "auto_increment" },
        { "name": "part_code", "type": "text", "notnull": true, "unique": true, "cmt": "零件代码" },
        { "name": "name", "type": "text", "notnull": true, "cmt": "零件名称" },
        { "name": "spec", "type": "text", "cmt": "规格(例:M2、220V/50Hz)。即使名称相同,规格不同也要登记为单独的 part_code" },
        { "name": "category", "type": "text", "cmt": "零件分类(电子零件/机构零件/包装材料等)" },
        { "name": "unit", "type": "text", "notnull": true, "default": "EA", "cmt": "单位" },
        { "name": "unit_cost", "type": "int4", "notnull": true, "default": "0", "cmt": "单价" },
        { "name": "current_stock", "type": "int4", "notnull": true, "default": "0", "cmt": "当前库存" },
        { "name": "safety_stock", "type": "int4", "notnull": true, "default": "0", "cmt": "安全库存(再订货点)" },
        { "name": "supplier", "type": "text", "cmt": "供应商" },
        { "name": "_user_id", "type": "int4", "notnull": true, "index": true },
        { "name": "_nick", "type": "text", "cmt": "最后登记/修改的成员的显示名称" },
        { "name": "_created_at", "type": "timestamp", "default": "now()" }
      ],
      "permissions": {
        "security": { "login": true, "ownerColumn": "_user_id" },
        "ops": {
          "list": { "login": true },
          "view": { "login": true },
          "create": { "login": true },
          "update": { "login": true },
          "delete": { "login": true, "roles": ["admin"] }
        }
      }
    },
    {
      "table": { "name": "products", "cmt": "产品主数据。任何成员都可以查看/登记/修改,只有管理员可以删除" },
      "columns": [
        { "name": "id", "type": "serial4", "primary": true, "default": "auto_increment" },
        { "name": "product_code", "type": "text", "notnull": true, "unique": true, "cmt": "产品代码" },
        { "name": "name", "type": "text", "notnull": true, "cmt": "产品名称" },
        { "name": "category", "type": "text", "cmt": "产品分类" },
        { "name": "unit", "type": "text", "notnull": true, "default": "EA", "cmt": "单位" },
        { "name": "price", "type": "int4", "notnull": true, "default": "0", "cmt": "销售价" },
        { "name": "current_stock", "type": "int4", "notnull": true, "default": "0", "cmt": "当前库存" },
        { "name": "_user_id", "type": "int4", "notnull": true, "index": true },
        { "name": "_nick", "type": "text", "cmt": "最后登记/修改的成员的显示名称" },
        { "name": "_created_at", "type": "timestamp", "default": "now()" }
      ],
      "permissions": {
        "security": { "login": true, "ownerColumn": "_user_id" },
        "ops": {
          "list": { "login": true },
          "view": { "login": true },
          "create": { "login": true },
          "update": { "login": true },
          "delete": { "login": true, "roles": ["admin"] }
        }
      }
    },
    {
      "table": { "name": "bom", "cmt": "各产品的零件构成表(单层)。对 bom_key(product_id:part_id)加 unique 约束,防止同一产品重复登记同一零件" },
      "columns": [
        { "name": "id", "type": "serial4", "primary": true, "default": "auto_increment" },
        { "name": "product_id", "type": "int4", "notnull": true, "index": true },
        { "name": "part_id", "type": "int4", "notnull": true, "index": true },
        { "name": "qty_per_unit", "type": "int4", "notnull": true, "default": "1", "cmt": "制造 1 个产品所需的零件数量" },
        { "name": "bom_key", "type": "text", "notnull": true, "unique": true, "cmt": "product_id:part_id 的组合。用于防止重复登记" },
        { "name": "_user_id", "type": "int4", "notnull": true, "index": true },
        { "name": "_nick", "type": "text", "cmt": "登记成员的显示名称" },
        { "name": "_created_at", "type": "timestamp", "default": "now()" }
      ],
      "permissions": {
        "security": { "login": true, "ownerColumn": "_user_id" },
        "ops": {
          "list": { "login": true },
          "view": { "login": true },
          "create": { "login": true },
          "update": { "login": true },
          "delete": { "login": true, "roles": ["admin"] }
        }
      }
    },
    {
      "table": { "name": "stock_transactions", "cmt": "入出库/组装的统一历史。item_type=part|product,tx_type=입고|출고|조립사용|조립생산(入库|出库|组装使用|组装生产)。一次组装生产事件由共享同一 batch_id 的多条组装使用(零件消耗)记录 + 1 条组装生产(产品增加)记录构成,因此可以追踪某个产品使用了哪些零件、用了多少" },
      "columns": [
        { "name": "id", "type": "serial4", "primary": true, "default": "auto_increment" },
        { "name": "item_type", "type": "text", "notnull": true, "cmt": "part | product" },
        { "name": "item_id", "type": "int4", "notnull": true, "index": true, "cmt": "parts.id 或 products.id" },
        { "name": "item_name", "type": "text", "notnull": true, "cmt": "登记时的品目名称快照" },
        { "name": "tx_type", "type": "text", "notnull": true, "cmt": "입고(入库)| 출고(出库)| 조립사용(组装使用)| 조립생산(组装生产)" },
        { "name": "reason", "type": "text", "cmt": "入出库原因。组装使用/组装生产的 tx_type 本身即为原因,因此留空" },
        { "name": "qty", "type": "int4", "notnull": true, "cmt": "始终为正数。方向由 tx_type 判断" },
        { "name": "batch_id", "type": "text", "index": true, "cmt": "组装生产事件的分组 id。单纯入出库时为空" },
        { "name": "note", "type": "text", "cmt": "备注" },
        { "name": "_user_id", "type": "int4", "notnull": true, "index": true },
        { "name": "_nick", "type": "text", "cmt": "登记成员的显示名称" },
        { "name": "_created_at", "type": "timestamp", "default": "now()" }
      ],
      "permissions": {
        "security": { "login": true, "ownerColumn": "_user_id" },
        "ops": {
          "list": { "login": true },
          "view": { "login": true },
          "create": { "login": true },
          "update": { "login": true, "roles": ["admin"] },
          "delete": { "login": true, "roles": ["admin"] }
        }
      }
    }
  ]
}

复制这个结果,在工作空间中通过创建 → 模板文件 → 新建架构(DB)创建一个空的架构文件。

选择创建 > 模板文件 > 新建架构(DB)的页面

输入文件名并保存后,就会创建一个空的架构文件。

新创建的空架构文件

点击右上角的编辑器标签页,然后原样粘贴刚才 AI 的回复。

架构编辑器页面

保存后移动到顶部的API 构建标签页,就能看到按表自动生成的 API 列表。

API 构建页面

点击部署展开设置,确认数据库标识符后再次点击部署。等待几秒钟后会出现“部署完成!”消息。最后,点击顶部的软盘按钮保存。到这里,DB 构成就完成了——零件/产品/构成表/入出库历史 4 张表,以及操作这些表的 REST API 都已实际创建,处于可以立即使用的状态。接下来该制作与这个 DB 连接的页面了。

2. 创建用于构成页面的 .html 文件

这次同样向 AI 提出请求。规划并整理想要制作的内容后传达给 AI。此时可以把刚才创建的 .sfn 文件内容也一起作为参考资料提供。

  • 登记零件·产品的输入表单
  • 登记入库·出库的表单
  • 登记“生产了多少个这个产品”后,自动计算所需零件数量并反映到库存
  • 用表格显示当前库存状态,并可直接在表格中修改值并保存

接着把下面的内容粘贴到 AI 聊天中。(最上方一并粘贴第 1 步生成的结果。)

[在此粘贴第 1 步的结果]

上面的架构已经部署好了。请制作一个使用这个架构的网页页面(index.html)。

页面加载和保存数据时,按照以下规则向服务器发送请求。

1. 获取已登录用户的 API 令牌:
   POST /api/auth/bootstrap  (credentials: "include")
   响应: { data: { access_token, user: { id, nick } } }

2. 之后的所有请求都附加此标头: Authorization: Bearer <access_token>

3. 表 CRUD:
   查询   GET  /api/web/{dbName}/{table}/list?列=值   → 响应 { rows: [...] }(没有结果时 rows 可能为 null,因此始终按 rows || [] 处理)
   创建   POST /api/web/{dbName}/{table}/create          → body: JSON,响应 { lastInsertId }
   修改   PUT  /api/web/{dbName}/{table}/update/{id}     → body: JSON(只发送更改的列也可以)
   删除   DELETE /api/web/{dbName}/{table}/delete/{id}

页面需要的功能如下。

- 可以新登记零件和产品的输入表单
- 可以登记零件/产品入库·出库的表单(登记后同时更新当前库存数量)
- 登记“生产了多少个这个产品”后,根据已登记的构成表自动计算所需零件数量,扣减零件库存并增加产品库存的功能。如果零件库存不足,则阻止登记并提示。
- 用表格显示当前零件/产品库存状态的页面。点击表格单元格即可就地修改值并保存。
- 按时间顺序显示入库/出库/组装历史的列表。

请把 HTML/CSS/JS 全部放在一个文件里。做成干净的白色背景、卡片式布局。
不要附加其他说明,只输出完成的 index.html 代码。

下面是这样生成的 html 文件示例。实际结果可能因 AI 而略有不同。

index.html

把这个文件上传到工作空间后,团队成员实际可用的页面就完成了。

3. 填充测试数据

要亲眼看到实际运行效果,就需要有数据。也可以直接让 AI 制作一个按一下按钮就能填入示例数据的页面。

[在此粘贴第 1 步的结果]

上面的架构已经部署好了,使用这个架构的 index.html 也已经做好了。
请制作一个按一下按钮就能自动填入测试数据的页面(mock-db-upload.html)。

数据请用与第 2 步页面相同的方式(通过 POST /api/auth/bootstrap 获取令牌,通过 POST /api/web/{dbName}/{table}/create 创建)写入实际服务器。

- 请实际创建并写入 10~15 个零件、3~5 个产品、每个产品的零件构成,以及几条入出库历史。
- 零件/产品的名称和数量请填入制造现场实际可能使用的值。
- 如果已经存在相同代码的数据,则只跳过该项并继续执行。
- 在页面上逐行以日志形式显示进度,结束后显示“完成”。
不要附加其他说明,只输出完成的 mock-db-upload.html 代码。

下面是这样生成的 html 文件示例。实际结果可能因 AI 而略有不同。这个页面不部署,只在需要准备演示时打开使用。

mock-db-upload.html

实际填入数据并使用后,运行效果如下。

零件状态——双击单元格即可直接修改·保存

BOM 登记——把右侧的零件卡片拖到左侧即可添加到构成中

组装生产登记——确定产品和生产数量后,会自动显示所需零件数量和当前库存

交易历史——按批次号一并保留组装生产·组装使用明细

4. 反复修改

不必一次做到完美。在使用页面的过程中,如果发现功能不足或想要修改的地方,继续向 AI 提出请求即可。不过,根据修改的内容不同,接下来要做的事情也不同。

  • 会改变 DB 结构(表·列)的修改——例如:添加新列、添加新表——需要重新获取修改后的 .sfn,粘贴到编辑器中,并在API 构建中重新部署。
  • 保持 DB 结构不变、只修改页面的修改——例如:设计、文案、按钮位置——只需重新获取 index.html 并覆盖现有文件即可。不需要重新部署 API。
  • 更改已有数据的表的结构时,请确认部署设置中的覆盖现有数据。启用覆盖后,现有数据将被永久删除。

仅凭这四个步骤,数据库设计、实际页面、测试数据,以及之后的修改,全部都由 AI 来完成。之后只需按照自己的想法继续打磨页面的设计或细节项目即可。