新增 VITE_API_BASE_URL2 環境變數,更新請求模組以移除 token2 支持,並在登錄頁面中整合新的 token 登錄功能,調整狀態管理以支持多個 token 的存儲。
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
# 基础环境变量示例
|
# 基础环境变量示例
|
||||||
VITE_API_BASE_URL=http://www.yishi.com
|
VITE_API_BASE_URL=http://www.yishi.com
|
||||||
|
VITE_API_BASE_URL2=https://kf.quwanzhi.com:9991
|
||||||
# VITE_API_BASE_URL=https://ckbapi.quwanzhi.com
|
# VITE_API_BASE_URL=https://ckbapi.quwanzhi.com
|
||||||
VITE_APP_TITLE=存客宝
|
VITE_APP_TITLE=存客宝
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
# 基础环境变量示例
|
# 基础环境变量示例
|
||||||
VITE_API_BASE_URL=https://ckbapi.quwanzhi.com
|
VITE_API_BASE_URL=https://ckbapi.quwanzhi.com
|
||||||
|
VITE_API_BASE_URL2=https://kf.quwanzhi.com:9991
|
||||||
# VITE_API_BASE_URL=http://www.yishi.com
|
# VITE_API_BASE_URL=http://www.yishi.com
|
||||||
VITE_APP_TITLE=存客宝
|
VITE_APP_TITLE=存客宝
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import axios, {
|
|||||||
} from "axios";
|
} from "axios";
|
||||||
import { Toast } from "antd-mobile";
|
import { Toast } from "antd-mobile";
|
||||||
import { useUserStore } from "@/store/module/user";
|
import { useUserStore } from "@/store/module/user";
|
||||||
const { token, token2 } = useUserStore.getState();
|
const { token } = useUserStore.getState();
|
||||||
const DEFAULT_DEBOUNCE_GAP = 1000;
|
const DEFAULT_DEBOUNCE_GAP = 1000;
|
||||||
const debounceMap = new Map<string, number>();
|
const debounceMap = new Map<string, number>();
|
||||||
|
|
||||||
@@ -19,13 +19,7 @@ const instance: AxiosInstance = axios.create({
|
|||||||
});
|
});
|
||||||
|
|
||||||
instance.interceptors.request.use((config: any) => {
|
instance.interceptors.request.use((config: any) => {
|
||||||
// 从配置中获取是否使用token2
|
if (token) {
|
||||||
const useToken2 = config.useToken2;
|
|
||||||
|
|
||||||
if (useToken2 && token2) {
|
|
||||||
config.headers = config.headers || {};
|
|
||||||
config.headers["Authorization"] = `Bearer ${token2}`;
|
|
||||||
} else if (token) {
|
|
||||||
config.headers = config.headers || {};
|
config.headers = config.headers || {};
|
||||||
config.headers["Authorization"] = `Bearer ${token}`;
|
config.headers["Authorization"] = `Bearer ${token}`;
|
||||||
}
|
}
|
||||||
@@ -62,7 +56,6 @@ export function request(
|
|||||||
method: Method = "GET",
|
method: Method = "GET",
|
||||||
config?: AxiosRequestConfig,
|
config?: AxiosRequestConfig,
|
||||||
debounceGap?: number,
|
debounceGap?: number,
|
||||||
isToken2?: boolean,
|
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
const gap =
|
const gap =
|
||||||
typeof debounceGap === "number" ? debounceGap : DEFAULT_DEBOUNCE_GAP;
|
typeof debounceGap === "number" ? debounceGap : DEFAULT_DEBOUNCE_GAP;
|
||||||
@@ -79,10 +72,7 @@ export function request(
|
|||||||
url,
|
url,
|
||||||
method,
|
method,
|
||||||
...config,
|
...config,
|
||||||
} as any;
|
};
|
||||||
|
|
||||||
// 添加自定义属性
|
|
||||||
(axiosConfig as any).useToken2 = isToken2;
|
|
||||||
|
|
||||||
// 如果是FormData,不设置Content-Type,让浏览器自动设置
|
// 如果是FormData,不设置Content-Type,让浏览器自动设置
|
||||||
if (data instanceof FormData) {
|
if (data instanceof FormData) {
|
||||||
|
|||||||
79
Cunkebao/src/api/request2.ts
Normal file
79
Cunkebao/src/api/request2.ts
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
import axios, {
|
||||||
|
AxiosInstance,
|
||||||
|
AxiosRequestConfig,
|
||||||
|
Method,
|
||||||
|
AxiosResponse,
|
||||||
|
} from "axios";
|
||||||
|
import { Toast } from "antd-mobile";
|
||||||
|
import { useUserStore } from "@/store/module/user";
|
||||||
|
const { token2 } = useUserStore.getState();
|
||||||
|
const DEFAULT_DEBOUNCE_GAP = 1000;
|
||||||
|
const debounceMap = new Map<string, number>();
|
||||||
|
|
||||||
|
interface RequestConfig extends AxiosRequestConfig {
|
||||||
|
headers: {
|
||||||
|
Client?: string;
|
||||||
|
"Content-Type"?: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const instance: AxiosInstance = axios.create({
|
||||||
|
baseURL: (import.meta as any).env?.VITE_API_BASE_URL2 || "/api",
|
||||||
|
timeout: 20000,
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Client: "kefu-client",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.interceptors.request.use((config: any) => {
|
||||||
|
if (token2) {
|
||||||
|
config.headers = config.headers || {};
|
||||||
|
config.headers["Authorization"] = `Bearer ${token2}`;
|
||||||
|
}
|
||||||
|
return config;
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.interceptors.response.use(
|
||||||
|
(res: AxiosResponse) => {
|
||||||
|
return res.data;
|
||||||
|
},
|
||||||
|
err => {
|
||||||
|
Toast.show({ content: err.message || "网络异常", position: "top" });
|
||||||
|
return Promise.reject(err);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
export function request(
|
||||||
|
url: string,
|
||||||
|
data?: any,
|
||||||
|
method: Method = "GET",
|
||||||
|
config?: RequestConfig,
|
||||||
|
debounceGap?: number,
|
||||||
|
): Promise<any> {
|
||||||
|
const gap =
|
||||||
|
typeof debounceGap === "number" ? debounceGap : DEFAULT_DEBOUNCE_GAP;
|
||||||
|
const key = `${method}_${url}_${JSON.stringify(data)}`;
|
||||||
|
const now = Date.now();
|
||||||
|
const last = debounceMap.get(key) || 0;
|
||||||
|
if (gap > 0 && now - last < gap) {
|
||||||
|
// Toast.show({ content: '请求过于频繁,请稍后再试', position: 'top' });
|
||||||
|
return Promise.reject("请求过于频繁,请稍后再试");
|
||||||
|
}
|
||||||
|
debounceMap.set(key, now);
|
||||||
|
|
||||||
|
const axiosConfig: RequestConfig = {
|
||||||
|
url,
|
||||||
|
method,
|
||||||
|
...config,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (method.toUpperCase() === "GET") {
|
||||||
|
axiosConfig.params = data;
|
||||||
|
} else {
|
||||||
|
axiosConfig.data = data;
|
||||||
|
}
|
||||||
|
return instance(axiosConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default request;
|
||||||
@@ -7,7 +7,12 @@ import {
|
|||||||
UserOutline,
|
UserOutline,
|
||||||
} from "antd-mobile-icons";
|
} from "antd-mobile-icons";
|
||||||
import { useUserStore } from "@/store/module/user";
|
import { useUserStore } from "@/store/module/user";
|
||||||
import { loginWithPassword, loginWithCode, sendVerificationCode } from "./api";
|
import {
|
||||||
|
loginWithPassword,
|
||||||
|
loginWithCode,
|
||||||
|
sendVerificationCode,
|
||||||
|
loginWithToken,
|
||||||
|
} from "./api";
|
||||||
import style from "./login.module.scss";
|
import style from "./login.module.scss";
|
||||||
|
|
||||||
const Login: React.FC = () => {
|
const Login: React.FC = () => {
|
||||||
@@ -18,7 +23,7 @@ const Login: React.FC = () => {
|
|||||||
const [showPassword, setShowPassword] = useState(false);
|
const [showPassword, setShowPassword] = useState(false);
|
||||||
const [agreeToTerms, setAgreeToTerms] = useState(false);
|
const [agreeToTerms, setAgreeToTerms] = useState(false);
|
||||||
|
|
||||||
const { login } = useUserStore();
|
const { login, login2 } = useUserStore();
|
||||||
|
|
||||||
// 倒计时效果
|
// 倒计时效果
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -66,32 +71,59 @@ const Login: React.FC = () => {
|
|||||||
Toast.show({ content: "请同意用户协议和隐私政策", position: "top" });
|
Toast.show({ content: "请同意用户协议和隐私政策", position: "top" });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
getToken(values)
|
||||||
|
.then(() => {
|
||||||
|
getToken2();
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const getToken = (values: any) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
// 添加typeId参数
|
// 添加typeId参数
|
||||||
const loginParams = {
|
const loginParams = {
|
||||||
...values,
|
...values,
|
||||||
typeId: activeTab as number,
|
typeId: activeTab as number,
|
||||||
};
|
};
|
||||||
|
|
||||||
let response;
|
const response =
|
||||||
if (activeTab === 1) {
|
activeTab === 1
|
||||||
response = await loginWithPassword(loginParams);
|
? loginWithPassword(loginParams)
|
||||||
} else {
|
: loginWithCode(loginParams);
|
||||||
response = await loginWithCode(loginParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取设备总数
|
response
|
||||||
const deviceTotal = response.deviceTotal || 0;
|
.then(res => {
|
||||||
|
// 获取设备总数
|
||||||
|
const deviceTotal = res.deviceTotal || 0;
|
||||||
|
|
||||||
// 更新状态管理(token会自动存储到localStorage,用户信息存储在状态管理中)
|
// 更新状态管理(token会自动存储到localStorage,用户信息存储在状态管理中)
|
||||||
login(response.token, response.member, deviceTotal);
|
login(res.token, res.member, deviceTotal);
|
||||||
} catch (error: any) {
|
resolve(res);
|
||||||
// 错误已在request中处理,这里不需要额外处理
|
})
|
||||||
} finally {
|
.catch(err => {
|
||||||
setLoading(false);
|
reject(err);
|
||||||
}
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const getToken2 = () => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const params = {
|
||||||
|
grant_type: "password",
|
||||||
|
password: "kr123456",
|
||||||
|
username: "kr_xf3",
|
||||||
|
};
|
||||||
|
const response = loginWithToken(params);
|
||||||
|
response.then(res => {
|
||||||
|
login2(res.access_token);
|
||||||
|
resolve(res);
|
||||||
|
});
|
||||||
|
response.catch(err => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 第三方登录处理
|
// 第三方登录处理
|
||||||
|
|||||||
@@ -1,33 +1,5 @@
|
|||||||
import request from "@/api/request";
|
import request from "@/api/request";
|
||||||
export interface LoginParams {
|
import request2 from "@/api/request2";
|
||||||
phone: string;
|
|
||||||
password?: string;
|
|
||||||
verificationCode?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface LoginResponse {
|
|
||||||
code: number;
|
|
||||||
msg: string;
|
|
||||||
data: {
|
|
||||||
token: string;
|
|
||||||
token_expired: string;
|
|
||||||
deviceTotal: number; // 设备总数
|
|
||||||
member: {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
phone: string;
|
|
||||||
s2_accountId: string;
|
|
||||||
avatar?: string;
|
|
||||||
email?: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SendCodeResponse {
|
|
||||||
code: number;
|
|
||||||
msg: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 密码登录
|
// 密码登录
|
||||||
export function loginWithPassword(params: any) {
|
export function loginWithPassword(params: any) {
|
||||||
return request("/v1/auth/login", params, "POST");
|
return request("/v1/auth/login", params, "POST");
|
||||||
@@ -52,3 +24,17 @@ export function logout() {
|
|||||||
export function getUserInfo() {
|
export function getUserInfo() {
|
||||||
return request("/v1/auth/user-info", {}, "GET");
|
return request("/v1/auth/user-info", {}, "GET");
|
||||||
}
|
}
|
||||||
|
//触客宝登陆
|
||||||
|
export function loginWithToken(params: any) {
|
||||||
|
return request2(
|
||||||
|
"/token",
|
||||||
|
params,
|
||||||
|
"POST",
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
1000,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ interface UserState {
|
|||||||
setToken2: (token2: string) => void;
|
setToken2: (token2: string) => void;
|
||||||
clearUser: () => void;
|
clearUser: () => void;
|
||||||
login: (token: string, userInfo: User, deviceTotal: number) => void;
|
login: (token: string, userInfo: User, deviceTotal: number) => void;
|
||||||
|
login2: (token2: string) => void;
|
||||||
logout: () => void;
|
logout: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,7 +42,8 @@ export const useUserStore = createPersistStore<UserState>(
|
|||||||
setUser: user => set({ user, isLoggedIn: true }),
|
setUser: user => set({ user, isLoggedIn: true }),
|
||||||
setToken: token => set({ token }),
|
setToken: token => set({ token }),
|
||||||
setToken2: token2 => set({ token2 }),
|
setToken2: token2 => set({ token2 }),
|
||||||
clearUser: () => set({ user: null, token: null, token2: null, isLoggedIn: false }),
|
clearUser: () =>
|
||||||
|
set({ user: null, token: null, token2: null, isLoggedIn: false }),
|
||||||
login: (token, userInfo, deviceTotal) => {
|
login: (token, userInfo, deviceTotal) => {
|
||||||
// 只将token存储到localStorage
|
// 只将token存储到localStorage
|
||||||
localStorage.setItem("token", token);
|
localStorage.setItem("token", token);
|
||||||
@@ -76,6 +78,10 @@ export const useUserStore = createPersistStore<UserState>(
|
|||||||
window.location.href = "/guide";
|
window.location.href = "/guide";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
login2: token2 => {
|
||||||
|
localStorage.setItem("token2", token2);
|
||||||
|
set({ token2, isLoggedIn: true });
|
||||||
|
},
|
||||||
logout: () => {
|
logout: () => {
|
||||||
// 清除localStorage中的token
|
// 清除localStorage中的token
|
||||||
localStorage.removeItem("token");
|
localStorage.removeItem("token");
|
||||||
|
|||||||
Reference in New Issue
Block a user