fix:优化登录模块

master
zhoulexin 13 hours ago
parent 07e6ee814f
commit 2079a63bdc

@ -2,6 +2,7 @@
<html lang="zh-CN"> <html lang="zh-CN">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>智能视觉管理平台</title> <title>智能视觉管理平台</title>
</head> </head>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1779701174734" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5938" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><path d="M512 512m-34.133333 0a34.133333 34.133333 0 1 0 68.266666 0 34.133333 34.133333 0 1 0-68.266666 0Z" fill="#1296db" p-id="5939"></path><path d="M512 392.533333c-85.333333 0-153.6 85.333333-187.733333 119.466667 34.133333 34.133333 102.4 119.466667 187.733333 119.466667 85.333333 0 153.6-85.333333 187.733333-119.466667-34.133333-34.133333-102.4-119.466667-187.733333-119.466667zM512 597.333333c-51.2 0-85.333333-34.133333-85.333333-85.333333S460.8 426.666667 512 426.666667s85.333333 34.133333 85.333333 85.333333-34.133333 85.333333-85.333333 85.333333z" fill="#1296db" p-id="5940"></path><path d="M512 0c-290.133333 0-512 221.866667-512 512s221.866667 512 512 512 512-221.866667 512-512-221.866667-512-512-512z m0 682.666667c-136.533333 0-238.933333-170.666667-238.933333-170.666667s102.4-170.666667 238.933333-170.666667 238.933333 170.666667 238.933333 170.666667-102.4 170.666667-238.933333 170.666667z" fill="#1296db" p-id="5941"></path></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

