feat:更新request.ts

This commit is contained in:
fangyunong 2025-07-04 11:33:47 +08:00
parent 19322ac91d
commit b231b77043
12 changed files with 152 additions and 13 deletions

1
.env Normal file
View File

@ -0,0 +1 @@
VITE_API_BASE_URL=http://your-api-url.com

1
auto-imports.d.ts vendored
View File

@ -21,6 +21,7 @@ declare global {
const isReactive: typeof import('vue')['isReactive']
const isReadonly: typeof import('vue')['isReadonly']
const isRef: typeof import('vue')['isRef']
const login: typeof import('./src/api/loginApi')['login']
const markRaw: typeof import('vue')['markRaw']
const nextTick: typeof import('vue')['nextTick']
const onActivated: typeof import('vue')['onActivated']

View File

@ -10,6 +10,7 @@
<script setup lang='ts'>
import { type GlobalThemeOverrides, dateZhCN, zhCN } from "naive-ui";
const themeOverrides: GlobalThemeOverrides = {
//
'common': {

7
src/api/loginApi.ts Normal file
View File

@ -0,0 +1,7 @@
import http from "@/utils/request";
//demo
export const login = () => {
return http.get('/get-user')
}

View File

@ -4,7 +4,7 @@ export const useAppStore = defineStore('User', () => {
//左侧菜单相关
const menuApp = reactive({
isExpaned:true, //
isExpaned:true, //折叠控制
});
return {
menuApp

View File

@ -2,14 +2,19 @@ import Cookies from "js-cookie";
const TokenKey:string = "Authorization";
// 获取token
export function getToken() {
return Cookies.get(TokenKey);
return Cookies.get(TokenKey) || localStorage.getItem(TokenKey);
}
// 设置token
export function setToken(token:string) {
return Cookies.set(TokenKey, token);
localStorage.setItem(TokenKey, token);
Cookies.set(TokenKey, token);
}
// 移除token
export function removeToken() {
return Cookies.remove(TokenKey);
localStorage.removeItem(TokenKey);
Cookies.remove(TokenKey);
}

4
src/utils/index.ts Normal file
View File

@ -0,0 +1,4 @@
// 深拷贝
export function deepClone(){
}

113
src/utils/request.ts Normal file
View File

@ -0,0 +1,113 @@
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
import { getToken, removeToken } from './auth';
// 定义后端返回的统一数据结构
interface ApiResponse<T = any> {
code: number;
data: T;
msg: string;
}
// 创建 Axios 实例
const createAxiosInstance = (): AxiosInstance => {
const instance = axios.create({
baseURL: import.meta.env.VITE_API_BASE_URL as string, // 从 Vite 环境变量获取 baseURL
timeout: 10000, // 请求超时时间
headers: {
'Content-Type': 'application/json',
},
});
// 请求拦截器
instance.interceptors.request.use(
(config) => {
// 添加 token 等请求头
const token = getToken()
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
// 响应拦截器
instance.interceptors.response.use(
(response: AxiosResponse<ApiResponse>) => {
const { code, msg } = response.data;
// 401 未授权,跳转首页
if (code === 401) {
// 这里调用退出登录的逻辑
console.log('未授权,跳转首页');
// 清除用户信息
removeToken();
// 跳转首页
window.location.href = '/'; //后续用发布订阅模式修改
return Promise.reject(new Error(msg || '未授权'));
}
// 其他非 200 状态码
if (code !== 200) {
console.error(`请求错误 ${code}: ${msg}`);
// 这里可以根据需要弹出错误提示
return Promise.reject(new Error(msg || '请求错误'));
}
// 返回数据部分
return response.data.data;
},
(error) => {
// 处理 HTTP 状态码不是 200 的情况
if (error.response) {
const { status, data } = error.response;
console.error(`HTTP 错误 ${status}:`, data);
} else {
console.error('请求错误:', error.message);
}
return Promise.reject(error);
}
);
return instance;
};
const http = createAxiosInstance();
// 封装通用的 request 函数
async function request<T = any>(config: AxiosRequestConfig): Promise<T> {
try {
const { data } = await http.request<ApiResponse<T>>(config);
return data.data;
} catch (error) {
// 这里可以统一处理错误,或者让调用者自己处理
throw error;
}
}
// 封装常用的 HTTP 方法
const httpClient = {
get<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> {
return request<T>({ ...config, method: 'GET', url });
},
post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
return request<T>({ ...config, method: 'POST', url, data });
},
put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
return request<T>({ ...config, method: 'PUT', url, data });
},
delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> {
return request<T>({ ...config, method: 'DELETE', url });
},
patch<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
return request<T>({ ...config, method: 'PATCH', url, data });
},
};
export default httpClient;

View File

@ -5,16 +5,17 @@
</template>
<script setup>
import { setToken } from '@/utils/auth';
import { useAuth0 } from '@auth0/auth0-vue';
import { useMessage } from 'naive-ui';
const { getAccessTokenSilently } = useAuth0();
const token = ref('');
const router = useRouter();
const message = useMessage();
const oSomethingWithToken = async () => {
try {
console.log('进来了吗??');
token.value = await getAccessTokenSilently();
const token = await getAccessTokenSilently();
setToken(token);
message.success('登录成功!');
router.push('/layout');
} catch (error) {

View File

@ -54,7 +54,7 @@
</div>
</div>
<div class="zn-hero__illustration">
<img src="/public/logo.jpg" alt="系统预览" />
<img src="/logo.jpg" alt="系统预览" />
</div>
</section>
@ -202,7 +202,7 @@
</div>
</template>
<script setup>
<script setup lang="ts">
import { ChevronForward, GitCompare, BarChartSharp, Server } from '@vicons/ionicons5';
import { useAuth0 } from '@auth0/auth0-vue';
import { useDialog } from 'naive-ui';

View File

@ -1,12 +1,14 @@
{
"moduleResolution":"node",
"include": ["env.d.ts", "src/**/*", "src/**/*.vue","auto-imports.d.ts"],
"moduleResolution": "node",
"include": ["env.d.ts", "src/**/*", "src/**/*.vue", "auto-imports.d.ts"],
"compilerOptions": {
"esModuleInterop":true,
"moduleResolution": "node",
"esModuleInterop": true,
"module": "es2020",
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
},
"lib":["es2022"],
"lib": ["es2022", "dom","dom.iterable"], // "dom" lib
}
}

View File

@ -5,6 +5,10 @@ import AutoImport from "unplugin-auto-import/vite";
// https://vite.dev/config/
export default defineConfig({
// ...其他配置
define: {
'process.env': process.env
},
plugins: [
vue(),
AutoImport({