- 在补数任务面板中添加入库类型单选按钮组,支持 MySQL 和 InfluxDB - 更新 AddData 接口定义,添加 StorageType 相关类型和选项接口 - 修改补数 API 请求逻辑,根据入库类型动态调整接口路径前缀 - 重构台账设备表单,统一使用装置网络参数作为 MAC 和 NDID 的单一数据源 - 优化台账线路表单,仅当存在 ID 时才设置 lineId 字段,避免空值传递 - 添加入库类型列表获取接口和相关数据处理逻辑 - 更新台账字典代码常量,新增终端型号字典码 - 优化台账树节点添加逻辑,增加前置条件验证和禁用原因提示 - 添加 InfluxDB 配置文件到额外资源目录 - 更新稳定数据分析视图,优化台账树数据结构处理和样式布局 - 完善 API 调试契约检查,确保设备和线路数据映射正确性 - 优化趋势查询性能,禁用全局加载状态提升用户体验
109 lines
3.9 KiB
TypeScript
109 lines
3.9 KiB
TypeScript
import http from '@/api'
|
|
import type { ResultData } from '@/api/interface'
|
|
import type { AddData } from './interface'
|
|
|
|
type AddDataRequestMethod = 'get' | 'post'
|
|
|
|
const ADD_DATA_ROUTE_PATHS = ['/addData', '/api/addData'] as const
|
|
const ADD_DATA_BASE_URL = String(import.meta.env.VITE_API_URL || '').trim()
|
|
const ADD_DATA_INFLUX_STORAGE_TYPE = 'INFLUXDB'
|
|
|
|
const resolveDevProxyTarget = () => {
|
|
const proxyConfig = import.meta.env.VITE_PROXY
|
|
if (!Array.isArray(proxyConfig)) return ''
|
|
|
|
const matchedProxy = proxyConfig.find(item => Array.isArray(item) && item[0] === '/api')
|
|
if (!matchedProxy?.[1]) return ''
|
|
|
|
return String(matchedProxy[1]).replace(/\/+$/, '')
|
|
}
|
|
|
|
const buildAddDataRequestPaths = (path: string) => {
|
|
const requestPaths = new Set<string>()
|
|
const devProxyTarget = resolveDevProxyTarget()
|
|
|
|
for (const routePath of ADD_DATA_ROUTE_PATHS) {
|
|
if (ADD_DATA_BASE_URL === '/api' && routePath.startsWith('/api/')) {
|
|
if (devProxyTarget) {
|
|
requestPaths.add(`${devProxyTarget}${routePath}${path}`)
|
|
}
|
|
|
|
requestPaths.add(`${window.location.origin}${routePath}${path}`)
|
|
continue
|
|
}
|
|
|
|
requestPaths.add(`${routePath}${path}`)
|
|
}
|
|
|
|
return Array.from(requestPaths)
|
|
}
|
|
|
|
const isFallbackableAddDataError = (error: unknown) => {
|
|
const responseCode = typeof error === 'object' && error !== null && 'code' in error ? String(error.code) : ''
|
|
const responseMessage = typeof error === 'object' && error !== null && 'message' in error ? String(error.message) : ''
|
|
const normalizedMessage = responseMessage.toLowerCase()
|
|
|
|
// 部分部署环境会把未命中的 addData 路由转到旧的操作分发入口,
|
|
// 前端在识别到“unknown operate”或典型路由错误时回退到备用前缀重试一次。
|
|
return (
|
|
responseCode === '404' ||
|
|
normalizedMessage.includes('unknown operate') ||
|
|
normalizedMessage.includes('not found') ||
|
|
normalizedMessage.includes('no handler found')
|
|
)
|
|
}
|
|
|
|
const requestAddData = async <T>(
|
|
method: AddDataRequestMethod,
|
|
path: string,
|
|
params?: object
|
|
): Promise<ResultData<T>> => {
|
|
let lastError: unknown
|
|
const requestPaths = buildAddDataRequestPaths(path)
|
|
|
|
for (let index = 0; index < requestPaths.length; index += 1) {
|
|
const requestPath = requestPaths[index]
|
|
|
|
try {
|
|
if (method === 'get') {
|
|
return await http.get<T>(requestPath)
|
|
}
|
|
|
|
return await http.post<T>(requestPath, params)
|
|
} catch (error) {
|
|
lastError = error
|
|
|
|
if (index === requestPaths.length - 1 || !isFallbackableAddDataError(error)) {
|
|
throw error
|
|
}
|
|
}
|
|
}
|
|
|
|
throw lastError
|
|
}
|
|
|
|
const resolveTaskPathPrefix = (storageType?: AddData.StorageType) => {
|
|
// MySQL 与 InfluxDB 任务接口相互独立,创建和状态轮询必须使用同一入库类型前缀。
|
|
return storageType === ADD_DATA_INFLUX_STORAGE_TYPE ? '/influx/task' : '/task'
|
|
}
|
|
|
|
export const getAddDataStorageTypeList = () => {
|
|
return requestAddData<AddData.StorageTypeItem[]>('get', '/storage-type/list')
|
|
}
|
|
|
|
export const getAddDataPreview = (params: AddData.TaskRequestParams) => {
|
|
return requestAddData<AddData.PreviewResponse>('post', '/task/preview', params)
|
|
}
|
|
|
|
export const createAddDataTask = (params: AddData.TaskRequestParams, storageType?: AddData.StorageType) => {
|
|
return requestAddData<AddData.CreateTaskResponse>('post', `${resolveTaskPathPrefix(storageType)}/create`, params)
|
|
}
|
|
|
|
export const getAddDataTaskStatus = (taskId: string | number, storageType?: AddData.StorageType) => {
|
|
return requestAddData<AddData.TaskStatusResponse>('get', `${resolveTaskPathPrefix(storageType)}/status/${taskId}`)
|
|
}
|
|
|
|
export const getAddDataTemplateList = () => {
|
|
return requestAddData<AddData.TemplateItem[]>('get', '/template/list')
|
|
}
|