@ -8,6 +8,12 @@
class="video-player" class="video-player"
></video> ></video>
<!-- 加载状态 -->
<div v-if="loading" class="loading-overlay">
<span class="spinner"></span>
<span>连接中...</span>
</div>
<!-- 录制状态指示器 --> <!-- 录制状态指示器 -->
<div v-if="isRecording" class="recording-indicator"> <div v-if="isRecording" class="recording-indicator">
<span class="dot"></span> 录制中 {{ recordTime }}s <span class="dot"></span> 录制中 {{ recordTime }}s
@ -36,6 +42,7 @@ const emit = defineEmits(['record-status-change','record-complete']);
const videoRef = ref(null); const videoRef = ref(null);
const error = ref(''); const error = ref('');
const loading = ref(false);
let pc = null; let pc = null;
// --- --- // --- ---
@ -59,6 +66,8 @@ const disconnect = () => {
// 2. WebRTC // 2. WebRTC
const connect = async () => { const connect = async () => {
loading.value = true;
error.value = '';
try { try {
pc = new RTCPeerConnection(); pc = new RTCPeerConnection();
pc.ontrack = (event) => { pc.ontrack = (event) => {
@ -85,6 +94,11 @@ const connect = async () => {
} catch (e) { } catch (e) {
error.value = '连接失败,请检查视频地址'; error.value = '连接失败,请检查视频地址';
console.error(e); console.error(e);
} finally {
let timeout = setTimeout(() => {
loading.value = false;
clearTimeout(timeout);
}, 1500);
} }
}; };
@ -215,6 +229,29 @@ defineExpose({
.video-player { width: 100%; height: 100%; object-fit: contain; } .video-player { width: 100%; height: 100%; object-fit: contain; }
.error-overlay { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: white; } .error-overlay { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: white; }
.loading-overlay {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: rgba(255, 255, 255, 0.85);
font-size: 14px;
display: flex;
align-items: center;
gap: 8px;
}
.spinner {
width: 20px;
height: 20px;
border: 2px solid rgba(255, 255, 255, 0.3);
border-top-color: #409eff;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.recording-indicator { .recording-indicator {
position: absolute; position: absolute;
top: 10px; top: 10px;

@ -2,10 +2,8 @@
<el-container class="layout-container"> <el-container class="layout-container">
<el-aside :width="isCollapsed ? '64px' : '200px'" class="aside"> <el-aside :width="isCollapsed ? '64px' : '200px'" class="aside">
<div class="logo"> <div class="logo">
<!-- <img src="@/assets/images/logo.png" alt="logo" v-if="!isCollapsed" /> --> <svg t="1776756485739" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2128" width="32" height="32"><path d="M512 40.832a381.76 381.76 0 1 0 381.76 381.76A381.824 381.824 0 0 0 512 40.832zM307.2 206.208a44.8 44.8 0 1 1 44.8 44.8 44.8 44.8 0 0 1-44.8-44.8zM512 582.272a159.68 159.68 0 1 1 159.68-159.68A159.68 159.68 0 0 1 512 582.272z m0 0" fill="#409EFF" p-id="2129"></path><path d="M797.312 761.728a380.416 380.416 0 0 1-567.104 4.16l-70.4 161.216c-12.8 30.016 12.8 56.128 57.6 56.128h593.984c45.312 0 70.976-26.112 57.6-56.128z m0 0" fill="#409EFF" p-id="2130"></path></svg>
<svg v-if="!isCollapsed" t="1776756485739" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2128" width="32" height="32"><path d="M512 40.832a381.76 381.76 0 1 0 381.76 381.76A381.824 381.824 0 0 0 512 40.832zM307.2 206.208a44.8 44.8 0 1 1 44.8 44.8 44.8 44.8 0 0 1-44.8-44.8zM512 582.272a159.68 159.68 0 1 1 159.68-159.68A159.68 159.68 0 0 1 512 582.272z m0 0" fill="#409EFF" p-id="2129"></path><path d="M797.312 761.728a380.416 380.416 0 0 1-567.104 4.16l-70.4 161.216c-12.8 30.016 12.8 56.128 57.6 56.128h593.984c45.312 0 70.976-26.112 57.6-56.128z m0 0" fill="#409EFF" p-id="2130"></path></svg>
<span v-if="!isCollapsed"></span> <span v-if="!isCollapsed"></span>
<el-icon v-else><Document /></el-icon>
</div> </div>
<el-menu <el-menu

@ -1,6 +1,6 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { ref } from 'vue' import { ref } from 'vue'
import { loginApi, registerApi, logoutApi, getUserInfoApi } from '@/api/user' import { loginApi, registerApi, logoutApi, getUserInfoApi, newPodApi } from '@/api/user'
export const useUserStore = defineStore('user', () => { export const useUserStore = defineStore('user', () => {
const token = ref(localStorage.getItem('token') || '') const token = ref(localStorage.getItem('token') || '')
@ -36,15 +36,25 @@ export const useUserStore = defineStore('user', () => {
const logout = async () => { const logout = async () => {
if (isLoggingOut.value) return if (isLoggingOut.value) return
isLoggingOut.value = true isLoggingOut.value = true
const params = {
"session": 2878481200,
"id": 2,
"call": {
"service": "rpc",
"method": "logout"
}
}
try { try {
await logoutApi() await logoutApi()
// 退出后台吊舱登录
await newPodApi(params)
} catch (e) { } catch (e) {
// 忽略logout接口错误 // 忽略logout接口错误
} finally { } finally {
token.value = '' token.value = ''
userInfo.value = null userInfo.value = null
localStorage.removeItem('token') localStorage.removeItem('token')
localStorage.removeItem('newPodSession')
isLoggingOut.value = false isLoggingOut.value = false
} }
} }

@ -192,8 +192,9 @@ const podInfo = async () => {
} }
} }
// //
const newPodSession = localStorage.getItem('newPodSession')
const params = { const params = {
"session": 671150784, "session": Number(newPodSession),
"id": 2, "id": 2,
"call": { "call": {
"service": "ptz", "service": "ptz",
@ -278,7 +279,7 @@ const aperture = async(val) => {
const wiperCtrl = ref(false) const wiperCtrl = ref(false)
const wiper = () => { const wiper = () => {
const reqParams = { const reqParams = {
"session": 671150784, "session": Number(newPodSession),
"id": 2, "id": 2,
"call": { "call": {
"service": "ptz", "service": "ptz",
@ -295,7 +296,7 @@ const initialization = ref(false)
const lensInitialization = async() => { const lensInitialization = async() => {
initialization.value = true initialization.value = true
const reqParams = { const reqParams = {
"session": 671150784, "session": Number(newPodSession),
"id": 2, "id": 2,
"call": { "call": {
"service": "ptz", "service": "ptz",

@ -97,12 +97,13 @@
@keydown.enter.exact.prevent="handleSend" @keydown.enter.exact.prevent="handleSend"
/> />
<div class="upload-popover"> <div class="upload-popover">
<el-popover :visible="popVisible" placement="top" :width="570" trigger="click"> <el-popover v-model:visible="popVisible" placement="top" :width="570" trigger="click">
<template #reference> <template #reference>
<el-icon @click="popVisible = true"><Upload /></el-icon> <el-icon><Upload /></el-icon>
</template> </template>
<el-cascader-panel v-model="datasetValue" :options="dataSetOptions" :props="{value:'id',label:'name'}" clearable filterable /> <el-cascader-panel v-model="datasetValue" :options="dataSetOptions" :props="{value:'id',label:'name'}" clearable filterable />
<div style="text-align: right; margin-top:5px;"> <div style="text-align: right; margin-top:5px;">
<el-button size="small" text @click="popVisible = false">取消</el-button>
<el-button size="small" type="danger" text @click="selectClear"></el-button> <el-button size="small" type="danger" text @click="selectClear"></el-button>
<el-button size="small" type="primary" text style="margin: 0;" @click="handleDatasetConfirm"></el-button> <el-button size="small" type="primary" text style="margin: 0;" @click="handleDatasetConfirm"></el-button>
</div> </div>

@ -176,32 +176,20 @@ const loginRules = {
] ]
} }
const generateRandomString = (length = 6) => { const generateRandomString = (length = 6) => {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' // + ( I, O )
let result = '' const chars = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ';
let result = '';
const charsLength = chars.length;
for (let i = 0; i < length; i++) { for (let i = 0; i < length; i++) {
result += chars.charAt(Math.floor(Math.random() * chars.length)) const randomIndex = Math.floor(Math.random() * charsLength);
result += chars[randomIndex];
} }
return result
return result;
} }
const handleLogin = async () => { const handleLogin = async () => {
// const random = generateRandomString()
// const podLogin = await newPodApi({
// "session": 0,
// "id": 2,
// "call": {
// "service": "rpc",
// "method": "login"
// },
// "params": {
// "userName": "admin",
// "password": sha256(md5('abcd1234')+random),
// "random": random,
// "ip": "127.0.0.1",
// "port": 80,
// "encryptType": 1
// }
// })
// return;
if (!loginFormRef.value) return if (!loginFormRef.value) return
await loginFormRef.value.validate(async (valid) => { await loginFormRef.value.validate(async (valid) => {
@ -210,6 +198,25 @@ const handleLogin = async () => {
try { try {
const res = await userStore.login(loginForm) const res = await userStore.login(loginForm)
if (res.success) { if (res.success) {
//
const random = generateRandomString()
const podLogin = await newPodApi({
"session": 0,
"id": 2,
"call": {
"service": "rpc",
"method": "login"
},
"params": {
"userName": "admin",
"password": sha256(sha256('abcd1234') + random),
"random": random,
"ip": "127.0.0.1",
"port": 80,
"encryptType": 1
}
})
localStorage.setItem('newPodSession', podLogin.params.session)
// //
if (rememberMe.value) { if (rememberMe.value) {
saveCredentials() saveCredentials()

Loading…
Cancel
Save