知识库发布按钮引发的查询版本发布状态(轮询?——>调用后端接口)以及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 数据
相关推荐
To_OC5 小时前
LC 131 分割回文串:刚学回溯时,我连怎么切字符串都想不明白
javascript·算法·leetcode
咩咩啃树皮5 小时前
第40篇:Vue3组件化开发精讲——组件拆分、复用、父子通信、工程化架构
java·前端·架构
阳光是sunny5 小时前
LangGraph中的Reducer是什么
前端·人工智能·后端
触底反弹5 小时前
一文搞懂 Tailwind CSS 弹性布局:从原理到实战
前端·css·html
阳光是sunny6 小时前
从链到图:LangGraph 入门基础全解析
前端·人工智能·后端
鱟鲥鳚6 小时前
Spring Boot 集成 LangChain4j:从模型调用到 Tool Calling(Demo版)
java·spring boot
To_OC6 小时前
LC 42 接雨水:暴力超时卡半天?前后缀数组一用就通了
javascript·算法·leetcode
小林ixn6 小时前
从 ??= 到 onKeyDown:一个 React 组件的“自我修养”
前端·javascript·react.js
REDcker7 小时前
显示分辨率标准对照详解
前端·网络·分辨率·显示·屏幕
এ慕ོ冬℘゜7 小时前
前端实战:jQuery 多条件联合搜索(标题模糊查询 + 日历时间段筛选)
前端·javascript·jquery