一个零依赖的本地画图 Web 应用。前端输入提示词,后端调用 GeekAI 图片生成接口。
cp .env.example .env
# 编辑 .env,填入 GEEKAI_API_KEY
npm run dev
打开 http://localhost:5173。
docker build -t huatu .
docker run --rm -p 5173:5173 \
--env-file .env \
-v "$(pwd)/logs:/app/logs" \
huatu
打开 http://localhost:5173。
可用环境变量:
GEEKAI_API_KEY: 必填,GeekAI API KeyGEEKAI_IMAGE_API_URL: 默认 https://geekai.co/api/v1/images/generationsGEEKAI_IMAGE_RESULT_API_BASE: 默认从生成接口推导为 https://geekai.co/api/v1/imagesGEEKAI_IMAGE_MODEL: 默认 gpt-image-2GENERATION_LOG_ENABLED: 默认开启。设为 false 可关闭服务端生成日志GENERATION_LOG_PATH: 默认 logs/generations.jsonlPORT: 默认 5173应用默认使用异步模式。前端拿到 task_id 后会调用本地 /api/result/:taskId,由后端代理查询官方 GET /images/{task_id} 接口。
模型、异步模式、返回格式、质量、尺寸和生成数量都由服务端固定,普通用户无法在页面或请求体里覆盖这些参数。
前端会把提示词草稿和最近 30 条生成历史保存在用户浏览器本地,刷新页面后会自动恢复最近一次结果。
异步结果最多查询 100 次,每次间隔 3 秒,最长等待约 5 分钟。
生成任务提交成功后会把 task_id 临时保存在用户浏览器本地。如果用户在生成完成前刷新页面,前端会自动恢复这个未完成任务并继续查询;任务成功、失败或超时后会清除该临时记录。
图片下载按钮会通过本地 /api/download-image 代理远程图片,并返回附件响应,避免浏览器因为跨域图片 URL 忽略 download 属性。
服务端会把生成提交、查询结果和最终完成记录写入 JSONL 日志,包含时间、IP、提示词、task_id 和图片 URL。日志默认位于 logs/generations.jsonl,该目录已加入 .gitignore。
应用会通过服务端 cookie 识别访客。游客默认没有免费生成额度;用户首次邮箱登录后默认获得 2 次生成额度。生成任务成功提交后扣除 1 次额度。
用户可以在页面输入邀请码兑换额度。同一个访客同一个邀请码只能兑换一次,默认每次兑换增加 5 次额度。
相关环境变量:
INVITE_CODES: 可用邀请码,多个邀请码用英文逗号分隔,例如 demo123,friend456GUEST_INITIAL_CREDITS: 新访客初始额度,默认 0USER_LOGIN_BONUS: 用户首次邮箱登录赠送额度,默认 2(设为 0 可关闭登录赠送)INVITE_CREDIT_GRANT: 每个邀请码兑换增加的额度,默认 5DATABASE_PATH: SQLite 数据库路径,默认 data/huatu.sqliteADMIN_USERNAME: 管理后台账号,默认 adminADMIN_PASSWORD: 管理后台密码,默认 admin123USER_LOGIN_CODE_DEBUG: 非生产环境是否在登录接口返回验证码,默认开启;上线接入邮件服务后应设为 false管理后台位于 /admin,可以查看统计、创建邀请码、调整访客额度和查看生成记录。上线前请务必修改 ADMIN_PASSWORD。
普通用户通过邮箱验证码登录。游客默认不可直接生成;首次登录默认获得 2 次额度。邀请码兑换需要先登录,兑换成功后增加额度。
注意:这个方案适合小范围试用和成本控制。访客身份依赖浏览器 cookie;如果要更强约束,需要账号登录、手机号/邮箱验证或支付系统。
普通用户邮箱验证码会通过 SMTP 发送。相关环境变量:
SMTP_HOST: SMTP 服务器,例如 smtp.163.comSMTP_PORT: SMTP 端口,例如 465SMTP_USER: SMTP 登录账号SMTP_PASSWORD: SMTP 授权码或密码SMTP_FROM: 发件人邮箱生产环境建议设置 USER_LOGIN_CODE_DEBUG=false,避免接口返回调试验证码。