Compare commits

...

6 Commits

12 changed files with 149 additions and 379 deletions

View File

@ -6,8 +6,8 @@ VITE_APP_ENV = 'development'
# 开发环境 # 开发环境
#VITE_APP_BASE_API = 'https://fuyuanshen.com/backend' #VITE_APP_BASE_API = 'https://fuyuanshen.com/backend'
VITE_APP_BASE_API = 'https://www.cnxhyc.com/jq' VITE_APP_BASE_API = 'https://www.cnxhyc.com/jq'
#VITE_APP_BASE_API = 'http://192.168.2.34:8000' #VITE_APP_BASE_API = 'http://192.168.2.23:8000'
#代永飞接口 #代永飞接口
# VITE_APP_BASE_API = 'http://457102h2d6.qicp.vip:24689' # VITE_APP_BASE_API = 'http://457102h2d6.qicp.vip:24689'

View File

@ -1,174 +0,0 @@
<style scoped>
.dashboard-container {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
position: relative;
overflow: hidden;
background: radial-gradient( 0% 0% at 0% 0%, #091B2D 0%, #0C2644 100%), #267AD0;
}
/* 全屏地图 - 背景图层 */
.fullscreen-map {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
pointer-events: none;
}
/* 顶部栏 */
.top-bar {
position: relative;
z-index: 10;
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 20px;
background-color: rgba(74, 85, 104, 0.9);
color: #fff;
font-size: 14px;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.top-bar h1 {
font-size: 18px;
margin: 0;
font-weight: 600;
}
.header-info {
display: flex;
gap: 16px;
align-items: center;
}
.header-info span {
font-size: 12px;
}
/* 悬浮模块容器 */
.floating-modules {
display: flex;
flex-direction: column;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: calc(100% - 60px); /* 减去顶部栏高度 */
z-index: 5;
padding: 20px;
box-sizing: border-box;
pointer-events: none;
}
.left-modules,
.right-modules {
display: flex;
flex-direction: column;
gap: 16px;
width: 100%;
flex: 1;
pointer-events: auto;
}
.bottom-middle-module {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
max-width: 800px;
pointer-events: auto;
}
.module-card {
background-color: rgba(107, 114, 128, 0.9);
border-radius: 6px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
border: 1px solid rgba(255, 255, 255, 0.1);
width: 100%;
box-sizing: border-box;
overflow: hidden;
}
.module-card:hover {
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.3);
}
.module-header {
padding: 10px 14px;
font-size: 14px;
font-weight: 600;
color: #fff;
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
display: flex;
align-items: center;
background: linear-gradient(90deg, #3b82f6, #60a5fa);
}
.module-header::before {
content: '';
display: inline-block;
width: 8px;
height: 16px;
margin-right: 8px;
border-radius: 2px;
background-color: inherit;
}
.module-content {
padding: 14px;
color: #e5e7eb;
font-size: 13px;
height: calc(100% - 36px);
box-sizing: border-box;
overflow: auto;
}
.overview-card .module-header::before { background-color: #3b82f6; }
.alarm-card .module-header::before { background-color: #ef4444; }
.realtime-card .module-header::before { background-color: #f97316; }
.module-card:nth-child(2) .module-header::before { background-color: #8b5cf6; }
.module-card:nth-child(3) .module-header::before { background-color: #06b6d4; }
@media (max-width: 1400px) {
.left-modules,
.right-modules {
width: 100%;
}
}
@media (max-width: 1200px) {
.left-modules,
.right-modules {
width: 100%;
}
.bottom-middle-module {
max-width: 600px;
}
}
@media (max-width: 900px) {
.left-modules,
.right-modules {
width: 100%;
}
.bottom-middle-module {
max-width: 500px;
}
}
@media (max-width: 768px) {
.left-modules,
.right-modules {
width: 100%;
}
.bottom-middle-module {
max-width: 100%;
}
}
</style>

View File

@ -592,17 +592,15 @@ const getMainLightModeLabel = (mode: any) => {
// 处理设备消息 // 处理设备消息
const handleDeviceMessage = (msg: any) => { const handleDeviceMessage = (msg: any) => {
try { try {
// 解析设备消息(假设格式为 { state: [类型, 模式值, 亮度, 续航...] }
const payloadObj = JSON.parse(msg.payload.toString()); const payloadObj = JSON.parse(msg.payload.toString());
const deviceState = payloadObj.state; // 设备状态数组 const deviceState = payloadObj.state; // 设备状态数组
if (!Array.isArray(deviceState)) { if (!Array.isArray(deviceState)) {
return; return;
} }
// 用switch处理不同的消息类型deviceState[0]
switch (deviceState[0]) { switch (deviceState[0]) {
case 1: case 1:
// 类型1灯光主键 // 类型1灯光主键
const lightModeId = getMainLightModeLabel(deviceState[1]); // 获取模式ID如'strong' const lightModeId = getMainLightModeLabel(deviceState[1]);
const brightness = deviceState[2]; // 亮度值 const brightness = deviceState[2]; // 亮度值
const batteryTime = deviceState[3]; // 续航时间 const batteryTime = deviceState[3]; // 续航时间
console.log('灯光模式消息:', { 模式ID: lightModeId, 亮度: brightness, 续航: batteryTime }); console.log('灯光模式消息:', { 模式ID: lightModeId, 亮度: brightness, 续航: batteryTime });
@ -625,7 +623,7 @@ const handleDeviceMessage = (msg: any) => {
break; break;
case 12: case 12:
// 灯光主键 // 灯光主键
const lightModeIdA = getMainLightModeLabel(deviceState[1]); // 获取模式ID如'strong' const lightModeIdA = getMainLightModeLabel(deviceState[1]);
if (lightModeIdA !== 'unknown') { if (lightModeIdA !== 'unknown') {
lightModes.value.forEach(mode => { lightModes.value.forEach(mode => {
const isActive = mode.id === lightModeIdA; const isActive = mode.id === lightModeIdA;
@ -650,7 +648,6 @@ const handleDeviceMessage = (msg: any) => {
break; break;
default: default:
// 其他类型消息(不处理,仅打印)
console.log('未处理的消息类型:', deviceState[0]); console.log('未处理的消息类型:', deviceState[0]);
break; break;
} }
@ -658,7 +655,7 @@ const handleDeviceMessage = (msg: any) => {
} }
}; };
onMounted(async () => { onMounted(async () => {
await getList(); // 先获取设备信息 await getList();
// 连接mqtt // 连接mqtt
onConnect(async () => { onConnect(async () => {
const deviceImei = deviceDetail.value.deviceImei; const deviceImei = deviceDetail.value.deviceImei;
@ -684,7 +681,7 @@ onMounted(async () => {
handleDeviceMessage(msg); handleDeviceMessage(msg);
}); });
onError((err) => { onError((err) => {
console.error('MQTT连接失败原因:', err.message); // 关键:打印连接失败的具体原因 console.error('MQTT连接失败原因:', err.message);
}); });
connect(); connect();
}); });

View File

@ -2,7 +2,7 @@
<div class="device-page p-2"> <div class="device-page p-2">
<!-- 头部信息栏 --> <!-- 头部信息栏 -->
<div class="header-bar"> <div class="header-bar">
<div>设备名称{{ deviceDetail.deviceName }}IMEI:{{deviceDetail.deviceImei }}</div> <div>设备名称{{ deviceDetail.deviceName }}IMEI:{{ deviceDetail.deviceImei }}</div>
<div>设备型号{{ deviceDetail.typeName }}</div> <div>设备型号{{ deviceDetail.typeName }}</div>
<div class="device-status"> <div class="device-status">
设备状态 设备状态
@ -19,8 +19,8 @@
<el-row :gutter="20" class="content-row" :class="deviceDetail.sta_ShakeBit == 1 || deviceDetail.staSOSGrade == 1 ? '' : 'displayNone'"> <el-row :gutter="20" class="content-row" :class="deviceDetail.sta_ShakeBit == 1 || deviceDetail.staSOSGrade == 1 ? '' : 'displayNone'">
<el-col :lg="24" :xs="24"> <el-col :lg="24" :xs="24">
<div class="staticRwo" :class="deviceDetail.sta_ShakeBit == 1 ? '' : 'displayNone'">设备静止报警中!</div> <div class="staticRwo" :class="deviceDetail.sta_ShakeBit == 1 ? '' : 'displayNone'">设备静止报警中!</div>
<div class="staticRwo" :class="(deviceDetail.staSOSGrade == 1 && Status.timeOut>0) ? '' : 'displayNone'" @click="showClose()"> <div class="staticRwo" :class="deviceDetail.staSOSGrade == 1 && Status.timeOut > 0 ? '' : 'displayNone'" @click="showClose()">
设备强制报警中<span v-show="Status.timeOut>0">,{{ Status.timeOut }}S</span>! 设备强制报警中<span v-show="Status.timeOut > 0">,{{ Status.timeOut }}S</span>!
</div> </div>
</el-col> </el-col>
</el-row> </el-row>
@ -209,7 +209,6 @@ import strongLightActive from '@/assets/images/strong-light_HL.png';
import floodLightDefault from '@/assets/images/flood-light.png'; import floodLightDefault from '@/assets/images/flood-light.png';
import floodLightActive from '@/assets/images/flood-light_HL.png'; import floodLightActive from '@/assets/images/flood-light_HL.png';
import di from '@/assets/images/di.png'; import di from '@/assets/images/di.png';
import diAc from '@/assets/images/diAc.png'; import diAc from '@/assets/images/diAc.png';
import high from '@/assets/images/high.png'; import high from '@/assets/images/high.png';
@ -314,7 +313,7 @@ const staticModes = ref<any[]>([
id: '2', id: '2',
name: '中档', name: '中档',
icon: zhong, // 直接使用导入的变量 icon: zhong, // 直接使用导入的变量
activeIcon:zhongAc, activeIcon: zhongAc,
active: false active: false
}, },
@ -394,7 +393,7 @@ const handleModeClick = async (id: string, type: string) => {
let dic = { promise: null, callback: null, key: '' }; let dic = { promise: null, callback: null, key: '' };
//测试环境假装成功 //测试环境假装成功
dic.promise = Promise.resolve({ code: 200, msg: '操作成功' }); dic.promise = Promise.resolve({ code: 200, msg: '操作成功' });
let arr = []; let arr = [];
@ -427,39 +426,35 @@ const handleModeClick = async (id: string, type: string) => {
dic.callback(); dic.callback();
} }
if (callback) { if (callback) {
callback(); callback();
} }
} else { } else {
proxy?.$modal.msgError(res.msg); proxy?.$modal.msgError(res.msg);
} }
}); });
}; };
if(type == 'sosMode' && Status.sosMode=== '1' && id==='0' && timer){ if (type == 'sosMode' && Status.sosMode === '1' && id === '0' && timer) {
showClose(); showClose();
return; return;
} } else if (type == 'sosMode' && id === '1' && timer == null) {
else if (type == 'sosMode' && id === '1' && timer==null) {
ShowConfirm({ ShowConfirm({
title: '提示', title: '提示',
text: '您确认开启180秒强制报警', text: '您确认开启180秒强制报警',
cancelCallback: ()=>{ cancelCallback: () => {
timer=null; timer = null;
}, },
OkCallback: () => { OkCallback: () => {
sendCmd(function () { sendCmd(function () {
Status.confirm.Visible = false; Status.confirm.Visible = false;
deviceDetail.value.staSOSGrade="1"; deviceDetail.value.staSOSGrade = '1';
Status.timeOut = 180; Status.timeOut = 180;
timer = setInterval(() => { timer = setInterval(() => {
if (Status.timeOut === 0) { if (Status.timeOut === 0) {
clearInterval(timer); clearInterval(timer);
timer = null; timer = null;
hideConfirm(); hideConfirm();
handleModeClick('1','sosMode'); handleModeClick('1', 'sosMode');
deviceDetail.value.staSOSGrade="0"; deviceDetail.value.staSOSGrade = '0';
return; return;
} }
@ -478,26 +473,32 @@ const handleModeClick = async (id: string, type: string) => {
}; };
const getList = () => { const getList = () => {
api.deviceRealTimeStatus(route.params.deviceId).then((res) => { return new Promise((resolve, reject) => {
if (res && res.code == 200) { api
let keys = Object.keys(res.data); .deviceRealTimeStatus(route.params.deviceId)
keys.forEach((key) => { .then((res) => {
deviceDetail.value[key] = res.data[key]; if (res && res.code == 200) {
});
Status.sosMode = res.data.staSOSGrade; let keys = Object.keys(res.data);
Status.staticPower = res.data.staDetectGrade; keys.forEach((key) => {
Status.lightMode = res.data.staLightGrade; deviceDetail.value[key] = res.data[key];
if(!deviceDetail.value.personnelInfo){ });
deviceDetail.value.personnelInfo={ Status.sosMode = res.data.staSOSGrade;
'id': null, Status.staticPower = res.data.staDetectGrade;
'deviceId': null, Status.lightMode = res.data.staLightGrade;
'name': null, if (!deviceDetail.value.personnelInfo) {
'position': null, deviceDetail.value.personnelInfo = {
'unitName': null, 'id': null,
'code': null 'deviceId': null,
'name': null,
'position': null,
'unitName': null,
'code': null
};
}
} }
} })
} .finally(resolve);
}); });
}; };
@ -563,8 +564,6 @@ const sendTextMessage = async () => {
batchId: '' batchId: ''
}; };
api.SendMessage(json).then((res) => { api.SendMessage(json).then((res) => {
if (res.code === 200) { if (res.code === 200) {
ElMessage.closeAll(); ElMessage.closeAll();
@ -588,52 +587,63 @@ const lookMap = (row: any) => {
function showClose() { function showClose() {
Status.confirm.Visible = true; Status.confirm.Visible = true;
Status.confirm.OkTxt = '关闭'; Status.confirm.OkTxt = '关闭';
Status.confirm.OkCallback=()=>{ Status.confirm.OkCallback = () => {
clearInterval(timer); clearInterval(timer);
timer=null; timer = null;
handleModeClick('0','sosMode'); handleModeClick('0', 'sosMode');
deviceDetail.value.staSOSGrade="0"; deviceDetail.value.staSOSGrade = '0';
Status.timeOut=0; Status.timeOut = 0;
hideConfirm(); hideConfirm();
} };
} }
// 处理设备消息 // 处理设备消息
const handleDeviceMessage = (payload: any) => { const handleDeviceMessage = (payload: any) => {
let json = JSON.parse(payload); let json = null;
try {
json = JSON.parse(payload);
} catch (ex) {
return;
}
let keys = Object.keys(json); let keys = Object.keys(json);
function parseDataMQ(json) { function parseDataMQ(json) {
deviceDetail.value.staDetectGrade = json.sta_DetectGrade; try {
deviceDetail.value.staLightGrade = json.sta_LightGrade; debugger;
deviceDetail.value.staDetectResult = json.sta_DetectResult; deviceDetail.value.staDetectGrade = json.sta_DetectGrade;
deviceDetail.value.staSOSGrade = json.sta_SOSGrade; deviceDetail.value.staLightGrade = json.sta_LightGrade;
deviceDetail.value.sta_ShakeBit = json.sta_ShakeBit; deviceDetail.value.staDetectResult = json.sta_DetectResult;
deviceDetail.value.staPowerTime = json.sta_PowerTime; deviceDetail.value.staSOSGrade = json.sta_SOSGrade;
deviceDetail.value.staPowerPercent = json.sta_PowerPercent; deviceDetail.value.sta_ShakeBit = json.sta_ShakeBit;
deviceDetail.value.longitude = json.sta_longitude; deviceDetail.value.staPowerTime = json.sta_PowerTime;
deviceDetail.value.latitude = json.sta_latitude; deviceDetail.value.staPowerPercent = json.sta_PowerPercent;
deviceDetail.value.onlineStatus = 1; deviceDetail.value.longitude = json.sta_longitude;
deviceDetail.value.latitude = json.sta_latitude;
deviceDetail.value.onlineStatus = 1;
Status.sosMode = json.sta_SOSGrade; Status.sosMode = json.sta_SOSGrade;
Status.staticPower = json.sta_DetectGrade; Status.staticPower = json.sta_DetectGrade;
Status.lightMode = json.sta_LightGrade; Status.lightMode = json.sta_LightGrade;
console.log('Status=', Status);
console.log('sosModes=', sosModes.value);
console.log('sta_SOSGrade=', json.sta_SOSGrade);
if (json.sta_PowerPercent < 20) {
centerDialogVisible.value = true;
}
if (json.sta_PowerPercent < 20) { if (json.sta_SOSGrade == 1 && json.sta_ShakeBit == 1) {
centerDialogVisible.value = true; confirm('设备SOS报警、静止预警中');
} return;
}
if (json.sta_SOSGrade == 1 && json.sta_ShakeBit == 1) { if (json.sta_SOSGrade == 1) {
confirm('设备SOS报警、静止预警中'); confirm('设备SOS报警中');
return; }
} if (json.sta_ShakeBit == 1) {
if (json.sta_SOSGrade == 1) { confirm('设备静止报警中');
confirm('设备SOS报警中'); }
} } catch (err) {}
if (json.sta_ShakeBit == 1) {
confirm('设备静止报警中');
}
} }
if (keys.indexOf('sta_DetectGrade') > -1) { if (keys.indexOf('sta_DetectGrade') > -1) {
@ -646,6 +656,7 @@ onMounted(async () => {
await getList(); // 先获取设备信息 await getList(); // 先获取设备信息
// 连接mqtt // 连接mqtt
onConnect(async () => { onConnect(async () => {
const deviceImei = deviceDetail.value.deviceImei; const deviceImei = deviceDetail.value.deviceImei;
if (!deviceImei) { if (!deviceImei) {
return; return;
@ -659,6 +670,7 @@ onMounted(async () => {
}); });
// 2. 注册消息接收回调(核心:处理设备发送的消息) // 2. 注册消息接收回调(核心:处理设备发送的消息)
onMessage((msg) => { onMessage((msg) => {
console.log('收到新消息:', { console.log('收到新消息:', {
主题: msg.topic, 主题: msg.topic,
内容: msg.payload, 内容: msg.payload,
@ -666,7 +678,7 @@ onMounted(async () => {
QoS: msg.qos QoS: msg.qos
}); });
// 在这里处理消息(根据实际业务逻辑) // 在这里处理消息(根据实际业务逻辑)
handleDeviceMessage(msg); handleDeviceMessage(msg.payload);
}); });
onError((err) => { onError((err) => {
console.error('MQTT连接失败原因:', err.message); // 关键:打印连接失败的具体原因 console.error('MQTT连接失败原因:', err.message); // 关键:打印连接失败的具体原因
@ -747,7 +759,7 @@ window.hideConfirm = function () {
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.p-2{ .p-2 {
background: rgba(247, 248, 252, 1); background: rgba(247, 248, 252, 1);
min-height: 100vh; min-height: 100vh;
box-sizing: border-box; box-sizing: border-box;

View File

@ -222,7 +222,7 @@ onUnmounted(() => {
} }
.amap-container { .amap-container {
height: calc(100vh - 22vh); height: calc(100vh - 25vh);
border-radius: 4px; border-radius: 4px;
overflow: hidden; overflow: hidden;
width: 100%; width: 100%;

View File

@ -82,7 +82,7 @@
</transition> </transition>
<el-card class="Maplist"> <el-card class="Maplist">
<div v-if="isListView" key="list"> <div v-if="isListView" key="list">
<el-table v-loading="loading" border :data="deviceList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" border :data="deviceList" @selection-change="handleSelectionChange" height="calc(100vh - 310px)">
<el-table-column type="selection" width="50" align="center" :selectable="isSelectable" /> <el-table-column type="selection" width="50" align="center" :selectable="isSelectable" />
<el-table-column label="设备名称" align="center" prop="deviceName" /> <el-table-column label="设备名称" align="center" prop="deviceName" />
<el-table-column label="设备图片" align="center" prop="devicePic"> <el-table-column label="设备图片" align="center" prop="devicePic">
@ -575,7 +575,7 @@ const forceAlarm = async () => {
} }
.Maplist { .Maplist {
height: calc(100vh - 24vh); //height: calc(100vh - 24vh);
overflow: auto; //overflow: auto;
} }
</style> </style>

View File

@ -58,7 +58,7 @@
</transition> </transition>
<el-card class="Maplist"> <el-card class="Maplist">
<div> <div>
<el-table v-loading="loading" border :data="deviceList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" border :data="deviceList" @selection-change="handleSelectionChange" height="calc(100vh - 400px)">
<el-table-column type="selection" width="50" align="center" /> <el-table-column type="selection" width="50" align="center" />
<el-table-column label="设备名称" align="center" prop="deviceName" /> <el-table-column label="设备名称" align="center" prop="deviceName" />
<el-table-column label="设备型号" align="center" prop="deviceType" /> <el-table-column label="设备型号" align="center" prop="deviceType" />
@ -299,7 +299,7 @@ height: calc(100vh - 8vh);
} }
.Maplist { .Maplist {
height: calc(100vh - 24vh); height: calc(100vh - 24vh);
overflow: auto; // overflow: auto;
} }
</style> </style>

View File

@ -58,7 +58,7 @@
</transition> </transition>
<el-card class="Maplist"> <el-card class="Maplist">
<div> <div>
<el-table v-loading="loading" border :data="deviceList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" border :data="deviceList" @selection-change="handleSelectionChange" height="calc(100vh - 400px)">
<el-table-column type="selection" width="50" align="center" /> <el-table-column type="selection" width="50" align="center" />
<el-table-column label="设备名称" align="center" prop="deviceName" /> <el-table-column label="设备名称" align="center" prop="deviceName" />
<el-table-column label="设备型号" align="center" prop="deviceType" /> <el-table-column label="设备型号" align="center" prop="deviceType" />
@ -308,6 +308,6 @@ height: calc(100vh - 8vh);
.Maplist { .Maplist {
height: calc(100vh - 24vh); height: calc(100vh - 24vh);
overflow: auto; // overflow: auto;
} }
</style> </style>

View File

@ -312,11 +312,11 @@
<span style="color: #409eff">批量导入完成共检测到 <span style="color: #e6a23c">{{ importResult.total }}</span> 条数据导入成功 <span style="color: #409eff">批量导入完成共检测到 <span style="color: #e6a23c">{{ importResult.total }}</span> 条数据导入成功
<span style="color: #67c23a">{{ importResult.succeed }}</span> 失败 <span style="color: #67c23a">{{ importResult.succeed }}</span> 失败
<span style="color: red">{{ importResult.errorSun }}</span> </span> <span style="color: red">{{ importResult.errorSun }}</span> </span>
<p v-if="importResult.errorSun > 0" style="padding: 10px">
<a :href="importResult.link">>>> 上传失败明细下载 <i class="el-icon-download" /></a>
</p>
</div> </div>
</el-upload> </el-upload>
<p v-if="importResult.errorSun > 0" style="padding: 10px">
<a :href="importResult.link">>>> 上传失败明细下载 <i class="el-icon-download" /></a>
</p>
<template #footer> <template #footer>
<div class="dialog-footer"> <div class="dialog-footer">
<el-button @click="importDialogVisible = false"> </el-button> <el-button @click="importDialogVisible = false"> </el-button>

View File

@ -10,7 +10,7 @@
</div> </div>
<div class="treeContent"> <div class="treeContent">
<el-tree :data="treeData" :props="defaultProps" accordion @node-click="handleNodeClick" :highlight-current="true"> <el-tree :default-expand-all="true" :data="treeData" :props="defaultProps" accordion @node-click="handleNodeClick" :highlight-current="true">
<template #default="{ node, data }"> <template #default="{ node, data }">
<div class="custom-tree-node"> <div class="custom-tree-node">
<span :class="data.parentId != null ? '' : 'treeBold'">{{ node.label }}</span> <span :class="data.parentId != null ? '' : 'treeBold'">{{ node.label }}</span>
@ -171,13 +171,18 @@
</el-dialog> </el-dialog>
<!-- 添加节点的弹出框 --> <!-- 添加节点的弹出框 -->
<el-dialog :width="350" :draggable="true" v-model="Status.dialogEditNode" :title="cEdit.id ? '修改分组' :(cEdit.pNode?'新增子节点': '新增根节点')" center> <el-dialog
:width="350"
:draggable="true"
v-model="Status.dialogEditNode"
:title="cEdit.id ? '修改分组' : cEdit.pNode ? '新增子节点' : '新增根节点'"
center
>
<div> <div>
<el-form class="demo-form-inline" :inline="true" :model="cEdit" label-width="auto" style="width: 100%"> <el-form class="demo-form-inline" :inline="true" :model="cEdit" label-width="auto" style="width: 100%">
<el-form-item label="分组名称"> <el-input v-model="cEdit.groupName" placeholder="请输入" /> </el-form-item <el-form-item label="分组名称"> <el-input v-model="cEdit.groupName" placeholder="请输入" /> </el-form-item>
> <div style="text-indent: 68px; color: #f56c6c; margin-top: -15px">{{ cEdit.groupName ? '' : '请输入分组名称' }}</div>
<div style="text-indent: 68px;color: #f56c6c;margin-top: -15px;">{{ cEdit.groupName?'':'请输入分组名称' }}</div> </el-form>
</el-form>
</div> </div>
<template #footer> <template #footer>
<div class="dialog-footer"> <div class="dialog-footer">
@ -337,18 +342,21 @@ var getDeviceList = () => {
deviceName: GjSearchForm.deviceName deviceName: GjSearchForm.deviceName
}; };
showloading(); showloading();
api return new Promise((resolve, reject) => {
.getNodeDevice(para) api
.then((res) => { .getNodeDevice(para)
deviceList.value = res.rows; .then((res) => {
pagin.total = res.total; deviceList.value = res.rows;
}) pagin.total = res.total;
.catch((ex) => { })
console.log('出现了异常', ex); .catch((ex) => {
}) console.log('出现了异常', ex);
.finally(() => { })
hideloading(); .finally(() => {
}); hideloading();
resolve();
});
});
}; };
//树控件节点点击事件 //树控件节点点击事件
var handleNodeClick = (node) => { var handleNodeClick = (node) => {
@ -363,6 +371,12 @@ var handleNodeClick = (node) => {
//树控件筛选后显示的数据源 //树控件筛选后显示的数据源
var treeData = computed(() => { var treeData = computed(() => {
let arr = api.treeNodeSearch(treeDataOrin.value, searchTxt.value, 'groupName', 'children'); let arr = api.treeNodeSearch(treeDataOrin.value, searchTxt.value, 'groupName', 'children');
if (arr.length && !checkNode.val) {
checkNode.val = arr[0].id;
getDeviceList().finally(() => {
checkNode.val = '';
});
}
return arr; return arr;
}); });
@ -379,7 +393,7 @@ var editNode = (node) => {
Status.isEditTreeNode = true; Status.isEditTreeNode = true;
cEdit.value.editNode = node; cEdit.value.editNode = node;
cEdit.value.pNode = null; cEdit.value.pNode = null;
Status.dialogEditNode=true; Status.dialogEditNode = true;
// //
}; };
@ -413,7 +427,7 @@ var completeEdit = (node) => {
if (res.code == 200) { if (res.code == 200) {
alert('操作成功'); alert('操作成功');
RefreshTree(); RefreshTree();
Status.dialogEditNode=false; Status.dialogEditNode = false;
} else { } else {
alert(res.msg); alert(res.msg);
} }
@ -477,7 +491,7 @@ var addNode = (node) => {
}; };
var saveNode = () => { var saveNode = () => {
if(!cEdit.value.groupName){ if (!cEdit.value.groupName) {
return; return;
} }
let val = new Date().getTime(); let val = new Date().getTime();
@ -917,8 +931,8 @@ onMounted(() => {
} }
.custom-tree-node .iconContent .icon { .custom-tree-node .iconContent .icon {
width: 18px; width: 15px;
height: 18px; height: 15px;
visibility: hidden; visibility: hidden;
} }

View File

@ -1,83 +1,6 @@
<template> <template>
<el-form :model="user" label-width="80px"> <div>敬请期待</div>
<div v-for="item in user">
<el-form-item :label="item.dictLabel" prop="dictLabel">
<el-input v-model="item.dictLabel" disabled />
</el-form-item>
<el-form-item label="版本号" prop="dictValue">
<el-input v-model="item.dictValue" placeholder="请输入版本号" clearable />
</el-form-item>
<el-form-item label="下载地址" prop="remark">
<el-input v-model="item.remark" placeholder="请输入wgt下载地址" clearable />
</el-form-item>
</div>
<el-form-item>
<el-button type="primary" @click="submit">保存</el-button>
</el-form-item>
</el-form>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import request from '@/utils/request';
const user = ref([
{
'dictValue': '',
'dictLabel': 'ios',
'remark': ''
},
{
'dictValue': '',
'dictLabel': 'android',
'remark': ''
}
]);
function getCfg() {
request({
url: '/app/auth/version',
method: 'get'
}).then((res) => {
if (res && res.code === 200) {
user.value.forEach((v) => {
let f = res.data.find((item) => {
return item.dictLabel === v.dictLabel;
});
if (f) {
v.dictValue = f.dictValue;
v.remark = f.remark;
}
});
}
});
}
function submit() {
let flag = [];
user.value.forEach((v) => {
let keys = Object.keys(v);
keys.forEach((k) => {
if (!v[k]) {
flag.push(false);
}
});
});
if (flag.length > 0) {
ElMessageBox.alert('所有项都是必填');
return;
}
request({
url: '/api/xinghan/device/UpVersion',
method: 'post',
data: user.value
}).then((res) => {
if (res && res.code === 200) {
ElMessageBox.alert('操作成功');
}
});
}
onMounted(() => {
getCfg();
});
</script> </script>

View File

@ -61,9 +61,7 @@
<el-tab-pane label="在线设备" name="onlineDevice"> <el-tab-pane label="在线设备" name="onlineDevice">
<onlineDevice :devices="state.devices" /> <onlineDevice :devices="state.devices" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="App版本" name="appVer">
<appVer />
</el-tab-pane>
</el-tabs> </el-tabs>
</el-card> </el-card>
</el-col> </el-col>