初始版本

This commit is contained in:
2026-04-23 16:30:57 +08:00
commit 0d0683a6e6
538 changed files with 113042 additions and 0 deletions

108
app/utils/request.ts Normal file
View File

@@ -0,0 +1,108 @@
import { useRequestFetch, useRuntimeConfig } from '#imports'
import { MODULES_API_URL, SERVER_API_URL, APP_API_URL } from '@/config/setting'
import { getTenantId } from '@/utils/domain'
import { getToken } from '@/utils/token-util'
type RequestConfig = {
params?: Record<string, any>
data?: any
headers?: Record<string, any>
responseType?: 'json' | 'blob' | 'text' | 'arrayBuffer'
}
type AxiosLikeResponse<T> = {
data: T
}
type NuxtFetch = ReturnType<typeof useRequestFetch>
type NuxtFetchOptions = NonNullable<Parameters<NuxtFetch>[1]>
type NuxtFetchMethod = NonNullable<NuxtFetchOptions['method']>
function getFetch(): NuxtFetch {
try {
return useRequestFetch()
} catch {
return globalThis.$fetch as unknown as NuxtFetch
}
}
function normalizeUrl(url: string) {
const config = useRuntimeConfig()
const serverBase = config.public.serverApiBase
const modulesBase = config.public.modulesApiBase
const appBase = config.public.appApiBase
if (url.startsWith(serverBase)) {
return SERVER_API_URL + url.slice(serverBase.length)
}
if (url.startsWith(modulesBase)) {
return MODULES_API_URL + url.slice(modulesBase.length)
}
if (url.startsWith(appBase)) {
return APP_API_URL + url.slice(appBase.length)
}
return url
}
function mergeHeaders(headers?: Record<string, any>) {
const config = useRuntimeConfig()
const tenantId = headers?.TenantId ?? headers?.tenantId ?? getTenantId(String(config.public.tenantId))
const token = getToken()
const merged: Record<string, string> = {
TenantId: String(tenantId)
}
if (token) {
merged.Authorization = token
}
if (headers) {
for (const [key, value] of Object.entries(headers)) {
if (value === undefined || value === null) continue
merged[key] = String(value)
}
}
return merged
}
function withDefaultModuleBase(url: string) {
if (url.startsWith('http://') || url.startsWith('https://')) return url
// 已带 /api 前缀的直接返回(避免重复拼接)
if (url.startsWith('/api/_server') || url.startsWith('/api/_modules') || url.startsWith('/api/_file')) return url
// App 模块走 /api/_app 前缀proxy: server/api/_app/[...path].ts
if (url.startsWith('/api/app')) return '/api/_app' + url.slice('/api/app'.length)
// 其余默认走 modules
if (!url.startsWith('/')) return MODULES_API_URL + '/' + url
return MODULES_API_URL + url
}
async function request<T>(
method: NuxtFetchMethod,
url: string,
body?: any,
config: RequestConfig = {}
): Promise<AxiosLikeResponse<T>> {
const $fetch = getFetch()
const normalized = withDefaultModuleBase(normalizeUrl(url))
const data = await $fetch<T>(normalized, {
method,
query: config.params,
body: body ?? config.data,
headers: mergeHeaders(config.headers),
responseType: config.responseType as any
})
return { data }
}
const requestClient = {
get: <T>(url: string, config?: RequestConfig) => request<T>('GET', url, undefined, config),
delete: <T>(url: string, config?: RequestConfig) => request<T>('DELETE', url, undefined, config),
post: <T>(url: string, data?: any, config?: RequestConfig) => request<T>('POST', url, data, config),
put: <T>(url: string, data?: any, config?: RequestConfig) => request<T>('PUT', url, data, config)
}
export default requestClient