Browse Source

补充目录和环境变量

master
zhangjiming 6 months ago
parent
commit
25d477b0da
  1. 3
      .env
  2. 27
      src/main.ts
  3. 58
      src/services/axios.ts
  4. 108
      src/services/socket.ts
  5. 9
      src/utils/index.ts

3
.env

@ -0,0 +1,3 @@
VITE_API_HOST=window.location.hostname
VITE_API_PORT=80
VITE_WS_PATH=/api/v1/app/ws/state

27
src/main.ts

@ -1,17 +1,20 @@
import './style.css'
import './assets/main.css'
import "./style.css";
import "./assets/main.css";
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import Vant from 'vant'
import App from './App.vue'
import router from './router'
import 'vant/lib/index.css';
import { createApp } from "vue";
import { createPinia } from "pinia";
import Vant from "vant";
import App from "./App.vue";
import router from "./router";
import "vant/lib/index.css";
const app = createApp(App)
const app = createApp(App);
app.use(createPinia())
app.use(router)
app.use(createPinia());
app.use(router);
app.use(Vant);
app.mount('#app')
app.mount("#app");
console.log("API HOST:", import.meta.env.VITE_API_HOST);
console.log("API PORT:", import.meta.env.VITE_API_PORT);

58
src/services/axios.ts

@ -0,0 +1,58 @@
import axios from "axios";
const url = `${window.location.protocol}://${import.meta.env.VITE_API_HOST}:${import.meta.env.VITE_API_PORT}`;
const apiClient = axios.create({
baseURL: url, // 设置请求的根路径
timeout: 60000,
headers: {
"Content-Type": "application/json",
},
});
// 请求拦截器
// apiClient.interceptors.request.use(
// (config) => {
// const token = sessionStorage.getItem("token");
// if (!config.headers) {
// config.headers = AxiosHeaders.from({}); // 确保 config.headers 是 AxiosHeaders 类型
// }
// if (token) {
// config.headers.set("Authorization", `Bearer ${encodeURIComponent(token)}`); // 使用 set 方法设置 Authorization
// }
// return config;
// },
// error => {
// return Promise.reject(error);
// }
// );
// 响应拦截器
apiClient.interceptors.response.use(
(response) => {
if (response.data && response.data.dataType === "ZAppPromopt") {
if (response.data.ecode === "USR_NOT_EXIT") {
return Promise.resolve(response.data);
} else if (response.data.ecode === "USR_PASSWORD_ERROR") {
return Promise.resolve(response.data);
} else {
console.log("接口出错", response.data);
// eventBus.emit("show-error-modal", response.data.data);
return Promise.reject(response.data);
}
}
return response;
},
error => {
// eventBus.emit("show-error-modal", {
// messageLevel: "Error",
// title: "网络请求失败",
// info: error.message,
// });
return Promise.reject(error);
}
);
export default apiClient;

108
src/services/socket.ts

@ -0,0 +1,108 @@
import { Subject } from "rxjs";
export type SocketState = 'open' | 'close' | 'error'
class WebSocketClient {
private ws: WebSocket | null = null;
private url: string;
private reconnectAttempts: number = -1;
private maxReconnectAttempts: number = 5;
private reconnectInterval: number = 3000;
readonly dataOb = new Subject()
readonly stateOb = new Subject<SocketState>()
constructor(url: string) {
this.url = url;
}
// 连接 WebSocket
connect(): void {
try {
// WebSocket.CONNECTING (0) WebSocket.OPEN (1)
if (this.ws && this.ws.readyState <= 1) {
// 已连接
console.log(`${this.url} 正在连接或已连接,无需重复连接`);
} else {
this.ws = new WebSocket(this.url);
this.bindEvents();
}
} catch (error) {
console.error("WebSocket 连接失败:", error);
this.reconnect();
}
}
// 绑定事件
private bindEvents(): void {
if (!this.ws) return;
// 连接建立时的处理
this.ws.onopen = () => {
console.log("WebSocket 连接已建立");
this.reconnectAttempts = -1; // 重置重连次数
this.stateOb.next('open')
};
// 接收消息的处理
this.ws.onmessage = (event: MessageEvent) => {
try {
const data = JSON.parse(event.data);
// console.log('🚀 ~ WebSocketClient ~ bindEvents ~ data:', data)
this.dataOb.next(data)
} catch (error) {
console.error("消息解析错误:", error);
}
};
this.ws.onclose = () => {
this.stateOb.next('close')
console.log("WebSocket 连接已关闭");
this.reconnect();
};
this.ws.onerror = error => {
this.stateOb.next('error')
console.error("WebSocket 错误:", error);
};
}
// 重连机制
private reconnect(): void {
if (this.reconnectAttempts === -1) {
this.reconnectAttempts = 0;
}
if (this.reconnectAttempts >= this.maxReconnectAttempts) {
console.log("达到最大重连次数,停止重连");
this.reconnectAttempts = -1;
return;
}
setTimeout(() => {
console.log(`尝试第 ${this.reconnectAttempts + 1} 次重连...`);
this.reconnectAttempts++;
this.connect();
}, this.reconnectInterval);
}
// 关闭连接
disconnect(): void {
if (this.ws) {
this.ws.close();
this.ws = null;
}
}
}
const urlSocketMap = new Map<string, WebSocketClient>();
// 导出 WebSocket 客户端
export const createWebSocket = (url: string): WebSocketClient => {
if (urlSocketMap.has(url)) {
return urlSocketMap.get(url)!;
} else {
const client = new WebSocketClient(url);
urlSocketMap.set(url, client);
return client;
}
};

9
src/utils/index.ts

@ -0,0 +1,9 @@
export function isValidIPv4(ip: string) {
const ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
return ipv4Regex.test(ip);
}
export function formatRemainTime(seconds: number) {
const min = Math.floor(seconds / 60).toFixed();
const sec = (seconds % 60).toFixed();
return min.padStart(2, "0") + ":" + sec.padStart(2, "0");
}
Loading…
Cancel
Save