知识库发布按钮引发的查询版本发布状态(轮询?——>调用后端接口)以及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 数据
相关推荐
running up2 小时前
Spring IOC/DI 核心知识
java·spring·rpc
fantasy5_52 小时前
C++ 智能指针深度解析:原理、实现与实战避坑
java·开发语言·c++
q_19132846952 小时前
基于SpringBoot2+Vue2的企业合作与活动管理平台
java·vue.js·经验分享·spring boot·笔记·mysql·计算机毕业设计
凌冰_2 小时前
JAVA与MySQL实现银行管理系统
java·开发语言·mysql
sleeppingfrog2 小时前
konva实现canvas画图基础版本
前端·javascript·css
Han.miracle2 小时前
Spring WebMVC入门实战:从概念到连接建立全解析
java·spring boot·spring·springmvc
Savvy..2 小时前
RabbitMQ
java·rabbitmq·java-rabbitmq
TT哇2 小时前
Spring Boot 项目中关于文件上传与访问的配置方案
java·spring boot·后端
jingling5552 小时前
Mark3D | 用 Mars3D 实现一个炫酷的三维地图
前端·javascript·3d·前端框架·html