用户端接口文档

本文档只描述终端用户 / 客户端需要调用的接口:注册登录、查询额度、调用 AI 功能、购买套餐。后台 CMS 管理接口不在本文范围内。

Base URLhttps://www.jielafu.cn
接口前缀/api
Content-Typeapplication/json

通用约定

鉴权

除注册、登录、查重、套餐列表等公开接口外,其余接口都需要在请求头带上用户凭证:

Authorization: Bearer utk_xxxxxxxx...

utk_ 开头的凭证由登录或注册接口返回。每次登录都会生成新凭证,旧凭证立即失效,客户端应把新凭证存起来替换旧的。

响应结构

成功:{ "code": 0, "message": "success", "data": {...} }

失败:{ "code": 402, "message": "积分不足…", "data": null }

判断逻辑:code === 0 即成功,其余一律失败。

计费与积分规则

用户的 points 就是可调用 AI 功能的次数。即梦 AI 4.6 每次调用扣 1 次(管理员可在后台「API 功能配置」里改单价)。

  1. 先扣后调:接口在请求上游之前就扣除次数,不存在"调用了却没扣"的情况。
  2. 余额不足直接拒绝:剩余次数 < 本次单价时返回 HTTP 402,不会调用上游,也不产生任何费用。
  3. 上游失败自动返还:上游报错或超时(504)时自动退回本次额度,响应会写明「已返还 1 次额度,当前剩余 N 次」。
  4. 入参不合法不扣费:缺 prompt、参考图不是合法图片等返回 400,在扣费之前拦截,额度不变。
  5. 查余额:响应头 X-Points-Remaining、data.charge 明细,或随时调用 GET /api/users/me。
{ "code": 402, "message": "积分不足:本次需要 1 次调用额度,当前剩余 0 次,请先购买套餐", "data": null }
判断逻辑:code === 0 即成功,其余一律失败。客户端建议显式判断 402,提示用户去购买套餐。

快速开始

# 1. 登录,拿到 token
curl -X POST https://www.jielafu.cn/api/users/login \
  -H "Content-Type: application/json" \
  -d '{"username":"alice","password":"123456"}'

# 2. 调用 AI 功能(扣 1 次额度)
curl -X POST https://www.jielafu.cn/api/call/jimeng_v46 \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer utk_上面拿到的token" \
  -d '{"prompt":"赛博朋克风格的城市夜景"}'

注册

注册需要手机号 + 邮箱验证码,分两步完成。

第一步:获取邮箱验证码

POST /api/users/send-code 公开
参数类型必填说明
emailstring是接收验证码的邮箱
curl -X POST https://www.jielafu.cn/api/users/send-code \
  -H "Content-Type: application/json" \
  -d '{"email":"alice@qq.com"}'
{
  "code": 0,
  "message": "验证码已发送,请查收邮件(若无请检查垃圾箱)",
  "data": { "email": "alice@qq.com", "ttlMinutes": 5, "resendSeconds": 60 }
}
同一邮箱 60 秒内只能发送一次、每天最多 20 次(均返回 429); 验证码 5 分钟有效、仅可使用一次;连续输错 5 次自动作废; 该邮箱已注册时返回 409,请直接登录。

第二步:提交注册

POST /api/users/register 公开

注册成功即视为已登录,直接返回 token,无需再调一次登录。

参数类型必填说明
usernamestring是3–32 位,仅字母、数字、下划线、点、连字符
passwordstring是至少 6 位
phonestring是11 位中国大陆手机号,不可与已有账号重复
emailstring是必须与接收验证码的邮箱一致
codestring是邮箱收到的 6 位验证码
nicknamestring否昵称,默认等于用户名
curl -X POST https://www.jielafu.cn/api/users/register \
  -H "Content-Type: application/json" \
  -d '{"username":"alice","password":"123456","phone":"13800138000","email":"alice@qq.com","code":"123456"}'
{
  "code": 0,
  "message": "注册成功,已赠送 5 次调用额度",
  "data": {
    "token": "utk_9f3c...",
    "tokenType": "Bearer",
    "tokenUpdatedAt": "2026-10-05 03:20:11",
    "user": {
      "id": 12, "username": "alice", "nickname": "爱丽丝",
      "phone": "13800138000", "email": "alice@qq.com", "emailVerified": true,
      "points": 5, "usedPoints": 0, "status": "active",
      "lastLoginAt": null, "createdAt": "2026-10-05 03:20:11"
    }
  }
}

