知识库发布按钮引发的查询版本发布状态(轮询?——>调用后端接口)以及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 数据
相关推荐
专注VB编程开发20年5 小时前
压栈顺序是反向(从右往左)的,但正因为是反向压栈,所以第一个参数反而离栈顶(ESP)最近。
java·开发语言·算法
椰汁菠萝5 小时前
spring boot下使用gdal解析tif文件
java·native·gdal·0
better_liang5 小时前
每日Java面试场景题知识点之-ELK日志分析
java·elk·微服务·面试题·日志分析·企业级开发
funnycoffee1235 小时前
F5 Big IP如何设置web和SSH登录的白名单
前端·tcp/ip·ssh
图南随笔5 小时前
Spring Boot(二十三):RedisTemplate的Set和Sorted Set类型操作
java·spring boot·redis·后端·缓存
say_fall5 小时前
C++ 类与对象易错点:初始化列表顺序 / 静态成员访问 / 隐式类型转换
android·java·开发语言·c++
JarvanMo5 小时前
国产 App,求你放过我的 iPhone 电量吧!
前端
先飞的笨鸟5 小时前
2026 年 Expo + React Native 项目接入微信分享完整指南
前端·ios·app
angelQ5 小时前
Vercel部署:前后端分离项目的整体部署流程及问题排查
前端·javascript
AI前端老薛5 小时前
CSS实现动画的几种方式
前端·css