diff --git a/auto-imports.d.ts b/auto-imports.d.ts index 8139ac9..08908ed 100644 --- a/auto-imports.d.ts +++ b/auto-imports.d.ts @@ -1,5 +1,5 @@ // Generated by 'unplugin-auto-import' export {} declare global { - const ElMessage: typeof import('element-plus/es')['ElMessage'] + } diff --git a/src/api/index.d.ts b/src/api/index.d.ts index c4a7d96..6481ada 100644 --- a/src/api/index.d.ts +++ b/src/api/index.d.ts @@ -22,6 +22,10 @@ export interface TRoleList { createTime?: string roleMenu?: TRoleMenu[] } +export interface TbindWeb { + devices: number[] + accountId: number +} export interface TStatisticsDevice { @@ -131,11 +135,10 @@ export namespace TLogin { export namespace TAccount { export interface IAdd { username: string; - password: string; phone: string; name: string; - orgId: number; - roleId: number; + orgId?: number | string; + roleId: number | string; status: number; } export interface IListReq extends Ipaging { @@ -282,6 +285,11 @@ export namespace TOrg { } } +export interface TstatisticsUseCount { + defaultCount: number; + monitorCount: number; + outsideCount: number; +} export namespace TWarnRecord { export interface IListReq extends Ipaging { @@ -314,6 +322,12 @@ export namespace TWarningDetail { interface TParams { id: number | string } + interface THealthData { + bo: number + hr: number + temp: number + time: number + } interface TRes { address: string adminName: string @@ -321,7 +335,7 @@ export namespace TWarningDetail { creatUser: string createTime: string deviceId: string - healthData: string + healthData: THealthData[] id: number lat: number lng: number diff --git a/src/api/index.ts b/src/api/index.ts index 42eb660..14b2751 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -1,5 +1,5 @@ import request from '../utils/request'; -import { TLogin, TAccount, IpagingRes, TDevice, TOrg, TRoleList, TStatisticsDevice, statisticsContentReq, statisticsContentRes, TStatisticsCount, TWarnRecord, TWarningDetail, TWarningConfirm, TDeviceConfigModify, TDeviceConfig, THealthLatestData, TLocateRecord, TSetUseStatus, TRoleMenuList, TRoleModify } from "./index.d"; +import { TLogin, TAccount, IpagingRes, TDevice, TOrg, TRoleList, TStatisticsDevice, statisticsContentReq, statisticsContentRes, TStatisticsCount, TWarnRecord, TWarningDetail, TWarningConfirm, TDeviceConfigModify, TDeviceConfig, THealthLatestData, TLocateRecord, TSetUseStatus, TRoleMenuList, TRoleModify, TbindWeb, TstatisticsUseCount } from "./index.d"; export const fetchLogin = (p: TLogin.Ireq): Promise => { return request({ @@ -76,6 +76,14 @@ export const accountList = (p: TAccount.IListReq): Promise => { + return request({ + url: '/v1/api/account/list/org', + method: 'get', + params: { orgId } + }); +}; // 重置密码 export const passwordReset = (p: TAccount.IResetPwd): Promise => { return request({ @@ -173,6 +181,13 @@ export const orgList = (p?: TOrg.IListReq): Promise => { + return request({ + url: '/v1/api/org/list', + method: 'get', + }); +}; // 删除机构 export const orgDelete = (p?: TOrg.Idel): Promise => { @@ -183,6 +198,15 @@ export const orgDelete = (p?: TOrg.Idel): Promise => { }); }; +// web设备绑定管理员 +export const bindWeb = (p: TbindWeb): Promise => { + return request({ + url: '/v1/api/device/web/bind/web', + method: 'post', + data: p + }); +}; + // 获取角色列表 export const roleList = (): Promise => { return request({ @@ -251,6 +275,14 @@ export const warnRecord = (p: TWarnRecord.IListReq): Promise => { + return request({ + url: '/v1/api/statistics/useCount', + method: 'get', + }); +}; + // 预警记录 export const warningDetail = (p: TWarningDetail.TParams): Promise => { return request({ diff --git a/src/assets/audio/warning1.mp3 b/src/assets/audio/warning1.mp3 deleted file mode 100644 index 098ae51..0000000 Binary files a/src/assets/audio/warning1.mp3 and /dev/null differ diff --git a/src/assets/img/avatar.png b/src/assets/img/avatar.png new file mode 100644 index 0000000..c23b9ea Binary files /dev/null and b/src/assets/img/avatar.png differ diff --git a/src/assets/img/img.jpg b/src/assets/img/img.jpg deleted file mode 100644 index cbe6c00..0000000 Binary files a/src/assets/img/img.jpg and /dev/null differ diff --git a/src/components/alarm.vue b/src/components/alarm.vue index 4c5957c..55cdd63 100644 --- a/src/components/alarm.vue +++ b/src/components/alarm.vue @@ -47,7 +47,6 @@ const emit = defineEmits(["close", "confirm"]); const handleAudioEnd = () => { emit("close"); - // if (audioPlayer.value) { // audioPlayer.value.play().catch((error) => { // console.error("自动播放被阻止:", error); @@ -56,23 +55,11 @@ const handleAudioEnd = () => { }; onMounted(() => { - // 确保在DOM完全加载后播放音频 - // if (audioPlayer.value) { - // setTimeout(() => { - // audioPlayer.value.play(); - // }); - // audioPlayer.value.play(); - // // 设置音频静音,浏览器允许自动播放 - // audioPlayer.value - // .play() - // .then(() => { - // // 自动播放成功后取消静音 - // audioPlayer.value.muted = false; - // }) - // .catch((error) => { - // console.log("自动播放失败", error); - // }); - // } + if (audioPlayer.value) { + audioPlayer.value.play().catch((error) => { + console.error("自动播放被阻止:", error); + }); + } }); diff --git a/src/components/header.vue b/src/components/header.vue index 6612b6f..24a2fc6 100644 --- a/src/components/header.vue +++ b/src/components/header.vue @@ -7,7 +7,7 @@ {{ item }}{{ index != tab.list.length - 1 ? " / " : "" }} -
{{ format(time) }} 更新
+
{{ format(comm.time) }} 更新
@@ -33,7 +33,7 @@ - {{ user.username }} + {{ comm.user.username }} @@ -49,23 +49,24 @@
diff --git a/src/layout/index copy.vue b/src/layout/index copy.vue deleted file mode 100644 index 3da49f4..0000000 --- a/src/layout/index copy.vue +++ /dev/null @@ -1,120 +0,0 @@ - - - - diff --git a/src/layout/index.vue b/src/layout/index.vue index e5d4aa6..cde39e7 100644 --- a/src/layout/index.vue +++ b/src/layout/index.vue @@ -13,8 +13,7 @@
- - + diff --git a/src/main.ts b/src/main.ts index 4ba0fbd..243d17e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -7,12 +7,14 @@ import { usePermissStore } from './store/permiss'; import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' import 'element-plus/dist/index.css'; import './assets/css/icon.css'; - +import WebSocketService from "@/utils/webSocket.js"; +const ws = new WebSocketService() const app = createApp(App); const pinia = createPinia(); pinia.use(piniaPluginPersistedstate); app.use(pinia); app.use(router); +app.provide('ws', ws) // 注册elementplus图标 for (const [key, component] of Object.entries(ElementPlusIconsVue)) { diff --git a/src/router/index.ts b/src/router/index.ts index 13489c7..2e44eb6 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -17,7 +17,7 @@ import m4_a from "@/assets/img/m4_a.png"; export const routes: RouteRecordRaw[] = [ { path: '/', - component: Layout, + component: () => import('@/layout/index.vue'), redirect: '/statisticalCenter', children: [ { @@ -123,14 +123,12 @@ const router = createRouter({ }); router.beforeEach((to, from, next) => { - NProgress.start(); const permiss = usePermissStore(); const comm = useCommonStore(); const tab = useTabsStore(); tab.setTabsItem(to.meta.tabs); comm.setTime() - if (typeof to.meta.permiss == 'string' && !permiss.key.includes(to.meta.permiss)) { // 如果没有权限,则进入403 next('/403'); diff --git a/src/types/form-option.ts b/src/types/form-option.ts index 29ecaa3..0cee5fc 100644 --- a/src/types/form-option.ts +++ b/src/types/form-option.ts @@ -18,5 +18,6 @@ export interface FormOptionList { activeText?: string; inactiveText?: string; required?: boolean; + defalut?: any; validator?: Function; } \ No newline at end of file diff --git a/src/utils/mapCustom.js b/src/utils/mapCustom.js index 505d8cd..993d718 100644 --- a/src/utils/mapCustom.js +++ b/src/utils/mapCustom.js @@ -10,6 +10,7 @@ export class MapCustom { } // 多边形回显 polyEditor(list, fn) { + if (!list) return; this.map.clearMap(); let pathList = []; list.forEach((item, index) => { diff --git a/src/utils/request.ts b/src/utils/request.ts index d0dba1e..fd84f2b 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -22,6 +22,8 @@ service.interceptors.request.use( service.interceptors.response.use( (response: AxiosResponse) => { const { data, headers } = response; + if (headers['content-type'] === "application/vnd.ms-excel;charset=utf-8") return data + if (data.code !== 200) { ElMessage.error(data.msg) diff --git a/src/utils/webSocket.js b/src/utils/webSocket.js index f881ffa..1f5ff68 100644 --- a/src/utils/webSocket.js +++ b/src/utils/webSocket.js @@ -1,33 +1,32 @@ -import { ref, onMounted, onUnmounted } from 'vue'; - -class WebSocketService { +import { useCommonStore } from "@/store/common"; +export default class WebSocketService { constructor() { this.url = import.meta.env.VITE_APP_URL_WEBSOCKET; this.socket = null; this.isAlive = false; // 用于判断心跳是否正常 this.reconnectAttempts = 0; // 重连尝试次数 this.MAX_RECONNECT_ATTEMPTS = 5; // 最大重连次数 - this.HEARTBEAT_INTERVAL = 5000; // 心跳间隔时间 (30秒) - // this.HEARTBEAT_INTERVAL = 30000; // 心跳间隔时间 (30秒) + // this.HEARTBEAT_INTERVAL = 5000; // 心跳间隔时间 (30秒) + this.HEARTBEAT_INTERVAL = 30000; // 心跳间隔时间 (30秒) this.heartbeatTimer = null; this.reconnectTimer = null; - this.connect(); + // this.connect(); } connect() { this.socket = new WebSocket(this.url); - this.socket.onopen = () => { console.log('WebSocket已连接'); this.webScoketLogin(); this.reconnectAttempts = 0; // 成功连接后重置重试次数 this.startHeartbeat(); // 开始心跳检测 }; - + this.onMessage() this.socket.onmessage = (event) => { // 处理接收到的消息 - console.log('Message received:', event.data); + console.log('WebSocket收到消息:', event.data); + this.receivePong() }; this.socket.onclose = () => { @@ -49,8 +48,9 @@ class WebSocketService { cmd: "webLogin", }) } - + // 开始发送心跳 startHeartbeat() { + console.log('开始发送心跳'); if (!this.heartbeatTimer) { this.heartbeatTimer = setInterval(() => { if (this.socket.readyState === WebSocket.OPEN) { @@ -60,7 +60,7 @@ class WebSocketService { }, this.HEARTBEAT_INTERVAL); } } - + // 关闭发送心态 stopHeartbeat() { if (this.heartbeatTimer) { clearInterval(this.heartbeatTimer); @@ -69,8 +69,6 @@ class WebSocketService { } sendPing() { - console.log('发送心跳', JSON.stringify({ cmd: 'heartbeat' })); - this.socket.send(JSON.stringify({ cmd: 'heartbeat' })); setTimeout(() => { if (!this.isAlive) { @@ -83,25 +81,39 @@ class WebSocketService { receivePong() { this.isAlive = true; } - + // 重新连接 attemptReconnect() { + const comm = useCommonStore(); + if (!comm.user.token) return if (this.reconnectAttempts < this.MAX_RECONNECT_ATTEMPTS) { this.reconnectAttempts++; - console.log(`Attempting to reconnect (${this.reconnectAttempts})...`); + console.log(`正在尝试重新连接 (${this.reconnectAttempts})...`); this.reconnectTimer = setTimeout(() => { this.connect(); }, 1000 * this.reconnectAttempts); // 指数退避算法 } else { - console.error('Max reconnect attempts reached'); + console.error('达到的最大重连尝试数'); } } - + // 发送消息 sendMessage(message) { + console.log('sendMessage'); if (this.socket && this.socket.readyState === WebSocket.OPEN) { this.socket.send(JSON.stringify(message)); } } + onMessage = (callback) => { + this.socket.onmessage = (event) => { + const data = JSON.parse(event.data); + if (data.cmd == "webLogin" && !data.code == 200) return this.webScoketLogin() + callback && callback(data); + if (event.data.includes('heartbeat')) { + this.receivePong(); + } + }; + }; + // 关闭连接 close() { this.stopHeartbeat(); if (this.reconnectTimer) { @@ -115,44 +127,3 @@ class WebSocketService { } } -export default function useWebSocket() { - const ws = new WebSocketService(); - - const message = ref(null); - const isConnected = ref(false); - - const onMessage = (callback) => { - ws.socket.onmessage = (event) => { - const data = JSON.parse(event.data); - if (data.cmd == "webLogin" && !data.code == 200) return ws.webScoketLogin() - - callback(data); - if (event.data.includes('heartbeat')) { - ws.receivePong(); - } - }; - }; - - const onClose = () => { - ws.socket.onclose() - }; - - const onOpen = (callback) => { - ws.socket.onopen = () => { - isConnected.value = true; - callback(); - }; - }; - - // onMounted(() => { - // onOpen(() => console.log('Connected')); - // onClose(() => console.log('Disconnected')); - // onMessage((data) => console.log('Received:', data)); - // }); - - // onUnmounted(() => { - // ws.close(); - // }); - - return { isConnected, message, sendMessage: ws.sendMessage.bind(ws), onMessage, onClose }; -} \ No newline at end of file diff --git a/src/views/incidentDispose/index.vue b/src/views/incidentDispose/index.vue index d4d3476..b0b8644 100644 --- a/src/views/incidentDispose/index.vue +++ b/src/views/incidentDispose/index.vue @@ -5,6 +5,7 @@
+
设备生理数据
@@ -20,7 +21,12 @@
绑定关联人名称:{{ curData.username }}
绑定关联人警号:{{ curData.userNumber }}
-
状态:{{ statusEnum[curData.status] }}
+
+ 状态: + + {{ statusEnum[curData.status] }} + +
紧急电话:{{ curData.adminPhone }}
隶属辖区:{{ curData.orgName }}
@@ -77,13 +83,14 @@ diff --git a/src/views/synthesizeManage/deviceManage/index.vue b/src/views/synthesizeManage/deviceManage/index.vue index 824db35..1c056b4 100644 --- a/src/views/synthesizeManage/deviceManage/index.vue +++ b/src/views/synthesizeManage/deviceManage/index.vue @@ -2,10 +2,10 @@
- + @@ -41,18 +41,22 @@ + + +
+ diff --git a/src/views/synthesizeManage/userManage/index.vue b/src/views/synthesizeManage/userManage/index.vue index b7cfe63..0b02d28 100644 --- a/src/views/synthesizeManage/userManage/index.vue +++ b/src/views/synthesizeManage/userManage/index.vue @@ -38,7 +38,10 @@
- + + + + @@ -50,16 +53,18 @@ diff --git a/src/views/synthesizeManage/userManage/resetPwd.vue b/src/views/synthesizeManage/userManage/resetPwd.vue new file mode 100644 index 0000000..5f34c9a --- /dev/null +++ b/src/views/synthesizeManage/userManage/resetPwd.vue @@ -0,0 +1,58 @@ + + + + diff --git a/sta.html b/sta.html deleted file mode 100644 index a4ce375..0000000 --- a/sta.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - 背景音乐示例 - - - - -

欢迎来到我的网站

- - - - - - - - - \ No newline at end of file