未开放注册返回 403;用户名 / 手机号 / 邮箱已被占用 409;手机号或邮箱格式不正确 400;验证码错误或过期 400。同一 IP 每小时最多注册 10 次。

登录 / 刷新 token

POST /api/users/login 公开
参数类型必填说明
usernamestring是用户名
passwordstring是密码
curl -X POST https://www.jielafu.cn/api/users/login \
  -H "Content-Type: application/json" \
  -d '{"username":"alice","password":"123456"}'

返回结构与注册一致。每次调用都会刷新 token,旧 token 立刻作废——在新设备登录会把旧设备顶下线。

用户名或密码错误 401;账号被停用 403;同一账号连续失败 8 次会限流 15 分钟 429。

我的信息

GET /api/users/me 需 token
curl https://www.jielafu.cn/api/users/me -H "Authorization: Bearer utk_xxx"
{
  "code": 0,
  "data": {
    "id": 12, "username": "alice", "nickname": "爱丽丝",
    "phone": "13800138000", "email": "alice@qq.com", "emailVerified": true,
    "points": 42, "usedPoints": 8, "status": "active",
    "lastLoginAt": "2026-10-05 03:20:11",
    "createdAt": "2026-10-05 03:10:02",
    "tokenUpdatedAt": "2026-10-05 03:20:11"
  }
}

points 剩余可调用次数,usedPoints 累计已消耗。phone / email 为注册时填写,emailVerified 表示邮箱是否已通过验证码校验。

points — 剩余可调用次数;usedPoints — 累计已消耗次数。

退出登录

POST /api/users/logout 需 token

清空服务端凭证,当前 token 立即失效,需要重新登录。

修改密码

POST /api/users/change-password 需 token
参数类型必填说明
oldPasswordstring是原密码
newPasswordstring是新密码,至少 6 位

成功后返回新 token,旧 token 立即失效(其它设备会被下线),客户端需保存新凭证。原密码不正确返回 400。

查重与注册开关

GET /api/users/register-status 公开

客户端可据此决定是否展示注册入口,以及是否需要提示「邮件服务未配置」。

{
  "code": 0,
  "data": {
    "enabled": true,
    "giftPoints": 5,
    "requirePhone": true,
    "requireEmailCode": true,
    "mailConfigured": true
  }
}

enabled 是否开放注册;giftPoints 注册赠送次数;requirePhone / requireEmailCode 是否强制手机号与邮箱验证码;mailConfigured 为 false 时无法发送验证码。

GET /api/users/check-username?username=alice 公开
GET /api/users/check-email?email=alice@qq.com 公开
{ "code": 0, "data": { "username": "alice", "formatOk": true, "available": false } }

formatOk 格式是否合法,available 是否未被占用,可用于注册表单实时校验。

可用功能列表

GET /api/call 公开

后台配置了哪些 AI 能力,客户端不需要关心上游地址与密钥——只需要知道功能标识 code 和该功能的参数。

{
  "code": 0,
  "data": {
    "list": [
      {
        "code": "jimeng_v46",
        "name": "即梦 AI 4.6 文生图",
        "description": "输入提示词生成图片,每次调用扣除 1 次额度",
        "costPoints": 1,
        "paramSchema": [
          { "key": "prompt", "label": "提示词", "type": "string", "required": true },
          { "key": "width",  "label": "宽度",   "type": "number", "required": false, "default": 2048, "min": 512, "max": 4096 }
        ]
      }
    ]
  }
}
用 paramSchema 可以直接渲染客户端表单,后台新增功能时客户端无需改代码。

通用调用

POST /api/call/{code} 需 token 按配置扣次数
curl -X POST https://www.jielafu.cn/api/call/jimeng_v46 \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer utk_xxx" \
  -d '{"prompt":"赛博朋克风格的城市夜景","width":2048,"height":2048}'
{
  "code": 0,
  "message": "调用成功",
  "data": {
    "feature": "jimeng_v46",
    "name": "即梦 AI 4.6 文生图",
    "cost": 1,
    "charge": { "before": 42, "after": 41, "amount": 1 },
    "result": { "images": ["https://..."], "taskId": "..." },
    "elapsedMs": 18320
  }
}

响应头:X-Points-Remaining: 41

