知识库发布按钮引发的查询版本发布状态(轮询?——>调用后端接口)以及api接口设计学习

知识库发布按钮通过查询当前版本是否之前已经发布过来控制按钮是置灰还是高亮

javascript 复制代码
  // 检查是否有待发布的任务
  const checkPublishStatus = useCallback(async () => {
    if (!kbId) {
      setHasPendingPublishTasks(false)
      return
    }

    try {
      const result = await api.tasks.list({
        task_type: 'upload',
        kb_id: kbId,
        page: 1,
        page_size: 1
      })

      const tasks = Array.isArray(result) ? result : (result?.items || result?.list || [])

      if (!tasks || tasks.length === 0) {
        setHasPendingPublishTasks(false)
        return
      }

      const hasPending = tasks.some(task => {
        const status = String(task.status || '').toLowerCase()
        const completedStatuses = ['completed', 'done', 'success', 'failed', 'error', 'cancelled', 'canceled']
        return !completedStatuses.includes(status) &&
          (status === 'pending' || status === 'running' || status === 'processing' || status === 'waiting' || status === '')
      })

      setHasPendingPublishTasks(hasPending)
    } catch (err) {
      console.error('检查发布状态失败:', err)
      setHasPendingPublishTasks(true)
    }
  }, [kbId])

  // 当kbId变化或文件列表更新时,检查发布状态
  useEffect(() => {
    checkPublishStatus()
  }, [checkPublishStatus])

  useEffect(() => {
    if (kbId && items.length > 0) {
      const timer = setTimeout(() => {
        checkPublishStatus()
      }, 1000)
      return () => clearTimeout(timer)
    }
  }, [kbId, items.length, checkPublishStatus])

这里我详细的理清他的后端逻辑,他是如何向后端请求接口的

【怎么调用后端接口来查询版本发布状态的?】

task_type 必须要是upload

首先第一个我觉得值得学习的就是这个自检查机制

这样子看我们还看不太懂,接下来我们去做详细的剖析

用useEffect套了两层,蛮妙

还有一个我觉得值得学习的就是整个项目的api接口设计

javascript 复制代码
// Task management
tasks: {
  list: ({ task_type, kb_id, status, page = 1, page_size = 20 } = {}) =>
    request('GET', '/v1/tasks/list', { query: { task_type, kb_id, status, page, page_size } }),
  // ...
}
javascript 复制代码
async function request(method, path, { query, body, token, headers, requireAuth = true, responseType } = {}) {
  // 1. 处理认证 token
  if (requireAuth && !token) {
    const storedToken = tokenManager.getToken()
    // ... token 处理逻辑
  }

  // 2. 构建完整的 URL
  const fullPath = API_BASE + API_PREFIX + path
  // API_BASE = '' (空字符串,使用代理)
  // API_PREFIX = '/api'
  // path = '/v1/tasks/list'
  // 最终: '/api/v1/tasks/list'
  
  const url = new URL(fullPath, window.location.origin)
  
  // 3. 添加查询参数
  if (query) {
    Object.entries(query).forEach(([k, v]) => {
      if (v !== undefined && v !== null && v !== '') {
        url.searchParams.append(k, String(v))
      }
    })
  }
  // 最终 URL: http://localhost:5173/api/v1/tasks/list?task_type=upload&kb_id=xxx&page=1&page_size=1

  // 4. 构建请求选项
  const requestOptions = {
    method: 'GET',  // HTTP 方法
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`  // 添加认证头
    }
  }

  // 5. 发送请求(使用浏览器原生的 fetch API)
  const res = await fetch(url.toString(), requestOptions)
  
  // 6. 处理响应
  const data = await res.json()
  return data
}

完整调用流程

javascript 复制代码
你在代码中调用:
  api.tasks.list({ task_type: 'upload', kb_id: kbId, page: 1, page_size: 1 })
         ↓
tasks.list 方法执行:
  request('GET', '/v1/tasks/list', { query: { task_type: 'upload', kb_id: kbId, ... } })
         ↓
request 函数执行:
  1. 获取 token
  2. 构建 URL: '/api/v1/tasks/list'
  3. 添加查询参数: ?task_type=upload&kb_id=xxx&page=1&page_size=1
  4. 添加 Authorization 头: Bearer token
         ↓
fetch API 发送 HTTP 请求:
  GET http://localhost:5173/api/v1/tasks/list?task_type=upload&kb_id=xxx&page=1&page_size=1
  Headers: {
    Authorization: Bearer xxx,
    Content-Type: application/json
  }
         ↓
后端服务器接收请求并处理
         ↓
返回响应数据
         ↓
request 函数解析响应并返回
         ↓
你得到 result 数据
相关推荐
二哈赛车手6 小时前
新人笔记---ApiFox的一些常见使用出错
java·笔记·spring
代码搬运媛6 小时前
Jest 测试框架详解与实现指南
前端
栗子~~7 小时前
JAVA - 二层缓存设计(本地缓冲+redis缓冲+广播所有本地缓冲失效) demo
java·redis·缓存
YDS8297 小时前
DeepSeek RAG&MCP + Agent智能体项目 —— RAG知识库的搭建和接口实现
java·ai·springboot·agent·rag·deepseek
counterxing7 小时前
我把 Codex 里的 Skills 做成了一个 MCP,还支持分享
前端·agent·ai编程
wangqiaowq7 小时前
windows下nginx的安装
linux·服务器·前端
之歆8 小时前
DAY_12JavaScript DOM 完全指南(二):实战与性能篇
开发语言·前端·javascript·ecmascript
发现一只大呆瓜8 小时前
Vite凭什么这么快?3分钟带你彻底搞懂 Vite 热更新的幕后黑手
前端·面试·vite
Maimai108088 小时前
React如何用 @microsoft/fetch-event-source 落地 SSE:比原生 EventSource 更灵活的实时推送方案
前端·javascript·react.js·microsoft·前端框架·reactjs·webassembly
candyTong8 小时前
Claude Code 的 Edit 工具是怎么工作的
javascript·后端·架构