mirror of
				https://github.com/soybeanjs/soybean-admin.git
				synced 2025-11-04 15:53:43 +08:00 
			
		
		
		
	refactor(projects): 请求适配器函数范型重构、优化请求相关的命名
This commit is contained in:
		@@ -1,30 +1,33 @@
 | 
			
		||||
/** 请求环境配置 */
 | 
			
		||||
/** 请求服务的环境配置 */
 | 
			
		||||
type ServiceEnv = Record<ServiceEnvType, ServiceEnvConfig>;
 | 
			
		||||
 | 
			
		||||
/** 不同服务的环境配置 */
 | 
			
		||||
/** 不同请求服务的环境配置 */
 | 
			
		||||
const serviceEnv: ServiceEnv = {
 | 
			
		||||
  dev: {
 | 
			
		||||
    pattern: '/proxy-pattrn',
 | 
			
		||||
    url: 'http://localhost:8080',
 | 
			
		||||
    proxy: '/proxy-flag'
 | 
			
		||||
    secondUrl: 'http://localhost:8081'
 | 
			
		||||
  },
 | 
			
		||||
  test: {
 | 
			
		||||
    pattern: '/proxy-pattrn',
 | 
			
		||||
    url: 'http://localhost:8080',
 | 
			
		||||
    proxy: '/proxy-flag'
 | 
			
		||||
    secondUrl: 'http://localhost:8081'
 | 
			
		||||
  },
 | 
			
		||||
  prod: {
 | 
			
		||||
    pattern: '/proxy-pattrn',
 | 
			
		||||
    url: 'http://localhost:8080',
 | 
			
		||||
    proxy: '/proxy-flag'
 | 
			
		||||
    secondUrl: 'http://localhost:8081'
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 获取当前模式的环境配置
 | 
			
		||||
 * 获取当前环境模式下的请求服务的配置
 | 
			
		||||
 * @param env 环境
 | 
			
		||||
 */
 | 
			
		||||
export function getEnvConfig(env: ImportMetaEnv) {
 | 
			
		||||
  const { VITE_ENV_TYPE = 'dev' } = env;
 | 
			
		||||
export function getServiceEnvConfig(env: ImportMetaEnv) {
 | 
			
		||||
  const { VITE_SERVICE_ENV = 'dev' } = env;
 | 
			
		||||
 | 
			
		||||
  const envConfig = serviceEnv[VITE_ENV_TYPE];
 | 
			
		||||
  const config = serviceEnv[VITE_SERVICE_ENV];
 | 
			
		||||
 | 
			
		||||
  return envConfig;
 | 
			
		||||
  return config;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -9,10 +9,15 @@ export function createViteProxy(isOpenProxy: boolean, envConfig: ServiceEnvConfi
 | 
			
		||||
  if (!isOpenProxy) return undefined;
 | 
			
		||||
 | 
			
		||||
  const proxy: Record<string, string | ProxyOptions> = {
 | 
			
		||||
    [envConfig.proxy]: {
 | 
			
		||||
    [envConfig.pattern]: {
 | 
			
		||||
      target: envConfig.url,
 | 
			
		||||
      changeOrigin: true,
 | 
			
		||||
      rewrite: path => path.replace(new RegExp(`^${envConfig.proxy}`), '')
 | 
			
		||||
      rewrite: path => path.replace(new RegExp(`^${envConfig.pattern}`), '')
 | 
			
		||||
    },
 | 
			
		||||
    [envConfig.pattern]: {
 | 
			
		||||
      target: envConfig.secondUrl,
 | 
			
		||||
      changeOrigin: true,
 | 
			
		||||
      rewrite: path => path.replace(new RegExp(`^${envConfig.pattern}`), '')
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								package.json
									
									
									
									
									
								
							@@ -7,12 +7,12 @@
 | 
			
		||||
    "url": "https://github.com/honghuangdc"
 | 
			
		||||
  },
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "dev": "cross-env VITE_ENV_TYPE=dev vite",
 | 
			
		||||
    "dev:test": "cross-env VITE_ENV_TYPE=test vite",
 | 
			
		||||
    "dev:prod": "cross-env VITE_ENV_TYPE=prod vite",
 | 
			
		||||
    "build": "npm run typecheck && cross-env VITE_ENV_TYPE=prod vite build",
 | 
			
		||||
    "build:dev": "npm run typecheck && cross-env VITE_ENV_TYPE=dev vite build",
 | 
			
		||||
    "build:test": "npm run typecheck && cross-env VITE_ENV_TYPE=test vite build",
 | 
			
		||||
    "dev": "cross-env VITE_SERVICE_ENV=dev vite",
 | 
			
		||||
    "dev:test": "cross-env VITE_SERVICE_ENV=test vite",
 | 
			
		||||
    "dev:prod": "cross-env VITE_SERVICE_ENV=prod vite",
 | 
			
		||||
    "build": "npm run typecheck && cross-env VITE_SERVICE_ENV=prod vite build",
 | 
			
		||||
    "build:dev": "npm run typecheck && cross-env VITE_SERVICE_ENV=dev vite build",
 | 
			
		||||
    "build:test": "npm run typecheck && cross-env VITE_SERVICE_ENV=test vite build",
 | 
			
		||||
    "build:vercel": "cross-env VITE_HASH_ROUTE=Y VITE_VERCEL=Y vite build",
 | 
			
		||||
    "preview": "vite preview",
 | 
			
		||||
    "typecheck": "vue-tsc --noEmit --skipLibCheck",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
export function adapterOfFetchDataWithAdapter(
 | 
			
		||||
  res: Service.RequestResult<ApiDemo.DataWithAdapter>
 | 
			
		||||
): Demo.DataWithAdapter {
 | 
			
		||||
  const { dataId, dataName } = res.data!;
 | 
			
		||||
 | 
			
		||||
  const result: Demo.DataWithAdapter = {
 | 
			
		||||
    id: dataId,
 | 
			
		||||
    name: dataName
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										10
									
								
								src/service/api/demo.adapter.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/service/api/demo.adapter.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
export function adapterOfFetchDataWithAdapter(data: ApiDemo.DataWithAdapter): Demo.DataWithAdapter {
 | 
			
		||||
  const { dataId, dataName } = data;
 | 
			
		||||
 | 
			
		||||
  const result: Demo.DataWithAdapter = {
 | 
			
		||||
    id: dataId,
 | 
			
		||||
    name: dataName
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,11 +1,11 @@
 | 
			
		||||
import { serviceAdapter } from '@/utils';
 | 
			
		||||
import { adapter } from '@/utils';
 | 
			
		||||
import { request, mockRequest } from '../request';
 | 
			
		||||
import { adapterOfFetchDataWithAdapter } from '../adapter';
 | 
			
		||||
import { adapterOfFetchDataWithAdapter } from './demo.adapter';
 | 
			
		||||
 | 
			
		||||
/** 带有适配器的请求(将请求结果进行数据处理) */
 | 
			
		||||
/** 带有适配器的请求示例 */
 | 
			
		||||
export async function fetchDataWithAdapter() {
 | 
			
		||||
  const res = await mockRequest.post<ApiDemo.DataWithAdapter>('/apiDemoWithAdapter');
 | 
			
		||||
  return serviceAdapter(adapterOfFetchDataWithAdapter, res);
 | 
			
		||||
  return adapter(adapterOfFetchDataWithAdapter, res);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** 测试代理后的请求 */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,12 @@
 | 
			
		||||
import { getEnvConfig } from '~/.env-config';
 | 
			
		||||
import { getServiceEnvConfig } from '~/.env-config';
 | 
			
		||||
import { createRequest } from './request';
 | 
			
		||||
 | 
			
		||||
const envConfig = getEnvConfig(import.meta.env);
 | 
			
		||||
const { pattern, url, secondUrl } = getServiceEnvConfig(import.meta.env);
 | 
			
		||||
 | 
			
		||||
const isHttpProxy = import.meta.env.VITE_HTTP_PROXY === 'Y';
 | 
			
		||||
 | 
			
		||||
export const request = createRequest({ baseURL: isHttpProxy ? envConfig.proxy : envConfig.url });
 | 
			
		||||
export const request = createRequest({ baseURL: isHttpProxy ? pattern : url });
 | 
			
		||||
 | 
			
		||||
export const secondRequest = createRequest({ baseURL: isHttpProxy ? pattern : secondUrl });
 | 
			
		||||
 | 
			
		||||
export const mockRequest = createRequest({ baseURL: '/mock' });
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								src/typings/env.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								src/typings/env.d.ts
									
									
									
									
										vendored
									
									
								
							@@ -8,10 +8,12 @@ type ServiceEnvType = 'dev' | 'test' | 'prod';
 | 
			
		||||
 | 
			
		||||
/** 后台服务的环境配置 */
 | 
			
		||||
interface ServiceEnvConfig {
 | 
			
		||||
  /** 匹配路径的正则字符串, 用于拦截地址转发代理(任意以 /开头 + 字符串, 单个/不起作用) */
 | 
			
		||||
  pattern: '/proxy-pattrn';
 | 
			
		||||
  /** 请求地址 */
 | 
			
		||||
  url: string;
 | 
			
		||||
  /** 代理标识, 用于拦截地址转发代理(和后端请求路径中有无该路径没有关系) */
 | 
			
		||||
  proxy: '/proxy-flag';
 | 
			
		||||
  /** 另一个后端请求地址(有多个不同的后端服务时) */
 | 
			
		||||
  secondUrl: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface ImportMetaEnv {
 | 
			
		||||
@@ -31,8 +33,8 @@ interface ImportMetaEnv {
 | 
			
		||||
  readonly VITE_AUTH_ROUTE_MODE: 'static' | 'dynamic';
 | 
			
		||||
  /** 路由首页的路径 */
 | 
			
		||||
  readonly VITE_ROUTE_HOME_PATH: Exclude<AuthRoute.RoutePath, '/' | '/not-found-page' | '/:pathMatch(.*)*'>;
 | 
			
		||||
  /** vite环境类型 */
 | 
			
		||||
  readonly VITE_ENV_TYPE?: ServiceEnvType;
 | 
			
		||||
  /** 后端服务的环境类型 */
 | 
			
		||||
  readonly VITE_SERVICE_ENV?: ServiceEnvType;
 | 
			
		||||
  /** 开启请求代理 */
 | 
			
		||||
  readonly VITE_HTTP_PROXY?: 'Y' | 'N';
 | 
			
		||||
  /** 是否开启打包文件大小结果分析 */
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								src/typings/system.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								src/typings/system.d.ts
									
									
									
									
										vendored
									
									
								
							@@ -70,6 +70,20 @@ declare namespace Service {
 | 
			
		||||
  /** 自定义的请求结果 */
 | 
			
		||||
  type RequestResult<T = any> = SuccessResult<T> | FailedResult;
 | 
			
		||||
 | 
			
		||||
  /** 多个请求数据结果 */
 | 
			
		||||
  type MultiRequestResult<T extends any[]> = T extends [infer First, ...infer Rest]
 | 
			
		||||
    ? First extends any
 | 
			
		||||
      ? Rest extends any[]
 | 
			
		||||
        ? [Service.RequestResult<First>, ...MultiRequestResult<Rest>]
 | 
			
		||||
        : [Service.RequestResult<First>]
 | 
			
		||||
      : Rest extends any[]
 | 
			
		||||
      ? MultiRequestResult<Rest>
 | 
			
		||||
      : []
 | 
			
		||||
    : [];
 | 
			
		||||
 | 
			
		||||
  /** 请求结果的适配器函数 */
 | 
			
		||||
  type ServiceAdapter<T = any, A extends any[] = any> = (...args: A) => T;
 | 
			
		||||
 | 
			
		||||
  /** mock示例接口类型:后端接口返回的数据的类型 */
 | 
			
		||||
  interface MockServiceResult<T = any> {
 | 
			
		||||
    /** 状态码 */
 | 
			
		||||
 
 | 
			
		||||
@@ -14,14 +14,11 @@ export async function handleServiceResult<T = any>(error: Service.RequestError |
 | 
			
		||||
  return success;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Adapter<T = any> = (...args: Service.RequestResult[]) => T;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 请求结果的数据转换适配器
 | 
			
		||||
 * @param adapter - 适配器函数
 | 
			
		||||
 * @param args - 适配器函数的参数
 | 
			
		||||
 */
 | 
			
		||||
export function serviceAdapter<T extends Adapter>(adapter: T, ...args: TypeUtil.GetFunArgs<T>) {
 | 
			
		||||
/** 请求结果的适配器:用于接收适配器函数和请求结果 */
 | 
			
		||||
export function adapter<T extends Service.ServiceAdapter>(
 | 
			
		||||
  adapterFun: T,
 | 
			
		||||
  ...args: Service.MultiRequestResult<TypeUtil.GetFunArgs<T>>
 | 
			
		||||
): Service.RequestResult<TypeUtil.GetFunReturn<T>> {
 | 
			
		||||
  let result: Service.RequestResult | undefined;
 | 
			
		||||
 | 
			
		||||
  const hasError = args.some(item => {
 | 
			
		||||
@@ -36,11 +33,12 @@ export function serviceAdapter<T extends Adapter>(adapter: T, ...args: TypeUtil.
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  if (!hasError) {
 | 
			
		||||
    const adapterFunArgs = args.map(item => item.data);
 | 
			
		||||
    result = {
 | 
			
		||||
      error: null,
 | 
			
		||||
      data: adapter(...args)
 | 
			
		||||
      data: adapterFun(...adapterFunArgs)
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return result as Service.RequestResult<TypeUtil.GetFunReturn<T>>;
 | 
			
		||||
  return result!;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,15 +1,15 @@
 | 
			
		||||
import { defineConfig, loadEnv } from 'vite';
 | 
			
		||||
import { getRootPath, getSrcPath, viteDefine, setupVitePlugins, createViteProxy } from './build';
 | 
			
		||||
import { getEnvConfig } from './.env-config';
 | 
			
		||||
import { getServiceEnvConfig } from './.env-config';
 | 
			
		||||
 | 
			
		||||
export default defineConfig(configEnv => {
 | 
			
		||||
  const viteEnv = loadEnv(configEnv.mode, process.cwd()) as ImportMetaEnv;
 | 
			
		||||
  const viteEnv = loadEnv(configEnv.mode, process.cwd()) as unknown as ImportMetaEnv;
 | 
			
		||||
 | 
			
		||||
  const rootPath = getRootPath();
 | 
			
		||||
  const srcPath = getSrcPath();
 | 
			
		||||
 | 
			
		||||
  const isOpenProxy = viteEnv.VITE_HTTP_PROXY === 'Y';
 | 
			
		||||
  const envConfig = getEnvConfig(viteEnv);
 | 
			
		||||
  const envConfig = getServiceEnvConfig(viteEnv);
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
    base: viteEnv.VITE_BASE_URL,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user