跳转至

07. 资源上传与站点配置

1. 通用上传(JWT)

POST /api/upload/file

multipart/form-data 字段:

  • file:文件
  • file_type:avatar / other / 自定义

返回示例:

{
  "code": 200,
  "message": "上传成功",
  "data": {
    "file_name": "avatar.jpg",
    "file_size": 53211,
    "file_type": "avatar",
    "minio_path": "uploads/avatar/2026/04/xxx.jpg",
    "file_url": "https://...",
    "thumbnail_url": "https://..."
  }
}

2. 操作证上传与查询(JWT)

POST /api/upload/operator-certificate

multipart/form-data 字段:

  • callsign(可选)
  • file(可选,multipart 兼容路径)
  • 或直传完成后:object_key + upload_token + file_name

推荐流程:POST /api/storage/presign-put(file_type=operator_cert)→ PUT 直传 → 本接口提交 object_key 和 upload_token。

说明:

  • callsign 仅表示“申请中的新呼号”,不会在用户提交时直接写入 users.callsign。
  • 只有管理员审批通过后,新呼号才会真正生效。
  • 如果提交的 callsign 已被其他用户占用,接口返回 409。
  • 操作证上限 20MB;支持图片与 PDF。

返回示例:

{
  "code": 200,
  "message": "操作证信息已提交,请等待管理员审核",
  "data": {
    "id": 99,
    "callsign": "BG7NEW",
    "file_name": "cert.pdf",
    "file_size": 124312,
    "upload_time": "2026-04-05 16:11:00"
  }
}

GET /api/operator-certificate

返回 active_cert(已通过)和 pending_cert(待审/拒绝最近一条)。 两类证书对象都会返回 callsign 字段,表示该证书对应的呼号。

3. 站点 Logo/Favicon(Admin)

multipart/form-data:file

POST /api/upload/favicon

multipart/form-data:file

配置中保存的是 object key;读取公开配置时由后端解析为可访问 URL。

3.1 通用存储与直传(JWT)

POST /api/storage/presign-put

申请直传凭证。body:

{
  "file_type": "assets",
  "file_name": "package.zip",
  "size": 1048576,
  "content_type": "application/zip"
}

file_type 支持 assets | client_resource | firmware | operator_cert。其中 assets、client_resource、firmware 仅管理员可申请,operator_cert 绑定当前用户。object key 仅由服务端生成。

返回示例(MinIO):

{
  "code": 200,
  "data": {
    "mode": "s3",
    "upload_url": "https://minio.example/...",
    "method": "PUT",
    "headers": { "Content-Type": "application/zip" },
    "object_key": "staging/assets/1/2026/07/xxx.zip",
    "upload_token": "signed-upload-grant",
    "expires_at": "2026-07-14T12:00:00Z",
    "max_size": 104857600,
    "content_type": "application/zip"
  }
}

local 驱动下 mode 为 local,upload_url 指向 PUT /api/storage/put?token=...&key=...(token 鉴权,无需 JWT)。 上传内容先进入 staging;complete 会校验申请人、类型、实际大小和有效期,再提升为新的不可变 final key。未完成且超过 24 小时的 staging 对象会自动清理。

PUT /api/storage/put

local 驱动专用直传入口;校验 query 中的 token 与 key 后写入存储。

4. 资源中心(Admin)

管理端

  • GET /api/assets(管理员列表,参数 parent_id)
  • POST /api/assets/folder
  • POST /api/assets/upload(multipart/form-data: parent_id + file + name + remark,兼容代理上传)
  • POST /api/assets/complete(直传完成后落库)
  • PUT /api/assets/:id
  • PUT /api/assets/:id/move
  • POST /api/assets/:id/replace
  • DELETE /api/assets/:id

直传完整流程:presign-put → 浏览器 PUT 到 upload_url → POST /api/assets/complete:

{
  "parent_id": 12,
  "name": "客户端安装包",
  "remark": "",
  "object_key": "staging/assets/1/2026/07/xxx.zip",
  "upload_token": "signed-upload-grant"
}

示例:创建文件夹

{ "name": "客户端安装包", "parent_id": null, "remark": "发布目录" }

示例:移动资源

{ "target_parent_id": 12 }

前台公开下载

  • GET /api/assets/tree
  • GET /api/assets/folder/:id
  • GET /api/assets/:id/download

下载链接返回示例:

{
  "code": 200,
  "message": "获取成功",
  "data": {
    "name": "draarl-client.exe",
    "size": 51200321,
    "mime_type": "application/octet-stream",
    "download_url": "https://...presigned..."
  }
}

4.1 固件上传(Admin)

  • POST /api/firmware:multipart/form-data(兼容代理上传)
  • POST /api/firmware/complete:直传完成后落库,服务端重算 SHA-256

complete body 示例:

{
  "dev_model": 1,
  "version": "1.2.3",
  "changelog": "修复连接",
  "object_key": "staging/firmware/1/2026/07/xxx.bin",
  "upload_token": "signed-upload-grant",
  "file_name": "firmware.bin"
}

固件仍使用独立表和 OTA API。新上传对象提升为 firmware/<dev-model>/<version>/<sha256>/<file-name>;旧记录和旧对象路径保持可读。

4.2 客户端资源上传(Admin)

通用客户端资源使用 file_type=client_resource 申请直传。complete 路径为 POST /api/client-resources/:resource_id/releases/:release_id/artifacts/complete, 请求必须携带至少一个明确的 platform/arch target。完整生命周期、manifest 和按需下载接口见 客户端资源分发。

5. 站点配置接口

公开读取

  • GET /api/config/public

返回示例:

{
  "code": 200,
  "message": "获取成功",
  "data": {
    "icp": { "icp": "粤ICP备xxxx号" },
    "systemInfo": { "name": "DraARL", "logo_url": "https://...", "favicon_url": "https://..." },
    "sso_enabled": true,
    "sso_name": "Keycloak"
  }
}

已登录读取

  • GET /api/config/category/:category

管理员配置(Admin)

  • PUT /api/config
  • PUT /api/config/icp
  • PUT /api/config/system
  • PUT /api/config/aprs
  • GET /api/config/all
  • GET /api/config/system
  • GET /api/config/aprs
  • GET /api/config/aprs/logs
  • DELETE /api/config/logo
  • DELETE /api/config/favicon
  • GET /api/config/smtp
  • PUT /api/config/smtp

SMTP 更新请求示例:

{
  "host": "smtp.qq.com",
  "port": 465,
  "use_ssl": true,
  "insecure_skip_verify": false,
  "sender_name": "DraARL",
  "sender_email": "noreply@example.com",
  "password": "授权码"
}