情况状态码说明
额度不足402提示先购买套餐
参数缺失 / 类型错误400按 paramSchema 校验
功能不存在或未开放404
功能已停用403
功能维护中503
上游失败或超时502 / 504开启失败返还时额度自动退回,错误信息中会说明
安全约定:响应与错误信息中不会出现上游地址、密钥或请求模板。

图生图(传入参考图)

即梦 4.6 的文生图与图生图共用同一个功能标识,区别只在于有没有传参考图。

字段类型说明
imageUrlsstring[]参考图的公网 URL。上游只接受公网可访问链接,不接受 base64
imagesstring[]参考图的 base64(JPEG / PNG,可带 data:image/...;base64, 前缀)。服务器会先托管成公网链接,再交给上游

两种方式可混用,合计最多 14 张;建议不超过 6 张——图片越多越大,处理时间越长,超过 6 张后参考效果反而下降。单张限制:JPEG / PNG,≤ 15 MB,分辨率 ≤ 4096×4096。

参考图已在公网(推荐)

curl -X POST https://www.jielafu.cn/api/call/jimeng_v46 \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer utk_xxx" \
  -d '{
    "prompt": "把这张图的背景换成夜晚的城市霓虹灯光,写实摄影风格",
    "imageUrls": ["https://example.com/cat.jpg"]
  }'

参考图在本地(传 base64,由服务器托管)

const fs = require('fs');

const b64 = fs.readFileSync('./cat.jpg').toString('base64');
const r = await fetch('https://www.jielafu.cn/api/call/jimeng_v46', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json', Authorization: 'Bearer utk_xxx' },
  body: JSON.stringify({
    prompt: '把这张图的背景换成夜晚的城市霓虹灯光,写实摄影风格',
    images: [b64],
  }),
}).then((x) => x.json());
注意:
  • 图生图时若未指定 width / height,模型会结合参考图尺寸自行决定宽高,不会像文生图那样默认按 2048×2048 出图
  • 请求体上限 32 MB;base64 比原图大约 1/3,大图建议先压缩到 2048px 以内再传
  • 上传的参考图会在服务器上保留 6 小时后自动清理,不要把它当作长期图床
  • 若返回「参考图托管到了内网地址」,说明管理员未配置 PUBLIC_BASE_URL,请改用 imageUrls 传入公网链接

即梦 AI 4.6 生图

功能标识为 jimeng_v46 时,也可用下面这组专用接口(参数更完整;计费规则一致,每次扣 1 次额度)。

同步生成(推荐)

POST /api/jimeng/generate 需 token 扣 1 次

提交任务后服务端自动轮询,直接返回成品图。

参数类型必填默认说明
promptstring是—提示词
imageUrlsstring[]否[]参考图公网 URL,填了就是图生图
imagesstring[]否[]参考图 base64(本地图,服务器托管后转交上游),见「图生图」章节
widthnumber否2048512–4096
heightnumber否2048512–4096
seednumber否—随机种子,填相同值可复现
scalenumber否—生成自由度
forceSingleboolean否true是否强制单图
returnUrlboolean否true返回图片 URL
watermarkboolean否false是否带水印
negativePromptstring否""反向提示词
timeoutMsnumber否配置值最长等待时间
curl -X POST https://www.jielafu.cn/api/jimeng/generate \
  -H "Content-Type: application/json" -H "Authorization: Bearer utk_xxx" \
  -d '{"prompt":"一只坐在窗台上的橘猫,午后阳光,写实风格"}'
{
  "code": 0,
  "message": "生成完成,共 1 张",
  "data": {
    "feature": "jimeng_v46",
    "taskId": "cgt-...",
    "status": "done",
    "images": ["https://.../xxx.jpeg"],
    "waitedMs": 15230,
    "charge": { "before": 42, "after": 41, "amount": 1 }
  }
}

异步提交 + 查询结果

POST /api/jimeng/submit 扣 1 次

参数同上,返回 { taskId, requestId },状态码 201。

GET /api/jimeng/result?taskId=xxx 免费
{ "code": 0, "data": { "taskId": "cgt-...", "status": "done", "images": ["https://..."], "finished": true } }

status 取值:pending(排队中)/running(生成中)/done(完成)/failed、error、expired、not_found(终态失败)。finished: true 表示已到终态,可停止轮询。

手动扣减额度

POST /api/users/consume 需 token

供外部系统直接扣次数(不走上游调用)。feature 默认 manual,count 默认 1。

{ "code": 0, "message": "已扣除 1 次调用额度", "data": { "before": 42, "after": 41, "cost": 1 } }

