显卡产品物模型对接

This commit is contained in:
1 2025-07-20 17:26:09 +08:00
parent f39ff9c360
commit ec7e9ff6b9
8 changed files with 1683 additions and 1156 deletions

BIN
dist.zip

Binary file not shown.

View File

@ -195,8 +195,8 @@
ref="voicecard" :device="form" @statusEvent="getDeviceStatusData($event)" />
<display v-else-if="form.productName && form.productName.toLowerCase().includes('显卡产品')"
ref="display" :device="form" @statusEvent="getDeviceStatusData($event)" />
<gateway v-else-if="form.productName && form.productName.toLowerCase().includes('网关')"
ref="gateway" :device="form" @statusEvent="getDeviceStatusData($event)" />
<gateway v-else-if="form.productName && form.productName.toLowerCase().includes('网关')" ref="gateway"
:device="form" @statusEvent="getDeviceStatusData($event)" />
<running-status v-else ref="runningStatus" :device="form"
@statusEvent="getDeviceStatusData($event)" />
@ -293,10 +293,10 @@
<alert-user ref="alertUser" :device="form" />
</el-tab-pane>
<!-- <el-tab-pane name="inlineVideo" :disabled="form.deviceId == 0" v-if="form.deviceType !== 3" lazy>
<el-tab-pane name="inlineVideo" :disabled="form.deviceId == 0" v-if="form.deviceType !== 3" lazy>
<span slot="label">{{ $t('device.device-edit.148398-75') }}</span>
<device-inline-video ref="deviceInlineVideo" :sipRelationList="form.sipRelationVOList" />
</el-tab-pane> -->
</el-tab-pane>
<el-tab-pane name="deviceAlert" v-hasPermi="['iot:alertLog:list']" :disabled="form.deviceId == 0" lazy>
<span slot="label">{{ $t('device.device-edit.148398-81') }}</span>
@ -461,7 +461,7 @@ import defaultSettings from '@/settings';
import gatewayRunningStatus from './gatewayrunning-status.vue';
import relay from './relay.vue'
import gatewaypre from './gatewaypre.vue'
import acousto_optic from'./acousto_optic.vue'
import acousto_optic from './acousto_optic.vue'
import voicecard from './voicecard.vue';
import display from './display.vue'
import gateway from './gateway.vue'
@ -1382,8 +1382,8 @@ export default {
color: #fff;
background-color: #486ff2;
border-radius: 4px;
height: 32px;
line-height: 34px;
/* height: 32px; */
/* line-height: 34px; */
}
.alert-wrap {

File diff suppressed because it is too large Load Diff

View File

@ -1,31 +1,33 @@
<template>
<div class="gateway-setting">
<!-- 设备模式和OTA升级部分保留 -->
<!-- 设备模式和OTA升级部分 - 卡片美化 -->
<el-row :gutter="20" class="mode-section">
<!-- 设备模式 -->
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
<el-card class="mode-card" shadow="hover">
<el-card class="mode-card elegant-card" shadow="hover">
<div class="mode-header">
<div class="icon-wrapper bg-blue">
<i class="el-icon-menu"></i>
</div>
<span class="mode-title">设备模式</span>
</div>
<div class="mode-content">
<span class="title" :style="{ color: statusColor.background }">{{ title }}</span>
<el-button type="text" @click="printThingsModels" style="margin-left: 10px">
<span class="title gradient-text">{{ title }}</span>
<!-- <el-button type="text" class="print-btn" @click="printThingsModels">
<i class="el-icon-printer"></i> 打印物模型
</el-button>
</el-button> -->
</div>
</el-card>
</el-col>
<!-- 设备升级 -->
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
<el-card class="mode-card" shadow="hover">
<el-card class="mode-card elegant-card" shadow="hover">
<div class="mode-header">
<div class="icon-wrapper bg-purple">
<svg-icon icon-class="ota" />
</div>
<span class="mode-title">OTA升级</span>
</div>
<div class="mode-content">
<el-button type="primary" size="mini" :plain="true" @click="viewVersion()">
<el-button type="primary" size="mini" class="gradient-btn" @click="viewVersion()">
查看固件版本
</el-button>
</div>
@ -33,69 +35,171 @@
</el-col>
</el-row>
<!-- 模组概况与设备模式卡片风格统一 -->
<el-row :gutter="20" class="mode-section">
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
<el-card class="mode-card" shadow="hover">
<div class="mode-header">
<i class="el-icon-s-platform"></i>
<span class="mode-title">模组概况</span>
<!-- 模组概况+网关参数设置卡片 - 美化 -->
<el-card class="setting-card elegant-card" shadow="hover">
<div class="setting-header">
<div class="header-decoration"></div>
<span class="setting-title with-underline">模组概况 & 网关参数设置</span>
</div>
<div class="mode-content">
<el-descriptions :column="2" border size="medium" class="overview-desc">
<div class="module-overview">
<el-descriptions :column="2" border size="medium" class="overview-desc elegant-desc">
<el-descriptions-item label="固件版本">
<span class="desc-value">{{ moduleInfo.firmwareVersion }}</span>
<span class="desc-value highlight">{{ moduleInfo.firmwareVersion }}</span>
</el-descriptions-item>
<el-descriptions-item label="MAC地址">
<span class="desc-value">{{ moduleInfo.mac }}</span>
<span class="desc-value highlight">{{ moduleInfo.mac }}</span>
</el-descriptions-item>
</el-descriptions>
</div>
</el-card>
</el-col>
</el-row>
<!-- 网关参数设置表单 -->
<el-card class="setting-card" shadow="hover" style="margin-top: 24px;">
<div slot="header" class="setting-header">
<span class="setting-title">网关参数设置</span>
</div>
<el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
<el-form :model="form" :rules="rules" ref="formRef" label-width="120px" class="elegant-form">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="网络ID" prop="networkId">
<el-input v-model="form.networkId" placeholder="请输入网络ID" />
<el-input v-model="form.networkId" placeholder="请输入网络ID" class="rounded-input" />
</el-form-item>
<el-form-item label="无线频段" prop="band">
<el-select v-model="form.band" placeholder="请选择无线频段">
<el-select v-model="form.band" placeholder="请选择无线频段" class="rounded-select">
<el-option label="2.4GHz" value="2.4G" />
<el-option label="5GHz" value="5G" />
</el-select>
</el-form-item>
<el-form-item label="信道" prop="channel">
<el-select v-model="form.channel" placeholder="请选择信道">
<el-select v-model="form.channel" placeholder="请选择信道" class="rounded-select">
<el-option v-for="ch in channelOptions" :key="ch" :label="ch" :value="ch" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="速率" prop="rate">
<el-select v-model="form.rate" placeholder="请选择速率">
<el-select v-model="form.rate" placeholder="请选择速率" class="rounded-select">
<el-option v-for="rate in rateOptions" :key="rate" :label="rate" :value="rate" />
</el-select>
</el-form-item>
<el-form-item label="功率" prop="power">
<el-select v-model="form.power" placeholder="请选择功率">
<el-select v-model="form.power" placeholder="请选择功率" class="rounded-select">
<el-option v-for="p in powerOptions" :key="p" :label="p" :value="p" />
</el-select>
</el-form-item>
<el-form-item label="设备地址" prop="deviceAddr">
<el-input v-model="form.deviceAddr" placeholder="请输入设备地址" />
<el-input v-model="form.deviceAddr" placeholder="请输入设备地址" class="rounded-input" />
</el-form-item>
</el-col>
</el-row>
<el-form-item label="事件开关" prop="eventSwitch">
<el-switch v-model="form.eventSwitch" active-text="开启" inactive-text="关闭" />
<el-switch v-model="form.eventSwitch" active-text="开启" inactive-text="关闭" active-color="#13ce66"
inactive-color="#ff4949" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">保存设置</el-button>
<el-button style="text-align: center;" type="primary" class="save-btn"
@click="onSubmit">保存设置</el-button>
</el-form-item>
</el-form>
</el-card>
<!-- 雷达触发设置卡片 - 美化 -->
<el-card class="radar-card elegant-card" shadow="hover">
<div class="setting-header">
<div class="header-decoration"></div>
<span class="setting-title with-underline">雷达触发设置</span>
</div>
<el-form :model="radarForm" ref="radarFormRef" label-width="140px" class="radar-form elegant-form">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="行驶速度 (km/h)" class="slider-item">
<el-slider v-model="radarForm.lowSpeed" :min="0" :max="100" range :show-tooltip="true"
tooltip-class="custom-tooltip" />
<span class="slider-value highlight">{{ radarForm.lowSpeed[0] }} - {{ radarForm.lowSpeed[1]
}}</span>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="触发速度 (km/h)" class="slider-item">
<el-slider v-model="radarForm.triggerSpeed" :min="0" :max="200" range :show-tooltip="true"
tooltip-class="custom-tooltip" />
<span class="slider-value highlight">{{ radarForm.triggerSpeed[0] }} - {{
radarForm.triggerSpeed[1] }}</span>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="超速速度 (km/h)" class="slider-item">
<el-slider v-model="radarForm.overSpeed" :min="0" :max="200" range :show-tooltip="true"
tooltip-class="custom-tooltip" />
<span class="slider-value highlight">{{ radarForm.overSpeed[0] }} - {{
radarForm.overSpeed[1] }}</span>
</el-form-item>
</el-col>
</el-row>
<el-form-item>
<el-button type="primary" class="save-btn" @click="onRadarSubmit">保存雷达设置</el-button>
</el-form-item>
</el-form>
</el-card>
<!-- 时间列表卡片 - 美化 -->
<el-card class="time-list-card elegant-card" shadow="hover">
<div class="setting-header" style="display: flex; align-items: center; justify-content: space-between;">
<div style="display: flex; align-items: center;">
<div class="header-decoration"></div>
<span class="setting-title with-underline">事件列表</span>
</div>
<el-button type="primary" icon="el-icon-plus" class="add-btn"
@click="openEventDialog = true">添加事件</el-button>
</div>
<el-table :data="timeList" border style="width: 100%; margin-top: 16px;" class="elegant-table"
:header-cell-style="{ background: '#f5f7fa', color: '#606266' }">
<el-table-column type="index" label="序号" width="60" align="center" />
<!-- <el-table-column prop="time" label="时间" width="120" align="center" /> -->
<el-table-column prop="event" label="事件" align="center" />
<el-table-column prop="plan" label="方案内容" align="center" />
</el-table>
<!-- 添加事件弹窗 -->
<el-dialog title="添加事件" :visible.sync="openEventDialog" width="500px" append-to-body>
<el-form :model="eventForm" :rules="eventRules" ref="eventFormRef" label-width="110px">
<el-form-item label="事件类型" prop="type">
<el-select v-model="eventForm.type" placeholder="请选择事件类型">
<el-option v-for="item in eventTypeOptions" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="事件来源" prop="source">
<el-select v-model="eventForm.source" placeholder="请选择事件来源">
<el-option v-for="item in eventSourceOptions" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="优先级" prop="priority">
<el-input-number v-model="eventForm.priority" :min="1" :max="10" />
</el-form-item>
<el-form-item label="显示节目" prop="program">
<el-select v-model="eventForm.program" placeholder="请选择显示节目">
<el-option v-for="item in programOptions" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="显示时长(秒)" prop="duration">
<el-input-number v-model="eventForm.duration" :min="1" :max="9999" />
</el-form-item>
<el-form-item label="输出引脚" prop="pin">
<el-select v-model="eventForm.pin" placeholder="请选择输出引脚">
<el-option v-for="item in pinOptions" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="输出电平" prop="level">
<el-select v-model="eventForm.level" placeholder="请选择输出电平">
<el-option label="高" value="高" />
<el-option label="低" value="低" />
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="openEventDialog = false"> </el-button>
<el-button type="primary" @click="handleAddEvent"> </el-button>
</div>
</el-dialog>
</el-card>
</div>
</template>
@ -128,6 +232,15 @@ export default {
power: [{ required: true, message: '请选择功率', trigger: 'change' }],
deviceAddr: [{ required: true, message: '请输入设备地址', trigger: 'blur' }],
},
//
radarForm: {
lowSpeed: [10, 30],
triggerSpeed: [40, 80],
overSpeed: [100, 150],
},
timeList: [
],
// OTA
title: '设备控制',
statusColor: {
@ -135,6 +248,73 @@ export default {
color: '#fff',
maxWidth: '200px',
},
openEventDialog: false,
eventForm: {
type: '',
source: '',
priority: 1,
program: '',
duration: 10,
pin: '',
level: '',
},
eventRules: {
type: [{ required: true, message: '请选择事件类型', trigger: 'change' }],
source: [{ required: true, message: '请输入事件来源', trigger: 'blur' }],
priority: [{ required: true, message: '请输入优先级', trigger: 'change' }],
program: [{ required: true, message: '请输入显示节目', trigger: 'blur' }],
duration: [{ required: true, message: '请输入显示时长', trigger: 'change' }],
pin: [{ required: true, message: '请输入输出引脚', trigger: 'blur' }],
level: [{ required: true, message: '请选择输出电平', trigger: 'change' }],
},
//
eventTypeOptions: [
{ label: '默认显示', value: '0' },
{ label: '雷达触发(RS485 雷达)', value: '1' },
{ label: '雷达超速(RS485 雷达)', value: '2' },
{ label: '车牌触发(摄像头)', value: '3' },
{ label: '车牌超速(摄像头)', value: '4' },
{ label: '行人检测(相机)', value: '5' },
{ label: 'IN1下降沿', value: '0x51' },
{ label: 'IN2上升沿', value: '0x52' },
{ label: 'IN3下降沿', value: '0x53' },
{ label: 'IN4上升沿', value: '0x54' },
{ label: 'IN1低电平', value: '0x55' },
{ label: 'IN2高电平', value: '0x56' },
{ label: 'IN3低电平', value: '0x57' },
{ label: 'IN4高电平', value: '0x58' },
{ label: '其他', value: '-1' },
],
eventSourceOptions: [
{ label: '本台设备', value: '0' },
{ label: '任意设备(不包含本设备)', value: '254' },
{ label: '任意设备', value: '255' },
{ label: '其他', value: '1' },
],
programOptions: [
{ label: '节目一', value: 'program1' },
{ label: '节目二', value: 'program2' },
{ label: '节目三', value: 'program3' },
{ label: '节目四', value: 'program4' },
{ label: '节目五', value: 'program5' },
{ label: '节目六', value: 'program6' },
{ label: '节目七', value: 'program7' },
{ label: '节目八', value: 'program8' },
],
pinOptions: [
{ label: '引脚1', value: 'pin1' },
{ label: '引脚2', value: 'pin2' },
{ label: '引脚3', value: 'pin3' },
{ label: '引脚4', value: 'pin4' },
{ label: '引脚5', value: 'pin5' },
{ label: '引脚6', value: 'pin6' },
{ label: '引脚7', value: 'pin7' },
{ label: '引脚8', value: 'pin8' },
{ label: '引脚9', value: 'pin9' },
],
};
},
methods: {
@ -152,6 +332,26 @@ export default {
viewVersion() {
this.$message.info('查看固件版本功能保留');
},
onRadarSubmit() {
this.$message.success('雷达设置已保存');
// TODO:
},
handleAddEvent() {
this.$refs.eventFormRef.validate((valid) => {
if (valid) {
// label
const typeLabel = (this.eventTypeOptions.find(item => item.value === this.eventForm.type) || {}).label || this.eventForm.type;
const sourceLabel = (this.eventSourceOptions.find(item => item.value === this.eventForm.source) || {}).label || this.eventForm.source;
this.timeList.push({
// time: new Date().toLocaleTimeString().slice(0, 5),
event: `${typeLabel} / ${sourceLabel}`,
plan: `优先级:${this.eventForm.priority} 节目:${this.programOptions.find(item => item.value === this.eventForm.program)?.label || this.eventForm.program} 时长:${this.eventForm.duration}s 引脚:${this.pinOptions.find(item => item.value === this.eventForm.pin)?.label || this.eventForm.pin} 电平:${this.eventForm.level}`
});
this.openEventDialog = false;
this.$refs.eventFormRef.resetFields();
}
});
},
},
};
</script>
@ -159,18 +359,80 @@ export default {
<style lang="scss" scoped>
.gateway-setting {
padding: 20px;
background-color: #f5f7fa;
.mode-section {
margin-bottom: 30px;
}
.mode-card {
margin-bottom: 20px;
transition: all 0.3s;
padding: 20px;
/* 优雅卡片样式 */
.elegant-card {
padding: 10px;
margin-top: 20px;
border-radius: 12px;
border: none;
transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
background: white;
&:hover {
transform: translateY(-5px);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
transform: translateY(-2px);
}
}
/* 卡片头部样式 */
.setting-header {
position: relative;
margin-bottom: 20px;
.header-decoration {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 4px;
background: linear-gradient(to bottom, #409EFF, #67C23A);
border-radius: 2px;
}
.setting-title {
font-size: 18px;
font-weight: bold;
color: #303133;
margin-left: 12px;
&.with-underline {
position: relative;
display: inline-block;
&::after {
content: '';
position: absolute;
left: 0;
bottom: -5px;
width: 100%;
height: 2px;
background: linear-gradient(to right, #409EFF, transparent);
}
}
}
}
/* 设备模式卡片 */
.mode-card {
height: 100%;
padding: 20px;
position: relative;
overflow: hidden;
&::before {
content: '';
position: absolute;
top: 0;
right: 0;
width: 100px;
height: 100px;
background: radial-gradient(circle, rgba(64, 158, 255, 0.1) 0%, rgba(64, 158, 255, 0) 70%);
}
.mode-header {
@ -178,11 +440,30 @@ export default {
align-items: center;
margin-bottom: 15px;
.icon-wrapper {
width: 36px;
height: 36px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-right: 12px;
i,
.svg-icon {
font-size: 20px;
margin-right: 8px;
color: #409EFF;
font-size: 18px;
color: white;
}
&.bg-blue {
background: linear-gradient(135deg, #409EFF, #64b5ff);
box-shadow: 0 4px 8px rgba(64, 158, 255, 0.3);
}
&.bg-purple {
background: linear-gradient(135deg, #a162e8, #c893ff);
box-shadow: 0 4px 8px rgba(161, 98, 232, 0.3);
}
}
.mode-title {
@ -199,13 +480,103 @@ export default {
.title {
font-size: 16px;
font-weight: bold;
&.gradient-text {
background: linear-gradient(to right, #409EFF, #67C23A);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
.overview-desc {
margin: 0 auto;
display: inline-block;
.print-btn {
color: #409EFF;
transition: all 0.3s;
&:hover {
color: #67C23A;
transform: translateY(-2px);
}
}
.gradient-btn {
background: linear-gradient(to right, #409EFF, #64b5ff);
border: none;
color: white;
transition: all 0.3s;
&:hover {
background: linear-gradient(to right, #64b5ff, #409EFF);
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(64, 158, 255, 0.3);
}
}
}
}
/* 表单样式 */
.elegant-form {
margin-top: 20px;
.el-form-item {
margin-bottom: 22px;
&:last-child {
margin-bottom: 0;
}
}
.rounded-input {
.el-input__inner {
border-radius: 20px;
padding-left: 15px;
}
}
.rounded-select {
.el-input__inner {
border-radius: 20px;
}
}
.slider-item {
.el-slider {
.el-slider__runway {
height: 6px;
border-radius: 3px;
}
.el-slider__bar {
height: 6px;
background: linear-gradient(to right, #409EFF, #64b5ff);
}
.el-slider__button {
width: 16px;
height: 16px;
border: 2px solid #409EFF;
}
}
}
.save-btn {
background: linear-gradient(to right, #409EFF, #64b5ff);
border: none;
border-radius: 20px;
padding: 10px 24px;
transition: all 0.3s;
&:hover {
background: linear-gradient(to right, #64b5ff, #409EFF);
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(64, 158, 255, 0.3);
}
}
}
/* 描述列表样式 */
.elegant-desc {
.el-descriptions__label {
background-color: #f5f7fa;
font-weight: bold;
color: #606266;
}
@ -214,23 +585,72 @@ export default {
font-size: 16px;
color: #222;
font-weight: 500;
}
}
}
}
.setting-card {
.setting-header {
.setting-title {
font-size: 16px;
&.highlight {
color: #409EFF;
font-weight: bold;
color: #303133;
}
}
}
.el-form {
margin-top: 20px;
max-width: 500px;
/* 表格样式 */
.elegant-table {
.el-table__header {
th {
background-color: #f5f7fa !important;
}
}
.el-table__body {
tr:hover {
td {
background-color: #f0f7ff !important;
}
}
}
}
/* 高亮文本 */
.highlight {
color: #409EFF;
font-weight: bold;
}
/* 滑块值显示 */
.slider-value {
display: inline-block;
min-width: 80px;
margin-left: 10px;
color: #409EFF;
font-weight: bold;
}
.add-btn {
background: linear-gradient(to right, #409EFF, #67C23A);
border: none;
color: #fff;
border-radius: 20px;
padding: 8px 22px;
font-weight: bold;
box-shadow: 0 2px 8px rgba(64, 158, 255, 0.10);
transition: all 0.3s;
margin-right: 10px;
&:hover {
background: linear-gradient(to right, #67C23A, #409EFF);
color: #fff;
transform: translateY(-2px);
}
}
}
/* 全局滑块提示样式 */
.custom-tooltip {
.el-slider__button {
.el-tooltip__popper {
background: #409EFF !important;
color: white !important;
border: none !important;
}
}
}

View File

@ -13,9 +13,9 @@
</div>
<div class="status-content">
<span class="title" :style="{ color: statusColor.background }">{{ title }}</span>
<el-button type="text" @click="printThingsModels" style="margin-left: 10px" class="print-btn">
<!-- <el-button type="text" @click="printThingsModels" style="margin-left: 10px" class="print-btn">
<i class="el-icon-printer"></i> 打印物模型
</el-button>
</el-button> -->
</div>
<!-- <div class="status-details">
<div class="detail-item">
@ -61,9 +61,7 @@
</el-card>
</el-col>
</el-row>
<!-- 子设备标题 -->
<el-row :gutter="20" style="margin-bottom: 20px;">
<el-row :gutter="20" style="margin-bottom: 10px; margin-top: 20px;">
<el-col :span="24">
<div class="sub-devices-title">
<i class="el-icon-connection"></i>
@ -72,10 +70,13 @@
</el-col>
</el-row>
<!-- 子产品Tab标签页 -->
<el-card class="sub-products-card" shadow="hover">
<!-- 子设备标题 -->
<el-tabs v-model="activeTab" type="card" @tab-click="handleTabClick">
<el-tab-pane label="显示屏控制" name="display">
<el-tab-pane label="显示屏控制" name="display" style="line-height: 42px; height: 42px;">
<div class="tab-content">
<display-component :device="device" ref="displayComponent" v-if="activeTab === 'display'">
</display-component>
@ -520,6 +521,7 @@ export default {
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
backdrop-filter: blur(10px);
background: rgba(255, 255, 255, 0.9);
padding: 24px 32px; //
&:hover {
transform: translateY(-8px) scale(1.02);
@ -737,14 +739,15 @@ export default {
font-size: 16px;
font-weight: 500;
padding: 0 35px;
// height: 50px;
// line-height: 50px;
position: relative;
z-index: 1;
height: 42px;
line-height: 42px;
border: 1px solid #e4e7ed;
border-bottom: none;
background: #f5f7fa;
color: #606266;
transition: all 0.3s ease;
position: relative;
&:hover {
color: #409EFF;
@ -761,6 +764,9 @@ export default {
.el-tabs__active-bar {
background: #409EFF;
height: 2px;
left: 0 !important;
width: 100% !important; //
border-radius: 2px;
}
}
@ -822,11 +828,11 @@ export default {
::v-deep .el-tabs__header {
padding: 0 10px;
.el-tabs__item {
::v-deep .el-tabs__item {
padding: 0 20px;
font-size: 14px;
height: 50px;
// line-height: 50px;
height: 42px;
line-height: 42px;
}
}

View File

@ -251,7 +251,7 @@
import deviceList from './device-list';
import { listGroup, getGroup, delGroup, addGroup, updateGroup } from '@/api/iot/group';
import { getUserId } from '@/utils/auth';
import { listDevice } from '@/api/iot/device';
import { listDeviceShort } from '@/api/iot/device';
import { getDeviceRunningStatus } from '@/api/iot/device';
import { serviceInvoke } from '@/api/iot/runstatus';
import { listThingsModel } from '@/api/iot/device';
@ -508,8 +508,9 @@ export default {
pageNum: 1,
pageSize: 1 //
};
const response = await listDevice(params);
console.log("params", JSON.stringify(params));
const response = await listDeviceShort(params);
console.log("zjj", JSON.stringify(response));
if (response.rows && response.rows.length > 0) {
const device = response.rows[0];
// 使getDeviceRunningStatus
@ -581,7 +582,7 @@ export default {
pageSize: 1000
};
const response = await listDevice(params);
const response = await listDeviceShort(params);
if (response.rows && response.rows.length > 0) {
for (const device of response.rows) {
const data = {
@ -614,7 +615,7 @@ export default {
pageSize: 1000
};
const response = await listDevice(params);
const response = await listDeviceShort(params);
if (response.rows && response.rows.length > 0) {
for (const device of response.rows) {
const data = {

View File

@ -9,17 +9,20 @@
<span class="info-item">{{ $t('product.product-edit.473153-1') }}{{ form.productName }}</span>
<span class="info-item">
{{ $t('product.product-edit.473153-85') }}
<el-button :disabled="form.isOwner === 0" v-if="form.status == 1" @click="changeProductStatus(1)" type="primary" size="small" plain style="height: 24px; padding: 0 10px">
<el-button :disabled="form.isOwner === 0" v-if="form.status == 1" @click="changeProductStatus(1)"
type="primary" size="small" plain style="height: 24px; padding: 0 10px">
{{ $t('product.product-edit.473153-86') }}
</el-button>
<el-button :disabled="form.isOwner === 0" v-if="form.status == 2" @click="changeProductStatus(2)" type="danger" size="small" plain style="height: 24px; padding: 0 10px">
<el-button :disabled="form.isOwner === 0" v-if="form.status == 2" @click="changeProductStatus(2)"
type="danger" size="small" plain style="height: 24px; padding: 0 10px">
{{ $t('product.product-edit.473153-87') }}
</el-button>
</span>
</div>
</el-card>
<el-card style="padding-bottom: 100px">
<el-tabs class="custom-tabs" v-model="activeName" tab-position="top" style="min-height: 400px" @tab-click="tabChange">
<el-tabs class="custom-tabs" v-model="activeName" tab-position="top" style="min-height: 400px"
@tab-click="tabChange">
<el-tab-pane name="basic">
<span slot="label">
{{ $t('product.product-edit.473153-0') }}
@ -28,48 +31,53 @@
<el-row :gutter="100">
<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="8">
<el-form-item :label="$t('product.product-edit.473153-1')" prop="productName">
<el-input v-model="form.productName" :placeholder="$t('product.product-edit.473153-2')" :readonly="form.status == 2 || form.isOwner == 0" />
<el-input v-model="form.productName"
:placeholder="$t('product.product-edit.473153-2')"
:readonly="form.status == 2 || form.isOwner == 0" />
</el-form-item>
<el-form-item :label="$t('product.product-edit.473153-3')" prop="categoryId">
<el-select
v-model="form.categoryId"
:placeholder="$t('product.product-edit.473153-4')"
@change="selectCategory"
style="width: 100%"
:disabled="form.status == 2 || form.isOwner == 0"
:filterable="true"
>
<el-option v-for="category in categoryShortList" :key="category.id" :label="category.name" :value="category.id"></el-option>
<el-select v-model="form.categoryId"
:placeholder="$t('product.product-edit.473153-4')" @change="selectCategory"
style="width: 100%" :disabled="form.status == 2 || form.isOwner == 0"
:filterable="true">
<el-option v-for="category in categoryShortList" :key="category.id"
:label="category.name" :value="category.id"></el-option>
</el-select>
</el-form-item>
<el-form-item :label="$t('product.product-edit.473153-78')" prop="deviceType">
<el-select
style="width: 100%"
v-model="form.deviceType"
<el-select style="width: 100%" v-model="form.deviceType"
:placeholder="$t('product.product-edit.473153-13')"
:disabled="form.status == 2 || form.isOwner == 0 || !!form.productId"
filterable
>
<el-option v-for="dict in dict.type.iot_device_type" :key="dict.value" :label="dict.label" :value="parseInt(dict.value)"></el-option>
filterable>
<el-option v-for="dict in dict.type.iot_device_type" :key="dict.value"
:label="dict.label" :value="parseInt(dict.value)"></el-option>
</el-select>
</el-form-item>
<el-form-item :label="$t('product.product-edit.473153-91')" prop="firmwareType">
<el-select style="width: 100%" v-model="form.firmwareType" :placeholder="$t('product.product-edit.473153-92')" :disabled="form.status == 2 || form.isOwner == 0" filterable>
<el-option v-for="dict in dict.type.iot_firmware_type" :key="dict.value" :label="dict.label" :value="parseInt(dict.value)"></el-option>
<el-select style="width: 100%" v-model="form.firmwareType"
:placeholder="$t('product.product-edit.473153-92')"
:disabled="form.status == 2 || form.isOwner == 0" filterable>
<el-option v-for="dict in dict.type.iot_firmware_type" :key="dict.value"
:label="dict.label" :value="parseInt(dict.value)"></el-option>
</el-select>
</el-form-item>
<el-form-item :label="$t('product.product-edit.473153-16')" prop="networkMethod">
<el-select v-model="form.networkMethod" :placeholder="$t('product.product-edit.473153-17')" style="width: 100%" :disabled="form.status == 2 || form.isOwner == 0">
<el-option v-for="dict in networkOptions" :key="dict.value" :label="dict.label" :value="parseInt(dict.value)"></el-option>
<el-select v-model="form.networkMethod"
:placeholder="$t('product.product-edit.473153-17')" style="width: 100%"
:disabled="form.status == 2 || form.isOwner == 0">
<el-option v-for="dict in networkOptions" :key="dict.value" :label="dict.label"
:value="parseInt(dict.value)"></el-option>
</el-select>
</el-form-item>
<el-form-item :label="$t('product.product-edit.473153-25')" prop="productId">
<el-input v-model="form.productId" :placeholder="$t('product.product-edit.473153-26')" readonly />
<el-input v-model="form.productId"
:placeholder="$t('product.product-edit.473153-26')" readonly />
</el-form-item>
<el-form-item :label="$t('product.product-edit.473153-18')">
<template slot="label">
<span>{{ $t('product.product-edit.473153-18') }}</span>
<el-tooltip style="cursor: pointer; margin-left: 5px" effect="light" placement="bottom">
<el-tooltip style="cursor: pointer; margin-left: 5px" effect="light"
placement="bottom">
<div slot="content">
{{ $t('product.product-edit.473153-19') }}
<br />
@ -77,115 +85,113 @@
<i class="el-icon-question" />
</el-tooltip>
</template>
<el-radio-group v-model="form.isSys" :disabled="form.status == 2 || form.isOwner == 0">
<el-radio-group v-model="form.isSys"
:disabled="form.status == 2 || form.isOwner == 0">
<el-radio :label="1">{{ $t('product.product-edit.473153-89') }}</el-radio>
<el-radio :label="0">{{ $t('product.product-edit.473153-90') }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item :label="$t('product.product-edit.473153-32')" prop="remark">
<el-input
v-model="form.remark"
type="textarea"
<el-input v-model="form.remark" type="textarea"
:autosize="{ minRows: 3, maxRows: 5 }"
:placeholder="$t('product.product-edit.473153-33')"
:disabled="form.status == 2 || form.isOwner == 0"
/>
:disabled="form.status == 2 || form.isOwner == 0" />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="8">
<el-form-item v-if="form.deviceType !== 3" :label="$t('product.product-edit.473153-81')" prop="protocolCode">
<el-select
v-model="form.protocolCode"
:placeholder="$t('product.product-edit.473153-82')"
style="width: 100%"
<el-form-item v-if="form.deviceType !== 3" :label="$t('product.product-edit.473153-81')"
prop="protocolCode">
<el-select v-model="form.protocolCode"
:placeholder="$t('product.product-edit.473153-82')" style="width: 100%"
:disabled="form.status == 2 || form.isOwner == 0 || !!form.productId"
@change="handleProductCodeChange"
:filterable="true"
>
<el-option v-for="p in protocolList" :key="p.protocolCode" :label="p.protocolName" :value="p.protocolCode" />
@change="handleProductCodeChange" :filterable="true">
<el-option v-for="p in protocolList" :key="p.protocolCode"
:label="p.protocolName" :value="p.protocolCode" />
</el-select>
</el-form-item>
<el-form-item v-if="form.deviceType !== 4" :label="$t('product.product-edit.473153-14')" prop="transport">
<el-select v-model="form.transport" :placeholder="$t('product.product-edit.473153-15')" style="width: 100%" :disabled="form.status === 2 || form.isOwner === 0">
<el-option
v-for="dict in dict.type.iot_transport_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
:disabled="(form.deviceType === 3 && dict.value !== 'GB28181') || (form.protocolCode === 'MODBUS-TCP' && dict.value !== 'TCP')"
/>
<el-form-item v-if="form.deviceType !== 4" :label="$t('product.product-edit.473153-14')"
prop="transport">
<el-select v-model="form.transport"
:placeholder="$t('product.product-edit.473153-15')" style="width: 100%"
:disabled="form.status === 2 || form.isOwner === 0">
<el-option v-for="dict in dict.type.iot_transport_type" :key="dict.value"
:label="dict.label" :value="dict.value"
:disabled="(form.deviceType === 3 && dict.value !== 'GB28181') || (form.protocolCode === 'MODBUS-TCP' && dict.value !== 'TCP')" />
</el-select>
</el-form-item>
<el-form-item v-if="form.transport === 'MQTT'" :label="$t('product.product-edit.473153-21')" prop="vertificateMethod">
<el-select v-model="form.vertificateMethod" :placeholder="$t('product.product-edit.473153-22')" style="width: 100%" :disabled="form.status == 2 || form.isOwner == 0">
<el-option v-for="dict in dict.type.iot_vertificate_method" :key="dict.value" :label="dict.label" :value="parseInt(dict.value)"></el-option>
<el-form-item v-if="form.transport === 'MQTT'"
:label="$t('product.product-edit.473153-21')" prop="vertificateMethod">
<el-select v-model="form.vertificateMethod"
:placeholder="$t('product.product-edit.473153-22')" style="width: 100%"
:disabled="form.status == 2 || form.isOwner == 0">
<el-option v-for="dict in dict.type.iot_vertificate_method" :key="dict.value"
:label="dict.label" :value="parseInt(dict.value)"></el-option>
</el-select>
</el-form-item>
<el-form-item v-if="form.deviceType !== 4" :label="$t('product.product-edit.473153-23')" prop="locationWay" :disabled="isEditing">
<el-select style="width: 100%" v-model="form.locationWay" :placeholder="$t('product.product-edit.473153-24')" clearable :disabled="form.status == 2 || form.isOwner == 0">
<el-option v-for="dict in dict.type.iot_location_way" :key="dict.value" :label="dict.label" :value="Number(dict.value)" />
<el-form-item v-if="form.deviceType !== 4" :label="$t('product.product-edit.473153-23')"
prop="locationWay" :disabled="isEditing">
<el-select style="width: 100%" v-model="form.locationWay"
:placeholder="$t('product.product-edit.473153-24')" clearable
:disabled="form.status == 2 || form.isOwner == 0">
<el-option v-for="dict in dict.type.iot_location_way" :key="dict.value"
:label="dict.label" :value="Number(dict.value)" />
</el-select>
</el-form-item>
<el-form-item v-if="form.transport === 'MQTT'" :label="$t('product.product-edit.473153-27')" prop="mqttAccount">
<el-input
style="width: 100%"
v-model="form.mqttAccount"
:placeholder="$t('product.product-edit.473153-28')"
:type="accountInputType"
:readonly="form.status === 2 || form.isOwner == 0"
>
<el-button slot="append" icon="el-icon-view" style="font-size: 18px" @click="changeInputType('account')"></el-button>
<el-form-item v-if="form.transport === 'MQTT'"
:label="$t('product.product-edit.473153-27')" prop="mqttAccount">
<el-input style="width: 100%" v-model="form.mqttAccount"
:placeholder="$t('product.product-edit.473153-28')" :type="accountInputType"
:readonly="form.status === 2 || form.isOwner == 0">
<el-button slot="append" icon="el-icon-view" style="font-size: 18px"
@click="changeInputType('account')"></el-button>
</el-input>
</el-form-item>
<el-form-item v-if="form.transport === 'MQTT'" :label="$t('product.product-edit.473153-29')" prop="mqttPassword">
<el-input
style="width: 100%"
v-model="form.mqttPassword"
:placeholder="$t('product.product-edit.473153-30')"
:type="passwordInputType"
:readonly="form.status === 2 || form.isOwner == 0"
>
<el-button slot="append" icon="el-icon-view" style="font-size: 18px" @click="changeInputType('password')"></el-button>
<el-form-item v-if="form.transport === 'MQTT'"
:label="$t('product.product-edit.473153-29')" prop="mqttPassword">
<el-input style="width: 100%" v-model="form.mqttPassword"
:placeholder="$t('product.product-edit.473153-30')" :type="passwordInputType"
:readonly="form.status === 2 || form.isOwner == 0">
<el-button slot="append" icon="el-icon-view" style="font-size: 18px"
@click="changeInputType('password')"></el-button>
</el-input>
</el-form-item>
<el-form-item v-if="form.transport === 'MQTT' && form.vertificateMethod !== 1" :label="$t('product.product-edit.473153-31')" prop="mqttSecret">
<el-input style="width: 100%" v-model="form.mqttSecret" :placeholder="$t('product.product-edit.473153-26')" :type="keyInputType" readonly>
<el-button slot="append" icon="el-icon-view" style="font-size: 18px" @click="changeInputType('key')"></el-button>
<el-form-item v-if="form.transport === 'MQTT' && form.vertificateMethod !== 1"
:label="$t('product.product-edit.473153-31')" prop="mqttSecret">
<el-input style="width: 100%" v-model="form.mqttSecret"
:placeholder="$t('product.product-edit.473153-26')" :type="keyInputType"
readonly>
<el-button slot="append" icon="el-icon-view" style="font-size: 18px"
@click="changeInputType('key')"></el-button>
</el-input>
</el-form-item>
<el-form-item v-if="form.transport === 'MQTT'" :label="$t('product.product-edit.473153-20')" prop="networkMethod">
<el-switch v-model="form.isAuthorize" @change="changeIsAuthorize(form.isAuthorize)" :active-value="1" :inactive-value="0" :disabled="form.status == 2 || form.isOwner == 0" />
<el-form-item v-if="form.transport === 'MQTT'"
:label="$t('product.product-edit.473153-20')" prop="networkMethod">
<el-switch v-model="form.isAuthorize" @change="changeIsAuthorize(form.isAuthorize)"
:active-value="1" :inactive-value="0"
:disabled="form.status == 2 || form.isOwner == 0" />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="8">
<el-form-item :label="$t('product.product-edit.473153-34')">
<div v-if="form.status === 2 && !form.imgUrl && form.isOwner != 0">
<el-image
style="height: 145px; height: 145px; border-radius: 10px"
<el-image style="height: 145px; height: 145px; border-radius: 10px"
:preview-src-list="[require('@/assets/images/gateway.png')]"
:src="require('@/assets/images/gateway.png')"
fit="cover"
v-if="form.deviceType == 2"
></el-image>
<el-image
style="height: 145px; height: 145px; border-radius: 10px"
:src="require('@/assets/images/gateway.png')" fit="cover"
v-if="form.deviceType == 2"></el-image>
<el-image style="height: 145px; height: 145px; border-radius: 10px"
:preview-src-list="[require('@/assets/images/video.png')]"
:src="require('@/assets/images/video.png')"
fit="cover"
v-else-if="form.deviceType == 3"
></el-image>
<el-image
style="height: 145px; height: 145px; border-radius: 10px"
:src="require('@/assets/images/video.png')" fit="cover"
v-else-if="form.deviceType == 3"></el-image>
<el-image style="height: 145px; height: 145px; border-radius: 10px"
:preview-src-list="[require('@/assets/images/product.png')]"
:src="require('@/assets/images/product.png')"
fit="cover"
v-else
></el-image>
:src="require('@/assets/images/product.png')" fit="cover" v-else></el-image>
</div>
<div v-else>
<imageUpload ref="image-upload" :disabled="form.status === 2 ? true : false" :value="form.imgUrl" :limit="1" :fileSize="1" @input="getImagePath($event)"></imageUpload>
<imageUpload ref="image-upload" :disabled="form.status === 2 ? true : false"
:value="form.imgUrl" :limit="1" :fileSize="1" @input="getImagePath($event)">
</imageUpload>
</div>
</el-form-item>
</el-col>
@ -193,10 +199,13 @@
<el-col :span="20">
<el-form-item style="text-align: center; margin: 40px 0px">
<el-button v-show="!!form.productId && form.status != 2 && form.isOwner != 0" type="primary" @click="handleSubmitForm" v-hasPermi="['iot:product:edit']">
<el-button v-show="!!form.productId && form.status != 2 && form.isOwner != 0"
type="primary" @click="handleSubmitForm" v-hasPermi="['iot:product:edit']">
{{ $t('update') }}
</el-button>
<el-button v-show="!form.productId && form.status != 2" type="primary" @click="handleSubmitForm" v-hasPermi="['iot:product:add']">{{ $t('add') }}</el-button>
<el-button v-show="!form.productId && form.status != 2" type="primary"
@click="handleSubmitForm" v-hasPermi="['iot:product:add']">{{ $t('add')
}}</el-button>
</el-form-item>
</el-col>
</el-form>
@ -207,33 +216,31 @@
<product-things-model ref="productThingsModel" :product="form" @updateModel="updateModel" />
</el-tab-pane>
<!-- 子产品 -->
<el-tab-pane
name="productSub"
<el-tab-pane name="productSub"
v-if="form.deviceType == 2 && (form.protocolCode == 'MODBUS-RTU' || form.protocolCode == 'MODBUS-TCP' || form.protocolCode == 'MODBUS-JSON-HP' || form.protocolCode == 'MODBUS-JSON-ZQWL')"
lazy
>
lazy>
<span slot="label">{{ $t('product.product-edit.473153-83') }}</span>
<product-sub ref="productSub" :product="form" />
</el-tab-pane>
<el-tab-pane
name="productModbus"
v-if="
<el-tab-pane name="productModbus" v-if="
(form.deviceType == 1 || form.deviceType == 4) &&
(form.protocolCode == 'MODBUS-RTU' || form.protocolCode == 'MODBUS-TCP' || form.protocolCode == 'MODBUS-JSON-HP' || form.protocolCode == 'MODBUS-JSON-ZQWL')
"
>
">
<span slot="label">
{{ $t('product.product-edit.473153-80') }}
</span>
<product-modbus ref="productModbus" :product="form" @sendPollType="sendPollType" />
</el-tab-pane>
<!-- 轮询任务 -->
<el-tab-pane name="productModbusTask" v-if="form.deviceType !== 3 && form.deviceType !== 2 && polltype === 0 && (form.protocolCode == 'MODBUS-RTU' || form.protocolCode == 'MODBUS-TCP')" lazy>
<el-tab-pane name="productModbusTask"
v-if="form.deviceType !== 3 && form.deviceType !== 2 && polltype === 0 && (form.protocolCode == 'MODBUS-RTU' || form.protocolCode == 'MODBUS-TCP')"
lazy>
<span slot="label">{{ $t('product.product-edit.473153-84') }}</span>
<product-modbus-task ref="productModbusTask" :product="form" @getSendData="getData($event)" />
</el-tab-pane>
<el-tab-pane name="productAuthorize" v-if="form.deviceType !== 3 && form.transport === 'MQTT'">
<span slot="label" v-hasPermi="['iot:authorize:query']">{{ $t('product.product-edit.473153-40') }}</span>
<span slot="label" v-hasPermi="['iot:authorize:query']">{{ $t('product.product-edit.473153-40')
}}</span>
<product-authorize ref="productAuthorize" :product="form" />
</el-tab-pane>
<el-tab-pane label="" name="sipConfig" v-if="form.deviceType === 3">
@ -461,7 +468,9 @@ export default {
getProductData() {
getProduct(this.form.productId).then((res) => {
if (res.code === 200) {
console.log('产品数据', JSON.stringify(res.data)); //
this.form = res.data;
console.log('当前form', JSON.stringify(this.form)); //
}
});
},

View File

@ -11,6 +11,16 @@ const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
const name = process.env.VUE_APP_TITLE || 'FastBee物联网平台'; // 网页标题
const port = process.env.port || process.env.npm_config_port || 80; // 端口
// 设置编译时间环境变量
// process.env.VUE_APP_BUILD_TIME = new Date().toLocaleString('zh-CN', {
// year: 'numeric',
// month: '2-digit',
// day: '2-digit',
// hour: '2-digit',
// minute: '2-digit',
// second: '2-digit'
// });
const { codeInspectorPlugin } = require('code-inspector-plugin');
// vue.config.js 配置说明