orval openApi接口生成

orval 是一个适合大型项目接口生成的openApi typescript接口文档的 工具库。

1、安装依赖

pnpm add orval -D

2、orval.config.ts配置文件

import { defineConfig } from 'orval';
export default defineConfig({
  api: {
    input: 'http://127.0.0.1:18880/api-doc/openapi.json/pc',
    output: {
      target: '../../src/services/clfSign.ts',
      mode: 'tags',
      schemas: '../../src/services/schemas',
      operationSchemas: '../../src/services/operationSchemas',
      clean: true,
      override: {
        mutator: {path: './customClient.ts',name: 'customClient'},
        header: () => 'orval 配合umi接口生成',
      },
    },
    hooks: {
      afterAllFilesWrite: 'prettier --write',
    },
  },
});

3、orval 配合umi接口生成

mutator 请求适配文件。

import { request } from '@umijs/max';
export const customClient = async <T>(config: { [key: string]: any }, opts?: { [key: string]: any }): Promise<T>=> {
  const { url, ...rest } = config;
  return await request(url, { ...rest, params: { ...rest?.params }, ...(opts || {}) }).then(({ data }) => data);
};
export default customClient;

4、orval 配合uni-app接口生成

mutator 请求适配文件

interface RequestConfig {
  url: string
  method: string
  params?: Record<string, string | number | boolean | undefined>
  data?: unknown
  headers?: Record<string, string>
}

export const customClient = async <T>({url,method,params,data,headers = {}}: RequestConfig): Promise<T> => {
  const queryString = params
    ? `?${new URLSearchParams(
        Object.entries(params).reduce(
          (acc, [key, value]) => {
            if (value !== undefined) {
              acc[key] = String(value)
            }
            return acc
          },
          {} as Record<string, string>
        )
      ).toString()}`
    : ''
  const fullUrl = `${url}${queryString}`
  const sessionToken = uni.getStorageSync('access_token') || ''
  const defaultHeaders: Record<string, string> = {
    ...(sessionToken && {
      Authorization: `Bearer ${sessionToken}`,
    }),
    ...headers,
  }

  return new Promise((resolve, reject) => {
    uni.request({
      url: fullUrl,
      method: method as 'GET' | 'POST' | 'PUT' | 'DELETE',
      data,
      header: defaultHeaders,
      withCredentials: false,
      success: res => {
        const responseData = res.data as T
        if (res.statusCode >= 200 && res.statusCode < 300) {
          resolve(responseData)
        } else {
          if (res.statusCode === 401 || res.statusCode === 403) {
            uni.setStorageSync('access_token', '')
            uni.navigateTo({ url: '/pages/Login/index' })
            reject(new Error('会话已过期,正在跳转到登录页面'))
            return
          }
          if (res.statusCode === 500) {
            uni.showToast({
              title: (res.data as any)?.errorMessage,
              icon: 'error',
              duration: 5000,
            })
            resolve(responseData)
            return
          }
          const errorMessage =
            typeof res.data === 'object' && res.data && 'message' in res.data
              ? (res.data as any).message
              : '未知错误'
          reject(
            new Error(`请求失败,状态码 ${res.statusCode}:${errorMessage}`)
          )
        }
      },
      fail: err => {
        uni.showToast({
          title: err.errMsg || '未知错误',
          icon: 'error',
          duration: 5000,
        })
        reject(new Error(`API 请求失败:${err.errMsg || '未知错误'}`))
      },
    })
  })
}

启动命令根据配置文件生成接口

"scripts":{
   "openapi": "orval --config ./config/orvalConfig/orval.config.ts"
}
posted @ 2026-02-10 15:46  boygdm  阅读(3)  评论(0)    收藏  举报