diff --git a/Cunkebao/.env.development b/Cunkebao/.env.development index c008d630..3fa6d21b 100644 --- a/Cunkebao/.env.development +++ b/Cunkebao/.env.development @@ -1,4 +1,5 @@ # 基础环境变量示例 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_APP_TITLE=存客宝 diff --git a/Cunkebao/.env.production b/Cunkebao/.env.production index d71cee1d..5b58400c 100644 --- a/Cunkebao/.env.production +++ b/Cunkebao/.env.production @@ -1,4 +1,5 @@ # 基础环境变量示例 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_APP_TITLE=存客宝 diff --git a/Cunkebao/src/api/request.ts b/Cunkebao/src/api/request.ts index 8cce9cac..6394d22e 100644 --- a/Cunkebao/src/api/request.ts +++ b/Cunkebao/src/api/request.ts @@ -6,7 +6,7 @@ import axios, { } from "axios"; import { Toast } from "antd-mobile"; import { useUserStore } from "@/store/module/user"; -const { token, token2 } = useUserStore.getState(); +const { token } = useUserStore.getState(); const DEFAULT_DEBOUNCE_GAP = 1000; const debounceMap = new Map(); @@ -19,13 +19,7 @@ const instance: AxiosInstance = axios.create({ }); instance.interceptors.request.use((config: any) => { - // 从配置中获取是否使用token2 - const useToken2 = config.useToken2; - - if (useToken2 && token2) { - config.headers = config.headers || {}; - config.headers["Authorization"] = `Bearer ${token2}`; - } else if (token) { + if (token) { config.headers = config.headers || {}; config.headers["Authorization"] = `Bearer ${token}`; } @@ -62,7 +56,6 @@ export function request( method: Method = "GET", config?: AxiosRequestConfig, debounceGap?: number, - isToken2?: boolean, ): Promise { const gap = typeof debounceGap === "number" ? debounceGap : DEFAULT_DEBOUNCE_GAP; @@ -79,10 +72,7 @@ export function request( url, method, ...config, - } as any; - - // 添加自定义属性 - (axiosConfig as any).useToken2 = isToken2; + }; // 如果是FormData,不设置Content-Type,让浏览器自动设置 if (data instanceof FormData) { diff --git a/Cunkebao/src/api/request2.ts b/Cunkebao/src/api/request2.ts new file mode 100644 index 00000000..544181c4 --- /dev/null +++ b/Cunkebao/src/api/request2.ts @@ -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(); + +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 { + 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; diff --git a/Cunkebao/src/pages/login/Login.tsx b/Cunkebao/src/pages/login/Login.tsx index 6617e26b..9691a663 100644 --- a/Cunkebao/src/pages/login/Login.tsx +++ b/Cunkebao/src/pages/login/Login.tsx @@ -7,7 +7,12 @@ import { UserOutline, } from "antd-mobile-icons"; 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"; const Login: React.FC = () => { @@ -18,7 +23,7 @@ const Login: React.FC = () => { const [showPassword, setShowPassword] = useState(false); const [agreeToTerms, setAgreeToTerms] = useState(false); - const { login } = useUserStore(); + const { login, login2 } = useUserStore(); // 倒计时效果 useEffect(() => { @@ -66,32 +71,59 @@ const Login: React.FC = () => { Toast.show({ content: "请同意用户协议和隐私政策", position: "top" }); return; } - setLoading(true); - try { + getToken(values) + .then(() => { + getToken2(); + }) + .finally(() => { + setLoading(false); + }); + }; + const getToken = (values: any) => { + return new Promise((resolve, reject) => { // 添加typeId参数 const loginParams = { ...values, typeId: activeTab as number, }; - let response; - if (activeTab === 1) { - response = await loginWithPassword(loginParams); - } else { - response = await loginWithCode(loginParams); - } + const response = + activeTab === 1 + ? loginWithPassword(loginParams) + : loginWithCode(loginParams); - // 获取设备总数 - const deviceTotal = response.deviceTotal || 0; + response + .then(res => { + // 获取设备总数 + const deviceTotal = res.deviceTotal || 0; - // 更新状态管理(token会自动存储到localStorage,用户信息存储在状态管理中) - login(response.token, response.member, deviceTotal); - } catch (error: any) { - // 错误已在request中处理,这里不需要额外处理 - } finally { - setLoading(false); - } + // 更新状态管理(token会自动存储到localStorage,用户信息存储在状态管理中) + login(res.token, res.member, deviceTotal); + resolve(res); + }) + .catch(err => { + 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); + }); + }); }; // 第三方登录处理 diff --git a/Cunkebao/src/pages/login/api.ts b/Cunkebao/src/pages/login/api.ts index 9c1f6e6c..16d81e33 100644 --- a/Cunkebao/src/pages/login/api.ts +++ b/Cunkebao/src/pages/login/api.ts @@ -1,33 +1,5 @@ import request from "@/api/request"; -export interface LoginParams { - 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; -} - +import request2 from "@/api/request2"; // 密码登录 export function loginWithPassword(params: any) { return request("/v1/auth/login", params, "POST"); @@ -52,3 +24,17 @@ export function logout() { export function getUserInfo() { 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, + ); +} diff --git a/Cunkebao/src/store/module/user.ts b/Cunkebao/src/store/module/user.ts index d73315c4..aeb811a8 100644 --- a/Cunkebao/src/store/module/user.ts +++ b/Cunkebao/src/store/module/user.ts @@ -29,6 +29,7 @@ interface UserState { setToken2: (token2: string) => void; clearUser: () => void; login: (token: string, userInfo: User, deviceTotal: number) => void; + login2: (token2: string) => void; logout: () => void; } @@ -41,7 +42,8 @@ export const useUserStore = createPersistStore( setUser: user => set({ user, isLoggedIn: true }), setToken: token => set({ token }), 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) => { // 只将token存储到localStorage localStorage.setItem("token", token); @@ -76,6 +78,10 @@ export const useUserStore = createPersistStore( window.location.href = "/guide"; } }, + login2: token2 => { + localStorage.setItem("token2", token2); + set({ token2, isLoggedIn: true }); + }, logout: () => { // 清除localStorage中的token localStorage.removeItem("token");