使用统计

GET /api/users/me/stats 需 token
{
  "code": 0,
  "data": {
    "points": 41,
    "usedPoints": 8,
    "rechargedPoints": 105,
    "byFeature": [ { "feature": "jimeng_v46", "total": 6, "count": 6 } ],
    "daily": [ { "day": "2026-10-05", "total": 3 } ],
    "orders": { "count": 2, "paidAmount": 49, "paidPoints": 100 }
  }
}

byFeature — 按功能聚合的消耗次数与笔数(最多 10 项);daily — 近 14 天每天消耗次数;orders — 累计订单数、已付金额(元)、已到账次数。

额度流水

GET /api/users/me/point-logs?limit=20 需 token
{
  "code": 0,
  "data": {
    "points": 41,
    "list": [
      { "id": 88, "type": "consume", "amount": -1, "beforePoints": 42, "afterPoints": 41,
        "feature": "jimeng_v46", "remark": "", "createdAt": "2026-10-05 03:31:02" },
      { "id": 87, "type": "recharge", "amount": 100, "beforePoints": 5, "afterPoints": 105,
        "feature": "", "remark": "订单 ORD... 到账", "createdAt": "2026-10-05 03:25:44" }
    ]
  }
}

type 取值:init(注册赠送)/recharge(购买到账)/consume(调用消耗)/adjust(管理员调整或失败返还)。

我的作品(创作记录)

每次调用 AI 生成成功后,系统会自动记一条作品:提示词、参数、消耗次数,以及图片原文(base64)。调用方不需要额外传参,落库在服务端完成。

分页查询我的作品

GET /api/users/me/works?page=1&pageSize=10 需 token
参数必填默认说明
page否1页码,从 1 开始
pageSize否10每页条数,范围 1 ~ 50
status否全部success 成功出图/failed 失败/all 全部
keyword否—按提示词模糊搜索
withBase64否0传 1 时连图片 base64 原文一并返回
{
  "code": 0,
  "data": {
    "list": [
      {
        "id": 41,
        "title": "一只坐在窗台上的橘猫,午后阳光",
        "prompt": "一只坐在窗台上的橘猫,午后阳光,写实摄影风格",
        "featureCode": "jimeng_v46",
        "status": "success",
        "imageCount": 1,
        "totalBytes": 3125736,
        "costPoints": 1,
        "elapsedMs": 10289,
        "createdAt": "2026-10-09 18:35:12",
        "images": [
          { "id": 47, "sortOrder": 0, "mime": "image/png", "bytes": 3125736,
            "preview": "/works/2026-10/mv0tvhqq-2f71a78b5100d3d8.png", "url": "" }
        ]
      }
    ],
    "pagination": {
      "page": 1, "pageSize": 10, "total": 37,
      "totalPages": 4, "hasMore": true, "nextPage": 2
    }
  }
}

翻页用 pagination 里的字段:hasMore 判断是否还有下一页,nextPage 直接给出下一页页码,totalPages 用于展示总页数。默认按最新在前排序。

默认不返回 base64:一页 10 条就是几十 MB,没有客户端扛得住。要拿图片原文,用 ?withBase64=1 拿整页,或调详情接口 GET /api/users/me/works/:id?base64=1 只取单条(推荐)。

images[].preview 是站内可直接访问的图片链接,拼上站点域名就能显示:

https://www.jielafu.cn/works/2026-10/mv0tvhqq-2f71a78b5100d3d8.png

预览文件被清理后,服务端会用库里的 base64 自动重建,链接不会失效;真正的图片原文始终存在数据库里。

作品详情

GET /api/users/me/works/:id?base64=1 需 token

返回单条作品(含 images 数组,默认带 preview,加 base64=1 时附原文)。查别人的作品返回 404。

删除作品

DELETE /api/users/me/works/:id 需 token

图片记录一并删除。只能删自己的,删别人的返回 404。

CMS 后台的「我的作品」页面就是这组接口的可视化版本:图片网格 + 翻页 + 搜索 + 删除,普通用户登录后直接可见。

套餐列表

GET /api/packages 公开
{
  "code": 0,
  "data": [
    { "id": 1, "name": "体验包", "code": "starter", "price": 9.9, "points": 10, "description": "10 次调用额度" },
    { "id": 2, "name": "标准包", "code": "standard", "price": 49,  "points": 100, "description": "100 次调用额度" }
  ]
}

