知识库发布按钮通过查询当前版本是否之前已经发布过来控制按钮是置灰还是高亮
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 数据