100j控制面包页面开发
This commit is contained in:
@ -6,8 +6,8 @@ VITE_APP_ENV = 'development'
|
||||
|
||||
# 开发环境
|
||||
# VITE_APP_BASE_API = 'http://139.224.253.23:8000'
|
||||
# VITE_APP_BASE_API = 'https://www.cnxhyc.com/jq'
|
||||
VITE_APP_BASE_API = 'http://192.168.110.57:8000'
|
||||
VITE_APP_BASE_API = 'https://www.cnxhyc.com/jq'
|
||||
#VITE_APP_BASE_API = 'http://192.168.110.57:8000'
|
||||
#代永飞接口
|
||||
# VITE_APP_BASE_API = 'http://457102h2d6.qicp.vip:24689'
|
||||
|
||||
|
||||
51
src/api/controlCenter/controlPanel/100J.ts
Normal file
51
src/api/controlCenter/controlPanel/100J.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
// 详情信息
|
||||
export const deviceDeatil = (id: string) => {
|
||||
return request({
|
||||
url: `/api/hby100j/device/${id}`,
|
||||
method: 'get',
|
||||
});
|
||||
};
|
||||
// 灯光模式
|
||||
function lightModeSettings (data: any) {
|
||||
return request({
|
||||
url: `/app/hby100j/device/lightAdjustment`,
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
//频率调节
|
||||
function staticPowerSetting (data: any) {
|
||||
return request({
|
||||
url: `/app/hby100j/device/strobeFrequency`,
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
// 修改音量
|
||||
function settingUpdateVolume (data: any) {
|
||||
return request({
|
||||
url: `/app/hby100j/device/updateVolume`,
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
// 强制报警
|
||||
function SosSetting (data: any) {
|
||||
return request({
|
||||
url: `/app/hby100j/device/forceAlarmActivation`,
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
export default {
|
||||
deviceDeatil,
|
||||
lightModeSettings:lightModeSettings,
|
||||
SosSetting:SosSetting,
|
||||
staticPowerSetting:staticPowerSetting,
|
||||
settingUpdateVolume:settingUpdateVolume
|
||||
};
|
||||
@ -36,12 +36,8 @@ export interface DeviceDetail {
|
||||
currentLightMode?: string;// 当前选中的灯光模式(如"strong",对应强光)
|
||||
sendMsg: string;
|
||||
lightBrightness: string;
|
||||
personnelInfo: { // 人员信息(嵌套对象,根据接口调整)
|
||||
unitName: string; // 单位
|
||||
position: string; // 职位
|
||||
name: string; // 姓名
|
||||
code: string; // ID(身份证/工号)
|
||||
};
|
||||
strobeFrequency: string;
|
||||
volume: string;
|
||||
chargeState: string;
|
||||
alarmStatus: number
|
||||
}
|
||||
|
||||
@ -28,7 +28,6 @@ function copyTextToClipboard(input: string, { target = document.body } = {}) {
|
||||
element.value = input;
|
||||
// Prevent keyboard from showing on mobile
|
||||
element.setAttribute('readonly', '');
|
||||
|
||||
element.style.contain = 'strict';
|
||||
element.style.position = 'absolute';
|
||||
element.style.left = '-9999px';
|
||||
|
||||
886
src/views/controlCenter/100J/index.vue
Normal file
886
src/views/controlCenter/100J/index.vue
Normal file
@ -0,0 +1,886 @@
|
||||
<template>
|
||||
<div class="device-page p-2">
|
||||
<!-- 头部信息栏 -->
|
||||
<div class="header-bar">
|
||||
<div>设备名称:{{ deviceDetail.deviceName }}</div>
|
||||
<div>设备型号:{{ deviceDetail.deviceImei }}</div>
|
||||
<div class="device-status">设备状态:
|
||||
<span :class="{ online: deviceDetail.onlineStatus === 1, offline: deviceDetail?.onlineStatus === 0 }">
|
||||
{{ deviceDetail.onlineStatus === 1 ? '在线' : '离线' }}
|
||||
</span>
|
||||
</div>
|
||||
<div>电量:{{ deviceDetail.batteryPercentage || 0 }}%</div>
|
||||
<div>续航:{{ deviceDetail.batteryRemainingTime || "0" }} 分钟</div>
|
||||
</div>
|
||||
|
||||
<!-- 主体内容区域 -->
|
||||
<div class="content-wrapper">
|
||||
<el-row :gutter="20" class="content-row" :class="deviceDetail.alarmStatus == 1 ? '' : 'displayNone'">
|
||||
<el-col :lg="24" :xs="24">
|
||||
<div class="staticRwo" :class="deviceDetail.alarmStatus == 1 ? '' : 'displayNone'"
|
||||
@click="showClose()">
|
||||
设备强制报警中!
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- 第一行:灯光模式 + 灯光亮度、强制报警、位置信息 -->
|
||||
<el-row :gutter="20" class="content-row">
|
||||
<el-col :lg="16" :xs="24">
|
||||
<div class="content-card">
|
||||
<h4 class="section-title">报警模式</h4>
|
||||
<div class="light-mode">
|
||||
<!-- 使用v-for循环渲染灯光模式卡片 -->
|
||||
<div class="mode-card" :class="{ 'active': mode.active }"
|
||||
@click.stop="handleVoiceType(mode.id)" v-for="mode in sta_VoiceType" :key="mode.id">
|
||||
<img :src="mode.active ? mode.activeIcon : mode.icon" :alt="mode.name"
|
||||
class="mode-icon" />
|
||||
<div class="mode-name">{{ mode.name }}</div>
|
||||
<el-switch v-model="mode.switchStatusVioice" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :lg="8" :xs="24">
|
||||
<div class="brightness-alarm">
|
||||
<el-button type="danger" class="alarm-btn" @click="forceAlarm" :loading="forceAlarmLoading"
|
||||
v-if="deviceDetail.alarmStatus === 0 || deviceDetail.alarmStatus === null"
|
||||
:loading-text="forceAlarmLoading ? '报警中...' : '强制报警'"> {{
|
||||
forceAlarmLoading ? '报警中' : '强制报警' }}</el-button>
|
||||
</div>
|
||||
<div class="content-card_gps">
|
||||
<h4 class="section-title">位置信息</h4>
|
||||
<div class="location-info">
|
||||
<div class="location-item">
|
||||
<span class="location-icon"></span>
|
||||
<span>经纬度 {{ deviceDetail && deviceDetail.longitude ?
|
||||
Number(deviceDetail.longitude).toFixed(4) : '无' }}
|
||||
{{ deviceDetail && deviceDetail.latitude ? Number(deviceDetail.latitude).toFixed(4)
|
||||
: '无' }} </span>
|
||||
</div>
|
||||
<div class="location-item">
|
||||
|
||||
<div>地址 <span class="lacatin_gps">{{ deviceDetail.address || "未获取到地址" }}</span></div>
|
||||
<el-button link type="primary" class="view-btn"
|
||||
@click="lookMap(deviceDetail)">查看</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 第二行:人员信息登记 + 发送信息 -->
|
||||
<el-row :gutter="20" class="content-row">
|
||||
<el-col :lg="16" :xs="24">
|
||||
<div class="content-card">
|
||||
<h4 class="section-title">警示灯模式</h4>
|
||||
<div class="light-mode">
|
||||
<!-- 使用v-for循环渲染灯光模式卡片 -->
|
||||
<div class="mode-card" :class="{ 'active': mode.active }"
|
||||
@click.stop="handleModeClick(mode.id)" v-for="mode in lightModes" :key="mode.id">
|
||||
<img :src="mode.active ? mode.activeIcon : mode.icon" :alt="mode.name"
|
||||
class="mode-icon" />
|
||||
<div class="mode-name">{{ mode.name }}</div>
|
||||
<el-switch v-model="mode.switchStatus" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :lg="8" :xs="24">
|
||||
<div class="content-card ">
|
||||
<div class="brightness-alarm">
|
||||
<div class="brightness-control">
|
||||
<span class="brightness-label">亮度</span>
|
||||
<el-input class="inputTFT" v-model="deviceDetail.lightBrightness" :min="10" :max="100"
|
||||
:step="1" size="small" />
|
||||
<span class="brightness-value">%</span>
|
||||
<el-button type="primary" class="save-btn" v-loading="lightModesLoading"
|
||||
@click="saveBtnlight">保存 </el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="brightness-alarm">
|
||||
<div class="brightness-control">
|
||||
<span class="brightness-label">频率</span>
|
||||
<el-input class="inputTFT" v-model="deviceDetail.strobeFrequency" :min="0.5" :max="10"
|
||||
:step="1" size="small" />
|
||||
<span class="brightness-value">HZ</span>
|
||||
<el-button type="primary" class="save-btn" @click="saveBtnstrobe">保存 </el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="brightness-alarm">
|
||||
<div class="brightness-control">
|
||||
<span class="brightness-label">音量</span>
|
||||
<el-input class="inputTFT" v-model="deviceDetail.volume" :min="10" :max="100" :step="1"
|
||||
size="small" />
|
||||
<span class="brightness-value">%</span>
|
||||
<el-button type="primary" class="save-btn" @click="saveBtnVolume">保存 </el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<!-- ===========充电提示框====== -->
|
||||
<el-dialog title="充电提示" v-model="centerDialogVisible" width="15%">
|
||||
<div style="display: flex; align-items: center;">
|
||||
<h3 style="color: rgba(224, 52, 52, 1)">设备电量低于20%</h3>
|
||||
</div>
|
||||
<div>请及时充电</div>
|
||||
<span slot="footer" class="dialog-footer" style="text-align: right;display: block;">
|
||||
<el-button type="primary" @click="centerDialogVisible = false">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script setup name="DeviceControl" lang="ts">
|
||||
const route = useRoute();
|
||||
import { useMqtt } from '@/utils/mqtt';
|
||||
import api from '@/api/controlCenter/controlPanel/100J'
|
||||
import { DeviceDetail, LightMode } from '@/api/controlCenter/controlPanel/types';
|
||||
import {getDeviceStatus } from '@/utils/function';
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const router = useRouter();
|
||||
// 导入图片资源(确保路径正确)
|
||||
import closeDefault from '@/assets/images/close.png';
|
||||
import closeActive from '@/assets/images/close_HL.png';
|
||||
import rb from '@/assets/images/rb.png';
|
||||
import rbAc from '@/assets/images/rbAc.png';
|
||||
import sg from '@/assets/images/sg.png';
|
||||
import sgAc from '@/assets/images/sgAc.png';
|
||||
const forceAlarmLoading = ref(false) //强制报警
|
||||
const lightModesLoading = ref(false)
|
||||
const centerDialogVisible = ref(false)
|
||||
const {
|
||||
connected,
|
||||
connect,
|
||||
subscribe,
|
||||
onConnect,
|
||||
onError,
|
||||
onMessage,
|
||||
disconnect
|
||||
} = useMqtt();
|
||||
// 报警模式
|
||||
const sta_VoiceType = ref([
|
||||
{
|
||||
id: 'fire',
|
||||
name: '消防',
|
||||
icon: sg, // 直接使用导入的变量
|
||||
activeIcon: sgAc,
|
||||
switchStatusVioice: true,
|
||||
active: true
|
||||
},
|
||||
{
|
||||
id: '0',
|
||||
name: '公安',
|
||||
icon: sg, // 直接使用导入的变量
|
||||
activeIcon: sgAc,
|
||||
active: false,
|
||||
switchStatusVioice: false,
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
name: '交警',
|
||||
icon: sg, // 直接使用导入的变量
|
||||
activeIcon: sgAc,
|
||||
switchStatusVioice: false,
|
||||
active: false
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
name: '市政',
|
||||
icon: sg, // 直接使用导入的变量
|
||||
activeIcon: sgAc,
|
||||
switchStatusVioice: false,
|
||||
active: false
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
name: '应急',
|
||||
icon: sg, // 直接使用导入的变量
|
||||
activeIcon: sgAc,
|
||||
switchStatusVioice: false,
|
||||
active: false
|
||||
},
|
||||
{
|
||||
id: '6',
|
||||
name: '医疗',
|
||||
icon: sg, // 直接使用导入的变量
|
||||
activeIcon: sgAc,
|
||||
switchStatusVioice: false,
|
||||
active: false
|
||||
},
|
||||
{
|
||||
id: '5',
|
||||
name: '铁道',
|
||||
icon: sg, // 直接使用导入的变量
|
||||
activeIcon: sgAc,
|
||||
switchStatusVioice: false,
|
||||
active: false
|
||||
},
|
||||
{
|
||||
id: '7',
|
||||
name: 'app语音',
|
||||
icon: sg, // 直接使用导入的变量
|
||||
activeIcon: sgAc,
|
||||
switchStatusVioice: false,
|
||||
active: false
|
||||
},
|
||||
{
|
||||
id: '-1',
|
||||
name: '关闭',
|
||||
icon: closeDefault, // 直接使用导入的变量
|
||||
activeIcon: closeActive,
|
||||
switchStatusVioice: false,
|
||||
active: false
|
||||
},
|
||||
])
|
||||
// 警示灯灯光模式数据(引用导入的图片)
|
||||
const lightModes = ref<LightMode[]>([
|
||||
{
|
||||
id: 'redBlueAlternate', // 红蓝交替
|
||||
name: '红蓝交替',
|
||||
icon: rb,
|
||||
activeIcon: rbAc,
|
||||
switchStatus: true,
|
||||
instructValue: '6',
|
||||
active: true,
|
||||
},
|
||||
{
|
||||
id: 'redFlash', // 红闪
|
||||
name: '红闪',
|
||||
icon: rb,
|
||||
activeIcon: rbAc,
|
||||
switchStatus: false,
|
||||
instructValue: '0',
|
||||
active: false,
|
||||
},
|
||||
{
|
||||
id: 'yellowFlash', // 黄闪
|
||||
name: '黄闪',
|
||||
icon: rb,
|
||||
activeIcon: rbAc,
|
||||
switchStatus: false,
|
||||
instructValue: '2',
|
||||
active: false
|
||||
},
|
||||
{
|
||||
id: 'blueFlash', // 蓝闪
|
||||
name: '蓝闪',
|
||||
icon: rb,
|
||||
activeIcon: rbAc,
|
||||
switchStatus: false,
|
||||
instructValue: '1',
|
||||
active: false
|
||||
},
|
||||
{
|
||||
id: 'redClockwise', // 红色顺时针
|
||||
name: '红色顺时针',
|
||||
icon: rb,
|
||||
activeIcon: rbAc,
|
||||
switchStatus: false,
|
||||
instructValue: '3',
|
||||
active: false
|
||||
},
|
||||
{
|
||||
id: 'yellowClockwise', // 黄色顺时针
|
||||
name: '黄色顺时针',
|
||||
icon: rb,
|
||||
activeIcon: rbAc,
|
||||
switchStatus: false,
|
||||
instructValue: '4',
|
||||
active: false
|
||||
},
|
||||
{
|
||||
id: 'redBlueClockwise', // 红蓝顺时针
|
||||
name: '红蓝顺时针',
|
||||
icon: rb,
|
||||
activeIcon: rbAc,
|
||||
switchStatus: false,
|
||||
instructValue: '5',
|
||||
active: false
|
||||
},
|
||||
{
|
||||
id: 'close', // 关闭
|
||||
name: '关闭',
|
||||
icon: closeDefault,
|
||||
activeIcon: closeActive,
|
||||
switchStatus: false,
|
||||
instructValue: '-1',
|
||||
active: false
|
||||
},
|
||||
]);
|
||||
const deviceDetail = ref<DeviceDetail & { typeName: string }>({
|
||||
lightBrightness: '',
|
||||
deviceName: '',
|
||||
deviceImei: '',
|
||||
onlineStatus: 0,
|
||||
batteryPercentage: 0,
|
||||
batteryRemainingTime: '',
|
||||
longitude: '',
|
||||
latitude: '',
|
||||
address: '',
|
||||
sendMsg: '',
|
||||
chargeState: '0',
|
||||
typeName: '',
|
||||
alarmStatus: 0,
|
||||
strobeFrequency: '0.5',
|
||||
volume: '10'
|
||||
});
|
||||
const isUpdatingStatus = ref(false);
|
||||
// 报警模式// 2. 点击卡片事件
|
||||
const handleVoiceType = async (targetId: string) => {
|
||||
const deviceId = route.params.deviceId as string;
|
||||
if (!deviceId) return;
|
||||
const targetMode = sta_VoiceType.value.find(mode => mode.id === targetId);
|
||||
if (!targetMode) return;
|
||||
if (targetMode.active) return;
|
||||
sta_VoiceType.value.forEach(mode => {
|
||||
mode.active = mode.id === targetId;
|
||||
if (mode.active) {
|
||||
mode.switchStatusVioice = true;
|
||||
} else {
|
||||
mode.switchStatusVioice = false;
|
||||
}
|
||||
});
|
||||
// 2. 调用强制报警接口
|
||||
const params = {
|
||||
deviceIds: [deviceId],
|
||||
voiceStrobeAlarm: targetId === '-1' ? 0 : 1,
|
||||
mode: targetId == '-1' ? 0 : targetId
|
||||
};
|
||||
try {
|
||||
const res = await api.SosSetting(params);
|
||||
if (res.code == 200) {
|
||||
proxy?.$modal.msgSuccess(res.msg);
|
||||
}
|
||||
} catch (error) {
|
||||
await getList()
|
||||
}
|
||||
};
|
||||
// 警示灯模式
|
||||
const handleModeClick = async (modeId: string) => {
|
||||
if (isUpdatingStatus.value || isSyncingStatus.value) return;
|
||||
try {
|
||||
const deviceId = route.params.deviceId as string;
|
||||
if (!deviceId) return;
|
||||
const targetMode = lightModes.value.find(m => m.id === modeId);
|
||||
if (!targetMode || !targetMode.instructValue) return;
|
||||
isUpdatingStatus.value = true;
|
||||
const res = await api.lightModeSettings({
|
||||
deviceId,
|
||||
instructValue: targetMode.instructValue,
|
||||
deviceImei: deviceDetail.value.deviceImei,
|
||||
typeName: deviceDetail.value.typeName,
|
||||
});
|
||||
if (res.code === 200) {
|
||||
ElMessage.closeAll();
|
||||
proxy?.$modal.msgSuccess(res.msg);
|
||||
setActiveLightMode(modeId);
|
||||
} else {
|
||||
proxy?.$modal.msgError(res.msg);
|
||||
const prevActiveMode = lightModes.value.find(m => m.active);
|
||||
if (prevActiveMode) {
|
||||
setActiveLightMode(prevActiveMode.id);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
// 异常时恢复状态
|
||||
const prevActiveMode = lightModes.value.find(m => m.active);
|
||||
if (prevActiveMode) {
|
||||
setActiveLightMode(prevActiveMode.id);
|
||||
}
|
||||
} finally {
|
||||
isUpdatingStatus.value = false;
|
||||
}
|
||||
};
|
||||
const isSyncingStatus = ref(false);
|
||||
// 警示灯接口
|
||||
const setActiveLightMode = (targetModeId: string) => {
|
||||
isSyncingStatus.value = true;
|
||||
lightModes.value.forEach(mode => {
|
||||
const isActive = mode.id === targetModeId;
|
||||
mode.active = isActive;
|
||||
mode.switchStatus = isActive;
|
||||
});
|
||||
isSyncingStatus.value = false;
|
||||
};
|
||||
const getList = async () => {
|
||||
try {
|
||||
const deviceId = route.params.deviceId;
|
||||
if (!deviceId) return;
|
||||
const res = await api.deviceDeatil(deviceId as string);
|
||||
deviceDetail.value = res.data;
|
||||
|
||||
// ==========灯光模式逻辑==========
|
||||
let targetModeId = "redBlueAlternate";
|
||||
const mainLightMode = String(res.data.strobeMode);
|
||||
const matchedMode = lightModes.value.find(
|
||||
mode => mode.instructValue === mainLightMode
|
||||
);
|
||||
if (matchedMode) {
|
||||
targetModeId = matchedMode.id;
|
||||
}
|
||||
setActiveLightMode(targetModeId);
|
||||
// 报警模式
|
||||
const alarmMode = String(res.data.alarmMode); // 报警模式ID
|
||||
const voiceStrobeAlarm = String(res.data.voiceStrobeAlarm); // 报警开关状态:1开启,0关闭
|
||||
// 先重置所有报警模式的状态
|
||||
sta_VoiceType.value.forEach(mode => {
|
||||
mode.active = false;
|
||||
mode.switchStatusVioice = false;
|
||||
});
|
||||
if (voiceStrobeAlarm === '1') {
|
||||
const matchedVoiceMode = sta_VoiceType.value.find(
|
||||
mode => mode.id === alarmMode
|
||||
);
|
||||
if (matchedVoiceMode) {
|
||||
matchedVoiceMode.active = true;
|
||||
matchedVoiceMode.switchStatusVioice = true;
|
||||
} else {
|
||||
console.warn('未找到对应的报警模式:', alarmMode);
|
||||
}
|
||||
} else {
|
||||
const closeMode = sta_VoiceType.value.find(mode => mode.id === '-1');
|
||||
if (closeMode) {
|
||||
closeMode.active = true;
|
||||
closeMode.switchStatusVioice = true;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取设备详情失败:', error);
|
||||
}
|
||||
};
|
||||
|
||||
// 灯光亮度
|
||||
const saveBtnlight = () => {
|
||||
lightModesLoading.value = true
|
||||
let data = {
|
||||
deviceId: route.params.deviceId,
|
||||
brightness: deviceDetail.value.lightBrightness,
|
||||
}
|
||||
api.lightModeSettings(data).then((res) => {
|
||||
if (res.code === 200) {
|
||||
lightModesLoading.value = false
|
||||
proxy?.$modal.msgSuccess(res.msg);
|
||||
|
||||
} else {
|
||||
lightModesLoading.value = false
|
||||
proxy?.$modal.msgError(res.msg);
|
||||
}
|
||||
|
||||
}).catch((error) => {
|
||||
lightModesLoading.value = false
|
||||
});
|
||||
}
|
||||
// 爆闪频率
|
||||
const saveBtnstrobe = () => {
|
||||
let data = {
|
||||
deviceId: route.params.deviceId,
|
||||
frequency: deviceDetail.value.strobeFrequency,
|
||||
}
|
||||
api.staticPowerSetting(data).then((res) => {
|
||||
if (res.code === 200) {
|
||||
proxy?.$modal.msgSuccess(res.msg);
|
||||
}
|
||||
})
|
||||
}
|
||||
// 修改音量
|
||||
const saveBtnVolume = () => {
|
||||
let data = {
|
||||
deviceId: route.params.deviceId,
|
||||
volume: deviceDetail.value.volume,
|
||||
}
|
||||
api.settingUpdateVolume(data).then((res) => {
|
||||
if (res.code === 200) {
|
||||
proxy?.$modal.msgSuccess(res.msg);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 解除报警
|
||||
const showClose = async () => {
|
||||
try {
|
||||
await proxy?.$modal.confirm('确定要对该设备解除报警?', '提示');
|
||||
// 2. 准备请求数据
|
||||
let data = {
|
||||
deviceIds: [route.params.deviceId],
|
||||
typeName: deviceDetail.value.typeName,
|
||||
deviceImeiList: [deviceDetail.value.deviceImei],
|
||||
instructValue: '0', //强制报警1,解除报警0
|
||||
}
|
||||
} catch (error: any) {
|
||||
}
|
||||
}
|
||||
|
||||
// 强制报警
|
||||
const forceAlarm = async () => {
|
||||
try {
|
||||
await proxy?.$modal.confirm('确定要对该设备开启强制报警?', '提示');
|
||||
forceAlarmLoading.value = true
|
||||
// 2. 准备请求数据
|
||||
let data = {
|
||||
deviceIds: [route.params.deviceId],
|
||||
typeName: deviceDetail.value.typeName,
|
||||
deviceImeiList: [deviceDetail.value.deviceImei],
|
||||
instructValue: '1', //强制报警1,解除报警0
|
||||
}
|
||||
|
||||
} catch (error: any) {
|
||||
// proxy?.$modal.msgWarning(error.msg)
|
||||
forceAlarmLoading.value = false;
|
||||
|
||||
} finally {
|
||||
forceAlarmLoading.value = false;
|
||||
}
|
||||
}
|
||||
const lookMap = (row: any) => {
|
||||
console.log(row, 'rowrowrowrowrworowrowrowrowrowrow');
|
||||
router.push({
|
||||
path: '/controlCenter/controlPanel',
|
||||
query: {
|
||||
view: 'map',
|
||||
deviceId: row.deviceId
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
onMounted(async () => {
|
||||
await getList();
|
||||
});
|
||||
onUnmounted(() => {
|
||||
});
|
||||
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.p-2 {
|
||||
background: rgba(247, 248, 252, 1);
|
||||
min-height: 100vh;
|
||||
box-sizing: border-box;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.device-page {
|
||||
.header-bar {
|
||||
border-radius: 8px;
|
||||
background: linear-gradient(135deg, #3400e7, #009bff);
|
||||
color: white;
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-weight: 600;
|
||||
|
||||
.device-status {
|
||||
.online {
|
||||
color: #00ff00;
|
||||
}
|
||||
|
||||
.offline {
|
||||
color: rgb(224, 52, 52);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content-wrapper {
|
||||
.content-row {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.content-card {
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 12px rgba(0, 34, 96, 0.1);
|
||||
background: white;
|
||||
padding: 0px 20px 50px;
|
||||
border: 1px solid #ebeef5;
|
||||
height: 289px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.content-card_gps {
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 12px rgba(0, 34, 96, 0.1);
|
||||
background: white;
|
||||
padding: 0px 20px 50px;
|
||||
border: 1px solid #ebeef5;
|
||||
height: 78%;
|
||||
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 20px;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.light-mode {
|
||||
display: flex;
|
||||
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.lacatin_gps {
|
||||
height: 70px;
|
||||
border-radius: 4px;
|
||||
background: rgba(247, 248, 252, 1);
|
||||
display: inline-block;
|
||||
width: 400px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.mode-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 15px;
|
||||
border: 1px solid #dcdfe6;
|
||||
border-radius: 8px;
|
||||
width: 107px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&.active {
|
||||
border-color: #409eff;
|
||||
background-color: rgba(64, 158, 255, 0.05);
|
||||
}
|
||||
|
||||
.mode-icon {
|
||||
width: 48px;
|
||||
margin-bottom: 10px;
|
||||
transition: all 0.3s ease;
|
||||
object-fit: scale-down;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.mode-name {
|
||||
font-size: 14px;
|
||||
margin-bottom: 12px;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.el-switch {
|
||||
--el-switch-on-color: #409eff;
|
||||
--el-switch-off-color: #dcdfe6;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
.brightness-alarm {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
|
||||
.brightness-control {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
border-radius: 39px;
|
||||
// box-shadow: 0px 0px 6px 0px rgba(0, 34, 96, 0.1);
|
||||
background: rgba(255, 255, 255, 1);
|
||||
width: 100%;
|
||||
// height: 54px;
|
||||
padding: 10px 20px;
|
||||
margin-top: 20px;
|
||||
|
||||
.brightness-label {
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
min-width: 70px;
|
||||
}
|
||||
|
||||
.brightness-value {
|
||||
font-size: 14px;
|
||||
color: #409eff;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.save-btn {
|
||||
padding: 6px 20px;
|
||||
border-radius: 29px;
|
||||
background: rgba(2, 124, 251, 1);
|
||||
border: none
|
||||
}
|
||||
|
||||
.inputTFT {
|
||||
width: 130px;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.alarm-btn {
|
||||
background-color: rgba(224, 52, 52, 1);
|
||||
border-color: rgba(224, 52, 52, 1);
|
||||
padding: 8px 20px;
|
||||
border-radius: 27px;
|
||||
}
|
||||
}
|
||||
|
||||
.location-info {
|
||||
.location-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
|
||||
.location-icon {
|
||||
margin-right: 8px;
|
||||
font-weight: bold;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.view-btn {
|
||||
margin: 0 8px;
|
||||
padding: 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 15px;
|
||||
margin-bottom: 15px;
|
||||
text-align: right;
|
||||
|
||||
.form-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.form-label {
|
||||
min-width: 35px;
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.el-input {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.register-btn {
|
||||
grid-column: 1 / 3;
|
||||
justify-self: start;
|
||||
padding: 6px 20px;
|
||||
position: absolute;
|
||||
right: 19px;
|
||||
bottom: 30px;
|
||||
border-radius: 29px;
|
||||
background: rgba(2, 124, 251, 1);
|
||||
border: none
|
||||
}
|
||||
}
|
||||
|
||||
.message-content {
|
||||
// display: flex;
|
||||
// flex-direction: column;
|
||||
// gap: 10px;
|
||||
|
||||
.el-textarea {
|
||||
border: 1px solid rgba(29, 111, 255, 1);
|
||||
border-radius: 4px;
|
||||
background: rgba(247, 248, 252, 1);
|
||||
border-radius: 6px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.el-textarea__inner {
|
||||
background: rgba(247, 248, 252, 1);
|
||||
}
|
||||
|
||||
.send-btn {
|
||||
align-self: flex-end;
|
||||
padding: 10px 20px;
|
||||
border-radius: 29px;
|
||||
background: rgba(2, 124, 251, 1);
|
||||
border: none;
|
||||
margin: 20px 0px 30px 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.upload-area {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100px;
|
||||
border: 1px dashed #dcdfe6;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.video-input {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
|
||||
.el-input {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.save-video-btn {
|
||||
padding: 6px 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 响应式调整
|
||||
@media (max-width: 768px) {
|
||||
.header-bar {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.form-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.form-grid .register-btn {
|
||||
grid-column: 1;
|
||||
}
|
||||
|
||||
.light-mode .mode-group {
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.light-mode .mode-item {
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.light-mode .mode-icon {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.path-img {
|
||||
width: 52px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.staticRwo {
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 12px rgba(0, 34, 96, 0.1);
|
||||
background: white;
|
||||
border: 1px solid #ebeef5;
|
||||
height: auto;
|
||||
line-height: 36px;
|
||||
box-sizing: border-box;
|
||||
text-indent: 15px;
|
||||
color: #ff0000;
|
||||
font-weight: bold;
|
||||
font-size: 17px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.displayNone {
|
||||
display: none !important;
|
||||
}
|
||||
</style>
|
||||
@ -6,3 +6,4 @@ export default () => {
|
||||
autoInstall: true
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user