price 单位元,points 为到账次数。

下单购买

POST /api/orders 需 token
参数类型说明
packageIdnumber套餐 ID
packageCodestring套餐编码
pointsnumber自定义充值次数(不走套餐时需 > 0)
amountnumber自定义金额(元)
remarkstring备注
curl -X POST https://www.jielafu.cn/api/orders \
  -H "Content-Type: application/json" -H "Authorization: Bearer utk_xxx" \
  -d '{"packageCode":"standard"}'
{
  "code": 0,
  "message": "下单成功,待支付",
  "data": {
    "id": 31, "orderNo": "ORD20261005033102a1b2",
    "packageName": "标准包", "amount": 49, "points": 100,
    "payStatus": "pending", "createdAt": "2026-10-05 03:31:02"
  }
}
下单后状态为 pending,管理员在后台确认收款后次数自动到账,客户端可用订单号展示给用户去付款。

我的订单

GET /api/orders/my?limit=20&payStatus=paid 需 token

payStatus 可筛 pending / paid / refunded,不传返回全部。

{
  "code": 0,
  "data": [
    { "id": 31, "orderNo": "ORD...", "packageName": "标准包", "amount": 49, "points": 100,
      "payStatus": "paid", "payMethod": "wechat", "paidAt": "2026-10-05 03:33:10",
      "createdAt": "2026-10-05 03:31:02" }
  ]
}

取消我的订单

POST /api/orders/my/{id}/cancel 需 token

只有待支付订单可以取消,且只能取消自己的订单。已支付或已取消的订单返回 409。

错误码

code含义客户端建议
0成功—
400参数错误检查必填项与类型
401未登录 / 凭证无效跳登录页重新登录
402额度不足引导购买套餐
403无权限 / 账号停用 / 功能停用提示联系管理员
404功能或资源不存在
409用户名已占用 / 订单状态冲突
429操作过于频繁稍后重试
500服务端异常稍后重试
502上游调用失败额度已自动返还,可重试
503功能维护中稍后再试
504上游超时额度已自动返还,可重试

完整示例

BASE=https://www.jielafu.cn

# 1. 登录
TOKEN=$(curl -s -X POST $BASE/api/users/login \
  -H "Content-Type: application/json" \
  -d '{"username":"alice","password":"123456"}' | grep -o '"token":"[^"]*"' | cut -d'"' -f4)
echo "token: $TOKEN"

# 2. 查余额
curl -s $BASE/api/users/me -H "Authorization: Bearer $TOKEN"

# 3. 看有哪些 AI 功能
curl -s $BASE/api/call

# 4. 调用即梦生图(扣 1 次)
curl -s -X POST $BASE/api/call/jimeng_v46 \
  -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" \
  -d '{"prompt":"赛博朋克风格的城市夜景"}'

# 5. 买套餐
curl -s -X POST $BASE/api/orders \
  -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" \
  -d '{"packageCode":"standard"}'

JavaScript

const BASE = 'https://www.jielafu.cn';
let token = localStorage.getItem('token');

async function api(path, body) {
  const res = await fetch(`$https://www.jielafu.cn${path}`, {
    method: body ? 'POST' : 'GET',
    headers: {
      'Content-Type': 'application/json',
      ...(token ? { Authorization: `Bearer ${token}` } : {}),
    },
    body: body ? JSON.stringify(body) : undefined,
  });
  const json = await res.json();
  if (json.code !== 0) throw new Error(`${json.code} ${json.message}`);
  return json.data;
}

// 登录:每次都要把新 token 存起来(旧的会失效)
const { token: t } = await api('/api/users/login', { username: 'alice', password: '123456' });
token = t;
localStorage.setItem('token', t);

// 调用 AI
const r = await api('/api/call/jimeng_v46', { prompt: '一只橘猫' });
console.log(r.result.images);

接入须知

1. token 必须更新:每次登录返回新 token,旧 token 立即失效,客户端一定要覆盖保存。
2. 额度即次数:points 就是剩余可调用次数,调用前可用 /api/users/me 判断。
3. 失败会返还:上游出错时若功能开启了失败返还,扣掉的次数自动退回,无需客户端处理。
4. 功能可能变动:可用功能与参数以 GET /api/call 返回的 paramSchema 为准,新增功能不需要改客户端代码。
5. 图片 URL 有效期:即梦返回的图片链接有有效期,建议客户端拿到后及时转存。