Merge pull request #27 from EzLittleChen/dev
fix(api): 修改websocket请求地址, 修改请求方式采用fetch处理
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# 后端服务地址
|
||||
VITE_SERVICE_URL="http://127.0.0.1:9190"
|
||||
VITE_SERVICE_URL="https://hulaspark.com"
|
||||
# websocket服务地址
|
||||
VITE_WEBSOCKET_URL="ws://127.0.0.1:8090"
|
||||
VITE_WEBSOCKET_URL="wss://hulaspark.com"
|
||||
# 项目标题
|
||||
VITE_APP_TITLE="HuLa—IM"
|
||||
# 项目名称
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { createAxios } from '@/services/request'
|
||||
// import { createAxios } from '@/services/request'
|
||||
import urls from '@/services/urls'
|
||||
import type {
|
||||
Response,
|
||||
BadgeType,
|
||||
// BadgeType,
|
||||
CacheBadgeItem,
|
||||
CacheBadgeReq,
|
||||
CacheUserItem,
|
||||
@@ -22,12 +22,18 @@ import type {
|
||||
UserItem
|
||||
} from '@/services/types'
|
||||
|
||||
const request = createAxios()
|
||||
// const request = createAxios()
|
||||
import request from '@/services/request'
|
||||
|
||||
const GET = <T>(url: string, params?: any) => request.get<T, Response>(url, params)
|
||||
const POST = <T>(url: string, params?: any) => request.post<T, Response>(url, params)
|
||||
const PUT = <T>(url: string, params?: any) => request.put<T, Response>(url, params)
|
||||
const DELETE = <T>(url: string, params?: any) => request.delete<T, Response>(url, params)
|
||||
// const GET = <T>(url: string, params?: any) => request.get<T, Response>(url, params)
|
||||
// const POST = <T>(url: string, params?: any) => request.post<T, Response>(url, params)
|
||||
// const PUT = <T>(url: string, params?: any) => request.put<T, Response>(url, params)
|
||||
// const DELETE = <T>(url: string, params?: any) => request.delete<T, Response>(url, params)
|
||||
|
||||
const GET = <T>(url: string, params?: any) => request.get<T>(url, params)
|
||||
const POST = <T>(url: string, params?: any) => request.post<T>(url, params)
|
||||
const PUT = <T>(url: string, params?: any) => request.put<T>(url, params)
|
||||
const DELETE = <T>(url: string, params?: any) => request.delete<T>(url, params)
|
||||
|
||||
export default {
|
||||
/** 获取用户信息 */
|
||||
@@ -52,7 +58,7 @@ export default {
|
||||
/** 获取用户详细信息 */
|
||||
getUserDetail: () => GET<UserInfoType>(urls.getUserInfoDetail, {}),
|
||||
/** 获取徽章列表 */
|
||||
getBadgeList: (): Promise<Response> => GET<BadgeType[]>(urls.getBadgeList),
|
||||
getBadgeList: (): Promise<Response> => GET(urls.getBadgeList),
|
||||
/** 设置用户勋章 */
|
||||
setUserBadge: (badgeId: number) => PUT<void>(urls.setUserBadge, { badgeId }),
|
||||
/** 修改用户名 */
|
||||
|
||||
159
src/services/http.ts
Normal file
159
src/services/http.ts
Normal file
@@ -0,0 +1,159 @@
|
||||
import { fetch } from '@tauri-apps/plugin-http'
|
||||
|
||||
/**
|
||||
* @description 请求参数
|
||||
* @since Beta v0.5.1
|
||||
* @property {"GET"|"POST"|"PUT"|"DELETE"} method 请求方法
|
||||
* @property {Record<string, string>} [headers] 请求头
|
||||
* @property {Record<string, any>} [query] 请求参数
|
||||
* @property {any} [body] 请求体
|
||||
* @property {boolean} [isBlob] 是否为Blob
|
||||
* @return HttpParams
|
||||
*/
|
||||
export type HttpParams = {
|
||||
method: 'GET' | 'POST' | 'PUT' | 'DELETE'
|
||||
headers?: Record<string, string>
|
||||
query?: Record<string, any>
|
||||
body?: any
|
||||
isBlob?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* @description HTTP 请求实现
|
||||
* @since Beta v0.5.1
|
||||
* @template T
|
||||
* @param {string} url 请求地址
|
||||
* @param {HttpParams} options 请求参数
|
||||
* @param {boolean} [fullResponse=false] 是否返回完整响应
|
||||
* @returns {Promise<T | { data: Promise<T>; resp: Response }>} 请求结果
|
||||
*/
|
||||
async function Http<T>(
|
||||
url: string,
|
||||
options: HttpParams,
|
||||
fullResponse?: true
|
||||
): Promise<{ data: Promise<T>; resp: Response }> {
|
||||
// 构建请求头
|
||||
const httpHeaders = new Headers(options.headers || {})
|
||||
|
||||
// 构建 fetch 请求选项
|
||||
const fetchOptions: RequestInit = {
|
||||
method: options.method,
|
||||
headers: httpHeaders
|
||||
}
|
||||
|
||||
// 判断是否需要添加请求体
|
||||
if (options.body) {
|
||||
if (!(options.body instanceof FormData || options.body instanceof URLSearchParams)) {
|
||||
fetchOptions.body = JSON.stringify(options.body)
|
||||
} else {
|
||||
fetchOptions.body = options.body // 如果是 FormData 或 URLSearchParams 直接使用
|
||||
}
|
||||
}
|
||||
|
||||
// 添加查询参数
|
||||
if (options.query) {
|
||||
const queryString = new URLSearchParams(options.query).toString()
|
||||
url += `?${queryString}`
|
||||
}
|
||||
|
||||
// 拼接 API 基础路径
|
||||
url = `${import.meta.env.VITE_SERVICE_URL}${url}`
|
||||
|
||||
console.log('fetch url: ', url)
|
||||
console.log('fetch options: ', fetchOptions)
|
||||
|
||||
try {
|
||||
const res = await fetch(url, fetchOptions)
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error(`HTTP error! status: ${res.status}`)
|
||||
}
|
||||
|
||||
const data = options.isBlob ? res.arrayBuffer() : res.json()
|
||||
|
||||
if (fullResponse) {
|
||||
return { data, resp: res }
|
||||
}
|
||||
|
||||
return data
|
||||
} catch (err) {
|
||||
console.error('HTTP request failed: ', err)
|
||||
throw err // 继续抛出错误以便调用方处理
|
||||
}
|
||||
}
|
||||
|
||||
export default Http
|
||||
|
||||
// import { fetch } from '@tauri-apps/plugin-http';
|
||||
// import * as qs from 'qs';
|
||||
|
||||
// const isAbsoluteURL = (url: string) => {
|
||||
// return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url);
|
||||
// };
|
||||
|
||||
// const combineURLs = (baseURL: string, relativeURL: string) => {
|
||||
// return relativeURL
|
||||
// ? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '')
|
||||
// : baseURL;
|
||||
// };
|
||||
|
||||
// const buildFullPath = (baseURL: string, requestedURL: string) => {
|
||||
// if (baseURL && !isAbsoluteURL(requestedURL)) {
|
||||
// return combineURLs(baseURL, requestedURL);
|
||||
// }
|
||||
// return requestedURL;
|
||||
// };
|
||||
|
||||
// const buildURL = (url: string | string[], params: any) => {
|
||||
// if (!params) {
|
||||
// return url;
|
||||
// }
|
||||
// const serializedParams = qs.stringify(params);
|
||||
// if (serializedParams) {
|
||||
// url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;
|
||||
// }
|
||||
// return url;
|
||||
// };
|
||||
|
||||
// const server = '';
|
||||
// const baseURL = `${server}/api/`;
|
||||
|
||||
// const BODY_TYPE = {
|
||||
// Form: 'Form',
|
||||
// Json: 'Json',
|
||||
// Text: 'Text',
|
||||
// Bytes: 'Bytes',
|
||||
// };
|
||||
|
||||
// const commonOptions = {
|
||||
// timeout: 60,
|
||||
// };
|
||||
|
||||
// const http = (url: string, options: any = {}) => {
|
||||
// const params = { ...options.params };
|
||||
// if (!options.headers) options.headers = {};
|
||||
// // todo 可以往 headers 中添加 token 或 cookie 等信息
|
||||
|
||||
// if (options?.body) {
|
||||
// if (options.body.type === BODY_TYPE.Form) {
|
||||
// options.headers['Content-Type'] = 'multipart/form-data';
|
||||
// }
|
||||
// }
|
||||
|
||||
// options = { ...commonOptions, ...options };
|
||||
// let fetchUrl:string = buildFullPath(baseURL, url)
|
||||
// return fetch(<string>buildURL(fetchUrl, params), options)
|
||||
// .then((res: any) => {
|
||||
// const { status, data } = res
|
||||
// if (status >= 200 && status < 400) {
|
||||
// return { data };
|
||||
// }
|
||||
// return Promise.reject({ status, data });
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// console.error(err);
|
||||
// return Promise.reject(err);
|
||||
// });
|
||||
// };
|
||||
|
||||
// export default http;
|
||||
@@ -1,5 +1,6 @@
|
||||
import axios, { AxiosInstance, AxiosRequestConfig } from 'axios'
|
||||
import { useSettingStore } from '@/stores/setting.ts'
|
||||
import Http, { HttpParams } from './http.ts'
|
||||
|
||||
/** 是否是测试环境 */
|
||||
const isTest = computed(() => {
|
||||
@@ -141,3 +142,117 @@ export const createAxios = (config?: AxiosRequestConfig): AxiosInstance => {
|
||||
|
||||
return instance
|
||||
}
|
||||
|
||||
// fetch 请求响应拦截器
|
||||
const responseInterceptor = async <T>(
|
||||
url: string,
|
||||
method: 'GET' | 'POST' | 'PUT' | 'DELETE',
|
||||
query: any,
|
||||
body: any
|
||||
): Promise<T> => {
|
||||
const token = useSettingStore().login.accountInfo.token
|
||||
|
||||
const headers = {
|
||||
'Content-Type': 'application/json;charset=utf-8',
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
|
||||
let httpParams: HttpParams = {
|
||||
method,
|
||||
headers
|
||||
}
|
||||
|
||||
if (method === 'GET') {
|
||||
httpParams = {
|
||||
...httpParams,
|
||||
query
|
||||
}
|
||||
} else {
|
||||
url = `${url}?${new URLSearchParams(query).toString()}`
|
||||
httpParams = {
|
||||
...httpParams,
|
||||
body
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const data = await Http(url, httpParams, true)
|
||||
|
||||
const resp = data.resp
|
||||
|
||||
if (resp.status > 400) {
|
||||
let message = ''
|
||||
switch (resp.status) {
|
||||
case 400:
|
||||
message = '错误请求'
|
||||
break
|
||||
case 401:
|
||||
message = '未授权,请重新登录'
|
||||
break
|
||||
case 403:
|
||||
message = '拒绝访问'
|
||||
break
|
||||
case 404:
|
||||
message = '请求错误,未找到该资源'
|
||||
window.location.href = '/NotFound'
|
||||
break
|
||||
case 405:
|
||||
message = '请求方法未允许'
|
||||
break
|
||||
case 408:
|
||||
message = '请求超时'
|
||||
break
|
||||
case 500:
|
||||
message = '服务器端出错'
|
||||
break
|
||||
case 501:
|
||||
message = '网络未实现'
|
||||
break
|
||||
case 502:
|
||||
message = '网络错误'
|
||||
break
|
||||
case 503:
|
||||
message = '服务不可用'
|
||||
break
|
||||
case 504:
|
||||
message = '网络超时'
|
||||
break
|
||||
case 505:
|
||||
message = 'http版本不支持该请求'
|
||||
break
|
||||
default:
|
||||
message = '连接错误'
|
||||
}
|
||||
return Promise.reject(`err: ${message}, status: ${resp.status}`)
|
||||
}
|
||||
|
||||
const res: any = await data.data
|
||||
|
||||
return Promise.resolve(res)
|
||||
} catch (err) {
|
||||
return Promise.reject(`http error: ${err}`)
|
||||
}
|
||||
}
|
||||
|
||||
const get = async <T>(url: string, query: T): Promise<T> => {
|
||||
return responseInterceptor(url, 'GET', query, {})
|
||||
}
|
||||
|
||||
const post = async <T>(url: string, params: any): Promise<T> => {
|
||||
return responseInterceptor(url, 'POST', {}, params)
|
||||
}
|
||||
|
||||
const put = async <T>(url: string, params: any): Promise<T> => {
|
||||
return responseInterceptor(url, 'PUT', {}, params)
|
||||
}
|
||||
|
||||
const del = async <T>(url: string, params: any): Promise<T> => {
|
||||
return responseInterceptor(url, 'DELETE', {}, params)
|
||||
}
|
||||
|
||||
export default {
|
||||
get,
|
||||
post,
|
||||
put,
|
||||
delete: del
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ const initConnection = () => {
|
||||
connection?.removeEventListener('error', onConnectError)
|
||||
// 建立链接
|
||||
// 本地配置到 .env 里面修改。生产配置在 .env.production 里面
|
||||
connection = new WebSocket(`${import.meta.env.VITE_WEBSOCKET_URL}${token ? `?token=${token}` : ''}`)
|
||||
connection = new WebSocket(`${import.meta.env.VITE_WEBSOCKET_URL}/websocket${token ? `?token=${token}` : ''}`)
|
||||
// 收到消息
|
||||
connection.addEventListener('message', onConnectMsg)
|
||||
// 建立链接
|
||||
|
||||
Reference in New Issue
Block a user