起因

之前那个 OpenClaw 定时任务发的邮件实在太烦了,满屏都是日报。我就想着,干脆单独整一个网站把这些东西收纳一下。

前段时间刚下了minimax agent,就打算先拿他练练手。

简单粗暴的技术栈

既然是个人小工具,主打一个“够用就行”:
前端直接 Vue 3 + Vite 配上 TailwindCSS,写样式快;后端 Spring Boot 连数据库都懒得装,直接上个 SQLite;部署更简单,宝塔面板 + Nginx 一把梭。

什么微服务、Docker、用户登录鉴权,通通不要。

三个晚上的“动嘴”实录

第一晚:主要是跟 AI 扯皮需求
我把想法整理了一下发给 AI。最关键的几个点我跟它强调了好几遍:内部用的,别整登录功能;别搞 Docker,直接跑 jar 包最省心;文件格式支持 HTML 和 Markdown 就行。AI 很快给出了方案和目录结构,我看了一眼没啥大坑,开搞。

第二晚:看着代码自己跑起来
这一晚主要就是把功能实现了。项目管理、文件上传、预览,还有前后端的部署。看着 AI 一行行把代码吐出来,我基本就在旁边当个“监工”,偶尔指点一下方向。

第三晚:修修补补
虽然 AI 写代码快,但 bug 还是有的,主要集中在一些细节上:

  • 封面图裂了:因为后端存了 /uploads/,但 Nginx 没配代理路径,导致 404。
  • 时间显示空白:后端返回的是 uploadTime,前端傻乎乎地去读 reportDate,字段没对上。
  • 列表顺序反了:最新的报告沉底了,得往下翻,看着难受。

不过修起来也快,把报错或者现象丢给 AI,基本 10 到 20 分钟就能搞定一个。

算笔账
  • 投入时间:断断续续大概 12 个小时。
  • 亲手写的代码:0 行。
  • 提的修改意见:大概 20 来次。
  • 上线后的 bug:3 个,都修好了。
一点真实感受

这一趟下来,最大的感触就是:真正耗时间的从来不是敲代码,而是想清楚到底要做什么,以及验证它做得对不对。 虽然省了敲代码的过程,但是校验与需求不确定性耗费了更多的时间。

文末附上项目源码与后端api接口文档。

AI 发布平台 API 文档

基础 URL:https://****/api

所有接口均支持 CORS(Access-Control-Allow-Origin: *),可直接从浏览器或任何客户端调用。


项目接口

GET /projects

获取所有项目列表。

响应示例

[
  {
    "id": 1,
    "name": "我的项目",
    "description": "项目描述",
    "createdAt": "2026-05-25T10:00:00",
    "coverImage": "/uploads/covers/1/abc123.jpg",  // 相对路径,访问时需加域名
    "reportCount": 3,
    "todayNewReports": 1
  }
]

coverImage 字段为相对路径,完整访问地址为 https://****/uploads/covers/1/abc123.jpg


GET /projects/{id}

获取指定项目详情。


POST /projects

创建项目。

请求体

{
  "name": "项目名称",       // 必填
  "description": "描述",
  "coverImage": "base64或URL"
}

响应 201 Created


PUT /projects/{id}

更新项目(支持文件上传)。

Content-Type: multipart/form-data

参数 类型 必填 说明
name String 新名称
description String 新描述
coverImage File 封面图片

DELETE /projects/{id}

删除项目(级联删除该项目的所有报告)。

响应 204 No Content


报告接口

GET /reports/ping

健康检查。

响应

{
  "version": "v4-diag",
  "timestamp": "2026-05-25T15:30:00Z"
}

GET /reports?projectId={id}

获取报告列表。可选按项目筛选。

响应示例

[
  {
    "id": 1,
    "projectId": 1,
    "fileName": "2026-05-25.html",
    "fileType": "html",
    "filePath": "/uploads/reports/1.html",
    "uploadTime": "2026-05-25T10:00:00",
    "fileContent": null
  }
]

GET /reports/{id}

获取指定报告详情。


POST /reports

上传报告文件。

Content-Type: multipart/form-data

参数 类型 必填 说明
file File 报告文件
projectId Long 所属项目 ID
fileType String 文件类型:html md pdf ppt pptx

支持的文件扩展名:.html .md .pdf .ppt .pptx

响应 201 Created


GET /reports/{id}/preview

预览报告。以合适的 Content-Type 返回文件内容,支持内联展示。

  • htmltext/html
  • mdtext/markdown
  • pdfapplication/pdf
  • ppt/pptx → 对应 Office 类型

GET /reports/{id}/download

下载报告。强制以附件形式返回原始文件。

响应头

Content-Disposition: attachment; filename="filename.html"

GET /reports/{id}/pdf

将报告转为 PDF 返回。目前对所有类型均适用。

响应 application/pdf


PUT /reports/{id}

更新报告元信息。

请求体

{
  "fileName": "新文件名.html",
  "fileType": "html"
}

DELETE /reports/{id}

删除指定报告。

响应 204 No Content


静态资源路径说明

coverImage 字段为后端存储的相对路径,需拼接完整 URL 才能在浏览器中访问:

字段 相对路径示例 完整访问地址
coverImage /uploads/covers/1/abc.jpg https://****/uploads/covers/1/abc.jpg

错误响应格式

所有错误返回 500 Internal Server Error,响应体:

{
  "error": "文件名: 错误描述",
  "type": "异常类名"
}

调用示例

cURL

# 创建项目
curl -X POST https://****/api/projects \
  -H "Content-Type: application/json" \
  -d '{"name":"我的项目","description":"测试"}'

# 上传报告
curl -X POST https://****/api/reports \
  -F "file=@./日报.html" \
  -F "projectId=1" \
  -F "fileType=html"

# 下载报告
curl -O https://****/api/reports/1/download

# 删除项目
curl -X DELETE https://****/api/projects/1

JavaScript (Fetch)

// 上传报告
const formData = new FormData()
formData.append('file', fileInput.files[0])
formData.append('projectId', 1)
formData.append('fileType', 'html')

const res = await fetch('https://****/api/reports', {
  method: 'POST',
  body: formData
})
const report = await res.json()

Python (requests)

import requests

# 创建项目
r = requests.post('https://****/api/projects', json={
    'name': '我的项目',
    'description': '测试描述'
})
print(r.json())

# 上传报告
r = requests.post('https://****/api/reports', files={
    'file': ('日报.html', open('日报.html', 'rb'), 'text/html')
}, data={
    'projectId': 1,
    'fileType': 'html'
})
print(r.json())
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