Created
April 25, 2022 13:26
-
-
Save l-7-l/99f03ee35788393eba2c7f55b369c4f6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* eslint-disable prefer-object-spread */ | |
import API from 'conf/API' | |
import ky, { BeforeErrorHook, BeforeRequestHook } from 'ky' | |
import { cookieRepo } from 'store/cookie' | |
import { message } from 'antd' | |
import type { KyInstance } from 'ky/distribution/types/ky' | |
import type { Input, Options } from 'ky/distribution/types/options' | |
import { DB_PROFILE_KEY } from 'conf/constants' | |
export interface PaginationParams { | |
readonly page?: number | |
readonly pagesize?: number | |
} | |
export interface Pagination<T> { | |
readonly total: number | |
readonly page: number | |
readonly pages: number | |
readonly list: readonly T[] | |
} | |
export interface Response<T> { | |
readonly status: 'success' | 'fail' | |
readonly code: number | |
readonly data: T | |
readonly error?: string | |
readonly message?: string | |
} | |
export type HttpReq = <T>(url: Input, options?: Options) => Promise<T> | |
const addAuthToken: BeforeRequestHook = (request) => { | |
const token = cookieRepo.accessToken | |
if (token) { | |
request.headers.set('Authorization', `Bearer ${token}`) | |
} | |
} | |
// const refreshToken: BeforeRequestHook = (req) => {} | |
const commonError: BeforeErrorHook = (error) => { | |
const { response } = error | |
if (response && response.body) { | |
// console.log('error: res', response.json()) | |
// error.name = 'GitHubError' | |
// error.message = `${response.body.message} (${response.statusCode})` | |
} | |
return error | |
} | |
export class Net { | |
readonly #ky: KyInstance | |
readonly get: HttpReq | |
readonly post: HttpReq | |
readonly put: HttpReq | |
readonly delete: HttpReq | |
readonly patch: HttpReq | |
static #instance: Net | |
static get instance() { | |
if (!Net.#instance) { | |
Net.#instance = new Net() | |
} | |
return Net.#instance | |
} | |
static readonly apiClient = (prefixUrl: string = API.baseUrl) => | |
ky.extend({ | |
prefixUrl, | |
mode: 'cors', | |
credentials: 'omit', | |
headers: { | |
'Content-Type': 'application/json; charset=UTF-8', | |
}, | |
hooks: { | |
beforeRequest: [addAuthToken], | |
beforeError: [commonError], | |
}, | |
}) | |
constructor() { | |
this.#ky = Net.apiClient() | |
this.get = this.#actionCreator('get') | |
this.post = this.#actionCreator('post') | |
this.put = this.#actionCreator('put') | |
this.patch = this.#actionCreator('patch') | |
this.delete = this.#actionCreator('delete') | |
Net.#instance = this | |
} | |
readonly #actionCreator = | |
(method: Options['method']) => | |
async <T>(url: Input, options?: Options) => | |
this.req<T>(url, Object.assign({ method }, options)) | |
async req<T>(url: Input, options?: Options) { | |
try { | |
const res = await this.#ky(url, options) | |
const json: Response<T> = await res.json() | |
if (json.status === 'success' && res.status === 200) { | |
return json.data | |
} | |
message.destroy() | |
message.error(json.message) | |
const { code } = json | |
// TODO: CODE ENUM | |
if ( | |
code === 401201 || // 单点登录 | |
code === 408002 || // 令牌错误 | |
code === 408003 || // 令牌过期 | |
code === 408004 || // 令牌无效 | |
(document && !document.location.pathname.startsWith('/login')) | |
) { | |
document.location.assign('/login') | |
if (localStorage) localStorage.removeItem(DB_PROFILE_KEY) | |
} | |
throw Error(json.error) | |
} catch (err) { | |
message.destroy() | |
throw err | |
} | |
} | |
pagination<T, R>( | |
url: string, | |
converter: (data: Pagination<T>) => R | |
): (page?: number, pageSize?: number) => Promise<R> | |
pagination<T>( | |
url: string | |
): (page?: number, pageSize?: number) => Promise<Pagination<T>> | |
pagination<T, R>(url: string, converter?: (data: Pagination<T>) => R) { | |
return async (page = 1, pageSize = 20) => { | |
const data = await this.req<Pagination<T>>(url, { | |
searchParams: { | |
page, | |
pagesize: pageSize, | |
}, | |
}) | |
if (converter) return converter(data) | |
return data | |
} | |
} | |
} | |
export default Net.instance |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment