From 5da54964920cdca8b60e3dfc1bd13f2b6b694b03 Mon Sep 17 00:00:00 2001 From: WangLeo <690854599@qq.com> Date: Tue, 2 Jun 2026 18:05:55 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=20API=20=E5=B1=82=E6=9E=B6?= =?UTF-8?q?=E6=9E=84=EF=BC=9A=E7=BB=9F=E4=B8=80=20HTTP=20=E8=AF=B7?= =?UTF-8?q?=E6=B1=82=E3=80=81=E6=96=B0=E5=A2=9E=E7=AE=97=E5=8A=9B=E8=B0=83?= =?UTF-8?q?=E5=BA=A6=E5=90=8E=E7=AB=AF=E8=B7=AF=E7=94=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 请求拦截器统一 Auth 头不带 Bearer 前缀,新增 /suanli 前缀路由到算力调度后端 - 任务创建/轮询/历史接口迁移至 apis/display,改为 axios 调用替代原始 fetch - 模型 API 分离为两层:apis 纯 HTTP 调用 + utils 缓存业务逻辑 - 新增历史任务列表接口 requestTaskHistory(支持 user_id/platform_code 筛选和分页) - 响应拦截器兼容 status/code 双字段,用户信息兼容新旧 data 格式 - 移除免费次数(freeTimes)体系 - 更新 CLAUDE.md 文档 --- .env.development | 6 +-- .env.production | 4 +- CLAUDE.md | 72 +++++++++++++++++++----------- components.d.ts | 3 ++ src/apis/auth/auth.js | 10 ++--- src/apis/display/index.js | 34 ++++++++++---- src/components/canvas/index.vue | 3 +- src/components/dialogBox/index.vue | 13 +----- src/stores/user.js | 49 ++++++++------------ src/utils/modelApi.js | 24 ++-------- src/utils/request.js | 26 +++++------ src/utils/websocket.js | 28 ++---------- src/views/home/display/index.vue | 14 +++--- 13 files changed, 129 insertions(+), 157 deletions(-) diff --git a/.env.development b/.env.development index b91e7f1..c6ad140 100644 --- a/.env.development +++ b/.env.development @@ -3,8 +3,7 @@ VITE_BASE = '/' # 主服务 VITE_API_PREFIX = '/api' -VITE_API_BASE_URL = 'http://test.xueai.art/api' # http://huanda.xueai.art http://106.54.11.219/api 43.248.131.153:8003 -VITE_API_WS_URL = 'ws://test.xueai.art/api' +VITE_API_BASE_URL = 'http://test.xueai.art/newapi/api' # http://huanda.xueai.art http://106.54.11.219/api 43.248.131.153:8003 # 支付服务 VITE_API_PAY_PREFIX = '/pay' @@ -12,7 +11,8 @@ VITE_API_PAY_TARGET = 'http://test.xueai.art' # http://43.248.133.202 test.xue # 任务处理模块 VITE_API_WORKFLOW_UPLOAD = 'http://43.248.97.19:4000/aigc/workflow/file/upload' # https://sxwz.xueai.art/workflow https://designtools.xueai.art/workflow -VITE_API_WORKFLOW_WS = 'ws://43.248.97.19:4000/testworkflow' +VITE_API_TASK_PREFIX = '/suanli' +VITE_API_TASK_TARGET = 'http://test.xueai.art' # 是否开启开发者工具 VITE_OPEN_DEVTOOLS = false diff --git a/.env.production b/.env.production index ab104c6..c14eeb0 100644 --- a/.env.production +++ b/.env.production @@ -7,7 +7,6 @@ VITE_BUILD_MOCK = false # 主服务 VITE_API_PREFIX = '/api' VITE_API_BASE_URL = 'https://sxwz.xueai.art/api' -VITE_API_WS_URL = 'wss://sxwz.xueai.art/api' # 支付服务 VITE_API_PAY_PREFIX = '/pay' @@ -15,7 +14,8 @@ VITE_API_PAY_TARGET = 'https://sxwz.xueai.art' # http://43.248.133.202 # 任务处理模块 VITE_API_WORKFLOW_UPLOAD = 'https://designtools.xueai.art/workflow/file/upload' # https://sxwz.xueai.art/workflow https://designtools.xueai.art/workflow -VITE_API_WORKFLOW_WS = 'wss://talkingdraw.xueai.art/testworkflow' +VITE_API_TASK_PREFIX = '/suanli' +VITE_API_TASK_TARGET = 'http://test.xueai.art' # 模型资源 VITE_API_MODEL_RESOURCE = 'https://resources.xueai.art/AIGC' diff --git a/CLAUDE.md b/CLAUDE.md index d288bdc..257feca 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -16,7 +16,7 @@ Vue 3 (Composition API) + Vite 7 + Pinia + Vue Router + Element Plus + Less + pn ## 架构概览 -AI 绘画/视频生成前端操作平台,通过 HTTP 接口对接后端和第三方 AI 平台(RunningHub),提交生成任务并轮询结果。 +AI 绘画/视频生成前端操作平台,通过 HTTP 接口对接算力调度后端(suanli)和第三方 AI 平台(RunningHub),提交生成任务并轮询结果。 ### 关键目录 @@ -25,36 +25,70 @@ src/ ├── main.js # 入口:创建 Vue 应用,安装 Pinia/Router/VueVirtualScroller ├── router/index.js # 路由定义 + token 验证守卫 ├── stores/ # Pinia 状态管理 -│ ├── user.js # 用户认证、信息、免费次数 +│ ├── user.js # 用户认证、信息 │ └── display.js # 生成历史列表、UI 状态(滚动、画布等) -├── apis/ # HTTP API 模块(auth/display),通过 axios 实例调用 +├── apis/ # HTTP API 层:纯请求封装,不含业务逻辑 +│ ├── auth/ # 认证相关(登录、token 校验、用户信息) +│ └── display/ # 任务创建/轮询/历史、平台模型、收藏/删除 ├── components/ # 通用组件 │ ├── dialogBox/ # 生成参数输入面板(核心交互入口),含模型选择、比例、上传等子组件 │ ├── virtual-scroller/# 虚拟滚动列表组件(自定义实现,reverse 模式) │ └── canvas/ # 图片画布编辑(圆/矩形选区,局部重绘) ├── views/ # 页面(home、login) ├── utils/ -│ ├── request.js # Axios 实例,拦截器处理 token 和不同服务的 baseURL 路由 -│ ├── websocket.js # 任务生成入口:HTTP POST 创建任务 + 20s 轮询获取结果 +│ ├── request.js # Axios 实例 + 拦截器:统一 Auth(不带 Bearer)+ 按前缀路由 baseURL +│ ├── websocket.js # 任务生成入口:组装参数 → 调用 API → 20s 轮询直至完成/失败 +│ ├── modelApi.js # 模型业务层:localStorage 每日缓存 + 模型名称→UUID 查找 │ ├── createTask.js # 调用平台适配器 Playload() 构造任务 body │ ├── modelConfig.js # 从远程 JSON 加载 workflow 配置,localStorage 每日缓存 -│ ├── modelApi.js # 从 /suanli/v1/platforms/:code/models 获取模型列表及 UUID │ └── auth.ts # token 存取工具(localStorage) ├── config/ │ ├── index.js # 平台配置入口,导出 runninghub 适配器 │ └── runninghub/ # RunningHub 平台适配器:Playload() 构造和 result() 解析 ``` +### API 层设计原则 + +- `src/apis/` 中的函数只做**纯 HTTP 调用**(`service.get/post/delete` 等),不包含缓存、localStorage、业务判断等逻辑 +- 缓存、数据转换等业务逻辑放在 `src/utils/` 中,调用 apis 层的原始函数 + +示例:`utils/modelApi.js` 导入 `apis/display` 的原始 `fetchPlatformModels`,在其上叠加 localStorage 每日缓存和 `getModelId` 查找逻辑。 + ### 核心数据流 1. 用户在 `dialogBox` 中设置参数(模型、提示词、比例、上传图片等) 2. 点击生成 → `dialogBox:handleStart()` 组装 data(含 modelId、params、imgs、request) 3. 调用 `websocket.js:generate(data, generateData)` 4. `generate()` 内部先通过 `createTask(data)` → `runninghub.Playload()` 构造 RunningHub workflow payload 作为 body -5. 调用 `modelApi.getModelId(type, modelName)` 从 `/suanli/v1/platforms/:code/models` 查找模型 UUID(带 localStorage 每日缓存) -6. POST `/api/v1/tasks` 提交任务(`{ model_id, body, request }`),携带 `X-Session-Id` 用于预扣费 +5. 调用 `modelApi.getModelId(type, modelName)` 查找模型 UUID(带 localStorage 每日缓存) +6. 调用 `requestCreateTask(body, sessionId)` → POST `/suanli/v1/tasks`(`{ model_id, body, request }`,携带 `X-Session-Id` 用于预扣费) 7. 返回 task_id → `displayStore.addGeneratingItem()` 在前端列表插入"生成中"条目 -8. 每 20 秒轮询 GET `/api/v1/tasks/{task_id}`,completed 时调用 `updateItemToSuccess()` 更新列表 +8. 每 20 秒轮询 `requestTaskStatus(taskId)` → GET `/suanli/v1/tasks/{task_id}`,completed 时调用 `updateItemToSuccess()` 更新列表 + +### 接口速查 + +| 函数 | 端点 | 用途 | +|------|------|------| +| `requestCreateTask` | POST `/suanli/v1/tasks` | 创建生成任务 | +| `requestTaskStatus` | GET `/suanli/v1/tasks/:id` | 查询单个任务状态 | +| `requestTaskHistory` | GET `/suanli/v1/tasks/history` | 历史任务列表(支持 `user_id`/`platform_code`/`page`/`pageSize`) | +| `fetchPlatformModels` | GET `/suanli/v1/platforms/:code/models` | 获取平台模型列表 | +| `cancelOrCollect` | POST `/collect/toggle` | 收藏/取消收藏 | +| `deleteGenerateHistory` | DELETE `/taskRecordHistory/delete` | 删除历史记录 | + +### 请求拦截器路由 + +拦截器统一设置 `Authorization: `(不带 Bearer 前缀),根据 URL 前缀切换后端: + +| URL 前缀 | 环境变量 | 示例 target | +|----------|----------|-------------| +| `/suanli` | `VITE_API_TASK_TARGET` | `http://test.xueai.art` | +| `/pay` | `VITE_API_PAY_TARGET` | `http://test.xueai.art` | +| 其他 | `VITE_API_BASE_URL`(默认) | `http://test.xueai.art/newapi/api` | + +### 响应格式兼容 + +响应拦截器同时识别 `code === 0` 和 `status === 0` 两种成功状态。用户信息接口兼容新旧两种格式:`data.userInfo` 嵌套(新)和 `data` 扁平(旧),在 store 的 `getInfo()` 中做了 `const u = res.data.userInfo || res.data` 的兼容处理。 ### 平台编码映射 @@ -63,28 +97,14 @@ src/ | Painting | `ai_painting_talk` | | Video | `ai_video_talk` | +映射函数 `getPlatformCode()` 位于 `utils/modelApi.js`。 + ### 自动导入 - `unplugin-auto-import`:自动导入 Vue/Router/Pinia API,`.vue` 中无需手动 import - `unplugin-vue-components`:自动注册 `src/components/` 下的组件和 Element Plus 组件 - Element Plus 图标通过 `unplugin-icons` 按需加载 -### 环境变量 - -`VITE_API_BASE_URL` 定义主 API 地址(含 `/api` 后缀)。请求拦截器根据 URL 前缀自动切换后端服务: - -| 前缀 | 用途 | -|------|------| -| `/pay` | 支付服务 | -| `/api`(默认) | 主服务(含任务创建 `/api/v1/tasks`) | - -新增的 `/suanli` 接口使用 `VITE_API_BASE_URL` 去掉 `/api` 后缀作为基础 URL。 - ### 路由守卫 -`src/router/index.js` 的 `beforeEach` 守卫检查 token 存在性和有效性(调用 `/auth/check/token`),无效则跳转 `/login`。支持通过 URL query `?token=xxx` 传入 token。 - -### Authorization 头 - -- 通过 axios 的请求(auth/display 等):拦截器自动加 `Bearer` 前缀 -- 通过 fetch 的请求(任务创建/轮询/模型列表):直接传 token,**不加** `Bearer` 前缀 +`src/router/index.js` 的 `beforeEach` 守卫检查 token 存在性和有效性(调用 `POST /login/validateToken`),无效则跳转 `/login`。支持通过 URL query `?token=xxx` 传入 token。 diff --git a/components.d.ts b/components.d.ts index ed64dd7..5fdb244 100644 --- a/components.d.ts +++ b/components.d.ts @@ -11,7 +11,10 @@ export {} /* prettier-ignore */ declare module 'vue' { export interface GlobalComponents { + 2: typeof import('./src/components/virtual-scroller/VirtualScroller copy 2.vue')['default'] + 3: typeof import('./src/components/virtual-scroller/VirtualScroller copy 3.vue')['default'] Canvas: typeof import('./src/components/canvas/index.vue')['default'] + copy: typeof import('./src/components/virtual-scroller/VirtualScroller copy.vue')['default'] DialogBox: typeof import('./src/components/dialogBox/index.vue')['default'] ElButton: typeof import('element-plus/es')['ElButton'] ElDatePicker: typeof import('element-plus/es')['ElDatePicker'] diff --git a/src/apis/auth/auth.js b/src/apis/auth/auth.js index dcced7c..3671381 100644 --- a/src/apis/auth/auth.js +++ b/src/apis/auth/auth.js @@ -38,14 +38,10 @@ export function logout() { /** @desc 获取用户信息 */ export const getUserInfo = () => { - return service.get(`${BASE_URL}/user/info`) -} - -/** @desc 获取路由信息 */ -export const getUserRoute = () => { - return service.get(`${BASE_URL}/route`) + return service.get(`/sysUser/currentUser +`) } export const checkUsertoken = () => { - return service.get(`${BASE_URL}/check/token`) + return service.post(`/login/validateToken`) } diff --git a/src/apis/display/index.js b/src/apis/display/index.js index da66eac..581246e 100644 --- a/src/apis/display/index.js +++ b/src/apis/display/index.js @@ -1,9 +1,6 @@ import service from '@/utils/request' -// 获取生成历史列表 -export function getGenerateHistoryList(query) { - return service.get('/taskRecordHistory', { params: query }) -} +// ==================== 历史记录 API(axios) ==================== // 取消或收藏 export function cancelOrCollect(query) { @@ -15,7 +12,28 @@ export function deleteGenerateHistory(query) { return service.delete('/taskRecordHistory/delete', { params: query }) } -// 获取免费次数 -export function getFreeTimes(id) { - return service.get('/plantformBalance/userBalances', { params: { id } }) -} \ No newline at end of file +// ==================== 任务 API(axios,经由 /suanli 前缀路由到算力调度后端) ==================== + +// 创建生成任务(HTTP POST /suanli/v1/tasks) +export function requestCreateTask(body, sessionId) { + return service.post('/suanli/v1/tasks', body, { + headers: { 'X-Session-Id': sessionId } + }) +} + +// 查询任务状态 / 获取历史任务结果(HTTP GET /suanli/v1/tasks/:id) +export function requestTaskStatus(taskId) { + return service.get(`/suanli/v1/tasks/${taskId}`) +} + +// 获取历史任务列表(HTTP GET /suanli/v1/tasks/history,支持平台筛选和分页) +export function requestTaskHistory(params) { + return service.get('/suanli/v1/tasks/history', { params }) +} + +// ==================== 平台模型 API ==================== + +// 获取平台模型列表(原始 HTTP 调用,不含缓存逻辑) +export function fetchPlatformModels(code) { + return service.get(`/suanli/v1/platforms/${code}/models`) +} diff --git a/src/components/canvas/index.vue b/src/components/canvas/index.vue index 794f742..bdae582 100644 --- a/src/components/canvas/index.vue +++ b/src/components/canvas/index.vue @@ -161,7 +161,7 @@